FAILED: patch "[PATCH] fs/ntfs3: Enable FALLOC_FL_INSERT_RANGE" failed to apply to 5.15-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From e4d2f4fd5341064d2b3c5158da69421a581e7ec1 Mon Sep 17 00:00:00 2001
From: Konstantin Komarov <[email protected]>
Date: Tue, 21 Jun 2022 12:49:52 +0300
Subject: [PATCH] fs/ntfs3: Enable FALLOC_FL_INSERT_RANGE
Changed logic in ntfs_fallocate - more clear checks in beginning instead of the middle of function and added FALLOC_FL_INSERT_RANGE. Fixes xfstest generic/064
Fixes 4342306f0f0d ("fs/ntfs3: Add file operations and implementation")
Signed-off-by Konstantin Komarov <[email protected]>
fs/ntfs3/file.c +55 -42
@@ -533,21 +533,35 @@ static int ntfs_truncate(struct inode *inode, loff_t new_size)static long ntfs_fallocate (struct file *file,int mode,loff_t vbo,loff_t len) {struct inode *inode = file->f_mapping->host; +struct address_space *mapping = inode->i_mapping;struct super_block *sb = inode->i_sb;struct ntfs_sb_info *sbi = sb->s_fs_info;struct ntfs_inode *ni =ntfs_i (inode);loff_t end = vbo + len;loff_t vbo_down =round_down (vbo,PAGE_SIZE ); -loff_t i_size; +bool is_supported_holes =is_sparsed (ni) ||is_compressed (ni); +loff_t i_size, new_size; +bool map_locked;int err;/* No support for dir. */ if (!S_ISREG (inode->i_mode))return -EOPNOTSUPP ; -/* Return error if mode is not supported. */ -if (mode & ~(FALLOC_FL_KEEP_SIZE |FALLOC_FL_PUNCH_HOLE | -FALLOC_FL_COLLAPSE_RANGE )) { +/* +* vfs_fallocate checks all possible combinations of mode. +* Do additional checks here before ntfs_set_state(dirty). +*/ +if (mode &FALLOC_FL_PUNCH_HOLE ) { +if (!is_supported_holes) +return -EOPNOTSUPP ; + }else if (mode &FALLOC_FL_COLLAPSE_RANGE ) { + }else if (mode &FALLOC_FL_INSERT_RANGE ) { +if (!is_supported_holes) +return -EOPNOTSUPP ; + }else if (mode & + ~(FALLOC_FL_KEEP_SIZE |FALLOC_FL_PUNCH_HOLE | +FALLOC_FL_COLLAPSE_RANGE |FALLOC_FL_INSERT_RANGE )) {ntfs_inode_warn (inode,"fallocate(0x%x) is not supported" , mode);return -EOPNOTSUPP ;
@@ -557,6 +571,8 @@ static long ntfs_fallocate(struct file *file, int mode, loff_t vbo, loff_t len)inode_lock (inode); i_size = inode->i_size; + new_size =max (end, i_size); + map_locked = false;if (WARN_ON (ni->ni_flags &NI_FLAG_COMPRESSED_MASK )) {/* Should never be here, see ntfs_file_open. */
@@ -564,38 +580,27 @@ static long ntfs_fallocate(struct file *file, int mode, loff_t vbo, loff_t len) goto out; } +if (mode & (FALLOC_FL_PUNCH_HOLE |FALLOC_FL_COLLAPSE_RANGE | +FALLOC_FL_INSERT_RANGE )) { +inode_dio_wait (inode); +filemap_invalidate_lock (mapping); + map_locked = true; + } +if (mode &FALLOC_FL_PUNCH_HOLE ) {u32 frame_size;loff_t mask, vbo_a, end_a, tmp; -if (!(mode &FALLOC_FL_KEEP_SIZE )) { - err = -EINVAL ; - goto out; - } - - err =filemap_write_and_wait_range (inode->i_mapping, vbo, - end -1 ); + err =filemap_write_and_wait_range (mapping, vbo, end -1 );if (err) goto out; - err =filemap_write_and_wait_range (inode->i_mapping, end, -LLONG_MAX ); + err =filemap_write_and_wait_range (mapping, end,LLONG_MAX );if (err) goto out; -inode_dio_wait (inode); -truncate_pagecache (inode, vbo_down); -if (!is_sparsed (ni) && !is_compressed (ni)) { -/* -* Normal file, can't make hole. -* TODO: Try to find way to save info about hole. -*/ - err = -EOPNOTSUPP ; - goto out; - } -ni_lock (ni); err =attr_punch_hole (ni, vbo, len, &frame_size);ni_unlock (ni);
@@ -627,17 +632,11 @@ static long ntfs_fallocate(struct file *file, int mode, loff_t vbo, loff_t len)ni_unlock (ni); } }else if (mode &FALLOC_FL_COLLAPSE_RANGE ) { -if (mode & ~FALLOC_FL_COLLAPSE_RANGE ) { - err = -EINVAL ; - goto out; - } -/* * Write tail of the last page before removed range since * it will get removed from the page cache below. */ - err =filemap_write_and_wait_range (inode->i_mapping, vbo_down, - vbo); + err =filemap_write_and_wait_range (mapping, vbo_down, vbo);if (err) goto out;
@@ -645,34 +644,45 @@ static long ntfs_fallocate(struct file *file, int mode, loff_t vbo, loff_t len)* Write data that will be shifted to preserve them * when discarding page cache below. */ - err =filemap_write_and_wait_range (inode->i_mapping, end, -LLONG_MAX ); + err =filemap_write_and_wait_range (mapping, end,LLONG_MAX );if (err) goto out; -/* Wait for existing dio to complete. */ -inode_dio_wait (inode); -truncate_pagecache (inode, vbo_down);ni_lock (ni); err =attr_collapse_range (ni, vbo, len);ni_unlock (ni); - }else { -/* -* Normal file: Allocate clusters, do not change 'valid' size. -*/ -loff_t new_size =max (end, i_size); + }else if (mode &FALLOC_FL_INSERT_RANGE ) { +/* Check new size. */ + err =inode_newsize_ok (inode, new_size); +if (err) + goto out; + +/* Write out all dirty pages. */ + err =filemap_write_and_wait_range (mapping, vbo_down, +LLONG_MAX ); +if (err) + goto out; +truncate_pagecache (inode, vbo_down); +ni_lock (ni); + err =attr_insert_range (ni, vbo, len); +ni_unlock (ni); + }else { +/* Check new size. */ err =inode_newsize_ok (inode, new_size);if (err) goto out; +/* +* Allocate clusters, do not change 'valid' size. +*/ err =ntfs_set_size (inode, new_size);if (err) goto out; -if (is_sparsed (ni) ||is_compressed (ni)) { +if (is_supported_holes) {CLST vcn_v = ni->i_valid >> sbi->cluster_bits;CLST vcn = vbo >> sbi->cluster_bits;CLST cend =bytes_to_cluster (sbi, end);
@@ -720,6 +730,9 @@ static long ntfs_fallocate(struct file *file, int mode, loff_t vbo, loff_t len) } out: +if (map_locked) +filemap_invalidate_unlock (mapping); +if (err == -EFBIG ) err = -ENOSPC ;