Re: [PATCH 10/10] gfs2: nfs lock support for gfs2

2006-12-07 Thread J. Bruce Fields
On Wed, Dec 06, 2006 at 10:47:46PM -0800, Marc Eshel wrote:
 Here is a rewrite of gdlm_plock_callback(). We still need to add the 
 lock cancel.
 Marc.
 
 int gdlm_plock_callback(struct plock_op *op)
 {
 struct file *file;
 struct file_lock *fl;
 int (*notify)(void *, void *, int) = NULL;
 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;
 
/* check if the following 2 are still valid or make a copy */
file = op-info.file;
fl = op-info.fl;
notify = op-info.callback;
 
if (!rv) { /* got fs lock */
rv = posix_lock_file(file, fl);
if (rv) { /* did not get posix lock */

If we never request the local lock until after we've gotten the lock
from GFS, then this should never happen.  So I think this could just be
a BUG_ON(rv)--except that would mean a failure in the lock manager could
oops the kernel, so maybe it'd be better just to printk.

--b.
-
To unsubscribe from this list: send the line unsubscribe linux-fsdevel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 10/10] gfs2: nfs lock support for gfs2

2006-12-06 Thread Steven Whitehouse
Hi,

This looks good to me, and I'm copying in Dave  Wendy who have both
done previous work in this area for further comment. Provided we can get
this tested, I'd be happy to accept the patch in its current form.

Steve.

On Wed, 2006-12-06 at 00:34 -0500, J. Bruce Fields wrote:
 From: J. Bruce Fields [EMAIL PROTECTED]
 
 From: Marc Eshel [EMAIL PROTECTED]
 
 Add NFS lock support to GFS2.  (Untested.)
 
 Signed-off-by: J. Bruce Fields [EMAIL PROTECTED]
 ---
  fs/gfs2/lm.c   |   10 
  fs/gfs2/lm.h   |2 +
  fs/gfs2/locking/dlm/lock_dlm.h |2 +
  fs/gfs2/locking/dlm/mount.c|1 +
  fs/gfs2/locking/dlm/plock.c|   95 
 +++-
  fs/gfs2/ops_export.c   |   52 ++
  include/linux/lm_interface.h   |3 +
  include/linux/lock_dlm_plock.h |3 +
  8 files changed, 166 insertions(+), 2 deletions(-)
 
 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..c21e667 100644
 --- a/fs/gfs2/locking/dlm/plock.c
 +++ b/fs/gfs2/locking/dlm/plock.c
 @@ -102,6 +102,93 @@ 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
 +   

Re: [PATCH 10/10] gfs2: nfs lock support for gfs2

2006-12-06 Thread David Teigland
On Wed, Dec 06, 2006 at 12:34:20AM -0500, J. Bruce Fields wrote:
 +int 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 (!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);
 + return rv;
 +}

..

 + if (found) {
 + if (op-info.callback)
 + gdlm_plock_callback(op);
 + else
 + wake_up(recv_wq);
 + }

The gfs side looks fine to me.  Did you forget to call fl_notify from
gdlm_plock_callback() or am I missing something?

Dave

-
To unsubscribe from this list: send the line unsubscribe linux-fsdevel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 10/10] gfs2: nfs lock support for gfs2

2006-12-06 Thread J. Bruce Fields
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);
}

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);
}

Note there's a race condition--that calls fl_notify before actually
getting the lock locally.  I don't *think* that's a problem, as long as
it's the filesystem and not the local lock list that's authoritative
when it comes to who gets a posix lock.

The more annoying problem is the need to cancel the GFS lock when
fl_notify fails; is that something that it's possible for GFS to do?

It can fail because lockd has a timeout--it waits a few seconds for the
callback, then gives up and returns a failure to the user.  If that
happens after your userspace posix lock manager acquires the lock (but
before fl_notify is called) then you've got to cancel it somehow.

--b.
-
To unsubscribe from this list: send the line unsubscribe linux-fsdevel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 10/10] gfs2: nfs lock support for gfs2

2006-12-06 Thread David Teigland
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);
   }
 
   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);
   }
 
 Note there's a race condition--that calls fl_notify before actually
 getting the lock locally.  I don't *think* that's a problem, as long as
 it's the filesystem and not the local lock list that's authoritative
 when it comes to who gets a posix lock.

agree

 The more annoying problem is the need to cancel the GFS lock when
 fl_notify fails; is that something that it's possible for GFS to do?
 
 It can fail because lockd has a timeout--it waits a few seconds for the
 callback, then gives up and returns a failure to the user.  If that
 happens after your userspace posix lock manager acquires the lock (but
 before fl_notify is called) then you've got to cancel it somehow.

I'd think we could just send an unlock for it at that point.  Set up an op
with GDLM_PLOCK_OP_UNLOCK and the same fields as the lock you're removing
and call send_op().  We probably need to flag this internal-unlock op so
that when the result arrives, device_write() delists and frees it itself.

(I wouldn't call this canceling, I think of cancel as trying to force a
blocked request to return/fail prematurely.)

Dave

-
To unsubscribe from this list: send the line unsubscribe linux-fsdevel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 10/10] gfs2: nfs lock support for gfs2

2006-12-06 Thread Marc Eshel
Here is a rewrite of gdlm_plock_callback(). We still need to add the 
lock cancel.

Marc.

int gdlm_plock_callback(struct plock_op *op)
{
struct file *file;
struct file_lock *fl;
int (*notify)(void *, void *, int) = NULL;
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;

   /* check if the following 2 are still valid or make a copy */
   file = op-info.file;
   fl = op-info.fl;
   notify = op-info.callback;

   if (!rv) { /* got fs lock */
   rv = posix_lock_file(file, fl);
   if (rv) { /* did not get posix lock */
   notify(fl, NULL, rv);
   log_error(gdlm_plock: vfs lock error file %p fl %p,
 file, fl);
   /* XXX: We need to cancel the fs lock here: */
   printk(gfs2 lock posix lock request failed\n);
   }
   else { /* got posix lock */
   if (notify(fl, NULL, 0)) {
   /* XXX: We need to cancel the fs lock here: */
   printk(gfs2 lock granted after lock request failed; 
dangling lock!\n);

   }
   }
   }
   else {  /* did not get fs lock */
   notify(fl, NULL, rv);
   }

   kfree(op);
   return rv;
}


David Teigland wrote:


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);
}

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);
}

Note there's a race condition--that calls fl_notify before actually
getting the lock locally.  I don't *think* that's a problem, as long as
it's the filesystem and not the local lock list that's authoritative
when it comes to who gets a posix lock.
   



agree

 


The more annoying problem is the need to cancel the GFS lock when
fl_notify fails; is that something that it's possible for GFS to do?

It can fail because lockd has a timeout--it waits a few seconds for the
callback, then gives up and returns a failure to the user.  If that
happens after your userspace posix lock manager acquires the lock (but
before fl_notify is called) then you've got to cancel it somehow.
   



I'd think we could just send an unlock for it at that point.  Set up an op
with GDLM_PLOCK_OP_UNLOCK and the same fields as the lock you're removing
and call send_op().  We probably need to flag this internal-unlock op so
that when the result arrives, device_write() delists and frees it itself.

(I wouldn't call this canceling, I think of cancel as trying to force a
blocked request to return/fail prematurely.)

Dave

 



-
To unsubscribe from this list: send the line unsubscribe linux-fsdevel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html