forked from Minki/linux
Merge branch 'for-linus' of git://linux-nfs.org/~bfields/linux
* 'for-linus' of git://linux-nfs.org/~bfields/linux: locks: fix vfs_test_lock() comment locks: make posix_test_lock() interface more consistent nfs: disable leases over NFS gfs2: stop giving out non-cluster-coherent leases locks: export setlease to filesystems locks: provide a file lease method enabling cluster-coherent leases locks: rename lease functions to reflect locks.c conventions locks: share more common lease code locks: clean up lease_alloc() locks: convert an -EINVAL return to a BUG leases: minor break_lease() comment clarification
This commit is contained in:
commit
a8dcf12f9e
@ -488,6 +488,29 @@ static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gfs2_setlease - acquire/release a file lease
|
||||||
|
* @file: the file pointer
|
||||||
|
* @arg: lease type
|
||||||
|
* @fl: file lock
|
||||||
|
*
|
||||||
|
* Returns: errno
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int gfs2_setlease(struct file *file, long arg, struct file_lock **fl)
|
||||||
|
{
|
||||||
|
struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We don't currently have a way to enforce a lease across the whole
|
||||||
|
* cluster; until we do, disable leases (by just returning -EINVAL),
|
||||||
|
* unless the administrator has requested purely local locking.
|
||||||
|
*/
|
||||||
|
if (!sdp->sd_args.ar_localflocks)
|
||||||
|
return -EINVAL;
|
||||||
|
return setlease(file, arg, fl);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gfs2_lock - acquire/release a posix lock on a file
|
* gfs2_lock - acquire/release a posix lock on a file
|
||||||
* @file: the file pointer
|
* @file: the file pointer
|
||||||
@ -638,6 +661,7 @@ const struct file_operations gfs2_file_fops = {
|
|||||||
.flock = gfs2_flock,
|
.flock = gfs2_flock,
|
||||||
.splice_read = generic_file_splice_read,
|
.splice_read = generic_file_splice_read,
|
||||||
.splice_write = generic_file_splice_write,
|
.splice_write = generic_file_splice_write,
|
||||||
|
.setlease = gfs2_setlease,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct file_operations gfs2_dir_fops = {
|
const struct file_operations gfs2_dir_fops = {
|
||||||
|
112
fs/locks.c
112
fs/locks.c
@ -458,22 +458,20 @@ static int lease_init(struct file *filp, int type, struct file_lock *fl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate a file_lock initialised to this type of lease */
|
/* Allocate a file_lock initialised to this type of lease */
|
||||||
static int lease_alloc(struct file *filp, int type, struct file_lock **flp)
|
static struct file_lock *lease_alloc(struct file *filp, int type)
|
||||||
{
|
{
|
||||||
struct file_lock *fl = locks_alloc_lock();
|
struct file_lock *fl = locks_alloc_lock();
|
||||||
int error = -ENOMEM;
|
int error = -ENOMEM;
|
||||||
|
|
||||||
if (fl == NULL)
|
if (fl == NULL)
|
||||||
goto out;
|
return ERR_PTR(error);
|
||||||
|
|
||||||
error = lease_init(filp, type, fl);
|
error = lease_init(filp, type, fl);
|
||||||
if (error) {
|
if (error) {
|
||||||
locks_free_lock(fl);
|
locks_free_lock(fl);
|
||||||
fl = NULL;
|
return ERR_PTR(error);
|
||||||
}
|
}
|
||||||
out:
|
return fl;
|
||||||
*flp = fl;
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if two locks overlap each other.
|
/* Check if two locks overlap each other.
|
||||||
@ -661,7 +659,7 @@ static int locks_block_on_timeout(struct file_lock *blocker, struct file_lock *w
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
posix_test_lock(struct file *filp, struct file_lock *fl)
|
posix_test_lock(struct file *filp, struct file_lock *fl)
|
||||||
{
|
{
|
||||||
struct file_lock *cfl;
|
struct file_lock *cfl;
|
||||||
@ -673,14 +671,12 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
|
|||||||
if (posix_locks_conflict(cfl, fl))
|
if (posix_locks_conflict(cfl, fl))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (cfl) {
|
if (cfl)
|
||||||
__locks_copy_lock(fl, cfl);
|
__locks_copy_lock(fl, cfl);
|
||||||
unlock_kernel();
|
else
|
||||||
return 1;
|
|
||||||
} else
|
|
||||||
fl->fl_type = F_UNLCK;
|
fl->fl_type = F_UNLCK;
|
||||||
unlock_kernel();
|
unlock_kernel();
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(posix_test_lock);
|
EXPORT_SYMBOL(posix_test_lock);
|
||||||
@ -1169,9 +1165,9 @@ static void time_out_leases(struct inode *inode)
|
|||||||
* @inode: the inode of the file to return
|
* @inode: the inode of the file to return
|
||||||
* @mode: the open mode (read or write)
|
* @mode: the open mode (read or write)
|
||||||
*
|
*
|
||||||
* break_lease (inlined for speed) has checked there already
|
* break_lease (inlined for speed) has checked there already is at least
|
||||||
* is a lease on this file. Leases are broken on a call to open()
|
* some kind of lock (maybe a lease) on this file. Leases are broken on
|
||||||
* or truncate(). This function can sleep unless you
|
* a call to open() or truncate(). This function can sleep unless you
|
||||||
* specified %O_NONBLOCK to your open().
|
* specified %O_NONBLOCK to your open().
|
||||||
*/
|
*/
|
||||||
int __break_lease(struct inode *inode, unsigned int mode)
|
int __break_lease(struct inode *inode, unsigned int mode)
|
||||||
@ -1179,12 +1175,10 @@ int __break_lease(struct inode *inode, unsigned int mode)
|
|||||||
int error = 0, future;
|
int error = 0, future;
|
||||||
struct file_lock *new_fl, *flock;
|
struct file_lock *new_fl, *flock;
|
||||||
struct file_lock *fl;
|
struct file_lock *fl;
|
||||||
int alloc_err;
|
|
||||||
unsigned long break_time;
|
unsigned long break_time;
|
||||||
int i_have_this_lease = 0;
|
int i_have_this_lease = 0;
|
||||||
|
|
||||||
alloc_err = lease_alloc(NULL, mode & FMODE_WRITE ? F_WRLCK : F_RDLCK,
|
new_fl = lease_alloc(NULL, mode & FMODE_WRITE ? F_WRLCK : F_RDLCK);
|
||||||
&new_fl);
|
|
||||||
|
|
||||||
lock_kernel();
|
lock_kernel();
|
||||||
|
|
||||||
@ -1212,8 +1206,9 @@ int __break_lease(struct inode *inode, unsigned int mode)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alloc_err && !i_have_this_lease && ((mode & O_NONBLOCK) == 0)) {
|
if (IS_ERR(new_fl) && !i_have_this_lease
|
||||||
error = alloc_err;
|
&& ((mode & O_NONBLOCK) == 0)) {
|
||||||
|
error = PTR_ERR(new_fl);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1260,7 +1255,7 @@ restart:
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
unlock_kernel();
|
unlock_kernel();
|
||||||
if (!alloc_err)
|
if (!IS_ERR(new_fl))
|
||||||
locks_free_lock(new_fl);
|
locks_free_lock(new_fl);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@ -1329,7 +1324,7 @@ int fcntl_getlease(struct file *filp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __setlease - sets a lease on an open file
|
* setlease - sets a lease on an open file
|
||||||
* @filp: file pointer
|
* @filp: file pointer
|
||||||
* @arg: type of lease to obtain
|
* @arg: type of lease to obtain
|
||||||
* @flp: input - file_lock to use, output - file_lock inserted
|
* @flp: input - file_lock to use, output - file_lock inserted
|
||||||
@ -1339,18 +1334,24 @@ int fcntl_getlease(struct file *filp)
|
|||||||
*
|
*
|
||||||
* Called with kernel lock held.
|
* 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 file_lock *fl, **before, **my_before = NULL, *lease;
|
||||||
struct dentry *dentry = filp->f_path.dentry;
|
struct dentry *dentry = filp->f_path.dentry;
|
||||||
struct inode *inode = dentry->d_inode;
|
struct inode *inode = dentry->d_inode;
|
||||||
int error, rdlease_count = 0, wrlease_count = 0;
|
int error, rdlease_count = 0, wrlease_count = 0;
|
||||||
|
|
||||||
|
if ((current->fsuid != inode->i_uid) && !capable(CAP_LEASE))
|
||||||
|
return -EACCES;
|
||||||
|
if (!S_ISREG(inode->i_mode))
|
||||||
|
return -EINVAL;
|
||||||
|
error = security_file_lock(filp, arg);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
|
||||||
time_out_leases(inode);
|
time_out_leases(inode);
|
||||||
|
|
||||||
error = -EINVAL;
|
BUG_ON(!(*flp)->fl_lmops->fl_break);
|
||||||
if (!flp || !(*flp) || !(*flp)->fl_lmops || !(*flp)->fl_lmops->fl_break)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
lease = *flp;
|
lease = *flp;
|
||||||
|
|
||||||
@ -1418,39 +1419,49 @@ static int __setlease(struct file *filp, long arg, struct file_lock **flp)
|
|||||||
out:
|
out:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(setlease);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* setlease - sets a lease on an open file
|
* vfs_setlease - sets a lease on an open file
|
||||||
* @filp: file pointer
|
* @filp: file pointer
|
||||||
* @arg: type of lease to obtain
|
* @arg: type of lease to obtain
|
||||||
* @lease: file_lock to use
|
* @lease: file_lock to use
|
||||||
*
|
*
|
||||||
* Call this to establish a lease on the file.
|
* 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 setlease(struct file *filp, long arg, struct file_lock **lease)
|
int vfs_setlease(struct file *filp, long arg, struct file_lock **lease)
|
||||||
{
|
{
|
||||||
struct dentry *dentry = filp->f_path.dentry;
|
|
||||||
struct inode *inode = dentry->d_inode;
|
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if ((current->fsuid != inode->i_uid) && !capable(CAP_LEASE))
|
|
||||||
return -EACCES;
|
|
||||||
if (!S_ISREG(inode->i_mode))
|
|
||||||
return -EINVAL;
|
|
||||||
error = security_file_lock(filp, arg);
|
|
||||||
if (error)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
lock_kernel();
|
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();
|
unlock_kernel();
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(vfs_setlease);
|
||||||
EXPORT_SYMBOL(setlease);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fcntl_setlease - sets a lease on an open file
|
* fcntl_setlease - sets a lease on an open file
|
||||||
@ -1469,14 +1480,6 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
|
|||||||
struct inode *inode = dentry->d_inode;
|
struct inode *inode = dentry->d_inode;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if ((current->fsuid != inode->i_uid) && !capable(CAP_LEASE))
|
|
||||||
return -EACCES;
|
|
||||||
if (!S_ISREG(inode->i_mode))
|
|
||||||
return -EINVAL;
|
|
||||||
error = security_file_lock(filp, arg);
|
|
||||||
if (error)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
locks_init_lock(&fl);
|
locks_init_lock(&fl);
|
||||||
error = lease_init(filp, arg, &fl);
|
error = lease_init(filp, arg, &fl);
|
||||||
if (error)
|
if (error)
|
||||||
@ -1484,15 +1487,15 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
|
|||||||
|
|
||||||
lock_kernel();
|
lock_kernel();
|
||||||
|
|
||||||
error = __setlease(filp, arg, &flp);
|
error = vfs_setlease(filp, arg, &flp);
|
||||||
if (error || arg == F_UNLCK)
|
if (error || arg == F_UNLCK)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
error = fasync_helper(fd, filp, 1, &flp->fl_fasync);
|
error = fasync_helper(fd, filp, 1, &flp->fl_fasync);
|
||||||
if (error < 0) {
|
if (error < 0) {
|
||||||
/* remove lease just inserted by __setlease */
|
/* remove lease just inserted by setlease */
|
||||||
flp->fl_type = F_UNLCK | F_INPROGRESS;
|
flp->fl_type = F_UNLCK | F_INPROGRESS;
|
||||||
flp->fl_break_time = jiffies- 10;
|
flp->fl_break_time = jiffies - 10;
|
||||||
time_out_leases(inode);
|
time_out_leases(inode);
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
@ -1597,8 +1600,7 @@ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd)
|
|||||||
/**
|
/**
|
||||||
* vfs_test_lock - test file byte range lock
|
* vfs_test_lock - test file byte range lock
|
||||||
* @filp: The file to test lock for
|
* @filp: The file to test lock for
|
||||||
* @fl: The lock to test
|
* @fl: The lock to test; also used to hold result
|
||||||
* @conf: Place to return a copy of the conflicting lock, if found
|
|
||||||
*
|
*
|
||||||
* Returns -ERRNO on failure. Indicates presence of conflicting lock by
|
* Returns -ERRNO on failure. Indicates presence of conflicting lock by
|
||||||
* setting conf->fl_type to something other than F_UNLCK.
|
* setting conf->fl_type to something other than F_UNLCK.
|
||||||
|
@ -53,6 +53,7 @@ static int nfs_fsync(struct file *, struct dentry *dentry, int datasync);
|
|||||||
static int nfs_check_flags(int flags);
|
static int nfs_check_flags(int flags);
|
||||||
static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl);
|
static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl);
|
||||||
static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl);
|
static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl);
|
||||||
|
static int nfs_setlease(struct file *file, long arg, struct file_lock **fl);
|
||||||
|
|
||||||
const struct file_operations nfs_file_operations = {
|
const struct file_operations nfs_file_operations = {
|
||||||
.llseek = nfs_file_llseek,
|
.llseek = nfs_file_llseek,
|
||||||
@ -69,6 +70,7 @@ const struct file_operations nfs_file_operations = {
|
|||||||
.flock = nfs_flock,
|
.flock = nfs_flock,
|
||||||
.splice_read = nfs_file_splice_read,
|
.splice_read = nfs_file_splice_read,
|
||||||
.check_flags = nfs_check_flags,
|
.check_flags = nfs_check_flags,
|
||||||
|
.setlease = nfs_setlease,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct inode_operations nfs_file_inode_operations = {
|
const struct inode_operations nfs_file_inode_operations = {
|
||||||
@ -400,7 +402,9 @@ static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
|
|||||||
|
|
||||||
lock_kernel();
|
lock_kernel();
|
||||||
/* Try local locking first */
|
/* Try local locking first */
|
||||||
if (posix_test_lock(filp, fl)) {
|
posix_test_lock(filp, fl);
|
||||||
|
if (fl->fl_type != F_UNLCK) {
|
||||||
|
/* found a conflict */
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -558,3 +562,13 @@ static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
|
|||||||
return do_unlk(filp, cmd, fl);
|
return do_unlk(filp, cmd, fl);
|
||||||
return do_setlk(filp, cmd, fl);
|
return do_setlk(filp, cmd, fl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int nfs_setlease(struct file *file, long arg, struct file_lock **fl)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* There is no protocol support for leases, so we have no way
|
||||||
|
* to implement them correctly in the face of opens by other
|
||||||
|
* clients.
|
||||||
|
*/
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
@ -256,7 +256,7 @@ nfs4_close_delegation(struct nfs4_delegation *dp)
|
|||||||
/* The following nfsd_close may not actually close the file,
|
/* The following nfsd_close may not actually close the file,
|
||||||
* but we want to remove the lease in any case. */
|
* but we want to remove the lease in any case. */
|
||||||
if (dp->dl_flock)
|
if (dp->dl_flock)
|
||||||
setlease(filp, F_UNLCK, &dp->dl_flock);
|
vfs_setlease(filp, F_UNLCK, &dp->dl_flock);
|
||||||
nfsd_close(filp);
|
nfsd_close(filp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1402,7 +1402,7 @@ void nfsd_release_deleg_cb(struct file_lock *fl)
|
|||||||
/*
|
/*
|
||||||
* Set the delegation file_lock back pointer.
|
* Set the delegation file_lock back pointer.
|
||||||
*
|
*
|
||||||
* Called from __setlease() with lock_kernel() held.
|
* Called from setlease() with lock_kernel() held.
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
void nfsd_copy_lock_deleg_cb(struct file_lock *new, struct file_lock *fl)
|
void nfsd_copy_lock_deleg_cb(struct file_lock *new, struct file_lock *fl)
|
||||||
@ -1416,7 +1416,7 @@ void nfsd_copy_lock_deleg_cb(struct file_lock *new, struct file_lock *fl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called from __setlease() with lock_kernel() held
|
* Called from setlease() with lock_kernel() held
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
int nfsd_same_client_deleg_cb(struct file_lock *onlist, struct file_lock *try)
|
int nfsd_same_client_deleg_cb(struct file_lock *onlist, struct file_lock *try)
|
||||||
@ -1716,10 +1716,10 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
|
|||||||
fl.fl_file = stp->st_vfs_file;
|
fl.fl_file = stp->st_vfs_file;
|
||||||
fl.fl_pid = current->tgid;
|
fl.fl_pid = current->tgid;
|
||||||
|
|
||||||
/* setlease checks to see if delegation should be handed out.
|
/* vfs_setlease checks to see if delegation should be handed out.
|
||||||
* the lock_manager callbacks fl_mylease and fl_change are used
|
* the lock_manager callbacks fl_mylease and fl_change are used
|
||||||
*/
|
*/
|
||||||
if ((status = setlease(stp->st_vfs_file,
|
if ((status = vfs_setlease(stp->st_vfs_file,
|
||||||
flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK, &flp))) {
|
flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK, &flp))) {
|
||||||
dprintk("NFSD: setlease failed [%d], no delegation\n", status);
|
dprintk("NFSD: setlease failed [%d], no delegation\n", status);
|
||||||
unhash_delegation(dp);
|
unhash_delegation(dp);
|
||||||
|
@ -862,7 +862,7 @@ extern void locks_init_lock(struct file_lock *);
|
|||||||
extern void locks_copy_lock(struct file_lock *, struct file_lock *);
|
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_posix(struct file *, fl_owner_t);
|
||||||
extern void locks_remove_flock(struct file *);
|
extern void locks_remove_flock(struct file *);
|
||||||
extern int posix_test_lock(struct file *, struct file_lock *);
|
extern void posix_test_lock(struct file *, struct file_lock *);
|
||||||
extern int posix_lock_file(struct file *, struct file_lock *, 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_lock_file_wait(struct file *, struct file_lock *);
|
||||||
extern int posix_unblock_lock(struct file *, struct file_lock *);
|
extern int posix_unblock_lock(struct file *, struct file_lock *);
|
||||||
@ -873,6 +873,7 @@ extern int flock_lock_file_wait(struct file *filp, struct file_lock *fl);
|
|||||||
extern int __break_lease(struct inode *inode, unsigned int flags);
|
extern int __break_lease(struct inode *inode, unsigned int flags);
|
||||||
extern void lease_get_mtime(struct inode *, struct timespec *time);
|
extern void lease_get_mtime(struct inode *, struct timespec *time);
|
||||||
extern int setlease(struct file *, long, struct file_lock **);
|
extern int setlease(struct file *, long, struct file_lock **);
|
||||||
|
extern int vfs_setlease(struct file *, long, struct file_lock **);
|
||||||
extern int lease_modify(struct file_lock **, int);
|
extern int lease_modify(struct file_lock **, int);
|
||||||
extern int lock_may_read(struct inode *, loff_t start, unsigned long count);
|
extern int lock_may_read(struct inode *, loff_t start, unsigned long count);
|
||||||
extern int lock_may_write(struct inode *, loff_t start, unsigned long count);
|
extern int lock_may_write(struct inode *, loff_t start, unsigned long count);
|
||||||
@ -1122,6 +1123,7 @@ struct file_operations {
|
|||||||
int (*flock) (struct file *, int, struct file_lock *);
|
int (*flock) (struct file *, int, struct file_lock *);
|
||||||
ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
|
ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
|
||||||
ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
|
ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
|
||||||
|
int (*setlease)(struct file *, long, struct file_lock **);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct inode_operations {
|
struct inode_operations {
|
||||||
|
Loading…
Reference in New Issue
Block a user