From: "J. Bruce Fields" <bfields@fieldses.org>
To: David Teigland <teigland@redhat.com>
Cc: linux-fsdevel@vger.kernel.org, nfs@lists.sourceforge.net,
Marc Eshel <eshel@almaden.ibm.com>
Subject: Re: [NFS] [PATCH 10/10] gfs2: nfs lock support for gfs2
Date: Wed, 6 Dec 2006 15:08:43 -0500 [thread overview]
Message-ID: <20061206200843.GI1714@fieldses.org> (raw)
In-Reply-To: <20061206195722.GH1714@fieldses.org>
On Wed, Dec 06, 2006 at 02:57:22PM -0500, J. Bruce Fields wrote:
> On Wed, Dec 06, 2006 at 09:49:51AM -0600, David Teigland wrote:
> > The gfs side looks fine to me. Did you forget to call fl_notify from
> > gdlm_plock_callback() or am I missing something?
>
> Yes, looks like we missed something, thanks. This code's an rfc (not
> even tested), so don't apply it yet! What we should have there is
> something like:
>
> rv = op->info.rv;
>
> if (fl_notify(fl, NULL, rv)) {
> /* XXX: We need to cancel the lock here: */
> printk("gfs2 lock granted after lock request failed; dangling lock!\n");
> }
(And note in the patch I sent out I stuck this in the wrong place--in
the synchronous instead of the asynchronous code. So the patch should
have been something closer to the following.)
--b.
diff --git a/fs/gfs2/lm.c b/fs/gfs2/lm.c
index effe4a3..cf7fd52 100644
--- a/fs/gfs2/lm.c
+++ b/fs/gfs2/lm.c
@@ -197,6 +197,16 @@ int gfs2_lm_plock(struct gfs2_sbd *sdp, struct lm_lockname *name,
return error;
}
+int gfs2_lm_plock_async(struct gfs2_sbd *sdp, struct lm_lockname *name,
+ struct file *file, int cmd, struct file_lock *fl)
+{
+ int error = -EIO;
+ if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
+ error = sdp->sd_lockstruct.ls_ops->lm_plock_async(
+ sdp->sd_lockstruct.ls_lockspace, name, file, cmd, fl);
+ return error;
+}
+
int gfs2_lm_punlock(struct gfs2_sbd *sdp, struct lm_lockname *name,
struct file *file, struct file_lock *fl)
{
diff --git a/fs/gfs2/lm.h b/fs/gfs2/lm.h
index 21cdc30..1ddd1fd 100644
--- a/fs/gfs2/lm.h
+++ b/fs/gfs2/lm.h
@@ -34,6 +34,8 @@ int gfs2_lm_plock_get(struct gfs2_sbd *sdp, struct lm_lockname *name,
struct file *file, struct file_lock *fl);
int gfs2_lm_plock(struct gfs2_sbd *sdp, struct lm_lockname *name,
struct file *file, int cmd, struct file_lock *fl);
+int gfs2_lm_plock_async(struct gfs2_sbd *sdp, struct lm_lockname *name,
+ struct file *file, int cmd, struct file_lock *fl);
int gfs2_lm_punlock(struct gfs2_sbd *sdp, struct lm_lockname *name,
struct file *file, struct file_lock *fl);
void gfs2_lm_recovery_done(struct gfs2_sbd *sdp, unsigned int jid,
diff --git a/fs/gfs2/locking/dlm/lock_dlm.h b/fs/gfs2/locking/dlm/lock_dlm.h
index 33af707..82af860 100644
--- a/fs/gfs2/locking/dlm/lock_dlm.h
+++ b/fs/gfs2/locking/dlm/lock_dlm.h
@@ -179,6 +179,8 @@ int gdlm_plock_init(void);
void gdlm_plock_exit(void);
int gdlm_plock(void *, struct lm_lockname *, struct file *, int,
struct file_lock *);
+int gdlm_plock_async(void *, struct lm_lockname *, struct file *, int,
+ struct file_lock *);
int gdlm_plock_get(void *, struct lm_lockname *, struct file *,
struct file_lock *);
int gdlm_punlock(void *, struct lm_lockname *, struct file *,
diff --git a/fs/gfs2/locking/dlm/mount.c b/fs/gfs2/locking/dlm/mount.c
index cdd1694..4339e3f 100644
--- a/fs/gfs2/locking/dlm/mount.c
+++ b/fs/gfs2/locking/dlm/mount.c
@@ -244,6 +244,7 @@ const struct lm_lockops gdlm_ops = {
.lm_lock = gdlm_lock,
.lm_unlock = gdlm_unlock,
.lm_plock = gdlm_plock,
+ .lm_plock_async = gdlm_plock_async,
.lm_punlock = gdlm_punlock,
.lm_plock_get = gdlm_plock_get,
.lm_cancel = gdlm_cancel,
diff --git a/fs/gfs2/locking/dlm/plock.c b/fs/gfs2/locking/dlm/plock.c
index 7365aec..f91a18a 100644
--- a/fs/gfs2/locking/dlm/plock.c
+++ b/fs/gfs2/locking/dlm/plock.c
@@ -102,6 +102,94 @@ int gdlm_plock(void *lockspace, struct lm_lockname *name,
return rv;
}
+int gdlm_plock_async(void *lockspace, struct lm_lockname *name,
+ struct file *file, int cmd, struct file_lock *fl)
+{
+ struct gdlm_ls *ls = lockspace;
+ struct plock_op *op;
+ int rv;
+
+ op = kzalloc(sizeof(*op), GFP_KERNEL);
+ if (!op)
+ return -ENOMEM;
+
+ op->info.optype = GDLM_PLOCK_OP_LOCK;
+ op->info.pid = fl->fl_pid;
+ op->info.ex = (fl->fl_type == F_WRLCK);
+ op->info.wait = IS_SETLKW(cmd);
+ op->info.fsid = ls->id;
+ 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) {
+ op->info.callback = fl->fl_lmops->fl_notify;
+ /* might need to make a copy */
+ op->info.fl = fl;
+ op->info.file = file;
+ } else
+ op->info.callback = NULL;
+
+ send_op(op);
+
+ if (op->info.callback == NULL)
+ wait_event(recv_wq, (op->done != 0));
+ else
+ return -EINPROGRESS;
+
+ spin_lock(&ops_lock);
+ if (!list_empty(&op->list)) {
+ printk(KERN_INFO "plock op on list\n");
+ list_del(&op->list);
+ }
+ spin_unlock(&ops_lock);
+
+ rv = op->info.rv;
+
+ if (!rv) {
+ if (posix_lock_file_wait(file, fl) < 0)
+ log_error("gdlm_plock: vfs lock error %x,%llx",
+ name->ln_type,
+ (unsigned long long)name->ln_number);
+ }
+
+ kfree(op);
+ return rv;
+}
+
+static void gdlm_plock_callback(struct plock_op *op)
+{
+ struct file *file;
+ struct file_lock *fl;
+ int rv;
+
+ spin_lock(&ops_lock);
+ if (!list_empty(&op->list)) {
+ printk(KERN_INFO "plock op on list\n");
+ list_del(&op->list);
+ }
+ spin_unlock(&ops_lock);
+
+ rv = op->info.rv;
+
+ if (fl_notify(fl, NULL, rv)) {
+ /* XXX: We need to cancel the lock here: */
+ printk("gfs2 lock granted after lock request failed; dangling lock!\n");
+ }
+
+ if (!rv) {
+ /* check if the following are still valid or make a copy */
+ file = op->info.file;
+ fl = op->info.fl;
+
+ if (posix_lock_file_wait(file, fl) < 0)
+ log_error("gdlm_plock: vfs lock error file %p fl %p",
+ file, fl);
+ }
+
+ kfree(op);
+}
+
int gdlm_punlock(void *lockspace, struct lm_lockname *name,
struct file *file, struct file_lock *fl)
{
@@ -242,8 +330,12 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
}
spin_unlock(&ops_lock);
- if (found)
- wake_up(&recv_wq);
+ if (found) {
+ if (op->info.callback)
+ gdlm_plock_callback(op);
+ else
+ wake_up(&recv_wq);
+ }
else
printk(KERN_INFO "gdlm dev_write no op %x %llx\n", info.fsid,
(unsigned long long)info.number);
diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c
index 86127d9..80ca84f 100644
--- a/fs/gfs2/ops_export.c
+++ b/fs/gfs2/ops_export.c
@@ -22,6 +22,7 @@
#include "glock.h"
#include "glops.h"
#include "inode.h"
+#include "lm.h"
#include "ops_export.h"
#include "rgrp.h"
#include "util.h"
@@ -287,6 +288,56 @@ fail:
gfs2_glock_dq_uninit(&i_gh);
return ERR_PTR(error);
}
+/**
+ * gfs2_exp_lock - acquire/release a posix lock on a file
+ * @file: the file pointer
+ * @cmd: either modify or retrieve lock state, possibly wait
+ * @fl: type and range of lock
+ *
+ * Returns: errno
+ */
+
+static int gfs2_exp_lock(struct file *file, int cmd, struct file_lock *fl)
+{
+ struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
+ struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host);
+ struct lm_lockname name =
+ { .ln_number = ip->i_num.no_addr,
+ .ln_type = LM_TYPE_PLOCK };
+
+ if (!(fl->fl_flags & FL_POSIX))
+ return -ENOLCK;
+ if ((ip->i_di.di_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
+ return -ENOLCK;
+
+ if (sdp->sd_args.ar_localflocks) {
+ if (IS_GETLK(cmd)) {
+ struct file_lock tmp;
+ int ret;
+ ret = posix_test_lock(file, fl, &tmp);
+ fl->fl_type = F_UNLCK;
+ if (ret)
+ memcpy(fl, &tmp, sizeof(struct file_lock));
+ return 0;
+ } else {
+ return posix_lock_file_wait(file, fl);
+ }
+ }
+
+ if (IS_GETLK(cmd))
+ return gfs2_lm_plock_get(sdp, &name, file, fl);
+ else if (fl->fl_type == F_UNLCK)
+ return gfs2_lm_punlock(sdp, &name, file, fl);
+ else {
+ /* If fl_notify is set make an async lock request
+ and reply withh -EINPROGRESS. When lock is granted
+ the gfs2_lm_plock_async should callback to fl_notify */
+ if (fl->fl_lmops->fl_notify)
+ return gfs2_lm_plock_async(sdp, &name, file, cmd, fl);
+ else
+ return gfs2_lm_plock(sdp, &name, file, cmd, fl);
+ }
+}
struct export_operations gfs2_export_ops = {
.decode_fh = gfs2_decode_fh,
@@ -294,5 +345,6 @@ struct export_operations gfs2_export_ops = {
.get_name = gfs2_get_name,
.get_parent = gfs2_get_parent,
.get_dentry = gfs2_get_dentry,
+ .lock = gfs2_exp_lock,
};
diff --git a/include/linux/lm_interface.h b/include/linux/lm_interface.h
index 1418fdc..28d5445 100644
--- a/include/linux/lm_interface.h
+++ b/include/linux/lm_interface.h
@@ -213,6 +213,9 @@ struct lm_lockops {
int (*lm_plock) (void *lockspace, struct lm_lockname *name,
struct file *file, int cmd, struct file_lock *fl);
+ int (*lm_plock_async) (void *lockspace, struct lm_lockname *name,
+ struct file *file, int cmd, struct file_lock *fl);
+
int (*lm_punlock) (void *lockspace, struct lm_lockname *name,
struct file *file, struct file_lock *fl);
diff --git a/include/linux/lock_dlm_plock.h b/include/linux/lock_dlm_plock.h
index fc34151..809c5b7 100644
--- a/include/linux/lock_dlm_plock.h
+++ b/include/linux/lock_dlm_plock.h
@@ -35,6 +35,9 @@ struct gdlm_plock_info {
__u64 start;
__u64 end;
__u64 owner;
+ void *callback;
+ void *fl;
+ void *file;
};
#endif
next prev parent reply other threads:[~2006-12-06 20:08 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-12-06 5:34 asynchronous locks for cluster exports J. Bruce Fields
[not found] ` <8eb625184e6025f7f3d081dfe0a805abdd62a068.1165380892.git.bfields@citi.umich.edu>
2006-12-06 5:34 ` [PATCH 1/10] lockd: add new export operation for nfsv4/lockd locking J. Bruce Fields
2006-12-06 5:34 ` J. Bruce Fields
2006-12-09 5:53 ` Wendy Cheng
2006-12-10 18:31 ` J. Bruce Fields
[not found] ` <cc7b88076df17bb41ac5d536de174b44eda6b73c.1165380893.git.bfields@citi.umich.edu>
2006-12-06 5:34 ` [PATCH 2/10] nfsd4: Convert NFSv4 to new lock interface J. Bruce Fields
2006-12-06 5:34 ` J. Bruce Fields
[not found] ` <610c7d52f6363606200fa1016804e7116d580c36.1165380893.git.bfields@citi.umich.edu>
2006-12-06 5:34 ` [PATCH 3/10] lockd: request deferral routine J. Bruce Fields
2006-12-06 5:34 ` J. Bruce Fields
[not found] ` <665bfdae3a5b77bb7755f4735069b7188f815d89.1165380893.git.bfields@citi.umich.edu>
2006-12-06 5:34 ` [PATCH 4/10] locks: add fl_notify arguments J. Bruce Fields
2006-12-06 5:34 ` J. Bruce Fields
[not found] ` <e9e7fa0047137e5c988edaacc3dc70a84eb02efb.1165380893.git.bfields@citi.umich.edu>
2006-12-06 5:34 ` [PATCH 5/10] lockd: handle fl_notify callbacks J. Bruce Fields
2006-12-06 5:34 ` J. Bruce Fields
[not found] ` <b24eab1e47a44c1855d47d54b2858a7e5c2d4653.1165380893.git.bfields@citi.umich.edu>
2006-12-06 5:34 ` [PATCH 6/10] lockd: pass cookie in nlmsvc_testlock J. Bruce Fields
2006-12-06 5:34 ` J. Bruce Fields
[not found] ` <c214e0a0062abdbb72f0810c25ab7688e51b4dbd.1165380893.git.bfields@citi.umich.edu>
2006-12-06 5:34 ` [PATCH 7/10] lockd: handle test_lock deferrals J. Bruce Fields
2006-12-06 5:34 ` J. Bruce Fields
[not found] ` <aee338c430e7f0a9afe63ea80d0278b97b01eeee.1165380893.git.bfields@citi.umich.edu>
2006-12-06 5:34 ` [PATCH 8/10] lockd: always preallocate block in nlmsvc_lock() J. Bruce Fields
2006-12-06 5:34 ` J. Bruce Fields
[not found] ` <4fbe0004219a67cb6da4d1b3a1cfd16a9cb09ed7.1165380893.git.bfields@citi.umich.edu>
2006-12-06 5:34 ` [PATCH 9/10] lockd: add code to handle deferred lock requests J. Bruce Fields
2006-12-06 5:34 ` J. Bruce Fields
[not found] ` <70549752c06e54117024429649fd7aa813f21bec.1165380893.git.bfields@citi.umich.edu>
2006-12-06 5:34 ` [PATCH 10/10] gfs2: nfs lock support for gfs2 J. Bruce Fields
2006-12-06 5:34 ` J. Bruce Fields
2006-12-06 6:00 ` [NFS] " Wendy Cheng
2006-12-06 13:26 ` Wendy Cheng
2006-12-06 12:02 ` Steven Whitehouse
2006-12-06 15:49 ` David Teigland
2006-12-06 19:57 ` J. Bruce Fields
2006-12-06 20:08 ` J. Bruce Fields [this message]
2006-12-06 20:58 ` David Teigland
2006-12-06 21:23 ` J. Bruce Fields
2006-12-06 21:42 ` David Teigland
2006-12-06 22:00 ` [NFS] " J. Bruce Fields
2006-12-07 15:30 ` David Teigland
2006-12-08 17:35 ` [NFS] " J. Bruce Fields
2006-12-07 6:47 ` Marc Eshel
2006-12-07 15:23 ` J. Bruce Fields
2006-12-07 15:43 ` [NFS] " Marc Eshel
2006-12-07 16:21 ` J. Bruce Fields
2006-12-07 18:52 ` [NFS] " Trond Myklebust
2006-12-14 23:04 ` [PATCH 1/10] lockd: add new export operation for nfsv4/lockd locking J. Bruce Fields
2006-12-15 5:52 ` Marc Eshel
2006-12-15 7:40 ` Christoph Hellwig
2006-12-07 16:51 ` asynchronous locks for cluster exports Christoph Hellwig
2006-12-14 22:51 ` J. Bruce Fields
2006-12-15 19:51 ` J. Bruce Fields
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20061206200843.GI1714@fieldses.org \
--to=bfields@fieldses.org \
--cc=eshel@almaden.ibm.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=nfs@lists.sourceforge.net \
--cc=teigland@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).