From 186a86f342625a9dce53fe537f8237c6099d5c54 Mon Sep 17 00:00:00 2001 From: Shehjar Tikoo Date: Thu, 1 Oct 2009 06:58:46 +0000 Subject: Global: Introduce setattr and fsetattr fops Signed-off-by: Anand V. Avati BUG: 146 (Add setattr FOP) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=146 --- xlators/cluster/unify/src/unify.c | 325 +++++++++++++------------------------- xlators/cluster/unify/src/unify.h | 2 + 2 files changed, 115 insertions(+), 212 deletions(-) (limited to 'xlators/cluster/unify') diff --git a/xlators/cluster/unify/src/unify.c b/xlators/cluster/unify/src/unify.c index 35c108963e3..b641fb3307e 100644 --- a/xlators/cluster/unify/src/unify.c +++ b/xlators/cluster/unify/src/unify.c @@ -1763,72 +1763,78 @@ unify_opendir (call_frame_t *frame, } -/** - * unify_chmod - - */ int32_t -unify_chmod (call_frame_t *frame, - xlator_t *this, - loc_t *loc, - mode_t mode) +unify_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct stat *statpre, + struct stat *statpost) { - unify_local_t *local = NULL; - unify_private_t *priv = this->private; - int32_t index = 0; int32_t callcnt = 0; - uint64_t tmp_list = 0; - - UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc); + unify_private_t *priv = this->private; + unify_local_t *local = frame->local; + call_frame_t *prev_frame = cookie; - /* Initialization */ - INIT_LOCAL (frame, local); + LOCK (&frame->lock); + { + callcnt = --local->call_count; + + if (op_ret == -1) { + gf_log (this->name, GF_LOG_ERROR, + "%s(): child(%s): path(%s): %s", + gf_fop_list[frame->root->op], + prev_frame->this->name, + (local->loc1.path)?local->loc1.path:"", + strerror (op_errno)); - loc_copy (&local->loc1, loc); - local->st_ino = loc->inode->ino; + local->op_errno = op_errno; + if ((op_errno == ENOENT) && priv->optimist) + local->op_ret = 0; + } - if (S_ISDIR (loc->inode->st_mode)) { - local->call_count = priv->child_count + 1; - - for (index = 0; index < (priv->child_count + 1); index++) { - STACK_WIND (frame, - unify_buf_cbk, - priv->xl_array[index], - priv->xl_array[index]->fops->chmod, - loc, mode); - } - } else { - inode_ctx_get (loc->inode, this, &tmp_list); - local->list = (int16_t *)(long)tmp_list; + if (op_ret >= 0) { + local->op_ret = 0; - for (index = 0; local->list[index] != -1; index++) { - local->call_count++; - callcnt++; - } - - for (index = 0; local->list[index] != -1; index++) { - STACK_WIND (frame, - unify_buf_cbk, - priv->xl_array[local->list[index]], - priv->xl_array[local->list[index]]->fops->chmod, - loc, - mode); - if (!--callcnt) - break; + if (NS (this) == prev_frame->this) { + local->st_ino = statpost->st_ino; + /* If the entry is directory, get the stat + from NS node */ + if (S_ISDIR (statpost->st_mode) || + !local->stpost.st_blksize) { + local->stpre = *statpre; + local->stpost = *statpost; + } + } + + if ((!S_ISDIR (statpost->st_mode)) && + (NS (this) != prev_frame->this)) { + /* If file, take the stat info from Storage + node. */ + local->stpre = *statpre; + local->stpost = *statpost; + } } } + UNLOCK (&frame->lock); + + if (!callcnt) { + /* If the inode number is not filled, operation should + fail */ + if (!local->st_ino) + local->op_ret = -1; + + local->stpre.st_ino = local->st_ino; + local->stpost.st_ino = local->st_ino; + unify_local_wipe (local); + STACK_UNWIND (frame, local->op_ret, local->op_errno, + &local->stpre, &local->stpost); + } return 0; } -/** - * unify_chown - - */ + int32_t -unify_chown (call_frame_t *frame, - xlator_t *this, - loc_t *loc, - uid_t uid, - gid_t gid) +unify_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, + struct stat *stbuf, int32_t valid) { unify_local_t *local = NULL; unify_private_t *priv = this->private; @@ -1836,24 +1842,24 @@ unify_chown (call_frame_t *frame, int32_t callcnt = 0; uint64_t tmp_list = 0; - UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc); + if (!(loc && loc->inode)) { + STACK_UNWIND (frame, -1, EINVAL, NULL, NULL); + return 0; + } /* Initialization */ INIT_LOCAL (frame, local); loc_copy (&local->loc1, loc); - local->st_ino = loc->inode->ino; if (S_ISDIR (loc->inode->st_mode)) { - local->call_count = priv->child_count + 1; + local->call_count = 1; - for (index = 0; index < (priv->child_count + 1); index++) { - STACK_WIND (frame, - unify_buf_cbk, - priv->xl_array[index], - priv->xl_array[index]->fops->chown, - loc, uid, gid); - } - } else { + STACK_WIND (frame, + unify_setattr_cbk, + NS (this), + NS (this)->fops->setattr, + loc, stbuf, valid); + } else { inode_ctx_get (loc->inode, this, &tmp_list); local->list = (int16_t *)(long)tmp_list; @@ -1864,10 +1870,11 @@ unify_chown (call_frame_t *frame, for (index = 0; local->list[index] != -1; index++) { STACK_WIND (frame, - unify_buf_cbk, + unify_setattr_cbk, priv->xl_array[local->list[index]], - priv->xl_array[local->list[index]]->fops->chown, - loc, uid, gid); + priv->xl_array[local->list[index]]->fops->setattr, + loc, stbuf, valid); + if (!--callcnt) break; } @@ -1877,6 +1884,42 @@ unify_chown (call_frame_t *frame, } +int32_t +unify_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, + struct stat *stbuf, int32_t valid) +{ + unify_local_t *local = NULL; + xlator_t *child = NULL; + uint64_t tmp_child = 0; + + UNIFY_CHECK_FD_AND_UNWIND_ON_ERR(fd); + + /* Initialization */ + INIT_LOCAL (frame, local); + + if (!fd_ctx_get (fd, this, &tmp_child)) { + /* If its set, then its file */ + child = (xlator_t *)(long)tmp_child; + + local->call_count = 2; + + STACK_WIND (frame, unify_setattr_cbk, child, + child->fops->fsetattr, fd, stbuf, valid); + + STACK_WIND (frame, unify_setattr_cbk, NS(this), + NS(this)->fops->fsetattr, fd, stbuf, valid); + } else { + local->call_count = 1; + + STACK_WIND (frame, unify_setattr_cbk, + NS(this), NS(this)->fops->fsetattr, + fd, stbuf, valid); + } + + return 0; +} + + /** * unify_truncate_cbk - */ @@ -1942,6 +1985,7 @@ unify_truncate_cbk (call_frame_t *frame, return 0; } + /** * unify_truncate - */ @@ -2004,62 +2048,6 @@ unify_truncate (call_frame_t *frame, return 0; } -/** - * unify_utimens - - */ -int32_t -unify_utimens (call_frame_t *frame, - xlator_t *this, - loc_t *loc, - struct timespec tv[2]) -{ - unify_local_t *local = NULL; - unify_private_t *priv = this->private; - int32_t index = 0; - int32_t callcnt = 0; - uint64_t tmp_list = 0; - - UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc); - - /* Initialization */ - INIT_LOCAL (frame, local); - loc_copy (&local->loc1, loc); - local->st_ino = loc->inode->ino; - - if (S_ISDIR (loc->inode->st_mode)) { - local->call_count = priv->child_count + 1; - - for (index = 0; index < (priv->child_count + 1); index++) { - STACK_WIND (frame, - unify_buf_cbk, - priv->xl_array[index], - priv->xl_array[index]->fops->utimens, - loc, tv); - } - } else { - inode_ctx_get (loc->inode, this, &tmp_list); - local->list = (int16_t *)(long)tmp_list; - - for (index = 0; local->list[index] != -1; index++) { - local->call_count++; - callcnt++; - } - - for (index = 0; local->list[index] != -1; index++) { - STACK_WIND (frame, - unify_buf_cbk, - priv->xl_array[local->list[index]], - priv->xl_array[local->list[index]]->fops->utimens, - loc, - tv); - if (!--callcnt) - break; - } - } - - return 0; -} - /** * unify_readlink_cbk - */ @@ -2331,90 +2319,6 @@ unify_ftruncate (call_frame_t *frame, } -/** - * unify_fchmod - - */ -int32_t -unify_fchmod (call_frame_t *frame, - xlator_t *this, - fd_t *fd, - mode_t mode) -{ - unify_local_t *local = NULL; - xlator_t *child = NULL; - uint64_t tmp_child = 0; - - UNIFY_CHECK_FD_AND_UNWIND_ON_ERR(fd); - - /* Initialization */ - INIT_LOCAL (frame, local); - local->st_ino = fd->inode->ino; - - if (!fd_ctx_get (fd, this, &tmp_child)) { - /* If its set, then its file */ - child = (xlator_t *)(long)tmp_child; - - local->call_count = 2; - - STACK_WIND (frame, unify_buf_cbk, child, - child->fops->fchmod, fd, mode); - - STACK_WIND (frame, unify_buf_cbk, NS(this), - NS(this)->fops->fchmod, fd, mode); - - } else { - /* this is an directory */ - local->call_count = 1; - - STACK_WIND (frame, unify_buf_cbk, - NS(this), NS(this)->fops->fchmod, fd, mode); - } - - return 0; -} - -/** - * unify_fchown - - */ -int32_t -unify_fchown (call_frame_t *frame, - xlator_t *this, - fd_t *fd, - uid_t uid, - gid_t gid) -{ - unify_local_t *local = NULL; - xlator_t *child = NULL; - uint64_t tmp_child = 0; - - UNIFY_CHECK_FD_AND_UNWIND_ON_ERR(fd); - - /* Initialization */ - INIT_LOCAL (frame, local); - local->st_ino = fd->inode->ino; - - if (!fd_ctx_get (fd, this, &tmp_child)) { - /* If its set, then its file */ - child = (xlator_t *)(long)tmp_child; - - local->call_count = 2; - - STACK_WIND (frame, unify_buf_cbk, child, - child->fops->fchown, fd, uid, gid); - - STACK_WIND (frame, unify_buf_cbk, NS(this), - NS(this)->fops->fchown, fd, uid, gid); - } else { - local->call_count = 1; - - STACK_WIND (frame, unify_buf_cbk, - NS(this), NS(this)->fops->fchown, - fd, uid, gid); - } - - return 0; -} - /** * unify_flush_cbk - */ @@ -4436,7 +4340,6 @@ fini (xlator_t *this) struct xlator_fops fops = { .stat = unify_stat, - .chmod = unify_chmod, .readlink = unify_readlink, .mknod = unify_mknod, .mkdir = unify_mkdir, @@ -4445,7 +4348,6 @@ struct xlator_fops fops = { .symlink = unify_symlink, .rename = unify_rename, .link = unify_link, - .chown = unify_chown, .truncate = unify_truncate, .create = unify_create, .open = unify_open, @@ -4464,9 +4366,6 @@ struct xlator_fops fops = { .ftruncate = unify_ftruncate, .fstat = unify_fstat, .lk = unify_lk, - .fchown = unify_fchown, - .fchmod = unify_fchmod, - .utimens = unify_utimens, .lookup = unify_lookup, .getdents = unify_getdents, .checksum = unify_checksum, @@ -4475,7 +4374,9 @@ struct xlator_fops fops = { .entrylk = unify_entrylk, .fentrylk = unify_fentrylk, .xattrop = unify_xattrop, - .fxattrop = unify_fxattrop + .fxattrop = unify_fxattrop, + .setattr = unify_setattr, + .fsetattr = unify_fsetattr, }; struct xlator_mops mops = { diff --git a/xlators/cluster/unify/src/unify.h b/xlators/cluster/unify/src/unify.h index 9841e5c7a95..a745a9414fc 100644 --- a/xlators/cluster/unify/src/unify.h +++ b/xlators/cluster/unify/src/unify.h @@ -97,6 +97,8 @@ struct _unify_local_t { int32_t count; // dir_entry_t count; fd_t *fd; struct stat stbuf; + struct stat stpre; + struct stat stpost; struct statvfs statvfs_buf; struct timespec tv[2]; char *name; -- cgit