[PATCH 103/119] xfs: provide switch to force filesystem to copy-on-write all the time

Darrick J. Wong
2016-06-17T01:29:06Z

Make it possible to force XFS to use copy on write all the time, at
least if reflink is turned on.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
fs/xfs/libxfs/xfs_refcount.c | 6 ++++++
fs/xfs/xfs_globals.c | 1 +
fs/xfs/xfs_linux.h | 1 +
fs/xfs/xfs_sysctl.c | 11 +++++++++++
fs/xfs/xfs_sysctl.h | 1 +
5 files changed, 20 insertions(+)

diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c
index 88f91d5..fd4369f 100644
--- a/fs/xfs/libxfs/xfs_refcount.c
+++ b/fs/xfs/libxfs/xfs_refcount.c
@@ -1190,6 +1190,12 @@ xfs_refcount_find_shared(

trace_xfs_refcount_find_shared(mp, agno, agbno, aglen);

+ if (xfs_always_cow) {
+ *fbno = agbno;
+ *flen = aglen;
+ return 0;
+ }
+
error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp);
if (error)
goto out;
diff --git a/fs/xfs/xfs_globals.c b/fs/xfs/xfs_globals.c
index f3f6aa9..9a55966 100644
--- a/fs/xfs/xfs_globals.c
+++ b/fs/xfs/xfs_globals.c
@@ -43,6 +43,7 @@ xfs_param_t xfs_params = {
.fstrm_timer = { 1, 30*100, 3600*100},
.eofb_timer = { 1, 300, 3600*24},
.cowb_timer = { 1, 300, 3600*24},
+ .always_cow = { 0, 0, 1 },
};

struct xfs_globals xfs_globals = {
diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h
index f05e2cf5..b70abad 100644
--- a/fs/xfs/xfs_linux.h
+++ b/fs/xfs/xfs_linux.h
@@ -117,6 +117,7 @@ typedef __u32 xfs_nlink_t;
#define xfs_fstrm_centisecs xfs_params.fstrm_timer.val
#define xfs_eofb_secs xfs_params.eofb_timer.val
#define xfs_cowb_secs xfs_params.cowb_timer.val
+#define xfs_always_cow xfs_params.always_cow.val

#define current_cpu() (raw_smp_processor_id())
#define current_pid() (current->pid)
diff --git a/fs/xfs/xfs_sysctl.c b/fs/xfs/xfs_sysctl.c
index afe1f66..650b8d5 100644
--- a/fs/xfs/xfs_sysctl.c
+++ b/fs/xfs/xfs_sysctl.c
@@ -193,6 +193,17 @@ static struct ctl_table xfs_table[] = {
.extra1 = &xfs_params.cowb_timer.min,
.extra2 = &xfs_params.cowb_timer.max,
},
+#ifdef DEBUG
+ {
+ .procname = "always_cow",
+ .data = &xfs_params.always_cow.val,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &xfs_params.always_cow.min,
+ .extra2 = &xfs_params.always_cow.max,
+ },
+#endif
/* please keep this the last entry */
#ifdef CONFIG_PROC_FS
{
diff --git a/fs/xfs/xfs_sysctl.h b/fs/xfs/xfs_sysctl.h
index 984a349..16099dc 100644
--- a/fs/xfs/xfs_sysctl.h
+++ b/fs/xfs/xfs_sysctl.h
@@ -49,6 +49,7 @@ typedef struct xfs_param {
xfs_sysctl_val_t fstrm_timer; /* Filestream dir-AG assoc'n timeout. */
xfs_sysctl_val_t eofb_timer; /* Interval between eofb scan wakeups */
xfs_sysctl_val_t cowb_timer; /* Interval between cowb scan wakeups */
+ xfs_sysctl_val_t always_cow; /* Always copy on write? */
} xfs_param_t;

/*