summaryrefslogtreecommitdiff
path: root/fs/locks.c
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@citi.umich.edu>2007-02-21 00:58:50 -0500
committerJ. Bruce Fields <bfields@citi.umich.edu>2007-05-06 18:06:44 -0400
commit3ee17abd14c728d4e0ca7a991c58f2250cb091af (patch)
tree6f49a9893dc656fac4d5a334946ccbf4e911891f /fs/locks.c
parent9d6a8c5c213e34c475e72b245a8eb709258e968c (diff)
downloadlwn-3ee17abd14c728d4e0ca7a991c58f2250cb091af.tar.gz
lwn-3ee17abd14c728d4e0ca7a991c58f2250cb091af.zip
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" <bfields@citi.umich.edu>
Diffstat (limited to 'fs/locks.c')
-rw-r--r--fs/locks.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/fs/locks.c b/fs/locks.c
index 749a0dc7cd4b..a31648e3ec1b 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1611,6 +1611,24 @@ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd)
return error;
}
+/**
+ * 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;
@@ -1663,12 +1681,9 @@ int fcntl_getlk(struct file *filp, struct flock __user *l)
if (error)
goto out;
- if (filp->f_op && filp->f_op->lock) {
- error = filp->f_op->lock(filp, F_GETLK, &file_lock);
- if (error < 0)
- goto out;
- } else
- posix_test_lock(filp, &file_lock);
+ error = vfs_test_lock(filp, &file_lock);
+ if (error)
+ goto out;
flock.l_type = file_lock.fl_type;
if (file_lock.fl_type != F_UNLCK) {
@@ -1797,13 +1812,10 @@ int fcntl_getlk64(struct file *filp, struct flock64 __user *l)
if (error)
goto out;
- if (filp->f_op && filp->f_op->lock) {
- error = filp->f_op->lock(filp, F_GETLK, &file_lock);
- if (error < 0)
- goto out;
- } else
- posix_test_lock(filp, &file_lock);
-
+ error = vfs_test_lock(filp, &file_lock);
+ if (error)
+ goto out;
+
flock.l_type = file_lock.fl_type;
if (file_lock.fl_type != F_UNLCK)
posix_lock_to_flock64(&flock, &file_lock);