From 8cbc4342478311c2a85260a7ca54d96cb7f71f7b Mon Sep 17 00:00:00 2001 From: David Teigland Date: Wed, 7 Nov 2007 09:03:56 -0600 Subject: [GFS2] check kthread_should_stop when waiting Use wait_event_interruptible() in the lock_dlm thread instead of an open coded equivalent, and include a kthread_should_stop() check in the wait test so we don't miss a kthread_stop(). Signed-off-by: David Teigland Signed-off-by: Steven Whitehouse --- fs/gfs2/locking/dlm/thread.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'fs/gfs2/locking') diff --git a/fs/gfs2/locking/dlm/thread.c b/fs/gfs2/locking/dlm/thread.c index bd938f06481d..521694fc19d6 100644 --- a/fs/gfs2/locking/dlm/thread.c +++ b/fs/gfs2/locking/dlm/thread.c @@ -273,18 +273,13 @@ static int gdlm_thread(void *data, int blist) struct gdlm_ls *ls = (struct gdlm_ls *) data; struct gdlm_lock *lp = NULL; uint8_t complete, blocking, submit, drop; - DECLARE_WAITQUEUE(wait, current); /* Only thread1 is allowed to do blocking callbacks since gfs may wait for a completion callback within a blocking cb. */ while (!kthread_should_stop()) { - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&ls->thread_wait, &wait); - if (no_work(ls, blist)) - schedule(); - remove_wait_queue(&ls->thread_wait, &wait); - set_current_state(TASK_RUNNING); + wait_event_interruptible(ls->thread_wait, + !no_work(ls, blist) || kthread_should_stop()); complete = blocking = submit = drop = 0; -- cgit v1.2.3 From 0b7580c786a5feda6291fe68ead3a1b92b6b35b8 Mon Sep 17 00:00:00 2001 From: Fabio Massimo Di Nitto Date: Thu, 15 Nov 2007 13:48:52 +0000 Subject: [GFS2] Check for installation of mount helpers for DLM mounts The patch is a fix to abort mount if the mount.gfs* and possible umount.* are missing from /sbin. While we do what we can to guarantee that they are installed properly in userland (CVS HEAD), we want to make sure that mount still aborts properly. The only sign of missing helpers is that lock_dlm will receive no mount options at all. According to David the problem does not exist for lock_nolock as the helpers are not required. The patch has been tested for both gfs and gfs2 and it works as expected. The lack of mount.gfs* will generate an error that is propagated to mount: oot@node1:~# mount -t gfs2 /dev/nbd2 /mnt/ mount: wrong fs type, bad option, bad superblock on /dev/nbd2, missing codepage or helper program, or other error In some cases useful info is found in syslog - try dmesg | tail or so [ 3513.303346] GFS2: fsid=: Trying to join cluster "lock_dlm", "gutsy:gfs2" [ 3513.304546] DLM/GFS2/GFS ERROR: (u)mount helpers are not installed properly! [ 3513.306290] GFS2: fsid=: can't mount proto=lock_dlm, table=gutsy:gfs2, hostdata= You might want to notice that it will also avoid mount to hang or fail silently or with strange errors that will require the cluster to reboot/restart before you can actually mount the filesystem again. Signed-off-by: Fabio M. Di Nitto Signed-off-by: Steven Whitehouse --- fs/gfs2/locking/dlm/mount.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'fs/gfs2/locking') diff --git a/fs/gfs2/locking/dlm/mount.c b/fs/gfs2/locking/dlm/mount.c index 41c5b04caaba..ab301023094f 100644 --- a/fs/gfs2/locking/dlm/mount.c +++ b/fs/gfs2/locking/dlm/mount.c @@ -67,6 +67,12 @@ static int make_args(struct gdlm_ls *ls, char *data_arg, int *nodir) memset(data, 0, 256); strncpy(data, data_arg, 255); + if (!strlen(data)) { + printk(KERN_ERR + "DLM/GFS2/GFS ERROR: (u)mount helpers are not installed!\n"); + return -EINVAL; + } + for (options = data; (x = strsep(&options, ":")); ) { if (!*x) continue; -- cgit v1.2.3 From 00c134756c5ad570a1ad3d6f93a67fc9c25a67ea Mon Sep 17 00:00:00 2001 From: David Teigland Date: Thu, 15 Nov 2007 09:01:13 -0600 Subject: [GFS2] tidy up error message Print error with log_error() to be consistent with others. Signed-off-by: David Teigland Signed-off-by: Fabio M. Di Nitto Signed-off-by: Steven Whitehouse --- fs/gfs2/locking/dlm/mount.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'fs/gfs2/locking') diff --git a/fs/gfs2/locking/dlm/mount.c b/fs/gfs2/locking/dlm/mount.c index ab301023094f..f2efff424224 100644 --- a/fs/gfs2/locking/dlm/mount.c +++ b/fs/gfs2/locking/dlm/mount.c @@ -68,8 +68,7 @@ static int make_args(struct gdlm_ls *ls, char *data_arg, int *nodir) strncpy(data, data_arg, 255); if (!strlen(data)) { - printk(KERN_ERR - "DLM/GFS2/GFS ERROR: (u)mount helpers are not installed!\n"); + log_error("no mount options, (u)mount helpers not installed"); return -EINVAL; } -- cgit v1.2.3 From 2066b58b0a038d7aedd24133677efb8856cac3a1 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Thu, 6 Dec 2007 09:35:25 -0600 Subject: [GFS2] use pid for plock owner for nfs clients The fl_owner is that of lockd when posix locks arrive from nfs clients, so it can't be used to distinguish between lock holders. Use fl_pid as owner instead; it's the pid of the process on the nfs client. Signed-off-by: David Teigland Signed-off-by: Steven Whitehouse --- fs/gfs2/locking/dlm/plock.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'fs/gfs2/locking') diff --git a/fs/gfs2/locking/dlm/plock.c b/fs/gfs2/locking/dlm/plock.c index 1f7b038530b4..2ebd374b3143 100644 --- a/fs/gfs2/locking/dlm/plock.c +++ b/fs/gfs2/locking/dlm/plock.c @@ -89,15 +89,19 @@ int gdlm_plock(void *lockspace, struct lm_lockname *name, op->info.number = name->ln_number; op->info.start = fl->fl_start; op->info.end = fl->fl_end; - op->info.owner = (__u64)(long) fl->fl_owner; if (fl->fl_lmops && fl->fl_lmops->fl_grant) { + /* fl_owner is lockd which doesn't distinguish + processes on the nfs client */ + op->info.owner = (__u64) fl->fl_pid; xop->callback = fl->fl_lmops->fl_grant; locks_init_lock(&xop->flc); locks_copy_lock(&xop->flc, fl); xop->fl = fl; xop->file = file; - } else + } else { + op->info.owner = (__u64)(long) fl->fl_owner; xop->callback = NULL; + } send_op(op); @@ -203,7 +207,10 @@ int gdlm_punlock(void *lockspace, struct lm_lockname *name, op->info.number = name->ln_number; op->info.start = fl->fl_start; op->info.end = fl->fl_end; - op->info.owner = (__u64)(long) fl->fl_owner; + if (fl->fl_lmops && fl->fl_lmops->fl_grant) + op->info.owner = (__u64) fl->fl_pid; + else + op->info.owner = (__u64)(long) fl->fl_owner; send_op(op); wait_event(recv_wq, (op->done != 0)); @@ -242,7 +249,10 @@ int gdlm_plock_get(void *lockspace, struct lm_lockname *name, op->info.number = name->ln_number; op->info.start = fl->fl_start; op->info.end = fl->fl_end; - op->info.owner = (__u64)(long) fl->fl_owner; + if (fl->fl_lmops && fl->fl_lmops->fl_grant) + op->info.owner = (__u64) fl->fl_pid; + else + op->info.owner = (__u64)(long) fl->fl_owner; send_op(op); wait_event(recv_wq, (op->done != 0)); -- cgit v1.2.3