summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRavishankar N <ravishankar@redhat.com>2015-12-07 18:03:03 +0530
committerPranith Kumar Karampuri <pkarampu@redhat.com>2015-12-20 20:04:38 -0800
commitd5a9e765543fd6eec5d522e4f3f062bef97aefed (patch)
tree01715711c096da5d6a21b255139b81ad07abbe8d
parent9644769ea174646eaf18b8a41873f67928be9c8d (diff)
afr: refresh inode using fstat
For fd based operations (fgetxattr, readv etc.) if an inode refresh is required, do so using fstat instead of lookup. This is because the file might have been deleted by another client before refresh but posix mandates that FOPS using already open fds must still succeed. Change-Id: Id5f71c3af4892b648eb747f363dffe6208e7ac09 BUG: 1285230 Signed-off-by: Ravishankar N <ravishankar@redhat.com> Reviewed-on: http://review.gluster.org/12894 Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com> Tested-by: NetBSD Build System <jenkins@build.gluster.org>
-rw-r--r--xlators/cluster/afr/src/afr-common.c117
-rw-r--r--xlators/features/index/src/index.c65
2 files changed, 144 insertions, 38 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
index 2be75b0b471..e7c79ce3dff 100644
--- a/xlators/cluster/afr/src/afr-common.c
+++ b/xlators/cluster/afr/src/afr-common.c
@@ -837,29 +837,27 @@ afr_inode_refresh_done (call_frame_t *frame, xlator_t *this)
return 0;
}
-
-int
+void
afr_inode_refresh_subvol_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, inode_t *inode,
- struct iatt *buf, dict_t *xdata, struct iatt *par)
+ int op_ret, int op_errno, struct iatt *buf,
+ dict_t *xdata, struct iatt *par)
{
- afr_local_t *local = NULL;
- int call_child = (long) cookie;
- int call_count = 0;
- GF_UNUSED int ret = 0;
- int8_t need_heal = 1;
-
- local = frame->local;
+ afr_local_t *local = NULL;
+ int call_child = (long) cookie;
+ int8_t need_heal = 1;
+ int call_count = 0;
+ GF_UNUSED int ret = 0;
- local->replies[call_child].valid = 1;
- local->replies[call_child].op_ret = op_ret;
- local->replies[call_child].op_errno = op_errno;
+ local = frame->local;
+ local->replies[call_child].valid = 1;
+ local->replies[call_child].op_ret = op_ret;
+ local->replies[call_child].op_errno = op_errno;
if (op_ret != -1) {
local->replies[call_child].poststat = *buf;
- local->replies[call_child].postparent = *par;
+ if (par)
+ local->replies[call_child].postparent = *par;
local->replies[call_child].xdata = dict_ref (xdata);
}
-
if (xdata) {
ret = dict_get_int8 (xdata, "link-count", &need_heal);
local->replies[call_child].need_heal = need_heal;
@@ -867,20 +865,30 @@ afr_inode_refresh_subvol_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->replies[call_child].need_heal = need_heal;
}
- call_count = afr_frame_return (frame);
-
- if (call_count == 0) {
+ call_count = afr_frame_return (frame);
+ if (call_count == 0) {
afr_set_need_heal (this, local);
afr_inode_refresh_done (frame, this);
}
+}
+
+int
+afr_inode_refresh_subvol_with_lookup_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int op_ret,
+ int op_errno, inode_t *inode,
+ struct iatt *buf, dict_t *xdata,
+ struct iatt *par)
+{
+ afr_inode_refresh_subvol_cbk (frame, cookie, this, op_ret, op_errno,
+ buf, xdata, par);
return 0;
}
int
-afr_inode_refresh_subvol (call_frame_t *frame, xlator_t *this, int i,
- inode_t *inode, dict_t *xdata)
+afr_inode_refresh_subvol_with_lookup (call_frame_t *frame, xlator_t *this,
+ int i, inode_t *inode, dict_t *xdata)
{
loc_t loc = {0, };
afr_private_t *priv = NULL;
@@ -890,12 +898,38 @@ afr_inode_refresh_subvol (call_frame_t *frame, xlator_t *this, int i,
loc.inode = inode;
gf_uuid_copy (loc.gfid, inode->gfid);
- STACK_WIND_COOKIE (frame, afr_inode_refresh_subvol_cbk,
+ STACK_WIND_COOKIE (frame, afr_inode_refresh_subvol_with_lookup_cbk,
(void *) (long) i, priv->children[i],
priv->children[i]->fops->lookup, &loc, xdata);
return 0;
}
+int
+afr_inode_refresh_subvol_with_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)
+{
+ afr_inode_refresh_subvol_cbk (frame, cookie, this, op_ret, op_errno,
+ buf, xdata, NULL);
+ return 0;
+}
+
+int
+afr_inode_refresh_subvol_with_fstat (call_frame_t *frame, xlator_t *this, int i,
+ dict_t *xdata)
+{
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+
+ priv = this->private;
+ local = frame->local;
+
+ STACK_WIND_COOKIE (frame, afr_inode_refresh_subvol_with_fstat_cbk,
+ (void *) (long) i, priv->children[i],
+ priv->children[i]->fops->fstat, local->fd, xdata);
+ return 0;
+}
int
afr_inode_refresh_do (call_frame_t *frame, xlator_t *this)
@@ -906,12 +940,23 @@ afr_inode_refresh_do (call_frame_t *frame, xlator_t *this)
int i = 0;
int ret = 0;
dict_t *xdata = NULL;
+ afr_fd_ctx_t *fd_ctx = NULL;
+ unsigned char *wind_subvols = NULL;
priv = this->private;
local = frame->local;
+ wind_subvols = alloca0 (priv->child_count);
afr_local_replies_wipe (local, priv);
+ if (local->fd) {
+ fd_ctx = afr_fd_ctx_get (local->fd, this);
+ if (!fd_ctx) {
+ afr_inode_refresh_done (frame, this);
+ return 0;
+ }
+ }
+
xdata = dict_new ();
if (!xdata) {
afr_inode_refresh_done (frame, this);
@@ -930,15 +975,35 @@ afr_inode_refresh_do (call_frame_t *frame, xlator_t *this)
"Unable to set link-count in dict ");
}
- local->call_count = AFR_COUNT (local->child_up, priv->child_count);
+ if (local->fd) {
+ for (i = 0; i < priv->child_count; i++) {
+ if (local->child_up[i] &&
+ fd_ctx->opened_on[i] == AFR_FD_OPENED)
+ wind_subvols[i] = 1;
+ }
+ } else {
+ memcpy (wind_subvols, local->child_up,
+ sizeof (*local->child_up) * priv->child_count);
+ }
+
+ local->call_count = AFR_COUNT (wind_subvols, priv->child_count);
call_count = local->call_count;
+ if (!call_count) {
+ dict_unref (xdata);
+ afr_inode_refresh_done (frame, this);
+ return 0;
+ }
for (i = 0; i < priv->child_count; i++) {
- if (!local->child_up[i])
+ if (!wind_subvols[i])
continue;
- afr_inode_refresh_subvol (frame, this, i, local->refreshinode,
- xdata);
+ if (local->fd)
+ afr_inode_refresh_subvol_with_fstat (frame, this, i,
+ xdata);
+ else
+ afr_inode_refresh_subvol_with_lookup (frame, this, i,
+ local->refreshinode, xdata);
if (!--call_count)
break;
diff --git a/xlators/features/index/src/index.c b/xlators/features/index/src/index.c
index 8350e79c412..6e4071ab539 100644
--- a/xlators/features/index/src/index.c
+++ b/xlators/features/index/src/index.c
@@ -1353,16 +1353,14 @@ out:
return count;
}
-int32_t
-index_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, dict_t *xdata, struct iatt *postparent)
+dict_t*
+index_fill_link_count (xlator_t *this, dict_t *xdata)
{
- int ret = -1;
- char *dir = NULL;
- index_priv_t *priv = this->private;
- int64_t count = -1;
+ int ret = -1;
+ index_priv_t *priv = NULL;
+ int64_t count = -1;
+ priv = this->private;
xdata = (xdata) ? dict_ref (xdata) : dict_new ();
if (!xdata)
goto out;
@@ -1376,14 +1374,26 @@ index_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (count == 0) {
ret = dict_set_int8 (xdata, "link-count", 0);
if (ret < 0)
- goto out;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to set link-count");
} else {
ret = dict_set_int8 (xdata, "link-count", 1);
if (ret < 0)
- goto out;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to set link-count");
}
out:
+ return xdata;
+}
+
+int32_t
+index_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, dict_t *xdata, struct iatt *postparent)
+{
+
+ xdata = index_fill_link_count (this, xdata);
STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, buf,
xdata, postparent);
if (xdata)
@@ -1418,7 +1428,7 @@ index_lookup (call_frame_t *frame, xlator_t *this,
return 0;
normal:
ret = dict_get_str (xattr_req, "link-count", &flag);
- if (!(ret || strcmp (flag, GF_XATTROP_INDEX_COUNT))) {
+ if ((ret == 0) && (strcmp (flag, GF_XATTROP_INDEX_COUNT) == 0)) {
STACK_WIND (frame, index_lookup_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->lookup, loc, xattr_req);
} else {
@@ -1430,6 +1440,36 @@ normal:
}
int32_t
+index_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)
+{
+ xdata = index_fill_link_count (this, xdata);
+ STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf, xdata);
+ if (xdata)
+ dict_unref (xdata);
+ return 0;
+}
+
+int32_t
+index_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+{
+ int ret = -1;
+ char *flag = NULL;
+
+ ret = dict_get_str (xdata, "link-count", &flag);
+ if ((ret == 0) && (strcmp (flag, GF_XATTROP_INDEX_COUNT) == 0)) {
+ STACK_WIND (frame, index_fstat_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fstat, fd, xdata);
+ } else {
+ STACK_WIND (frame, default_fstat_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fstat, fd, xdata);
+ }
+
+ return 0;
+}
+
+int32_t
index_opendir (call_frame_t *frame, xlator_t *this,
loc_t *loc, fd_t *fd, dict_t *xdata)
{
@@ -1809,7 +1849,8 @@ struct xlator_fops fops = {
.lookup = index_lookup,
.opendir = index_opendir,
.readdir = index_readdir,
- .unlink = index_unlink
+ .unlink = index_unlink,
+ .fstat = index_fstat,
};
struct xlator_dumpops dumpops;