Blame view

fs/gfs2/sys.c 17.5 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>
5b825c3af   Ingo Molnar   sched/headers: Pr...
11
  #include <linux/cred.h>
b3b94faa5   David Teigland   [GFS2] The core o...
12
13
14
15
16
  #include <linux/spinlock.h>
  #include <linux/completion.h>
  #include <linux/buffer_head.h>
  #include <linux/module.h>
  #include <linux/kobject.h>
7c0f6ba68   Linus Torvalds   Replace <asm/uacc...
17
  #include <linux/uaccess.h>
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
18
  #include <linux/gfs2_ondisk.h>
31e54b01f   Steven Whitehouse   GFS2: Add sysfs l...
19
  #include <linux/genhd.h>
b3b94faa5   David Teigland   [GFS2] The core o...
20
21
  
  #include "gfs2.h"
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
22
  #include "incore.h"
b3b94faa5   David Teigland   [GFS2] The core o...
23
24
25
26
  #include "sys.h"
  #include "super.h"
  #include "glock.h"
  #include "quota.h"
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
27
  #include "util.h"
64d576ba2   Steven Whitehouse   GFS2: Add a "demo...
28
  #include "glops.h"
6ecd7c2dd   Tejun Heo   gfs2: use workque...
29
  #include "recovery.h"
b3b94faa5   David Teigland   [GFS2] The core o...
30

48c2b6136   Steven Whitehouse   GFS2: Add commit=...
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
  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...
52
  static const struct sysfs_ops gfs2_attr_ops = {
48c2b6136   Steven Whitehouse   GFS2: Add commit=...
53
54
55
56
57
58
  	.show  = gfs2_attr_show,
  	.store = gfs2_attr_store,
  };
  
  
  static struct kset *gfs2_kset;
