summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrutika Dhananjay <kdhananj@redhat.com>2015-08-10 19:10:21 +0530
committerPranith Kumar Karampuri <pkarampu@redhat.com>2015-08-19 02:15:04 -0700
commit470a50b1d5017f015a1f3f3ea65a33902a02ffea (patch)
tree4627307c0ce2c5d15da3d6655b5d2ead48166dc1
parenta4bbb71e91744ed387606dd4eb5bee55cf86b079 (diff)
features/shard: Ensure shards are owned by the same owner/group as the original file
Change-Id: Id759af8f3ff5fd8bfa9f8121bab25722709d42b7 BUG: 1251824 Signed-off-by: Krutika Dhananjay <kdhananj@redhat.com> Reviewed-on: http://review.gluster.org/11874 Tested-by: NetBSD Build System <jenkins@build.gluster.org> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
-rw-r--r--tests/bugs/shard/bug-1251824.t61
-rw-r--r--xlators/features/shard/src/shard.c73
-rw-r--r--xlators/features/shard/src/shard.h3
3 files changed, 106 insertions, 31 deletions
diff --git a/tests/bugs/shard/bug-1251824.t b/tests/bugs/shard/bug-1251824.t
new file mode 100644
index 00000000000..71bfdc7fdae
--- /dev/null
+++ b/tests/bugs/shard/bug-1251824.t
@@ -0,0 +1,61 @@
+#!/bin/bash
+
+. $(dirname $0)/../../include.rc
+
+cleanup;
+
+TEST glusterd
+TEST pidof glusterd
+TEST $CLI volume create $V0 $H0:$B0/${V0}{0,1}
+TEST $CLI volume set $V0 features.shard on
+TEST $CLI volume start $V0
+
+TEST $GFS --volfile-id=$V0 --volfile-server=$H0 $M0
+TEST useradd -M test_user 2>/dev/null
+
+# Create 3 files as root.
+TEST touch $M0/foo
+TEST touch $M0/bar
+TEST touch $M0/baz
+
+# Change ownership to non-root on foo and bar.
+TEST chown test_user:test_user $M0/foo
+TEST chown test_user:test_user $M0/bar
+
+# Write 6M of data on foo as non-root, 2M overflowing into block-1.
+su -m test_user -c "dd if=/dev/zero of=$M0/foo bs=1M count=6"
+
+# Ensure owner and group are same on the shard as the main file.
+gfid_foo=`getfattr -n glusterfs.gfid.string $M0/foo 2>/dev/null \
+ | grep glusterfs.gfid.string | cut -d '"' -f 2`
+
+EXPECT "test_user" echo `find $B0 -name $gfid_foo.1 | xargs stat -c %U`
+EXPECT "test_user" echo `find $B0 -name $gfid_foo.1 | xargs stat -c %G`
+
+# Write 6M of data on bar as root.
+TEST dd if=/dev/zero of=$M0/bar bs=1M count=6
+
+# Ensure owner and group are same on the shard as the main file.
+gfid_bar=`getfattr -n glusterfs.gfid.string $M0/bar 2>/dev/null \
+ | grep glusterfs.gfid.string | cut -d '"' -f 2`
+
+EXPECT "test_user" echo `find $B0 -name $gfid_bar.1 | xargs stat -c %U`
+EXPECT "test_user" echo `find $B0 -name $gfid_bar.1 | xargs stat -c %G`
+
+# Write 6M of data on baz as root.
+TEST dd if=/dev/zero of=$M0/baz bs=1M count=6
+
+# Ensure owner andgroup are same on the shard as the main file.
+gfid_baz=`getfattr -n glusterfs.gfid.string $M0/baz 2>/dev/null \
+ | grep glusterfs.gfid.string | cut -d '"' -f 2`
+
+EXPECT "root" echo `find $B0 -name $gfid_baz.1 | xargs stat -c %U`
+EXPECT "root" echo `find $B0 -name $gfid_baz.1 | xargs stat -c %G`
+userdel test_user
+
+TEST umount $M0
+
+TEST $CLI volume stop $V0
+TEST $CLI volume delete $V0
+
+cleanup;
diff --git a/xlators/features/shard/src/shard.c b/xlators/features/shard/src/shard.c
index 52b95472ba7..ba1579f1170 100644
--- a/xlators/features/shard/src/shard.c
+++ b/xlators/features/shard/src/shard.c
@@ -2551,8 +2551,11 @@ shard_common_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
done:
call_count = shard_call_count_return (frame);
- if (call_count == 0)
+ if (call_count == 0) {
+ frame->root->uid = local->uid;
+ frame->root->gid = local->gid;
local->post_mknod_handler (frame, this);
+ }
return 0;
}
@@ -2581,9 +2584,14 @@ shard_common_resume_mknod (call_frame_t *frame, xlator_t *this,
fd = local->fd;
shard_idx_iter = local->first_block;
last_block = local->last_block;
- call_count = local->call_count;
+ call_count = local->call_count = local->create_count;
local->post_mknod_handler = post_mknod_handler;
+ local->uid = frame->root->uid;
+ local->gid = frame->root->gid;
+ frame->root->uid = local->prebuf.ia_uid;
+ frame->root->gid = local->prebuf.ia_gid;
+
ret = shard_inode_ctx_get_all (fd->inode, this, &ctx_tmp);
if (ret) {
gf_log (this->name, GF_LOG_ERROR, "Failed to get inode ctx for"
@@ -2697,11 +2705,13 @@ shard_post_resolve_readv_handler (call_frame_t *frame, xlator_t *this)
}
}
- if (local->call_count)
+ if (local->call_count) {
+ local->create_count = local->call_count;
shard_common_resume_mknod (frame, this,
shard_post_mknod_readv_handler);
- else
+ } else {
shard_readv_do (frame, this);
+ }
return 0;
}
@@ -3033,7 +3043,7 @@ next:
}
int
-shard_post_lookup_writev_handler (call_frame_t *frame, xlator_t *this)
+shard_post_lookup_shards_writev_handler (call_frame_t *frame, xlator_t *this)
{
shard_local_t *local = NULL;
@@ -3045,21 +3055,13 @@ shard_post_lookup_writev_handler (call_frame_t *frame, xlator_t *this)
return 0;
}
- local->postbuf = local->prebuf;
-
- /* At this point, calculate the size of the hole if it is going to be
- * created as part of this write.
- */
- if (local->offset > local->prebuf.ia_size)
- local->hole_size = local->offset - local->prebuf.ia_size;
-
shard_writev_do (frame, this);
return 0;
}
int
-shard_post_lookup_shards_writev_handler (call_frame_t *frame, xlator_t *this)
+shard_post_mknod_writev_handler (call_frame_t *frame, xlator_t *this)
{
shard_local_t *local = NULL;
@@ -3071,13 +3073,19 @@ shard_post_lookup_shards_writev_handler (call_frame_t *frame, xlator_t *this)
return 0;
}
- shard_lookup_base_file (frame, this, &local->loc,
- shard_post_lookup_writev_handler);
+ if (!local->eexist_count) {
+ shard_writev_do (frame, this);
+ } else {
+ local->call_count = local->eexist_count;
+ shard_common_lookup_shards (frame, this, local->loc.inode,
+ shard_post_lookup_shards_writev_handler);
+ }
+
return 0;
}
int
-shard_post_mknod_writev_handler (call_frame_t *frame, xlator_t *this)
+shard_post_lookup_writev_handler (call_frame_t *frame, xlator_t *this)
{
shard_local_t *local = NULL;
@@ -3089,14 +3097,19 @@ shard_post_mknod_writev_handler (call_frame_t *frame, xlator_t *this)
return 0;
}
- if (!local->eexist_count) {
- shard_lookup_base_file (frame, this, &local->loc,
- shard_post_lookup_writev_handler);
- } else {
- local->call_count = local->eexist_count;
- shard_common_lookup_shards (frame, this, local->loc.inode,
- shard_post_lookup_shards_writev_handler);
- }
+ local->postbuf = local->prebuf;
+
+ /* At this point, calculate the size of the hole if it is going to be
+ * created as part of this write.
+ */
+ if (local->offset > local->prebuf.ia_size)
+ local->hole_size = local->offset - local->prebuf.ia_size;
+
+ if (local->create_count)
+ shard_common_resume_mknod (frame, this,
+ shard_post_mknod_writev_handler);
+ else
+ shard_writev_do (frame, this);
return 0;
}
@@ -3114,12 +3127,10 @@ shard_post_resolve_writev_handler (call_frame_t *frame, xlator_t *this)
return 0;
}
- if (local->call_count)
- shard_common_resume_mknod (frame, this,
- shard_post_mknod_writev_handler);
- else
- shard_lookup_base_file (frame, this, &local->loc,
- shard_post_lookup_writev_handler);
+ local->create_count = local->call_count;
+
+ shard_lookup_base_file (frame, this, &local->loc,
+ shard_post_lookup_writev_handler);
return 0;
}
diff --git a/xlators/features/shard/src/shard.h b/xlators/features/shard/src/shard.h
index 2e2b3abd593..61255cd4936 100644
--- a/xlators/features/shard/src/shard.h
+++ b/xlators/features/shard/src/shard.h
@@ -144,9 +144,12 @@ typedef struct shard_local {
int num_blocks;
int call_count;
int eexist_count;
+ int create_count;
int xflag;
int count;
uint32_t flags;
+ uint32_t uid;
+ uint32_t gid;
uint64_t block_size;
uint64_t dst_block_size;
off_t offset;