From 9d008240e684ea13b35b107589f354a266aca850 Mon Sep 17 00:00:00 2001
From: Peter Georg <peter.georg@physik.uni-regensburg.de>
Date: Wed, 22 Sep 2021 22:32:42 +0200
Subject: [PATCH 9005/9005] Compat: Add fiemap_prep function
---
src/compat.h | 43 +++++++++++++++++++++++++++++++++++++++++++
src/file.c | 2 ++
2 files changed, 45 insertions(+)
create mode 100644 src/compat.h
diff --git a/src/compat.h b/src/compat.h
new file mode 100644
index 0000000..9862d76
--- /dev/null
+++ b/src/compat.h
@@ -0,0 +1,43 @@
+ /**
+ * fiemap_prep - check validity of requested flags for fiemap
+ * @inode: Inode to operate on
+ * @fieinfo: Fiemap context passed into ->fiemap
+ * @start: Start of the mapped range
+ * @len: Length of the mapped range, can be truncated by this function.
+ * @supported_flags: Set of fiemap flags that the file system understands
+ *
+ * This function must be called from each ->fiemap instance to validate the
+ * fiemap request against the file system parameters.
+ *
+ * Returns 0 on success, or a negative error on failure.
+ */
+static int fiemap_prep(struct inode *inode, struct fiemap_extent_info *fieinfo,
+ u64 start, u64 *len, u32 supported_flags)
+{
+ u64 maxbytes = inode->i_sb->s_maxbytes;
+ u32 incompat_flags;
+ int ret = 0;
+
+ if (*len == 0)
+ return -EINVAL;
+ if (start > maxbytes)
+ return -EFBIG;
+
+ /*
+ * Shrink request scope to what the fs can actually handle.
+ */
+ if (*len > maxbytes || (maxbytes - *len) < start)
+ *len = maxbytes - start;
+
+ supported_flags |= FIEMAP_FLAG_SYNC;
+ supported_flags &= FIEMAP_FLAGS_COMPAT;
+ incompat_flags = fieinfo->fi_flags & ~supported_flags;
+ if (incompat_flags) {
+ fieinfo->fi_flags = incompat_flags;
+ return -EBADR;
+ }
+
+ if (fieinfo->fi_flags & FIEMAP_FLAG_SYNC)
+ ret = filemap_write_and_wait(inode->i_mapping);
+ return ret;
+}
diff --git a/src/file.c b/src/file.c
index d89afcd..d72800c 100644
--- a/src/file.c
+++ b/src/file.c
@@ -17,6 +17,8 @@
#include "ntfs.h"
#include "ntfs_fs.h"
+#include "compat.h"
+
static int ntfs_ioctl_fitrim(struct ntfs_sb_info *sbi, unsigned long arg)
{
struct fstrim_range __user *user_range;
--
2.31.1