Commit 0c750012 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull file locking updates from Christian Brauner:
 "A few years ago struct file_lock_context was added to allow for
  separate lists to track different types of file locks instead of using
  a singly-linked list for all of them.

  Now leases no longer need to be tracked using struct file_lock.
  However, a lot of the infrastructure is identical for leases and locks
  so separating them isn't trivial.

  This splits a group of fields used by both file locks and leases into
  a new struct file_lock_core. The new core struct is embedded in struct
  file_lock. Coccinelle was used to convert a lot of the callers to deal
  with the move, with the remaining 25% or so converted by hand.

  Afterwards several internal functions in fs/locks.c are made to work
  with struct file_lock_core. Ultimately this allows to split struct
  file_lock into struct file_lock and struct file_lease. The file lease
  APIs are then converted to take struct file_lease"

* tag 'vfs-6.9.file' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (51 commits)
  filelock: fix deadlock detection in POSIX locking
  filelock: always define for_each_file_lock()
  smb: remove redundant check
  filelock: don't do security checks on nfsd setlease calls
  filelock: split leases out of struct file_lock
  filelock: remove temporary compatibility macros
  smb/server: adapt to breakup of struct file_lock
  smb/client: adapt to breakup of struct file_lock
  ocfs2: adapt to breakup of struct file_lock
  nfsd: adapt to breakup of struct file_lock
  nfs: adapt to breakup of struct file_lock
  lockd: adapt to breakup of struct file_lock
  fuse: adapt to breakup of struct file_lock
  gfs2: adapt to breakup of struct file_lock
  dlm: adapt to breakup of struct file_lock
  ceph: adapt to breakup of struct file_lock
  afs: adapt to breakup of struct file_lock
  9p: adapt to breakup of struct file_lock
  filelock: convert seqfile handling to use file_lock_core
  filelock: convert locks_translate_pid to take file_lock_core
  ...
parents b5683a37 14786d94
Loading
Loading
Loading
Loading
+20 −20
Original line number Diff line number Diff line
@@ -107,7 +107,7 @@ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl)

	p9_debug(P9_DEBUG_VFS, "filp: %p lock: %p\n", filp, fl);

	if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
	if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->c.flc_type != F_UNLCK) {
		filemap_write_and_wait(inode->i_mapping);
		invalidate_mapping_pages(&inode->i_data, 0, -1);
	}
@@ -121,13 +121,12 @@ static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl)
	struct p9_fid *fid;
	uint8_t status = P9_LOCK_ERROR;
	int res = 0;
	unsigned char fl_type;
	struct v9fs_session_info *v9ses;

	fid = filp->private_data;
	BUG_ON(fid == NULL);

	BUG_ON((fl->fl_flags & FL_POSIX) != FL_POSIX);
	BUG_ON((fl->c.flc_flags & FL_POSIX) != FL_POSIX);

	res = locks_lock_file_wait(filp, fl);
	if (res < 0)
