linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Qu Wenruo <quwenruo@cn.fujitsu.com>
To: linux-btrfs@vger.kernel.org
Cc: Wang Xiaoguang <wangxg.fnst@cn.fujitsu.com>
Subject: [PATCH v6 15/19] btrfs: dedup: Add ioctl for inband deduplication
Date: Fri,  5 Feb 2016 09:22:35 +0800	[thread overview]
Message-ID: <1454635359-10013-16-git-send-email-quwenruo@cn.fujitsu.com> (raw)
In-Reply-To: <1454635359-10013-1-git-send-email-quwenruo@cn.fujitsu.com>

From: Wang Xiaoguang <wangxg.fnst@cn.fujitsu.com>

Add ioctl interface for inband deduplication, which includes:
1) enable
2) disable
3) status

We will later add ioctl to disable inband dedup for given file/dir.

Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: Wang Xiaoguang <wangxg.fnst@cn.fujitsu.com>
---
 fs/btrfs/dedup.c           | 48 ++++++++++++++++++++++++++++++++++++++-----
 fs/btrfs/dedup.h           | 10 ++++++++-
 fs/btrfs/ioctl.c           | 51 ++++++++++++++++++++++++++++++++++++++++++++++
 fs/btrfs/sysfs.c           |  2 ++
 include/uapi/linux/btrfs.h | 24 ++++++++++++++++++++++
 5 files changed, 129 insertions(+), 6 deletions(-)

