hc
2024-05-10 cde9070d9970eef1f7ec2360586c802a16230ad8
kernel/fs/ceph/locks.c
....@@ -32,7 +32,7 @@
3232
3333 static void ceph_fl_copy_lock(struct file_lock *dst, struct file_lock *src)
3434 {
35
- struct inode *inode = file_inode(src->fl_file);
35
+ struct inode *inode = file_inode(dst->fl_file);
3636 atomic_inc(&ceph_inode(inode)->i_filelock_ref);
3737 }
3838
....@@ -59,7 +59,7 @@
5959 static int ceph_lock_message(u8 lock_type, u16 operation, struct inode *inode,
6060 int cmd, u8 wait, struct file_lock *fl)
6161 {
62
- struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc;
62
+ struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(inode->i_sb);
6363 struct ceph_mds_request *req;
6464 int err;
6565 u64 length = 0;
....@@ -73,7 +73,7 @@
7373 * window. Caller function will decrease the counter.
7474 */
7575 fl->fl_ops = &ceph_fl_lock_ops;
76
- atomic_inc(&ceph_inode(inode)->i_filelock_ref);
76
+ fl->fl_ops->fl_copy_lock(fl, NULL);
7777 }
7878
7979 if (operation != CEPH_MDS_OP_SETFILELOCK || cmd == CEPH_LOCK_UNLOCK)
....@@ -206,6 +206,21 @@
206206 return 0;
207207 }
208208
209
+static int try_unlock_file(struct file *file, struct file_lock *fl)
210
+{
211
+ int err;
212
+ unsigned int orig_flags = fl->fl_flags;
213
+ fl->fl_flags |= FL_EXISTS;
214
+ err = locks_lock_file_wait(file, fl);
215
+ fl->fl_flags = orig_flags;
216
+ if (err == -ENOENT) {
217
+ if (!(orig_flags & FL_EXISTS))
218
+ err = 0;
219
+ return err;
220
+ }
221
+ return 1;
222
+}
223
+
209224 /**
210225 * Attempt to set an fcntl lock.
211226 * For now, this just goes away to the server. Later it may be more awesome.
....@@ -236,15 +251,6 @@
236251 spin_lock(&ci->i_ceph_lock);
237252 if (ci->i_ceph_flags & CEPH_I_ERROR_FILELOCK) {
238253 err = -EIO;
239
- } else if (op == CEPH_MDS_OP_SETFILELOCK) {
240
- /*
241
- * increasing i_filelock_ref closes race window between
242
- * handling request reply and adding file_lock struct to
243
- * inode. Otherwise, i_auth_cap may get trimmed in the
244
- * window. Caller function will decrease the counter.
245
- */
246
- fl->fl_ops = &ceph_fl_lock_ops;
247
- atomic_inc(&ci->i_filelock_ref);
248254 }
249255 spin_unlock(&ci->i_ceph_lock);
250256 if (err < 0) {
....@@ -260,9 +266,15 @@
260266 else
261267 lock_cmd = CEPH_LOCK_UNLOCK;
262268
269
+ if (op == CEPH_MDS_OP_SETFILELOCK && F_UNLCK == fl->fl_type) {
270
+ err = try_unlock_file(file, fl);
271
+ if (err <= 0)
272
+ return err;
273
+ }
274
+
263275 err = ceph_lock_message(CEPH_LOCK_FCNTL, op, inode, lock_cmd, wait, fl);
264276 if (!err) {
265
- if (op == CEPH_MDS_OP_SETFILELOCK) {
277
+ if (op == CEPH_MDS_OP_SETFILELOCK && F_UNLCK != fl->fl_type) {
266278 dout("mds locked, locking locally\n");
267279 err = posix_lock_file(file, fl, NULL);
268280 if (err) {
....@@ -298,10 +310,6 @@
298310 spin_lock(&ci->i_ceph_lock);
299311 if (ci->i_ceph_flags & CEPH_I_ERROR_FILELOCK) {
300312 err = -EIO;
301
- } else {
302
- /* see comment in ceph_lock */
303
- fl->fl_ops = &ceph_fl_lock_ops;
304
- atomic_inc(&ci->i_filelock_ref);
305313 }
306314 spin_unlock(&ci->i_ceph_lock);
307315 if (err < 0) {
....@@ -320,9 +328,15 @@
320328 else
321329 lock_cmd = CEPH_LOCK_UNLOCK;
322330
331
+ if (F_UNLCK == fl->fl_type) {
332
+ err = try_unlock_file(file, fl);
333
+ if (err <= 0)
334
+ return err;
335
+ }
336
+
323337 err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK,
324338 inode, lock_cmd, wait, fl);
325
- if (!err) {
339
+ if (!err && F_UNLCK != fl->fl_type) {
326340 err = locks_lock_file_wait(file, fl);
327341 if (err) {
328342 ceph_lock_message(CEPH_LOCK_FLOCK,