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: "Yan, Zheng" <zyan@redhat.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
Родитель
cb63483ad0
Коммит
bbb480ab05
|
@ -210,6 +210,21 @@ static int ceph_lock_wait_for_completion(struct ceph_mds_client *mdsc,
|
|||
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.
|
||||
* 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)
|
|||
else
|
||||
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);
|
||||
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");
|
||||
err = posix_lock_file(file, fl, NULL);
|
||||
if (err) {
|
||||
|
@ -311,9 +332,15 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
|
|||
else
|
||||
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,
|
||||
inode, lock_cmd, wait, fl);
|
||||
if (!err) {
|
||||
if (!err && F_UNLCK != fl->fl_type) {
|
||||
err = locks_lock_file_wait(file, fl);
|
||||
if (err) {
|
||||
ceph_lock_message(CEPH_LOCK_FLOCK,
|
||||
|
|
Загрузка…
Ссылка в новой задаче