tier:unlink during migration

files deleted during promotion were not deleting as the
files are moving from hashed to non-hashed.

On deleting a file that is undergoing promotion,
the unlink call is not sent to the dst file as the
hashed subvol == cached subvol. This causes
the file to reappear once the migration is complete.

This patch also fixes a problem with stale linkfile
deleting.

Change-Id: I4b02a498218c9d8eeaa4556fa4219e91e7fa71e5
BUG: 1282390
Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com>
Reviewed-on: http://review.gluster.org/12829
Tested-by: NetBSD Build System <jenkins@build.gluster.org>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Dan Lambright <dlambrig@redhat.com>
Tested-by: Dan Lambright <dlambrig@redhat.com>
This commit is contained in:
Mohammed Rafi KC 2015-11-30 19:02:54 +05:30 committed by Dan Lambright
parent 27c16d6da8
commit b5de382afa
9 changed files with 594 additions and 146 deletions

View File

@ -235,6 +235,7 @@
#define DHT_COMMITHASH_STR "commithash"
#define DHT_SKIP_NON_LINKTO_UNLINK "unlink-only-if-dht-linkto-file"
#define TIER_SKIP_NON_LINKTO_UNLINK "unlink-only-if-tier-linkto-file"
#define DHT_SKIP_OPEN_FD_UNLINK "dont-unlink-for-open-fd"
#define DHT_IATT_IN_XDATA_KEY "dht-get-iatt-in-xattr"

View File

@ -0,0 +1,91 @@
#!/bin/bash
. $(dirname $0)/../../include.rc
. $(dirname $0)/../../volume.rc
. $(dirname $0)/../../tier.rc
DEMOTE_FREQ=5
PROMOTE_FREQ=5
function create_dist_rep_vol () {
mkdir $B0/cold
mkdir $B0/hot
TEST $CLI volume create $V0 replica 2 $H0:$B0/cold/${V0}{0..3}
TEST $CLI volume set $V0 performance.quick-read off
TEST $CLI volume set $V0 performance.io-cache off
TEST $CLI volume set $V0 features.ctr-enabled on
TEST $CLI volume start $V0
}
function attach_dist_rep_tier () {
TEST $CLI volume attach-tier $V0 replica 2 $H0:$B0/hot/${V0}{0..3}
TEST $CLI volume set $V0 cluster.tier-demote-frequency $DEMOTE_FREQ
TEST $CLI volume set $V0 cluster.tier-promote-frequency $PROMOTE_FREQ
TEST $CLI volume set $V0 cluster.read-freq-threshold 0
TEST $CLI volume set $V0 cluster.write-freq-threshold 0
TEST $CLI volume set $V0 cluster.tier-mode test
}
cleanup;
#Basic checks
TEST glusterd
TEST pidof glusterd
TEST $CLI volume info
#Create and start a volume
create_dist_rep_vol
# Mount FUSE
TEST glusterfs -s $H0 --volfile-id $V0 $M0
# Create a large file (320MB), so that rebalance takes time
TEST dd if=/dev/zero of=$M0/foo bs=64k count=5120
# Get the path of the file on the cold tier
CPATH=`find $B0/cold/ -name foo`
echo "File path on cold tier: "$CPATH
#Now attach the tier
attach_dist_rep_tier
#Write into the file to promote it
echo "good morning">>$M0/foo
# Wait for the tier process to promote the file
EXPECT_WITHIN $REBALANCE_TIMEOUT "yes" is_sticky_set $CPATH
# Get the path of the file on the hot tier
HPATH=`find $B0/hot/ -name foo`
echo "File path on hot tier: "$HPATH
TEST rm -rf $M0/foo
TEST ! stat $HPATH
TEST ! stat $CPATH
#unlink during demotion
HPATH="";
CPATH="";
# Create a large file (320MB), so that rebalance takes time
TEST dd if=/dev/zero of=$M0/foo1 bs=64k count=5120
# Get the path of the file on the hot tier
HPATH=`find $B0/hot/ -name foo1`
echo "File path on hot tier : "$HPATH
EXPECT_WITHIN $REBALANCE_TIMEOUT "yes" is_sticky_set $HPATH
# Get the path of the file on the cold tier
CPATH=`find $B0/cold/ -name foo1`
echo "File path on cold tier : "$CPATH
TEST rm -rf $M0/foo1
TEST ! stat $HPATH
TEST ! stat $CPATH
cleanup;

View File

