Blame view

fs/gfs2/sys.c 17.6 KB
b3b94faa5   David Teigland   [GFS2] The core o...
1
2
  /*
   * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
3a8a9a103   Steven Whitehouse   [GFS2] Update cop...
3
   * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
b3b94faa5   David Teigland   [GFS2] The core o...
4
5
6
   *
   * This copyrighted material is made available to anyone wishing to use,
   * modify, copy, or redistribute it subject to the terms and conditions
e9fc2aa09   Steven Whitehouse   [GFS2] Update cop...
7
   * of the GNU General Public License version 2.
b3b94faa5   David Teigland   [GFS2] The core o...
8
   */
d77d1b58a   Joe Perches   GFS2: Use pr_<lev...
9
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
b3b94faa5   David Teigland   [GFS2] The core o...
10
  #include <linux/sched.h>
b3b94faa5   David Teigland   [GFS2] The core o...
11
12
13
14
15
  #include <linux/spinlock.h>
  #include <linux/completion.h>
  #include <linux/buffer_head.h>
  #include <linux/module.h>
  #include <linux/kobject.h>
b3b94faa5   David Teigland   [GFS2] The core o...
16
  #include <asm/uaccess.h>
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
17
  #include <linux/gfs2_ondisk.h>
31e54b01f   Steven Whitehouse   GFS2: Add sysfs l...
18
  #include <linux/genhd.h>
b3b94faa5   David Teigland   [GFS2] The core o...
19
20
  
  #include "gfs2.h"
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
21
  #include "incore.h"
b3b94faa5   David Teigland   [GFS2] The core o...
22
23
24
25
  #include "sys.h"
  #include "super.h"
  #include "glock.h"
  #include "quota.h"
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
26
  #include "util.h"
64d576ba2   Steven Whitehouse   GFS2: Add a "demo...
27
  #include "glops.h"
6ecd7c2dd   Tejun Heo   gfs2: use workque...
28
  #include "recovery.h"
b3b94faa5   David Teigland   [GFS2] The core o...
29

48c2b6136   Steven Whitehouse   GFS2: Add commit=...
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
  struct gfs2_attr {
  	struct attribute attr;
  	ssize_t (*show)(struct gfs2_sbd *, char *);
  	ssize_t (*store)(struct gfs2_sbd *, const char *, size_t);
  };
  
  static ssize_t gfs2_attr_show(struct kobject *kobj, struct attribute *attr,
  			      char *buf)
  {
  	struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj);
  	struct gfs2_attr *a = container_of(attr, struct gfs2_attr, attr);
  	return a->show ? a->show(sdp, buf) : 0;
  }
  
  static ssize_t gfs2_attr_store(struct kobject *kobj, struct attribute *attr,
  			       const char *buf, size_t len)
  {
  	struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj);
  	struct gfs2_attr *a = container_of(attr, struct gfs2_attr, attr);
  	return a->store ? a->store(sdp, buf, len) : len;
  }
52cf25d0a   Emese Revfy   Driver core: Cons...
51
  static const struct sysfs_ops gfs2_attr_ops = {
48c2b6136   Steven Whitehouse   GFS2: Add commit=...
52
53
54
55
56
57
  	.show  = gfs2_attr_show,
  	.store = gfs2_attr_store,
  };
  
  
  static struct kset *gfs2_kset;
