提交 ef4a48c5 编写于 作者: L Linus Torvalds

Merge tag 'locks-v3.18-1' of git://git.samba.org/jlayton/linux

Pull file locking related changes from Jeff Layton:
 "This release is a little more busy for file locking changes than the
  last:

   - a set of patches from Kinglong Mee to fix the lockowner handling in
     knfsd
   - a pile of cleanups to the internal file lease API.  This should get
     us a bit closer to allowing for setlease methods that can block.

  There are some dependencies between mine and Bruce's trees this cycle,
  and I based my tree on top of the requisite patches in Bruce's tree"

* tag 'locks-v3.18-1' of git://git.samba.org/jlayton/linux: (26 commits)
  locks: fix fcntl_setlease/getlease return when !CONFIG_FILE_LOCKING
  locks: flock_make_lock should return a struct file_lock (or PTR_ERR)
  locks: set fl_owner for leases to filp instead of current->files
  locks: give lm_break a return value
  locks: __break_lease cleanup in preparation of allowing direct removal of leases
  locks: remove i_have_this_lease check from __break_lease
  locks: move freeing of leases outside of i_lock
  locks: move i_lock acquisition into generic_*_lease handlers
  locks: define a lm_setup handler for leases
  locks: plumb a "priv" pointer into the setlease routines
  nfsd: don't keep a pointer to the lease in nfs4_file
  locks: clean up vfs_setlease kerneldoc comments
  locks: generic_delete_lease doesn't need a file_lock at all
  nfsd: fix potential lease memory leak in nfs4_setlease
  locks: close potential race in lease_get_mtime
  security: make security_file_set_fowner, f_setown and __f_setown void return
  locks: consolidate "nolease" routines
  locks: remove lock_may_read and lock_may_write
  lockd: rip out deferred lock handling from testlock codepath
  NFSD: Get reference of lockowner when coping file_lock
  ...
