diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 259549698ba7e607b105360f36ececb7e92fff51..ba344f01478272bfb033e3ebd7e20c7ee3e5010b 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -33,6 +33,7 @@ #include #include #include +#include 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, @@ -1182,6 +1208,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, };