b3b94faa5   David Teigland   [GFS2] The core o...
58
59
  static ssize_t id_show(struct gfs2_sbd *sdp, char *buf)
  {
c7227e464   Bob Peterson   [GFS2] Given devi...
60
61
62
  	return snprintf(buf, PAGE_SIZE, "%u:%u
  ",
  			MAJOR(sdp->sd_vfs->s_dev), MINOR(sdp->sd_vfs->s_dev));
b3b94faa5   David Teigland   [GFS2] The core o...
63
64
65
66
  }
  
  static ssize_t fsname_show(struct gfs2_sbd *sdp, char *buf)
  {
3204a6c05   David Teigland   [GFS2] use snprin...
67
68
  	return snprintf(buf, PAGE_SIZE, "%s
  ", sdp->sd_fsname);
b3b94faa5   David Teigland   [GFS2] The core o...
69
  }
02e3cc70e   Steven Whitehouse   GFS2: Expose UUID...
70
71
72
73
74
75
76
77
78
79
80
81
82
  static int gfs2_uuid_valid(const u8 *uuid)
  {
  	int i;
  
  	for (i = 0; i < 16; i++) {
  		if (uuid[i])
  			return 1;
  	}
  	return 0;
  }
  
  static ssize_t uuid_show(struct gfs2_sbd *sdp, char *buf)
  {
32e471ef1   Steven Whitehouse   GFS2: Use UUID fi...
83
84
  	struct super_block *s = sdp->sd_vfs;
  	const u8 *uuid = s->s_uuid;
02e3cc70e   Steven Whitehouse   GFS2: Expose UUID...
85
86
87
  	buf[0] = '\0';
  	if (!gfs2_uuid_valid(uuid))
  		return 0;
f0b34ae63   Joe Perches   fs/gfs2/sys.c: us...
88
89
  	return snprintf(buf, PAGE_SIZE, "%pUB
  ", uuid);
02e3cc70e   Steven Whitehouse   GFS2: Expose UUID...
90
  }
b3b94faa5   David Teigland   [GFS2] The core o...
91
92
  static ssize_t freeze_show(struct gfs2_sbd *sdp, char *buf)
  {
d564053f0   Steven Whitehouse   GFS2: Clean up fr...
93
94
  	struct super_block *sb = sdp->sd_vfs;
  	int frozen = (sb->s_writers.frozen == SB_UNFROZEN) ? 0 : 1;
b3b94faa5   David Teigland   [GFS2] The core o...
95

3566c9647   alex chen   GFS2: fix sprintf...
96
97
  	return snprintf(buf, PAGE_SIZE, "%d
  ", frozen);
b3b94faa5   David Teigland   [GFS2] The core o...
98
99
100
101
  }
  
  static ssize_t freeze_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
  {
e50ead480   Fabian Frederick   gfs2: convert sim...
102
103
104
105
106
  	int error, n;
  
  	error = kstrtoint(buf, 0, &n);
  	if (error)
  		return error;
b3b94faa5   David Teigland   [GFS2] The core o...
107
108
  
  	if (!capable(CAP_SYS_ADMIN))
417358187   Zhao Hongjiang   fs: change return...
109
  		return -EPERM;
b3b94faa5   David Teigland   [GFS2] The core o...
110
111
112
  
  	switch (n) {
  	case 0:
d564053f0   Steven Whitehouse   GFS2: Clean up fr...
113
  		error = thaw_super(sdp->sd_vfs);
b3b94faa5   David Teigland   [GFS2] The core o...
114
115
  		break;
  	case 1:
d564053f0   Steven Whitehouse   GFS2: Clean up fr...
116
  		error = freeze_super(sdp->sd_vfs);
b3b94faa5   David Teigland   [GFS2] The core o...
117
118
  		break;
  	default:
d564053f0   Steven Whitehouse   GFS2: Clean up fr...
119
  		return -EINVAL;
b3b94faa5   David Teigland   [GFS2] The core o...
120
  	}
d564053f0   Steven Whitehouse   GFS2: Clean up fr...
121
  	if (error) {
b3b94faa5   David Teigland   [GFS2] The core o...
122
  		fs_warn(sdp, "freeze %d error %d", n, error);
d564053f0   Steven Whitehouse   GFS2: Clean up fr...
123
124
  		return error;
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
125

d564053f0   Steven Whitehouse   GFS2: Clean up fr...
126
  	return len;
b3b94faa5   David Teigland   [GFS2] The core o...
127
128
129
130
131
  }
  
  static ssize_t withdraw_show(struct gfs2_sbd *sdp, char *buf)
  {
  	unsigned int b = test_bit(SDF_SHUTDOWN, &sdp->sd_flags);
3204a6c05   David Teigland   [GFS2] use snprin...
132
133
  	return snprintf(buf, PAGE_SIZE, "%u
  ", b);
b3b94faa5   David Teigland   [GFS2] The core o...
134
135
136
137
  }
  
  static ssize_t withdraw_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
  {
e50ead480   Fabian Frederick   gfs2: convert sim...
138
  	int error, val;
b3b94faa5   David Teigland   [GFS2] The core o...
139
  	if (!capable(CAP_SYS_ADMIN))
417358187   Zhao Hongjiang   fs: change return...
140
  		return -EPERM;
b3b94faa5   David Teigland   [GFS2] The core o...
141

e50ead480   Fabian Frederick   gfs2: convert sim...
142
143
144
145
146
  	error = kstrtoint(buf, 0, &val);
  	if (error)
  		return error;
  
  	if (val != 1)
b3b94faa5   David Teigland   [GFS2] The core o...
147
  		return -EINVAL;
cb94eb066   Joe Perches   GFS2: Convert gfs...
148
149
  	gfs2_lm_withdraw(sdp, "withdrawing from cluster at user's request
  ");
b3b94faa5   David Teigland   [GFS2] The core o...
150
151
152
153
154
155
  	return len;
  }
  
  static ssize_t statfs_sync_store(struct gfs2_sbd *sdp, const char *buf,
  				 size_t len)
  {
e50ead480   Fabian Frederick   gfs2: convert sim...
156
  	int error, val;
b3b94faa5   David Teigland   [GFS2] The core o...
157
  	if (!capable(CAP_SYS_ADMIN))
417358187   Zhao Hongjiang   fs: change return...
158
  		return -EPERM;
b3b94faa5   David Teigland   [GFS2] The core o...
159

e50ead480   Fabian Frederick   gfs2: convert sim...
160
161
162
163
164
  	error = kstrtoint(buf, 0, &val);
  	if (error)
  		return error;
  
  	if (val != 1)
b3b94faa5   David Teigland   [GFS2] The core o...
165
  		return -EINVAL;
8c42d637f   Steven Whitehouse   GFS2: Alter argum...
166
  	gfs2_statfs_sync(sdp->sd_vfs, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
167
168
  	return len;
  }
b3b94faa5   David Teigland   [GFS2] The core o...
169
170
171
  static ssize_t quota_sync_store(struct gfs2_sbd *sdp, const char *buf,
  				size_t len)
  {
e50ead480   Fabian Frederick   gfs2: convert sim...
172
  	int error, val;
b3b94faa5   David Teigland   [GFS2] The core o...
173
  	if (!capable(CAP_SYS_ADMIN))
417358187   Zhao Hongjiang   fs: change return...
174
  		return -EPERM;
b3b94faa5   David Teigland   [GFS2] The core o...
175

e50ead480   Fabian Frederick   gfs2: convert sim...
176
177
178
179
180
  	error = kstrtoint(buf, 0, &val);
  	if (error)
  		return error;
  
  	if (val != 1)
b3b94faa5   David Teigland   [GFS2] The core o...
181
  		return -EINVAL;
ceed17236   Jan Kara   quota: Split dquo...
182
  	gfs2_quota_sync(sdp->sd_vfs, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
183
184
185
186
187
188
  	return len;
  }
  
  static ssize_t quota_refresh_user_store(struct gfs2_sbd *sdp, const char *buf,
  					size_t len)
  {
ed87dabcc   Eric W. Biederman   gfs2: Convert gfs...
189
  	struct kqid qid;
ea7623385   Steven Whitehouse   GFS2: Add proper ...
190
  	int error;
cd915493f   Steven Whitehouse   [GFS2] Change all...
191
  	u32 id;
b3b94faa5   David Teigland   [GFS2] The core o...
192
193
  
  	if (!capable(CAP_SYS_ADMIN))
417358187   Zhao Hongjiang   fs: change return...
194
  		return -EPERM;
b3b94faa5   David Teigland   [GFS2] The core o...
195

e50ead480   Fabian Frederick   gfs2: convert sim...
196
197
198
  	error = kstrtou32(buf, 0, &id);
  	if (error)
  		return error;
b3b94faa5   David Teigland   [GFS2] The core o...
199

ed87dabcc   Eric W. Biederman   gfs2: Convert gfs...
200
201
202
203
204
  	qid = make_kqid(current_user_ns(), USRQUOTA, id);
  	if (!qid_valid(qid))
  		return -EINVAL;
  
  	error = gfs2_quota_refresh(sdp, qid);
ea7623385   Steven Whitehouse   GFS2: Add proper ...
205
  	return error ? error : len;
b3b94faa5   David Teigland   [GFS2] The core o...
206
207
208
209
210
  }
  
  static ssize_t quota_refresh_group_store(struct gfs2_sbd *sdp, const char *buf,
  					 size_t len)
  {
ed87dabcc   Eric W. Biederman   gfs2: Convert gfs...
211
  	struct kqid qid;
ea7623385   Steven Whitehouse   GFS2: Add proper ...
212
  	int error;
cd915493f   Steven Whitehouse   [GFS2] Change all...
213
  	u32 id;
b3b94faa5   David Teigland   [GFS2] The core o...
214
215
  
  	if (!capable(CAP_SYS_ADMIN))
417358187   Zhao Hongjiang   fs: change return...
216
  		return -EPERM;
b3b94faa5   David Teigland   [GFS2] The core o...
217

e50ead480   Fabian Frederick   gfs2: convert sim...
218
219
220
  	error = kstrtou32(buf, 0, &id);
  	if (error)
  		return error;
b3b94faa5   David Teigland   [GFS2] The core o...
221

ed87dabcc   Eric W. Biederman   gfs2: Convert gfs...
222
223
224
225
226
  	qid = make_kqid(current_user_ns(), GRPQUOTA, id);
  	if (!qid_valid(qid))
  		return -EINVAL;
  
  	error = gfs2_quota_refresh(sdp, qid);
ea7623385   Steven Whitehouse   GFS2: Add proper ...
227
  	return error ? error : len;
b3b94faa5   David Teigland   [GFS2] The core o...
228
  }
64d576ba2   Steven Whitehouse   GFS2: Add a "demo...
229
230
231
232
233
234
235
236
237
238
239
  static ssize_t demote_rq_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
  {
  	struct gfs2_glock *gl;
  	const struct gfs2_glock_operations *glops;
  	unsigned int glmode;
  	unsigned int gltype;
  	unsigned long long glnum;
  	char mode[16];
  	int rv;
  
  	if (!capable(CAP_SYS_ADMIN))
417358187   Zhao Hongjiang   fs: change return...
240
  		return -EPERM;
64d576ba2   Steven Whitehouse   GFS2: Add a "demo...
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
  
  	rv = sscanf(buf, "%u:%llu %15s", &gltype, &glnum,
  		    mode);
  	if (rv != 3)
  		return -EINVAL;
  
  	if (strcmp(mode, "EX") == 0)
  		glmode = LM_ST_UNLOCKED;
  	else if ((strcmp(mode, "CW") == 0) || (strcmp(mode, "DF") == 0))
  		glmode = LM_ST_DEFERRED;
  	else if ((strcmp(mode, "PR") == 0) || (strcmp(mode, "SH") == 0))
  		glmode = LM_ST_SHARED;
  	else
  		return -EINVAL;
  
  	if (gltype > LM_TYPE_JOURNAL)
  		return -EINVAL;
24972557b   Benjamin Marzinski   GFS2: remove tran...
258
259
  	if (gltype == LM_TYPE_NONDISK && glnum == GFS2_FREEZE_LOCK)
  		glops = &gfs2_freeze_glops;
134669854   Steven Whitehouse   GFS2: Fix type ma...
260
261
  	else
  		glops = gfs2_glops_list[gltype];
64d576ba2   Steven Whitehouse   GFS2: Add a "demo...
262
263
  	if (glops == NULL)
  		return -EINVAL;
6a99be5d7   Steven Whitehouse   GFS2: Fix typo
264
  	if (!test_and_set_bit(SDF_DEMOTE, &sdp->sd_flags))
913a71d25   Steven Whitehouse   GFS2: Add some us...
265
266
  		fs_info(sdp, "demote interface used
  ");
64d576ba2   Steven Whitehouse   GFS2: Add a "demo...
267
268
269
270
271
272
273
  	rv = gfs2_glock_get(sdp, glnum, glops, 0, &gl);
  	if (rv)
  		return rv;
  	gfs2_glock_cb(gl, glmode);
  	gfs2_glock_put(gl);
  	return len;
  }
b3b94faa5   David Teigland   [GFS2] The core o...
274
275
276
277
278
279
  
  #define GFS2_ATTR(name, mode, show, store) \
  static struct gfs2_attr gfs2_attr_##name = __ATTR(name, mode, show, store)
  
  GFS2_ATTR(id,                  0444, id_show,       NULL);
  GFS2_ATTR(fsname,              0444, fsname_show,   NULL);
02e3cc70e   Steven Whitehouse   GFS2: Expose UUID...
280
  GFS2_ATTR(uuid,                0444, uuid_show,     NULL);
b3b94faa5   David Teigland   [GFS2] The core o...
281
  GFS2_ATTR(freeze,              0644, freeze_show,   freeze_store);
b3b94faa5   David Teigland   [GFS2] The core o...
282
283
284
285
286
  GFS2_ATTR(withdraw,            0644, withdraw_show, withdraw_store);
  GFS2_ATTR(statfs_sync,         0200, NULL,          statfs_sync_store);
  GFS2_ATTR(quota_sync,          0200, NULL,          quota_sync_store);
  GFS2_ATTR(quota_refresh_user,  0200, NULL,          quota_refresh_user_store);
  GFS2_ATTR(quota_refresh_group, 0200, NULL,          quota_refresh_group_store);
64d576ba2   Steven Whitehouse   GFS2: Add a "demo...
287
  GFS2_ATTR(demote_rq,           0200, NULL,	    demote_rq_store);
b3b94faa5   David Teigland   [GFS2] The core o...
288
289
290
291
  
  static struct attribute *gfs2_attrs[] = {
  	&gfs2_attr_id.attr,
  	&gfs2_attr_fsname.attr,
02e3cc70e   Steven Whitehouse   GFS2: Expose UUID...
292
  	&gfs2_attr_uuid.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
293
  	&gfs2_attr_freeze.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
294
295
296
297
298
  	&gfs2_attr_withdraw.attr,
  	&gfs2_attr_statfs_sync.attr,
  	&gfs2_attr_quota_sync.attr,
  	&gfs2_attr_quota_refresh_user.attr,
  	&gfs2_attr_quota_refresh_group.attr,
64d576ba2   Steven Whitehouse   GFS2: Add a "demo...
299
  	&gfs2_attr_demote_rq.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
300
301
  	NULL,
  };
0d515210b   Bob Peterson   GFS2: Add kobject...
302
303
304
305
306
307
  static void gfs2_sbd_release(struct kobject *kobj)
  {
  	struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj);
  
  	kfree(sdp);
  }
b3b94faa5   David Teigland   [GFS2] The core o...
308
  static struct kobj_type gfs2_ktype = {
0d515210b   Bob Peterson   GFS2: Add kobject...
309
  	.release = gfs2_sbd_release,
b3b94faa5   David Teigland   [GFS2] The core o...
310
311
312
  	.default_attrs = gfs2_attrs,
  	.sysfs_ops     = &gfs2_attr_ops,
  };
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
  
  /*
   * lock_module. Originally from lock_dlm
   */
  
  static ssize_t proto_name_show(struct gfs2_sbd *sdp, char *buf)
  {
  	const struct lm_lockops *ops = sdp->sd_lockstruct.ls_ops;
  	return sprintf(buf, "%s
  ", ops->lm_proto_name);
  }
  
  static ssize_t block_show(struct gfs2_sbd *sdp, char *buf)
  {
  	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
  	ssize_t ret;
  	int val = 0;
e0c2a9aa1   David Teigland   GFS2: dlm based r...
330
  	if (test_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags))
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
331
332
333
334
335
336
337
338
339
  		val = 1;
  	ret = sprintf(buf, "%d
  ", val);
  	return ret;
  }
  
  static ssize_t block_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
  {
  	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
e50ead480   Fabian Frederick   gfs2: convert sim...
340
  	int ret, val;
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
341

e50ead480   Fabian Frederick   gfs2: convert sim...
342
343
344
  	ret = kstrtoint(buf, 0, &val);
  	if (ret)
  		return ret;
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
345
346
  
  	if (val == 1)
e0c2a9aa1   David Teigland   GFS2: dlm based r...
347
  		set_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags);
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
348
  	else if (val == 0) {
e0c2a9aa1   David Teigland   GFS2: dlm based r...
349
  		clear_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags);
4e857c58e   Peter Zijlstra   arch: Mass conver...
350
  		smp_mb__after_atomic();
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
351
352
  		gfs2_glock_thaw(sdp);
  	} else {
e50ead480   Fabian Frederick   gfs2: convert sim...
353
  		return -EINVAL;
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
354
  	}
e50ead480   Fabian Frederick   gfs2: convert sim...
355
  	return len;
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
356
  }
fd95e81cb   Steven Whitehouse   GFS2: Reinstate w...
357
358
359
360
361
362
363
364
365
366
  static ssize_t wdack_show(struct gfs2_sbd *sdp, char *buf)
  {
  	int val = completion_done(&sdp->sd_wdack) ? 1 : 0;
  
  	return sprintf(buf, "%d
  ", val);
  }
  
  static ssize_t wdack_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
  {
e50ead480   Fabian Frederick   gfs2: convert sim...
367
  	int ret, val;
fd95e81cb   Steven Whitehouse   GFS2: Reinstate w...
368

e50ead480   Fabian Frederick   gfs2: convert sim...
369
370
371
  	ret = kstrtoint(buf, 0, &val);
  	if (ret)
  		return ret;
fd95e81cb   Steven Whitehouse   GFS2: Reinstate w...
372
373
374
375
376
  
  	if ((val == 1) &&
  	    !strcmp(sdp->sd_lockstruct.ls_ops->lm_proto_name, "lock_dlm"))
  		complete(&sdp->sd_wdack);
  	else
e50ead480   Fabian Frederick   gfs2: convert sim...
377
378
  		return -EINVAL;
  	return len;
fd95e81cb   Steven Whitehouse   GFS2: Reinstate w...
379
  }
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
380
381
382
383
384
385
  static ssize_t lkfirst_show(struct gfs2_sbd *sdp, char *buf)
  {
  	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
  	return sprintf(buf, "%d
  ", ls->ls_first);
  }
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
386
387
388
389
390
391
392
393
  static ssize_t lkfirst_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
  {
  	unsigned first;
  	int rv;
  
  	rv = sscanf(buf, "%u", &first);
  	if (rv != 1 || first > 1)
  		return -EINVAL;
3942ae531   Steven Whitehouse   GFS2: Fix race du...
394
395
396
  	rv = wait_for_completion_killable(&sdp->sd_locking_init);
  	if (rv)
  		return rv;
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
397
398
399
400
401
402
403
404
405
  	spin_lock(&sdp->sd_jindex_spin);
  	rv = -EBUSY;
  	if (test_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0)
  		goto out;
  	rv = -EINVAL;
  	if (sdp->sd_args.ar_spectator)
  		goto out;
  	if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL)
  		goto out;
e0c2a9aa1   David Teigland   GFS2: dlm based r...
406
407
  	sdp->sd_lockstruct.ls_first = first;
  	rv = 0;
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
408
409
410
411
  out:
          spin_unlock(&sdp->sd_jindex_spin);
          return rv ? rv : len;
  }
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
412
413
414
  static ssize_t first_done_show(struct gfs2_sbd *sdp, char *buf)
  {
  	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
e0c2a9aa1   David Teigland   GFS2: dlm based r...
415
416
  	return sprintf(buf, "%d
  ", !!test_bit(DFL_FIRST_MOUNT_DONE, &ls->ls_recover_flags));
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
417
  }
e0c2a9aa1   David Teigland   GFS2: dlm based r...
418
  int gfs2_recover_set(struct gfs2_sbd *sdp, unsigned jid)
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
419
420
  {
  	struct gfs2_jdesc *jd;
fe64d517d   Steven Whitehouse   GFS2: Umount reco...
421
  	int rv;
0e48e055a   Bob Peterson   GFS2: Prevent rec...
422
423
  	/* Wait for our primary journal to be initialized */
  	wait_for_completion(&sdp->sd_journal_ready);
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
424
  	spin_lock(&sdp->sd_jindex_spin);
fe64d517d   Steven Whitehouse   GFS2: Umount reco...
425
426
427
428
  	rv = -EBUSY;
  	if (sdp->sd_jdesc->jd_jid == jid)
  		goto out;
  	rv = -ENOENT;
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
429
430
431
  	list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) {
  		if (jd->jd_jid != jid)
  			continue;
6ecd7c2dd   Tejun Heo   gfs2: use workque...
432
  		rv = gfs2_recover_journal(jd, false);
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
433
434
  		break;
  	}
fe64d517d   Steven Whitehouse   GFS2: Umount reco...
435
  out:
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
436
  	spin_unlock(&sdp->sd_jindex_spin);
e0c2a9aa1   David Teigland   GFS2: dlm based r...
437
438
439
440
441
442
443
444
445
446
447
  	return rv;
  }
  
  static ssize_t recover_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
  {
  	unsigned jid;
  	int rv;
  
  	rv = sscanf(buf, "%u", &jid);
  	if (rv != 1)
  		return -EINVAL;
1a058f528   David Teigland   gfs2: fix recover...
448
449
450
451
  	if (test_bit(SDF_NORECOVERY, &sdp->sd_flags)) {
  		rv = -ESHUTDOWN;
  		goto out;
  	}
e0c2a9aa1   David Teigland   GFS2: dlm based r...
452

1a058f528   David Teigland   gfs2: fix recover...
453
454
  	rv = gfs2_recover_set(sdp, jid);
  out:
fe64d517d   Steven Whitehouse   GFS2: Umount reco...
455
  	return rv ? rv : len;
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
  }
  
  static ssize_t recover_done_show(struct gfs2_sbd *sdp, char *buf)
  {
  	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
  	return sprintf(buf, "%d
  ", ls->ls_recover_jid_done);
  }
  
  static ssize_t recover_status_show(struct gfs2_sbd *sdp, char *buf)
  {
  	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
  	return sprintf(buf, "%d
  ", ls->ls_recover_jid_status);
  }
e1b28aab5   Steven Whitehouse   GFS2: Remove lock...
471
472
  static ssize_t jid_show(struct gfs2_sbd *sdp, char *buf)
  {
feb47ca93   Steven Whitehouse   GFS2: Improve jou...
473
474
  	return sprintf(buf, "%d
  ", sdp->sd_lockstruct.ls_jid);
e1b28aab5   Steven Whitehouse   GFS2: Remove lock...
475
  }
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
476
477
  static ssize_t jid_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
  {
feb47ca93   Steven Whitehouse   GFS2: Improve jou...
478
          int jid;
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
479
  	int rv;
feb47ca93   Steven Whitehouse   GFS2: Improve jou...
480
  	rv = sscanf(buf, "%d", &jid);
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
481
482
  	if (rv != 1)
  		return -EINVAL;
3942ae531   Steven Whitehouse   GFS2: Fix race du...
483
484
485
  	rv = wait_for_completion_killable(&sdp->sd_locking_init);
  	if (rv)
  		return rv;
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
486
487
  	spin_lock(&sdp->sd_jindex_spin);
  	rv = -EINVAL;
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
488
489
490
  	if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL)
  		goto out;
  	rv = -EBUSY;
feb47ca93   Steven Whitehouse   GFS2: Improve jou...
491
  	if (test_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0)
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
492
  		goto out;
feb47ca93   Steven Whitehouse   GFS2: Improve jou...
493
494
495
  	rv = 0;
  	if (sdp->sd_args.ar_spectator && jid > 0)
  		rv = jid = -EINVAL;
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
496
  	sdp->sd_lockstruct.ls_jid = jid;
feb47ca93   Steven Whitehouse   GFS2: Improve jou...
497
  	clear_bit(SDF_NOJOURNALID, &sdp->sd_flags);
4e857c58e   Peter Zijlstra   arch: Mass conver...
498
  	smp_mb__after_atomic();
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
499
  	wake_up_bit(&sdp->sd_flags, SDF_NOJOURNALID);
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
500
501
502
503
  out:
  	spin_unlock(&sdp->sd_jindex_spin);
  	return rv ? rv : len;
  }
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
504
  #define GDLM_ATTR(_name,_mode,_show,_store) \
48c2b6136   Steven Whitehouse   GFS2: Add commit=...
505
  static struct gfs2_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store)
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
506

d7e623da1   Steven Whitehouse   GFS2: Fix permiss...
507
508
  GDLM_ATTR(proto_name,		0444, proto_name_show,		NULL);
  GDLM_ATTR(block,		0644, block_show,		block_store);
fd95e81cb   Steven Whitehouse   GFS2: Reinstate w...
509
  GDLM_ATTR(withdraw,		0644, wdack_show,		wdack_store);
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
510
511
  GDLM_ATTR(jid,			0644, jid_show,			jid_store);
  GDLM_ATTR(first,		0644, lkfirst_show,		lkfirst_store);
d7e623da1   Steven Whitehouse   GFS2: Fix permiss...
512
513
514
515
  GDLM_ATTR(first_done,		0444, first_done_show,		NULL);
  GDLM_ATTR(recover,		0600, NULL,			recover_store);
  GDLM_ATTR(recover_done,		0444, recover_done_show,	NULL);
  GDLM_ATTR(recover_status,	0444, recover_status_show,	NULL);
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
516
517
518
519
520
  
  static struct attribute *lock_module_attrs[] = {
  	&gdlm_attr_proto_name.attr,
  	&gdlm_attr_block.attr,
  	&gdlm_attr_withdraw.attr,
e1b28aab5   Steven Whitehouse   GFS2: Remove lock...
521
  	&gdlm_attr_jid.attr,
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
522
523
524
525
526
  	&gdlm_attr_first.attr,
  	&gdlm_attr_first_done.attr,
  	&gdlm_attr_recover.attr,
  	&gdlm_attr_recover_done.attr,
  	&gdlm_attr_recover_status.attr,
ea67eedb2   Steven Whitehouse   [GFS2] Fix end of...
527
  	NULL,
b3b94faa5   David Teigland   [GFS2] The core o...
528
  };
b3b94faa5   David Teigland   [GFS2] The core o...
529
  /*
b3b94faa5   David Teigland   [GFS2] The core o...
530
531
532
533
534
   * get and set struct gfs2_tune fields
   */
  
  static ssize_t quota_scale_show(struct gfs2_sbd *sdp, char *buf)
  {
3204a6c05   David Teigland   [GFS2] use snprin...
535
536
537
538
  	return snprintf(buf, PAGE_SIZE, "%u %u
  ",
  			sdp->sd_tune.gt_quota_scale_num,
  			sdp->sd_tune.gt_quota_scale_den);
b3b94faa5   David Teigland   [GFS2] The core o...
539
540
541
542
543
544
545
546
547
  }
  
  static ssize_t quota_scale_store(struct gfs2_sbd *sdp, const char *buf,
  				 size_t len)
  {
  	struct gfs2_tune *gt = &sdp->sd_tune;
  	unsigned int x, y;
  
  	if (!capable(CAP_SYS_ADMIN))
417358187   Zhao Hongjiang   fs: change return...
548
  		return -EPERM;
b3b94faa5   David Teigland   [GFS2] The core o...
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
  
  	if (sscanf(buf, "%u %u", &x, &y) != 2 || !y)
  		return -EINVAL;
  
  	spin_lock(&gt->gt_spin);
  	gt->gt_quota_scale_num = x;
  	gt->gt_quota_scale_den = y;
  	spin_unlock(&gt->gt_spin);
  	return len;
  }
  
  static ssize_t tune_set(struct gfs2_sbd *sdp, unsigned int *field,
  			int check_zero, const char *buf, size_t len)
  {
  	struct gfs2_tune *gt = &sdp->sd_tune;
  	unsigned int x;
e50ead480   Fabian Frederick   gfs2: convert sim...
565
  	int error;
b3b94faa5   David Teigland   [GFS2] The core o...
566
567
  
  	if (!capable(CAP_SYS_ADMIN))
417358187   Zhao Hongjiang   fs: change return...
568
  		return -EPERM;
b3b94faa5   David Teigland   [GFS2] The core o...
569

e50ead480   Fabian Frederick   gfs2: convert sim...
570
571
572
  	error = kstrtouint(buf, 0, &x);
  	if (error)
  		return error;
b3b94faa5   David Teigland   [GFS2] The core o...
573
574
575
576
577
578
579
580
581
  
  	if (check_zero && !x)
  		return -EINVAL;
  
  	spin_lock(&gt->gt_spin);
  	*field = x;
  	spin_unlock(&gt->gt_spin);
  	return len;
  }
b3b94faa5   David Teigland   [GFS2] The core o...
582
  #define TUNE_ATTR_3(name, show, store)                                        \
48c2b6136   Steven Whitehouse   GFS2: Add commit=...
583
  static struct gfs2_attr tune_attr_##name = __ATTR(name, 0644, show, store)
b3b94faa5   David Teigland   [GFS2] The core o...
584
585
586
587
  
  #define TUNE_ATTR_2(name, store)                                              \
  static ssize_t name##_show(struct gfs2_sbd *sdp, char *buf)                   \
  {                                                                             \
3204a6c05   David Teigland   [GFS2] use snprin...
588
589
  	return snprintf(buf, PAGE_SIZE, "%u
  ", sdp->sd_tune.gt_##name);      \
b3b94faa5   David Teigland   [GFS2] The core o...
590
591
592
593
594
595
596
597
598
  }                                                                             \
  TUNE_ATTR_3(name, name##_show, store)
  
  #define TUNE_ATTR(name, check_zero)                                           \
  static ssize_t name##_store(struct gfs2_sbd *sdp, const char *buf, size_t len)\
  {                                                                             \
  	return tune_set(sdp, &sdp->sd_tune.gt_##name, check_zero, buf, len);  \
  }                                                                             \
  TUNE_ATTR_2(name, name##_store)
b3b94faa5   David Teigland   [GFS2] The core o...
599
600
  TUNE_ATTR(quota_warn_period, 0);
  TUNE_ATTR(quota_quantum, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
601
602
  TUNE_ATTR(max_readahead, 0);
  TUNE_ATTR(complain_secs, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
603
604
  TUNE_ATTR(statfs_slow, 0);
  TUNE_ATTR(new_files_jdata, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
605
  TUNE_ATTR(statfs_quantum, 1);
b3b94faa5   David Teigland   [GFS2] The core o...
606
607
608
  TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store);
  
  static struct attribute *tune_attrs[] = {
b3b94faa5   David Teigland   [GFS2] The core o...
609
610
  	&tune_attr_quota_warn_period.attr,
  	&tune_attr_quota_quantum.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
611
612
  	&tune_attr_max_readahead.attr,
  	&tune_attr_complain_secs.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
613
  	&tune_attr_statfs_slow.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
614
  	&tune_attr_statfs_quantum.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
615
616
  	&tune_attr_quota_scale.attr,
  	&tune_attr_new_files_jdata.attr,
ea67eedb2   Steven Whitehouse   [GFS2] Fix end of...
617
  	NULL,
b3b94faa5   David Teigland   [GFS2] The core o...
618
  };
b3b94faa5   David Teigland   [GFS2] The core o...
619
620
  static struct attribute_group tune_group = {
  	.name = "tune",
ea67eedb2   Steven Whitehouse   [GFS2] Fix end of...
621
  	.attrs = tune_attrs,
b3b94faa5   David Teigland   [GFS2] The core o...
622
  };
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
623
624
625
626
  static struct attribute_group lock_module_group = {
  	.name = "lock_module",
  	.attrs = lock_module_attrs,
  };
b3b94faa5   David Teigland   [GFS2] The core o...
627
628
  int gfs2_sys_fs_add(struct gfs2_sbd *sdp)
  {
440d6da20   Steven Whitehouse   GFS2: Add some mo...
629
  	struct super_block *sb = sdp->sd_vfs;
b3b94faa5   David Teigland   [GFS2] The core o...
630
  	int error;
440d6da20   Steven Whitehouse   GFS2: Add some mo...
631
632
633
  	char ro[20];
  	char spectator[20];
  	char *envp[] = { ro, spectator, NULL };
0d515210b   Bob Peterson   GFS2: Add kobject...
634
  	int sysfs_frees_sdp = 0;
440d6da20   Steven Whitehouse   GFS2: Add some mo...
635
636
637
  
  	sprintf(ro, "RDONLY=%d", (sb->s_flags & MS_RDONLY) ? 1 : 0);
  	sprintf(spectator, "SPECTATOR=%d", sdp->sd_args.ar_spectator ? 1 : 0);
b3b94faa5   David Teigland   [GFS2] The core o...
638

9bec101a0   Greg Kroah-Hartman   kset: convert gfs...
639
  	sdp->sd_kobj.kset = gfs2_kset;
901195ed7   Greg Kroah-Hartman   Kobject: change G...
640
641
  	error = kobject_init_and_add(&sdp->sd_kobj, &gfs2_ktype, NULL,
  				     "%s", sdp->sd_table_name);
b3b94faa5   David Teigland   [GFS2] The core o...
642
  	if (error)
0d515210b   Bob Peterson   GFS2: Add kobject...
643
  		goto fail_reg;
b3b94faa5   David Teigland   [GFS2] The core o...
644

0d515210b   Bob Peterson   GFS2: Add kobject...
645
646
  	sysfs_frees_sdp = 1; /* Freeing sdp is now done by sysfs calling
  				function gfs2_sbd_release. */
b3b94faa5   David Teigland   [GFS2] The core o...
647
648
  	error = sysfs_create_group(&sdp->sd_kobj, &tune_group);
  	if (error)
f6eb53498   Steven Whitehouse   GFS2: Remove args...
649
  		goto fail_reg;
b3b94faa5   David Teigland   [GFS2] The core o...
650

f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
651
652
653
  	error = sysfs_create_group(&sdp->sd_kobj, &lock_module_group);
  	if (error)
  		goto fail_tune;
31e54b01f   Steven Whitehouse   GFS2: Add sysfs l...
654
655
656
657
658
  	error = sysfs_create_link(&sdp->sd_kobj,
  				  &disk_to_dev(sb->s_bdev->bd_disk)->kobj,
  				  "device");
  	if (error)
  		goto fail_lock_module;
440d6da20   Steven Whitehouse   GFS2: Add some mo...
659
  	kobject_uevent_env(&sdp->sd_kobj, KOBJ_ADD, envp);
b3b94faa5   David Teigland   [GFS2] The core o...
660
  	return 0;
31e54b01f   Steven Whitehouse   GFS2: Add sysfs l...
661
662
  fail_lock_module:
  	sysfs_remove_group(&sdp->sd_kobj, &lock_module_group);
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
663
664
  fail_tune:
  	sysfs_remove_group(&sdp->sd_kobj, &tune_group);
a91ea69ff   Steven Whitehouse   [GFS2] Align all ...
665
  fail_reg:
0d515210b   Bob Peterson   GFS2: Add kobject...
666
  	free_percpu(sdp->sd_lkstats);
65952fb4e   David Teigland   [GFS2] print moun...
667
  	fs_err(sdp, "error %d adding sysfs files", error);
0d515210b   Bob Peterson   GFS2: Add kobject...
668
669
670
671
672
  	if (sysfs_frees_sdp)
  		kobject_put(&sdp->sd_kobj);
  	else
  		kfree(sdp);
  	sb->s_fs_info = NULL;
b3b94faa5   David Teigland   [GFS2] The core o...
673
674
675
676
677
  	return error;
  }
  
  void gfs2_sys_fs_del(struct gfs2_sbd *sdp)
  {
31e54b01f   Steven Whitehouse   GFS2: Add sysfs l...
678
  	sysfs_remove_link(&sdp->sd_kobj, "device");
b3b94faa5   David Teigland   [GFS2] The core o...
679
  	sysfs_remove_group(&sdp->sd_kobj, &tune_group);
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
680
  	sysfs_remove_group(&sdp->sd_kobj, &lock_module_group);
197b12d67   Greg Kroah-Hartman   Kobject: convert ...
681
  	kobject_put(&sdp->sd_kobj);
b3b94faa5   David Teigland   [GFS2] The core o...
682
  }
fdd1062eb   Steven Whitehouse   GFS2: Send some s...
683
684
685
686
  static int gfs2_uevent(struct kset *kset, struct kobject *kobj,
  		       struct kobj_uevent_env *env)
  {
  	struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj);
32e471ef1   Steven Whitehouse   GFS2: Use UUID fi...
687
688
  	struct super_block *s = sdp->sd_vfs;
  	const u8 *uuid = s->s_uuid;
02e3cc70e   Steven Whitehouse   GFS2: Expose UUID...
689

fdd1062eb   Steven Whitehouse   GFS2: Send some s...
690
691
  	add_uevent_var(env, "LOCKTABLE=%s", sdp->sd_table_name);
  	add_uevent_var(env, "LOCKPROTO=%s", sdp->sd_proto_name);
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
692
  	if (!test_bit(SDF_NOJOURNALID, &sdp->sd_flags))
feb47ca93   Steven Whitehouse   GFS2: Improve jou...
693
  		add_uevent_var(env, "JOURNALID=%d", sdp->sd_lockstruct.ls_jid);
f0b34ae63   Joe Perches   fs/gfs2/sys.c: us...
694
695
  	if (gfs2_uuid_valid(uuid))
  		add_uevent_var(env, "UUID=%pUB", uuid);
fdd1062eb   Steven Whitehouse   GFS2: Send some s...
696
697
  	return 0;
  }
9cd43611c   Emese Revfy   kobject: Constify...
698
  static const struct kset_uevent_ops gfs2_uevent_ops = {
fdd1062eb   Steven Whitehouse   GFS2: Send some s...
699
700
  	.uevent = gfs2_uevent,
  };
b3b94faa5   David Teigland   [GFS2] The core o...
701
702
  int gfs2_sys_init(void)
  {
fdd1062eb   Steven Whitehouse   GFS2: Send some s...
703
  	gfs2_kset = kset_create_and_add("gfs2", &gfs2_uevent_ops, fs_kobj);
9bec101a0   Greg Kroah-Hartman   kset: convert gfs...
704
705
706
  	if (!gfs2_kset)
  		return -ENOMEM;
  	return 0;
b3b94faa5   David Teigland   [GFS2] The core o...
707
708
709
710
  }
  
  void gfs2_sys_uninit(void)
  {
9bec101a0   Greg Kroah-Hartman   kset: convert gfs...
711
  	kset_unregister(gfs2_kset);
b3b94faa5   David Teigland   [GFS2] The core o...
712
  }