diff options
| author | Krutika Dhananjay <kdhananj@redhat.com> | 2015-08-10 19:10:21 +0530 | 
|---|---|---|
| committer | Pranith Kumar Karampuri <pkarampu@redhat.com> | 2015-08-19 02:15:04 -0700 | 
| commit | 470a50b1d5017f015a1f3f3ea65a33902a02ffea (patch) | |
| tree | 4627307c0ce2c5d15da3d6655b5d2ead48166dc1 | |
| parent | a4bbb71e91744ed387606dd4eb5bee55cf86b079 (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.t | 61 | ||||
| -rw-r--r-- | xlators/features/shard/src/shard.c | 73 | ||||
| -rw-r--r-- | xlators/features/shard/src/shard.h | 3 | 
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;  | 
