Skip to content

Commit 807252f

Browse files
Marios MakassikisSteve French
authored andcommitted
ksmbd: fix recursive locking in vfs helpers
Running smb2.rename test from Samba smbtorture suite against a kernel built with lockdep triggers a "possible recursive locking detected" warning. This is because mnt_want_write() is called twice with no mnt_drop_write() in between: -> ksmbd_vfs_mkdir() -> ksmbd_vfs_kern_path_create() -> kern_path_create() -> filename_create() -> mnt_want_write() -> mnt_want_write() Fix this by removing the mnt_want_write/mnt_drop_write calls from vfs helpers that call kern_path_create(). Full lockdep trace below: ============================================ WARNING: possible recursive locking detected 6.6.0-rc5 torvalds#775 Not tainted -------------------------------------------- kworker/1:1/32 is trying to acquire lock: ffff888005ac83f8 (sb_writers#5){.+.+}-{0:0}, at: ksmbd_vfs_mkdir+0xe1/0x410 but task is already holding lock: ffff888005ac83f8 (sb_writers#5){.+.+}-{0:0}, at: filename_create+0xb6/0x260 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(sb_writers#5); lock(sb_writers#5); *** DEADLOCK *** May be due to missing lock nesting notation 4 locks held by kworker/1:1/32: #0: ffff8880064e4138 ((wq_completion)ksmbd-io){+.+.}-{0:0}, at: process_one_work+0x40e/0x980 #1: ffff888005b0fdd0 ((work_completion)(&work->work)){+.+.}-{0:0}, at: process_one_work+0x40e/0x980 #2: ffff888005ac83f8 (sb_writers#5){.+.+}-{0:0}, at: filename_create+0xb6/0x260 #3: ffff8880057ce760 (&type->i_mutex_dir_key#3/1){+.+.}-{3:3}, at: filename_create+0x123/0x260 Cc: [email protected] Fixes: 40b268d ("ksmbd: add mnt_want_write to ksmbd vfs functions") Signed-off-by: Marios Makassikis <[email protected]> Acked-by: Namjae Jeon <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 3354db6 commit 807252f

File tree

1 file changed

+3
-20
lines changed

1 file changed

+3
-20
lines changed

fs/smb/server/vfs.c

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,6 @@ int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode)
173173
return err;
174174
}
175175

176-
err = mnt_want_write(path.mnt);
177-
if (err)
178-
goto out_err;
179-
180176
mode |= S_IFREG;
181177
err = vfs_create(mnt_idmap(path.mnt), d_inode(path.dentry),
182178
dentry, mode, true);
@@ -186,9 +182,7 @@ int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode)
186182
} else {
187183
pr_err("File(%s): creation failed (err:%d)\n", name, err);
188184
}
189-
mnt_drop_write(path.mnt);
190185

191-
out_err:
192186
done_path_create(&path, dentry);
193187
return err;
194188
}
@@ -219,10 +213,6 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode)
219213
return err;
220214
}
221215

222-
err = mnt_want_write(path.mnt);
223-
if (err)
224-
goto out_err2;
225-
226216
idmap = mnt_idmap(path.mnt);
227217
mode |= S_IFDIR;
228218
err = vfs_mkdir(idmap, d_inode(path.dentry), dentry, mode);
@@ -233,21 +223,19 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode)
233223
dentry->d_name.len);
234224
if (IS_ERR(d)) {
235225
err = PTR_ERR(d);
236-
goto out_err1;
226+
goto out_err;
237227
}
238228
if (unlikely(d_is_negative(d))) {
239229
dput(d);
240230
err = -ENOENT;
241-
goto out_err1;
231+
goto out_err;
242232
}
243233

244234
ksmbd_vfs_inherit_owner(work, d_inode(path.dentry), d_inode(d));
245235
dput(d);
246236
}
247237

248-
out_err1:
249-
mnt_drop_write(path.mnt);
250-
out_err2:
238+
out_err:
251239
done_path_create(&path, dentry);
252240
if (err)
253241
pr_err("mkdir(%s): creation failed (err:%d)\n", name, err);
@@ -665,16 +653,11 @@ int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname,
665653
goto out3;
666654
}
667655

668-
err = mnt_want_write(newpath.mnt);
669-
if (err)
670-
goto out3;
671-
672656
err = vfs_link(oldpath.dentry, mnt_idmap(newpath.mnt),
673657
d_inode(newpath.dentry),
674658
dentry, NULL);
675659
if (err)
676660
ksmbd_debug(VFS, "vfs_link failed err %d\n", err);
677-
mnt_drop_write(newpath.mnt);
678661

679662
out3:
680663
done_path_create(&newpath, dentry);

0 commit comments

Comments
 (0)