diff --git a/fs/btrfs/dedup.c b/fs/btrfs/dedup.c
index 8972cff..b7ecb8f 100644
--- a/fs/btrfs/dedup.c
+++ b/fs/btrfs/dedup.c
@@ -135,12 +135,12 @@ out:
 }
 
 int btrfs_dedup_enable(struct btrfs_fs_info *fs_info, u16 type, u16 backend,
-		       u64 blocksize, u64 limit_nr)
+		       u64 blocksize, u64 limit_nr, u64 limit_mem)
 {
 	struct btrfs_dedup_info *dedup_info;
 	int create_tree;
 	u64 compat_ro_flag = btrfs_super_compat_ro_flags(fs_info->super_copy);
-	u64 limit = limit_nr;
+	u64 limit;
 	int ret = 0;
 
 	/* Sanity check */
@@ -153,11 +153,22 @@ int btrfs_dedup_enable(struct btrfs_fs_info *fs_info, u16 type, u16 backend,
 		return -EINVAL;
 	if (backend >= BTRFS_DEDUP_BACKEND_LAST)
 		return -EINVAL;
+	/* Only one limit is accept */
+	if (limit_nr && limit_mem)
+		return -EINVAL;
 
-	if (backend == BTRFS_DEDUP_BACKEND_INMEMORY && limit_nr == 0)
-		limit = 4096; /* default value */
-	if (backend == BTRFS_DEDUP_BACKEND_ONDISK && limit_nr != 0)
+	if (backend == BTRFS_DEDUP_BACKEND_INMEMORY) {
+		if (!limit_nr && !limit_mem)
+			limit = BTRFS_DEDUP_LIMIT_NR_DEFAULT;
+		else if (limit_nr)
+			limit = limit_nr;
+		else
+			limit = limit_mem / (sizeof(struct inmem_hash) +
+					btrfs_dedup_sizes[type]);
+	}
+	if (backend == BTRFS_DEDUP_BACKEND_ONDISK)
 		limit = 0;
+
 	/* Ondisk backend needs DEDUP RO compat feature */
 	if (!(compat_ro_flag & BTRFS_FEATURE_COMPAT_RO_DEDUP) &&
 	    backend == BTRFS_DEDUP_BACKEND_ONDISK)
@@ -208,6 +219,33 @@ out:
 	return ret;
 }
 
+void btrfs_dedup_status(struct btrfs_fs_info *fs_info,
+			struct btrfs_ioctl_dedup_args *dargs)
+{
+	struct btrfs_dedup_info *dedup_info = fs_info->dedup_info;
+
+	if (!fs_info->dedup_enabled || !dedup_info) {
+		dargs->status = 0;
+		dargs->blocksize = 0;
+		dargs->backend = 0;
+		dargs->hash_type = 0;
+		dargs->limit_nr = 0;
+		dargs->current_nr = 0;
+		return;
+	}
+	mutex_lock(&dedup_info->lock);
+	dargs->status = 1;
+	dargs->blocksize = dedup_info->blocksize;
+	dargs->backend = dedup_info->backend;
+	dargs->hash_type = dedup_info->hash_type;
+	dargs->limit_nr = dedup_info->limit_nr;
+	dargs->limit_mem = dedup_info->limit_nr *
+		(sizeof(struct inmem_hash) +
+		 btrfs_dedup_sizes[dedup_info->hash_type]);
+	dargs->current_nr = dedup_info->current_nr;
+	mutex_unlock(&dedup_info->lock);
+}
+
 int btrfs_dedup_resume(struct btrfs_fs_info *fs_info,
 		       struct btrfs_root *dedup_root)
 {
diff --git a/fs/btrfs/dedup.h b/fs/btrfs/dedup.h
index a580072..8a99a7f 100644
--- a/fs/btrfs/dedup.h
+++ b/fs/btrfs/dedup.h
@@ -100,7 +100,15 @@ static inline struct btrfs_dedup_hash *btrfs_dedup_alloc_hash(u16 type)
  * Called at dedup enable time.
  */
 int btrfs_dedup_enable(struct btrfs_fs_info *fs_info, u16 type, u16 backend,
-		       u64 blocksize, u64 limit_nr);
+		       u64 blocksize, u64 limit_nr, u64 limit_mem);
+
+/*
+ * Get inband dedup info
+ * Since it needs to access different backends' hash size, which
+ * is not exported, we need such simple function.
+ */
+void btrfs_dedup_status(struct btrfs_fs_info *fs_info,
+			struct btrfs_ioctl_dedup_args *dargs);
 
 /*
  * Disable dedup and invalidate all its dedup data.
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 1568f57..2bd1a97 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -59,6 +59,7 @@
 #include "props.h"
 #include "sysfs.h"
 #include "qgroup.h"
+#include "dedup.h"
 
 #ifdef CONFIG_64BIT
 /* If we have a 32-bit userspace and 64-bit kernel, then the UAPI
@@ -3220,6 +3221,54 @@ out:
 	return ret;
 }
 
+static long btrfs_ioctl_dedup_ctl(struct btrfs_root *root, void __user *args)
+{
+	struct btrfs_ioctl_dedup_args *dargs;
+	struct btrfs_fs_info *fs_info = root->fs_info;
+	int ret;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	dargs = memdup_user(args, sizeof(*dargs));
+	if (IS_ERR(dargs)) {
+		ret = PTR_ERR(dargs);
+		return ret;
+	}
+
+	if (dargs->cmd >= BTRFS_DEDUP_CTL_LAST) {
+		ret = -EINVAL;
+		goto out;
+	}
+	switch (dargs->cmd) {
+	case BTRFS_DEDUP_CTL_ENABLE:
+		mutex_lock(&fs_info->dedup_ioctl_lock);
+		ret = btrfs_dedup_enable(fs_info, dargs->hash_type,
+					 dargs->backend, dargs->blocksize,
+					 dargs->limit_nr, dargs->limit_mem);
+		mutex_unlock(&fs_info->dedup_ioctl_lock);
+		break;
+	case BTRFS_DEDUP_CTL_DISABLE:
+		mutex_lock(&fs_info->dedup_ioctl_lock);
+		ret = btrfs_dedup_disable(fs_info);
+		mutex_unlock(&fs_info->dedup_ioctl_lock);
+		break;
+	case BTRFS_DEDUP_CTL_STATUS:
+		btrfs_dedup_status(fs_info, dargs);
+		if (copy_to_user(args, dargs, sizeof(*dargs)))
+			ret = -EFAULT;
+		else
+			ret = 0;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+out:
+	kfree(dargs);
+	return ret;
+}
+
 static int clone_finish_inode_update(struct btrfs_trans_handle *trans,
 				     struct inode *inode,
 				     u64 endoff,
@@ -5584,6 +5633,8 @@ long btrfs_ioctl(struct file *file, unsigned int
 		return btrfs_ioctl_set_fslabel(file, argp);
 	case BTRFS_IOC_FILE_EXTENT_SAME:
 		return btrfs_ioctl_file_extent_same(file, argp);
+	case BTRFS_IOC_DEDUP_CTL:
+		return btrfs_ioctl_dedup_ctl(root, argp);
 	case BTRFS_IOC_GET_SUPPORTED_FEATURES:
 		return btrfs_ioctl_get_supported_features(file, argp);
 	case BTRFS_IOC_GET_FEATURES:
diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c
index 539e7b5..75e5ca85 100644
--- a/fs/btrfs/sysfs.c
+++ b/fs/btrfs/sysfs.c
@@ -203,6 +203,7 @@ BTRFS_FEAT_ATTR_INCOMPAT(raid56, RAID56);
 BTRFS_FEAT_ATTR_INCOMPAT(skinny_metadata, SKINNY_METADATA);
 BTRFS_FEAT_ATTR_INCOMPAT(no_holes, NO_HOLES);
 BTRFS_FEAT_ATTR_COMPAT_RO(free_space_tree, FREE_SPACE_TREE);
+BTRFS_FEAT_ATTR_COMPAT_RO(dedup, DEDUP);
 
 static struct attribute *btrfs_supported_feature_attrs[] = {
 	BTRFS_FEAT_ATTR_PTR(mixed_backref),
@@ -215,6 +216,7 @@ static struct attribute *btrfs_supported_feature_attrs[] = {
 	BTRFS_FEAT_ATTR_PTR(skinny_metadata),
 	BTRFS_FEAT_ATTR_PTR(no_holes),
 	BTRFS_FEAT_ATTR_PTR(free_space_tree),
+	BTRFS_FEAT_ATTR_PTR(dedup),
 	NULL
 };
 
diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h
index dea8931..666f940 100644
--- a/include/uapi/linux/btrfs.h
+++ b/include/uapi/linux/btrfs.h
@@ -445,6 +445,28 @@ struct btrfs_ioctl_get_dev_stats {
 	__u64 unused[128 - 2 - BTRFS_DEV_STAT_VALUES_MAX]; /* pad to 1k */
 };
 
+/*
+ * de-duplication control modes
+ * For re-config, re-enable will handle it
+ * TODO: Add support to disable per-file/dir dedup operation
+ */
+#define BTRFS_DEDUP_CTL_ENABLE	1
+#define BTRFS_DEDUP_CTL_DISABLE 2
+#define BTRFS_DEDUP_CTL_STATUS	3
+#define BTRFS_DEDUP_CTL_LAST	4
+struct btrfs_ioctl_dedup_args {
+	__u16 cmd;		/* In: command(see above macro) */
+	__u64 blocksize;	/* In/Out: For enable/status */
+	__u64 limit_nr;		/* In/Out: For enable/status */
+	__u64 limit_mem;	/* In/Out: For enable/status */
+	__u64 current_nr;	/* Out: For status output */
+	__u16 backend;		/* In/Out: For enable/status */
+	__u16 hash_type;	/* In/Out: For enable/status */
+	u8 status;		/* Out: For status output */
+	/* pad to 512 bytes */
+	u8 __unused[473];
+};
+
 #define BTRFS_QUOTA_CTL_ENABLE	1
 #define BTRFS_QUOTA_CTL_DISABLE	2
 #define BTRFS_QUOTA_CTL_RESCAN__NOTUSED	3
@@ -653,6 +675,8 @@ static inline char *btrfs_err_str(enum btrfs_err_code err_code)
 				    struct btrfs_ioctl_dev_replace_args)
 #define BTRFS_IOC_FILE_EXTENT_SAME _IOWR(BTRFS_IOCTL_MAGIC, 54, \
 					 struct btrfs_ioctl_same_args)
