summaryrefslogtreecommitdiff
path: root/fs/ntfs3/fsntfs.c
diff options
context:
space:
mode:
authorKonstantin Komarov <almaz.alexandrovich@paragon-software.com>2022-10-07 20:20:14 +0300
committerKonstantin Komarov <almaz.alexandrovich@paragon-software.com>2022-11-14 19:50:46 +0300
commit910013f7c7ba9fb82ce33536c58212907ca05969 (patch)
tree10c67ae795c392a0cea0c2735a4ae4b0b019550e /fs/ntfs3/fsntfs.c
parent0ad9dfcb8d3fd6ef91983ccb93fafbf9e3115796 (diff)
downloadlwn-910013f7c7ba9fb82ce33536c58212907ca05969.tar.gz
lwn-910013f7c7ba9fb82ce33536c58212907ca05969.zip
fs/ntfs3: Restore correct state after ENOSPC in attr_data_get_block
Added new function ntfs_check_for_free_space. Added undo mechanism in attr_data_get_block. Fixes xfstest generic/083 Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Diffstat (limited to 'fs/ntfs3/fsntfs.c')
-rw-r--r--fs/ntfs3/fsntfs.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c
index b68a7b780262..4f04e8594a8f 100644
--- a/fs/ntfs3/fsntfs.c
+++ b/fs/ntfs3/fsntfs.c
@@ -444,6 +444,39 @@ up_write:
}
/*
+ * ntfs_check_for_free_space
+ *
+ * Check if it is possible to allocate 'clen' clusters and 'mlen' Mft records
+ */
+bool ntfs_check_for_free_space(struct ntfs_sb_info *sbi, CLST clen, CLST mlen)
+{
+ size_t free, zlen, avail;
+ struct wnd_bitmap *wnd;
+
+ wnd = &sbi->used.bitmap;
+ down_read_nested(&wnd->rw_lock, BITMAP_MUTEX_CLUSTERS);
+ free = wnd_zeroes(wnd);
+ zlen = wnd_zone_len(wnd);
+ up_read(&wnd->rw_lock);
+
+ if (free < zlen + clen)
+ return false;
+
+ avail = free - (zlen + clen);
+
+ wnd = &sbi->mft.bitmap;
+ down_read_nested(&wnd->rw_lock, BITMAP_MUTEX_MFT);
+ free = wnd_zeroes(wnd);
+ zlen = wnd_zone_len(wnd);
+ up_read(&wnd->rw_lock);
+
+ if (free >= zlen + mlen)
+ return true;
+
+ return avail >= bytes_to_cluster(sbi, mlen << sbi->record_bits);
+}
+
+/*
* ntfs_extend_mft - Allocate additional MFT records.
*
* sbi->mft.bitmap is locked for write.