Unverified Commit c4b3ffb5 authored by Christian Brauner's avatar Christian Brauner
Browse files

Merge series 'filelock: split file leases out of struct file_lock' of...

Merge series 'filelock: split file leases out of struct file_lock' of https://lore.kernel.org/r/20240131-flsplit-v3-0-c6129007ee8d@kernel.org

Pull file locking series from Jeff Layton:

Long ago, file locks used to hang off of a singly-linked list in struct
inode. Because of this, when leases were added, they were added to the
same list and so they had to be tracked using the same sort of
structure.

Several years ago, we added struct file_lock_context, which allowed us
to use separate lists to track different types of file locks. Given
that, leases no longer need to be tracked using struct file_lock.

That said, a lot of the underlying infrastructure _is_ the same between
file leases and locks, so we can't completely separate everything.

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

It then converts several internal functions in fs/locks.c to work with
struct file_lock_core. Lastly, struct file_lock is split into struct
file_lock and file_lease, and the lease-related APIs converted to take
struct file_lease.

I also added a few small helpers and converted several users over to
them. That reduces the size of the per-fs conversion patches later in
the series. I played with some others too, but they were too awkward
or not frequently used enough to make it worthwhile.

* series 'filelock: split file leases out of struct file_lock' of https://lore.kernel.org/r/20240131-flsplit-v3-0-c6129007ee8d@kernel.org

: (47 commits)

  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
  filelock: convert locks_insert_lock_ctx and locks_delete_lock_ctx
  filelock: convert locks_wake_up_blocks to take a file_lock_core pointer
  filelock: make assign_type helper take a file_lock_core pointer
  filelock: reorganize locks_delete_block and __locks_insert_block
  ...

Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parents 6613476e c69ff407
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