Skip to content

Commit 47178c7

Browse files
Ronnie Sahlbergsmfrench
authored andcommitted
cifs: fix handlecache and multiuser
In multiuser each individual user has their own tcon structure for the share and thus their own handle for a cached directory. When we umount such a share we much make sure to release the pinned down dentry for each such tcon and not just the master tcon. Otherwise we will get nasty warnings on umount that dentries are still in use: [ 3459.590047] BUG: Dentry 00000000115c6f41{i=12000000019d95,n=/} still in use\ (2) [unmount of cifs cifs] ... [ 3459.590492] Call Trace: [ 3459.590500] d_walk+0x61/0x2a0 [ 3459.590518] ? shrink_lock_dentry.part.0+0xe0/0xe0 [ 3459.590526] shrink_dcache_for_umount+0x49/0x110 [ 3459.590535] generic_shutdown_super+0x1a/0x110 [ 3459.590542] kill_anon_super+0x14/0x30 [ 3459.590549] cifs_kill_sb+0xf5/0x104 [cifs] [ 3459.590773] deactivate_locked_super+0x36/0xa0 [ 3459.590782] cleanup_mnt+0x131/0x190 [ 3459.590789] task_work_run+0x5c/0x90 [ 3459.590798] exit_to_user_mode_loop+0x151/0x160 [ 3459.590809] exit_to_user_mode_prepare+0x83/0xd0 [ 3459.590818] syscall_exit_to_user_mode+0x12/0x30 [ 3459.590828] do_syscall_64+0x48/0x90 [ 3459.590833] entry_SYSCALL_64_after_hwframe+0x44/0xae Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Acked-by: Paulo Alcantara (SUSE) <pc@cjr.nz> Cc: stable@vger.kernel.org Signed-off-by: Steve French <stfrench@microsoft.com>
1 parent 6e40698 commit 47178c7

1 file changed

Lines changed: 10 additions & 3 deletions

File tree

fs/cifs/cifsfs.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,9 @@ static void cifs_kill_sb(struct super_block *sb)
254254
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
255255
struct cifs_tcon *tcon;
256256
struct cached_fid *cfid;
257+
struct rb_root *root = &cifs_sb->tlink_tree;
258+
struct rb_node *node;
259+
struct tcon_link *tlink;
257260

258261
/*
259262
* We ned to release all dentries for the cached directories
@@ -263,17 +266,21 @@ static void cifs_kill_sb(struct super_block *sb)
263266
dput(cifs_sb->root);
264267
cifs_sb->root = NULL;
265268
}
266-
tcon = cifs_sb_master_tcon(cifs_sb);
267-
if (tcon) {
269+
spin_lock(&cifs_sb->tlink_tree_lock);
270+
node = rb_first(root);
271+
while (node != NULL) {
272+
tlink = rb_entry(node, struct tcon_link, tl_rbnode);
273+
tcon = tlink_tcon(tlink);
268274
cfid = &tcon->crfid;
269275
mutex_lock(&cfid->fid_mutex);
270276
if (cfid->dentry) {
271-
272277
dput(cfid->dentry);
273278
cfid->dentry = NULL;
274279
}
275280
mutex_unlock(&cfid->fid_mutex);
281+
node = rb_next(node);
276282
}
283+
spin_unlock(&cifs_sb->tlink_tree_lock);
277284

278285
kill_anon_super(sb);
279286
cifs_umount(cifs_sb);

0 commit comments

Comments
 (0)