cluster/afr: Handle REPLICATE_TRASH_DIR from old bricks
Change-Id: Ib99f79d3fa607c818dbc62006516480f598d8add BUG: 886998 Signed-off-by: Pranith Kumar K <pkarampu@redhat.com> Reviewed-on: http://review.gluster.org/4640 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com>
This commit is contained in:
parent
115f6a679b
commit
4944fc943e
@ -143,6 +143,7 @@
|
||||
ZR_FILE_CONTENT_STRLEN))
|
||||
|
||||
#define DEFAULT_VAR_RUN_DIRECTORY DATADIR "/run/gluster"
|
||||
#define GF_REPLICATE_TRASH_DIR ".landfill"
|
||||
|
||||
/* GlusterFS's maximum supported Auxilary GIDs */
|
||||
/* TODO: Keeping it to 200, so that we can fit in 2KB buffer for auth data
|
||||
|
@ -684,6 +684,17 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
gf_boolean_t
|
||||
loc_is_root (loc_t *loc)
|
||||
{
|
||||
if (loc && __is_root_gfid (loc->gfid)) {
|
||||
return _gf_true;
|
||||
} else if (loc && loc->inode && __is_root_gfid (loc->inode->gfid)) {
|
||||
return _gf_true;
|
||||
}
|
||||
return _gf_false;
|
||||
}
|
||||
|
||||
int
|
||||
xlator_list_destroy (xlator_list_t *list)
|
||||
{
|
||||
|
@ -922,6 +922,7 @@ void loc_wipe (loc_t *loc);
|
||||
int loc_path (loc_t *loc, const char *bname);
|
||||
void loc_gfid (loc_t *loc, uuid_t gfid);
|
||||
char* loc_gfid_utoa (loc_t *loc);
|
||||
gf_boolean_t loc_is_root (loc_t *loc);
|
||||
int xlator_mem_acct_init (xlator_t *xl, int num_types);
|
||||
int is_gf_log_command (xlator_t *trans, const char *name, char *value);
|
||||
int glusterd_check_log_level (const char *value);
|
||||
|
52
tests/bugs/bug-886998.t
Normal file
52
tests/bugs/bug-886998.t
Normal file
@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
|
||||
. $(dirname $0)/../include.rc
|
||||
. $(dirname $0)/../volume.rc
|
||||
|
||||
cleanup;
|
||||
|
||||
# This tests that the replicate trash directory(.landfill) has following
|
||||
# properties.
|
||||
# Note: This is to have backward compatibility with 3.3 glusterfs
|
||||
# In the latest releases this dir is present inside .glusterfs of brick.
|
||||
# 1) lookup of trash dir fails
|
||||
# 2) readdir does not show this directory
|
||||
# 3) Self-heal does not do any self-heal of these directories.
|
||||
gfid1="0xc2e75dde97f346e7842d1076a8e699f8"
|
||||
TEST glusterd
|
||||
TEST pidof glusterd
|
||||
TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}0 $H0:$B0/${V0}1
|
||||
TEST $CLI volume start $V0
|
||||
TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --attribute-timeout=0 --entry-timeout=0 --direct-io-mode=enable
|
||||
|
||||
TEST mkdir $B0/${V0}1/.landfill
|
||||
TEST setfattr -n trusted.gfid -v $gfid1 $B0/${V0}1/.landfill
|
||||
TEST mkdir $B0/${V0}0/.landfill
|
||||
TEST setfattr -n trusted.gfid -v $gfid1 $B0/${V0}0/.landfill
|
||||
|
||||
TEST ! stat $M0/.landfill
|
||||
EXPECT "" echo $(ls -a $M0 | grep ".landfill")
|
||||
|
||||
TEST rmdir $B0/${V0}0/.landfill
|
||||
#Force a conservative merge and it should not create .landfill
|
||||
TEST setfattr -n trusted.afr.$V0-client-0 -v 0x000000000000000000000000 $B0/${V0}0/
|
||||
TEST setfattr -n trusted.afr.$V0-client-1 -v 0x000000000000000000000001 $B0/${V0}0/
|
||||
|
||||
TEST setfattr -n trusted.afr.$V0-client-0 -v 0x000000000000000000000001 $B0/${V0}1/
|
||||
TEST setfattr -n trusted.afr.$V0-client-1 -v 0x000000000000000000000000 $B0/${V0}1/
|
||||
|
||||
EXPECT "" echo $(ls -a $M0 | grep ".landfill")
|
||||
TEST ! stat $B0/${V0}0/.landfill
|
||||
TEST stat $B0/${V0}1/.landfill
|
||||
|
||||
#TEST that the dir is not deleted even when xattrs suggest to delete
|
||||
TEST setfattr -n trusted.afr.$V0-client-0 -v 0x000000000000000000000000 $B0/${V0}0/
|
||||
TEST setfattr -n trusted.afr.$V0-client-1 -v 0x000000000000000000000001 $B0/${V0}0/
|
||||
|
||||
TEST setfattr -n trusted.afr.$V0-client-0 -v 0x000000000000000000000000 $B0/${V0}1/
|
||||
TEST setfattr -n trusted.afr.$V0-client-1 -v 0x000000000000000000000000 $B0/${V0}1/
|
||||
|
||||
EXPECT "" echo $(ls -a $M0 | grep ".landfill")
|
||||
TEST ! stat $B0/${V0}0/.landfill
|
||||
TEST stat $B0/${V0}1/.landfill
|
||||
cleanup;
|
@ -2351,6 +2351,13 @@ afr_lookup (call_frame_t *frame, xlator_t *this,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (local->loc.path &&
|
||||
(strcmp (local->loc.path, "/" GF_REPLICATE_TRASH_DIR) == 0)) {
|
||||
op_errno = EPERM;
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = inode_ctx_get (local->loc.inode, this, &ctx);
|
||||
if (ret == 0) {
|
||||
/* lookup is a revalidate */
|
||||
|
@ -383,14 +383,36 @@ afr_forget_entries (fd_t *fd)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
afr_readdir_filter_trash_dir (gf_dirent_t *entries, fd_t *fd)
|
||||
{
|
||||
gf_dirent_t * entry = NULL;
|
||||
gf_dirent_t * tmp = NULL;
|
||||
|
||||
list_for_each_entry_safe (entry, tmp, &entries->list, list) {
|
||||
if (__is_root_gfid (fd->inode->gfid) &&
|
||||
!strcmp (entry->d_name, GF_REPLICATE_TRASH_DIR)) {
|
||||
list_del_init (&entry->list);
|
||||
GF_FREE (entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t
|
||||
afr_readdir_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)
|
||||
{
|
||||
afr_local_t *local = NULL;
|
||||
|
||||
if (op_ret == -1)
|
||||
goto out;
|
||||
|
||||
local = frame->local;
|
||||
afr_readdir_filter_trash_dir (entries, local->fd);
|
||||
AFR_STACK_UNWIND (readdir, frame, op_ret, op_errno, entries, NULL);
|
||||
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -400,8 +422,16 @@ afr_readdirp_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)
|
||||
{
|
||||
afr_local_t *local = NULL;
|
||||
|
||||
if (op_ret == -1)
|
||||
goto out;
|
||||
|
||||
local = frame->local;
|
||||
afr_readdir_filter_trash_dir (entries, local->fd);
|
||||
AFR_STACK_UNWIND (readdirp, frame, op_ret, op_errno, entries, NULL);
|
||||
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -613,6 +613,19 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gf_boolean_t
|
||||
can_skip_entry_self_heal (char *name, loc_t *parent_loc)
|
||||
{
|
||||
if (strcmp (name, ".") == 0) {
|
||||
return _gf_true;
|
||||
} else if (strcmp (name, "..") == 0) {
|
||||
return _gf_true;
|
||||
} else if (loc_is_root (parent_loc) &&
|
||||
(strcmp (name, GF_REPLICATE_TRASH_DIR) == 0)) {
|
||||
return _gf_true;
|
||||
}
|
||||
return _gf_false;
|
||||
}
|
||||
|
||||
int
|
||||
afr_sh_entry_expunge_entry (call_frame_t *frame, xlator_t *this,
|
||||
@ -640,13 +653,7 @@ afr_sh_entry_expunge_entry (call_frame_t *frame, xlator_t *this,
|
||||
sh->expunge_done = afr_sh_entry_expunge_entry_done;
|
||||
|
||||
name = entry->d_name;
|
||||
|
||||
if ((strcmp (name, ".") == 0)
|
||||
|| (strcmp (name, "..") == 0)) {
|
||||
|
||||
gf_log (this->name, GF_LOG_TRACE,
|
||||
"skipping inspection of %s under %s",
|
||||
name, local->loc.path);
|
||||
if (can_skip_entry_self_heal (name, &local->loc)) {
|
||||
op_ret = 0;
|
||||
goto out;
|
||||
}
|
||||
@ -1901,12 +1908,7 @@ afr_sh_entry_impunge_entry (call_frame_t *frame, xlator_t *this,
|
||||
active_src = sh->active_source;
|
||||
sh->impunge_done = afr_sh_entry_impunge_entry_done;
|
||||
|
||||
if ((strcmp (entry->d_name, ".") == 0)
|
||||
|| (strcmp (entry->d_name, "..") == 0)) {
|
||||
|
||||
gf_log (this->name, GF_LOG_TRACE,
|
||||
"skipping inspection of %s under %s",
|
||||
entry->d_name, local->loc.path);
|
||||
if (can_skip_entry_self_heal (entry->d_name, &local->loc)) {
|
||||
op_ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user