@@ -136,7 +135,7 @@ static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl)
	/* convert posix lock to p9 tlock args */
	memset(&flock, 0, sizeof(flock));
	/* map the lock type */
	switch (fl->fl_type) {
	switch (fl->c.flc_type) {
	case F_RDLCK:
		flock.type = P9_LOCK_TYPE_RDLCK;
		break;
@@ -152,7 +151,7 @@ static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl)
		flock.length = 0;
	else
		flock.length = fl->fl_end - fl->fl_start + 1;
	flock.proc_id = fl->fl_pid;
	flock.proc_id = fl->c.flc_pid;
	flock.client_id = fid->clnt->name;
	if (IS_SETLKW(cmd))
		flock.flags = P9_LOCK_FLAGS_BLOCK;
@@ -207,12 +206,13 @@ static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl)
	 * incase server returned error for lock request, revert
	 * it locally
	 */
	if (res < 0 && fl->fl_type != F_UNLCK) {
		fl_type = fl->fl_type;
		fl->fl_type = F_UNLCK;
	if (res < 0 && fl->c.flc_type != F_UNLCK) {
		unsigned char type = fl->c.flc_type;

		fl->c.flc_type = F_UNLCK;
		/* Even if this fails we want to return the remote error */
		locks_lock_file_wait(filp, fl);
		fl->fl_type = fl_type;
		fl->c.flc_type = type;
	}
	if (flock.client_id != fid->clnt->name)
		kfree(flock.client_id);
@@ -234,7 +234,7 @@ static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
	 * if we have a conflicting lock locally, no need to validate
	 * with server
	 */
	if (fl->fl_type != F_UNLCK)
	if (fl->c.flc_type != F_UNLCK)
		return res;

	/* convert posix lock to p9 tgetlock args */
@@ -245,7 +245,7 @@ static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
		glock.length = 0;
	else
		glock.length = fl->fl_end - fl->fl_start + 1;
	glock.proc_id = fl->fl_pid;
	glock.proc_id = fl->c.flc_pid;
	glock.client_id = fid->clnt->name;

	res = p9_client_getlock_dotl(fid, &glock);
@@ -254,13 +254,13 @@ static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
	/* map 9p lock type to os lock type */
	switch (glock.type) {
	case P9_LOCK_TYPE_RDLCK:
		fl->fl_type = F_RDLCK;
		fl->c.flc_type = F_RDLCK;
		break;
	case P9_LOCK_TYPE_WRLCK:
		fl->fl_type = F_WRLCK;
		fl->c.flc_type = F_WRLCK;
		break;
	case P9_LOCK_TYPE_UNLCK:
		fl->fl_type = F_UNLCK;
		fl->c.flc_type = F_UNLCK;
		break;
	}
	if (glock.type != P9_LOCK_TYPE_UNLCK) {
@@ -269,7 +269,7 @@ static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
			fl->fl_end = OFFSET_MAX;
		else
			fl->fl_end = glock.start + glock.length - 1;
		fl->fl_pid = -glock.proc_id;
		fl->c.flc_pid = -glock.proc_id;
	}
out:
	if (glock.client_id != fid->clnt->name)
@@ -293,7 +293,7 @@ static int v9fs_file_lock_dotl(struct file *filp, int cmd, struct file_lock *fl)
	p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %pD\n",
		 filp, cmd, fl, filp);

	if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
	if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->c.flc_type != F_UNLCK) {
		filemap_write_and_wait(inode->i_mapping);
		invalidate_mapping_pages(&inode->i_data, 0, -1);
	}
@@ -324,16 +324,16 @@ static int v9fs_file_flock_dotl(struct file *filp, int cmd,
	p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %pD\n",
		 filp, cmd, fl, filp);

	if (!(fl->fl_flags & FL_FLOCK))
	if (!(fl->c.flc_flags & FL_FLOCK))
		goto out_err;

	if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
	if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->c.flc_type != F_UNLCK) {
		filemap_write_and_wait(inode->i_mapping);
		invalidate_mapping_pages(&inode->i_data, 0, -1);
	}
	/* Convert flock to posix lock */
	fl->fl_flags |= FL_POSIX;
	fl->fl_flags ^= FL_FLOCK;
	fl->c.flc_flags |= FL_POSIX;
	fl->c.flc_flags ^= FL_FLOCK;

	if (IS_SETLK(cmd) | IS_SETLKW(cmd))
		ret = v9fs_file_do_lock(filp, cmd, fl);
+30 −30
Original line number Diff line number Diff line
@@ -93,13 +93,13 @@ static void afs_grant_locks(struct afs_vnode *vnode)
	bool exclusive = (vnode->lock_type == AFS_LOCK_WRITE);

	list_for_each_entry_safe(p, _p, &vnode->pending_locks, fl_u.afs.link) {
		if (!exclusive && p->fl_type == F_WRLCK)
		if (!exclusive && lock_is_write(p))
			continue;

		list_move_tail(&p->fl_u.afs.link, &vnode->granted_locks);
		p->fl_u.afs.state = AFS_LOCK_GRANTED;
		trace_afs_flock_op(vnode, p, afs_flock_op_grant);
		wake_up(&p->fl_wait);
		locks_wake_up(p);
	}
}

