return result;
}
-int
+void
posix_test_lock(struct file *filp, struct file_lock *fl)
{
struct file_lock *cfl;
if (posix_locks_conflict(cfl, fl))
break;
}
- if (cfl) {
+ if (cfl)
__locks_copy_lock(fl, cfl);
- unlock_kernel();
- return 1;
- } else
+ else
fl->fl_type = F_UNLCK;
unlock_kernel();
- return 0;
+ return;
}
EXPORT_SYMBOL(posix_test_lock);
*
* Called with kernel lock held.
*/
-static int setlease(struct file *filp, long arg, struct file_lock **flp)
+int setlease(struct file *filp, long arg, struct file_lock **flp)
{
struct file_lock *fl, **before, **my_before = NULL, *lease;
struct dentry *dentry = filp->f_path.dentry;
out:
return error;
}
+EXPORT_SYMBOL(setlease);
/**
* vfs_setlease - sets a lease on an open file
* @lease: file_lock to use
*
* Call this to establish a lease on the file.
- * The fl_lmops fl_break function is required by break_lease
+ * The (*lease)->fl_lmops->fl_break operation must be set; if not,
+ * break_lease will oops!
+ *
+ * This will call the filesystem's setlease file method, if
+ * defined. Note that there is no getlease method; instead, the
+ * filesystem setlease method should call back to setlease() to
+ * add a lease to the inode's lease list, where fcntl_getlease() can
+ * find it. Since fcntl_getlease() only reports whether the current
+ * task holds a lease, a cluster filesystem need only do this for
+ * leases held by processes on this node.
+ *
+ * There is also no break_lease method; filesystems that
+ * handle their own leases shoud break leases themselves from the
+ * filesystem's open, create, and (on truncate) setattr methods.
+ *
+ * Warning: the only current setlease methods exist only to disable
+ * leases in certain cases. More vfs changes may be required to
+ * allow a full filesystem lease implementation.
*/
int vfs_setlease(struct file *filp, long arg, struct file_lock **lease)
int error;
lock_kernel();
- error = setlease(filp, arg, lease);
+ if (filp->f_op && filp->f_op->setlease)
+ error = filp->f_op->setlease(filp, arg, lease);
+ else
+ error = setlease(filp, arg, lease);
unlock_kernel();
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
+ * @fl: The lock to test; also used to hold result
*
* Returns -ERRNO on failure. Indicates presence of conflicting lock by
* setting conf->fl_type to something other than F_UNLCK.
{
filelock_cache = kmem_cache_create("file_lock_cache",
sizeof(struct file_lock), 0, SLAB_PANIC,
- init_once, NULL);
+ init_once);
return 0;
}