diff options
author | Sage Weil <sage@newdream.net> | 2011-05-25 17:56:12 -0400 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2011-06-08 00:36:45 -0400 |
commit | 0c1f91f27140cf3b6e38dc4e892adac241c73a20 (patch) | |
tree | 5058e4c66a16e2c1d808ce66317ef2c9fdb21590 | |
parent | 0e98728fa32d338907631349a8cc2afa07c0cb9a (diff) |
ceph: unwind canceled flock state
If we request a lock and then abort (e.g., ^C), we need to send a matching
unlock request to the MDS to unwind our lock attempt to avoid indefinitely
blocking other clients.
Reported-by: Brian Chrisman <brchrisman@gmail.com>
Signed-off-by: Sage Weil <sage@newdream.net>
-rw-r--r-- | fs/ceph/locks.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c index 7f0f72c53f7e..80576d05d687 100644 --- a/fs/ceph/locks.c +++ b/fs/ceph/locks.c | |||
@@ -33,11 +33,10 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file, | |||
33 | length = fl->fl_end - fl->fl_start + 1; | 33 | length = fl->fl_end - fl->fl_start + 1; |
34 | 34 | ||
35 | dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, " | 35 | dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, " |
36 | "length: %llu, wait: %d, type`: %d", (int)lock_type, | 36 | "length: %llu, wait: %d, type: %d", (int)lock_type, |
37 | (int)operation, (u64)fl->fl_pid, fl->fl_start, | 37 | (int)operation, (u64)fl->fl_pid, fl->fl_start, |
38 | length, wait, fl->fl_type); | 38 | length, wait, fl->fl_type); |
39 | 39 | ||
40 | |||
41 | req->r_args.filelock_change.rule = lock_type; | 40 | req->r_args.filelock_change.rule = lock_type; |
42 | req->r_args.filelock_change.type = cmd; | 41 | req->r_args.filelock_change.type = cmd; |
43 | req->r_args.filelock_change.pid = cpu_to_le64((u64)fl->fl_pid); | 42 | req->r_args.filelock_change.pid = cpu_to_le64((u64)fl->fl_pid); |
@@ -71,7 +70,7 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file, | |||
71 | } | 70 | } |
72 | ceph_mdsc_put_request(req); | 71 | ceph_mdsc_put_request(req); |
73 | dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, " | 72 | dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, " |
74 | "length: %llu, wait: %d, type`: %d, err code %d", (int)lock_type, | 73 | "length: %llu, wait: %d, type: %d, err code %d", (int)lock_type, |
75 | (int)operation, (u64)fl->fl_pid, fl->fl_start, | 74 | (int)operation, (u64)fl->fl_pid, fl->fl_start, |
76 | length, wait, fl->fl_type, err); | 75 | length, wait, fl->fl_type, err); |
77 | return err; | 76 | return err; |
@@ -110,16 +109,20 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl) | |||
110 | dout("mds locked, locking locally"); | 109 | dout("mds locked, locking locally"); |
111 | err = posix_lock_file(file, fl, NULL); | 110 | err = posix_lock_file(file, fl, NULL); |
112 | if (err && (CEPH_MDS_OP_SETFILELOCK == op)) { | 111 | if (err && (CEPH_MDS_OP_SETFILELOCK == op)) { |
113 | /* undo! This should only happen if the kernel detects | 112 | /* undo! This should only happen if |
114 | * local deadlock. */ | 113 | * the kernel detects local |
114 | * deadlock. */ | ||
115 | ceph_lock_message(CEPH_LOCK_FCNTL, op, file, | 115 | ceph_lock_message(CEPH_LOCK_FCNTL, op, file, |
116 | CEPH_LOCK_UNLOCK, 0, fl); | 116 | CEPH_LOCK_UNLOCK, 0, fl); |
117 | dout("got %d on posix_lock_file, undid lock", err); | 117 | dout("got %d on posix_lock_file, undid lock", |
118 | err); | ||
118 | } | 119 | } |
119 | } | 120 | } |
120 | 121 | ||
121 | } else { | 122 | } else if (err == -ERESTARTSYS) { |
122 | dout("mds returned error code %d", err); | 123 | dout("undoing lock\n"); |
124 | ceph_lock_message(CEPH_LOCK_FCNTL, op, file, | ||
125 | CEPH_LOCK_UNLOCK, 0, fl); | ||
123 | } | 126 | } |
124 | return err; | 127 | return err; |
125 | } | 128 | } |
@@ -156,8 +159,11 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl) | |||
156 | file, CEPH_LOCK_UNLOCK, 0, fl); | 159 | file, CEPH_LOCK_UNLOCK, 0, fl); |
157 | dout("got %d on flock_lock_file_wait, undid lock", err); | 160 | dout("got %d on flock_lock_file_wait, undid lock", err); |
158 | } | 161 | } |
159 | } else { | 162 | } else if (err == -ERESTARTSYS) { |
160 | dout("mds error code %d", err); | 163 | dout("undoing lock\n"); |
164 | ceph_lock_message(CEPH_LOCK_FLOCK, | ||
165 | CEPH_MDS_OP_SETFILELOCK, | ||
166 | file, CEPH_LOCK_UNLOCK, 0, fl); | ||
161 | } | 167 | } |
162 | return err; | 168 | return err; |
163 | } | 169 | } |