Blame view

fs/gfs2/sys.c 16.3 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
  
  /*
   * 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...
294
  	if (test_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags))
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
  		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)
e0c2a9aa1   David Teigland   GFS2: dlm based r...
310
  		set_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags);
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
311
  	else if (val == 0) {
e0c2a9aa1   David Teigland   GFS2: dlm based r...
312
  		clear_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags);
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
313
314
315
316
317
318
319
  		smp_mb__after_clear_bit();
  		gfs2_glock_thaw(sdp);
  	} else {
  		ret = -EINVAL;
  	}
  	return ret;
  }
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
320
321
322
323
324
325
  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...
326
327
328
329
330
331
332
333
  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...
334
335
336
  	rv = wait_for_completion_killable(&sdp->sd_locking_init);
  	if (rv)
  		return rv;
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
337
338
339
340
341
342
343
344
345
  	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...
346
347
  	sdp->sd_lockstruct.ls_first = first;
  	rv = 0;
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
348
349
350
351
  out:
          spin_unlock(&sdp->sd_jindex_spin);
          return rv ? rv : len;
  }
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
352
353
354
  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...
355
356
  	return sprintf(buf, "%d
  ", !!test_bit(DFL_FIRST_MOUNT_DONE, &ls->ls_recover_flags));
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
357
  }
e0c2a9aa1   David Teigland   GFS2: dlm based r...
358
  int gfs2_recover_set(struct gfs2_sbd *sdp, unsigned jid)
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
359
360
  {
  	struct gfs2_jdesc *jd;
fe64d517d   Steven Whitehouse   GFS2: Umount reco...
361
  	int rv;
fe64d517d   Steven Whitehouse   GFS2: Umount reco...
362
  	rv = -ESHUTDOWN;
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
363
  	spin_lock(&sdp->sd_jindex_spin);
fe64d517d   Steven Whitehouse   GFS2: Umount reco...
364
365
366
367
368
369
  	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_...
370
371
372
  	list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) {
  		if (jd->jd_jid != jid)
  			continue;
6ecd7c2dd   Tejun Heo   gfs2: use workque...
373
  		rv = gfs2_recover_journal(jd, false);
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
374
375
  		break;
  	}
fe64d517d   Steven Whitehouse   GFS2: Umount reco...
376
  out:
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
377
  	spin_unlock(&sdp->sd_jindex_spin);
e0c2a9aa1   David Teigland   GFS2: dlm based r...
378
379
380
381
382
383
384
385
386
387
388
389
390
  	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;
  
  	rv = gfs2_recover_set(sdp, jid);
fe64d517d   Steven Whitehouse   GFS2: Umount reco...
391
  	return rv ? rv : len;
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
  }
  
  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...
407
408
  static ssize_t jid_show(struct gfs2_sbd *sdp, char *buf)
  {
feb47ca93   Steven Whitehouse   GFS2: Improve jou...
409
410
  	return sprintf(buf, "%d
  ", sdp->sd_lockstruct.ls_jid);
e1b28aab5   Steven Whitehouse   GFS2: Remove lock...
411
  }
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
412
413
  static ssize_t jid_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
  {
feb47ca93   Steven Whitehouse   GFS2: Improve jou...
414
          int jid;
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
415
  	int rv;
feb47ca93   Steven Whitehouse   GFS2: Improve jou...
416
  	rv = sscanf(buf, "%d", &jid);
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
417
418
  	if (rv != 1)
  		return -EINVAL;
3942ae531   Steven Whitehouse   GFS2: Fix race du...
419
420
421
  	rv = wait_for_completion_killable(&sdp->sd_locking_init);
  	if (rv)
  		return rv;
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
422
423
  	spin_lock(&sdp->sd_jindex_spin);
  	rv = -EINVAL;
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
424
425
426
  	if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL)
  		goto out;
  	rv = -EBUSY;
feb47ca93   Steven Whitehouse   GFS2: Improve jou...
427
  	if (test_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0)
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
428
  		goto out;
feb47ca93   Steven Whitehouse   GFS2: Improve jou...
429
430
431
  	rv = 0;
  	if (sdp->sd_args.ar_spectator && jid > 0)
  		rv = jid = -EINVAL;
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
432
  	sdp->sd_lockstruct.ls_jid = jid;
feb47ca93   Steven Whitehouse   GFS2: Improve jou...
433
  	clear_bit(SDF_NOJOURNALID, &sdp->sd_flags);
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
434
435
  	smp_mb__after_clear_bit();
  	wake_up_bit(&sdp->sd_flags, SDF_NOJOURNALID);
ba6e93645   Steven Whitehouse   GFS2: Wait for jo...
436
437
438
439
  out:
  	spin_unlock(&sdp->sd_jindex_spin);
  	return rv ? rv : len;
  }
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
440
  #define GDLM_ATTR(_name,_mode,_show,_store) \
48c2b6136   Steven Whitehouse   GFS2: Add commit=...
441
  static struct gfs2_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store)
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
442

d7e623da1   Steven Whitehouse   GFS2: Fix permiss...
443
444
445
  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...
446
447
  GDLM_ATTR(jid,			0644, jid_show,			jid_store);
  GDLM_ATTR(first,		0644, lkfirst_show,		lkfirst_store);
d7e623da1   Steven Whitehouse   GFS2: Fix permiss...
448
449
450
451
  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_...
452
453
454
455
456
  
  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...
457
  	&gdlm_attr_jid.attr,
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
458
459
460
461
462
  	&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...
463
  	NULL,
b3b94faa5   David Teigland   [GFS2] The core o...
464
  };
b3b94faa5   David Teigland   [GFS2] The core o...
465
  /*
b3b94faa5   David Teigland   [GFS2] The core o...
466
467
468
469
470
   * 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...
471
472
473
474
  	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...
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
509
510
511
512
513
514
  }
  
  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...
515
  #define TUNE_ATTR_3(name, show, store)                                        \
48c2b6136   Steven Whitehouse   GFS2: Add commit=...
516
  static struct gfs2_attr tune_attr_##name = __ATTR(name, 0644, show, store)
b3b94faa5   David Teigland   [GFS2] The core o...
517
518
519
520
  
  #define TUNE_ATTR_2(name, store)                                              \
  static ssize_t name##_show(struct gfs2_sbd *sdp, char *buf)                   \
  {                                                                             \
3204a6c05   David Teigland   [GFS2] use snprin...
521
522
  	return snprintf(buf, PAGE_SIZE, "%u
  ", sdp->sd_tune.gt_##name);      \
b3b94faa5   David Teigland   [GFS2] The core o...
523
524
525
526
527
528
529
530
531
  }                                                                             \
  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...
532
533
  TUNE_ATTR(quota_warn_period, 0);
  TUNE_ATTR(quota_quantum, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
534
535
  TUNE_ATTR(max_readahead, 0);
  TUNE_ATTR(complain_secs, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
536
537
  TUNE_ATTR(statfs_slow, 0);
  TUNE_ATTR(new_files_jdata, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
538
  TUNE_ATTR(quota_simul_sync, 1);
b3b94faa5   David Teigland   [GFS2] The core o...
539
  TUNE_ATTR(statfs_quantum, 1);
b3b94faa5   David Teigland   [GFS2] The core o...
540
541
542
  TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store);
  
  static struct attribute *tune_attrs[] = {
b3b94faa5   David Teigland   [GFS2] The core o...
543
544
  	&tune_attr_quota_warn_period.attr,
  	&tune_attr_quota_quantum.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
545
546
  	&tune_attr_max_readahead.attr,
  	&tune_attr_complain_secs.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
547
548
  	&tune_attr_statfs_slow.attr,
  	&tune_attr_quota_simul_sync.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
549
  	&tune_attr_statfs_quantum.attr,
b3b94faa5   David Teigland   [GFS2] The core o...
550
551
  	&tune_attr_quota_scale.attr,
  	&tune_attr_new_files_jdata.attr,
ea67eedb2   Steven Whitehouse   [GFS2] Fix end of...
552
  	NULL,
b3b94faa5   David Teigland   [GFS2] The core o...
553
  };
b3b94faa5   David Teigland   [GFS2] The core o...
554
555
  static struct attribute_group tune_group = {
  	.name = "tune",
ea67eedb2   Steven Whitehouse   [GFS2] Fix end of...
556
  	.attrs = tune_attrs,
b3b94faa5   David Teigland   [GFS2] The core o...
557
  };
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
558
559
560
561
  static struct attribute_group lock_module_group = {
  	.name = "lock_module",
  	.attrs = lock_module_attrs,
  };
b3b94faa5   David Teigland   [GFS2] The core o...
562
563
  int gfs2_sys_fs_add(struct gfs2_sbd *sdp)
  {
440d6da20   Steven Whitehouse   GFS2: Add some mo...
564
  	struct super_block *sb = sdp->sd_vfs;
b3b94faa5   David Teigland   [GFS2] The core o...
565
  	int error;
440d6da20   Steven Whitehouse   GFS2: Add some mo...
566
567
568
569
570
571
  	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...
572

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

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

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