Blame view

fs/gfs2/sys.c 16.1 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
9
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
93
  static ssize_t freeze_show(struct gfs2_sbd *sdp, char *buf)
  {
  	unsigned int count;
f55ab26a8   Steven Whitehouse   [GFS2] Use mutice...
94
  	mutex_lock(&sdp->sd_freeze_lock);
b3b94faa5   David Teigland   [GFS2] The core o...
95
  	count = sdp->sd_freeze_count;
f55ab26a8   Steven Whitehouse   [GFS2] Use mutice...
96
  	mutex_unlock(&sdp->sd_freeze_lock);
b3b94faa5   David Teigland   [GFS2] The core o...
97

3204a6c05   David Teigland   [GFS2] use snprin...
98
99
  	return snprintf(buf, PAGE_SIZE, "%u
  ", count);
b3b94faa5   David Teigland   [GFS2] The core o...
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
  }
  
  static ssize_t freeze_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
  {
  	ssize_t ret = len;
  	int error = 0;
  	int n = simple_strtol(buf, NULL, 0);
  
  	if (!capable(CAP_SYS_ADMIN))
  		return -EACCES;
  
  	switch (n) {
  	case 0:
  		gfs2_unfreeze_fs(sdp);
  		break;
  	case 1:
  		error = gfs2_freeze_fs(sdp);
  		break;
  	default:
  		ret = -EINVAL;
  	}
  
  	if (error)
  		fs_warn(sdp, "freeze %d error %d", n, error);
  
  	return ret;
  }
  
  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...
131
132
  	return snprintf(buf, PAGE_SIZE, "%u
  ", b);
b3b94faa5   David Teigland   [GFS2] The core o...
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
  }
  
  static ssize_t withdraw_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
  {
  	if (!capable(CAP_SYS_ADMIN))
  		return -EACCES;
  
  	if (simple_strtol(buf, NULL, 0) != 1)
  		return -EINVAL;
  
  	gfs2_lm_withdraw(sdp,
  		"GFS2: fsid=%s: withdrawing from cluster at user's request
  ",
  		sdp->sd_fsname);
  	return len;
  }
  
  static ssize_t statfs_sync_store(struct gfs2_sbd *sdp, const char *buf,
  				 size_t len)
  {
  	if (!capable(CAP_SYS_ADMIN))
  		return -EACCES;
  
  	if (simple_strtol(buf, NULL, 0) != 1)
  		return -EINVAL;
8c42d637f   Steven Whitehouse   GFS2: Alter argum...
158
  	gfs2_statfs_sync(sdp->sd_vfs, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
159
160
  	return len;
  }
b3b94faa5   David Teigland   [GFS2] The core o...
161
162
163
164
165
166
167
168
  static ssize_t quota_sync_store(struct gfs2_sbd *sdp, const char *buf,
  				size_t len)
  {
  	if (!capable(CAP_SYS_ADMIN))
  		return -EACCES;
  
  	if (simple_strtol(buf, NULL, 0) != 1)
  		return -EINVAL;
5fb324ad2   Christoph Hellwig   quota: move code ...
169
  	gfs2_quota_sync(sdp->sd_vfs, 0, 1);
b3b94faa5   David Teigland   [GFS2] The core o...
170
171
172
173
174
175
  	return len;
  }
  
  static ssize_t quota_refresh_user_store(struct gfs2_sbd *sdp, const char *buf,
  					size_t len)
  {
ea7623385   Steven Whitehouse   GFS2: Add proper ...
176
  	int error;
cd915493f   Steven Whitehouse   [GFS2] Change all...
177
  	u32 id;
b3b94faa5   David Teigland   [GFS2] The core o...
178
179
180
181
182
  
  	if (!capable(CAP_SYS_ADMIN))
  		return -EACCES;
  
  	id = simple_strtoul(buf, NULL, 0);
ea7623385   Steven Whitehouse   GFS2: Add proper ...
183
184
  	error = gfs2_quota_refresh(sdp, 1, id);
  	return error ? error : len;
b3b94faa5   David Teigland   [GFS2] The core o...
185
186
187
188
189
  }
  
  static ssize_t quota_refresh_group_store(struct gfs2_sbd *sdp, const char *buf,
  					 size_t len)
  {
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
194
195
196
  
  	if (!capable(CAP_SYS_ADMIN))
  		return -EACCES;
  
  	id = simple_strtoul(buf, NULL, 0);
ea7623385   Steven Whitehouse   GFS2: Add proper ...
197
198
  	error = gfs2_quota_refresh(sdp, 0, id);
  	return error ? error : len;
b3b94faa5   David Teigland   [GFS2] The core o...
199
  }
64d576ba2   Steven Whitehouse   GFS2: Add a "demo...
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
  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))
  		return -EACCES;
  
  	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;