@ -1163,9 +1163,19 @@ dht_lookup_unlink_stale_linkto_cbk (call_frame_t *frame, void *cookie,
int
dht_fill_dict_to_avoid_unlink_of_migrating_file (dict_t *dict) {
int ret = 0;
int ret = 0;
xlator_t *this = NULL;
char *linktoskip_key = NULL;
ret = dict_set_int32 (dict, DHT_SKIP_NON_LINKTO_UNLINK, 1);
this = THIS;
GF_VALIDATE_OR_GOTO ("dht", this, err);
if (dht_is_tier_xlator (this))
linktoskip_key = TIER_SKIP_NON_LINKTO_UNLINK;
else
linktoskip_key = DHT_SKIP_NON_LINKTO_UNLINK;
ret = dict_set_int32 (dict, linktoskip_key, 1);
if (ret)
goto err;
@ -2427,60 +2437,13 @@ err:
return 0;
}
int
dht_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, struct iatt *preparent,
struct iatt *postparent, dict_t *xdata)
{
dht_local_t *local = NULL;
call_frame_t *prev = NULL;
local = frame->local;
prev = cookie;
LOCK (&frame->lock);
{
if (op_ret == -1) {
local->op_ret = -1;
local->op_errno = op_errno;
gf_msg_debug (this->name, op_errno,
"Unlink: subvolume %s returned -1",
prev->this->name);
goto unlock;
}
local->op_ret = 0;
local->postparent = *postparent;
local->preparent = *preparent;
if (local->loc.parent) {
dht_inode_ctx_time_update (local->loc.parent, this,
&local->preparent, 0);
dht_inode_ctx_time_update (local->loc.parent, this,
&local->postparent, 1);
}
}
unlock:
UNLOCK (&frame->lock);
DHT_STACK_UNWIND (unlink, frame, local->op_ret, local->op_errno,
&local->preparent, &local->postparent, NULL);
return 0;
}
int
dht_unlink_linkfile_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, struct iatt *preparent,
struct iatt *postparent, dict_t *xdata)
{
dht_local_t *local = NULL;
call_frame_t *prev = NULL;
xlator_t *cached_subvol = NULL;
dht_local_t *local = NULL;
call_frame_t *prev = NULL;
local = frame->local;
prev = cookie;
@ -2502,27 +2465,75 @@ dht_unlink_linkfile_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
unlock:
UNLOCK (&frame->lock);
if (local->op_ret == -1)
goto err;
cached_subvol = dht_subvol_get_cached (this, local->loc.inode);
if (!cached_subvol) {
gf_msg_debug (this->name, 0,
"no cached subvolume for path=%s",
local->loc.path);
local->op_errno = EINVAL;
goto err;
}
STACK_WIND (frame, dht_unlink_cbk,
cached_subvol, cached_subvol->fops->unlink,
&local->loc, local->flags, NULL);
DHT_STACK_UNWIND (unlink, frame, local->op_ret, local->op_errno,
&local->preparent, &local->postparent, xdata);
return 0;
}
int
dht_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, struct iatt *preparent,
struct iatt *postparent, dict_t *xdata)
{
dht_local_t *local = NULL;
call_frame_t *prev = NULL;
xlator_t *hashed_subvol = NULL;
local = frame->local;
prev = cookie;
LOCK (&frame->lock);
{
if (op_ret == -1) {
if (op_errno != ENOENT) {
local->op_ret = -1;
local->op_errno = op_errno;
} else {
local->op_ret = 0;
}
gf_msg_debug (this->name, op_errno,
"Unlink: subvolume %s returned -1",
prev->this->name);
goto unlock;
}
local->op_ret = 0;
local->postparent = *postparent;
local->preparent = *preparent;
if (local->loc.parent) {
dht_inode_ctx_time_update (local->loc.parent, this,
&local->preparent, 0);
dht_inode_ctx_time_update (local->loc.parent, this,
&local->postparent, 1);
}
}
unlock:
UNLOCK (&frame->lock);
if (!local->op_ret) {
hashed_subvol = dht_subvol_get_hashed (this, &local->loc);
if (hashed_subvol &&
hashed_subvol != local->cached_subvol) {
/*
* If hashed and cached are different, then we need
* to unlink linkfile from hashed subvol if data
* file is deleted successfully
*/
STACK_WIND (frame, dht_unlink_linkfile_cbk,
hashed_subvol,
hashed_subvol->fops->unlink, &local->loc,
local->flags, xdata);
return 0;
}
}
DHT_STACK_UNWIND (unlink, frame, local->op_ret, local->op_errno,
&local->preparent, &local->postparent, xdata);
err:
DHT_STACK_UNWIND (unlink, frame, -1, local->op_errno,
NULL, NULL, NULL);
return 0;
}
@ -5608,7 +5619,6 @@ dht_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
dict_t *xdata)
{
xlator_t *cached_subvol = NULL;
xlator_t *hashed_subvol = NULL;
int op_errno = -1;
dht_local_t *local = NULL;
@ -5623,15 +5633,6 @@ dht_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
goto err;
}
hashed_subvol = dht_subvol_get_hashed (this, loc);
/* Dont fail unlink if hashed_subvol is NULL which can be the result
* of layout anomaly */
if (!hashed_subvol) {
gf_msg_debug (this->name, 0,
"no subvolume in layout for path=%s",
loc->path);
}
cached_subvol = local->cached_subvol;
if (!cached_subvol) {
gf_msg_debug (this->name, 0,
@ -5641,15 +5642,9 @@ dht_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
}
local->flags = xflag;
if (hashed_subvol && hashed_subvol != cached_subvol) {
STACK_WIND (frame, dht_unlink_linkfile_cbk,
hashed_subvol, hashed_subvol->fops->unlink, loc,
xflag, xdata);
} else {
STACK_WIND (frame, dht_unlink_cbk,
cached_subvol, cached_subvol->fops->unlink, loc,
xflag, xdata);
}
STACK_WIND (frame, dht_unlink_cbk,
cached_subvol, cached_subvol->fops->unlink, loc,
xflag, xdata);
return 0;
err:
@ -8121,3 +8116,11 @@ int32_t dht_set_local_rebalance (xlator_t *this, dht_local_t *local,
return 0;
}
gf_boolean_t
dht_is_tier_xlator (xlator_t *this)
{
if (strcmp (this->type, "cluster/tier") == 0)
return _gf_true;
return _gf_false;
}

View File

@ -1117,6 +1117,9 @@ dht_layout_missing_dirs (dht_layout_t *layout);
int
dht_refresh_layout (call_frame_t *frame);
gf_boolean_t
dht_is_tier_xlator (xlator_t *this);
int
dht_build_parent_loc (xlator_t *this, loc_t *parent, loc_t *child,
int32_t *op_errno);

View File

@ -16,6 +16,302 @@
#include "tier-common.h"
#include "tier.h"
int
tier_unlink_nonhashed_linkfile_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int op_ret, int op_errno,
struct iatt *preparent,
struct iatt *postparent, dict_t *xdata)
{
dht_local_t *local = NULL;
call_frame_t *prev = NULL;
local = frame->local;
prev = cookie;
LOCK (&frame->lock);
{
if ((op_ret == -1) && (op_errno != ENOENT)) {
local->op_errno = op_errno;
local->op_ret = op_ret;
gf_msg_debug (this->name, op_errno,
"Unlink link: subvolume %s"
" returned -1",
prev->this->name);
goto unlock;
}
local->op_ret = 0;
}
unlock:
UNLOCK (&frame->lock);
if (local->op_ret == -1)
goto err;
DHT_STACK_UNWIND (unlink, frame, local->op_ret, local->op_errno,
&local->preparent, &local->postparent, NULL);
return 0;
err:
DHT_STACK_UNWIND (unlink, frame, -1, local->op_errno,
NULL, NULL, NULL);
return 0;
}
int
tier_unlink_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, inode_t *inode,
struct iatt *preparent, dict_t *xdata,
struct iatt *postparent)
{
dht_local_t *local = NULL;
call_frame_t *prev = NULL;
dht_conf_t *conf = NULL;
xlator_t *hot_subvol = NULL;
local = frame->local;
prev = cookie;
conf = this->private;
hot_subvol = TIER_UNHASHED_SUBVOL;
if (!op_ret) {
/*
* linkfile present on hot tier. unlinking the linkfile
*/
STACK_WIND (frame, tier_unlink_nonhashed_linkfile_cbk,
hot_subvol, hot_subvol->fops->unlink,
&local->loc, local->flags, NULL);
return 0;
}
LOCK (&frame->lock);
{
if (op_errno == ENOENT) {
local->op_ret = 0;
local->op_errno = op_errno;
} else {
local->op_ret = op_ret;
local->op_errno = op_errno;
}
gf_msg_debug (this->name, op_errno,
"Lookup : subvolume %s returned -1",
prev->this->name);
}
UNLOCK (&frame->lock);
DHT_STACK_UNWIND (unlink, frame, local->op_ret, local->op_errno,
&local->preparent, &local->postparent, xdata);
return 0;
}
int
tier_unlink_linkfile_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, struct iatt *preparent,
struct iatt *postparent, dict_t *xdata)
{
dht_local_t *local = NULL;
call_frame_t *prev = NULL;
local = frame->local;
prev = cookie;
LOCK (&frame->lock);
{
/* Ignore EINVAL for tier to ignore error when the file
does not exist on the other tier */
if ((op_ret == -1) && !((op_errno == ENOENT) ||
(op_errno == EINVAL))) {
local->op_errno = op_errno;
local->op_ret = op_ret;
gf_msg_debug (this->name, op_errno,
"Unlink link: subvolume %s"
" returned -1",
prev->this->name);
goto unlock;
}
local->op_ret = 0;
}
unlock:
UNLOCK (&frame->lock);
if (local->op_ret == -1)
goto err;
DHT_STACK_UNWIND (unlink, frame, local->op_ret, local->op_errno,
&local->preparent, &local->postparent, xdata);
return 0;
err:
DHT_STACK_UNWIND (unlink, frame, -1, local->op_errno,
NULL, NULL, NULL);
return 0;
}
int32_t
tier_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, struct iatt *preparent,
struct iatt *postparent, dict_t *xdata)
{
dht_local_t *local = NULL;
call_frame_t *prev = NULL;
struct iatt *stbuf = NULL;
dht_conf_t *conf = NULL;
int ret = -1;
xlator_t *hot_tier = NULL;
xlator_t *cold_tier = NULL;
local = frame->local;
prev = cookie;
conf = this->private;
cold_tier = TIER_HASHED_SUBVOL;
hot_tier = TIER_UNHASHED_SUBVOL;
LOCK (&frame->lock);
{
if (op_ret == -1) {
if (op_errno == ENOENT) {
local->op_ret = 0;
} else {
local->op_ret = -1;
local->op_errno = op_errno;
}
gf_msg_debug (this->name, op_errno,
"Unlink: subvolume %s returned -1"
" with errno = %d",
prev->this->name, op_errno);
goto unlock;
}
local->op_ret = 0;
local->postparent = *postparent;
local->preparent = *preparent;
if (local->loc.parent) {
dht_inode_ctx_time_update (local->loc.parent, this,
&local->preparent, 0);
dht_inode_ctx_time_update (local->loc.parent, this,
&local->postparent, 1);
}
}
unlock:
UNLOCK (&frame->lock);
if (local->op_ret)
goto out;
if (cold_tier != local->cached_subvol) {
/*
* File is present in hot tier, so there will be
* a link file on cold tier, deleting the linkfile
* from cold tier
*/
STACK_WIND (frame, tier_unlink_linkfile_cbk,
cold_tier,
cold_tier->fops->unlink, &local->loc,
local->flags, xdata);
return 0;
}
ret = dict_get_bin (xdata, DHT_IATT_IN_XDATA_KEY, (void **) &stbuf);
if (!ret && stbuf && ((IS_DHT_MIGRATION_PHASE2 (stbuf)) ||
IS_DHT_MIGRATION_PHASE1 (stbuf))) {
/*
* File is migrating from cold to hot tier.
* Delete the destination linkfile.
*/
STACK_WIND (frame, tier_unlink_lookup_cbk,
hot_tier,
hot_tier->fops->lookup,
&local->loc, NULL);
return 0;
}
out:
DHT_STACK_UNWIND (unlink, frame, local->op_ret, local->op_errno,
&local->preparent, &local->postparent, xdata);
return 0;
}
int
tier_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
dict_t *xdata)
{
xlator_t *cached_subvol = NULL;
xlator_t *hashed_subvol = NULL;
dht_conf_t *conf = NULL;
int op_errno = -1;
dht_local_t *local = NULL;
int ret = -1;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
VALIDATE_OR_GOTO (loc, err);
conf = this->private;
local = dht_local_init (frame, loc, NULL, GF_FOP_UNLINK);
if (!local) {
op_errno = ENOMEM;
goto err;
}
hashed_subvol = TIER_HASHED_SUBVOL;
cached_subvol = local->cached_subvol;
if (!cached_subvol) {
gf_msg_debug (this->name, 0,
"no cached subvolume for path=%s", loc->path);
op_errno = EINVAL;
goto err;
}
local->flags = xflag;
if (hashed_subvol == cached_subvol) {
/*
* File resides in cold tier. We need to stat
* the file to see if it is being promoted.
* If yes we need to delete the destination
* file as well.
*/
xdata = xdata ? dict_ref (xdata) : dict_new ();
if (xdata) {
ret = dict_set_dynstr_with_alloc (xdata,
DHT_IATT_IN_XDATA_KEY, "yes");
if (ret) {
gf_msg_debug (this->name, 0,
"Failed to set dictionary key %s",
DHT_IATT_IN_XDATA_KEY);
}
}
}
/*
* File is on hot tier, delete the data file first, then
* linkfile from cold.
*/
STACK_WIND (frame, tier_unlink_cbk,
cached_subvol, cached_subvol->fops->unlink, loc,
xflag, xdata);
if (xdata)
dict_unref (xdata);
return 0;
err:
op_errno = (op_errno == -1) ? errno : op_errno;
DHT_STACK_UNWIND (unlink, frame, -1, op_errno, NULL, NULL, NULL);
return 0;
}
int
tier_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, gf_dirent_t *orig_entries,

