Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=150b393456e5a23513cace286a019e87151e47f0
Commit:     150b393456e5a23513cace286a019e87151e47f0
Parent:     7723ec9777d9832849b76475b1a21a2872a40d20
Author:     Marc Eshel <[EMAIL PROTECTED]>
AuthorDate: Thu Jan 18 16:15:35 2007 -0500
Committer:  J. Bruce Fields <[EMAIL PROTECTED]>
CommitDate: Sun May 6 19:23:24 2007 -0400

    locks: allow {vfs,posix}_lock_file to return conflicting lock
    
    The nfsv4 protocol's lock operation, in the case of a conflict, returns
    information about the conflicting lock.
    
    It's unclear how clients can use this, so for now we're not going so far as 
to
    add a filesystem method that can return a conflicting lock, but we may as 
well
    return something in the local case when it's easy to.
    
    Signed-off-by: Marc Eshel <[EMAIL PROTECTED]>
    Signed-off-by: "J. Bruce Fields" <[EMAIL PROTECTED]>
---
 fs/lockd/svclock.c  |    6 +++---
 fs/lockd/svcsubs.c  |    2 +-
 fs/locks.c          |   45 ++++++++++++++++++++-------------------------
 fs/nfsd/nfs4state.c |   10 ++++++----
 include/linux/fs.h  |    5 ++---
 5 files changed, 32 insertions(+), 36 deletions(-)

diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 97b0160..3b0e7a4 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -363,7 +363,7 @@ again:
        } else
                lock = &block->b_call->a_args.lock;
 
-       error = posix_lock_file(file->f_file, &lock->fl);
+       error = posix_lock_file(file->f_file, &lock->fl, NULL);
        lock->fl.fl_flags &= ~FL_SLEEP;
 
        dprintk("lockd: posix_lock_file returned %d\n", error);
@@ -467,7 +467,7 @@ nlmsvc_unlock(struct nlm_file *file, struct nlm_lock *lock)
        nlmsvc_cancel_blocked(file, lock);
 
        lock->fl.fl_type = F_UNLCK;
-       error = posix_lock_file(file->f_file, &lock->fl);
+       error = posix_lock_file(file->f_file, &lock->fl, NULL);
 
        return (error < 0)? nlm_lck_denied_nolocks : nlm_granted;
 }
@@ -569,7 +569,7 @@ nlmsvc_grant_blocked(struct nlm_block *block)
 
        /* Try the lock operation again */
        lock->fl.fl_flags |= FL_SLEEP;
