]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
fs/ntfs3: Add new argument is_mft to ntfs_mark_rec_free
authorKonstantin Komarov <almaz.alexandrovich@paragon-software.com>
Thu, 30 Jun 2022 16:14:43 +0000 (19:14 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 19 Jan 2026 12:09:30 +0000 (13:09 +0100)
[ Upstream commit 071100ea0e6c353258f322cb2f8dde9be62d6808 ]

This argument helps in avoiding double locking

Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Stable-dep-of: 4d78d1173a65 ("fs/ntfs3: out1 also needs to put mi")
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/ntfs3/frecord.c
fs/ntfs3/fsntfs.c
fs/ntfs3/inode.c
fs/ntfs3/ntfs_fs.h

index a74bbfec8e3ac5dec0177f1e232813f4ff677cc4..b5f3e7bc5d6daf242cccb2dc06565bb1f9a4e9ff 100644 (file)
@@ -1037,7 +1037,7 @@ out2:
        err = -EINVAL;
 
 out1:
-       ntfs_mark_rec_free(sbi, rno);
+       ntfs_mark_rec_free(sbi, rno, is_mft);
 
 out:
        return err;
@@ -1232,7 +1232,7 @@ static int ni_expand_mft_list(struct ntfs_inode *ni)
                mft_min = mft_new;
                mi_min = mi_new;
        } else {
-               ntfs_mark_rec_free(sbi, mft_new);
+               ntfs_mark_rec_free(sbi, mft_new, true);
                mft_new = 0;
                ni_remove_mi(ni, mi_new);
        }
@@ -1315,7 +1315,7 @@ static int ni_expand_mft_list(struct ntfs_inode *ni)
 
 out:
        if (mft_new) {
-               ntfs_mark_rec_free(sbi, mft_new);
+               ntfs_mark_rec_free(sbi, mft_new, true);
                ni_remove_mi(ni, mi_new);
        }
 
@@ -1577,7 +1577,7 @@ int ni_delete_all(struct ntfs_inode *ni)
                mi->dirty = true;
                mi_write(mi, 0);
 
-               ntfs_mark_rec_free(sbi, mi->rno);
+               ntfs_mark_rec_free(sbi, mi->rno, false);
                ni_remove_mi(ni, mi);
                mi_put(mi);
                node = next;
@@ -1588,7 +1588,7 @@ int ni_delete_all(struct ntfs_inode *ni)
        ni->mi.dirty = true;
        err = mi_write(&ni->mi, 0);
 
-       ntfs_mark_rec_free(sbi, ni->mi.rno);
+       ntfs_mark_rec_free(sbi, ni->mi.rno, false);
 
        return err;
 }
@@ -3292,7 +3292,7 @@ int ni_write_inode(struct inode *inode, int sync, const char *hint)
                        err = err2;
 
                if (is_empty) {
-                       ntfs_mark_rec_free(sbi, mi->rno);
+                       ntfs_mark_rec_free(sbi, mi->rno, false);
                        rb_erase(node, &ni->mi_tree);
                        mi_put(mi);
                }
index c82398194cd10fdbabf3a0d03f9246a601f981c9..7dc2ae7dec591a1714b0408427ab8b6422d89d57 100644 (file)
@@ -703,12 +703,14 @@ out:
 
 /*
  * ntfs_mark_rec_free - Mark record as free.
+ * is_mft - true if we are changing MFT
  */
-void ntfs_mark_rec_free(struct ntfs_sb_info *sbi, CLST rno)
+void ntfs_mark_rec_free(struct ntfs_sb_info *sbi, CLST rno, bool is_mft)
 {
        struct wnd_bitmap *wnd = &sbi->mft.bitmap;
 
-       down_write_nested(&wnd->rw_lock, BITMAP_MUTEX_MFT);
+       if (!is_mft)
+               down_write_nested(&wnd->rw_lock, BITMAP_MUTEX_MFT);
        if (rno >= wnd->nbits)
                goto out;
 
@@ -727,7 +729,8 @@ void ntfs_mark_rec_free(struct ntfs_sb_info *sbi, CLST rno)
                sbi->mft.next_free = rno;
 
 out:
-       up_write(&wnd->rw_lock);
+       if (!is_mft)
+               up_write(&wnd->rw_lock);
 }
 
 /*
index 0f4e166112de1549b987a68cdf825cb19cec0a7e..7ac76e6c35dcf7752cde1d2e023904d4dd01b86b 100644 (file)
@@ -1668,7 +1668,7 @@ out4:
        ni->mi.dirty = false;
        discard_new_inode(inode);
 out3:
-       ntfs_mark_rec_free(sbi, ino);
+       ntfs_mark_rec_free(sbi, ino, false);
 
 out2:
        __putname(new_de);
index f7ef60bed6d8430db340c508a0bfc8818e7fe8e1..69d1442eea623a55effa4a58adb2dcce046ff8fb 100644 (file)
@@ -596,7 +596,7 @@ int ntfs_look_for_free_space(struct ntfs_sb_info *sbi, CLST lcn, CLST len,
                             enum ALLOCATE_OPT opt);
 int ntfs_look_free_mft(struct ntfs_sb_info *sbi, CLST *rno, bool mft,
                       struct ntfs_inode *ni, struct mft_inode **mi);
-void ntfs_mark_rec_free(struct ntfs_sb_info *sbi, CLST rno);
+void ntfs_mark_rec_free(struct ntfs_sb_info *sbi, CLST rno, bool is_mft);
 int ntfs_clear_mft_tail(struct ntfs_sb_info *sbi, size_t from, size_t to);
 int ntfs_refresh_zone(struct ntfs_sb_info *sbi);
 int ntfs_update_mftmirr(struct ntfs_sb_info *sbi, int wait);