[Devel] [PATCH] fs: sync: prevent possible deadlock in sync_collect_filesystems
Alexander Mikhalitsyn
alexander.mikhalitsyn at virtuozzo.com
Thu Mar 4 18:59:39 MSK 2021
There are two problems:
1. kmalloc should be called with GFP_NOWAIT to prevent sleep
under spinlock taken
2. spin_lock(&sb_lock) under spinlock(mnt_ns_list)
There we have a small probability of deadlock, to overcome
this let's use spin_trylock(&sb_lock) here.
Cc: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
Cc: Vasily Averin <vvs at virtuozzo.com>
Signed-off-by: Alexander Mikhalitsyn <alexander.mikhalitsyn at virtuozzo.com>
---
fs/sync.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/fs/sync.c b/fs/sync.c
index 1cf0f0b38824..b2b72ac75615 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -150,7 +150,7 @@ static int sync_collect_filesystems(struct ve_struct *ve, struct list_head *sync
if (sync_filesystem_collected(sync_list, mnt->mnt.mnt_sb))
continue;
- ss = kmalloc(sizeof(*ss), GFP_KERNEL);
+ ss = kmalloc(sizeof(*ss), GFP_NOWAIT);
if (ss == NULL) {
ret = -ENOMEM;
break;
@@ -161,7 +161,14 @@ static int sync_collect_filesystems(struct ve_struct *ve, struct list_head *sync
* alive. And it means, that we can safely increase it's usage
* counter.
*/
- spin_lock(&sb_lock);
+ if (unlikely(!spin_trylock(&sb_lock))) {
+ /*
+ * If we can't take spinlock then just skip that mount to prevent
+ * possible deadlocks here.
+ */
+ kfree(ss);
+ continue;
+ }
ss->sb->s_count++;
spin_unlock(&sb_lock);
list_add_tail(&ss->list, sync_list);
--
2.28.0
More information about the Devel
mailing list