@@ -112,25 +112,24 @@ static void afs_next_locker(struct afs_vnode *vnode, int error)
{
	struct file_lock *p, *_p, *next = NULL;
	struct key *key = vnode->lock_key;
	unsigned int fl_type = F_RDLCK;
	unsigned int type = F_RDLCK;

	_enter("");

	if (vnode->lock_type == AFS_LOCK_WRITE)
		fl_type = F_WRLCK;
		type = F_WRLCK;

	list_for_each_entry_safe(p, _p, &vnode->pending_locks, fl_u.afs.link) {
		if (error &&
		    p->fl_type == fl_type &&
		    afs_file_key(p->fl_file) == key) {
		    p->c.flc_type == type &&
		    afs_file_key(p->c.flc_file) == key) {
			list_del_init(&p->fl_u.afs.link);
			p->fl_u.afs.state = error;
			wake_up(&p->fl_wait);
			locks_wake_up(p);
		}

		/* Select the next locker to hand off to. */
		if (next &&
		    (next->fl_type == F_WRLCK || p->fl_type == F_RDLCK))
		if (next && (lock_is_write(next) || lock_is_read(p)))
			continue;
		next = p;
	}
@@ -142,7 +141,7 @@ static void afs_next_locker(struct afs_vnode *vnode, int error)
		afs_set_lock_state(vnode, AFS_VNODE_LOCK_SETTING);
		next->fl_u.afs.state = AFS_LOCK_YOUR_TRY;
		trace_afs_flock_op(vnode, next, afs_flock_op_wake);
		wake_up(&next->fl_wait);
		locks_wake_up(next);
	} else {
		afs_set_lock_state(vnode, AFS_VNODE_LOCK_NONE);
		trace_afs_flock_ev(vnode, NULL, afs_flock_no_lockers, 0);
@@ -166,7 +165,7 @@ static void afs_kill_lockers_enoent(struct afs_vnode *vnode)
			       struct file_lock, fl_u.afs.link);
		list_del_init(&p->fl_u.afs.link);
		p->fl_u.afs.state = -ENOENT;
		wake_up(&p->fl_wait);
		locks_wake_up(p);
	}

	key_put(vnode->lock_key);
@@ -464,14 +463,14 @@ static int afs_do_setlk(struct file *file, struct file_lock *fl)

	_enter("{%llx:%llu},%llu-%llu,%u,%u",
	       vnode->fid.vid, vnode->fid.vnode,
	       fl->fl_start, fl->fl_end, fl->fl_type, mode);
	       fl->fl_start, fl->fl_end, fl->c.flc_type, mode);

	fl->fl_ops = &afs_lock_ops;
	INIT_LIST_HEAD(&fl->fl_u.afs.link);
	fl->fl_u.afs.state = AFS_LOCK_PENDING;

	partial = (fl->fl_start != 0 || fl->fl_end != OFFSET_MAX);
	type = (fl->fl_type == F_RDLCK) ? AFS_LOCK_READ : AFS_LOCK_WRITE;
	type = lock_is_read(fl) ? AFS_LOCK_READ : AFS_LOCK_WRITE;
	if (mode == afs_flock_mode_write && partial)
		type = AFS_LOCK_WRITE;

