[Gluster-devel] [RFC PATCH 1/1] bd: Add FOPS for overload operations
M. Mohan Kumar
mohan at in.ibm.com
Tue Dec 24 13:20:53 UTC 2013
From: "M. Mohan Kumar" <mohan at in.ibm.com>
Add FOPs for overload operations instead of relying on setxattr interfaces.
Signed-off-by: M. Mohan Kumar <mohan at in.ibm.com>
---
xlators/storage/bd/src/bd-helper.c | 14 +++-
xlators/storage/bd/src/bd.c | 144 ++++++++++++++++++++++++++++++++++++-
xlators/storage/bd/src/bd.h | 1 +
3 files changed, 153 insertions(+), 6 deletions(-)
diff --git a/xlators/storage/bd/src/bd-helper.c b/xlators/storage/bd/src/bd-helper.c
index 63e26d8..45af163 100644
--- a/xlators/storage/bd/src/bd-helper.c
+++ b/xlators/storage/bd/src/bd-helper.c
@@ -51,6 +51,9 @@ bd_local_free (xlator_t *this, bd_local_t *local)
fd_unref (local->fd);
else if (local->loc.path)
loc_wipe (&local->loc);
+ if (local->dfd)
+ fd_unref (local->dfd);
+
if (local->dict)
dict_unref (local->dict);
if (local->inode)
@@ -634,6 +637,7 @@ bd_clone (bd_local_t *local, bd_priv_t *priv)
bd_gfid_t source = {0, };
bd_gfid_t dest = {0, };
void *bufp[IOV_NR] = {0, };
+ uuid_t gfid = {0, };
vec = GF_CALLOC (IOV_NR, sizeof (struct iovec), gf_common_mt_iovec);
if (!vec)
@@ -648,15 +652,19 @@ bd_clone (bd_local_t *local, bd_priv_t *priv)
}
uuid_utoa_r (local->loc.gfid, source);
- uuid_utoa_r (local->dloc->gfid, dest);
+ if (local->dfd)
+ uuid_copy (gfid, local->dfd->inode->gfid);
+ else
+ uuid_copy (gfid, local->dloc->gfid);
+
+ uuid_utoa_r (gfid, dest);
gf_asprintf (&spath, "/dev/%s/%s", priv->vg, source);
gf_asprintf (&dpath, "/dev/%s/%s", priv->vg, dest);
if (!spath || !dpath)
goto out;
- ret = bd_create (local->dloc->gfid, local->size,
- local->bdatt->type, priv);
+ ret = bd_create (gfid, local->size, local->bdatt->type, priv);
if (ret)
goto out;
diff --git a/xlators/storage/bd/src/bd.c b/xlators/storage/bd/src/bd.c
index 17a9a5f..d2a3b00 100644
--- a/xlators/storage/bd/src/bd.c
+++ b/xlators/storage/bd/src/bd.c
@@ -1151,9 +1151,14 @@ bd_offload_getx_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- STACK_WIND (frame, bd_offload_setx_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr,
- local->dloc, local->dict, 0, NULL);
+ if (!local->dfd)
+ STACK_WIND (frame, bd_offload_setx_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->setxattr,
+ local->dloc, local->dict, 0, NULL);
+ else
+ STACK_WIND (frame, bd_offload_setx_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fsetxattr,
+ local->dfd, local->dict, 0, NULL);
return 0;
@@ -2225,6 +2230,139 @@ err:
return 0;
}
+/*
+ splice: Copies data between two file descriptors. It transfers up to len
+ bytes of data from the file descriptor fd_in to the file descriptor fd_out.
+ FIXME: Check if destination file is on the same brick by checking
+ LINKTO xattr
+ */
+static int
+bd_splice (call_frame_t *frame, xlator_t *this, fd_t *fd_in, off_t offset_in,
+ fd_t *fd_out, off_t offset_out, size_t len, unsigned int flags,
+ dict_t *xdata)
+{
+ bd_attr_t *bdatt_in = NULL;
+ bd_attr_t *bdatt_out = NULL;
+ bd_local_t *local = NULL;
+ int op_errno = 0;
+
+ bd_inode_ctx_get (fd_in->inode, this, &bdatt_in);
+ if (!bdatt_in) {
+ op_errno = EINVAL;
+ gf_log (this->name, GF_LOG_WARNING, "source fd is not a BD");
+ goto out;
+ }
+
+ if (offset_in + len > bdatt_in->iatt.ia_size) {
+ op_errno = EINVAL;
+ gf_log (this->name, GF_LOG_WARNING, "Attempt to copy beyond "
+ "source disk capacity");
+ goto out;
+ }
+
+ bd_inode_ctx_get (fd_out->inode, this, &bdatt_out);
+ if (bdatt_out) {
+ op_errno = EINVAL;
+ gf_log (this->name, GF_LOG_WARNING, "destination fd is already "
+ "mapped to BD");
+ goto out;
+ }
+
+ if (!IA_ISREG (fd_out->inode->ia_type)) {
+ op_errno = EINVAL;
+ gf_log (this->name, GF_LOG_WARNING, "destination fd is not a "
+ "regular file");
+ goto out;
+ }
+
+ /* set bd xattr */
+
+ local = bd_local_init (frame, this);
+ BD_VALIDATE_MEM_ALLOC (local, op_errno, out);
+
+ local->inode = inode_ref (fd_in->inode);
+ local->fd = fd_ref (fd_in);
+ local->dfd = fd_ref (fd_out);
+ local->offload = BD_OF_CLONE;
+
+ local->bdatt = CALLOC (1, sizeof (bd_attr_t));
+ BD_VALIDATE_MEM_ALLOC (local->bdatt, op_errno, out);
+
+ STACK_WIND (frame, bd_offload_getx_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->getxattr,
+ &local->loc, BD_XATTR, NULL);
+
+out:
+ BD_STACK_UNWIND (splice, frame, -1, op_errno, NULL);
+ return 0;
+}
+
+/*
+ reflink: Create a COW file(BD) 'dloc' for given 'loc'
+
+ FIXME: Check if destination file is on the same brick by checking
+ LINKTO xattr
+
+ http://lwn.net/Articles/331808/
+*/
+static int
+bd_reflink (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, loc_t *refloc, dict_t *xdata)
+{
+ bd_attr_t *bdatt_in = NULL;
+ bd_attr_t *bdatt_out = NULL;
+ bd_local_t *local = NULL;
+ int op_errno = 0;
+
+ bd_inode_ctx_get (loc->inode, this, &bdatt_in);
+ if (!bdatt_in) {
+ op_errno = EINVAL;
+ gf_log (this->name, GF_LOG_WARNING, "source file is not a BD");
+ goto out;
+ }
+
+ bd_inode_ctx_get (refloc->inode, this, &bdatt_out);
+ if (bdatt_out) {
+ op_errno = EINVAL;
+ gf_log (this->name, GF_LOG_WARNING, "destination file is "
+ "already mapped to BD");
+ goto out;
+ }
+
+ if (!IA_ISREG (refloc->inode->ia_type)) {
+ op_errno = EINVAL;
+ gf_log (this->name, GF_LOG_WARNING, "destination file is not a "
+ "regular file");
+ goto out;
+ }
+
+ local = bd_local_init (frame, this);
+ BD_VALIDATE_MEM_ALLOC (local, op_errno, out);
+
+ local->inode = inode_ref (loc->inode);
+ loc_copy (&local->loc, loc);
+ local->inode = inode_ref (loc->inode);
+
+ local->dloc = CALLOC (1, sizeof (loc_t));
+ BD_VALIDATE_MEM_ALLOC (local->dloc, op_errno, out);
+
+ loc_copy (local->dloc, refloc);
+ local->offload = BD_OF_SNAPSHOT;
+
+ local->size = bd_get_default_extent (this->private);
+
+ local->bdatt = CALLOC (1, sizeof (bd_attr_t));
+ BD_VALIDATE_MEM_ALLOC (local->bdatt, op_errno, out);
+
+ STACK_WIND (frame, bd_offload_getx_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->getxattr,
+ &local->loc, BD_XATTR, NULL);
+
+out:
+ BD_STACK_UNWIND (reflink, frame, -1, op_errno, NULL);
+ return 0;
+}
+
/**
* notify - when parent sends PARENT_UP, send CHILD_UP event from here
*/
diff --git a/xlators/storage/bd/src/bd.h b/xlators/storage/bd/src/bd.h
index f59bc6a..0fc08fc 100644
--- a/xlators/storage/bd/src/bd.h
+++ b/xlators/storage/bd/src/bd.h
@@ -150,6 +150,7 @@ typedef struct {
bd_offload_t offload;
uint64_t size;
loc_t *dloc;
+ fd_t *dfd;
} bd_local_t;
/* Prototypes */
--
1.7.11.7
More information about the Gluster-devel
mailing list