Skip to content

Commit

Permalink
Merge tag 'locks-v3.18-1' of git://git.samba.org/jlayton/linux
Browse files Browse the repository at this point in the history
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
  ...
  • Loading branch information
torvalds committed Oct 11, 2014
2 parents 90d0c37 + 1b2b32d commit ef4a48c
Show file tree
Hide file tree
Showing 26 changed files with 354 additions and 488 deletions.
11 changes: 6 additions & 5 deletions Documentation/filesystems/Locking
Original file line number Diff line number Diff line change
Expand Up @@ -464,15 +464,12 @@ prototypes:
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 *, int, loff_t, loff_t);
};

locking rules:
All may block except for ->setlease.
No VFS locks held on entry except for ->setlease.

->setlease has the file_list_lock held and must not sleep.
All may block.

->llseek() locking has moved from llseek to the individual llseek
implementations. If your fs is not using generic_file_llseek, you
Expand All @@ -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
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 -------------------------------
prototypes:
int (*write_dquot) (struct dquot *);
Expand Down
7 changes: 4 additions & 3 deletions Documentation/filesystems/vfs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -826,7 +826,7 @@ struct file_operations {
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_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);
int (*show_fdinfo)(struct seq_file *m, struct file *f);
};
Expand Down Expand Up @@ -895,8 +895,9 @@ otherwise noted.
splice_read: called by the VFS to splice data from file to a pipe. This
method is used by the splice(2) system call

setlease: called by the VFS to set or release a file lock lease.
setlease has the file_lock_lock held and must not sleep.
setlease: called by the VFS to set or release a file lock lease. setlease
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.

Expand Down
4 changes: 1 addition & 3 deletions drivers/net/tun.c
Original file line number Diff line number Diff line change
Expand Up @@ -2152,9 +2152,7 @@ static int tun_chr_fasync(int fd, struct file *file, int on)
goto out;

if (on) {
ret = __f_setown(file, task_pid(current), PIDTYPE_PID, 0);
if (ret)
goto out;
__f_setown(file, task_pid(current), PIDTYPE_PID, 0);
tfile->flags |= TUN_FASYNC;
} else
tfile->flags &= ~TUN_FASYNC;
Expand Down
3 changes: 2 additions & 1 deletion drivers/tty/tty_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -2186,8 +2186,9 @@ static int __tty_fasync(int fd, struct file *filp, int on)
}
get_pid(pid);
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
retval = __f_setown(filp, pid, type, 0);
__f_setown(filp, pid, type, 0);
put_pid(pid);
retval = 0;
}
out:
return retval;
Expand Down
7 changes: 4 additions & 3 deletions fs/cifs/cifsfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -813,7 +813,8 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int 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
Expand All @@ -829,7 +830,7 @@ static int cifs_setlease(struct file *file, long arg, struct file_lock **lease)
if (arg == F_UNLCK ||
((arg == F_RDLCK) && CIFS_CACHE_READ(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 &&
!CIFS_CACHE_READ(CIFS_I(inode)))
/*
Expand All @@ -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
* else.
*/
return generic_setlease(file, arg, lease);
return generic_setlease(file, arg, lease, priv);
else
return -EAGAIN;
}
Expand Down
8 changes: 4 additions & 4 deletions fs/dlm/plock.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ struct plock_op {

struct plock_xop {
struct plock_op xop;
void *callback;
int (*callback)(struct file_lock *fl, int result);
void *fl;
void *file;
struct file_lock flc;
Expand Down Expand Up @@ -190,7 +190,7 @@ static int dlm_plock_callback(struct plock_op *op)
struct file *file;
struct file_lock *fl;
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;
int rv = 0;

Expand All @@ -209,7 +209,7 @@ static int dlm_plock_callback(struct plock_op *op)
notify = xop->callback;

if (op->info.rv) {
notify(fl, NULL, op->info.rv);
notify(fl, op->info.rv);
goto out;
}

Expand All @@ -228,7 +228,7 @@ static int dlm_plock_callback(struct plock_op *op)
(unsigned long long)op->info.number, file, fl);
}

rv = notify(fl, NULL, 0);
rv = notify(fl, 0);
if (rv) {
/* XXX: We need to cancel the fs lock here: */
log_print("dlm_plock_callback: lock granted after lock request "
Expand Down
21 changes: 7 additions & 14 deletions fs/fcntl.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,36 +98,28 @@ static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
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 err;

err = security_file_set_fowner(filp);
if (err)
return err;

security_file_set_fowner(filp);
f_modown(filp, pid, type, force);
return 0;
}
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;
struct pid *pid;
int who = arg;
int result;
type = PIDTYPE_PID;
if (who < 0) {
type = PIDTYPE_PGID;
who = -who;
}
rcu_read_lock();
pid = find_vpid(who);
result = __f_setown(filp, pid, type, force);
__f_setown(filp, pid, type, force);
rcu_read_unlock();
return result;
}
EXPORT_SYMBOL(f_setown);

Expand Down Expand Up @@ -181,7 +173,7 @@ static int f_setown_ex(struct file *filp, unsigned long arg)
if (owner.pid && !pid)
ret = -ESRCH;
else
ret = __f_setown(filp, pid, type, 1);
__f_setown(filp, pid, type, 1);
rcu_read_unlock();

return ret;
Expand Down Expand Up @@ -302,7 +294,8 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
force_successful_syscall_return();
break;
case F_SETOWN:
err = f_setown(filp, arg, 1);
f_setown(filp, arg, 1);
err = 0;
break;
case F_GETOWN_EX:
err = f_getown_ex(filp, arg);
Expand Down
22 changes: 1 addition & 21 deletions fs/gfs2/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -913,26 +913,6 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,

#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
* @file: the file pointer
Expand Down Expand Up @@ -1078,7 +1058,7 @@ const struct file_operations gfs2_file_fops = {
.flock = gfs2_flock,
.splice_read = generic_file_splice_read,
.splice_write = iter_file_splice_write,
.setlease = gfs2_setlease,
.setlease = simple_nosetlease,
.fallocate = gfs2_fallocate,
};

Expand Down
18 changes: 18 additions & 0 deletions fs/libfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1075,3 +1075,21 @@ struct inode *alloc_anon_inode(struct super_block *s)
return 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);
Loading

0 comments on commit ef4a48c

Please sign in to comment.