Commit bbb480ab authored by Yan, Zheng's avatar Yan, Zheng Committed by Ilya Dryomov

ceph: check if file lock exists before sending unlock request

When a process exits, kernel closes its files. locks_remove_file()
is called to remove file locks on these files. locks_remove_file()
tries unlocking files even there is no file lock.
Signed-off-by: default avatar"Yan, Zheng" <zyan@redhat.com>
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent cb63483a
...@@ -210,6 +210,21 @@ static int ceph_lock_wait_for_completion(struct ceph_mds_client *mdsc, ...@@ -210,6 +210,21 @@ static int ceph_lock_wait_for_completion(struct ceph_mds_client *mdsc,
return 0; return 0;
} }
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;
err = locks_lock_file_wait(file, fl);
fl->fl_flags = orig_flags;
if (err == -ENOENT) {
if (!(orig_flags & FL_EXISTS))
err = 0;
return err;
}
return 1;
}
/** /**
* Attempt to set an fcntl lock. * Attempt to set an fcntl lock.
* For now, this just goes away to the server. Later it may be more awesome. * For now, this just goes away to the server. Later it may be more awesome.
...@@ -255,9 +270,15 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl) ...@@ -255,9 +270,15 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
else else
lock_cmd = CEPH_LOCK_UNLOCK; lock_cmd = CEPH_LOCK_UNLOCK;
if (op == CEPH_MDS_OP_SETFILELOCK && F_UNLCK == fl->fl_type) {
err = try_unlock_file(file, fl);
if (err <= 0)
return err;
}
err = ceph_lock_message(CEPH_LOCK_FCNTL, op, inode, lock_cmd, wait, fl); err = ceph_lock_message(CEPH_LOCK_FCNTL, op, inode, lock_cmd, wait, fl);
if (!err) { if (!err) {
if (op == CEPH_MDS_OP_SETFILELOCK) { if (op == CEPH_MDS_OP_SETFILELOCK && F_UNLCK != fl->fl_type) {
dout("mds locked, locking locally\n"); dout("mds locked, locking locally\n");
err = posix_lock_file(file, fl, NULL); err = posix_lock_file(file, fl, NULL);
if (err) { if (err) {
...@@ -311,9 +332,15 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl) ...@@ -311,9 +332,15 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
else else
lock_cmd = CEPH_LOCK_UNLOCK; lock_cmd = CEPH_LOCK_UNLOCK;
if (F_UNLCK == fl->fl_type) {
err = try_unlock_file(file, fl);
if (err <= 0)
return err;
}
err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK, err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK,
inode, lock_cmd, wait, fl); inode, lock_cmd, wait, fl);
if (!err) { if (!err && F_UNLCK != fl->fl_type) {
err = locks_lock_file_wait(file, fl); err = locks_lock_file_wait(file, fl);
if (err) { if (err) {
ceph_lock_message(CEPH_LOCK_FLOCK, ceph_lock_message(CEPH_LOCK_FLOCK,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment