From: Konstantin Komarov Date: Thu, 30 Jun 2022 16:14:43 +0000 (+0300) Subject: fs/ntfs3: Add new argument is_mft to ntfs_mark_rec_free X-Git-Tag: v5.15.198~433 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=83177ae964867c6450c0c3fa78bc7244d4409ecc;p=thirdparty%2Fkernel%2Fstable.git fs/ntfs3: Add new argument is_mft to ntfs_mark_rec_free [ Upstream commit 071100ea0e6c353258f322cb2f8dde9be62d6808 ] This argument helps in avoiding double locking Signed-off-by: Konstantin Komarov Stable-dep-of: 4d78d1173a65 ("fs/ntfs3: out1 also needs to put mi") Signed-off-by: Sasha Levin --- diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c index a74bbfec8e3ac..b5f3e7bc5d6da 100644 --- a/fs/ntfs3/frecord.c +++ b/fs/ntfs3/frecord.c @@ -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); } diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c index c82398194cd10..7dc2ae7dec591 100644 --- a/fs/ntfs3/fsntfs.c +++ b/fs/ntfs3/fsntfs.c @@ -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); } /* diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c index 0f4e166112de1..7ac76e6c35dcf 100644 --- a/fs/ntfs3/inode.c +++ b/fs/ntfs3/inode.c @@ -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); diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h index f7ef60bed6d84..69d1442eea623 100644 --- a/fs/ntfs3/ntfs_fs.h +++ b/fs/ntfs3/ntfs_fs.h @@ -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);