aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
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
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')
-rw-r--r--fs/gfs2/incore.h1
-rw-r--r--fs/gfs2/ops_fstype.c27
-rw-r--r--fs/gfs2/sys.c57
3 files changed, 80 insertions, 5 deletions
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index b5d7363b22da..8fcbce48a128 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -460,6 +460,7 @@ enum {
460 SDF_NOBARRIERS = 3, 460 SDF_NOBARRIERS = 3,
461 SDF_NORECOVERY = 4, 461 SDF_NORECOVERY = 4,
462 SDF_DEMOTE = 5, 462 SDF_DEMOTE = 5,
463 SDF_NOJOURNALID = 6,
463}; 464};
464 465
465#define GFS2_FSNAME_LEN 256 466#define GFS2_FSNAME_LEN 256
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 3593b3a7290e..45a4a36195d8 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -76,7 +76,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
76 76
77 sb->s_fs_info = sdp; 77 sb->s_fs_info = sdp;
78 sdp->sd_vfs = sb; 78 sdp->sd_vfs = sb;
79 79 set_bit(SDF_NOJOURNALID, &sdp->sd_flags);
80 gfs2_tune_init(&sdp->sd_tune); 80 gfs2_tune_init(&sdp->sd_tune);
81 81
82 init_waitqueue_head(&sdp->sd_glock_wait); 82 init_waitqueue_head(&sdp->sd_glock_wait);
@@ -1050,7 +1050,8 @@ static int gfs2_lm_mount(struct gfs2_sbd *sdp, int silent)
1050 ret = match_int(&tmp[0], &option); 1050 ret = match_int(&tmp[0], &option);
1051 if (ret || option < 0) 1051 if (ret || option < 0)
1052 goto hostdata_error; 1052 goto hostdata_error;
1053 ls->ls_jid = option; 1053 if (test_and_clear_bit(SDF_NOJOURNALID, &sdp->sd_flags))
1054 ls->ls_jid = option;
1054 break; 1055 break;
1055 case Opt_id: 1056 case Opt_id:
1056 /* Obsolete, but left for backward compat purposes */ 1057 /* Obsolete, but left for backward compat purposes */
@@ -1102,6 +1103,24 @@ void gfs2_lm_unmount(struct gfs2_sbd *sdp)
1102 lm->lm_unmount(sdp); 1103 lm->lm_unmount(sdp);
1103} 1104}
1104 1105
1106static int gfs2_journalid_wait(void *word)
1107{
1108 if (signal_pending(current))
1109 return -EINTR;
1110 schedule();
1111 return 0;
1112}
1113
1114static int wait_on_journal(struct gfs2_sbd *sdp)
1115{
1116 if (sdp->sd_args.ar_spectator)
1117 return 0;
1118 if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL)
1119 return 0;
1120
1121 return wait_on_bit(&sdp->sd_flags, SDF_NOJOURNALID, gfs2_journalid_wait, TASK_INTERRUPTIBLE);
1122}
1123
1105void gfs2_online_uevent(struct gfs2_sbd *sdp) 1124void gfs2_online_uevent(struct gfs2_sbd *sdp)
1106{ 1125{
1107 struct super_block *sb = sdp->sd_vfs; 1126 struct super_block *sb = sdp->sd_vfs;
@@ -1194,6 +1213,10 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent
1194 if (error) 1213 if (error)
1195 goto fail_locking; 1214 goto fail_locking;
1196 1215
1216 error = wait_on_journal(sdp);
1217 if (error)
1218 goto fail_sb;
1219
1197 error = init_inodes(sdp, DO); 1220 error = init_inodes(sdp, DO);
1198 if (error) 1221 if (error)
1199 goto fail_sb; 1222 goto fail_sb;
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);