Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
loop: don't print warnings if the underlying filesystem doesn't suppo…
…rt discard

On Tue, 12 Oct 2021, Christoph Hellwig wrote:

> On Mon, Oct 04, 2021 at 09:01:33AM -0400, Mikulas Patocka wrote:
> > Do you want this patch?
>
> Yes, this looks like what I want.  Minor nitpicks below:
>
> > +	.fallocate_flags = BLKDEV_FALLOC_FL_SUPPORTED,
>
> I'd probably call this fallocate_supported_flags.
>
> > +	.fallocate_flags = FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE,
>
> Please avoid over 80 lines for a plain list of flags.

OK. Here I'm sending a new version of the patch.

BTW. for some filesystems (cifs, ext4, fuse, ...), the supported falloc
flags vary dynamically - for example, ext4 can do COLLAPSE_RANGE and
INSERT_RANGE operations only if the filesystem is not ext2 or ext3 and if
the file is not encrypted.

Should we add a new flag FALLOC_FL_RETURN_SUPORTED_FLAGS that will return
the supported flags instead of using a static field in the file_operations
structure?

Mikulas

From: Mikulas Patocka <mpatocka@redhat.com>

The loop driver checks for the fallocate method and if it is present, it
assumes that the filesystem can do FALLOC_FL_ZERO_RANGE and
FALLOC_FL_PUNCH_HOLE requests. However, some filesystems (such as fat, or
tmpfs) have the fallocate method, but lack the capability to do
FALLOC_FL_ZERO_RANGE and/or FALLOC_FL_PUNCH_HOLE.

This results in syslog warnings "blk_update_request: operation not
supported error, dev loop0, sector 0 op 0x9:(WRITE_ZEROES) flags 0x800800
phys_seg 0 prio class 0". The error can be reproduced with this command:
"truncate -s 1GiB /tmp/file; losetup /dev/loop0 /tmp/file; blkdiscard -z
/dev/loop0"

This patch introduces a field "fallocate_supported_flags" in struct
file_operations that specifies the flags that are supported by the
fallocate methods. The loopback driver will check this field to determine
if FALLOC_FL_PUNCH_HOLE or FALLOC_FL_ZERO_RANGE is supported

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
  • Loading branch information
Mikulas Patocka authored and intel-lab-lkp committed Oct 12, 2021
1 parent a54cbb6 commit c381403
Show file tree
Hide file tree
Showing 19 changed files with 53 additions and 2 deletions.
1 change: 1 addition & 0 deletions block/fops.c
Expand Up @@ -595,6 +595,7 @@ const struct file_operations def_blk_fops = {
.splice_read = generic_file_splice_read,
.splice_write = iter_file_splice_write,
.fallocate = blkdev_fallocate,
.fallocate_supported_flags = BLKDEV_FALLOC_FL_SUPPORTED,
};

