diff options
Diffstat (limited to 'xlators/performance/md-cache/src/md-cache.c')
| -rw-r--r-- | xlators/performance/md-cache/src/md-cache.c | 915 |
1 files changed, 723 insertions, 192 deletions
diff --git a/xlators/performance/md-cache/src/md-cache.c b/xlators/performance/md-cache/src/md-cache.c index 45b024d9a..84c363ad9 100644 --- a/xlators/performance/md-cache/src/md-cache.c +++ b/xlators/performance/md-cache/src/md-cache.c @@ -1,20 +1,11 @@ /* - Copyright (c) 2012 Red Hat, Inc. <http://www.redhat.com> + Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ #ifndef _CONFIG_H @@ -27,6 +18,7 @@ #include "dict.h" #include "xlator.h" #include "md-cache-mem-types.h" +#include "glusterfs-acl.h" #include <assert.h> #include <sys/time.h> @@ -39,32 +31,35 @@ struct mdc_conf { int timeout; + gf_boolean_t cache_posix_acl; + gf_boolean_t cache_selinux; + gf_boolean_t force_readdirp; }; -struct mdc_key { +static struct mdc_key { const char *name; int load; int check; } mdc_keys[] = { { - .name = "system.posix_acl_access", - .load = 1, + .name = POSIX_ACL_ACCESS_XATTR, + .load = 0, .check = 1, }, { - .name = "system.posix_acl_default", - .load = 1, + .name = POSIX_ACL_DEFAULT_XATTR, + .load = 0, .check = 1, }, { - .name = "security.selinux", - .load = 1, + .name = GF_SELINUX_XATTR_KEY, + .load = 0, .check = 1, }, { .name = "security.capability", - .load = 1, + .load = 0, .check = 1, }, { @@ -72,7 +67,11 @@ struct mdc_key { .load = 0, .check = 1, }, - {}, + { + .name = NULL, + .load = 0, + .check = 0, + } }; @@ -125,15 +124,17 @@ struct md_cache { char *linkname; time_t ia_time; time_t xa_time; + gf_lock_t lock; }; struct mdc_local { - loc_t loc; - loc_t loc2; - fd_t *fd; - char *linkname; - dict_t *xattr; + loc_t loc; + loc_t loc2; + fd_t *fd; + char *linkname; + char *key; + dict_t *xattr; }; @@ -175,7 +176,7 @@ __mdc_inode_ctx_set (xlator_t *this, inode_t *inode, struct md_cache *mdc) uint64_t mdc_int = 0; mdc_int = (long) mdc; - ret = __inode_ctx_set2 (inode, this, &mdc_int, 0); + ret = __inode_ctx_set (inode, this, &mdc_int); return ret; } @@ -228,8 +229,9 @@ mdc_local_wipe (xlator_t *this, mdc_local_t *local) if (local->fd) fd_unref (local->fd); - if (local->linkname) - GF_FREE (local->linkname); + GF_FREE (local->linkname); + + GF_FREE (local->key); if (local->xattr) dict_unref (local->xattr); @@ -255,8 +257,7 @@ mdc_inode_wipe (xlator_t *this, inode_t *inode) if (mdc->xattr) dict_unref (mdc->xattr); - if (mdc->linkname) - GF_FREE (mdc->linkname); + GF_FREE (mdc->linkname); GF_FREE (mdc); @@ -285,6 +286,8 @@ mdc_inode_prep (xlator_t *this, inode_t *inode) goto unlock; } + LOCK_INIT (&mdc->lock); + ret = __mdc_inode_ctx_set (this, inode, mdc); if (ret) { gf_log (this->name, GF_LOG_ERROR, @@ -305,15 +308,19 @@ is_md_cache_iatt_valid (xlator_t *this, struct md_cache *mdc) { struct mdc_conf *conf = NULL; time_t now = 0; - + gf_boolean_t ret = _gf_true; conf = this->private; time (&now); - if (now > (mdc->ia_time + conf->timeout)) - return _gf_false; + LOCK (&mdc->lock); + { + if (now >= (mdc->ia_time + conf->timeout)) + ret = _gf_false; + } + UNLOCK (&mdc->lock); - return _gf_true; + return ret; } @@ -322,15 +329,20 @@ is_md_cache_xatt_valid (xlator_t *this, struct md_cache *mdc) { struct mdc_conf *conf = NULL; time_t now = 0; + gf_boolean_t ret = _gf_true; conf = this->private; time (&now); - if (now > (mdc->xa_time + conf->timeout)) - return _gf_false; + LOCK (&mdc->lock); + { + if (now >= (mdc->xa_time + conf->timeout)) + ret = _gf_false; + } + UNLOCK (&mdc->lock); - return _gf_true; + return ret; } @@ -373,7 +385,8 @@ mdc_to_iatt (struct md_cache *mdc, struct iatt *iatt) int -mdc_inode_iatt_set (xlator_t *this, inode_t *inode, struct iatt *iatt) +mdc_inode_iatt_set_validate(xlator_t *this, inode_t *inode, struct iatt *prebuf, + struct iatt *iatt) { int ret = -1; struct md_cache *mdc = NULL; @@ -382,20 +395,41 @@ mdc_inode_iatt_set (xlator_t *this, inode_t *inode, struct iatt *iatt) if (!mdc) goto out; - if (!iatt || !iatt->ia_ctime) { - mdc->ia_time = 0; - return 0; - } - - mdc_from_iatt (mdc, iatt); - - time (&mdc->ia_time); + LOCK (&mdc->lock); + { + if (!iatt || !iatt->ia_ctime) { + mdc->ia_time = 0; + goto unlock; + } + /* + * Invalidate the inode if the mtime or ctime has changed + * and the prebuf doesn't match the value we have cached. + * TODO: writev returns with a NULL iatt due to + * performance/write-behind, causing invalidation on writes. + */ + if (IA_ISREG(inode->ia_type) && + ((iatt->ia_mtime != mdc->md_mtime) || + (iatt->ia_ctime != mdc->md_ctime))) + if (!prebuf || (prebuf->ia_ctime != mdc->md_ctime) || + (prebuf->ia_mtime != mdc->md_mtime)) + inode_invalidate(inode); + + mdc_from_iatt (mdc, iatt); + + time (&mdc->ia_time); + } +unlock: + UNLOCK (&mdc->lock); ret = 0; out: return ret; } +int mdc_inode_iatt_set(xlator_t *this, inode_t *inode, struct iatt *iatt) +{ + return mdc_inode_iatt_set_validate(this, inode, NULL, iatt); +} int mdc_inode_iatt_get (xlator_t *this, inode_t *inode, struct iatt *iatt) @@ -409,7 +443,11 @@ mdc_inode_iatt_get (xlator_t *this, inode_t *inode, struct iatt *iatt) if (!is_md_cache_iatt_valid (this, mdc)) goto out; - mdc_to_iatt (mdc, iatt); + LOCK (&mdc->lock); + { + mdc_to_iatt (mdc, iatt); + } + UNLOCK (&mdc->lock); uuid_copy (iatt->ia_gfid, inode->gfid); iatt->ia_ino = gfid_to_ino (inode->gfid); @@ -421,12 +459,71 @@ out: return ret; } +struct updatedict { + dict_t *dict; + int ret; +}; + +static int +updatefn(dict_t *dict, char *key, data_t *value, void *data) +{ + struct updatedict *u = data; + const char *mdc_key; + int i = 0; + + for (mdc_key = mdc_keys[i].name; (mdc_key = mdc_keys[i].name); i++) { + if (!mdc_keys[i].check) + continue; + if (strcmp(mdc_key, key)) + continue; + + if (!u->dict) { + u->dict = dict_new(); + if (!u->dict) { + u->ret = -1; + return -1; + } + } + + if (dict_set(u->dict, key, value) < 0) { + u->ret = -1; + return -1; + } + + break; + } + return 0; +} + +static int +mdc_dict_update(dict_t **tgt, dict_t *src) +{ + struct updatedict u = { + .dict = *tgt, + .ret = 0, + }; + + dict_foreach(src, updatefn, &u); + + if (*tgt) + return u.ret; + + if ((u.ret < 0) && u.dict) { + dict_unref(u.dict); + return u.ret; + } + + *tgt = u.dict; + + return u.ret; +} int mdc_inode_xatt_set (xlator_t *this, inode_t *inode, dict_t *dict) { int ret = -1; struct md_cache *mdc = NULL; + dict_t *newdict = NULL; mdc = mdc_inode_prep (this, inode); if (!mdc) @@ -435,13 +532,25 @@ mdc_inode_xatt_set (xlator_t *this, inode_t *inode, dict_t *dict) if (!dict) goto out; - if (mdc->xattr) - dict_unref (mdc->xattr); + LOCK (&mdc->lock); + { + if (mdc->xattr) { + dict_unref (mdc->xattr); + mdc->xattr = NULL; + } - mdc->xattr = dict_ref (dict); + ret = mdc_dict_update(&newdict, dict); + if (ret < 0) { + UNLOCK(&mdc->lock); + goto out; + } - time (&mdc->xa_time); + if (newdict) + mdc->xattr = newdict; + time (&mdc->xa_time); + } + UNLOCK (&mdc->lock); ret = 0; out: return ret; @@ -461,14 +570,42 @@ mdc_inode_xatt_update (xlator_t *this, inode_t *inode, dict_t *dict) if (!dict) goto out; - if (!mdc->xattr) - mdc->xattr = dict_ref (dict); - else - dict_copy (dict, mdc->xattr); + LOCK (&mdc->lock); + { + ret = mdc_dict_update(&mdc->xattr, dict); + if (ret < 0) { + UNLOCK(&mdc->lock); + goto out; + } - mdc->xattr = dict_ref (dict); + time (&mdc->xa_time); + } + UNLOCK (&mdc->lock); + + ret = 0; +out: + return ret; +} - time (&mdc->xa_time); + +int +mdc_inode_xatt_unset (xlator_t *this, inode_t *inode, char *name) +{ + int ret = -1; + struct md_cache *mdc = NULL; + + mdc = mdc_inode_prep (this, inode); + if (!mdc) + goto out; + + if (!name) + goto out; + + LOCK (&mdc->lock); + { + dict_del (mdc->xattr, name); + } + UNLOCK (&mdc->lock); ret = 0; out: @@ -488,13 +625,61 @@ mdc_inode_xatt_get (xlator_t *this, inode_t *inode, dict_t **dict) if (!is_md_cache_xatt_valid (this, mdc)) goto out; - if (!mdc->xattr) + LOCK (&mdc->lock); + { + ret = 0; + /* Missing xattr only means no keys were there, i.e + a negative cache for the "loaded" keys + */ + if (!mdc->xattr) + goto unlock; + + if (dict) + *dict = dict_ref (mdc->xattr); + } +unlock: + UNLOCK (&mdc->lock); + +out: + return ret; +} + + +int +mdc_inode_iatt_invalidate (xlator_t *this, inode_t *inode) +{ + int ret = -1; + struct md_cache *mdc = NULL; + + if (mdc_inode_ctx_get (this, inode, &mdc) != 0) goto out; - if (dict) - *dict = dict_ref (mdc->xattr); + LOCK (&mdc->lock); + { + mdc->ia_time = 0; + } + UNLOCK (&mdc->lock); + +out: + return ret; +} + + +int +mdc_inode_xatt_invalidate (xlator_t *this, inode_t *inode) +{ + int ret = -1; + struct md_cache *mdc = NULL; + + if (mdc_inode_ctx_get (this, inode, &mdc) != 0) + goto out; + + LOCK (&mdc->lock); + { + mdc->xa_time = 0; + } + UNLOCK (&mdc->lock); - ret = 0; out: return ret; } @@ -533,7 +718,7 @@ is_mdc_key_satisfied (const char *key) return 0; for (mdc_key = mdc_keys[i].name; (mdc_key = mdc_keys[i].name); i++) { - if (!mdc_keys[i].check) + if (!mdc_keys[i].load) continue; if (strcmp (mdc_key, key) == 0) return 1; @@ -543,13 +728,15 @@ is_mdc_key_satisfied (const char *key) } -static void +static int checkfn (dict_t *this, char *key, data_t *value, void *data) { struct checkpair *pair = data; if (!is_mdc_key_satisfied (key)) pair->ret = 0; + + return 0; } @@ -599,12 +786,13 @@ out: int mdc_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, - dict_t *xattr_req) + dict_t *xdata) { int ret = 0; struct iatt stbuf = {0, }; struct iatt postparent = {0, }; dict_t *xattr_rsp = NULL; + dict_t *xattr_alloc = NULL; mdc_local_t *local = NULL; @@ -612,18 +800,25 @@ mdc_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, if (!local) goto uncached; + if (!loc->name) + /* A nameless discovery is dangerous to cache. We + perform nameless lookup with the intention of + re-establishing an inode "properly" + */ + goto uncached; + loc_copy (&local->loc, loc); ret = mdc_inode_iatt_get (this, loc->inode, &stbuf); if (ret != 0) goto uncached; - if (xattr_req) { + if (xdata) { ret = mdc_inode_xatt_get (this, loc->inode, &xattr_rsp); if (ret != 0) goto uncached; - if (!mdc_xattr_satisfied (this, xattr_req, xattr_rsp)) + if (!mdc_xattr_satisfied (this, xdata, xattr_rsp)) goto uncached; } @@ -636,22 +831,25 @@ mdc_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, return 0; uncached: - if (xattr_req) - mdc_load_reqs (this, xattr_req); + if (!xdata) + xdata = xattr_alloc = dict_new (); + if (xdata) + mdc_load_reqs (this, xdata); STACK_WIND (frame, mdc_lookup_cbk, FIRST_CHILD (this), - FIRST_CHILD (this)->fops->lookup, loc, xattr_req); + FIRST_CHILD (this)->fops->lookup, loc, xdata); if (xattr_rsp) dict_unref (xattr_rsp); - + if (xattr_alloc) + dict_unref (xattr_alloc); return 0; } int mdc_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *buf) + int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata) { mdc_local_t *local = NULL; @@ -665,14 +863,14 @@ mdc_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, mdc_inode_iatt_set (this, local->loc.inode, buf); out: - MDC_STACK_UNWIND (stat, frame, op_ret, op_errno, buf); + MDC_STACK_UNWIND (stat, frame, op_ret, op_errno, buf, xdata); return 0; } int -mdc_stat (call_frame_t *frame, xlator_t *this, loc_t *loc) +mdc_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { int ret; struct iatt stbuf; @@ -688,21 +886,22 @@ mdc_stat (call_frame_t *frame, xlator_t *this, loc_t *loc) if (ret != 0) goto uncached; - MDC_STACK_UNWIND (stat, frame, 0, 0, &stbuf); + MDC_STACK_UNWIND (stat, frame, 0, 0, &stbuf, xdata); return 0; uncached: STACK_WIND (frame, mdc_stat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->stat, - loc); + loc, xdata); return 0; } int mdc_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *buf) + int32_t op_ret, int32_t op_errno, struct iatt *buf, + dict_t *xdata) { mdc_local_t *local = NULL; @@ -716,14 +915,14 @@ mdc_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, mdc_inode_iatt_set (this, local->fd->inode, buf); out: - MDC_STACK_UNWIND (fstat, frame, op_ret, op_errno, buf); + MDC_STACK_UNWIND (fstat, frame, op_ret, op_errno, buf, xdata); return 0; } int -mdc_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd) +mdc_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { int ret; struct iatt stbuf; @@ -739,14 +938,14 @@ mdc_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd) if (ret != 0) goto uncached; - MDC_STACK_UNWIND (fstat, frame, 0, 0, &stbuf); + MDC_STACK_UNWIND (fstat, frame, 0, 0, &stbuf, xdata); return 0; uncached: STACK_WIND (frame, mdc_fstat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat, - fd); + fd, xdata); return 0; } @@ -754,7 +953,7 @@ uncached: int mdc_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct iatt *prebuf, struct iatt *postbuf) + struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { mdc_local_t *local = NULL; @@ -766,10 +965,11 @@ mdc_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (!local) goto out; - mdc_inode_iatt_set (this, local->loc.inode, postbuf); + mdc_inode_iatt_set_validate(this, local->loc.inode, prebuf, postbuf); out: - MDC_STACK_UNWIND (truncate, frame, op_ret, op_errno, prebuf, postbuf); + MDC_STACK_UNWIND (truncate, frame, op_ret, op_errno, prebuf, postbuf, + xdata); return 0; } @@ -777,7 +977,7 @@ out: int mdc_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, - off_t offset) + off_t offset, dict_t *xdata) { mdc_local_t *local = NULL; @@ -787,7 +987,7 @@ mdc_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, STACK_WIND (frame, mdc_truncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, - loc, offset); + loc, offset, xdata); return 0; } @@ -795,7 +995,7 @@ mdc_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, int mdc_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct iatt *prebuf, struct iatt *postbuf) + struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { mdc_local_t *local = NULL; @@ -807,10 +1007,11 @@ mdc_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (!local) goto out; - mdc_inode_iatt_set (this, local->fd->inode, postbuf); + mdc_inode_iatt_set_validate(this, local->fd->inode, prebuf, postbuf); out: - MDC_STACK_UNWIND (ftruncate, frame, op_ret, op_errno, prebuf, postbuf); + MDC_STACK_UNWIND (ftruncate, frame, op_ret, op_errno, prebuf, postbuf, + xdata); return 0; } @@ -818,7 +1019,7 @@ out: int mdc_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, - off_t offset) + off_t offset, dict_t *xdata) { mdc_local_t *local = NULL; @@ -828,7 +1029,7 @@ mdc_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, STACK_WIND (frame, mdc_ftruncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, - fd, offset); + fd, offset, xdata); return 0; } @@ -836,7 +1037,8 @@ mdc_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, int mdc_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, - struct iatt *buf, struct iatt *preparent, struct iatt *postparent) + struct iatt *buf, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) { mdc_local_t *local = NULL; @@ -858,25 +1060,25 @@ mdc_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } out: MDC_STACK_UNWIND (mknod, frame, op_ret, op_errno, inode, buf, - preparent, postparent); + preparent, postparent, xdata); return 0; } int mdc_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, - mode_t mode, dev_t rdev, dict_t *params) + mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata) { mdc_local_t *local = NULL; local = mdc_local_get (frame); loc_copy (&local->loc, loc); - local->xattr = dict_ref (params); + local->xattr = dict_ref (xdata); STACK_WIND (frame, mdc_mknod_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, - loc, mode, rdev, params); + loc, mode, rdev, umask, xdata); return 0; } @@ -884,7 +1086,8 @@ mdc_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, int mdc_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, - struct iatt *buf, struct iatt *preparent, struct iatt *postparent) + struct iatt *buf, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) { mdc_local_t *local = NULL; @@ -906,25 +1109,25 @@ mdc_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } out: MDC_STACK_UNWIND (mkdir, frame, op_ret, op_errno, inode, buf, - preparent, postparent); + preparent, postparent, xdata); return 0; } int mdc_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, - mode_t mode, dict_t *params) + mode_t mode, mode_t umask, dict_t *xdata) { mdc_local_t *local = NULL; local = mdc_local_get (frame); loc_copy (&local->loc, loc); - local->xattr = dict_ref (params); + local->xattr = dict_ref (xdata); STACK_WIND (frame, mdc_mkdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, - loc, mode, params); + loc, mode, umask, xdata); return 0; } @@ -932,7 +1135,7 @@ mdc_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int mdc_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) + struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { mdc_local_t *local = NULL; @@ -954,13 +1157,14 @@ mdc_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, out: MDC_STACK_UNWIND (unlink, frame, op_ret, op_errno, - preparent, postparent); + preparent, postparent, xdata); return 0; } int -mdc_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc) +mdc_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t xflag, + dict_t *xdata) { mdc_local_t *local = NULL; @@ -970,7 +1174,7 @@ mdc_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc) STACK_WIND (frame, mdc_unlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, - loc); + loc, xflag, xdata); return 0; } @@ -978,7 +1182,7 @@ mdc_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc) int mdc_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct iatt *preparent, struct iatt *postparent) + struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { mdc_local_t *local = NULL; @@ -996,13 +1200,14 @@ mdc_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, out: MDC_STACK_UNWIND (rmdir, frame, op_ret, op_errno, - preparent, postparent); + preparent, postparent, xdata); return 0; } int -mdc_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flag) +mdc_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flag, + dict_t *xdata) { mdc_local_t *local = NULL; @@ -1012,7 +1217,7 @@ mdc_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flag) STACK_WIND (frame, mdc_rmdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rmdir, - loc, flag); + loc, flag, xdata); return 0; } @@ -1020,7 +1225,8 @@ mdc_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flag) int mdc_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, - struct iatt *buf, struct iatt *preparent, struct iatt *postparent) + struct iatt *buf, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) { mdc_local_t *local = NULL; @@ -1041,14 +1247,14 @@ mdc_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } out: MDC_STACK_UNWIND (symlink, frame, op_ret, op_errno, inode, buf, - preparent, postparent); + preparent, postparent, xdata); return 0; } int mdc_symlink (call_frame_t *frame, xlator_t *this, const char *linkname, - loc_t *loc, dict_t *params) + loc_t *loc, mode_t umask, dict_t *xdata) { mdc_local_t *local = NULL; @@ -1060,7 +1266,7 @@ mdc_symlink (call_frame_t *frame, xlator_t *this, const char *linkname, STACK_WIND (frame, mdc_symlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink, - linkname, loc, params); + linkname, loc, umask, xdata); return 0; } @@ -1069,7 +1275,8 @@ int mdc_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) + struct iatt *prenewparent, struct iatt *postnewparent, + dict_t *xdata) { mdc_local_t *local = NULL; @@ -1098,14 +1305,15 @@ mdc_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } out: MDC_STACK_UNWIND (rename, frame, op_ret, op_errno, buf, - preoldparent, postoldparent, prenewparent, postnewparent); + preoldparent, postoldparent, prenewparent, + postnewparent, xdata); return 0; } int mdc_rename (call_frame_t *frame, xlator_t *this, - loc_t *oldloc, loc_t *newloc) + loc_t *oldloc, loc_t *newloc, dict_t *xdata) { mdc_local_t *local = NULL; @@ -1116,7 +1324,7 @@ mdc_rename (call_frame_t *frame, xlator_t *this, STACK_WIND (frame, mdc_rename_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, - oldloc, newloc); + oldloc, newloc, xdata); return 0; } @@ -1124,7 +1332,7 @@ mdc_rename (call_frame_t *frame, xlator_t *this, int mdc_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, - struct iatt *preparent, struct iatt *postparent) + struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { mdc_local_t *local = NULL; @@ -1145,14 +1353,14 @@ mdc_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } out: MDC_STACK_UNWIND (link, frame, op_ret, op_errno, inode, buf, - preparent, postparent); + preparent, postparent, xdata); return 0; } int mdc_link (call_frame_t *frame, xlator_t *this, - loc_t *oldloc, loc_t *newloc) + loc_t *oldloc, loc_t *newloc, dict_t *xdata) { mdc_local_t *local = NULL; @@ -1163,7 +1371,7 @@ mdc_link (call_frame_t *frame, xlator_t *this, STACK_WIND (frame, mdc_link_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, - oldloc, newloc); + oldloc, newloc, xdata); return 0; } @@ -1171,7 +1379,8 @@ mdc_link (call_frame_t *frame, xlator_t *this, int mdc_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) + struct iatt *buf, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) { mdc_local_t *local = NULL; @@ -1193,25 +1402,25 @@ mdc_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } out: MDC_STACK_UNWIND (create, frame, op_ret, op_errno, fd, inode, buf, - preparent, postparent); + preparent, postparent, xdata); return 0; } int mdc_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, - mode_t mode, fd_t *fd, dict_t *params) + mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { mdc_local_t *local = NULL; local = mdc_local_get (frame); loc_copy (&local->loc, loc); - local->xattr = dict_ref (params); + local->xattr = dict_ref (xdata); STACK_WIND (frame, mdc_create_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, - loc, flags, mode, fd, params); + loc, flags, mode, umask, fd, xdata); return 0; } @@ -1220,7 +1429,7 @@ int mdc_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 *iobref) + struct iatt *stbuf, struct iobref *iobref, dict_t *xdata) { mdc_local_t *local = NULL; @@ -1236,7 +1445,7 @@ mdc_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, out: MDC_STACK_UNWIND (readv, frame, op_ret, op_errno, vector, count, - stbuf, iobref); + stbuf, iobref, xdata); return 0; } @@ -1244,7 +1453,7 @@ out: int mdc_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, - off_t offset, uint32_t flags) + off_t offset, uint32_t flags, dict_t *xdata) { mdc_local_t *local = NULL; @@ -1254,7 +1463,7 @@ mdc_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, STACK_WIND (frame, mdc_readv_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, - fd, size, offset, flags); + fd, size, offset, flags, xdata); return 0; } @@ -1262,7 +1471,7 @@ mdc_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, int mdc_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) + struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { mdc_local_t *local = NULL; @@ -1274,10 +1483,11 @@ mdc_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (!local) goto out; - mdc_inode_iatt_set (this, local->fd->inode, postbuf); + mdc_inode_iatt_set_validate(this, local->fd->inode, prebuf, postbuf); out: - MDC_STACK_UNWIND (writev, frame, op_ret, op_errno, prebuf, postbuf); + MDC_STACK_UNWIND (writev, frame, op_ret, op_errno, prebuf, postbuf, + xdata); return 0; } @@ -1285,7 +1495,8 @@ out: int mdc_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, - int count, off_t offset, uint32_t flags, struct iobref *iobref) + int count, off_t offset, uint32_t flags, struct iobref *iobref, + dict_t *xdata) { mdc_local_t *local = NULL; @@ -1295,7 +1506,7 @@ mdc_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, STACK_WIND (frame, mdc_writev_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, - fd, vector, count, offset, flags, iobref); + fd, vector, count, offset, flags, iobref, xdata); return 0; } @@ -1303,7 +1514,7 @@ mdc_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int mdc_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct iatt *prebuf, struct iatt *postbuf) + struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { mdc_local_t *local = NULL; @@ -1317,10 +1528,11 @@ mdc_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (!local) goto out; - mdc_inode_iatt_set (this, local->loc.inode, postbuf); + mdc_inode_iatt_set_validate(this, local->loc.inode, prebuf, postbuf); out: - MDC_STACK_UNWIND (setattr, frame, op_ret, op_errno, prebuf, postbuf); + MDC_STACK_UNWIND (setattr, frame, op_ret, op_errno, prebuf, postbuf, + xdata); return 0; } @@ -1328,7 +1540,7 @@ out: int mdc_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, - struct iatt *stbuf, int valid) + struct iatt *stbuf, int valid, dict_t *xdata) { mdc_local_t *local = NULL; @@ -1338,7 +1550,7 @@ mdc_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, STACK_WIND (frame, mdc_setattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setattr, - loc, stbuf, valid); + loc, stbuf, valid, xdata); return 0; } @@ -1346,7 +1558,7 @@ mdc_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, int mdc_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct iatt *prebuf, struct iatt *postbuf) + struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { mdc_local_t *local = NULL; @@ -1358,10 +1570,11 @@ mdc_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (!local) goto out; - mdc_inode_iatt_set (this, local->fd->inode, postbuf); + mdc_inode_iatt_set_validate(this, local->fd->inode, prebuf, postbuf); out: - MDC_STACK_UNWIND (fsetattr, frame, op_ret, op_errno, prebuf, postbuf); + MDC_STACK_UNWIND (fsetattr, frame, op_ret, op_errno, prebuf, postbuf, + xdata); return 0; } @@ -1369,7 +1582,7 @@ out: int mdc_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, - struct iatt *stbuf, int valid) + struct iatt *stbuf, int valid, dict_t *xdata) { mdc_local_t *local = NULL; @@ -1377,9 +1590,9 @@ mdc_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, local->fd = fd_ref (fd); - STACK_WIND (frame, mdc_setattr_cbk, + STACK_WIND (frame, mdc_fsetattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetattr, - fd, stbuf, valid); + fd, stbuf, valid, xdata); return 0; } @@ -1387,7 +1600,7 @@ mdc_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, int mdc_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct iatt *prebuf, struct iatt *postbuf) + struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { mdc_local_t *local = NULL; @@ -1399,17 +1612,19 @@ mdc_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (!local) goto out; - mdc_inode_iatt_set (this, local->fd->inode, postbuf); + mdc_inode_iatt_set_validate(this, local->fd->inode, prebuf, postbuf); out: - MDC_STACK_UNWIND (fsync, frame, op_ret, op_errno, prebuf, postbuf); + MDC_STACK_UNWIND (fsync, frame, op_ret, op_errno, prebuf, postbuf, + xdata); return 0; } int -mdc_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int datasync) +mdc_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int datasync, + dict_t *xdata) { mdc_local_t *local = NULL; @@ -1419,14 +1634,14 @@ mdc_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int datasync) STACK_WIND (frame, mdc_fsync_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsync, - fd, datasync); + fd, datasync, xdata); return 0; } int mdc_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) + int32_t op_ret, int32_t op_errno, dict_t *xdata) { mdc_local_t *local = NULL; @@ -1440,8 +1655,10 @@ mdc_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, mdc_inode_xatt_update (this, local->loc.inode, local->xattr); + mdc_inode_iatt_invalidate (this, local->loc.inode); + out: - MDC_STACK_UNWIND (setxattr, frame, op_ret, op_errno); + MDC_STACK_UNWIND (setxattr, frame, op_ret, op_errno, xdata); return 0; } @@ -1449,7 +1666,7 @@ out: int mdc_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, - dict_t *xattr, int flags) + dict_t *xattr, int flags, dict_t *xdata) { mdc_local_t *local = NULL; @@ -1460,14 +1677,14 @@ mdc_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, STACK_WIND (frame, mdc_setxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, - loc, xattr, flags); + loc, xattr, flags, xdata); return 0; } int mdc_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) + int32_t op_ret, int32_t op_errno, dict_t *xdata) { mdc_local_t *local = NULL; @@ -1481,8 +1698,9 @@ mdc_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, mdc_inode_xatt_update (this, local->fd->inode, local->xattr); + mdc_inode_iatt_invalidate (this, local->fd->inode); out: - MDC_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno); + MDC_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno, xdata); return 0; } @@ -1490,7 +1708,7 @@ out: int mdc_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, - dict_t *xattr, int flags) + dict_t *xattr, int flags, dict_t *xdata) { mdc_local_t *local = NULL; @@ -1501,13 +1719,14 @@ mdc_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, STACK_WIND (frame, mdc_fsetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, - fd, xattr, flags); + fd, xattr, flags, xdata); return 0; } int mdc_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dict_t *xattr) + int32_t op_ret, int32_t op_errno, dict_t *xattr, + dict_t *xdata) { mdc_local_t *local = NULL; @@ -1521,16 +1740,18 @@ mdc_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, mdc_inode_xatt_update (this, local->loc.inode, xattr); out: - MDC_STACK_UNWIND (getxattr, frame, op_ret, op_errno, xattr); + MDC_STACK_UNWIND (getxattr, frame, op_ret, op_errno, xattr, xdata); return 0; } int -mdc_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, const char *key) +mdc_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, const char *key, + dict_t *xdata) { int ret; + int op_errno = ENODATA; mdc_local_t *local = NULL; dict_t *xattr = NULL; @@ -1547,24 +1768,27 @@ mdc_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, const char *key) if (ret != 0) goto uncached; - if (!dict_get (xattr, (char *)key)) - goto uncached; + if (!xattr || !dict_get (xattr, (char *)key)) { + ret = -1; + op_errno = ENODATA; + } - MDC_STACK_UNWIND (getxattr, frame, 0, 0, xattr); + MDC_STACK_UNWIND (getxattr, frame, ret, op_errno, xattr, xdata); return 0; uncached: STACK_WIND (frame, mdc_getxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr, - loc, key); + loc, key, xdata); return 0; } int mdc_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dict_t *xattr) + int32_t op_ret, int32_t op_errno, dict_t *xattr, + dict_t *xdata) { mdc_local_t *local = NULL; @@ -1578,18 +1802,20 @@ mdc_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, mdc_inode_xatt_update (this, local->fd->inode, xattr); out: - MDC_STACK_UNWIND (fgetxattr, frame, op_ret, op_errno, xattr); + MDC_STACK_UNWIND (fgetxattr, frame, op_ret, op_errno, xattr, xdata); return 0; } int -mdc_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, const char *key) +mdc_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, const char *key, + dict_t *xdata) { int ret; mdc_local_t *local = NULL; dict_t *xattr = NULL; + int op_errno = ENODATA; local = mdc_local_get (frame); if (!local) @@ -1604,24 +1830,117 @@ mdc_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, const char *key) if (ret != 0) goto uncached; - if (!dict_get (xattr, (char *)key)) - goto uncached; + if (!xattr || !dict_get (xattr, (char *)key)) { + ret = -1; + op_errno = ENODATA; + } - MDC_STACK_UNWIND (fgetxattr, frame, 0, 0, xattr); + MDC_STACK_UNWIND (fgetxattr, frame, ret, op_errno, xattr, xdata); return 0; uncached: STACK_WIND (frame, mdc_fgetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fgetxattr, - fd, key); + fd, key, xdata); + return 0; +} + +int +mdc_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ + mdc_local_t *local = NULL; + + local = frame->local; + + if (op_ret != 0) + goto out; + + if (!local) + goto out; + + if (local->key) + mdc_inode_xatt_unset (this, local->loc.inode, local->key); + else + mdc_inode_xatt_invalidate (this, local->loc.inode); + + mdc_inode_iatt_invalidate (this, local->loc.inode); +out: + MDC_STACK_UNWIND (removexattr, frame, op_ret, op_errno, xdata); + + return 0; +} + + +int +mdc_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc, + const char *name, dict_t *xdata) +{ + mdc_local_t *local = NULL; + + local = mdc_local_get (frame); + + loc_copy (&local->loc, loc); + + local->key = gf_strdup (name); + + STACK_WIND (frame, mdc_removexattr_cbk, + FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr, + loc, name, xdata); + return 0; +} + + +int +mdc_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ + mdc_local_t *local = NULL; + + local = frame->local; + + if (op_ret != 0) + goto out; + + if (!local) + goto out; + + if (local->key) + mdc_inode_xatt_unset (this, local->fd->inode, local->key); + else + mdc_inode_xatt_invalidate (this, local->fd->inode); + + mdc_inode_iatt_invalidate (this, local->fd->inode); +out: + MDC_STACK_UNWIND (fremovexattr, frame, op_ret, op_errno, xdata); + + return 0; +} + + +int +mdc_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd, + const char *name, dict_t *xdata) +{ + mdc_local_t *local = NULL; + + local = mdc_local_get (frame); + + local->fd = fd_ref (fd); + + local->key = gf_strdup (name); + + STACK_WIND (frame, mdc_fremovexattr_cbk, + FIRST_CHILD(this), FIRST_CHILD(this)->fops->fremovexattr, + fd, name, xdata); return 0; } int mdc_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int op_ret, int op_errno, gf_dirent_t *entries) + int op_ret, int op_errno, gf_dirent_t *entries, dict_t *xdata) { gf_dirent_t *entry = NULL; @@ -1636,40 +1955,187 @@ mdc_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } unwind: - STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries); + STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries, xdata); return 0; } int mdc_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, - size_t size, off_t offset, dict_t *xattr_req) + size_t size, off_t offset, dict_t *xdata) { + dict_t *xattr_alloc = NULL; + + if (!xdata) + xdata = xattr_alloc = dict_new (); + if (xdata) + mdc_load_reqs (this, xdata); + STACK_WIND (frame, mdc_readdirp_cbk, FIRST_CHILD (this), FIRST_CHILD (this)->fops->readdirp, - fd, size, offset, xattr_req); + fd, size, offset, xdata); + if (xattr_alloc) + dict_unref (xattr_alloc); return 0; } +int +mdc_readdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, + int op_errno, gf_dirent_t *entries, dict_t *xdata) +{ + STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, entries, xdata); + return 0; +} int mdc_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, - size_t size, off_t offset) + size_t size, off_t offset, dict_t *xdata) { - dict_t *xattr_req = NULL; - - xattr_req = dict_new (); + int need_unref = 0; + struct mdc_conf *conf = this->private; - if (xattr_req) { - mdc_load_reqs (this, xattr_req); + if (!conf->force_readdirp) { + STACK_WIND(frame, mdc_readdir_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->readdir, fd, size, offset, + xdata); + return 0; } - STACK_WIND (frame, mdc_readdirp_cbk, - FIRST_CHILD (this), FIRST_CHILD (this)->fops->readdirp, - fd, size, offset, xattr_req); + if (!xdata) { + xdata = dict_new (); + need_unref = 1; + } + + if (xdata) + mdc_load_reqs (this, xdata); + + STACK_WIND(frame, mdc_readdirp_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->readdirp, fd, size, offset, + xdata); + + if (need_unref && xdata) + dict_unref (xdata); + return 0; } +int +mdc_fallocate_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) +{ + mdc_local_t *local = NULL; + + local = frame->local; + + if (op_ret != 0) + goto out; + + if (!local) + goto out; + + mdc_inode_iatt_set_validate(this, local->fd->inode, prebuf, postbuf); + +out: + MDC_STACK_UNWIND (fallocate, frame, op_ret, op_errno, prebuf, postbuf, + xdata); + + return 0; +} + +int mdc_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, + off_t offset, size_t len, dict_t *xdata) +{ + mdc_local_t *local; + + local = mdc_local_get(frame); + local->fd = fd_ref(fd); + + STACK_WIND(frame, mdc_fallocate_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fallocate, fd, mode, offset, len, + xdata); + + return 0; +} + +int +mdc_discard_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) +{ + mdc_local_t *local = NULL; + + local = frame->local; + + if (op_ret != 0) + goto out; + + if (!local) + goto out; + + mdc_inode_iatt_set_validate(this, local->fd->inode, prebuf, postbuf); + +out: + MDC_STACK_UNWIND(discard, frame, op_ret, op_errno, prebuf, postbuf, + xdata); + + return 0; +} + +int mdc_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + size_t len, dict_t *xdata) +{ + mdc_local_t *local; + + local = mdc_local_get(frame); + local->fd = fd_ref(fd); + + STACK_WIND(frame, mdc_discard_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->discard, fd, offset, len, + xdata); + + return 0; +} + +int +mdc_zerofill_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) +{ + mdc_local_t *local = NULL; + + local = frame->local; + + if (op_ret != 0) + goto out; + + if (!local) + goto out; + + mdc_inode_iatt_set_validate(this, local->fd->inode, prebuf, postbuf); + +out: + MDC_STACK_UNWIND(zerofill, frame, op_ret, op_errno, prebuf, postbuf, + xdata); + + return 0; +} + +int mdc_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + size_t len, dict_t *xdata) +{ + mdc_local_t *local; + + local = mdc_local_get(frame); + local->fd = fd_ref(fd); + + STACK_WIND(frame, mdc_zerofill_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->zerofill, fd, offset, len, + xdata); + + return 0; +} + int mdc_forget (xlator_t *this, inode_t *inode) @@ -1681,13 +2147,51 @@ mdc_forget (xlator_t *this, inode_t *inode) int +is_strpfx (const char *str1, const char *str2) +{ + /* is one of the string a prefix of the other? */ + int i; + + for (i = 0; str1[i] == str2[i]; i++) { + if (!str1[i] || !str2[i]) + break; + } + + return !(str1[i] && str2[i]); +} + + +int +mdc_key_load_set (struct mdc_key *keys, char *pattern, gf_boolean_t val) +{ + struct mdc_key *key = NULL; + + for (key = keys; key->name; key++) { + if (is_strpfx (key->name, pattern)) + key->load = val; + } + + return 0; +} + + +int reconfigure (xlator_t *this, dict_t *options) { struct mdc_conf *conf = NULL; conf = this->private; - GF_OPTION_RECONF ("timeout", conf->timeout, options, int32, out); + GF_OPTION_RECONF ("md-cache-timeout", conf->timeout, options, int32, out); + + GF_OPTION_RECONF ("cache-selinux", conf->cache_selinux, options, bool, out); + mdc_key_load_set (mdc_keys, "security.", conf->cache_selinux); + + GF_OPTION_RECONF ("cache-posix-acl", conf->cache_posix_acl, options, bool, out); + mdc_key_load_set (mdc_keys, "system.posix_acl_", conf->cache_posix_acl); + + GF_OPTION_RECONF("force-readdirp", conf->force_readdirp, options, bool, out); + out: return 0; } @@ -1713,8 +2217,15 @@ init (xlator_t *this) return -1; } - GF_OPTION_INIT ("timeout", conf->timeout, int32, out); + GF_OPTION_INIT ("md-cache-timeout", conf->timeout, int32, out); + + GF_OPTION_INIT ("cache-selinux", conf->cache_selinux, bool, out); + mdc_key_load_set (mdc_keys, "security.", conf->cache_selinux); + GF_OPTION_INIT ("cache-posix-acl", conf->cache_posix_acl, bool, out); + mdc_key_load_set (mdc_keys, "system.posix_acl_", conf->cache_posix_acl); + + GF_OPTION_INIT("force-readdirp", conf->force_readdirp, bool, out); out: this->private = conf; @@ -1752,8 +2263,13 @@ struct xlator_fops fops = { .fsetxattr = mdc_fsetxattr, .getxattr = mdc_getxattr, .fgetxattr = mdc_fgetxattr, + .removexattr = mdc_removexattr, + .fremovexattr= mdc_fremovexattr, .readdirp = mdc_readdirp, - .readdir = mdc_readdir + .readdir = mdc_readdir, + .fallocate = mdc_fallocate, + .discard = mdc_discard, + .zerofill = mdc_zerofill, }; @@ -1762,11 +2278,26 @@ struct xlator_cbks cbks = { }; struct volume_options options[] = { - { .key = {"timeout"}, + { .key = {"cache-selinux"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "false", + }, + { .key = {"cache-posix-acl"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "false", + }, + { .key = {"md-cache-timeout"}, .type = GF_OPTION_TYPE_INT, .min = 0, .max = 60, .default_value = "1", .description = "Time period after which cache has to be refreshed", }, + { .key = {"force-readdirp"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "true", + .description = "Convert all readdir requests to readdirplus to " + "collect stat info on each entry.", + }, + { .key = {NULL} }, }; |
