summaryrefslogtreecommitdiff
path: root/fs/nfsd
diff options
context:
space:
mode:
authorTrond Myklebust <trondmy@gmail.com>2020-01-06 21:20:47 +0300
committerJ. Bruce Fields <bfields@redhat.com>2020-01-23 00:25:40 +0300
commit90d2f1da832fd23290ef0c0d964d97501e5e8553 (patch)
treef268c330df953f234da0d75438c3802d20e0cc7b /fs/nfsd
parentb6669305d35a3459877afef6e9f68e81bef92972 (diff)
downloadlinux-90d2f1da832fd23290ef0c0d964d97501e5e8553.tar.xz
nfsd: Fix a soft lockup race in nfsd_file_mark_find_or_create()
If nfsd_file_mark_find_or_create() keeps winning the race for the nfsd_file_fsnotify_group->mark_mutex against nfsd_file_mark_put() then it can soft lock up, since fsnotify_add_inode_mark() ends up always finding an existing entry. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/filecache.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c
index 9c2b29e07975..f275c11c4e28 100644
--- a/fs/nfsd/filecache.c
+++ b/fs/nfsd/filecache.c
@@ -132,9 +132,13 @@ nfsd_file_mark_find_or_create(struct nfsd_file *nf)
struct nfsd_file_mark,
nfm_mark));
mutex_unlock(&nfsd_file_fsnotify_group->mark_mutex);
- fsnotify_put_mark(mark);
- if (likely(nfm))
+ if (nfm) {
+ fsnotify_put_mark(mark);
break;
+ }
+ /* Avoid soft lockup race with nfsd_file_mark_put() */
+ fsnotify_destroy_mark(mark, nfsd_file_fsnotify_group);
+ fsnotify_put_mark(mark);
} else
mutex_unlock(&nfsd_file_fsnotify_group->mark_mutex);