From 5b81a81a4c214de64d4b103501e2d8363a6cc1e6 Mon Sep 17 00:00:00 2001 From: Marc Eshel Date: Tue, 5 Dec 2006 23:31:28 -0500 Subject: [PATCH] --- yaml --- r: 54492 b: refs/heads/master c: 2beb6614f5e36c6165b704c167d82ef3e4ceaa0c h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/fs/locks.c | 19 +++++++++++++++++++ trunk/include/linux/fs.h | 1 + 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 55ff1f14594b..3c7a67e67181 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: fd85b8170dabbf021987875ef7f903791f4f181e +refs/heads/master: 2beb6614f5e36c6165b704c167d82ef3e4ceaa0c diff --git a/trunk/fs/locks.c b/trunk/fs/locks.c index 242328e17f32..53b0cd153202 100644 --- a/trunk/fs/locks.c +++ b/trunk/fs/locks.c @@ -1698,6 +1698,25 @@ int fcntl_getlk(struct file *filp, struct flock __user *l) * 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. + * + * To avoid blocking kernel daemons, such as lockd, that need to acquire POSIX + * locks, the ->lock() interface may return asynchronously, before the lock has + * been granted or denied by the underlying filesystem, if (and only if) + * fl_grant is set. Callers expecting ->lock() to return asynchronously + * will only use F_SETLK, not F_SETLKW; they will set FL_SLEEP if (and only if) + * the request is for a blocking lock. When ->lock() does return asynchronously, + * it must return -EINPROGRESS, and call ->fl_grant() when the lock + * request completes. + * If the request is for non-blocking lock the file system should return + * -EINPROGRESS then try to get the lock and call the callback routine with + * the result. If the request timed out the callback routine will return a + * nonzero return code and the file system should release the lock. The file + * system is also responsible to keep a corresponding posix lock when it + * grants a lock so the VFS can find out which locks are locally held and do + * the correct lock cleanup when required. + * The underlying filesystem must not drop the kernel lock or call + * ->fl_grant() before returning to the caller with a -EINPROGRESS + * return code. */ int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl, struct file_lock *conf) { diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index 64b8ae205309..b22991d5f16b 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -785,6 +785,7 @@ struct file_lock_operations { struct lock_manager_operations { int (*fl_compare_owner)(struct file_lock *, struct file_lock *); void (*fl_notify)(struct file_lock *); /* unblock callback */ + int (*fl_grant)(struct file_lock *, struct file_lock *, int); void (*fl_copy_lock)(struct file_lock *, struct file_lock *); void (*fl_release_private)(struct file_lock *); void (*fl_break)(struct file_lock *);