From: "M. Mohan Kumar" <mo...@in.ibm.com> Add FOPs for overload operations instead of relying on setxattr interfaces.
Signed-off-by: M. Mohan Kumar <mo...@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 _______________________________________________ Gluster-devel mailing list Gluster-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/gluster-devel