...@@ -464,15 +464,12 @@ prototypes: ...@@ -464,15 +464,12 @@ prototypes:
size_t, unsigned int); size_t, unsigned int);
ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *,
size_t, unsigned int); size_t, unsigned int);
int (*setlease)(struct file *, long, struct file_lock **); int (*setlease)(struct file *, long, struct file_lock **, void **);
long (*fallocate)(struct file *, int, loff_t, loff_t); long (*fallocate)(struct file *, int, loff_t, loff_t);
}; };
locking rules: locking rules:
All may block except for ->setlease. All may block.
No VFS locks held on entry except for ->setlease.
->setlease has the file_list_lock held and must not sleep.
->llseek() locking has moved from llseek to the individual llseek ->llseek() locking has moved from llseek to the individual llseek
implementations. If your fs is not using generic_file_llseek, you implementations. If your fs is not using generic_file_llseek, you
...@@ -496,6 +493,10 @@ components. And there are other reasons why the current interface is a mess... ...@@ -496,6 +493,10 @@ components. And there are other reasons why the current interface is a mess...
->read on directories probably must go away - we should just enforce -EISDIR ->read on directories probably must go away - we should just enforce -EISDIR
in sys_read() and friends. in sys_read() and friends.
->setlease operations should call generic_setlease() before or after setting
the lease within the individual filesystem to record the result of the
operation
--------------------------- dquot_operations ------------------------------- --------------------------- dquot_operations -------------------------------
prototypes: prototypes:
int (*write_dquot) (struct dquot *); int (*write_dquot) (struct dquot *);
......
...@@ -826,7 +826,7 @@ struct file_operations { ...@@ -826,7 +826,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 *, size_t, unsigned int); ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, size_t, unsigned int);
ssize_t (*splice_read)(struct file *, struct pipe_inode_info *, size_t, unsigned int); ssize_t (*splice_read)(struct file *, struct pipe_inode_info *, size_t, unsigned int);
int (*setlease)(struct file *, long arg, struct file_lock **); int (*setlease)(struct file *, long arg, struct file_lock **, void **);
long (*fallocate)(struct file *, int mode, loff_t offset, loff_t len); long (*fallocate)(struct file *, int mode, loff_t offset, loff_t len);
int (*show_fdinfo)(struct seq_file *m, struct file *f); int (*show_fdinfo)(struct seq_file *m, struct file *f);
}; };
...@@ -895,8 +895,9 @@ otherwise noted. ...@@ -895,8 +895,9 @@ otherwise noted.
splice_read: called by the VFS to splice data from file to a pipe. This splice_read: called by the VFS to splice data from file to a pipe. This
method is used by the splice(2) system call method is used by the splice(2) system call
setlease: called by the VFS to set or release a file lock lease. setlease: called by the VFS to set or release a file lock lease. setlease
setlease has the file_lock_lock held and must not sleep. implementations should call generic_setlease to record or remove
the lease in the inode after setting it.
fallocate: called by the VFS to preallocate blocks or punch a hole. fallocate: called by the VFS to preallocate blocks or punch a hole.
......
...@@ -2152,9 +2152,7 @@ static int tun_chr_fasync(int fd, struct file *file, int on) ...@@ -2152,9 +2152,7 @@ static int tun_chr_fasync(int fd, struct file *file, int on)
goto out; goto out;
if (on) { if (on) {
ret = __f_setown(file, task_pid(current), PIDTYPE_PID, 0); __f_setown(file, task_pid(current), PIDTYPE_PID, 0);
if (ret)
goto out;
tfile->flags |= TUN_FASYNC; tfile->flags |= TUN_FASYNC;
} else } else
tfile->flags &= ~TUN_FASYNC; tfile->flags &= ~TUN_FASYNC;
......
...@@ -2186,8 +2186,9 @@ static int __tty_fasync(int fd, struct file *filp, int on) ...@@ -2186,8 +2186,9 @@ static int __tty_fasync(int fd, struct file *filp, int on)
} }
get_pid(pid); get_pid(pid);
spin_unlock_irqrestore(&tty->ctrl_lock, flags); spin_unlock_irqrestore(&tty->ctrl_lock, flags);
retval = __f_setown(filp, pid, type, 0); __f_setown(filp, pid, type, 0);
put_pid(pid); put_pid(pid);
retval = 0;
} }
out: out:
return retval; return retval;
......
...@@ -813,7 +813,8 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int whence) ...@@ -813,7 +813,8 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int whence)
return generic_file_llseek(file, offset, whence); return generic_file_llseek(file, offset, whence);
} }
static int cifs_setlease(struct file *file, long arg, struct file_lock **lease) static int
cifs_setlease(struct file *file, long arg, struct file_lock **lease, void **priv)
{ {
/* /*
* Note that this is called by vfs setlease with i_lock held to * Note that this is called by vfs setlease with i_lock held to
...@@ -829,7 +830,7 @@ static int cifs_setlease(struct file *file, long arg, struct file_lock **lease) ...@@ -829,7 +830,7 @@ static int cifs_setlease(struct file *file, long arg, struct file_lock **lease)
if (arg == F_UNLCK || if (arg == F_UNLCK ||
((arg == F_RDLCK) && CIFS_CACHE_READ(CIFS_I(inode))) || ((arg == F_RDLCK) && CIFS_CACHE_READ(CIFS_I(inode))) ||
((arg == F_WRLCK) && CIFS_CACHE_WRITE(CIFS_I(inode)))) ((arg == F_WRLCK) && CIFS_CACHE_WRITE(CIFS_I(inode))))
return generic_setlease(file, arg, lease); return generic_setlease(file, arg, lease, priv);
else if (tlink_tcon(cfile->tlink)->local_lease && else if (tlink_tcon(cfile->tlink)->local_lease &&
!CIFS_CACHE_READ(CIFS_I(inode))) !CIFS_CACHE_READ(CIFS_I(inode)))
/* /*
...@@ -840,7 +841,7 @@ static int cifs_setlease(struct file *file, long arg, struct file_lock **lease) ...@@ -840,7 +841,7 @@ static int cifs_setlease(struct file *file, long arg, struct file_lock **lease)
* knows that the file won't be changed on the server by anyone * knows that the file won't be changed on the server by anyone
* else. * else.
*/ */
return generic_setlease(file, arg, lease); return generic_setlease(file, arg, lease, priv);
else else
return -EAGAIN; return -EAGAIN;
} }
......
...@@ -30,7 +30,7 @@ struct plock_op { ...@@ -30,7 +30,7 @@ struct plock_op {
struct plock_xop { struct plock_xop {
struct plock_op xop; struct plock_op xop;
void *callback; int (*callback)(struct file_lock *fl, int result);
void *fl; void *fl;
void *file; void *file;
struct file_lock flc; struct file_lock flc;
...@@ -190,7 +190,7 @@ static int dlm_plock_callback(struct plock_op *op) ...@@ -190,7 +190,7 @@ static int dlm_plock_callback(struct plock_op *op)
struct file *file; struct file *file;
struct file_lock *fl; struct file_lock *fl;
struct file_lock *flc; struct file_lock *flc;
int (*notify)(void *, void *, int) = NULL; int (*notify)(struct file_lock *fl, int result) = NULL;
struct plock_xop *xop = (struct plock_xop *)op; struct plock_xop *xop = (struct plock_xop *)op;
int rv = 0; int rv = 0;
...@@ -209,7 +209,7 @@ static int dlm_plock_callback(struct plock_op *op) ...@@ -209,7 +209,7 @@ static int dlm_plock_callback(struct plock_op *op)
notify = xop->callback; notify = xop->callback;
if (op->info.rv) { if (op->info.rv) {
notify(fl, NULL, op->info.rv); notify(fl, op->info.rv);
goto out; goto out;
} }
...@@ -228,7 +228,7 @@ static int dlm_plock_callback(struct plock_op *op) ...@@ -228,7 +228,7 @@ static int dlm_plock_callback(struct plock_op *op)
(unsigned long long)op->info.number, file, fl); (unsigned long long)op->info.number, file, fl);
} }
rv = notify(fl, NULL, 0); rv = notify(fl, 0);
if (rv) { if (rv) {
/* XXX: We need to cancel the fs lock here: */ /* XXX: We need to cancel the fs lock here: */
log_print("dlm_plock_callback: lock granted after lock request " log_print("dlm_plock_callback: lock granted after lock request "
......
...@@ -98,26 +98,19 @@ static void f_modown(struct file *filp, struct pid *pid, enum pid_type type, ...@@ -98,26 +98,19 @@ static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
write_unlock_irq(&filp->f_owner.lock); write_unlock_irq(&filp->f_owner.lock);
} }
int __f_setown(struct file *filp, struct pid *pid, enum pid_type type, void __f_setown(struct file *filp, struct pid *pid, enum pid_type type,
int force) int force)
{ {
int err; security_file_set_fowner(filp);
err = security_file_set_fowner(filp);
if (err)
return err;
f_modown(filp, pid, type, force); f_modown(filp, pid, type, force);
return 0;
} }
EXPORT_SYMBOL(__f_setown); EXPORT_SYMBOL(__f_setown);
int f_setown(struct file *filp, unsigned long arg, int force) void f_setown(struct file *filp, unsigned long arg, int force)
{ {
enum pid_type type; enum pid_type type;
struct pid *pid; struct pid *pid;
int who = arg; int who = arg;
int result;
type = PIDTYPE_PID; type = PIDTYPE_PID;
if (who < 0) { if (who < 0) {
type = PIDTYPE_PGID; type = PIDTYPE_PGID;
...@@ -125,9 +118,8 @@ int f_setown(struct file *filp, unsigned long arg, int force) ...@@ -125,9 +118,8 @@ int f_setown(struct file *filp, unsigned long arg, int force)
} }
rcu_read_lock(); rcu_read_lock();
pid = find_vpid(who); pid = find_vpid(who);
result = __f_setown(filp, pid, type, force); __f_setown(filp, pid, type, force);
rcu_read_unlock(); rcu_read_unlock();
return result;
} }
EXPORT_SYMBOL(f_setown); EXPORT_SYMBOL(f_setown);
...@@ -181,7 +173,7 @@ static int f_setown_ex(struct file *filp, unsigned long arg) ...@@ -181,7 +173,7 @@ static int f_setown_ex(struct file *filp, unsigned long arg)
if (owner.pid && !pid) if (owner.pid && !pid)
ret = -ESRCH; ret = -ESRCH;
else else
ret = __f_setown(filp, pid, type, 1); __f_setown(filp, pid, type, 1);
rcu_read_unlock(); rcu_read_unlock();
return ret; return ret;
...@@ -302,7 +294,8 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, ...@@ -302,7 +294,8 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
force_successful_syscall_return(); force_successful_syscall_return();
break; break;
case F_SETOWN: case F_SETOWN:
err = f_setown(filp, arg, 1); f_setown(filp, arg, 1);
err = 0;
break; break;
case F_GETOWN_EX: case F_GETOWN_EX:
err = f_getown_ex(filp, arg); err = f_getown_ex(filp, arg);
......
...@@ -913,26 +913,6 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, ...@@ -913,26 +913,6 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
#ifdef CONFIG_GFS2_FS_LOCKING_DLM #ifdef CONFIG_GFS2_FS_LOCKING_DLM
/**
* gfs2_setlease - acquire/release a file lease
* @file: the file pointer
* @arg: lease type
* @fl: file lock
*
* 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.
*
* Locking: called under i_lock
*
* Returns: errno
*/
static int gfs2_setlease(struct file *file, long arg, struct file_lock **fl)
{
return -EINVAL;
}
/** /**
* 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
...@@ -1078,7 +1058,7 @@ const struct file_operations gfs2_file_fops = { ...@@ -1078,7 +1058,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 = iter_file_splice_write, .splice_write = iter_file_splice_write,
.setlease = gfs2_setlease, .setlease = simple_nosetlease,
.fallocate = gfs2_fallocate, .fallocate = gfs2_fallocate,
}; };
......
...@@ -1075,3 +1075,21 @@ struct inode *alloc_anon_inode(struct super_block *s) ...@@ -1075,3 +1075,21 @@ struct inode *alloc_anon_inode(struct super_block *s)
return inode; return inode;
} }
EXPORT_SYMBOL(alloc_anon_inode); EXPORT_SYMBOL(alloc_anon_inode);
/**
* simple_nosetlease - generic helper for prohibiting leases
* @filp: file pointer
* @arg: type of lease to obtain
* @flp: new lease supplied for insertion
* @priv: private data for lm_setup operation
*
* Generic helper for filesystems that do not wish to allow leases to be set.
* All arguments are ignored and it just returns -EINVAL.
*/
int
simple_nosetlease(struct file *filp, long arg, struct file_lock **flp,
void **priv)
{
return -EINVAL;
}
EXPORT_SYMBOL(simple_nosetlease);
...@@ -245,7 +245,6 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_host *host, ...@@ -245,7 +245,6 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_host *host,
block->b_daemon = rqstp->rq_server; block->b_daemon = rqstp->rq_server;
block->b_host = host; block->b_host = host;
block->b_file = file; block->b_file = file;
block->b_fl = NULL;
file->f_count++; file->f_count++;
/* Add to file's list of blocks */ /* Add to file's list of blocks */
...@@ -295,7 +294,6 @@ static void nlmsvc_free_block(struct kref *kref) ...@@ -295,7 +294,6 @@ static void nlmsvc_free_block(struct kref *kref)
nlmsvc_freegrantargs(block->b_call); nlmsvc_freegrantargs(block->b_call);
nlmsvc_release_call(block->b_call); nlmsvc_release_call(block->b_call);
nlm_release_file(block->b_file); nlm_release_file(block->b_file);
kfree(block->b_fl);
kfree(block); kfree(block);
} }
...@@ -508,7 +506,6 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file, ...@@ -508,7 +506,6 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
struct nlm_host *host, struct nlm_lock *lock, struct nlm_host *host, struct nlm_lock *lock,
struct nlm_lock *conflock, struct nlm_cookie *cookie) struct nlm_lock *conflock, struct nlm_cookie *cookie)
{ {
struct nlm_block *block = NULL;
int error; int error;
__be32 ret; __be32 ret;
...@@ -519,63 +516,26 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file, ...@@ -519,63 +516,26 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
(long long)lock->fl.fl_start, (long long)lock->fl.fl_start,
(long long)lock->fl.fl_end); (long long)lock->fl.fl_end);
/* Get existing block (in case client is busy-waiting) */
block = nlmsvc_lookup_block(file, lock);
if (block == NULL) {
struct file_lock *conf = kzalloc(sizeof(*conf), GFP_KERNEL);
if (conf == NULL)
return nlm_granted;
block = nlmsvc_create_block(rqstp, host, file, lock, cookie);
if (block == NULL) {
kfree(conf);
return nlm_granted;
}
block->b_fl = conf;
}
if (block->b_flags & B_QUEUED) {
dprintk("lockd: nlmsvc_testlock deferred block %p flags %d fl %p\n",
block, block->b_flags, block->b_fl);
if (block->b_flags & B_TIMED_OUT) {
nlmsvc_unlink_block(block);
ret = nlm_lck_denied;
goto out;
}
if (block->b_flags & B_GOT_CALLBACK) {
nlmsvc_unlink_block(block);
if (block->b_fl != NULL
&& block->b_fl->fl_type != F_UNLCK) {
lock->fl = *block->b_fl;
goto conf_lock;
} else {
ret = nlm_granted;
goto out;
}
}
ret = nlm_drop_reply;
goto out;
}
if (locks_in_grace(SVC_NET(rqstp))) { if (locks_in_grace(SVC_NET(rqstp))) {
ret = nlm_lck_denied_grace_period; ret = nlm_lck_denied_grace_period;
goto out; goto out;
} }
error = vfs_test_lock(file->f_file, &lock->fl); error = vfs_test_lock(file->f_file, &lock->fl);
if (error == FILE_LOCK_DEFERRED) {
ret = nlmsvc_defer_lock_rqst(rqstp, block);
goto out;
}
if (error) { if (error) {
/* We can't currently deal with deferred test requests */
if (error == FILE_LOCK_DEFERRED)
WARN_ON_ONCE(1);
ret = nlm_lck_denied_nolocks; ret = nlm_lck_denied_nolocks;
goto out; goto out;
} }
if (lock->fl.fl_type == F_UNLCK) { if (lock->fl.fl_type == F_UNLCK) {
ret = nlm_granted; ret = nlm_granted;
goto out; goto out;
} }
conf_lock:
dprintk("lockd: conflicting lock(ty=%d, %Ld-%Ld)\n", dprintk("lockd: conflicting lock(ty=%d, %Ld-%Ld)\n",
lock->fl.fl_type, (long long)lock->fl.fl_start, lock->fl.fl_type, (long long)lock->fl.fl_start,
(long long)lock->fl.fl_end); (long long)lock->fl.fl_end);
...@@ -586,10 +546,9 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file, ...@@ -586,10 +546,9 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
conflock->fl.fl_type = lock->fl.fl_type; conflock->fl.fl_type = lock->fl.fl_type;
conflock->fl.fl_start = lock->fl.fl_start; conflock->fl.fl_start = lock->fl.fl_start;
conflock->fl.fl_end = lock->fl.fl_end; conflock->fl.fl_end = lock->fl.fl_end;
locks_release_private(&lock->fl);
ret = nlm_lck_denied; ret = nlm_lck_denied;
out: out:
if (block)
nlmsvc_release_block(block);
return ret; return ret;
} }
...@@ -660,29 +619,22 @@ nlmsvc_cancel_blocked(struct net *net, struct nlm_file *file, struct nlm_lock *l ...@@ -660,29 +619,22 @@ nlmsvc_cancel_blocked(struct net *net, struct nlm_file *file, struct nlm_lock *l
* This is a callback from the filesystem for VFS file lock requests. * This is a callback from the filesystem for VFS file lock requests.
* It will be used if lm_grant is defined and the filesystem can not * It will be used if lm_grant is defined and the filesystem can not
* respond to the request immediately. * respond to the request immediately.
* For GETLK request it will copy the reply to the nlm_block.
* For SETLK or SETLKW request it will get the local posix lock. * For SETLK or SETLKW request it will get the local posix lock.
* In all cases it will move the block to the head of nlm_blocked q where * In all cases it will move the block to the head of nlm_blocked q where
* nlmsvc_retry_blocked() can send back a reply for SETLKW or revisit the * nlmsvc_retry_blocked() can send back a reply for SETLKW or revisit the
* deferred rpc for GETLK and SETLK. * deferred rpc for GETLK and SETLK.
*/ */
static void static void
nlmsvc_update_deferred_block(struct nlm_block *block, struct file_lock *conf, nlmsvc_update_deferred_block(struct nlm_block *block, int result)
int result)
{ {
block->b_flags |= B_GOT_CALLBACK; block->b_flags |= B_GOT_CALLBACK;
if (result == 0) if (result == 0)
block->b_granted = 1; block->b_granted = 1;
else else
block->b_flags |= B_TIMED_OUT; block->b_flags |= B_TIMED_OUT;
if (conf) {
if (block->b_fl)
__locks_copy_lock(block->b_fl, conf);
}
} }
static int nlmsvc_grant_deferred(struct file_lock *fl, struct file_lock *conf, static int nlmsvc_grant_deferred(struct file_lock *fl, int result)
int result)
{ {
struct nlm_block *block; struct nlm_block *block;
int rc = -ENOENT; int rc = -ENOENT;
...@@ -697,7 +649,7 @@ static int nlmsvc_grant_deferred(struct file_lock *fl, struct file_lock *conf, ...@@ -697,7 +649,7 @@ static int nlmsvc_grant_deferred(struct file_lock *fl, struct file_lock *conf,
rc = -ENOLCK; rc = -ENOLCK;
break; break;
} }
nlmsvc_update_deferred_block(block, conf, result); nlmsvc_update_deferred_block(block, result);
} else if (result == 0) } else if (result == 0)
block->b_granted = 1; block->b_granted = 1;
......
此差异已折叠。
...@@ -919,17 +919,6 @@ int nfs_flock(struct file *filp, int cmd, struct file_lock *fl) ...@@ -919,17 +919,6 @@ int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
} }
EXPORT_SYMBOL_GPL(nfs_flock); EXPORT_SYMBOL_GPL(nfs_flock);
/*
* There is no protocol support for leases, so we have no way to implement
* them correctly in the face of opens by other clients.
*/
int nfs_setlease(struct file *file, long arg, struct file_lock **fl)
{
dprintk("NFS: setlease(%pD2, arg=%ld)\n", file, arg);
return -EINVAL;
}
EXPORT_SYMBOL_GPL(nfs_setlease);
const struct file_operations nfs_file_operations = { const struct file_operations nfs_file_operations = {
.llseek = nfs_file_llseek, .llseek = nfs_file_llseek,
.read = new_sync_read, .read = new_sync_read,
...@@ -946,6 +935,6 @@ const struct file_operations nfs_file_operations = { ...@@ -946,6 +935,6 @@ const struct file_operations nfs_file_operations = {
.splice_read = nfs_file_splice_read, .splice_read = nfs_file_splice_read,
.splice_write = iter_file_splice_write, .splice_write = iter_file_splice_write,
.check_flags = nfs_check_flags, .check_flags = nfs_check_flags,
.setlease = nfs_setlease, .setlease = simple_nosetlease,
}; };
EXPORT_SYMBOL_GPL(nfs_file_operations); EXPORT_SYMBOL_GPL(nfs_file_operations);
...@@ -339,7 +339,6 @@ int nfs_file_release(struct inode *, struct file *); ...@@ -339,7 +339,6 @@ int nfs_file_release(struct inode *, struct file *);
int nfs_lock(struct file *, int, struct file_lock *); int nfs_lock(struct file *, int, struct file_lock *);
int nfs_flock(struct file *, int, struct file_lock *); int nfs_flock(struct file *, int, struct file_lock *);
int nfs_check_flags(int); int nfs_check_flags(int);
int nfs_setlease(struct file *, long, struct file_lock **);
/* inode.c */ /* inode.c */
extern struct workqueue_struct *nfsiod_workqueue; extern struct workqueue_struct *nfsiod_workqueue;
......
...@@ -131,5 +131,5 @@ const struct file_operations nfs4_file_operations = { ...@@ -131,5 +131,5 @@ const struct file_operations nfs4_file_operations = {
.splice_read = nfs_file_splice_read, .splice_read = nfs_file_splice_read,
.splice_write = iter_file_splice_write, .splice_write = iter_file_splice_write,
.check_flags = nfs_check_flags, .check_flags = nfs_check_flags,
.setlease = nfs_setlease, .setlease = simple_nosetlease,
}; };
...@@ -218,6 +218,13 @@ static void nfsd4_put_session(struct nfsd4_session *ses) ...@@ -218,6 +218,13 @@ static void nfsd4_put_session(struct nfsd4_session *ses)
spin_unlock(&nn->client_lock); spin_unlock(&nn->client_lock);
} }
static inline struct nfs4_stateowner *
nfs4_get_stateowner(struct nfs4_stateowner *sop)
{
atomic_inc(&sop->so_count);
return sop;
}
static int static int
same_owner_str(struct nfs4_stateowner *sop, struct xdr_netobj *owner) same_owner_str(struct nfs4_stateowner *sop, struct xdr_netobj *owner)
{ {
...@@ -237,10 +244,8 @@ find_openstateowner_str_locked(unsigned int hashval, struct nfsd4_open *open, ...@@ -237,10 +244,8 @@ find_openstateowner_str_locked(unsigned int hashval, struct nfsd4_open *open,
so_strhash) { so_strhash) {
if (!so->so_is_open_owner) if (!so->so_is_open_owner)
continue; continue;
if (same_owner_str(so, &open->op_owner)) { if (same_owner_str(so, &open->op_owner))
atomic_inc(&so->so_count); return openowner(nfs4_get_stateowner(so));
return openowner(so);
}
} }
return NULL; return NULL;
} }
...@@ -678,18 +683,14 @@ nfs4_put_stid(struct nfs4_stid *s) ...@@ -678,18 +683,14 @@ nfs4_put_stid(struct nfs4_stid *s)
static void nfs4_put_deleg_lease(struct nfs4_file *fp) static void nfs4_put_deleg_lease(struct nfs4_file *fp)
{ {
struct file *filp = NULL; struct file *filp = NULL;
struct file_lock *fl;
spin_lock(&fp->fi_lock); spin_lock(&fp->fi_lock);
if (fp->fi_lease && atomic_dec_and_test(&fp->fi_delegees)) { if (fp->fi_deleg_file && atomic_dec_and_test(&fp->fi_delegees))
swap(filp, fp->fi_deleg_file); swap(filp, fp->fi_deleg_file);
fl = fp->fi_lease;
fp->fi_lease = NULL;
}
spin_unlock(&fp->fi_lock); spin_unlock(&fp->fi_lock);
if (filp) { if (filp) {
vfs_setlease(filp, F_UNLCK, &fl); vfs_setlease(filp, F_UNLCK, NULL, NULL);
fput(filp); fput(filp);
} }
} }
...@@ -1655,7 +1656,7 @@ __destroy_client(struct nfs4_client *clp) ...@@ -1655,7 +1656,7 @@ __destroy_client(struct nfs4_client *clp)
} }
while (!list_empty(&clp->cl_openowners)) { while (!list_empty(&clp->cl_openowners)) {
oo = list_entry(clp->cl_openowners.next, struct nfs4_openowner, oo_perclient); oo = list_entry(clp->cl_openowners.next, struct nfs4_openowner, oo_perclient);
atomic_inc(&oo->oo_owner.so_count); nfs4_get_stateowner(&oo->oo_owner);
release_openowner(oo); release_openowner(oo);
} }
nfsd4_shutdown_callback(clp); nfsd4_shutdown_callback(clp);
...@@ -3067,8 +3068,8 @@ static void nfsd4_init_file(struct nfs4_file *fp, struct knfsd_fh *fh) ...@@ -3067,8 +3068,8 @@ static void nfsd4_init_file(struct nfs4_file *fp, struct knfsd_fh *fh)
INIT_LIST_HEAD(&fp->fi_stateids); INIT_LIST_HEAD(&fp->fi_stateids);
INIT_LIST_HEAD(&fp->fi_delegations); INIT_LIST_HEAD(&fp->fi_delegations);
fh_copy_shallow(&fp->fi_fhandle, fh); fh_copy_shallow(&fp->fi_fhandle, fh);
fp->fi_deleg_file = NULL;
fp->fi_had_conflict = false; fp->fi_had_conflict = false;
fp->fi_lease = NULL;
fp->fi_share_deny = 0; fp->fi_share_deny = 0;
memset(fp->fi_fds, 0, sizeof(fp->fi_fds)); memset(fp->fi_fds, 0, sizeof(fp->fi_fds));
memset(fp->fi_access, 0, sizeof(fp->fi_access)); memset(fp->fi_access, 0, sizeof(fp->fi_access));
...@@ -3136,8 +3137,7 @@ static void nfsd4_cstate_assign_replay(struct nfsd4_compound_state *cstate, ...@@ -3136,8 +3137,7 @@ static void nfsd4_cstate_assign_replay(struct nfsd4_compound_state *cstate,
{ {
if (!nfsd4_has_session(cstate)) { if (!nfsd4_has_session(cstate)) {
mutex_lock(&so->so_replay.rp_mutex); mutex_lock(&so->so_replay.rp_mutex);
cstate->replay_owner = so; cstate->replay_owner = nfs4_get_stateowner(so);
atomic_inc(&so->so_count);
} }
} }
...@@ -3236,8 +3236,7 @@ static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp, ...@@ -3236,8 +3236,7 @@ static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp,
atomic_inc(&stp->st_stid.sc_count); atomic_inc(&stp->st_stid.sc_count);
stp->st_stid.sc_type = NFS4_OPEN_STID; stp->st_stid.sc_type = NFS4_OPEN_STID;
INIT_LIST_HEAD(&stp->st_locks); INIT_LIST_HEAD(&stp->st_locks);
stp->st_stateowner = &oo->oo_owner; stp->st_stateowner = nfs4_get_stateowner(&oo->oo_owner);
atomic_inc(&stp->st_stateowner->so_count);
get_nfs4_file(fp); get_nfs4_file(fp);
stp->st_stid.sc_file = fp; stp->st_stid.sc_file = fp;
stp->st_access_bmap = 0; stp->st_access_bmap = 0;
...@@ -3434,18 +3433,20 @@ static void nfsd_break_one_deleg(struct nfs4_delegation *dp) ...@@ -3434,18 +3433,20 @@ static void nfsd_break_one_deleg(struct nfs4_delegation *dp)
} }
/* Called from break_lease() with i_lock held. */ /* Called from break_lease() with i_lock held. */
static void nfsd_break_deleg_cb(struct file_lock *fl) static bool
nfsd_break_deleg_cb(struct file_lock *fl)
{ {
bool ret = false;
struct nfs4_file *fp = (struct nfs4_file *)fl->fl_owner; struct nfs4_file *fp = (struct nfs4_file *)fl->fl_owner;
struct nfs4_delegation *dp; struct nfs4_delegation *dp;
if (!fp) { if (!fp) {
WARN(1, "(%p)->fl_owner NULL\n", fl); WARN(1, "(%p)->fl_owner NULL\n", fl);
return; return ret;
} }
if (fp->fi_had_conflict) { if (fp->fi_had_conflict) {
WARN(1, "duplicate break on %p\n", fp); WARN(1, "duplicate break on %p\n", fp);
return; return ret;
} }
/* /*
* We don't want the locks code to timeout the lease for us; * We don't want the locks code to timeout the lease for us;
...@@ -3457,24 +3458,23 @@ static void nfsd_break_deleg_cb(struct file_lock *fl) ...@@ -3457,24 +3458,23 @@ static void nfsd_break_deleg_cb(struct file_lock *fl)
spin_lock(&fp->fi_lock); spin_lock(&fp->fi_lock);
fp->fi_had_conflict = true; fp->fi_had_conflict = true;
/* /*
* If there are no delegations on the list, then we can't count on this * If there are no delegations on the list, then return true
* lease ever being cleaned up. Set the fl_break_time to jiffies so that * so that the lease code will go ahead and delete it.
* time_out_leases will do it ASAP. The fact that fi_had_conflict is now
* true should keep any new delegations from being hashed.
*/ */
if (list_empty(&fp->fi_delegations)) if (list_empty(&fp->fi_delegations))
fl->fl_break_time = jiffies; ret = true;
else else
list_for_each_entry(dp, &fp->fi_delegations, dl_perfile) list_for_each_entry(dp, &fp->fi_delegations, dl_perfile)
nfsd_break_one_deleg(dp); nfsd_break_one_deleg(dp);
spin_unlock(&fp->fi_lock); spin_unlock(&fp->fi_lock);
return ret;
} }
static static int
int nfsd_change_deleg_cb(struct file_lock **onlist, int arg) nfsd_change_deleg_cb(struct file_lock **onlist, int arg, struct list_head *dispose)
{ {
if (arg & F_UNLCK) if (arg & F_UNLCK)
return lease_modify(onlist, arg); return lease_modify(onlist, arg, dispose);
else else
return -EAGAIN; return -EAGAIN;
} }
...@@ -3820,7 +3820,7 @@ static struct file_lock *nfs4_alloc_init_lease(struct nfs4_file *fp, int flag) ...@@ -3820,7 +3820,7 @@ static struct file_lock *nfs4_alloc_init_lease(struct nfs4_file *fp, int flag)
static int nfs4_setlease(struct nfs4_delegation *dp) static int nfs4_setlease(struct nfs4_delegation *dp)
{ {
struct nfs4_file *fp = dp->dl_stid.sc_file; struct nfs4_file *fp = dp->dl_stid.sc_file;
struct file_lock *fl; struct file_lock *fl, *ret;
struct file *filp; struct file *filp;
int status = 0; int status = 0;
...@@ -3834,11 +3834,12 @@ static int nfs4_setlease(struct nfs4_delegation *dp) ...@@ -3834,11 +3834,12 @@ static int nfs4_setlease(struct nfs4_delegation *dp)
return -EBADF; return -EBADF;
} }
fl->fl_file = filp; fl->fl_file = filp;
status = vfs_setlease(filp, fl->fl_type, &fl); ret = fl;
if (status) { status = vfs_setlease(filp, fl->fl_type, &fl, NULL);
if (fl)
locks_free_lock(fl); locks_free_lock(fl);
if (status)
goto out_fput; goto out_fput;
}
spin_lock(&state_lock); spin_lock(&state_lock);
spin_lock(&fp->fi_lock); spin_lock(&fp->fi_lock);
/* Did the lease get broken before we took the lock? */ /* Did the lease get broken before we took the lock? */
...@@ -3846,13 +3847,12 @@ static int nfs4_setlease(struct nfs4_delegation *dp) ...@@ -3846,13 +3847,12 @@ static int nfs4_setlease(struct nfs4_delegation *dp)
if (fp->fi_had_conflict) if (fp->fi_had_conflict)
goto out_unlock; goto out_unlock;
/* Race breaker */ /* Race breaker */
if (fp->fi_lease) { if (fp->fi_deleg_file) {
status = 0; status = 0;
atomic_inc(&fp->fi_delegees); atomic_inc(&fp->fi_delegees);
hash_delegation_locked(dp, fp); hash_delegation_locked(dp, fp);
goto out_unlock; goto out_unlock;
} }
fp->fi_lease = fl;
fp->fi_deleg_file = filp; fp->fi_deleg_file = filp;
atomic_set(&fp->fi_delegees, 1); atomic_set(&fp->fi_delegees, 1);
hash_delegation_locked(dp, fp); hash_delegation_locked(dp, fp);
...@@ -3885,7 +3885,7 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh, ...@@ -3885,7 +3885,7 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh,
spin_lock(&state_lock); spin_lock(&state_lock);
spin_lock(&fp->fi_lock); spin_lock(&fp->fi_lock);
dp->dl_stid.sc_file = fp; dp->dl_stid.sc_file = fp;
if (!fp->fi_lease) { if (!fp->fi_deleg_file) {
spin_unlock(&fp->fi_lock); spin_unlock(&fp->fi_lock);
spin_unlock(&state_lock); spin_unlock(&state_lock);
status = nfs4_setlease(dp); status = nfs4_setlease(dp);
...@@ -4929,9 +4929,25 @@ nfs4_transform_lock_offset(struct file_lock *lock) ...@@ -4929,9 +4929,25 @@ nfs4_transform_lock_offset(struct file_lock *lock)
lock->fl_end = OFFSET_MAX; lock->fl_end = OFFSET_MAX;
} }
/* Hack!: For now, we're defining this just so we can use a pointer to it static void nfsd4_fl_get_owner(struct file_lock *dst, struct file_lock *src)
* as a unique cookie to identify our (NFSv4's) posix locks. */ {
struct nfs4_lockowner *lo = (struct nfs4_lockowner *)src->fl_owner;
dst->fl_owner = (fl_owner_t)lockowner(nfs4_get_stateowner(&lo->lo_owner));
}
static void nfsd4_fl_put_owner(struct file_lock *fl)
{
struct nfs4_lockowner *lo = (struct nfs4_lockowner *)fl->fl_owner;
if (lo) {
nfs4_put_stateowner(&lo->lo_owner);
fl->fl_owner = NULL;
}
}
static const struct lock_manager_operations nfsd_posix_mng_ops = { static const struct lock_manager_operations nfsd_posix_mng_ops = {
.lm_get_owner = nfsd4_fl_get_owner,
.lm_put_owner = nfsd4_fl_put_owner,
}; };
static inline void static inline void
...@@ -4977,10 +4993,8 @@ find_lockowner_str_locked(clientid_t *clid, struct xdr_netobj *owner, ...@@ -4977,10 +4993,8 @@ find_lockowner_str_locked(clientid_t *clid, struct xdr_netobj *owner,
so_strhash) { so_strhash) {
if (so->so_is_open_owner) if (so->so_is_open_owner)
continue; continue;
if (!same_owner_str(so, owner)) if (same_owner_str(so, owner))
continue; return lockowner(nfs4_get_stateowner(so));
atomic_inc(&so->so_count);
return lockowner(so);
} }
return NULL; return NULL;
} }
...@@ -5059,8 +5073,7 @@ init_lock_stateid(struct nfs4_ol_stateid *stp, struct nfs4_lockowner *lo, ...@@ -5059,8 +5073,7 @@ init_lock_stateid(struct nfs4_ol_stateid *stp, struct nfs4_lockowner *lo,
atomic_inc(&stp->st_stid.sc_count); atomic_inc(&stp->st_stid.sc_count);
stp->st_stid.sc_type = NFS4_LOCK_STID; stp->st_stid.sc_type = NFS4_LOCK_STID;
stp->st_stateowner = &lo->lo_owner; stp->st_stateowner = nfs4_get_stateowner(&lo->lo_owner);
atomic_inc(&lo->lo_owner.so_count);
get_nfs4_file(fp); get_nfs4_file(fp);
stp->st_stid.sc_file = fp; stp->st_stid.sc_file = fp;
stp->st_stid.sc_free = nfs4_free_lock_stateid; stp->st_stid.sc_free = nfs4_free_lock_stateid;
...@@ -5299,7 +5312,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, ...@@ -5299,7 +5312,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
status = nfserr_openmode; status = nfserr_openmode;
goto out; goto out;
} }
file_lock->fl_owner = (fl_owner_t)lock_sop;
file_lock->fl_owner = (fl_owner_t)lockowner(nfs4_get_stateowner(&lock_sop->lo_owner));
file_lock->fl_pid = current->tgid; file_lock->fl_pid = current->tgid;
file_lock->fl_file = filp; file_lock->fl_file = filp;
file_lock->fl_flags = FL_POSIX; file_lock->fl_flags = FL_POSIX;
...@@ -5495,7 +5509,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, ...@@ -5495,7 +5509,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
} }
file_lock->fl_type = F_UNLCK; file_lock->fl_type = F_UNLCK;
file_lock->fl_owner = (fl_owner_t)lockowner(stp->st_stateowner); file_lock->fl_owner = (fl_owner_t)lockowner(nfs4_get_stateowner(stp->st_stateowner));
file_lock->fl_pid = current->tgid; file_lock->fl_pid = current->tgid;
file_lock->fl_file = filp; file_lock->fl_file = filp;
file_lock->fl_flags = FL_POSIX; file_lock->fl_flags = FL_POSIX;
...@@ -5602,7 +5616,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, ...@@ -5602,7 +5616,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
} }
} }
atomic_inc(&sop->so_count); nfs4_get_stateowner(sop);
break; break;
} }
spin_unlock(&clp->cl_lock); spin_unlock(&clp->cl_lock);
......
...@@ -486,7 +486,6 @@ struct nfs4_file { ...@@ -486,7 +486,6 @@ struct nfs4_file {
atomic_t fi_access[2]; atomic_t fi_access[2];
u32 fi_share_deny; u32 fi_share_deny;
struct file *fi_deleg_file; struct file *fi_deleg_file;
struct file_lock *fi_lease;
atomic_t fi_delegees; atomic_t fi_delegees;
struct knfsd_fh fi_fhandle; struct knfsd_fh fi_fhandle;
bool fi_had_conflict; bool fi_had_conflict;
......
...@@ -346,13 +346,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg) ...@@ -346,13 +346,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
goto out; goto out;
} }
error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0); __f_setown(filp, task_pid(current), PIDTYPE_PID, 0);
if (error) {
/* if we added, we must shoot */
if (dn_mark == new_dn_mark)
destroy = 1;
goto out;
}
error = attach_dn(dn, dn_mark, id, fd, filp, mask); error = attach_dn(dn, dn_mark, id, fd, filp, mask);
/* !error means that we attached the dn to the dn_mark, so don't free it */ /* !error means that we attached the dn to the dn_mark, so don't free it */
......
...@@ -851,13 +851,7 @@ static inline struct file *get_file(struct file *f) ...@@ -851,13 +851,7 @@ static inline struct file *get_file(struct file *f)
*/ */
#define FILE_LOCK_DEFERRED 1 #define FILE_LOCK_DEFERRED 1
/* /* legacy typedef, should eventually be removed */
* The POSIX file lock owner is determined by
* the "struct files_struct" in the thread group
* (or NULL for no owner - BSD locks).
*
* Lockd stuffs a "host" pointer into this.
*/
typedef void *fl_owner_t; typedef void *fl_owner_t;
struct file_lock_operations { struct file_lock_operations {
...@@ -868,10 +862,13 @@ struct file_lock_operations { ...@@ -868,10 +862,13 @@ struct file_lock_operations {
struct lock_manager_operations { struct lock_manager_operations {
int (*lm_compare_owner)(struct file_lock *, struct file_lock *); int (*lm_compare_owner)(struct file_lock *, struct file_lock *);
unsigned long (*lm_owner_key)(struct file_lock *); unsigned long (*lm_owner_key)(struct file_lock *);
void (*lm_get_owner)(struct file_lock *, struct file_lock *);
void (*lm_put_owner)(struct file_lock *);
void (*lm_notify)(struct file_lock *); /* unblock callback */ void (*lm_notify)(struct file_lock *); /* unblock callback */
int (*lm_grant)(struct file_lock *, struct file_lock *, int); int (*lm_grant)(struct file_lock *, int);
void (*lm_break)(struct file_lock *); bool (*lm_break)(struct file_lock *);
int (*lm_change)(struct file_lock **, int); int (*lm_change)(struct file_lock **, int, struct list_head *);
void (*lm_setup)(struct file_lock *, void **);
}; };
struct lock_manager { struct lock_manager {
...@@ -966,7 +963,7 @@ void locks_free_lock(struct file_lock *fl); ...@@ -966,7 +963,7 @@ void locks_free_lock(struct file_lock *fl);
extern void locks_init_lock(struct file_lock *); extern void locks_init_lock(struct file_lock *);
extern struct file_lock * locks_alloc_lock(void); extern struct file_lock * locks_alloc_lock(void);
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_copy_lock(struct file_lock *, const struct file_lock *); extern void locks_copy_conflock(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_file(struct file *); extern void locks_remove_file(struct file *);
extern void locks_release_private(struct file_lock *); extern void locks_release_private(struct file_lock *);
...@@ -980,11 +977,9 @@ extern int vfs_cancel_lock(struct file *filp, struct file_lock *fl); ...@@ -980,11 +977,9 @@ extern int vfs_cancel_lock(struct file *filp, struct file_lock *fl);
extern int flock_lock_file_wait(struct file *filp, struct file_lock *fl); extern int flock_lock_file_wait(struct file *filp, struct file_lock *fl);
extern int __break_lease(struct inode *inode, unsigned int flags, unsigned int type); extern int __break_lease(struct inode *inode, unsigned int flags, unsigned int type);
extern void lease_get_mtime(struct inode *, struct timespec *time); extern void lease_get_mtime(struct inode *, struct timespec *time);
extern int generic_setlease(struct file *, long, struct file_lock **); extern int generic_setlease(struct file *, long, struct file_lock **, void **priv);
extern int vfs_setlease(struct file *, long, struct file_lock **); extern int vfs_setlease(struct file *, long, struct file_lock **, void **);
extern int lease_modify(struct file_lock **, int); extern int lease_modify(struct file_lock **, int, struct list_head *);
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);
#else /* !CONFIG_FILE_LOCKING */ #else /* !CONFIG_FILE_LOCKING */
static inline int fcntl_getlk(struct file *file, unsigned int cmd, static inline int fcntl_getlk(struct file *file, unsigned int cmd,
struct flock __user *user) struct flock __user *user)
...@@ -1013,12 +1008,12 @@ static inline int fcntl_setlk64(unsigned int fd, struct file *file, ...@@ -1013,12 +1008,12 @@ static inline int fcntl_setlk64(unsigned int fd, struct file *file,
#endif #endif
static inline int fcntl_setlease(unsigned int fd, struct file *filp, long arg) static inline int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
{ {
return 0; return -EINVAL;
} }
static inline int fcntl_getlease(struct file *filp) static inline int fcntl_getlease(struct file *filp)
{ {
return 0; return F_UNLCK;
} }
static inline void locks_init_lock(struct file_lock *fl) static inline void locks_init_lock(struct file_lock *fl)
...@@ -1026,7 +1021,7 @@ static inline void locks_init_lock(struct file_lock *fl) ...@@ -1026,7 +1021,7 @@ static inline void locks_init_lock(struct file_lock *fl)
return; return;
} }
static inline void __locks_copy_lock(struct file_lock *new, struct file_lock *fl) static inline void locks_copy_conflock(struct file_lock *new, struct file_lock *fl)
{ {
return; return;
} }
...@@ -1100,33 +1095,22 @@ static inline void lease_get_mtime(struct inode *inode, struct timespec *time) ...@@ -1100,33 +1095,22 @@ static inline void lease_get_mtime(struct inode *inode, struct timespec *time)
} }
static inline int generic_setlease(struct file *filp, long arg, static inline int generic_setlease(struct file *filp, long arg,
struct file_lock **flp) struct file_lock **flp, void **priv)
{ {
return -EINVAL; return -EINVAL;
} }
static inline int vfs_setlease(struct file *filp, long arg, static inline int vfs_setlease(struct file *filp, long arg,
struct file_lock **lease) struct file_lock **lease, void **priv)
{ {
return -EINVAL; return -EINVAL;
} }
static inline int lease_modify(struct file_lock **before, int arg) static inline int lease_modify(struct file_lock **before, int arg,
struct list_head *dispose)
{ {
return -EINVAL; return -EINVAL;
} }
static inline int lock_may_read(struct inode *inode, loff_t start,
unsigned long len)
{
return 1;
}
static inline int lock_may_write(struct inode *inode, loff_t start,
unsigned long len)
{
return 1;
}
#endif /* !CONFIG_FILE_LOCKING */ #endif /* !CONFIG_FILE_LOCKING */
...@@ -1151,8 +1135,8 @@ extern void fasync_free(struct fasync_struct *); ...@@ -1151,8 +1135,8 @@ extern void fasync_free(struct fasync_struct *);
/* can be called from interrupts */ /* can be called from interrupts */
extern void kill_fasync(struct fasync_struct **, int, int); extern void kill_fasync(struct fasync_struct **, int, int);
extern int __f_setown(struct file *filp, struct pid *, enum pid_type, int force); extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force);
extern int f_setown(struct file *filp, unsigned long arg, int force); extern void f_setown(struct file *filp, unsigned long arg, int force);
extern void f_delown(struct file *filp); extern void f_delown(struct file *filp);
extern pid_t f_getown(struct file *filp); extern pid_t f_getown(struct file *filp);
extern int send_sigurg(struct fown_struct *fown); extern int send_sigurg(struct fown_struct *fown);
...@@ -1506,7 +1490,7 @@ struct file_operations { ...@@ -1506,7 +1490,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 **); int (*setlease)(struct file *, long, struct file_lock **, void **);
long (*fallocate)(struct file *file, int mode, loff_t offset, long (*fallocate)(struct file *file, int mode, loff_t offset,
loff_t len); loff_t len);
int (*show_fdinfo)(struct seq_file *m, struct file *f); int (*show_fdinfo)(struct seq_file *m, struct file *f);
...@@ -2611,6 +2595,7 @@ extern int simple_write_end(struct file *file, struct address_space *mapping, ...@@ -2611,6 +2595,7 @@ extern int simple_write_end(struct file *file, struct address_space *mapping,
struct page *page, void *fsdata); struct page *page, void *fsdata);
extern int always_delete_dentry(const struct dentry *); extern int always_delete_dentry(const struct dentry *);
extern struct inode *alloc_anon_inode(struct super_block *); extern struct inode *alloc_anon_inode(struct super_block *);
extern int simple_nosetlease(struct file *, long, struct file_lock **, void **);
extern const struct dentry_operations simple_dentry_operations; extern const struct dentry_operations simple_dentry_operations;
extern struct dentry *simple_lookup(struct inode *, struct dentry *, unsigned int flags); extern struct dentry *simple_lookup(struct inode *, struct dentry *, unsigned int flags);
......
...@@ -178,7 +178,6 @@ struct nlm_block { ...@@ -178,7 +178,6 @@ struct nlm_block {
unsigned char b_granted; /* VFS granted lock */ unsigned char b_granted; /* VFS granted lock */
struct nlm_file * b_file; /* file in question */ struct nlm_file * b_file; /* file in question */
struct cache_req * b_cache_req; /* deferred request handling */ struct cache_req * b_cache_req; /* deferred request handling */
struct file_lock * b_fl; /* set for GETLK */
struct cache_deferred_req * b_deferred_req; struct cache_deferred_req * b_deferred_req;
unsigned int b_flags; /* block flags */ unsigned int b_flags; /* block flags */
#define B_QUEUED 1 /* lock queued */ #define B_QUEUED 1 /* lock queued */
......
...@@ -1559,7 +1559,7 @@ struct security_operations { ...@@ -1559,7 +1559,7 @@ struct security_operations {
int (*file_lock) (struct file *file, unsigned int cmd); int (*file_lock) (struct file *file, unsigned int cmd);
int (*file_fcntl) (struct file *file, unsigned int cmd, int (*file_fcntl) (struct file *file, unsigned int cmd,
unsigned long arg); unsigned long arg);
int (*file_set_fowner) (struct file *file); void (*file_set_fowner) (struct file *file);
int (*file_send_sigiotask) (struct task_struct *tsk, int (*file_send_sigiotask) (struct task_struct *tsk,
struct fown_struct *fown, int sig); struct fown_struct *fown, int sig);
int (*file_receive) (struct file *file); int (*file_receive) (struct file *file);
...@@ -1834,7 +1834,7 @@ int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, ...@@ -1834,7 +1834,7 @@ int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
unsigned long prot); unsigned long prot);
int security_file_lock(struct file *file, unsigned int cmd); int security_file_lock(struct file *file, unsigned int cmd);
int security_file_fcntl(struct file *file, unsigned int cmd, unsigned long arg); int security_file_fcntl(struct file *file, unsigned int cmd, unsigned long arg);
int security_file_set_fowner(struct file *file); void security_file_set_fowner(struct file *file);
int security_file_send_sigiotask(struct task_struct *tsk, int security_file_send_sigiotask(struct task_struct *tsk,
struct fown_struct *fown, int sig); struct fown_struct *fown, int sig);
int security_file_receive(struct file *file); int security_file_receive(struct file *file);
...@@ -2312,9 +2312,9 @@ static inline int security_file_fcntl(struct file *file, unsigned int cmd, ...@@ -2312,9 +2312,9 @@ static inline int security_file_fcntl(struct file *file, unsigned int cmd,
return 0; return 0;
} }
static inline int security_file_set_fowner(struct file *file) static inline void security_file_set_fowner(struct file *file)
{ {
return 0; return;
} }
static inline int security_file_send_sigiotask(struct task_struct *tsk, static inline int security_file_send_sigiotask(struct task_struct *tsk,
......
...@@ -53,15 +53,15 @@ DECLARE_EVENT_CLASS(filelock_lease, ...@@ -53,15 +53,15 @@ DECLARE_EVENT_CLASS(filelock_lease,
), ),
TP_fast_assign( TP_fast_assign(
__entry->fl = fl; __entry->fl = fl ? fl : NULL;
__entry->s_dev = inode->i_sb->s_dev; __entry->s_dev = inode->i_sb->s_dev;
__entry->i_ino = inode->i_ino; __entry->i_ino = inode->i_ino;
__entry->fl_next = fl->fl_next; __entry->fl_next = fl ? fl->fl_next : NULL;
__entry->fl_owner = fl->fl_owner; __entry->fl_owner = fl ? fl->fl_owner : NULL;
__entry->fl_flags = fl->fl_flags; __entry->fl_flags = fl ? fl->fl_flags : 0;
__entry->fl_type = fl->fl_type; __entry->fl_type = fl ? fl->fl_type : 0;
__entry->fl_break_time = fl->fl_break_time; __entry->fl_break_time = fl ? fl->fl_break_time : 0;
__entry->fl_downgrade_time = fl->fl_downgrade_time; __entry->fl_downgrade_time = fl ? fl->fl_downgrade_time : 0;
), ),
TP_printk("fl=0x%p dev=0x%x:0x%x ino=0x%lx fl_next=0x%p fl_owner=0x%p fl_flags=%s fl_type=%s fl_break_time=%lu fl_downgrade_time=%lu", TP_printk("fl=0x%p dev=0x%x:0x%x ino=0x%lx fl_next=0x%p fl_owner=0x%p fl_flags=%s fl_type=%s fl_break_time=%lu fl_downgrade_time=%lu",
......
...@@ -1065,7 +1065,8 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg) ...@@ -1065,7 +1065,8 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
err = -EFAULT; err = -EFAULT;
if (get_user(pid, (int __user *)argp)) if (get_user(pid, (int __user *)argp))
break; break;
err = f_setown(sock->file, pid, 1); f_setown(sock->file, pid, 1);
err = 0;
break; break;
case FIOGETOWN: case FIOGETOWN:
case SIOCGPGRP: case SIOCGPGRP:
......
...@@ -343,9 +343,9 @@ static int cap_file_fcntl(struct file *file, unsigned int cmd, ...@@ -343,9 +343,9 @@ static int cap_file_fcntl(struct file *file, unsigned int cmd,
return 0; return 0;
} }
static int cap_file_set_fowner(struct file *file) static void cap_file_set_fowner(struct file *file)
{ {
return 0; return;
} }
static int cap_file_send_sigiotask(struct task_struct *tsk, static int cap_file_send_sigiotask(struct task_struct *tsk,
......
...@@ -775,9 +775,9 @@ int security_file_fcntl(struct file *file, unsigned int cmd, unsigned long arg) ...@@ -775,9 +775,9 @@ int security_file_fcntl(struct file *file, unsigned int cmd, unsigned long arg)
return security_ops->file_fcntl(file, cmd, arg); return security_ops->file_fcntl(file, cmd, arg);
} }
int security_file_set_fowner(struct file *file) void security_file_set_fowner(struct file *file)
{ {
return security_ops->file_set_fowner(file); security_ops->file_set_fowner(file);
} }
int security_file_send_sigiotask(struct task_struct *tsk, int security_file_send_sigiotask(struct task_struct *tsk,
......
...@@ -3346,14 +3346,12 @@ static int selinux_file_fcntl(struct file *file, unsigned int cmd, ...@@ -3346,14 +3346,12 @@ static int selinux_file_fcntl(struct file *file, unsigned int cmd,
return err; return err;
} }
static int selinux_file_set_fowner(struct file *file) static void selinux_file_set_fowner(struct file *file)
{ {
struct file_security_struct *fsec; struct file_security_struct *fsec;
fsec = file->f_security; fsec = file->f_security;
fsec->fown_sid = current_sid(); fsec->fown_sid = current_sid();
return 0;
} }
static int selinux_file_send_sigiotask(struct task_struct *tsk, static int selinux_file_send_sigiotask(struct task_struct *tsk,
......
...@@ -1390,12 +1390,11 @@ static int smack_mmap_file(struct file *file, ...@@ -1390,12 +1390,11 @@ static int smack_mmap_file(struct file *file,
* Returns 0 * Returns 0
* Further research may be required on this one. * Further research may be required on this one.
*/ */
static int smack_file_set_fowner(struct file *file) static void smack_file_set_fowner(struct file *file)
{ {
struct smack_known *skp = smk_of_current(); struct smack_known *skp = smk_of_current();
file->f_security = skp->smk_known; file->f_security = skp->smk_known;
return 0;
} }
/** /**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册