b3b94faa5   David Teigland   [GFS2] The core o...
59
60
  static ssize_t id_show(struct gfs2_sbd *sdp, char *buf)
  {
c7227e464   Bob Peterson   [GFS2] Given devi...
61
62
63
  	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...
64
65
66
67
  }
  
  static ssize_t fsname_show(struct gfs2_sbd *sdp, char *buf)
  {
3204a6c05   David Teigland   [GFS2] use snprin...
68
69
  	return snprintf(buf, PAGE_SIZE, "%s
  ", sdp->sd_fsname);
b3b94faa5   David Teigland   [GFS2] The core o...
70
  }
02e3cc70e   Steven Whitehouse   GFS2: Expose UUID...
71
72
  static ssize_t uuid_show(struct gfs2_sbd *sdp, char *buf)
  {
32e471ef1   Steven Whitehouse   GFS2: Use UUID fi...
73
  	struct super_block *s = sdp->sd_vfs;
85787090a   Christoph Hellwig   fs: switch ->s_uu...
74

02e3cc70e   Steven Whitehouse   GFS2: Expose UUID...
75
  	buf[0] = '\0';
85787090a   Christoph Hellwig   fs: switch ->s_uu...
76
  	if (uuid_is_null(&s->s_uuid))
02e3cc70e   Steven Whitehouse   GFS2: Expose UUID...
77
  		return 0;
85787090a   Christoph Hellwig   fs: switch ->s_uu...
78
79
  	return snprintf(buf, PAGE_SIZE, "%pUB
  ", &s->s_uuid);
02e3cc70e   Steven Whitehouse   GFS2: Expose UUID...
80
  }
b3b94faa5   David Teigland   [GFS2] The core o...
81
82
  static ssize_t freeze_show(struct gfs2_sbd *sdp, char *buf)
  {
d564053f0   Steven Whitehouse   GFS2: Clean up fr...
83
84
  	struct super_block *sb = sdp->sd_vfs;
  	int frozen = (sb->s_writers.frozen == SB_UNFROZEN) ? 0 : 1;
b3b94faa5   David Teigland   [GFS2] The core o...
85

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

d564053f0   Steven Whitehouse   GFS2: Clean up fr...
116
  	return len;
b3b94faa5   David Teigland   [GFS2] The core o...
117
118
119
120
121
  }
  
  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...
122
123
  	return snprintf(buf, PAGE_SIZE, "%u
  ", b);
b3b94faa5   David Teigland   [GFS2] The core o...
124
125
126
127
  }
  
  static ssize_t withdraw_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
  {
e50ead480   Fabian Frederick   gfs2: convert sim...
128
  	int error, val;
b3b94faa5   David Teigland   [GFS2] The core o...
129
  	if (!capable(CAP_SYS_ADMIN))
417358187   Zhao Hongjiang   fs: change return...
130
  		return -EPERM;
b3b94faa5   David Teigland   [GFS2] The core o...
131

e50ead480   Fabian Frederick   gfs2: convert sim...
132
133
134
135
136
  	error = kstrtoint(buf, 0, &val);
  	if (error)
  		return error;
  
  	if (val != 1)
b3b94faa5   David Teigland   [GFS2] The core o...
137
  		return -EINVAL;
cb94eb066   Joe Perches   GFS2: Convert gfs...
138
139
  	gfs2_lm_withdraw(sdp, "withdrawing from cluster at user's request
  ");
b3b94faa5   David Teigland   [GFS2] The core o...
140
141
142
143
144
145
  	return len;
  }
  
  static ssize_t statfs_sync_store(struct gfs2_sbd *sdp, const char *buf,
  				 size_t len)
  {
e50ead480   Fabian Frederick   gfs2: convert sim...
146
  	int error, val;
b3b94faa5   David Teigland   [GFS2] The core o...
147
  	if (!capable(CAP_SYS_ADMIN))
417358187   Zhao Hongjiang   fs: change return...
148
  		return -EPERM;
b3b94faa5   David Teigland   [GFS2] The core o...
149

e50ead480   Fabian Frederick   gfs2: convert sim...
150
151
152
153
154
  	error = kstrtoint(buf, 0, &val);
  	if (error)
  		return error;
  
  	if (val != 1)
b3b94faa5   David Teigland   [GFS2] The core o...
155
  		return -EINVAL;
8c42d637f   Steven Whitehouse   GFS2: Alter argum...
156
  	gfs2_statfs_sync(sdp->sd_vfs, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
157
158
  	return len;
  }
b3b94faa5   David Teigland   [GFS2] The core o...
159
160
161
  static ssize_t quota_sync_store(struct gfs2_sbd *sdp, const char *buf,
  				size_t len)
  {
e50ead480   Fabian Frederick   gfs2: convert sim...
162
  	int error, val;
b3b94faa5   David Teigland   [GFS2] The core o...
163
  	if (!capable(CAP_SYS_ADMIN))
417358187   Zhao Hongjiang   fs: change return...
164
  		return -EPERM;
b3b94faa5   David Teigland   [GFS2] The core o...
165

e50ead480   Fabian Frederick   gfs2: convert sim...
166
167
168
169
170
  	error = kstrtoint(buf, 0, &val);
  	if (error)
  		return error;
  
  	if (val != 1)
b3b94faa5   David Teigland   [GFS2] The core o...
171
  		return -EINVAL;
ceed17236   Jan Kara   quota: Split dquo...
172
  	gfs2_quota_sync(sdp->sd_vfs, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
173
174
175
176
177
178
  	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...
179
  	struct kqid qid;
ea7623385   Steven Whitehouse   GFS2: Add proper ...
180
  	int error;
cd915493f   Steven Whitehouse   [GFS2] Change all...
181
  	u32 id;
b3b94faa5   David Teigland   [GFS2] The core o...
182
183
  
  	if (!capable(CAP_SYS_ADMIN))
417358187   Zhao Hongjiang   fs: change return...
184
  		return -EPERM;
b3b94faa5   David Teigland   [GFS2] The core o...
185

e50ead480   Fabian Frederick   gfs2: convert sim...
186
187
188
  	error = kstrtou32(buf, 0, &id);
  	if (error)
  		return error;
b3b94faa5   David Teigland   [GFS2] The core o...
189

ed87dabcc   Eric W. Biederman   gfs2: Convert gfs...
190
191
192
193
194
  	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 ...
195
  	return error ? error : len;
b3b94faa5   David Teigland   [GFS2] The core o...
196
197
198
199
200
  }
  
  static ssize_t quota_refresh_group_store(struct gfs2_sbd *sdp, const char *buf,
  					 size_t len)
  {
ed87dabcc   Eric W. Biederman   gfs2: Convert gfs...
201
  	struct kqid qid;
ea7623385   Steven Whitehouse   GFS2: Add proper ...
202
  	int error;
cd915493f   Steven Whitehouse   [GFS2] Change all...
203
  	u32 id;
b3b94faa5   David Teigland   [GFS2] The core o...
204
205
  
  	if (!capable(CAP_SYS_ADMIN))
417358187   Zhao Hongjiang   fs: change return...
206
  		return -EPERM;
b3b94faa5   David Teigland   [GFS2] The core o...
207

e50ead480   Fabian Frederick   gfs2: convert sim...
208
209
210
  	error = kstrtou32(buf, 0, &id);
  	if (error)
  		return error;
b3b94faa5   David Teigland   [GFS2] The core o...
211

ed87dabcc   Eric W. Biederman   gfs2: Convert gfs...
212
213
214
215
216
  	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 ...
217
  	return error ? error : len;
b3b94faa5   David Teigland   [GFS2] The core o...
218
  }
64d576ba2   Steven Whitehouse   GFS2: Add a "demo...
219
220
221
222
223
224
225
226
227
228
229
  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...
230
  		return -EPERM;
64d576ba2   Steven Whitehouse   GFS2: Add a "demo...
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
  
  	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...
248
249
  	if (gltype == LM_TYPE_NONDISK && glnum == GFS2_FREEZE_LOCK)
  		glops = &gfs2_freeze_glops;
134669854   Steven Whitehouse   GFS2: Fix type ma...
250
251
  	else
  		glops = gfs2_glops_list[gltype];
64d576ba2   Steven Whitehouse   GFS2: Add a "demo...
252
253
  	if (glops == NULL)
  		return -EINVAL;
6a99be5d7   Steven Whitehouse   GFS2: Fix typo
254
  	if (!test_and_set_bit(SDF_DEMOTE, &sdp->sd_flags))
913a71d25   Steven Whitehouse   GFS2: Add some us...
255
256
  		fs_info(sdp, "demote interface used
  ");
64d576ba2   Steven Whitehouse   GFS2: Add a "demo...
257
258
259
260
261
262
263
  	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...
264
265
266
267
268
269
  
  #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...
270
  GFS2_ATTR(uuid,                0444, uuid_show,     NULL);
b3b94faa5   David Teigland   [GFS2] The core o...
271
  GFS2_ATTR(freeze,              0644, freeze_show,   freeze_store);
b3b94faa5   David Teigland   [GFS2] The core o...
272
273
274
275
276
  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...
277
  GFS2_ATTR(demote_rq,           0200, NULL,	    demote_rq_store);
b3b94faa5   David Teigland   [GFS2] The core o...
278
279
280
281
  
  static struct attribute *gfs2_attrs[] = {
  	&gfs2_attr_id.attr,
  	&gfs2_attr_fsname.attr,
02e3cc70e   Steven Whitehouse   GFS2: Expose UUID...
282
  	&gfs2_attr_uuid.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
283
  	&gfs2_attr_freeze.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
284
285
286
287
288
  	&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...
289
  	&gfs2_attr_demote_rq.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
290
291
  	NULL,
  };
0d515210b   Bob Peterson   GFS2: Add kobject...
292
293
294
295
296
297
  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...
298
  static struct kobj_type gfs2_ktype = {
0d515210b   Bob Peterson   GFS2: Add kobject...
299
  	.release = gfs2_sbd_release,
b3b94faa5   David Teigland   [GFS2] The core o...
300
301
302
  	.default_attrs = gfs2_attrs,
  	.sysfs_ops     = &gfs2_attr_ops,
  };
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
  
  /*
   * 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...
320
  	if (test_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags))
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
321
322
323
324
325
326
327
328
329
  		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...
330
  	int ret, val;
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
331

e50ead480   Fabian Frederick   gfs2: convert sim...
332
333
334
  	ret = kstrtoint(buf, 0, &val);
  	if (ret)
  		return ret;
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
335
336
  
  	if (val == 1)
e0c2a9aa1   David Teigland   GFS2: dlm based r...
337
  		set_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags);
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
338
  	else if (val == 0) {
e0c2a9aa1   David Teigland   GFS2: dlm based r...
339
  		clear_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags);
4e857c58e   Peter Zijlstra   arch: Mass conver...
340
  		smp_mb__after_atomic();
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
341
342
  		gfs2_glock_thaw(sdp);
  	} else {
e50ead480   Fabian Frederick   gfs2: convert sim...
343
  		return -EINVAL;
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
344
  	}
e50ead480   Fabian Frederick   gfs2: convert sim...
345
  	return len;
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
346
  }
fd95e81cb   Steven Whitehouse   GFS2: Reinstate w...
347
348
349
350
351
352
353
354
355
356
  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...
357
  	int ret, val;
fd95e81cb   Steven Whitehouse   GFS2: Reinstate w...
358

e50ead480   Fabian Frederick   gfs2: convert sim...
359
360
361
  	ret = kstrtoint(buf, 0, &val);
  	if (ret)
  		return ret;
fd95e81cb   Steven Whitehouse   GFS2: Reinstate w...
362
363
364
365
366
  
  	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...
367
368
  		return -EINVAL;
  	return len;
fd95e81cb   Steven Whitehouse   GFS2: Reinstate w...
369
  }
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
370
371
372
373
374
375
  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...
376
377
378
379
380
381
382
383
  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...
384
385
386
  	rv = wait_for_completion_killable(&sdp->sd_locking_init);
  	if (rv)
  		return rv;
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
387
388
389
390
391
392
393
394
395
  	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...
396
397
  	sdp->sd_lockstruct.ls_first = first;
  	rv = 0;
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
398
399
400
401
  out:
          spin_unlock(&sdp->sd_jindex_spin);
          return rv ? rv : len;
  }
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
402
403
404
  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...
405
406
  	return sprintf(buf, "%d
  ", !!test_bit(DFL_FIRST_MOUNT_DONE, &ls->ls_recover_flags));
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
407
  }
e0c2a9aa1   David Teigland   GFS2: dlm based r...
408
  int gfs2_recover_set(struct gfs2_sbd *sdp, unsigned jid)
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
409
410
  {
  	struct gfs2_jdesc *jd;
fe64d517d   Steven Whitehouse   GFS2: Umount reco...
411
  	int rv;
0e48e055a   Bob Peterson   GFS2: Prevent rec...
412
413
  	/* Wait for our primary journal to be initialized */
  	wait_for_completion(&sdp->sd_journal_ready);
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
414
  	spin_lock(&sdp->sd_jindex_spin);
fe64d517d   Steven Whitehouse   GFS2: Umount reco...
415
416
417
418
  	rv = -EBUSY;
  	if (sdp->sd_jdesc->jd_jid == jid)
  		goto out;
  	rv = -ENOENT;
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
419
420
421
  	list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) {
  		if (jd->jd_jid != jid)
  			continue;
6ecd7c2dd   Tejun Heo   gfs2: use workque...
422
  		rv = gfs2_recover_journal(jd, false);
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
423
424
  		break;
  	}
fe64d517d   Steven Whitehouse   GFS2: Umount reco...
425
  out:
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
426
  	spin_unlock(&sdp->sd_jindex_spin);
e0c2a9aa1   David Teigland   GFS2: dlm based r...
427
428
429
430
431
432
433
434
435
436
437
  	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...
438
439
440
441
  	if (test_bit(SDF_NORECOVERY, &sdp->sd_flags)) {
  		rv = -ESHUTDOWN;
  		goto out;
  	}
e0c2a9aa1   David Teigland   GFS2: dlm based r...
442

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

d7e623da1   Steven Whitehouse   GFS2: Fix permiss...
497
498
  GDLM_ATTR(proto_name,		0444, proto_name_show,		NULL);
  GDLM_ATTR(block,		0644, block_show,		block_store);
fd95e81cb   Steven Whitehouse   GFS2: Reinstate w...
499
  GDLM_ATTR(withdraw,		0644, wdack_show,		wdack_store);
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
500
501
  GDLM_ATTR(jid,			0644, jid_show,			jid_store);
  GDLM_ATTR(first,		0644, lkfirst_show,		lkfirst_store);
d7e623da1   Steven Whitehouse   GFS2: Fix permiss...
502
503
504
505
  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_...
506
507
508
509
510
  
  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...
511
  	&gdlm_attr_jid.attr,
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
512
513
514
515
516
  	&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...
517
  	NULL,
b3b94faa5   David Teigland   [GFS2] The core o...
518
  };
b3b94faa5   David Teigland   [GFS2] The core o...
519
  /*
b3b94faa5   David Teigland   [GFS2] The core o...
520
521
522
523
524
   * 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...
525
526
527
528
  	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...
529
530
531
532
533
534
535
536
537
  }
  
  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...
538
  		return -EPERM;
b3b94faa5   David Teigland   [GFS2] The core o...
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
  
  	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...
555
  	int error;
b3b94faa5   David Teigland   [GFS2] The core o...
556
557
  
  	if (!capable(CAP_SYS_ADMIN))
417358187   Zhao Hongjiang   fs: change return...
558
  		return -EPERM;
b3b94faa5   David Teigland   [GFS2] The core o...
559

e50ead480   Fabian Frederick   gfs2: convert sim...
560
561
562
  	error = kstrtouint(buf, 0, &x);
  	if (error)
  		return error;
b3b94faa5   David Teigland   [GFS2] The core o...
563
564
565
566
567
568
569
570
571
  
  	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...
572
  #define TUNE_ATTR_3(name, show, store)                                        \
48c2b6136   Steven Whitehouse   GFS2: Add commit=...
573
  static struct gfs2_attr tune_attr_##name = __ATTR(name, 0644, show, store)
b3b94faa5   David Teigland   [GFS2] The core o...
574
575
576
577
  
  #define TUNE_ATTR_2(name, store)                                              \
  static ssize_t name##_show(struct gfs2_sbd *sdp, char *buf)                   \
  {                                                                             \
3204a6c05   David Teigland   [GFS2] use snprin...
578
579
  	return snprintf(buf, PAGE_SIZE, "%u
  ", sdp->sd_tune.gt_##name);      \
b3b94faa5   David Teigland   [GFS2] The core o...
580
581
582
583
584
585
586
587
588
  }                                                                             \
  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...
589
590
  TUNE_ATTR(quota_warn_period, 0);
  TUNE_ATTR(quota_quantum, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
591
592
  TUNE_ATTR(max_readahead, 0);
  TUNE_ATTR(complain_secs, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
593
594
  TUNE_ATTR(statfs_slow, 0);
  TUNE_ATTR(new_files_jdata, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
595
  TUNE_ATTR(statfs_quantum, 1);
b3b94faa5   David Teigland   [GFS2] The core o...
596
597
598
  TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store);
  
  static struct attribute *tune_attrs[] = {
b3b94faa5   David Teigland   [GFS2] The core o...
599
600
  	&tune_attr_quota_warn_period.attr,
  	&tune_attr_quota_quantum.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
601
602
  	&tune_attr_max_readahead.attr,
  	&tune_attr_complain_secs.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
603
  	&tune_attr_statfs_slow.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
604
  	&tune_attr_statfs_quantum.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
605
606
  	&tune_attr_quota_scale.attr,
  	&tune_attr_new_files_jdata.attr,
ea67eedb2   Steven Whitehouse   [GFS2] Fix end of...
607
  	NULL,
b3b94faa5   David Teigland   [GFS2] The core o...
608
  };
29695254e   Arvind Yadav   GFS2: constify at...
609
  static const struct attribute_group tune_group = {
b3b94faa5   David Teigland   [GFS2] The core o...
610
  	.name = "tune",
ea67eedb2   Steven Whitehouse   [GFS2] Fix end of...
611
  	.attrs = tune_attrs,
b3b94faa5   David Teigland   [GFS2] The core o...
612
  };
29695254e   Arvind Yadav   GFS2: constify at...
613
  static const struct attribute_group lock_module_group = {
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
614
615
616
  	.name = "lock_module",
  	.attrs = lock_module_attrs,
  };
b3b94faa5   David Teigland   [GFS2] The core o...
617
618
  int gfs2_sys_fs_add(struct gfs2_sbd *sdp)
  {
440d6da20   Steven Whitehouse   GFS2: Add some mo...
619
  	struct super_block *sb = sdp->sd_vfs;
b3b94faa5   David Teigland   [GFS2] The core o...
620
  	int error;
440d6da20   Steven Whitehouse   GFS2: Add some mo...
621
622
623
  	char ro[20];
  	char spectator[20];
  	char *envp[] = { ro, spectator, NULL };
0d515210b   Bob Peterson   GFS2: Add kobject...
624
  	int sysfs_frees_sdp = 0;
440d6da20   Steven Whitehouse   GFS2: Add some mo...
625

bc98a42c1   David Howells   VFS: Convert sb->...
626
  	sprintf(ro, "RDONLY=%d", sb_rdonly(sb));
440d6da20   Steven Whitehouse   GFS2: Add some mo...
627
  	sprintf(spectator, "SPECTATOR=%d", sdp->sd_args.ar_spectator ? 1 : 0);
b3b94faa5   David Teigland   [GFS2] The core o...
628

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

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

f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
641
642
643
  	error = sysfs_create_group(&sdp->sd_kobj, &lock_module_group);
  	if (error)
  		goto fail_tune;
31e54b01f   Steven Whitehouse   GFS2: Add sysfs l...
644
645
646
647
648
  	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...
649
  	kobject_uevent_env(&sdp->sd_kobj, KOBJ_ADD, envp);
b3b94faa5   David Teigland   [GFS2] The core o...
650
  	return 0;
31e54b01f   Steven Whitehouse   GFS2: Add sysfs l...
651
652
  fail_lock_module:
  	sysfs_remove_group(&sdp->sd_kobj, &lock_module_group);
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
653
654
  fail_tune:
  	sysfs_remove_group(&sdp->sd_kobj, &tune_group);
a91ea69ff   Steven Whitehouse   [GFS2] Align all ...
655
  fail_reg:
0d515210b   Bob Peterson   GFS2: Add kobject...
656
  	free_percpu(sdp->sd_lkstats);
65952fb4e   David Teigland   [GFS2] print moun...
657
  	fs_err(sdp, "error %d adding sysfs files", error);
0d515210b   Bob Peterson   GFS2: Add kobject...
658
659
660
661
662
  	if (sysfs_frees_sdp)
  		kobject_put(&sdp->sd_kobj);
  	else
  		kfree(sdp);
  	sb->s_fs_info = NULL;
b3b94faa5   David Teigland   [GFS2] The core o...
663
664
665
666
667
  	return error;
  }
  
  void gfs2_sys_fs_del(struct gfs2_sbd *sdp)
  {
31e54b01f   Steven Whitehouse   GFS2: Add sysfs l...
668
  	sysfs_remove_link(&sdp->sd_kobj, "device");
b3b94faa5   David Teigland   [GFS2] The core o...
669
  	sysfs_remove_group(&sdp->sd_kobj, &tune_group);
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
670
  	sysfs_remove_group(&sdp->sd_kobj, &lock_module_group);
197b12d67   Greg Kroah-Hartman   Kobject: convert ...
671
  	kobject_put(&sdp->sd_kobj);
b3b94faa5   David Teigland   [GFS2] The core o...
672
  }
fdd1062eb   Steven Whitehouse   GFS2: Send some s...
673
674
675
676
  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...
677
  	struct super_block *s = sdp->sd_vfs;
02e3cc70e   Steven Whitehouse   GFS2: Expose UUID...
678

fdd1062eb   Steven Whitehouse   GFS2: Send some s...
679
680
  	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...
681
  	if (!test_bit(SDF_NOJOURNALID, &sdp->sd_flags))
feb47ca93   Steven Whitehouse   GFS2: Improve jou...
682
  		add_uevent_var(env, "JOURNALID=%d", sdp->sd_lockstruct.ls_jid);
85787090a   Christoph Hellwig   fs: switch ->s_uu...
683
684
  	if (!uuid_is_null(&s->s_uuid))
  		add_uevent_var(env, "UUID=%pUB", &s->s_uuid);
fdd1062eb   Steven Whitehouse   GFS2: Send some s...
685
686
  	return 0;
  }
9cd43611c   Emese Revfy   kobject: Constify...
687
  static const struct kset_uevent_ops gfs2_uevent_ops = {
fdd1062eb   Steven Whitehouse   GFS2: Send some s...
688
689
  	.uevent = gfs2_uevent,
  };
b3b94faa5   David Teigland   [GFS2] The core o...
690
691
  int gfs2_sys_init(void)
  {
fdd1062eb   Steven Whitehouse   GFS2: Send some s...
692
  	gfs2_kset = kset_create_and_add("gfs2", &gfs2_uevent_ops, fs_kobj);
9bec101a0   Greg Kroah-Hartman   kset: convert gfs...
693
694
695
  	if (!gfs2_kset)
  		return -ENOMEM;
  	return 0;
b3b94faa5   David Teigland   [GFS2] The core o...
696
697
698
699
  }
  
  void gfs2_sys_uninit(void)
  {
9bec101a0   Greg Kroah-Hartman   kset: convert gfs...
700
  	kset_unregister(gfs2_kset);
b3b94faa5   David Teigland   [GFS2] The core o...
701
  }