afs: Fix AFS file locking to allow fine grained locks
[ Upstream commit 68ce801ffd ]
Fix AFS file locking to allow fine grained locks as some applications, such
as firefox, won't work if they can't take such locks on certain state files
- thereby preventing the use of kAFS to distribute a home directory.
Note that this cannot be made completely functional as the protocol only
has provision for whole-file locks, so there exists the possibility of a
process deadlocking itself by getting a partial read-lock on a file first
and then trying to get a non-overlapping write-lock - but we got the
server's read lock with the first lock, so we're now stuck.
OpenAFS solves this by just granting any partial-range lock directly
without consulting the server - and hoping there's no remote collision. I
want to implement that in a separate patch and it requires a bit more
thought.
Fixes: 8d6c554126b8 ("AFS: implement file locking")
Reported-by: Jonathan Billings <jsbillings@jsbillings.org>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
adf1983a4f
commit
49862ce901
1 changed files with 9 additions and 14 deletions
|
|
@ -432,10 +432,6 @@ static int afs_do_setlk(struct file *file, struct file_lock *fl)
|
|||
|
||||
_enter("{%x:%u},%u", vnode->fid.vid, vnode->fid.vnode, fl->fl_type);
|
||||
|
||||
/* only whole-file locks are supported */
|
||||
if (fl->fl_start != 0 || fl->fl_end != OFFSET_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
fl->fl_ops = &afs_lock_ops;
|
||||
INIT_LIST_HEAD(&fl->fl_u.afs.link);
|
||||
fl->fl_u.afs.state = AFS_LOCK_PENDING;
|
||||
|
|
@ -587,10 +583,6 @@ static int afs_do_unlk(struct file *file, struct file_lock *fl)
|
|||
/* Flush all pending writes before doing anything with locks. */
|
||||
vfs_fsync(file, 0);
|
||||
|
||||
/* only whole-file unlocks are supported */
|
||||
if (fl->fl_start != 0 || fl->fl_end != OFFSET_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
ret = posix_lock_file(file, fl, NULL);
|
||||
_leave(" = %d [%u]", ret, vnode->lock_state);
|
||||
return ret;
|
||||
|
|
@ -618,12 +610,15 @@ static int afs_do_getlk(struct file *file, struct file_lock *fl)
|
|||
goto error;
|
||||
|
||||
lock_count = READ_ONCE(vnode->status.lock_count);
|
||||
if (lock_count > 0)
|
||||
fl->fl_type = F_RDLCK;
|
||||
else
|
||||
fl->fl_type = F_WRLCK;
|
||||
fl->fl_start = 0;
|
||||
fl->fl_end = OFFSET_MAX;
|
||||
if (lock_count != 0) {
|
||||
if (lock_count > 0)
|
||||
fl->fl_type = F_RDLCK;
|
||||
else
|
||||
fl->fl_type = F_WRLCK;
|
||||
fl->fl_start = 0;
|
||||
fl->fl_end = OFFSET_MAX;
|
||||
fl->fl_pid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue