diff options
Diffstat (limited to 'xlators/features/trash/src/trash.c')
-rw-r--r-- | xlators/features/trash/src/trash.c | 425 |
1 files changed, 20 insertions, 405 deletions
diff --git a/xlators/features/trash/src/trash.c b/xlators/features/trash/src/trash.c index 932f4696b78..80be9b110cb 100644 --- a/xlators/features/trash/src/trash.c +++ b/xlators/features/trash/src/trash.c @@ -18,6 +18,26 @@ #define root_gfid (uuid_t){0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1} #define trash_gfid (uuid_t){0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5} #define internal_op_gfid (uuid_t){0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6} + +int32_t +trash_truncate_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, + struct iatt *prebuf, struct iatt *postbuf, + dict_t *xdata); + +int32_t +trash_truncate_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, inode_t *inode, + struct iatt *stbuf, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata); + +int32_t +trash_unlink_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *buf, + struct iatt *preoldparent, struct iatt *postoldparent, + struct iatt *prenewparent, struct iatt *postnewparent, + dict_t *xdata); + /* Common routines used in this translator */ /** @@ -248,38 +268,6 @@ wipe_eliminate_path (trash_elim_path *trav) } } -int32_t -trash_ftruncate_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct iovec *vector, int32_t count, - struct iatt *stbuf, struct iobref *iobuf, - dict_t *xdata); - -int32_t -trash_truncate_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct iatt *prebuf, struct iatt *postbuf, - dict_t *xdata); - -int32_t -trash_truncate_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, inode_t *inode, - struct iatt *stbuf, struct iatt *preparent, - struct iatt *postparent, dict_t *xdata); - -int32_t -trash_ftruncate_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, inode_t *inode, - struct iatt *stbuf, struct iatt *preparent, - struct iatt *postparent, dict_t *xdata); - -int32_t -trash_unlink_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *buf, - struct iatt *preoldparent, struct iatt *postoldparent, - struct iatt *prenewparent, struct iatt *postnewparent, - dict_t *xdata); - /** * This getxattr calls returns existing trash directory path in * the dictionary @@ -1647,379 +1635,6 @@ out: return ret; } -int32_t -trash_ftruncate_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct iatt *preparent, struct iatt *postparent, - dict_t *xdata) -{ - trash_local_t *local = NULL; - - local = frame->local; - GF_VALIDATE_OR_GOTO ("trash", local, out); - - if (op_ret == -1) { - gf_log (this->name, GF_LOG_DEBUG, - "%s: failed to unlink new file: %s", - local->newloc.path, strerror(op_errno)); - } - - STACK_WIND (frame, trash_common_unwind_buf_cbk, - FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, - local->fd, local->fop_offset, xdata); -out: - return 0; -} - -int32_t -trash_ftruncate_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct iatt *prebuf, struct iatt *postbuf, - dict_t *xdata) -{ - trash_local_t *local = NULL; - - local = frame->local; - GF_VALIDATE_OR_GOTO ("trash", local, out); - - if (op_ret == -1) { - STACK_WIND (frame, trash_ftruncate_unlink_cbk, - FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, - &local->newloc, 0, xdata); - return 0; - } - - if (local->cur_offset < local->fsize) { - local->cur_offset += GF_BLOCK_READV_SIZE; - STACK_WIND (frame, trash_ftruncate_readv_cbk, - FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, - local->fd, (size_t)GF_BLOCK_READV_SIZE, - local->cur_offset, 0, xdata); - return 0; - } - - STACK_WIND (frame, trash_common_unwind_buf_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->ftruncate, local->fd, - local->fop_offset, xdata); -out: - return 0; -} - - -int32_t -trash_ftruncate_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct iovec *vector, int32_t count, - struct iatt *stbuf, struct iobref *iobuf, - dict_t *xdata) -{ - trash_local_t *local = NULL; - - local = frame->local; - GF_VALIDATE_OR_GOTO ("trash", local, out); - - local->fsize = stbuf->ia_size; - - if (op_ret == -1) { - STACK_WIND (frame, trash_ftruncate_unlink_cbk, - FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, - &local->newloc, 0, xdata); - return 0; - } - - STACK_WIND (frame, trash_ftruncate_writev_cbk, - FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, - local->newfd, vector, count, local->cur_offset, 0, - NULL, xdata); -out: - return 0; -} - - -int32_t -trash_ftruncate_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, fd_t *fd, - inode_t *inode, struct iatt *buf, - struct iatt *preparent, struct iatt *postparent, - dict_t *xdata) -{ - trash_local_t *local = NULL; - char *tmp_str = NULL; - char *dir_name = NULL; - char *tmp_path = NULL; - loc_t tmp_loc = {0,}; - char *pathbuf = NULL; - char *tmp_stat = NULL; - char real_path[PATH_MAX] = {0,}; - trash_private_t *priv = NULL; - - priv = this->private; - GF_VALIDATE_OR_GOTO ("trash", priv, out); - - local = frame->local; - GF_VALIDATE_OR_GOTO ("trash", local, out); - - /* This will be more accurate */ - inode_path (fd->inode, NULL, &pathbuf); - - if ((op_ret == -1) && (op_errno == ENOENT)) { - tmp_str = gf_strdup (local->newpath); - if (!tmp_str) { - gf_log (this->name, GF_LOG_DEBUG, "out of memory"); - goto out; - } - dir_name = dirname (tmp_str); - - tmp_path = gf_strdup (dir_name); - if (!tmp_path) { - gf_log (this->name, GF_LOG_DEBUG, "out of memory"); - goto out; - } - loc_copy (&tmp_loc, &local->newloc); - tmp_loc.path = gf_strdup (tmp_path); - if (!tmp_loc.path) { - gf_log (this->name, GF_LOG_DEBUG, "out of memory"); - goto out; - } - strcpy (real_path, priv->brick_path); - remove_trash_path (tmp_path, (frame->root->pid < 0), tmp_stat); - if (tmp_stat) - strcat (real_path, tmp_stat); - /* create the directory with proper permissions */ - STACK_WIND_COOKIE (frame, trash_truncate_mkdir_cbk, - tmp_path, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->mkdir, - &tmp_loc, get_permission(real_path), - 0022, xdata); - loc_wipe (&tmp_loc); - goto out; - } - - if (op_ret == -1) { - STACK_WIND (frame, trash_common_unwind_buf_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->ftruncate, - local->fd, local->fop_offset, xdata); - goto out; - } - - STACK_WIND (frame, trash_ftruncate_readv_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->readv, local->fd, - (size_t)GF_BLOCK_READV_SIZE, local->cur_offset, 0, xdata); -out: - if (tmp_str) - GF_FREE (tmp_str); - if (tmp_path) - GF_FREE (tmp_path); - - return 0; -} - - -int32_t -trash_ftruncate_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, inode_t *inode, - struct iatt *stbuf, struct iatt *preparent, - struct iatt *postparent, dict_t *xdata) -{ - trash_local_t *local = NULL; - trash_private_t *priv = NULL; - char *tmp_str = NULL; - char *tmp_path = NULL; - char *tmp_dirname = NULL; - char *dir_name = NULL; - char *tmp_stat = NULL; - char real_path[PATH_MAX] = {0,}; - size_t count = 0; - int32_t flags = 0; - int32_t loop_count = 0; - int i = 0; - loc_t tmp_loc = {0,}; - int ret = 0; - - priv = this->private; - GF_VALIDATE_OR_GOTO ("trash", priv, out); - - local = frame->local; - GF_VALIDATE_OR_GOTO ("trash", priv, out); - - loop_count = local->loop_count; - - tmp_str = gf_strdup (local->newpath); - if (!tmp_str) { - gf_log (this->name, GF_LOG_DEBUG, "out of memory"); - ret = ENOMEM; - goto out; - } - - if ((op_ret == -1) && (op_errno == ENOENT)) { - tmp_dirname = strchr (tmp_str, '/'); - while (tmp_dirname) { - count = tmp_dirname - tmp_str; - if (count == 0) - count = 1; - i++; - if (i > loop_count) - break; - tmp_dirname = strchr (tmp_str + count + 1, '/'); - } - tmp_path = gf_memdup (local->newpath, count + 1); - if (!tmp_path) { - gf_log (this->name, GF_LOG_DEBUG, "out of memory"); - ret = ENOMEM; - goto out; - } - tmp_path[count] = '\0'; - - loc_copy (&tmp_loc, &local->newloc); - tmp_loc.path = gf_strdup (tmp_path); - if (!tmp_loc.path) { - gf_log (this->name, GF_LOG_DEBUG, "out of memory"); - ret = ENOMEM; - goto out; - } - strcpy (real_path, priv->brick_path); - remove_trash_path (tmp_path, (frame->root->pid < 0), tmp_stat); - if (tmp_stat) - strcat (real_path, tmp_stat); - STACK_WIND_COOKIE (frame, trash_ftruncate_mkdir_cbk, - tmp_path, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->mkdir, - &tmp_loc, get_permission(real_path), - 0022, xdata); - loc_wipe (&tmp_loc); - goto out; - } - - if (op_ret == 0) { - dir_name = dirname (tmp_str); - if (strcmp ((char *)cookie, dir_name) == 0) { - flags = O_CREAT|O_EXCL|O_WRONLY; - strcpy (real_path, priv->brick_path); - strcat (real_path, local->origpath); - /* Call create again once directory structure - is created. */ - STACK_WIND (frame, trash_ftruncate_create_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->create, - &local->newloc, flags, - get_permission (real_path), - 0022, local->newfd, xdata); - goto out; - } - } - - LOCK (&frame->lock); - { - loop_count = ++local->loop_count; - } - UNLOCK (&frame->lock); - - tmp_dirname = strchr (tmp_str, '/'); - while (tmp_dirname) { - count = tmp_dirname - tmp_str; - if (count == 0) - count = 1; - i++; - if ((i > loop_count) || (count > PATH_MAX)) - break; - tmp_dirname = strchr (tmp_str + count + 1, '/'); - } - tmp_path = gf_memdup (local->newpath, count + 1); - if (!tmp_path) { - gf_log (this->name, GF_LOG_DEBUG, "out of memory"); - ret = ENOMEM; - goto out; - } - tmp_path[count] = '\0'; - - loc_copy (&tmp_loc, &local->newloc); - tmp_loc.path = gf_strdup (tmp_path); - if (!tmp_loc.path) { - gf_log (this->name, GF_LOG_DEBUG, "out of memory"); - ret = ENOMEM; - goto out; - } - - /* Stores the the name of directory to be created */ - tmp_loc.name = gf_strdup (strrchr(tmp_path, '/') + 1); - if (!tmp_loc.name) { - gf_log (this->name, GF_LOG_DEBUG, "out of memory"); - ret = ENOMEM; - goto out; - } - - strcpy (real_path, priv->brick_path); - remove_trash_path (tmp_path, (frame->root->pid < 0), tmp_stat); - if (tmp_stat) - strcat (real_path, tmp_stat); - STACK_WIND_COOKIE (frame, trash_ftruncate_mkdir_cbk, tmp_path, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->mkdir, &tmp_loc, - get_permission(real_path), - 0022, xdata); -out: - if (tmp_str) - GF_FREE (tmp_str); - if (tmp_path) - GF_FREE (tmp_path); - - return ret; -} - - -int32_t -trash_ftruncate_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *buf, - dict_t *xdata) -{ - trash_private_t *priv = NULL; - trash_local_t *local = NULL; - - priv = this->private; - GF_VALIDATE_OR_GOTO ("trash", priv, out); - - local = frame->local; - GF_VALIDATE_OR_GOTO ("trash", local, out); - - if (op_ret == -1) { - gf_log (this->name, GF_LOG_DEBUG, - "%s: %s",local->newloc.path, strerror(op_errno)); - - TRASH_STACK_UNWIND (ftruncate, frame, -1, op_errno, buf, - NULL, xdata); - goto out; - } - - /* Only last hardlink will be moved to trash directory */ - if (buf->ia_nlink > 1) { - STACK_WIND (frame, trash_common_unwind_buf_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->ftruncate, - local->fd, local->fop_offset, xdata); - goto out; - } - - if ((buf->ia_size > (priv->max_trash_file_size))) - { - STACK_WIND (frame, trash_common_unwind_buf_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->ftruncate, - local->fd, local->fop_offset, xdata); - goto out; - } - - - STACK_WIND (frame, trash_truncate_create_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->create, &local->newloc, - ( O_CREAT | O_EXCL | O_WRONLY ), - st_mode_from_ia (buf->ia_prot, local->loc.inode->ia_type), - 0022, local->newfd, xdata); - -out: - return 0; -} - /** * When we call truncate from terminal it comes to ftruncate of trash-xlator. * Since truncate internally calls ftruncate and we receive fd of the file, |