GIT 406d4adb97269ceebee3c4a09fa2e53f69827d97 git://git.linux-nfs.org/~bfields/linux.git#server-cluster-locking-api commit Author: Marc Eshel Date: Tue Nov 14 16:37:25 2006 -0500 gfs2: nfs lock support for gfs2 Add NFS lock support to GFS2. Signed-off-by: Marc Eshel Signed-off-by: J. Bruce Fields Acked-by: Steven Whitehouse commit 7d3614f84625fe2088ab865d3e721dd297e3bcd2 Author: Marc Eshel Date: Tue Nov 28 16:27:06 2006 -0500 lockd: add code to handle deferred lock requests Rewrite nlmsvc_lock() to use the asynchronous interface. As with testlock, we answer nlm requests in nlmsvc_lock by first looking up the block and then using the results we find in the block if B_QUEUED is set, and calling vfs_lock_file() otherwise. If this a new lock request and we get -EINPROGRESS return on a non-blocking request then we defer the request. Also modify nlmsvc_unlock() to call the filesystem method if appropriate. Signed-off-by: Marc Eshel Signed-off-by: J. Bruce Fields commit 5d0563c791356533802771b634243abe5a9b1661 Author: Marc Eshel Date: Tue Dec 5 23:48:10 2006 -0500 lockd: always preallocate block in nlmsvc_lock() Normally we could skip ever having to allocate a block in the case where the client asks for a non-blocking lock, or asks for a blocking lock that succeeds immediately. However we're going to want to always look up a block first in order to check whether we're revisiting a deferred lock call, and to be prepared to handle the case where the filesystem returns -EINPROGRESS--in that case we want to make sure the lock we've given the filesystem is the one embedded in the block that we'll use to track the deferred request. Signed-off-by: Marc Eshel Signed-off-by: J. Bruce Fields commit 5ffafbe049903ed020096e6f378f03963ebe77b2 Author: Marc Eshel Date: Tue Nov 28 16:27:06 2006 -0500 lockd: handle test_lock deferrals Rewrite nlmsvc_testlock() to use the new asynchronous interface: instead of immediately doing a posix_test_lock(), we first look for a matching block. If the subsequent test_lock returns anything other than -EINPROGRESS, we then remove the block we've found and return the results. If it returns -EINPROGRESS, then we defer the lock request. In the case where the block we find in the first step has B_QUEUED set, we bypass the vfs_test_lock entirely, instead using the block to decide how to respond: with nlm_lck_denied if B_TIMED_OUT is set. with nlm_granted if B_GOT_CALLBACK is set. by dropping if neither B_TIMED_OUT nor B_GOT_CALLBACK is set Signed-off-by: Marc Eshel Signed-off-by: J. Bruce Fields commit eea31a615bb381410a1786e7195a7b4edc43751c Author: Marc Eshel Date: Tue Nov 28 16:27:06 2006 -0500 lockd: pass cookie in nlmsvc_testlock Change NLM internal interface to pass more information for test lock; we need this to make sure the cookie information is pushed down to the place where we do request deferral, which is handled for testlock by the following patch. Signed-off-by: Marc Eshel Signed-off-by: J. Bruce Fields commit 905364c4eea3b896962bdab283b38e330b762bbf Author: Marc Eshel Date: Tue Nov 28 16:26:51 2006 -0500 lockd: handle fl_grant callbacks Add code to handle file system callback when the lock is finally granted. Signed-off-by: Marc Eshel Signed-off-by: J. Bruce Fields commit 81d3a45d51d4a6797ee7eeb929a2351cec0749e4 Author: Marc Eshel Date: Tue Nov 28 16:26:47 2006 -0500 lockd: save lock state on deferral We need to keep some state for a pending asynchronous lock request, so this patch adds that state to struct nlm_block. This also adds a function which defers the request, by calling rqstp->rq_chandle.defer and storing the resulting deferred request in a nlm_block structure which we insert into lockd's global block list. That new function isn't called yet, so it's dead code until a later patch. Signed-off-by: Marc Eshel Signed-off-by: J. Bruce Fields commit fffd7d3da6c12836a6639aec99963172f36dfb78 Author: Marc Eshel Date: Tue Dec 5 23:31:28 2006 -0500 locks: add fl_grant callback for asynchronous lock return Acquiring a lock on a cluster filesystem may require communication with remote hosts, and to avoid blocking lockd or nfsd threads during such communication, we allow the results to be returned asynchronously. When a ->lock() call needs to block, the file system will return -EINPROGRESS, and then later return the results with a call to the routine in the fl_grant field of the lock_manager_operations struct. This differs from the case when ->lock returns -EAGAIN to a blocking lock request; in that case, the filesystem calls fl_notify when the lock is granted, and the caller retries the original lock. So while fl_notify is merely a hint to the caller that it should retry, fl_grant actually communicates the final result of the lock operation (with the lock already acquired in the succesful case). Therefore fl_grant takes a lock, a status and, for the test lock case, a conflicting lock. We also allow fl_grant to return an error to the filesystem, to handle the case where the fl_grant requests arrives after the lock manager has already given up waiting for it. Signed-off-by: Marc Eshel Signed-off-by: J. Bruce Fields commit 7c3d438e42f93bc6e8af11312514dc16d4d79792 Author: Marc Eshel Date: Tue Nov 28 16:26:41 2006 -0500 nfsd4: Convert NFSv4 to new lock interface Convert NFSv4 to the new lock interface. We don't define any callback for now, so we're not taking advantage of the asynchronous feature--that's less critical for the multi-threaded nfsd then it is for the single-threaded lockd. But this does allow a cluster filesystems to export cluster-coherent locking to NFS. Note that it's cluster filesystems that are the issue--of the filesystems that define lock methods (nfs, cifs, etc.), most are not exportable by nfsd. Signed-off-by: Marc Eshel Signed-off-by: J. Bruce Fields commit 5eca0f69987e0015b1a0826c1aae7ed1817e38d2 Author: Marc Eshel Date: Thu Jan 18 17:52:58 2007 -0500 locks: add lock cancel command Lock managers need to be able to cancel pending lock requests. In the case where the exported filesystem manages its own locks, it's not sufficient just to call posix_unblock_lock(); we need to let the filesystem know what's happening too. We do this by adding a new fcntl lock command: FL_CANCELLK. Some day this might also be made available to userspace applications that could benefit from an asynchronous locking api. Signed-off-by: Marc Eshel Signed-off-by: "J. Bruce Fields" commit 28f7fafd3c3569e512959fbc11f0f5439829b711 Author: Marc Eshel Date: Thu Jan 18 16:15:35 2007 -0500 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 Signed-off-by: "J. Bruce Fields" commit c73cc36e5950b716c8049a7e7561dce09f28885e Author: Marc Eshel Date: Thu Jan 18 15:08:55 2007 -0500 locks: factor out generic/filesystem switch from setlock code Factor out the code that switches between generic and filesystem-specific lock methods; eventually we want to call this from lock managers (lockd and nfsd) too; currently they only call the generic methods. This patch does that for all the setlk code. Signed-off-by: Marc Eshel Signed-off-by: "J. Bruce Fields" commit 4881672641f01a2c7331038ce38edf4035b28d0a Author: J. Bruce Fields Date: Wed Feb 21 00:58:50 2007 -0500 locks: factor out generic/filesystem switch from test_lock Factor out the code that switches between generic and filesystem-specific lock methods; eventually we want to call this from lock managers (lockd and nfsd) too; currently they only call the generic methods. This patch does that for test_lock. Note that this hasn't been necessary until recently, because the few filesystems that define ->lock() (nfs, cifs...) aren't exportable via NFS. However GFS (and, in the future, other cluster filesystems) need to implement their own locking to get cluster-coherent locking, and also want to be able to export locking to NFS (lockd and NFSv4). So we accomplish this by factoring out code such as this and exporting it for the use of lockd and nfsd. Signed-off-by: "J. Bruce Fields" commit a11b5895b2e4eb61079404f5f0d41f9ade230930 Author: Marc Eshel Date: Wed Feb 21 00:55:18 2007 -0500 locks: give posix_test_lock same interface as ->lock posix_test_lock() and ->lock() do the same job but have gratuitously different interfaces. Modify posix_test_lock() so the two agree, simplifying some code in the process. Signed-off-by: Marc Eshel Signed-off-by: "J. Bruce Fields" commit 1d50a768373ff01c1c6ca3a33bb802b84c704e2c Author: J. Bruce Fields Date: Thu Feb 22 18:48:53 2007 -0500 locks: make ->lock release private data before returning in GETLK case The file_lock argument to ->lock is used to return the conflicting lock when found. There's no reason for the filesystem to return any private information with this conflicting lock, but nfsv4 is. Fix nfsv4 client, and modify locks.c to stop calling fl_release_private for it in this case. Signed-off-by: "J. Bruce Fields" Cc: "Trond Myklebust" " commit 15f2802c27e4a3e2b9e004c4f093abe715a5169d Author: J. Bruce Fields Date: Tue Feb 20 16:10:11 2007 -0500 locks: create posix-to-flock helper functions Factor out a bit of messy code by creating posix-to-flock counterparts to the existing flock-to-posix helper functions. Cc: Christoph Hellwig Signed-off-by: "J. Bruce Fields" commit 3cb6cfabcbbb8683eddfeb2dcaa3c0a9e0581c75 Author: J. Bruce Fields Date: Wed Feb 14 14:25:00 2007 -0500 locks: trivial removal of unnecessary parentheses Remove some unnecessary parentheses. Signed-off-by: "J. Bruce Fields" fs/locks.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 54 insertions(+), 0 deletions(-) diff --git a/fs/locks.c b/fs/locks.c index 8ec16ab..63aa8b5 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -669,6 +669,7 @@ posix_test_lock(struct file *filp, struc { struct file_lock *cfl; + fl->fl_type = F_UNLCK; lock_kernel(); for (cfl = filp->f_path.dentry->d_inode->i_flock; cfl; cfl = cfl->fl_next) { if (!IS_POSIX(cfl)) @@ -1597,6 +1598,7 @@ asmlinkage long sys_flock(unsigned int f return error; } +<<<<<<< HEAD/fs/locks.c /** * vfs_test_lock - test file byte range lock * @filp: The file to test lock for @@ -1648,6 +1650,58 @@ static void posix_lock_to_flock64(struct } #endif +======= +/** + * vfs_test_lock - test file byte range lock + * @filp: The file to test lock for + * @fl: The lock to test + * @conf: Place to return a copy of the conflicting lock, if found + * + * Returns -ERRNO on failure. Indicates presence of conflicting lock by + * setting conf->fl_type to something other than F_UNLCK. + */ +int vfs_test_lock(struct file *filp, struct file_lock *fl) +{ + if (filp->f_op && filp->f_op->lock) + return filp->f_op->lock(filp, F_GETLK, fl); + posix_test_lock(filp, fl); + return 0; +} +EXPORT_SYMBOL_GPL(vfs_test_lock); + +static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl) +{ + flock->l_pid = fl->fl_pid; +#if BITS_PER_LONG == 32 + /* + * Make sure we can represent the posix lock via + * legacy 32bit flock. + */ + if (fl->fl_start > OFFT_OFFSET_MAX) + return -EOVERFLOW; + if (fl->fl_end != OFFSET_MAX && fl->fl_end > OFFT_OFFSET_MAX) + return -EOVERFLOW; +#endif + flock->l_start = fl->fl_start; + flock->l_len = fl->fl_end == OFFSET_MAX ? 0 : + fl->fl_end - fl->fl_start + 1; + flock->l_whence = 0; + return 0; +} + +#if BITS_PER_LONG == 32 +static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl) +{ + flock->l_pid = fl->fl_pid; + flock->l_start = fl->fl_start; + flock->l_len = fl->fl_end == OFFSET_MAX ? 0 : + fl->fl_end - fl->fl_start + 1; + flock->l_whence = 0; + flock->l_type = fl->fl_type; +} +#endif + +>>>>>>> /fs/locks.c /* Report the first existing lock that would conflict with l. * This implements the F_GETLK command of fcntl(). */