summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/dht/src/dht-helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/cluster/dht/src/dht-helper.c')
-rw-r--r--xlators/cluster/dht/src/dht-helper.c280
1 files changed, 280 insertions, 0 deletions
diff --git a/xlators/cluster/dht/src/dht-helper.c b/xlators/cluster/dht/src/dht-helper.c
index 08825cf0b93..ed84a3b79b6 100644
--- a/xlators/cluster/dht/src/dht-helper.c
+++ b/xlators/cluster/dht/src/dht-helper.c
@@ -266,6 +266,286 @@ dht_mig_info_is_invalid (xlator_t *current, xlator_t *src_subvol,
return _gf_false;
}
+
+
+/* Used to check if fd fops have the fd opened on the cached subvol
+ * This is required when:
+ * 1. an fd is opened on FILE1 on subvol1
+ * 2. the file is migrated to subvol2
+ * 3. a lookup updates the cached subvol in the inode_ctx to subvol2
+ * 4. a write comes on the fd
+ * The write is sent to subvol2 on an fd which has been opened only on fd1
+ * Since the migration phase checks don't kick in, the fop fails with EBADF
+ *
+ */
+
+
+int
+dht_check_and_open_fd_on_subvol_complete (int ret, call_frame_t *frame,
+ void *data)
+{
+ glusterfs_fop_t fop = 0;
+ dht_local_t *local = NULL;
+ xlator_t *subvol = NULL;
+ fd_t *fd = NULL;
+ int op_errno = -1;
+
+ local = frame->local;
+ fop = local->fop;
+ subvol = local->cached_subvol;
+ fd = local->fd;
+
+ if (ret) {
+ op_errno = local->op_errno;
+ goto handle_err;
+ }
+
+ switch (fop) {
+
+ case GF_FOP_WRITE:
+
+ STACK_WIND_COOKIE (frame, dht_writev_cbk, subvol, subvol,
+ subvol->fops->writev, fd,
+ local->rebalance.vector,
+ local->rebalance.count,
+ local->rebalance.offset,
+ local->rebalance.flags,
+ local->rebalance.iobref, local->xattr_req);
+ break;
+
+ case GF_FOP_FLUSH:
+
+ STACK_WIND (frame, dht_flush_cbk, subvol,
+ subvol->fops->flush, fd, local->xattr_req);
+ break;
+
+ case GF_FOP_FSETATTR:
+
+ STACK_WIND_COOKIE (frame, dht_file_setattr_cbk, subvol,
+ subvol, subvol->fops->fsetattr, fd,
+ &local->rebalance.stbuf,
+ local->rebalance.flags,
+ local->xattr_req);
+ break;
+
+ case GF_FOP_ZEROFILL:
+ STACK_WIND_COOKIE (frame, dht_zerofill_cbk, subvol, subvol,
+ subvol->fops->zerofill, fd,
+ local->rebalance.offset,
+ local->rebalance.size, local->xattr_req);
+
+ break;
+
+ case GF_FOP_DISCARD:
+ STACK_WIND_COOKIE (frame, dht_discard_cbk, subvol, subvol,
+ subvol->fops->discard, local->fd,
+ local->rebalance.offset,
+ local->rebalance.size,
+ local->xattr_req);
+ break;
+
+ case GF_FOP_FALLOCATE:
+ STACK_WIND_COOKIE (frame, dht_fallocate_cbk, subvol, subvol,
+ subvol->fops->fallocate, fd,
+ local->rebalance.flags,
+ local->rebalance.offset,
+ local->rebalance.size,
+ local->xattr_req);
+ break;
+
+ case GF_FOP_FTRUNCATE:
+ STACK_WIND_COOKIE (frame, dht_truncate_cbk, subvol, subvol,
+ subvol->fops->ftruncate, fd,
+ local->rebalance.offset, local->xattr_req);
+ break;
+
+ case GF_FOP_FSYNC:
+ STACK_WIND_COOKIE (frame, dht_fsync_cbk, subvol, subvol,
+ subvol->fops->fsync, local->fd,
+ local->rebalance.flags, local->xattr_req);
+ break;
+
+ case GF_FOP_READ:
+ STACK_WIND (frame, dht_readv_cbk, subvol, subvol->fops->readv,
+ local->fd, local->rebalance.size,
+ local->rebalance.offset,
+ local->rebalance.flags, local->xattr_req);
+ break;
+
+ case GF_FOP_FSTAT:
+ STACK_WIND_COOKIE (frame, dht_file_attr_cbk, subvol,
+ subvol, subvol->fops->fstat, fd,
+ local->xattr_req);
+ break;
+
+ default:
+ break;
+
+ }
+
+ goto out;
+
+ /* Could not open the fd on the dst. Unwind */
+
+handle_err:
+
+ switch (fop) {
+
+ case GF_FOP_WRITE:
+ DHT_STACK_UNWIND (writev, frame, -1,
+ op_errno, NULL, NULL, NULL);
+ break;
+
+ case GF_FOP_FLUSH:
+ DHT_STACK_UNWIND (flush, frame, -1, op_errno, NULL);
+ break;
+
+ case GF_FOP_FSETATTR:
+ DHT_STACK_UNWIND (fsetattr, frame, -1, op_errno,
+ NULL, NULL, NULL);
+ break;
+
+ case GF_FOP_ZEROFILL:
+ DHT_STACK_UNWIND (zerofill, frame, -1, op_errno,
+ NULL, NULL, NULL);
+ break;
+
+ case GF_FOP_DISCARD:
+ DHT_STACK_UNWIND (discard, frame, -1, op_errno,
+ NULL, NULL, NULL);
+ break;
+
+ case GF_FOP_FALLOCATE:
+ DHT_STACK_UNWIND (fallocate, frame, -1, op_errno,
+ NULL, NULL, NULL);
+ break;
+
+ case GF_FOP_FTRUNCATE:
+ DHT_STACK_UNWIND (ftruncate, frame, -1, op_errno,
+ NULL, NULL, NULL);
+ break;
+
+ case GF_FOP_FSYNC:
+ DHT_STACK_UNWIND (fsync, frame, -1, op_errno, NULL, NULL, NULL);
+ break;
+
+ case GF_FOP_READ:
+ DHT_STACK_UNWIND (readv, frame, -1, op_errno, NULL,
+ 0, NULL, NULL, NULL);
+ break;
+
+ case GF_FOP_FSTAT:
+ DHT_STACK_UNWIND (fstat, frame, -1, op_errno, NULL, NULL);
+ break;
+
+ default:
+ break;
+ }
+
+out:
+
+ return 0;
+
+}
+
+
+/* Check once again if the fd has been opened on the cached subvol.
+ * If not, open and update the fd_ctx.
+ */
+
+int
+dht_check_and_open_fd_on_subvol_task (void *data)
+{
+ loc_t loc = {0,};
+ int ret = -1;
+ call_frame_t *frame = NULL;
+ dht_local_t *local = NULL;
+ fd_t *fd = NULL;
+ xlator_t *this = NULL;
+ xlator_t *subvol = NULL;
+
+
+ frame = data;
+ local = frame->local;
+ this = THIS;
+ fd = local->fd;
+ subvol = local->cached_subvol;
+
+
+ if (fd_is_anonymous (fd) || dht_fd_open_on_dst (this, fd, subvol)) {
+ ret = 0;
+ goto out;
+ }
+
+ gf_msg_debug (this->name, 0,
+ "Opening fd (%p, flags=0%o) on file %s @ %s",
+ fd, fd->flags, uuid_utoa (fd->inode->gfid),
+ subvol->name);
+
+
+ loc.inode = inode_ref (fd->inode);
+ gf_uuid_copy (loc.gfid, fd->inode->gfid);
+
+ /* Open this on the dst subvol */
+
+ SYNCTASK_SETID(0, 0);
+
+ ret = syncop_open (subvol, &loc,
+ (fd->flags & ~(O_CREAT | O_EXCL | O_TRUNC)),
+ fd, NULL, NULL);
+
+ if (ret < 0) {
+
+ gf_msg (this->name, GF_LOG_ERROR, -ret,
+ DHT_MSG_OPEN_FD_ON_DST_FAILED,
+ "Failed to open the fd"
+ " (%p, flags=0%o) on file %s @ %s",
+ fd, fd->flags, uuid_utoa (fd->inode->gfid),
+ subvol->name);
+
+ local->op_errno = -ret;
+ ret = -1;
+
+ } else {
+ dht_fd_ctx_set (this, fd, subvol);
+ }
+
+ SYNCTASK_SETID (frame->root->uid, frame->root->gid);
+out:
+ loc_wipe (&loc);
+
+ return ret;
+}
+
+
+int
+dht_check_and_open_fd_on_subvol (xlator_t *this, call_frame_t *frame)
+{
+ int ret = -1;
+ dht_local_t *local = NULL;
+
+/*
+ if (dht_fd_open_on_dst (this, fd, subvol))
+ goto out;
+*/
+ local = frame->local;
+
+ ret = synctask_new (this->ctx->env,
+ dht_check_and_open_fd_on_subvol_task,
+ dht_check_and_open_fd_on_subvol_complete,
+ frame, frame);
+
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR, 0, 0,
+ "Failed to create synctask"
+ " to check and open fd=%p", local->fd);
+ }
+
+ return ret;
+}
+
+
+
int
dht_frame_return (call_frame_t *frame)
{