Skip to content

Commit aabb45f

Browse files
amir73iljankara
authored andcommitted
dnotify: use fsnotify group lock helpers
Before commit 9542e6a ("nfsd: Containerise filecache laundrette") nfsd would close open files in direct reclaim context. There is no guarantee that others memory shrinkers don't do the same and no guarantee that future shrinkers won't do that. For example, if overlayfs implements inode cache of fscache would keep open files to cached objects, inode shrinkers could end up closing open files to underlying fs. Direct reclaim from dnotify mark allocation context may try to close open files that have dnotify marks of the same group and hit a deadlock on mark_mutex. Set the FSNOTIFY_GROUP_NOFS flag to prevent going into direct reclaim from allocations under dnotify group lock and use the safe group lock helpers. Link: https://lore.kernel.org/r/20220422120327.3459282-11-amir73il@gmail.com Suggested-by: Jan Kara <jack@suse.cz> Link: https://lore.kernel.org/r/20220321112310.vpr7oxro2xkz5llh@quack3.lan/ Signed-off-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Jan Kara <jack@suse.cz>
1 parent b8962a9 commit aabb45f

1 file changed

Lines changed: 7 additions & 6 deletions

File tree

fs/notify/dnotify/dnotify.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ void dnotify_flush(struct file *filp, fl_owner_t id)
168168
return;
169169
dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark);
170170

171-
mutex_lock(&dnotify_group->mark_mutex);
171+
fsnotify_group_lock(dnotify_group);
172172

173173
spin_lock(&fsn_mark->lock);
174174
prev = &dn_mark->dn;
@@ -191,7 +191,7 @@ void dnotify_flush(struct file *filp, fl_owner_t id)
191191
free = true;
192192
}
193193

194-
mutex_unlock(&dnotify_group->mark_mutex);
194+
fsnotify_group_unlock(dnotify_group);
195195

196196
if (free)
197197
fsnotify_free_mark(fsn_mark);
@@ -324,7 +324,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
324324
new_dn_mark->dn = NULL;
325325

326326
/* this is needed to prevent the fcntl/close race described below */
327-
mutex_lock(&dnotify_group->mark_mutex);
327+
fsnotify_group_lock(dnotify_group);
328328

329329
/* add the new_fsn_mark or find an old one. */
330330
fsn_mark = fsnotify_find_mark(&inode->i_fsnotify_marks, dnotify_group);
@@ -334,7 +334,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
334334
} else {
335335
error = fsnotify_add_inode_mark_locked(new_fsn_mark, inode, 0);
336336
if (error) {
337-
mutex_unlock(&dnotify_group->mark_mutex);
337+
fsnotify_group_unlock(dnotify_group);
338338
goto out_err;
339339
}
340340
spin_lock(&new_fsn_mark->lock);
@@ -383,7 +383,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
383383

384384
if (destroy)
385385
fsnotify_detach_mark(fsn_mark);
386-
mutex_unlock(&dnotify_group->mark_mutex);
386+
fsnotify_group_unlock(dnotify_group);
387387
if (destroy)
388388
fsnotify_free_mark(fsn_mark);
389389
fsnotify_put_mark(fsn_mark);
@@ -401,7 +401,8 @@ static int __init dnotify_init(void)
401401
SLAB_PANIC|SLAB_ACCOUNT);
402402
dnotify_mark_cache = KMEM_CACHE(dnotify_mark, SLAB_PANIC|SLAB_ACCOUNT);
403403

404-
dnotify_group = fsnotify_alloc_group(&dnotify_fsnotify_ops, 0);
404+
dnotify_group = fsnotify_alloc_group(&dnotify_fsnotify_ops,
405+
FSNOTIFY_GROUP_NOFS);
405406
if (IS_ERR(dnotify_group))
406407
panic("unable to allocate fsnotify group for dnotify\n");
407408
dnotify_sysctl_init();

0 commit comments

Comments
 (0)