@@ -524,7 +523,7 @@ static int afs_do_setlk(struct file *file, struct file_lock *fl)
	}

	if (vnode->lock_state == AFS_VNODE_LOCK_NONE &&
	    !(fl->fl_flags & FL_SLEEP)) {
	    !(fl->c.flc_flags & FL_SLEEP)) {
		ret = -EAGAIN;
		if (type == AFS_LOCK_READ) {
			if (vnode->status.lock_count == -1)
@@ -621,7 +620,7 @@ static int afs_do_setlk(struct file *file, struct file_lock *fl)
	return 0;

lock_is_contended:
	if (!(fl->fl_flags & FL_SLEEP)) {
	if (!(fl->c.flc_flags & FL_SLEEP)) {
		list_del_init(&fl->fl_u.afs.link);
		afs_next_locker(vnode, 0);
		ret = -EAGAIN;
@@ -641,7 +640,7 @@ static int afs_do_setlk(struct file *file, struct file_lock *fl)
	spin_unlock(&vnode->lock);

	trace_afs_flock_ev(vnode, fl, afs_flock_waiting, 0);
	ret = wait_event_interruptible(fl->fl_wait,
	ret = wait_event_interruptible(fl->c.flc_wait,
				       fl->fl_u.afs.state != AFS_LOCK_PENDING);
	trace_afs_flock_ev(vnode, fl, afs_flock_waited, ret);

@@ -704,7 +703,8 @@ static int afs_do_unlk(struct file *file, struct file_lock *fl)
	struct afs_vnode *vnode = AFS_FS_I(file_inode(file));
	int ret;

	_enter("{%llx:%llu},%u", vnode->fid.vid, vnode->fid.vnode, fl->fl_type);
	_enter("{%llx:%llu},%u", vnode->fid.vid, vnode->fid.vnode,
	       fl->c.flc_type);

	trace_afs_flock_op(vnode, fl, afs_flock_op_unlock);

@@ -730,11 +730,11 @@ static int afs_do_getlk(struct file *file, struct file_lock *fl)
	if (vnode->lock_state == AFS_VNODE_LOCK_DELETED)
		return -ENOENT;

	fl->fl_type = F_UNLCK;
	fl->c.flc_type = F_UNLCK;

	/* check local lock records first */
	posix_test_lock(file, fl);
	if (fl->fl_type == F_UNLCK) {
	if (lock_is_unlock(fl)) {
		/* no local locks; consult the server */
		ret = afs_fetch_status(vnode, key, false, NULL);
		if (ret < 0)
@@ -743,18 +743,18 @@ static int afs_do_getlk(struct file *file, struct file_lock *fl)
		lock_count = READ_ONCE(vnode->status.lock_count);
		if (lock_count != 0) {
			if (lock_count > 0)
				fl->fl_type = F_RDLCK;
				fl->c.flc_type = F_RDLCK;
			else
				fl->fl_type = F_WRLCK;
				fl->c.flc_type = F_WRLCK;
			fl->fl_start = 0;
			fl->fl_end = OFFSET_MAX;
			fl->fl_pid = 0;
			fl->c.flc_pid = 0;
		}
	}

	ret = 0;
error:
	_leave(" = %d [%hd]", ret, fl->fl_type);
	_leave(" = %d [%hd]", ret, fl->c.flc_type);
	return ret;
}

@@ -769,7 +769,7 @@ int afs_lock(struct file *file, int cmd, struct file_lock *fl)

	_enter("{%llx:%llu},%d,{t=%x,fl=%x,r=%Ld:%Ld}",
	       vnode->fid.vid, vnode->fid.vnode, cmd,
	       fl->fl_type, fl->fl_flags,
	       fl->c.flc_type, fl->c.flc_flags,
	       (long long) fl->fl_start, (long long) fl->fl_end);

	if (IS_GETLK(cmd))
@@ -778,7 +778,7 @@ int afs_lock(struct file *file, int cmd, struct file_lock *fl)
	fl->fl_u.afs.debug_id = atomic_inc_return(&afs_file_lock_debug_id);
	trace_afs_flock_op(vnode, fl, afs_flock_op_lock);

	if (fl->fl_type == F_UNLCK)
	if (lock_is_unlock(fl))
		ret = afs_do_unlk(file, fl);
	else
		ret = afs_do_setlk(file, fl);
@@ -804,7 +804,7 @@ int afs_flock(struct file *file, int cmd, struct file_lock *fl)

	_enter("{%llx:%llu},%d,{t=%x,fl=%x}",
	       vnode->fid.vid, vnode->fid.vnode, cmd,
	       fl->fl_type, fl->fl_flags);
	       fl->c.flc_type, fl->c.flc_flags);

	/*
	 * No BSD flocks over NFS allowed.
@@ -813,14 +813,14 @@ int afs_flock(struct file *file, int cmd, struct file_lock *fl)
	 * Not sure whether that would be unique, though, or whether
	 * that would break in other places.
	 */
	if (!(fl->fl_flags & FL_FLOCK))
	if (!(fl->c.flc_flags & FL_FLOCK))
		return -ENOLCK;

	fl->fl_u.afs.debug_id = atomic_inc_return(&afs_file_lock_debug_id);
	trace_afs_flock_op(vnode, fl, afs_flock_op_flock);

	/* we're simulating flock() locks using posix locks on the server */
	if (fl->fl_type == F_UNLCK)
	if (lock_is_unlock(fl))
		ret = afs_do_unlk(file, fl);
	else
		ret = afs_do_setlk(file, fl);
@@ -843,7 +843,7 @@ int afs_flock(struct file *file, int cmd, struct file_lock *fl)
 */
static void afs_fl_copy_lock(struct file_lock *new, struct file_lock *fl)
{
	struct afs_vnode *vnode = AFS_FS_I(file_inode(fl->fl_file));
	struct afs_vnode *vnode = AFS_FS_I(file_inode(fl->c.flc_file));

	_enter("");

@@ -861,7 +861,7 @@ static void afs_fl_copy_lock(struct file_lock *new, struct file_lock *fl)
 */
static void afs_fl_release_private(struct file_lock *fl)
{
	struct afs_vnode *vnode = AFS_FS_I(file_inode(fl->fl_file));
	struct afs_vnode *vnode = AFS_FS_I(file_inode(fl->c.flc_file));

	_enter("");

+38 −36
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ void __init ceph_flock_init(void)

static void ceph_fl_copy_lock(struct file_lock *dst, struct file_lock *src)
{
	struct inode *inode = file_inode(dst->fl_file);
	struct inode *inode = file_inode(dst->c.flc_file);
	atomic_inc(&ceph_inode(inode)->i_filelock_ref);
	dst->fl_u.ceph.inode = igrab(inode);
}
@@ -110,17 +110,18 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct inode *inode,
	else
		length = fl->fl_end - fl->fl_start + 1;

	owner = secure_addr(fl->fl_owner);
	owner = secure_addr(fl->c.flc_owner);

	doutc(cl, "rule: %d, op: %d, owner: %llx, pid: %llu, "
		    "start: %llu, length: %llu, wait: %d, type: %d\n",
		    (int)lock_type, (int)operation, owner, (u64)fl->fl_pid,
		    fl->fl_start, length, wait, fl->fl_type);
		    (int)lock_type, (int)operation, owner,
		    (u64) fl->c.flc_pid,
		    fl->fl_start, length, wait, fl->c.flc_type);

	req->r_args.filelock_change.rule = lock_type;
	req->r_args.filelock_change.type = cmd;
	req->r_args.filelock_change.owner = cpu_to_le64(owner);
	req->r_args.filelock_change.pid = cpu_to_le64((u64)fl->fl_pid);
	req->r_args.filelock_change.pid = cpu_to_le64((u64) fl->c.flc_pid);
	req->r_args.filelock_change.start = cpu_to_le64(fl->fl_start);
	req->r_args.filelock_change.length = cpu_to_le64(length);
	req->r_args.filelock_change.wait = wait;
@@ -130,13 +131,13 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct inode *inode,
		err = ceph_mdsc_wait_request(mdsc, req, wait ?
					ceph_lock_wait_for_completion : NULL);
	if (!err && operation == CEPH_MDS_OP_GETFILELOCK) {
		fl->fl_pid = -le64_to_cpu(req->r_reply_info.filelock_reply->pid);
		fl->c.flc_pid = -le64_to_cpu(req->r_reply_info.filelock_reply->pid);
		if (CEPH_LOCK_SHARED == req->r_reply_info.filelock_reply->type)
			fl->fl_type = F_RDLCK;
			fl->c.flc_type = F_RDLCK;
		else if (CEPH_LOCK_EXCL == req->r_reply_info.filelock_reply->type)
			fl->fl_type = F_WRLCK;
			fl->c.flc_type = F_WRLCK;
		else
			fl->fl_type = F_UNLCK;
			fl->c.flc_type = F_UNLCK;

		fl->fl_start = le64_to_cpu(req->r_reply_info.filelock_reply->start);
		length = le64_to_cpu(req->r_reply_info.filelock_reply->start) +
@@ -150,8 +151,8 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct inode *inode,
	ceph_mdsc_put_request(req);
	doutc(cl, "rule: %d, op: %d, pid: %llu, start: %llu, "
	      "length: %llu, wait: %d, type: %d, err code %d\n",
	      (int)lock_type, (int)operation, (u64)fl->fl_pid,
	      fl->fl_start, length, wait, fl->fl_type, err);
	      (int)lock_type, (int)operation, (u64) fl->c.flc_pid,
	      fl->fl_start, length, wait, fl->c.flc_type, err);
	return err;
}

@@ -227,10 +228,10 @@ static int ceph_lock_wait_for_completion(struct ceph_mds_client *mdsc,
static int try_unlock_file(struct file *file, struct file_lock *fl)
{
	int err;
	unsigned int orig_flags = fl->fl_flags;
	fl->fl_flags |= FL_EXISTS;
	unsigned int orig_flags = fl->c.flc_flags;
	fl->c.flc_flags |= FL_EXISTS;
	err = locks_lock_file_wait(file, fl);
	fl->fl_flags = orig_flags;
	fl->c.flc_flags = orig_flags;
	if (err == -ENOENT) {
		if (!(orig_flags & FL_EXISTS))
			err = 0;
@@ -253,13 +254,13 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
	u8 wait = 0;
	u8 lock_cmd;

	if (!(fl->fl_flags & FL_POSIX))
	if (!(fl->c.flc_flags & FL_POSIX))
		return -ENOLCK;

	if (ceph_inode_is_shutdown(inode))
		return -ESTALE;

	doutc(cl, "fl_owner: %p\n", fl->fl_owner);
	doutc(cl, "fl_owner: %p\n", fl->c.flc_owner);

	/* set wait bit as appropriate, then make command as Ceph expects it*/
	if (IS_GETLK(cmd))
@@ -273,19 +274,19 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
	}
	spin_unlock(&ci->i_ceph_lock);
	if (err < 0) {
		if (op == CEPH_MDS_OP_SETFILELOCK && F_UNLCK == fl->fl_type)
		if (op == CEPH_MDS_OP_SETFILELOCK && lock_is_unlock(fl))
			posix_lock_file(file, fl, NULL);
		return err;
	}

	if (F_RDLCK == fl->fl_type)
	if (lock_is_read(fl))
		lock_cmd = CEPH_LOCK_SHARED;
	else if (F_WRLCK == fl->fl_type)
	else if (lock_is_write(fl))
		lock_cmd = CEPH_LOCK_EXCL;
	else
		lock_cmd = CEPH_LOCK_UNLOCK;

	if (op == CEPH_MDS_OP_SETFILELOCK && F_UNLCK == fl->fl_type) {
	if (op == CEPH_MDS_OP_SETFILELOCK && lock_is_unlock(fl)) {
		err = try_unlock_file(file, fl);
		if (err <= 0)
			return err;
@@ -293,7 +294,7 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl)

	err = ceph_lock_message(CEPH_LOCK_FCNTL, op, inode, lock_cmd, wait, fl);
	if (!err) {
		if (op == CEPH_MDS_OP_SETFILELOCK && F_UNLCK != fl->fl_type) {
		if (op == CEPH_MDS_OP_SETFILELOCK && F_UNLCK != fl->c.flc_type) {
			doutc(cl, "locking locally\n");
			err = posix_lock_file(file, fl, NULL);
			if (err) {
@@ -319,13 +320,13 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
	u8 wait = 0;
	u8 lock_cmd;

	if (!(fl->fl_flags & FL_FLOCK))
	if (!(fl->c.flc_flags & FL_FLOCK))
		return -ENOLCK;

	if (ceph_inode_is_shutdown(inode))
		return -ESTALE;

	doutc(cl, "fl_file: %p\n", fl->fl_file);
	doutc(cl, "fl_file: %p\n", fl->c.flc_file);

	spin_lock(&ci->i_ceph_lock);
	if (ci->i_ceph_flags & CEPH_I_ERROR_FILELOCK) {
@@ -333,7 +334,7 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
	}
	spin_unlock(&ci->i_ceph_lock);
	if (err < 0) {
		if (F_UNLCK == fl->fl_type)
		if (lock_is_unlock(fl))
			locks_lock_file_wait(file, fl);
		return err;
	}
@@ -341,14 +342,14 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
	if (IS_SETLKW(cmd))
		wait = 1;

	if (F_RDLCK == fl->fl_type)
	if (lock_is_read(fl))
		lock_cmd = CEPH_LOCK_SHARED;
	else if (F_WRLCK == fl->fl_type)
	else if (lock_is_write(fl))
		lock_cmd = CEPH_LOCK_EXCL;
	else
		lock_cmd = CEPH_LOCK_UNLOCK;

	if (F_UNLCK == fl->fl_type) {
	if (lock_is_unlock(fl)) {
		err = try_unlock_file(file, fl);
		if (err <= 0)
			return err;
@@ -356,7 +357,7 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl)

	err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK,
				inode, lock_cmd, wait, fl);
	if (!err && F_UNLCK != fl->fl_type) {
	if (!err && F_UNLCK != fl->c.flc_type) {
		err = locks_lock_file_wait(file, fl);
		if (err) {
			ceph_lock_message(CEPH_LOCK_FLOCK,
@@ -385,9 +386,9 @@ void ceph_count_locks(struct inode *inode, int *fcntl_count, int *flock_count)
	ctx = locks_inode_context(inode);
	if (ctx) {
		spin_lock(&ctx->flc_lock);
		list_for_each_entry(lock, &ctx->flc_posix, fl_list)
		for_each_file_lock(lock, &ctx->flc_posix)
			++(*fcntl_count);
		list_for_each_entry(lock, &ctx->flc_flock, fl_list)
		for_each_file_lock(lock, &ctx->flc_flock)
			++(*flock_count);
		spin_unlock(&ctx->flc_lock);
	}
@@ -408,10 +409,10 @@ static int lock_to_ceph_filelock(struct inode *inode,
	cephlock->start = cpu_to_le64(lock->fl_start);
	cephlock->length = cpu_to_le64(lock->fl_end - lock->fl_start + 1);
	cephlock->client = cpu_to_le64(0);
	cephlock->pid = cpu_to_le64((u64)lock->fl_pid);
	cephlock->owner = cpu_to_le64(secure_addr(lock->fl_owner));
	cephlock->pid = cpu_to_le64((u64) lock->c.flc_pid);
	cephlock->owner = cpu_to_le64(secure_addr(lock->c.flc_owner));

	switch (lock->fl_type) {
	switch (lock->c.flc_type) {
	case F_RDLCK:
		cephlock->type = CEPH_LOCK_SHARED;
		break;
@@ -422,7 +423,8 @@ static int lock_to_ceph_filelock(struct inode *inode,
		cephlock->type = CEPH_LOCK_UNLOCK;
		break;
	default:
		doutc(cl, "Have unknown lock type %d\n", lock->fl_type);
		doutc(cl, "Have unknown lock type %d\n",
		      lock->c.flc_type);
		err = -EINVAL;
	}

@@ -453,7 +455,7 @@ int ceph_encode_locks_to_buffer(struct inode *inode,
		return 0;

	spin_lock(&ctx->flc_lock);
	list_for_each_entry(lock, &ctx->flc_posix, fl_list) {
	for_each_file_lock(lock, &ctx->flc_posix) {
		++seen_fcntl;
		if (seen_fcntl > num_fcntl_locks) {
			err = -ENOSPC;
@@ -464,7 +466,7 @@ int ceph_encode_locks_to_buffer(struct inode *inode,
			goto fail;
		++l;
	}
	list_for_each_entry(lock, &ctx->flc_flock, fl_list) {
	for_each_file_lock(lock, &ctx->flc_flock) {
		++seen_flock;
		if (seen_flock > num_flock_locks) {
			err = -ENOSPC;
+22 −22
Original line number Diff line number Diff line
@@ -138,14 +138,14 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
	}

	op->info.optype		= DLM_PLOCK_OP_LOCK;
	op->info.pid		= fl->fl_pid;
	op->info.ex		= (fl->fl_type == F_WRLCK);
	op->info.wait		= !!(fl->fl_flags & FL_SLEEP);
	op->info.pid		= fl->c.flc_pid;
	op->info.ex		= lock_is_write(fl);
	op->info.wait		= !!(fl->c.flc_flags & FL_SLEEP);
	op->info.fsid		= ls->ls_global_id;
	op->info.number		= number;
	op->info.start		= fl->fl_start;
	op->info.end		= fl->fl_end;
	op->info.owner = (__u64)(long)fl->fl_owner;
	op->info.owner = (__u64)(long) fl->c.flc_owner;
	/* async handling */
	if (fl->fl_lmops && fl->fl_lmops->lm_grant) {
		op_data = kzalloc(sizeof(*op_data), GFP_NOFS);
@@ -258,7 +258,7 @@ static int dlm_plock_callback(struct plock_op *op)
	}

	/* got fs lock; bookkeep locally as well: */
	flc->fl_flags &= ~FL_SLEEP;
	flc->c.flc_flags &= ~FL_SLEEP;
	if (posix_lock_file(file, flc, NULL)) {
		/*
		 * This can only happen in the case of kmalloc() failure.
@@ -291,7 +291,7 @@ int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
	struct dlm_ls *ls;
	struct plock_op *op;
	int rv;
	unsigned char fl_flags = fl->fl_flags;
	unsigned char saved_flags = fl->c.flc_flags;

	ls = dlm_find_lockspace_local(lockspace);
	if (!ls)
@@ -304,7 +304,7 @@ int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
	}

	/* cause the vfs unlock to return ENOENT if lock is not found */
	fl->fl_flags |= FL_EXISTS;
	fl->c.flc_flags |= FL_EXISTS;

	rv = locks_lock_file_wait(file, fl);
	if (rv == -ENOENT) {
@@ -317,14 +317,14 @@ int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
	}

	op->info.optype		= DLM_PLOCK_OP_UNLOCK;
	op->info.pid		= fl->fl_pid;
	op->info.pid		= fl->c.flc_pid;
	op->info.fsid		= ls->ls_global_id;
	op->info.number		= number;
	op->info.start		= fl->fl_start;
	op->info.end		= fl->fl_end;
	op->info.owner = (__u64)(long)fl->fl_owner;
	op->info.owner = (__u64)(long) fl->c.flc_owner;

	if (fl->fl_flags & FL_CLOSE) {
	if (fl->c.flc_flags & FL_CLOSE) {
		op->info.flags |= DLM_PLOCK_FL_CLOSE;
		send_op(op);
		rv = 0;
@@ -345,7 +345,7 @@ int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
	dlm_release_plock_op(op);
out:
	dlm_put_lockspace(ls);
	fl->fl_flags = fl_flags;
	fl->c.flc_flags = saved_flags;
	return rv;
}
EXPORT_SYMBOL_GPL(dlm_posix_unlock);
@@ -375,14 +375,14 @@ int dlm_posix_cancel(dlm_lockspace_t *lockspace, u64 number, struct file *file,
		return -EINVAL;

	memset(&info, 0, sizeof(info));
	info.pid = fl->fl_pid;
	info.ex = (fl->fl_type == F_WRLCK);
	info.pid = fl->c.flc_pid;
	info.ex = lock_is_write(fl);
	info.fsid = ls->ls_global_id;
	dlm_put_lockspace(ls);
	info.number = number;
	info.start = fl->fl_start;
	info.end = fl->fl_end;
	info.owner = (__u64)(long)fl->fl_owner;
	info.owner = (__u64)(long) fl->c.flc_owner;

	rv = do_lock_cancel(&info);
	switch (rv) {
@@ -437,13 +437,13 @@ int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file,
	}

	op->info.optype		= DLM_PLOCK_OP_GET;
	op->info.pid		= fl->fl_pid;
	op->info.ex		= (fl->fl_type == F_WRLCK);
	op->info.pid		= fl->c.flc_pid;
	op->info.ex		= lock_is_write(fl);
	op->info.fsid		= ls->ls_global_id;
	op->info.number		= number;
	op->info.start		= fl->fl_start;
	op->info.end		= fl->fl_end;
	op->info.owner = (__u64)(long)fl->fl_owner;
	op->info.owner = (__u64)(long) fl->c.flc_owner;

	send_op(op);
	wait_event(recv_wq, (op->done != 0));
@@ -455,16 +455,16 @@ int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file,

	rv = op->info.rv;

	fl->fl_type = F_UNLCK;
	fl->c.flc_type = F_UNLCK;
	if (rv == -ENOENT)
		rv = 0;
	else if (rv > 0) {
		locks_init_lock(fl);
		fl->fl_type = (op->info.ex) ? F_WRLCK : F_RDLCK;
		fl->fl_flags = FL_POSIX;
		fl->fl_pid = op->info.pid;
		fl->c.flc_type = (op->info.ex) ? F_WRLCK : F_RDLCK;
		fl->c.flc_flags = FL_POSIX;
		fl->c.flc_pid = op->info.pid;
		if (op->info.nodeid != dlm_our_nodeid())
			fl->fl_pid = -fl->fl_pid;
			fl->c.flc_pid = -fl->c.flc_pid;
		fl->fl_start = op->info.start;
		fl->fl_end = op->info.end;
		rv = 0;
+7 −7
Original line number Diff line number Diff line
@@ -2509,14 +2509,14 @@ static int convert_fuse_file_lock(struct fuse_conn *fc,
		 * translate it into the caller's pid namespace.
		 */
		rcu_read_lock();
		fl->fl_pid = pid_nr_ns(find_pid_ns(ffl->pid, fc->pid_ns), &init_pid_ns);
		fl->c.flc_pid = pid_nr_ns(find_pid_ns(ffl->pid, fc->pid_ns), &init_pid_ns);
		rcu_read_unlock();
		break;

	default:
		return -EIO;
	}
	fl->fl_type = ffl->type;
	fl->c.flc_type = ffl->type;
	return 0;
}

@@ -2530,10 +2530,10 @@ static void fuse_lk_fill(struct fuse_args *args, struct file *file,

	memset(inarg, 0, sizeof(*inarg));
	inarg->fh = ff->fh;
	inarg->owner = fuse_lock_owner_id(fc, fl->fl_owner);
	inarg->owner = fuse_lock_owner_id(fc, fl->c.flc_owner);
	inarg->lk.start = fl->fl_start;
	inarg->lk.end = fl->fl_end;
	inarg->lk.type = fl->fl_type;
	inarg->lk.type = fl->c.flc_type;
	inarg->lk.pid = pid;
	if (flock)
		inarg->lk_flags |= FUSE_LK_FLOCK;
@@ -2570,8 +2570,8 @@ static int fuse_setlk(struct file *file, struct file_lock *fl, int flock)
	struct fuse_mount *fm = get_fuse_mount(inode);
	FUSE_ARGS(args);
	struct fuse_lk_in inarg;
	int opcode = (fl->fl_flags & FL_SLEEP) ? FUSE_SETLKW : FUSE_SETLK;
	struct pid *pid = fl->fl_type != F_UNLCK ? task_tgid(current) : NULL;
	int opcode = (fl->c.flc_flags & FL_SLEEP) ? FUSE_SETLKW : FUSE_SETLK;
	struct pid *pid = fl->c.flc_type != F_UNLCK ? task_tgid(current) : NULL;
	pid_t pid_nr = pid_nr_ns(pid, fm->fc->pid_ns);
	int err;

@@ -2581,7 +2581,7 @@ static int fuse_setlk(struct file *file, struct file_lock *fl, int flock)
	}

	/* Unlock on close is handled by the flush method */
	if ((fl->fl_flags & FL_CLOSE_POSIX) == FL_CLOSE_POSIX)
	if ((fl->c.flc_flags & FL_CLOSE_POSIX) == FL_CLOSE_POSIX)
		return 0;

	fuse_lk_fill(&args, file, fl, opcode, pid_nr, flock, &inarg);
Loading