134669854   Steven Whitehouse   GFS2: Fix type ma...
229
230
231
232
  	if (gltype == LM_TYPE_NONDISK && glnum == GFS2_TRANS_LOCK)
  		glops = &gfs2_trans_glops;
  	else
  		glops = gfs2_glops_list[gltype];
64d576ba2   Steven Whitehouse   GFS2: Add a "demo...
233
234
  	if (glops == NULL)
  		return -EINVAL;
6a99be5d7   Steven Whitehouse   GFS2: Fix typo
235
  	if (!test_and_set_bit(SDF_DEMOTE, &sdp->sd_flags))
913a71d25   Steven Whitehouse   GFS2: Add some us...
236
237
  		fs_info(sdp, "demote interface used
  ");
64d576ba2   Steven Whitehouse   GFS2: Add a "demo...
238
239
240
241
242
243
244
  	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...
245
246
247
248
249
250
  
  #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...
251
  GFS2_ATTR(uuid,                0444, uuid_show,     NULL);
b3b94faa5   David Teigland   [GFS2] The core o...
252
  GFS2_ATTR(freeze,              0644, freeze_show,   freeze_store);
b3b94faa5   David Teigland   [GFS2] The core o...
253
254
255
256
257
  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...
258
  GFS2_ATTR(demote_rq,           0200, NULL,	    demote_rq_store);
b3b94faa5   David Teigland   [GFS2] The core o...
259
260
261
262
  
  static struct attribute *gfs2_attrs[] = {
  	&gfs2_attr_id.attr,
  	&gfs2_attr_fsname.attr,
02e3cc70e   Steven Whitehouse   GFS2: Expose UUID...
263
  	&gfs2_attr_uuid.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
264
  	&gfs2_attr_freeze.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
265
266
267
268
269
  	&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...
270
  	&gfs2_attr_demote_rq.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
271
272
  	NULL,
  };
b3b94faa5   David Teigland   [GFS2] The core o...
273
274
275
276
  static struct kobj_type gfs2_ktype = {
  	.default_attrs = gfs2_attrs,
  	.sysfs_ops     = &gfs2_attr_ops,
  };
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
  
  /*
   * 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;
  
  	if (test_bit(DFL_BLOCK_LOCKS, &ls->ls_flags))
  		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;
  	ssize_t ret = len;
  	int val;
  
  	val = simple_strtol(buf, NULL, 0);
  
  	if (val == 1)
  		set_bit(DFL_BLOCK_LOCKS, &ls->ls_flags);
  	else if (val == 0) {
  		clear_bit(DFL_BLOCK_LOCKS, &ls->ls_flags);
  		smp_mb__after_clear_bit();
  		gfs2_glock_thaw(sdp);
  	} else {
  		ret = -EINVAL;
  	}
  	return ret;
  }
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
321
322
323
324
325
326
  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...
327
328
329
330
331
332
333
334
  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...
335
336
337
  	rv = wait_for_completion_killable(&sdp->sd_locking_init);
  	if (rv)
  		return rv;
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
  	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;
          sdp->sd_lockstruct.ls_first = first;
          rv = 0;
  out:
          spin_unlock(&sdp->sd_jindex_spin);
          return rv ? rv : len;
  }
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
353
354
355
356
357
358
  static ssize_t first_done_show(struct gfs2_sbd *sdp, char *buf)
  {
  	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
  	return sprintf(buf, "%d
  ", ls->ls_first_done);
  }
fe64d517d   Steven Whitehouse   GFS2: Umount reco...
359
  static ssize_t recover_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
360
  {
fe64d517d   Steven Whitehouse   GFS2: Umount reco...
361
  	unsigned jid;
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
362
  	struct gfs2_jdesc *jd;
fe64d517d   Steven Whitehouse   GFS2: Umount reco...
363
364
365
366
367
  	int rv;
  
  	rv = sscanf(buf, "%u", &jid);
  	if (rv != 1)
  		return -EINVAL;
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
368

fe64d517d   Steven Whitehouse   GFS2: Umount reco...
369
  	rv = -ESHUTDOWN;
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
370
  	spin_lock(&sdp->sd_jindex_spin);
fe64d517d   Steven Whitehouse   GFS2: Umount reco...
371
372
373
374
375
376
  	if (test_bit(SDF_NORECOVERY, &sdp->sd_flags))
  		goto out;
  	rv = -EBUSY;
  	if (sdp->sd_jdesc->jd_jid == jid)
  		goto out;
  	rv = -ENOENT;
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
377
378
379
  	list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) {
  		if (jd->jd_jid != jid)
  			continue;
6ecd7c2dd   Tejun Heo   gfs2: use workque...
380
  		rv = gfs2_recover_journal(jd, false);
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
381
382
  		break;
  	}
fe64d517d   Steven Whitehouse   GFS2: Umount reco...
383
  out:
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
384
  	spin_unlock(&sdp->sd_jindex_spin);
fe64d517d   Steven Whitehouse   GFS2: Umount reco...
385
  	return rv ? rv : len;
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
  }
  
  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...
401
402
  static ssize_t jid_show(struct gfs2_sbd *sdp, char *buf)
  {
feb47ca93   Steven Whitehouse   GFS2: Improve jou...
403
404
  	return sprintf(buf, "%d
  ", sdp->sd_lockstruct.ls_jid);
e1b28aab5   Steven Whitehouse   GFS2: Remove lock...
405
  }
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
406
407
  static ssize_t jid_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
  {
feb47ca93   Steven Whitehouse   GFS2: Improve jou...
408
          int jid;
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
409
  	int rv;
feb47ca93   Steven Whitehouse   GFS2: Improve jou...
410
  	rv = sscanf(buf, "%d", &jid);
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
411
412
  	if (rv != 1)
  		return -EINVAL;
3942ae531   Steven Whitehouse   GFS2: Fix race du...
413
414
415
  	rv = wait_for_completion_killable(&sdp->sd_locking_init);
  	if (rv)
  		return rv;
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
416
417
  	spin_lock(&sdp->sd_jindex_spin);
  	rv = -EINVAL;
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
418
419
420
  	if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL)
  		goto out;
  	rv = -EBUSY;
feb47ca93   Steven Whitehouse   GFS2: Improve jou...
421
  	if (test_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0)
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
422
  		goto out;
feb47ca93   Steven Whitehouse   GFS2: Improve jou...
423
424
425
  	rv = 0;
  	if (sdp->sd_args.ar_spectator && jid > 0)
  		rv = jid = -EINVAL;
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
426
  	sdp->sd_lockstruct.ls_jid = jid;
feb47ca93   Steven Whitehouse   GFS2: Improve jou...
427
  	clear_bit(SDF_NOJOURNALID, &sdp->sd_flags);
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
428
429
  	smp_mb__after_clear_bit();
  	wake_up_bit(&sdp->sd_flags, SDF_NOJOURNALID);
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
430
431
432
433
  out:
  	spin_unlock(&sdp->sd_jindex_spin);
  	return rv ? rv : len;
  }
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
434
  #define GDLM_ATTR(_name,_mode,_show,_store) \
48c2b6136   Steven Whitehouse   GFS2: Add commit=...
435
  static struct gfs2_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store)
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
436

d7e623da1   Steven Whitehouse   GFS2: Fix permiss...
437
438
439
  GDLM_ATTR(proto_name,		0444, proto_name_show,		NULL);
  GDLM_ATTR(block,		0644, block_show,		block_store);
  GDLM_ATTR(withdraw,		0644, withdraw_show,		withdraw_store);
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
440
441
  GDLM_ATTR(jid,			0644, jid_show,			jid_store);
  GDLM_ATTR(first,		0644, lkfirst_show,		lkfirst_store);
d7e623da1   Steven Whitehouse   GFS2: Fix permiss...
442
443
444
445
  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_...
446
447
448
449
450
  
  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...
451
  	&gdlm_attr_jid.attr,
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
452
453
454
455
456
  	&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...
457
  	NULL,
b3b94faa5   David Teigland   [GFS2] The core o...
458
  };
b3b94faa5   David Teigland   [GFS2] The core o...
459
  /*
b3b94faa5   David Teigland   [GFS2] The core o...
460
461
462
463
464
   * 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...
465
466
467
468
  	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...
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
  }
  
  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))
  		return -EACCES;
  
  	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;
  
  	if (!capable(CAP_SYS_ADMIN))
  		return -EACCES;
  
  	x = simple_strtoul(buf, NULL, 0);
  
  	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...
509
  #define TUNE_ATTR_3(name, show, store)                                        \
48c2b6136   Steven Whitehouse   GFS2: Add commit=...
510
  static struct gfs2_attr tune_attr_##name = __ATTR(name, 0644, show, store)
b3b94faa5   David Teigland   [GFS2] The core o...
511
512
513
514
  
  #define TUNE_ATTR_2(name, store)                                              \
  static ssize_t name##_show(struct gfs2_sbd *sdp, char *buf)                   \
  {                                                                             \
3204a6c05   David Teigland   [GFS2] use snprin...
515
516
  	return snprintf(buf, PAGE_SIZE, "%u
  ", sdp->sd_tune.gt_##name);      \
b3b94faa5   David Teigland   [GFS2] The core o...
517
518
519
520
521
522
523
524
525
  }                                                                             \
  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...
526
527
  TUNE_ATTR(quota_warn_period, 0);
  TUNE_ATTR(quota_quantum, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
528
529
  TUNE_ATTR(max_readahead, 0);
  TUNE_ATTR(complain_secs, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
530
531
  TUNE_ATTR(statfs_slow, 0);
  TUNE_ATTR(new_files_jdata, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
532
  TUNE_ATTR(quota_simul_sync, 1);
b3b94faa5   David Teigland   [GFS2] The core o...
533
  TUNE_ATTR(statfs_quantum, 1);
b3b94faa5   David Teigland   [GFS2] The core o...
534
535
536
  TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store);
  
  static struct attribute *tune_attrs[] = {
b3b94faa5   David Teigland   [GFS2] The core o...
537
538
  	&tune_attr_quota_warn_period.attr,
  	&tune_attr_quota_quantum.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
539
540
  	&tune_attr_max_readahead.attr,
  	&tune_attr_complain_secs.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
541
542
  	&tune_attr_statfs_slow.attr,
  	&tune_attr_quota_simul_sync.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
543
  	&tune_attr_statfs_quantum.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
544
545
  	&tune_attr_quota_scale.attr,
  	&tune_attr_new_files_jdata.attr,
ea67eedb2   Steven Whitehouse   [GFS2] Fix end of...
546
  	NULL,
b3b94faa5   David Teigland   [GFS2] The core o...
547
  };
b3b94faa5   David Teigland   [GFS2] The core o...
548
549
  static struct attribute_group tune_group = {
  	.name = "tune",
ea67eedb2   Steven Whitehouse   [GFS2] Fix end of...
550
  	.attrs = tune_attrs,
b3b94faa5   David Teigland   [GFS2] The core o...
551
  };
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
552
553
554
555
  static struct attribute_group lock_module_group = {
  	.name = "lock_module",
  	.attrs = lock_module_attrs,
  };
b3b94faa5   David Teigland   [GFS2] The core o...
556
557
  int gfs2_sys_fs_add(struct gfs2_sbd *sdp)
  {
440d6da20   Steven Whitehouse   GFS2: Add some mo...
558
  	struct super_block *sb = sdp->sd_vfs;
b3b94faa5   David Teigland   [GFS2] The core o...
559
  	int error;
440d6da20   Steven Whitehouse   GFS2: Add some mo...
560
561
562
563
564
565
  	char ro[20];
  	char spectator[20];
  	char *envp[] = { ro, spectator, NULL };
  
  	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...
566

9bec101a0   Greg Kroah-Hartman   kset: convert gfs...
567
  	sdp->sd_kobj.kset = gfs2_kset;
901195ed7   Greg Kroah-Hartman   Kobject: change G...
568
569
  	error = kobject_init_and_add(&sdp->sd_kobj, &gfs2_ktype, NULL,
  				     "%s", sdp->sd_table_name);
b3b94faa5   David Teigland   [GFS2] The core o...
570
571
  	if (error)
  		goto fail;
b3b94faa5   David Teigland   [GFS2] The core o...
572
573
  	error = sysfs_create_group(&sdp->sd_kobj, &tune_group);
  	if (error)
f6eb53498   Steven Whitehouse   GFS2: Remove args...
574
  		goto fail_reg;
b3b94faa5   David Teigland   [GFS2] The core o...
575

f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
576
577
578
  	error = sysfs_create_group(&sdp->sd_kobj, &lock_module_group);
  	if (error)
  		goto fail_tune;
31e54b01f   Steven Whitehouse   GFS2: Add sysfs l...
579
580
581
582
583
  	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...
584
  	kobject_uevent_env(&sdp->sd_kobj, KOBJ_ADD, envp);
b3b94faa5   David Teigland   [GFS2] The core o...
585
  	return 0;
31e54b01f   Steven Whitehouse   GFS2: Add sysfs l...
586
587
  fail_lock_module:
  	sysfs_remove_group(&sdp->sd_kobj, &lock_module_group);
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
588
589
  fail_tune:
  	sysfs_remove_group(&sdp->sd_kobj, &tune_group);
a91ea69ff   Steven Whitehouse   [GFS2] Align all ...
590
  fail_reg:
197b12d67   Greg Kroah-Hartman   Kobject: convert ...
591
  	kobject_put(&sdp->sd_kobj);
a91ea69ff   Steven Whitehouse   [GFS2] Align all ...
592
  fail:
65952fb4e   David Teigland   [GFS2] print moun...
593
  	fs_err(sdp, "error %d adding sysfs files", error);
b3b94faa5   David Teigland   [GFS2] The core o...
594
595
596
597
598
  	return error;
  }
  
  void gfs2_sys_fs_del(struct gfs2_sbd *sdp)
  {
31e54b01f   Steven Whitehouse   GFS2: Add sysfs l...
599
  	sysfs_remove_link(&sdp->sd_kobj, "device");
b3b94faa5   David Teigland   [GFS2] The core o...
600
  	sysfs_remove_group(&sdp->sd_kobj, &tune_group);
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
601
  	sysfs_remove_group(&sdp->sd_kobj, &lock_module_group);
197b12d67   Greg Kroah-Hartman   Kobject: convert ...
602
  	kobject_put(&sdp->sd_kobj);
b3b94faa5   David Teigland   [GFS2] The core o...
603
  }
fdd1062eb   Steven Whitehouse   GFS2: Send some s...
604
605
606
607
  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...
608
609
  	struct super_block *s = sdp->sd_vfs;
  	const u8 *uuid = s->s_uuid;
02e3cc70e   Steven Whitehouse   GFS2: Expose UUID...
610

fdd1062eb   Steven Whitehouse   GFS2: Send some s...
611
612
  	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...
613
  	if (!test_bit(SDF_NOJOURNALID, &sdp->sd_flags))
feb47ca93   Steven Whitehouse   GFS2: Improve jou...
614
  		add_uevent_var(env, "JOURNALID=%d", sdp->sd_lockstruct.ls_jid);
f0b34ae63   Joe Perches   fs/gfs2/sys.c: us...
615
616
  	if (gfs2_uuid_valid(uuid))
  		add_uevent_var(env, "UUID=%pUB", uuid);
fdd1062eb   Steven Whitehouse   GFS2: Send some s...
617
618
  	return 0;
  }
9cd43611c   Emese Revfy   kobject: Constify...
619
  static const struct kset_uevent_ops gfs2_uevent_ops = {
fdd1062eb   Steven Whitehouse   GFS2: Send some s...
620
621
  	.uevent = gfs2_uevent,
  };
b3b94faa5   David Teigland   [GFS2] The core o...
622
623
  int gfs2_sys_init(void)
  {
fdd1062eb   Steven Whitehouse   GFS2: Send some s...
624
  	gfs2_kset = kset_create_and_add("gfs2", &gfs2_uevent_ops, fs_kobj);
9bec101a0   Greg Kroah-Hartman   kset: convert gfs...
625
626
627
  	if (!gfs2_kset)
  		return -ENOMEM;
  	return 0;
b3b94faa5   David Teigland   [GFS2] The core o...
628
629
630
631
  }
  
  void gfs2_sys_uninit(void)
  {
9bec101a0   Greg Kroah-Hartman   kset: convert gfs...
632
  	kset_unregister(gfs2_kset);
b3b94faa5   David Teigland   [GFS2] The core o...
633
  }