static __init int blkdev_init(void)
Expand Down
10 changes: 8 additions & 2 deletions drivers/block/loop.c
Expand Up @@ -947,7 +947,10 @@ static void loop_config_discard(struct loop_device *lo)
* encryption is enabled, because it may give an attacker
* useful information.
*/
} else if (!file->f_op->fallocate || lo->lo_encrypt_key_size) {
} else if ((file->f_op->fallocate_supported_flags &
(FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE)) !=
(FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE) ||
lo->lo_encrypt_key_size) {
max_discard_sectors = 0;
granularity = 0;

Expand All @@ -959,7 +962,10 @@ static void loop_config_discard(struct loop_device *lo)
if (max_discard_sectors) {
q->limits.discard_granularity = granularity;
blk_queue_max_discard_sectors(q, max_discard_sectors);
blk_queue_max_write_zeroes_sectors(q, max_discard_sectors);
if (file->f_op->fallocate_supported_flags & FALLOC_FL_ZERO_RANGE)
blk_queue_max_write_zeroes_sectors(q, max_discard_sectors);
else
blk_queue_max_write_zeroes_sectors(q, 0);
blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
} else {
q->limits.discard_granularity = 0;
Expand Down
2 changes: 2 additions & 0 deletions fs/btrfs/file.c
Expand Up @@ -3688,6 +3688,8 @@ const struct file_operations btrfs_file_operations = {
.release = btrfs_release_file,
.fsync = btrfs_sync_file,
.fallocate = btrfs_fallocate,
.fallocate_supported_flags = FALLOC_FL_KEEP_SIZE |
FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE,
.unlocked_ioctl = btrfs_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = btrfs_compat_ioctl,
Expand Down
1 change: 1 addition & 0 deletions fs/ceph/file.c
Expand Up @@ -2492,5 +2492,6 @@ const struct file_operations ceph_file_fops = {
.unlocked_ioctl = ceph_ioctl,
.compat_ioctl = compat_ptr_ioctl,
.fallocate = ceph_fallocate,
.fallocate_supported_flags = FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE,
.copy_file_range = ceph_copy_file_range,
};
18 changes: 18 additions & 0 deletions fs/cifs/cifsfs.c
Expand Up @@ -1281,6 +1281,9 @@ const struct file_operations cifs_file_ops = {
.remap_file_range = cifs_remap_file_range,
.setlease = cifs_setlease,
.fallocate = cifs_fallocate,
.fallocate_supported_flags = FALLOC_FL_PUNCH_HOLE |
FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE |
FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE,
};

const struct file_operations cifs_file_strict_ops = {
Expand All @@ -1301,6 +1304,9 @@ const struct file_operations cifs_file_strict_ops = {
.remap_file_range = cifs_remap_file_range,
.setlease = cifs_setlease,
.fallocate = cifs_fallocate,
.fallocate_supported_flags = FALLOC_FL_PUNCH_HOLE |
FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE |
FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE,
};

const struct file_operations cifs_file_direct_ops = {
Expand All @@ -1321,6 +1327,9 @@ const struct file_operations cifs_file_direct_ops = {
.llseek = cifs_llseek,
.setlease = cifs_setlease,
.fallocate = cifs_fallocate,
.fallocate_supported_flags = FALLOC_FL_PUNCH_HOLE |
FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE |
FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE,
};

const struct file_operations cifs_file_nobrl_ops = {
Expand All @@ -1339,6 +1348,9 @@ const struct file_operations cifs_file_nobrl_ops = {
.remap_file_range = cifs_remap_file_range,
.setlease = cifs_setlease,
.fallocate = cifs_fallocate,
.fallocate_supported_flags = FALLOC_FL_PUNCH_HOLE |
FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE |
FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE,
};

const struct file_operations cifs_file_strict_nobrl_ops = {
Expand All @@ -1357,6 +1369,9 @@ const struct file_operations cifs_file_strict_nobrl_ops = {
.remap_file_range = cifs_remap_file_range,
.setlease = cifs_setlease,
.fallocate = cifs_fallocate,
.fallocate_supported_flags = FALLOC_FL_PUNCH_HOLE |
FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE |
FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE,
};

const struct file_operations cifs_file_direct_nobrl_ops = {
Expand All @@ -1375,6 +1390,9 @@ const struct file_operations cifs_file_direct_nobrl_ops = {
.llseek = cifs_llseek,
.setlease = cifs_setlease,
.fallocate = cifs_fallocate,
.fallocate_supported_flags = FALLOC_FL_PUNCH_HOLE |
FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE |
FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE,
};

const struct file_operations cifs_dir_ops = {
Expand Down
3 changes: 3 additions & 0 deletions fs/ext4/file.c
Expand Up @@ -929,6 +929,9 @@ const struct file_operations ext4_file_operations = {
.splice_read = generic_file_splice_read,
.splice_write = iter_file_splice_write,
.fallocate = ext4_fallocate,
.fallocate_supported_flags = FALLOC_FL_KEEP_SIZE |
FALLOC_FL_PUNCH_HOLE | FALLOC_FL_COLLAPSE_RANGE |
FALLOC_FL_ZERO_RANGE | FALLOC_FL_INSERT_RANGE,
};

const struct inode_operations ext4_file_inode_operations = {
Expand Down
3 changes: 3 additions & 0 deletions fs/f2fs/file.c
Expand Up @@ -4499,6 +4499,9 @@ const struct file_operations f2fs_file_operations = {
.flush = f2fs_file_flush,
.fsync = f2fs_sync_file,
.fallocate = f2fs_fallocate,
.fallocate_supported_flags = FALLOC_FL_KEEP_SIZE |
FALLOC_FL_PUNCH_HOLE | FALLOC_FL_COLLAPSE_RANGE |
FALLOC_FL_ZERO_RANGE | FALLOC_FL_INSERT_RANGE,
.unlocked_ioctl = f2fs_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = f2fs_compat_ioctl,
Expand Down
1 change: 1 addition & 0 deletions fs/fat/file.c
Expand Up @@ -211,6 +211,7 @@ const struct file_operations fat_file_operations = {
.splice_read = generic_file_splice_read,
.splice_write = iter_file_splice_write,
.fallocate = fat_fallocate,
.fallocate_supported_flags = FALLOC_FL_KEEP_SIZE,
};

static int fat_cont_expand(struct inode *inode, loff_t size)
Expand Down
2 changes: 2 additions & 0 deletions fs/fuse/file.c
Expand Up @@ -3147,6 +3147,8 @@ static const struct file_operations fuse_file_operations = {
.compat_ioctl = fuse_file_compat_ioctl,
.poll = fuse_file_poll,
.fallocate = fuse_file_fallocate,
.fallocate_supported_flags = FALLOC_FL_KEEP_SIZE |
FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE,
.copy_file_range = fuse_copy_file_range,
};

Expand Down
1 change: 1 addition & 0 deletions fs/gfs2/file.c
Expand Up @@ -1366,6 +1366,7 @@ const struct file_operations gfs2_file_fops = {
.splice_write = gfs2_file_splice_write,
.setlease = simple_nosetlease,
.fallocate = gfs2_fallocate,
.fallocate_supported_flags = FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
};

const struct file_operations gfs2_dir_fops = {
Expand Down
1 change: 1 addition & 0 deletions fs/hugetlbfs/inode.c
Expand Up @@ -1163,6 +1163,7 @@ const struct file_operations hugetlbfs_file_operations = {
.get_unmapped_area = hugetlb_get_unmapped_area,
.llseek = default_llseek,
.fallocate = hugetlbfs_fallocate,
.fallocate_supported_flags = FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE,
};

static const struct inode_operations hugetlbfs_dir_inode_operations = {
Expand Down
1 change: 1 addition & 0 deletions fs/nfs/nfs4file.c
Expand Up @@ -457,6 +457,7 @@ const struct file_operations nfs4_file_operations = {
.copy_file_range = nfs4_copy_file_range,
.llseek = nfs4_file_llseek,
.fallocate = nfs42_fallocate,
.fallocate_supported_flags = FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
.remap_file_range = nfs42_remap_file_range,
#else
.llseek = nfs_file_llseek,
Expand Down
2 changes: 2 additions & 0 deletions fs/ntfs3/file.c
Expand Up @@ -1247,6 +1247,8 @@ const struct file_operations ntfs_file_operations = {
.fsync = generic_file_fsync,
.splice_write = iter_file_splice_write,
.fallocate = ntfs_fallocate,
.fallocate_supported_flags = FALLOC_FL_KEEP_SIZE |
FALLOC_FL_PUNCH_HOLE | FALLOC_FL_COLLAPSE_RANGE,
.release = ntfs_file_release,
};
// clang-format on
2 changes: 2 additions & 0 deletions fs/ocfs2/file.c
Expand Up @@ -2746,6 +2746,7 @@ const struct file_operations ocfs2_fops = {
.splice_read = generic_file_splice_read,
.splice_write = iter_file_splice_write,
.fallocate = ocfs2_fallocate,
.fallocate_supported_flags = FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE,
.remap_file_range = ocfs2_remap_file_range,
};

Expand Down Expand Up @@ -2792,6 +2793,7 @@ const struct file_operations ocfs2_fops_no_plocks = {
.splice_read = generic_file_splice_read,
.splice_write = iter_file_splice_write,
.fallocate = ocfs2_fallocate,
.fallocate_supported_flags = FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE,
.remap_file_range = ocfs2_remap_file_range,
};

Expand Down
1 change: 1 addition & 0 deletions fs/overlayfs/file.c
Expand Up @@ -658,6 +658,7 @@ const struct file_operations ovl_file_operations = {
.fsync = ovl_fsync,
.mmap = ovl_mmap,
.fallocate = ovl_fallocate,
.fallocate_supported_flags = FALLOC_FL_SUPPORTED_MASK,
.fadvise = ovl_fadvise,
.flush = ovl_flush,
.splice_read = generic_file_splice_read,
Expand Down
1 change: 1 addition & 0 deletions fs/xfs/xfs_file.c
Expand Up @@ -1464,6 +1464,7 @@ const struct file_operations xfs_file_operations = {
.fsync = xfs_file_fsync,
.get_unmapped_area = thp_get_unmapped_area,
.fallocate = xfs_file_fallocate,
.fallocate_supported_flags = XFS_FALLOC_FL_SUPPORTED,
.fadvise = xfs_file_fadvise,
.remap_file_range = xfs_file_remap_range,
};
Expand Down
1 change: 1 addition & 0 deletions include/linux/fs.h
Expand Up @@ -2094,6 +2094,7 @@ struct file_operations {
int (*setlease)(struct file *, long, struct file_lock **, void **);
long (*fallocate)(struct file *file, int mode, loff_t offset,
loff_t len);
unsigned fallocate_supported_flags;
void (*show_fdinfo)(struct seq_file *m, struct file *f);
#ifndef CONFIG_MMU
unsigned (*mmap_capabilities)(struct file *);
Expand Down
3 changes: 3 additions & 0 deletions ipc/shm.c
Expand Up @@ -44,6 +44,7 @@
#include <linux/mount.h>
#include <linux/ipc_namespace.h>
#include <linux/rhashtable.h>
#include <linux/falloc.h>

#include <linux/uaccess.h>

Expand Down Expand Up @@ -558,6 +559,7 @@ static const struct file_operations shm_file_operations = {
.get_unmapped_area = shm_get_unmapped_area,
.llseek = noop_llseek,
.fallocate = shm_fallocate,
.fallocate_supported_flags = FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE,
};

/*
Expand All @@ -571,6 +573,7 @@ static const struct file_operations shm_file_operations_huge = {
.get_unmapped_area = shm_get_unmapped_area,
.llseek = noop_llseek,
.fallocate = shm_fallocate,
.fallocate_supported_flags = FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE,
};

bool is_file_shm_hugepages(struct file *file)
Expand Down
1 change: 1 addition & 0 deletions mm/shmem.c
Expand Up @@ -3796,6 +3796,7 @@ static const struct file_operations shmem_file_operations = {
.splice_read = generic_file_splice_read,
.splice_write = iter_file_splice_write,
.fallocate = shmem_fallocate,
.fallocate_supported_flags = FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE,
#endif
};

Expand Down

0 comments on commit c381403

Please sign in to comment.