+#define BTRFS_IOC_DEDUP_CTL	_IOWR(BTRFS_IOCTL_MAGIC, 55, \
+				      struct btrfs_ioctl_dedup_args)
 #define BTRFS_IOC_GET_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, \
 				   struct btrfs_ioctl_feature_flags)
 #define BTRFS_IOC_SET_FEATURES _IOW(BTRFS_IOCTL_MAGIC, 57, \
-- 
2.7.0




  parent reply	other threads:[~2016-02-05  1:24 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-05  1:22 [PATCH v6 00/19][For 4.6] Btrfs: Add inband (write time) de-duplication framework Qu Wenruo
2016-02-05  1:22 ` [PATCH v6 01/19] btrfs: dedup: Introduce dedup framework and its header Qu Wenruo
2016-02-05  1:22 ` [PATCH v6 02/19] btrfs: dedup: Introduce function to initialize dedup info Qu Wenruo
2016-02-05  1:22 ` [PATCH v6 03/19] btrfs: dedup: Introduce function to add hash into in-memory tree Qu Wenruo
2016-02-05  1:22 ` [PATCH v6 04/19] btrfs: dedup: Introduce function to remove hash from " Qu Wenruo
2016-02-05  1:22 ` [PATCH v6 05/19] btrfs: delayed-ref: Add support for increasing data ref under spinlock Qu Wenruo
2016-02-05  1:22 ` [PATCH v6 06/19] btrfs: dedup: Introduce function to search for an existing hash Qu Wenruo
2016-02-05  1:22 ` [PATCH v6 07/19] btrfs: dedup: Implement btrfs_dedup_calc_hash interface Qu Wenruo
2016-02-05  1:22 ` [PATCH v6 08/19] btrfs: ordered-extent: Add support for dedup Qu Wenruo
2016-02-05  1:22 ` [PATCH v6 09/19] btrfs: dedup: Inband in-memory only de-duplication implement Qu Wenruo
2016-02-05  1:22 ` [PATCH v6 10/19] btrfs: dedup: Add basic tree structure for on-disk dedup method Qu Wenruo
2016-02-05  1:22 ` [PATCH v6 11/19] btrfs: dedup: Introduce interfaces to resume and cleanup dedup info Qu Wenruo
2016-02-05  1:22 ` [PATCH v6 12/19] btrfs: dedup: Add support for on-disk hash search Qu Wenruo
2016-02-05  1:22 ` [PATCH v6 13/19] btrfs: dedup: Add support to delete hash for on-disk backend Qu Wenruo
2016-02-05  1:22 ` [PATCH v6 14/19] btrfs: dedup: Add support for adding " Qu Wenruo
2016-02-05  1:22 ` Qu Wenruo [this message]
2016-02-05  1:22 ` [PATCH v6 16/19] btrfs: dedup: add an inode nodedup flag Qu Wenruo
2016-02-05  1:22 ` [PATCH v6 17/19] btrfs: dedup: add a property handler for online dedup Qu Wenruo
2016-02-05  1:22 ` [PATCH v6 18/19] btrfs: dedup: add per-file online dedup control Qu Wenruo
2016-02-05  1:22 ` [PATCH v6 19/19] btrfs: try more times to alloc metadata reserve space Qu Wenruo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1454635359-10013-16-git-send-email-quwenruo@cn.fujitsu.com \
    --to=quwenruo@cn.fujitsu.com \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=wangxg.fnst@cn.fujitsu.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).