aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/sys.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2010-06-14 05:01:30 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2010-07-29 04:36:35 -0400
commitba6e93645f039bd357e04b7b9d18f4e67757725e (patch)
tree11d2d4491255cd9a298fe098f6ec52e0f3d8b577 /fs/gfs2/sys.c
parent30116ff6c6d140bc696cc624e6d8e38f018c886e (diff)
GFS2: Wait for journal id on mount if not specified on mount command line
This patch implements a wait for the journal id in the case that it has not been specified on the command line. This is to allow the future removal of the mount.gfs2 helper. The journal id would instead be directly communicated by gfs_controld to the file system. Here is a comparison of the two systems: Current: 1. mount calls mount.gfs2 2. mount.gfs2 connects to gfs_controld to retrieve the journal id 3. mount.gfs2 adds the journal id to the mount command line and calls the mount system call 4. gfs_controld receives the status of the mount request via a uevent Proposed: 1. mount calls the mount system call (no mount.gfs2 helper) 2. gfs_controld receives a uevent for a gfs2 fs which it doesn't know about already 3. gfs_controld assigns a journal id to it via sysfs 4. the mount system call then completes as normal (sending a uevent according to status) The advantage of the proposed system is that it is completely backward compatible with the current system both at the kernel and at the userland levels. The "first" parameter can also be set the same way, with the restriction that it must be set before the journal id is assigned. In addition, if mount becomes stuck waiting for a reply from gfs_controld which never arrives, then it is killable and will abort the mount gracefully. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/sys.c')
-rw-r--r--fs/gfs2/sys.c57
1 files changed, 54 insertions, 3 deletions
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c
index 37f5393e68e6..d019d0d55e00 100644
--- a/fs/gfs2/sys.c
+++ b/fs/gfs2/sys.c
@@ -325,6 +325,30 @@ static ssize_t lkfirst_show(struct gfs2_sbd *sdp, char *buf)
325 return sprintf(buf, "%d\n", ls->ls_first); 325 return sprintf(buf, "%d\n", ls->ls_first);
326} 326}
327 327
328static ssize_t lkfirst_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
329{
330 unsigned first;
331 int rv;
332
333 rv = sscanf(buf, "%u", &first);
334 if (rv != 1 || first > 1)
335 return -EINVAL;
336 spin_lock(&sdp->sd_jindex_spin);
337 rv = -EBUSY;
338 if (test_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0)
339 goto out;
340 rv = -EINVAL;
341 if (sdp->sd_args.ar_spectator)
342 goto out;
343 if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL)
344 goto out;
345 sdp->sd_lockstruct.ls_first = first;
346 rv = 0;
347out:
348 spin_unlock(&sdp->sd_jindex_spin);
349 return rv ? rv : len;
350}
351
328static ssize_t first_done_show(struct gfs2_sbd *sdp, char *buf) 352static ssize_t first_done_show(struct gfs2_sbd *sdp, char *buf)
329{ 353{
330 struct lm_lockstruct *ls = &sdp->sd_lockstruct; 354 struct lm_lockstruct *ls = &sdp->sd_lockstruct;
@@ -377,14 +401,41 @@ static ssize_t jid_show(struct gfs2_sbd *sdp, char *buf)
377 return sprintf(buf, "%u\n", sdp->sd_lockstruct.ls_jid); 401 return sprintf(buf, "%u\n", sdp->sd_lockstruct.ls_jid);
378} 402}
379 403
404static ssize_t jid_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
405{
406 unsigned jid;
407 int rv;
408
409 rv = sscanf(buf, "%u", &jid);
410 if (rv != 1)
411 return -EINVAL;
412
413 spin_lock(&sdp->sd_jindex_spin);
414 rv = -EINVAL;
415 if (sdp->sd_args.ar_spectator)
416 goto out;
417 if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL)
418 goto out;
419 rv = -EBUSY;
420 if (test_and_clear_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0)
421 goto out;
422 sdp->sd_lockstruct.ls_jid = jid;
423 smp_mb__after_clear_bit();
424 wake_up_bit(&sdp->sd_flags, SDF_NOJOURNALID);
425 rv = 0;
426out:
427 spin_unlock(&sdp->sd_jindex_spin);
428 return rv ? rv : len;
429}
430
380#define GDLM_ATTR(_name,_mode,_show,_store) \ 431#define GDLM_ATTR(_name,_mode,_show,_store) \
381static struct gfs2_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store) 432static struct gfs2_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store)
382 433
383GDLM_ATTR(proto_name, 0444, proto_name_show, NULL); 434GDLM_ATTR(proto_name, 0444, proto_name_show, NULL);
384GDLM_ATTR(block, 0644, block_show, block_store); 435GDLM_ATTR(block, 0644, block_show, block_store);
385GDLM_ATTR(withdraw, 0644, withdraw_show, withdraw_store); 436GDLM_ATTR(withdraw, 0644, withdraw_show, withdraw_store);
386GDLM_ATTR(jid, 0444, jid_show, NULL); 437GDLM_ATTR(jid, 0644, jid_show, jid_store);
387GDLM_ATTR(first, 0444, lkfirst_show, NULL); 438GDLM_ATTR(first, 0644, lkfirst_show, lkfirst_store);
388GDLM_ATTR(first_done, 0444, first_done_show, NULL); 439GDLM_ATTR(first_done, 0444, first_done_show, NULL);
389GDLM_ATTR(recover, 0600, NULL, recover_store); 440GDLM_ATTR(recover, 0600, NULL, recover_store);
390GDLM_ATTR(recover_done, 0444, recover_done_show, NULL); 441GDLM_ATTR(recover_done, 0444, recover_done_show, NULL);
@@ -564,7 +615,7 @@ static int gfs2_uevent(struct kset *kset, struct kobject *kobj,
564 615
565 add_uevent_var(env, "LOCKTABLE=%s", sdp->sd_table_name); 616 add_uevent_var(env, "LOCKTABLE=%s", sdp->sd_table_name);
566 add_uevent_var(env, "LOCKPROTO=%s", sdp->sd_proto_name); 617 add_uevent_var(env, "LOCKPROTO=%s", sdp->sd_proto_name);
567 if (!sdp->sd_args.ar_spectator) 618 if (!test_bit(SDF_NOJOURNALID, &sdp->sd_flags))
568 add_uevent_var(env, "JOURNALID=%u", sdp->sd_lockstruct.ls_jid); 619 add_uevent_var(env, "JOURNALID=%u", sdp->sd_lockstruct.ls_jid);
569 if (gfs2_uuid_valid(uuid)) 620 if (gfs2_uuid_valid(uuid))
570 add_uevent_var(env, "UUID=%pUB", uuid); 621 add_uevent_var(env, "UUID=%pUB", uuid);