summaryrefslogtreecommitdiffstats
path: root/xlators/features/quota/src/quota.c
diff options
context:
space:
mode:
authorRaghavendra Bhat <raghavendra@redhat.com>2016-03-14 15:10:17 -0400
committerRaghavendra G <rgowdapp@redhat.com>2016-03-26 09:33:48 -0700
commit06d50c1c00fe35c6bc2192a392b8a749984f3efc (patch)
treef9bd6219e456b3b580e7ff8b2a0ec3973161fd2c /xlators/features/quota/src/quota.c
parent351ec36e3146b7605334cb658927b447b1dbc796 (diff)
storage/posix: send proper iatt attributes for the root inode
* changes in posix to send proper iatt attributes for the root directory when ancestry is built. Before posix was filling only the gfid and the inode type in the iatt structure keeping rest of the fields zeros. This was cached by posix-acl and used to send EACCES when some fops came on that object if the uid of the caller is same as the uid of the object on the disk. * getting and setting inode_ctx in function 'posix_acl_ctx_get' is not atomic and can lead to memory leak when there are multiple looups for an inode at same time. This patch fix this problem * Linking an inode in posix_build_ancestry, can cause a race in posix_acl. When parent inode is linked in posix_build_ancestry, and before it reaches posix_acl_readdirp_cbkc, reate/lookup can come on a leaf-inode, as parent-inode-ctx not yet updated in posix_acl_readdirp_cbk, create/lookup can fail with EACCESS. So do the inode linking in the quota xlator Change-Id: I3101eefb65551cc4162c4ff2963be1b73deacd6d BUG: 1320818 Signed-off-by: Raghavendra Bhat <raghavendra@redhat.com> Reviewed-on: http://review.gluster.org/13730 Tested-by: Vijaikumar Mallikarjuna <vmallika@redhat.com> Smoke: Gluster Build System <jenkins@build.gluster.com> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
Diffstat (limited to 'xlators/features/quota/src/quota.c')
-rw-r--r--xlators/features/quota/src/quota.c51
1 files changed, 36 insertions, 15 deletions
diff --git a/xlators/features/quota/src/quota.c b/xlators/features/quota/src/quota.c
index 105d70cbea6..847c93f37c0 100644
--- a/xlators/features/quota/src/quota.c
+++ b/xlators/features/quota/src/quota.c
@@ -737,13 +737,17 @@ quota_build_ancestry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
gf_dirent_t *entries, dict_t *xdata)
{
- inode_t *parent = NULL, *tmp_parent = NULL;
- gf_dirent_t *entry = NULL;
- loc_t loc = {0, };
- quota_dentry_t *dentry = NULL, *tmp = NULL;
- quota_inode_ctx_t *ctx = NULL;
- struct list_head parents = {0, };
- quota_local_t *local = NULL;
+ inode_t *parent = NULL;
+ inode_t *tmp_parent = NULL;
+ inode_t *linked_inode = NULL;
+ inode_t *tmp_inode = NULL;
+ gf_dirent_t *entry = NULL;
+ loc_t loc = {0, };
+ quota_dentry_t *dentry = NULL;
+ quota_dentry_t *tmp = NULL;
+ quota_inode_ctx_t *ctx = NULL;
+ struct list_head parents = {0, };
+ quota_local_t *local = NULL;
INIT_LIST_HEAD (&parents);
@@ -753,14 +757,6 @@ quota_build_ancestry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret < 0)
goto err;
- parent = inode_parent (local->loc.inode, 0, NULL);
- if (parent == NULL) {
- gf_msg (this->name, GF_LOG_WARNING, EINVAL,
- Q_MSG_PARENT_NULL, "parent is NULL");
- op_errno = EINVAL;
- goto err;
- }
-
if ((op_ret > 0) && (entries != NULL)) {
list_for_each_entry (entry, &entries->list, list) {
if (__is_root_gfid (entry->inode->gfid)) {
@@ -776,6 +772,23 @@ quota_build_ancestry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
*/
tmp_parent = NULL;
+ } else {
+ /* For a non-root entry, link this inode */
+ linked_inode = inode_link (entry->inode,
+ tmp_parent,
+ entry->d_name,
+ &entry->d_stat);
+ if (linked_inode) {
+ tmp_inode = entry->inode;
+ entry->inode = linked_inode;
+ inode_unref (tmp_inode);
+ } else {
+ gf_msg (this->name, GF_LOG_WARNING,
+ EINVAL, Q_MSG_PARENT_NULL,
+ "inode link failed");
+ op_errno = EINVAL;
+ goto err;
+ }
}
gf_uuid_copy (loc.gfid, entry->d_stat.ia_gfid);
@@ -793,6 +806,14 @@ quota_build_ancestry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
}
+ parent = inode_parent (local->loc.inode, 0, NULL);
+ if (parent == NULL) {
+ gf_msg (this->name, GF_LOG_WARNING, EINVAL,
+ Q_MSG_PARENT_NULL, "parent is NULL");
+ op_errno = EINVAL;
+ goto err;
+ }
+
quota_inode_ctx_get (local->loc.inode, this, &ctx, 0);
quota_add_parents_from_ctx (ctx, &parents);