-       error = posix_lock_file(file->f_file, &lock->fl);
+       error = posix_lock_file(file->f_file, &lock->fl, NULL);
        lock->fl.fl_flags &= ~FL_SLEEP;
 
        switch (error) {
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
index c0df00c..5095708 100644
--- a/fs/lockd/svcsubs.c
+++ b/fs/lockd/svcsubs.c
@@ -182,7 +182,7 @@ again:
                        lock.fl_type  = F_UNLCK;
                        lock.fl_start = 0;
                        lock.fl_end   = OFFSET_MAX;
-                       if (posix_lock_file(file->f_file, &lock) < 0) {
+                       if (posix_lock_file(file->f_file, &lock, NULL) < 0) {
                                printk("lockd: unlock failure in %s:%d\n",
                                                __FILE__, __LINE__);
                                return 1;
diff --git a/fs/locks.c b/fs/locks.c
index f4fd151..ee46584 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -801,7 +801,7 @@ out:
        return error;
 }
 
-static int __posix_lock_file_conf(struct inode *inode, struct file_lock 
*request, struct file_lock *conflock)
+static int __posix_lock_file(struct inode *inode, struct file_lock *request, 
struct file_lock *conflock)
 {
        struct file_lock *fl;
        struct file_lock *new_fl = NULL;
@@ -1007,6 +1007,7 @@ static int __posix_lock_file_conf(struct inode *inode, 
struct file_lock *request
  * posix_lock_file - Apply a POSIX-style lock to a file
  * @filp: The file to apply the lock to
  * @fl: The lock to be applied
+ * @conflock: Place to return a copy of the conflicting lock, if found.
  *
  * Add a POSIX style lock to a file.
  * We merge adjacent & overlapping locks whenever possible.
@@ -1016,26 +1017,12 @@ static int __posix_lock_file_conf(struct inode *inode, 
struct file_lock *request
  * whether or not a lock was successfully freed by testing the return
  * value for -ENOENT.
  */
-int posix_lock_file(struct file *filp, struct file_lock *fl)
-{
-       return __posix_lock_file_conf(filp->f_path.dentry->d_inode, fl, NULL);
-}
-EXPORT_SYMBOL(posix_lock_file);
-
-/**
- * posix_lock_file_conf - Apply a POSIX-style lock to a file
- * @filp: The file to apply the lock to
- * @fl: The lock to be applied
- * @conflock: Place to return a copy of the conflicting lock, if found.
- *
- * Except for the conflock parameter, acts just like posix_lock_file.
- */
-int posix_lock_file_conf(struct file *filp, struct file_lock *fl,
+int posix_lock_file(struct file *filp, struct file_lock *fl,
                        struct file_lock *conflock)
 {
-       return __posix_lock_file_conf(filp->f_path.dentry->d_inode, fl, 
conflock);
+       return __posix_lock_file(filp->f_path.dentry->d_inode, fl, conflock);
 }
-EXPORT_SYMBOL(posix_lock_file_conf);
+EXPORT_SYMBOL(posix_lock_file);
 
 /**
  * posix_lock_file_wait - Apply a POSIX-style lock to a file
@@ -1051,7 +1038,7 @@ int posix_lock_file_wait(struct file *filp, struct 
file_lock *fl)
        int error;
        might_sleep ();
        for (;;) {
-               error = posix_lock_file(filp, fl);
+               error = posix_lock_file(filp, fl, NULL);
                if ((error != -EAGAIN) || !(fl->fl_flags & FL_SLEEP))
                        break;
                error = wait_event_interruptible(fl->fl_wait, !fl->fl_next);
@@ -1123,7 +1110,7 @@ int locks_mandatory_area(int read_write, struct inode 
*inode,
        fl.fl_end = offset + count - 1;
 
        for (;;) {
-               error = __posix_lock_file_conf(inode, &fl, NULL);
+               error = __posix_lock_file(inode, &fl, NULL);
                if (error != -EAGAIN)
                        break;
                if (!(fl.fl_flags & FL_SLEEP))
@@ -1703,13 +1690,21 @@ out:
  * @filp: The file to apply the lock to
  * @cmd: type of locking operation (F_SETLK, F_GETLK, etc.)
  * @fl: The lock to be applied
+ * @conf: Place to return a copy of the conflicting lock, if found.
+ *
+ * A caller that doesn't care about the conflicting lock may pass NULL
+ * as the final argument.
+ *
+ * If the filesystem defines a private ->lock() method, then @conf will
+ * be left unchanged; so a caller that cares should initialize it to
+ * some acceptable default.
  */
-int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl)
+int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl, 
struct file_lock *conf)
 {
        if (filp->f_op && filp->f_op->lock)
                return filp->f_op->lock(filp, cmd, fl);
        else
-               return posix_lock_file(filp, fl);
+               return posix_lock_file(filp, fl, conf);
 }
 EXPORT_SYMBOL_GPL(vfs_lock_file);
 
@@ -1776,7 +1771,7 @@ again:
                goto out;
 
        for (;;) {
-               error = vfs_lock_file(filp, cmd, file_lock);
+               error = vfs_lock_file(filp, cmd, file_lock, NULL);
                if (error != -EAGAIN || cmd == F_SETLK)
                        break;
                error = wait_event_interruptible(file_lock->fl_wait,
@@ -1902,7 +1897,7 @@ again:
                goto out;
 
        for (;;) {
-               error = vfs_lock_file(filp, cmd, file_lock);
+               error = vfs_lock_file(filp, cmd, file_lock, NULL);
                if (error != -EAGAIN || cmd == F_SETLK64)
                        break;
                error = wait_event_interruptible(file_lock->fl_wait,
@@ -1956,7 +1951,7 @@ void locks_remove_posix(struct file *filp, fl_owner_t 
owner)
        lock.fl_ops = NULL;
        lock.fl_lmops = NULL;
 
-       vfs_lock_file(filp, F_SETLK, &lock);
+       vfs_lock_file(filp, F_SETLK, &lock, NULL);
 
        if (lock.fl_ops && lock.fl_ops->fl_release_private)
                lock.fl_ops->fl_release_private(&lock);
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index e42c7a0..03b0578 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -2657,6 +2657,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct 
nfsd4_compound_state *cstate,
        struct file_lock conflock;
        __be32 status = 0;
        unsigned int strhashval;
+       unsigned int cmd;
        int err;
 
        dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n",
@@ -2739,10 +2740,12 @@ nfsd4_lock(struct svc_rqst *rqstp, struct 
nfsd4_compound_state *cstate,
                case NFS4_READ_LT:
                case NFS4_READW_LT:
                        file_lock.fl_type = F_RDLCK;
+                       cmd = F_SETLK;
                break;
                case NFS4_WRITE_LT:
                case NFS4_WRITEW_LT:
                        file_lock.fl_type = F_WRLCK;
+                       cmd = F_SETLK;
                break;
                default:
                        status = nfserr_inval;
@@ -2769,9 +2772,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct 
nfsd4_compound_state *cstate,
 
        /* XXX?: Just to divert the locks_release_private at the start of
         * locks_copy_lock: */
-       conflock.fl_ops = NULL;
-       conflock.fl_lmops = NULL;
-       err = posix_lock_file_conf(filp, &file_lock, &conflock);
+       locks_init_lock(&conflock);
+       err = posix_lock_file(filp, &file_lock, &conflock);
        switch (-err) {
        case 0: /* success! */
                update_stateid(&lock_stp->st_stateid);
@@ -2933,7 +2935,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct 
nfsd4_compound_state *cstate,
        /*
        *  Try to unlock the file in the VFS.
        */
-       err = posix_lock_file(filp, &file_lock);
+       err = posix_lock_file(filp, &file_lock, NULL);
        if (err) {
                dprintk("NFSD: nfs4_locku: posix_lock_file failed!\n");
                goto out_nfserr;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 1d5ccdd..c92d0bd 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -852,12 +852,11 @@ extern void locks_copy_lock(struct file_lock *, struct 
file_lock *);
 extern void locks_remove_posix(struct file *, fl_owner_t);
 extern void locks_remove_flock(struct file *);
 extern int posix_test_lock(struct file *, struct file_lock *);
-extern int posix_lock_file_conf(struct file *, struct file_lock *, struct 
file_lock *);
-extern int posix_lock_file(struct file *, struct file_lock *);
+extern int posix_lock_file(struct file *, struct file_lock *, struct file_lock 
*);
 extern int posix_lock_file_wait(struct file *, struct file_lock *);
 extern int posix_unblock_lock(struct file *, struct file_lock *);
 extern int vfs_test_lock(struct file *, struct file_lock *);
-extern int vfs_lock_file(struct file *, unsigned int, struct file_lock *);
+extern int vfs_lock_file(struct file *, unsigned int, struct file_lock *, 
struct file_lock *);
 extern int flock_lock_file_wait(struct file *filp, struct file_lock *fl);
 extern int __break_lease(struct inode *inode, unsigned int flags);
 extern void lease_get_mtime(struct inode *, struct timespec *time);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to