diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 2924edf1b4084e01033af69f98e76f6ba5015127..2da2e3ac412142cc03c81973567ac83616888a03 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -33,6 +33,7 @@ #include <linux/pagevec.h> #include <linux/backing-dev.h> #include <linux/mman.h> +#include <linux/fadvise.h> static const struct vm_operations_struct xfs_file_vm_ops; @@ -926,6 +927,31 @@ xfs_file_fallocate( return error; } +STATIC int +xfs_file_fadvise( + struct file *file, + loff_t start, + loff_t end, + int advice) +{ + struct xfs_inode *ip = XFS_I(file_inode(file)); + int ret; + int lockflags = 0; + + /* + * Operations creating pages in page cache need protection from hole + * punching and similar ops + */ + if (advice == POSIX_FADV_WILLNEED) { + lockflags = XFS_IOLOCK_SHARED; + xfs_ilock(ip, lockflags); + } + ret = generic_fadvise(file, start, end, advice); + if (lockflags) + xfs_iunlock(ip, lockflags); + return ret; +} + STATIC int xfs_file_clone_range( struct file *file_in, @@ -1183,6 +1209,7 @@ const struct file_operations xfs_file_operations = { .fsync = xfs_file_fsync, .get_unmapped_area = thp_get_unmapped_area, .fallocate = xfs_file_fallocate, + .fadvise = xfs_file_fadvise, .clone_file_range = xfs_file_clone_range, .dedupe_file_range = xfs_file_dedupe_range, };