Skip to content

Commit ee25861

Browse files
committed
Merge tag 'vfs-6.12.fallocate' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull vfs fallocate updates from Christian Brauner: "This contains work to try and cleanup some the fallocate mode handling. Currently, it confusingly mixes operation modes and an optional flag. The work here tries to better define operation modes and optional flags allowing the core and filesystem code to use switch statements to switch on the operation mode" * tag 'vfs-6.12.fallocate' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: xfs: refactor xfs_file_fallocate xfs: move the xfs_is_always_cow_inode check into xfs_alloc_file_space xfs: call xfs_flush_unmap_range from xfs_free_file_space fs: sort out the fallocate mode vs flag mess ext4: remove tracing for FALLOC_FL_NO_HIDE_STALE block: remove checks for FALLOC_FL_NO_HIDE_STALE
2 parents 3352633 + 7fbabbb commit ee25861

File tree

7 files changed

+258
-187
lines changed

7 files changed

+258
-187
lines changed

block/fops.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,7 @@ static ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to)
771771

772772
#define BLKDEV_FALLOC_FL_SUPPORTED \
773773
(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE | \
774-
FALLOC_FL_ZERO_RANGE | FALLOC_FL_NO_HIDE_STALE)
774+
FALLOC_FL_ZERO_RANGE)
775775

776776
static long blkdev_fallocate(struct file *file, int mode, loff_t start,
777777
loff_t len)
@@ -830,14 +830,6 @@ static long blkdev_fallocate(struct file *file, int mode, loff_t start,
830830
len >> SECTOR_SHIFT, GFP_KERNEL,
831831
BLKDEV_ZERO_NOFALLBACK);
832832
break;
833-
case FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE | FALLOC_FL_NO_HIDE_STALE:
834-
error = truncate_bdev_range(bdev, file_to_blk_mode(file), start, end);
835-
if (error)
836-
goto fail;
837-
838-
error = blkdev_issue_discard(bdev, start >> SECTOR_SHIFT,
839-
len >> SECTOR_SHIFT, GFP_KERNEL);
840-
break;
841833
default:
842834
error = -EOPNOTSUPP;
843835
}

fs/open.c

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -252,40 +252,39 @@ int vfs_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
252252
if (offset < 0 || len <= 0)
253253
return -EINVAL;
254254

255-
/* Return error if mode is not supported */
256-
if (mode & ~FALLOC_FL_SUPPORTED_MASK)
255+
if (mode & ~(FALLOC_FL_MODE_MASK | FALLOC_FL_KEEP_SIZE))
257256
return -EOPNOTSUPP;
258257

259-
/* Punch hole and zero range are mutually exclusive */
260-
if ((mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE)) ==
261-
(FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE))
262-
return -EOPNOTSUPP;
263-
264-
/* Punch hole must have keep size set */
265-
if ((mode & FALLOC_FL_PUNCH_HOLE) &&
266-
!(mode & FALLOC_FL_KEEP_SIZE))
258+
/*
259+
* Modes are exclusive, even if that is not obvious from the encoding
260+
* as bit masks and the mix with the flag in the same namespace.
261+
*
262+
* To make things even more complicated, FALLOC_FL_ALLOCATE_RANGE is
263+
* encoded as no bit set.
264+
*/
265+
switch (mode & FALLOC_FL_MODE_MASK) {
266+
case FALLOC_FL_ALLOCATE_RANGE:
267+
case FALLOC_FL_UNSHARE_RANGE:
268+
case FALLOC_FL_ZERO_RANGE:
269+
break;
270+
case FALLOC_FL_PUNCH_HOLE:
271+
if (!(mode & FALLOC_FL_KEEP_SIZE))
272+
return -EOPNOTSUPP;
273+
break;
274+
case FALLOC_FL_COLLAPSE_RANGE:
275+
case FALLOC_FL_INSERT_RANGE:
276+
if (mode & FALLOC_FL_KEEP_SIZE)
277+
return -EOPNOTSUPP;
278+
break;
279+
default:
267280
return -EOPNOTSUPP;
268-
269-
/* Collapse range should only be used exclusively. */
270-
if ((mode & FALLOC_FL_COLLAPSE_RANGE) &&
271-
(mode & ~FALLOC_FL_COLLAPSE_RANGE))
272-
return -EINVAL;
273-
274-
/* Insert range should only be used exclusively. */
275-
if ((mode & FALLOC_FL_INSERT_RANGE) &&
276-
(mode & ~FALLOC_FL_INSERT_RANGE))
277-
return -EINVAL;
278-
279-
/* Unshare range should only be used with allocate mode. */
280-
if ((mode & FALLOC_FL_UNSHARE_RANGE) &&
281-
(mode & ~(FALLOC_FL_UNSHARE_RANGE | FALLOC_FL_KEEP_SIZE)))
282-
return -EINVAL;
281+
}
283282

284283
if (!(file->f_mode & FMODE_WRITE))
285284
return -EBADF;
286285

287286
/*
288-
* We can only allow pure fallocate on append only files
287+
* On append-only files only space preallocation is supported.
289288
*/
290289
if ((mode & ~FALLOC_FL_KEEP_SIZE) && IS_APPEND(inode))
291290
return -EPERM;

fs/xfs/xfs_bmap_util.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,9 @@ xfs_alloc_file_space(
653653
xfs_bmbt_irec_t imaps[1], *imapp;
654654
int error;
655655

656+
if (xfs_is_always_cow_inode(ip))
657+
return 0;
658+
656659
trace_xfs_alloc_file_space(ip);
657660

658661
if (xfs_is_shutdown(mp))
@@ -848,6 +851,14 @@ xfs_free_file_space(
848851
if (len <= 0) /* if nothing being freed */
849852
return 0;
850853

854+
/*
855+
* Now AIO and DIO has drained we flush and (if necessary) invalidate
856+
* the cached range over the first operation we are about to run.
857+
*/
858+
error = xfs_flush_unmap_range(ip, offset, len);
859+
if (error)
860+
return error;
861+
851862
startoffset_fsb = XFS_B_TO_FSB(mp, offset);
852863
endoffset_fsb = XFS_B_TO_FSBT(mp, offset + len);
853864

0 commit comments

Comments
 (0)