View File

@ -10,6 +10,11 @@
#ifndef _TIER_COMMON_H_
#define _TIER_COMMON_H_
/* Function definitions */
int32_t
tier_unlink (call_frame_t *frame, xlator_t *this,
loc_t *loc, int xflag, dict_t *xdata);
int32_t
tier_readdirp (call_frame_t *frame,

View File

@ -1986,7 +1986,7 @@ struct xlator_fops fops = {
.readdirp = tier_readdirp,
.fsyncdir = dht_fsyncdir,
.symlink = dht_symlink,
.unlink = dht_unlink,
.unlink = tier_unlink,
.link = dht_link,
.mkdir = dht_mkdir,
.rmdir = dht_rmdir,

View File

@ -1579,6 +1579,66 @@ err:
return -1;
}
static
int32_t posix_set_iatt_in_dict (dict_t *dict, struct iatt *in_stbuf)
{
int ret = -1;
struct iatt *stbuf = NULL;
int32_t len = sizeof(struct iatt);
if (!dict || !in_stbuf)
return ret;
stbuf = GF_CALLOC (1, len, gf_common_mt_char);
if (!stbuf)
return ret;
memcpy (stbuf, in_stbuf, len);
ret = dict_set_bin (dict, DHT_IATT_IN_XDATA_KEY, stbuf, len);
if (ret)
GF_FREE (stbuf);
return ret;
}
gf_boolean_t
posix_skip_non_linkto_unlink (dict_t *xdata, loc_t *loc, char *key,
const char *linkto_xattr, struct iatt *stbuf,
const char *real_path)
{
gf_boolean_t skip_unlink = _gf_false;
gf_boolean_t is_dht_linkto_file = _gf_false;
int unlink_if_linkto = 0;
ssize_t xattr_size = -1;
int op_ret = -1;
op_ret = dict_get_int32 (xdata, key,
&unlink_if_linkto);
if (!op_ret && unlink_if_linkto) {
is_dht_linkto_file = IS_DHT_LINKFILE_MODE (stbuf);
if (!is_dht_linkto_file)
return _gf_true;
LOCK (&loc->inode->lock);
xattr_size = sys_lgetxattr (real_path, linkto_xattr, NULL, 0);
if (xattr_size <= 0)
skip_unlink = _gf_true;
UNLOCK (&loc->inode->lock);
gf_msg ("posix", GF_LOG_INFO, 0, P_MSG_XATTR_STATUS,
"linkto_xattr status: %"PRIu32" for %s", skip_unlink,
real_path);
}
return skip_unlink;
}
int32_t
posix_unlink (call_frame_t *frame, xlator_t *this,
loc_t *loc, int xflag, dict_t *xdata)
@ -1589,6 +1649,7 @@ posix_unlink (call_frame_t *frame, xlator_t *this,
char *par_path = NULL;
int32_t fd = -1;
struct iatt stbuf = {0,};
struct iatt postbuf = {0,};
struct posix_private *priv = NULL;
struct iatt preparent = {0,};
struct iatt postparent = {0,};
@ -1597,6 +1658,7 @@ posix_unlink (call_frame_t *frame, xlator_t *this,
int32_t unlink_if_linkto = 0;
int32_t check_open_fd = 0;
int32_t skip_unlink = 0;
int32_t fdstat_requested = 0;
int32_t ctr_link_req = 0;
ssize_t xattr_size = -1;
int32_t is_dht_linkto_file = 0;
@ -1650,40 +1712,30 @@ posix_unlink (call_frame_t *frame, xlator_t *this,
goto out;
}
}
op_ret = dict_get_int32 (xdata, DHT_SKIP_NON_LINKTO_UNLINK,
&unlink_if_linkto);
if (!op_ret && unlink_if_linkto) {
LOCK (&loc->inode->lock);
xattr_size = sys_lgetxattr (real_path, LINKTO, NULL, 0);
if (xattr_size <= 0) {
skip_unlink = 1;
} else {
is_dht_linkto_file = IS_DHT_LINKFILE_MODE (&stbuf);
if (!is_dht_linkto_file)
skip_unlink = 1;
}
UNLOCK (&loc->inode->lock);
gf_msg (this->name, GF_LOG_INFO, 0, P_MSG_XATTR_STATUS,
"linkto_xattr status: %"PRIu32" for %s", skip_unlink,
real_path);
if (skip_unlink) {
op_ret = -1;
op_errno = EBUSY;
goto out;
}
/*
* If either of the function return true, skip_unlink.
* If first first function itself return true,
* we don't need to call second function, skip unlink.
*/
skip_unlink = posix_skip_non_linkto_unlink (xdata, loc,
DHT_SKIP_NON_LINKTO_UNLINK,
DHT_LINKTO, &stbuf,
real_path);
skip_unlink = skip_unlink || posix_skip_non_linkto_unlink (xdata, loc,
TIER_SKIP_NON_LINKTO_UNLINK,
TIER_LINKTO, &stbuf,
real_path);
if (skip_unlink) {
op_ret = -1;
op_errno = EBUSY;
goto out;
}
if (xdata && dict_get (xdata, DHT_IATT_IN_XDATA_KEY)) {
fdstat_requested = 1;
}
if (priv->background_unlink) {
if (priv->background_unlink || fdstat_requested) {
if (IA_ISREG (loc->inode->ia_type)) {
fd = open (real_path, O_RDONLY);
if (fd == -1) {
@ -1726,6 +1778,24 @@ posix_unlink (call_frame_t *frame, xlator_t *this,
goto out;
}
unwind_dict = dict_new ();
if (!unwind_dict) {
op_errno = -ENOMEM;
op_ret = -1;
goto out;
}
if (fdstat_requested) {
op_ret = posix_fdstat (this, fd, &postbuf);
if (op_ret == -1) {
op_errno = errno;
gf_msg (this->name, GF_LOG_ERROR, errno,
P_MSG_FSTAT_FAILED, "post operation "
"fstat failed on fd=%d", fd);
goto out;
}
op_ret = posix_set_iatt_in_dict (unwind_dict, &postbuf);
}
op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent);
if (op_ret == -1) {
op_errno = errno;
@ -1735,7 +1805,7 @@ posix_unlink (call_frame_t *frame, xlator_t *this,
goto out;
}
unwind_dict = posix_dict_set_nlink (xdata, NULL, stbuf.ia_nlink);
unwind_dict = posix_dict_set_nlink (xdata, unwind_dict, stbuf.ia_nlink);
op_ret = 0;
out:
SET_TO_OLD_FS_ID ();
@ -3334,31 +3404,6 @@ map_xattr_flags(int flags)
}
#endif
static
int32_t posix_set_iatt_in_dict (dict_t *dict, struct iatt *in_stbuf)
{
int ret = -1;
struct iatt *stbuf = NULL;
int32_t len = sizeof(struct iatt);
if (!dict || !in_stbuf)
return ret;
stbuf = GF_CALLOC (1, len, gf_common_mt_char);
if (!stbuf)
return ret;
memcpy (stbuf, in_stbuf, len);
ret = dict_set_bin (dict, DHT_IATT_IN_XDATA_KEY, stbuf, len);
if (ret)
GF_FREE (stbuf);
return ret;
}
int32_t
posix_setxattr (call_frame_t *frame, xlator_t *this,
loc_t *loc, dict_t *dict, int flags, dict_t *xdata)

View File

@ -50,7 +50,11 @@
#define ACL_BUFFER_MAX 4096 /* size of character buffer */
#define LINKTO "trusted.glusterfs.dht.linkto"
#define DHT_LINKTO "trusted.glusterfs.dht.linkto"
/*
* TIER_MODE need to be changed when we stack tiers
*/
#define TIER_LINKTO "trusted.tier.tier-dht.linkto"
#define POSIX_GFID_HANDLE_SIZE(base_path_len) (base_path_len + SLEN("/") \
+ SLEN(GF_HIDDEN_PATH) + SLEN("/") \