cluster/afr: Refactor internal locking code to allow multiple inodelks
For implementing copy_file_range fop, AFR needs to perform two inodelks in the same transaction. This patch brings in the necessary structure to make it easier to do so. Entry-locks in AFR were already taking multiple entry-locks on different inodes with the respective basenames. This patch extends the logic in inodelks to use the same lockee_t structure. This lead to removal of quite a lot of duplicate code present in afr-lk-common.c as both the locks are doing same things except 'winding' part. updates: #536 Change-Id: Ibfce7e3f260bb27b18645152ec680c33866fe0ae Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
This commit is contained in:
parent
8d38c5b733
commit
a12cadc137
@ -1794,11 +1794,9 @@ afr_local_transaction_cleanup(afr_local_t *local, xlator_t *this)
|
||||
|
||||
afr_matrix_cleanup(local->pending, priv->child_count);
|
||||
|
||||
GF_FREE(local->internal_lock.locked_nodes);
|
||||
|
||||
GF_FREE(local->internal_lock.lower_locked_nodes);
|
||||
|
||||
afr_entry_lockee_cleanup(&local->internal_lock);
|
||||
afr_lockees_cleanup(&local->internal_lock);
|
||||
|
||||
GF_FREE(local->transaction.pre_op);
|
||||
|
||||
@ -5708,11 +5706,6 @@ afr_internal_lock_init(afr_internal_lock_t *lk, size_t child_count)
|
||||
{
|
||||
int ret = -ENOMEM;
|
||||
|
||||
lk->locked_nodes = GF_CALLOC(sizeof(*lk->locked_nodes), child_count,
|
||||
gf_afr_mt_char);
|
||||
if (NULL == lk->locked_nodes)
|
||||
goto out;
|
||||
|
||||
lk->lower_locked_nodes = GF_CALLOC(sizeof(*lk->lower_locked_nodes),
|
||||
child_count, gf_afr_mt_char);
|
||||
if (NULL == lk->lower_locked_nodes)
|
||||
|
@ -425,15 +425,11 @@ int
|
||||
afr_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
|
||||
mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
|
||||
{
|
||||
afr_private_t *priv = NULL;
|
||||
afr_local_t *local = NULL;
|
||||
afr_internal_lock_t *int_lock = NULL;
|
||||
call_frame_t *transaction_frame = NULL;
|
||||
int ret = -1;
|
||||
int op_errno = ENOMEM;
|
||||
|
||||
priv = this->private;
|
||||
|
||||
transaction_frame = copy_frame(frame);
|
||||
if (!transaction_frame)
|
||||
goto out;
|
||||
@ -475,16 +471,6 @@ afr_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
|
||||
|
||||
local->transaction.main_frame = frame;
|
||||
local->transaction.basename = AFR_BASENAME(loc->path);
|
||||
int_lock = &local->internal_lock;
|
||||
|
||||
int_lock->lockee_count = 0;
|
||||
ret = afr_init_entry_lockee(&int_lock->lockee[0], local,
|
||||
&local->transaction.parent_loc,
|
||||
local->transaction.basename, priv->child_count);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
int_lock->lockee_count++;
|
||||
ret = afr_transaction(transaction_frame, this, AFR_ENTRY_TRANSACTION);
|
||||
if (ret < 0) {
|
||||
op_errno = -ret;
|
||||
@ -555,15 +541,11 @@ int
|
||||
afr_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
|
||||
dev_t dev, mode_t umask, dict_t *xdata)
|
||||
{
|
||||
afr_private_t *priv = NULL;
|
||||
afr_local_t *local = NULL;
|
||||
afr_internal_lock_t *int_lock = NULL;
|
||||
call_frame_t *transaction_frame = NULL;
|
||||
int ret = -1;
|
||||
int op_errno = ENOMEM;
|
||||
|
||||
priv = this->private;
|
||||
|
||||
transaction_frame = copy_frame(frame);
|
||||
if (!transaction_frame)
|
||||
goto out;
|
||||
@ -598,16 +580,6 @@ afr_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
|
||||
|
||||
local->transaction.main_frame = frame;
|
||||
local->transaction.basename = AFR_BASENAME(loc->path);
|
||||
int_lock = &local->internal_lock;
|
||||
|
||||
int_lock->lockee_count = 0;
|
||||
ret = afr_init_entry_lockee(&int_lock->lockee[0], local,
|
||||
&local->transaction.parent_loc,
|
||||
local->transaction.basename, priv->child_count);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
int_lock->lockee_count++;
|
||||
ret = afr_transaction(transaction_frame, this, AFR_ENTRY_TRANSACTION);
|
||||
if (ret < 0) {
|
||||
op_errno = -ret;
|
||||
@ -676,15 +648,11 @@ int
|
||||
afr_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
|
||||
mode_t umask, dict_t *xdata)
|
||||
{
|
||||
afr_private_t *priv = NULL;
|
||||
afr_local_t *local = NULL;
|
||||
afr_internal_lock_t *int_lock = NULL;
|
||||
call_frame_t *transaction_frame = NULL;
|
||||
int ret = -1;
|
||||
int op_errno = ENOMEM;
|
||||
|
||||
priv = this->private;
|
||||
|
||||
transaction_frame = copy_frame(frame);
|
||||
if (!transaction_frame)
|
||||
goto out;
|
||||
@ -726,16 +694,6 @@ afr_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
|
||||
|
||||
local->transaction.main_frame = frame;
|
||||
local->transaction.basename = AFR_BASENAME(loc->path);
|
||||
int_lock = &local->internal_lock;
|
||||
|
||||
int_lock->lockee_count = 0;
|
||||
ret = afr_init_entry_lockee(&int_lock->lockee[0], local,
|
||||
&local->transaction.parent_loc,
|
||||
local->transaction.basename, priv->child_count);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
int_lock->lockee_count++;
|
||||
ret = afr_transaction(transaction_frame, this, AFR_ENTRY_TRANSACTION);
|
||||
if (ret < 0) {
|
||||
op_errno = -ret;
|
||||
@ -804,15 +762,11 @@ int
|
||||
afr_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
|
||||
dict_t *xdata)
|
||||
{
|
||||
afr_private_t *priv = NULL;
|
||||
afr_local_t *local = NULL;
|
||||
afr_internal_lock_t *int_lock = NULL;
|
||||
call_frame_t *transaction_frame = NULL;
|
||||
int ret = -1;
|
||||
int op_errno = ENOMEM;
|
||||
|
||||
priv = this->private;
|
||||
|
||||
transaction_frame = copy_frame(frame);
|
||||
if (!transaction_frame)
|
||||
goto out;
|
||||
@ -847,16 +801,6 @@ afr_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
|
||||
|
||||
local->transaction.main_frame = frame;
|
||||
local->transaction.basename = AFR_BASENAME(newloc->path);
|
||||
int_lock = &local->internal_lock;
|
||||
|
||||
int_lock->lockee_count = 0;
|
||||
ret = afr_init_entry_lockee(&int_lock->lockee[0], local,
|
||||
&local->transaction.parent_loc,
|
||||
local->transaction.basename, priv->child_count);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
int_lock->lockee_count++;
|
||||
ret = afr_transaction(transaction_frame, this, AFR_ENTRY_TRANSACTION);
|
||||
if (ret < 0) {
|
||||
op_errno = -ret;
|
||||
@ -926,15 +870,11 @@ int
|
||||
afr_symlink(call_frame_t *frame, xlator_t *this, const char *linkpath,
|
||||
loc_t *loc, mode_t umask, dict_t *xdata)
|
||||
{
|
||||
afr_private_t *priv = NULL;
|
||||
afr_local_t *local = NULL;
|
||||
afr_internal_lock_t *int_lock = NULL;
|
||||
call_frame_t *transaction_frame = NULL;
|
||||
int ret = -1;
|
||||
int op_errno = ENOMEM;
|
||||
|
||||
priv = this->private;
|
||||
|
||||
transaction_frame = copy_frame(frame);
|
||||
if (!transaction_frame)
|
||||
goto out;
|
||||
@ -968,16 +908,6 @@ afr_symlink(call_frame_t *frame, xlator_t *this, const char *linkpath,
|
||||
|
||||
local->transaction.main_frame = frame;
|
||||
local->transaction.basename = AFR_BASENAME(loc->path);
|
||||
int_lock = &local->internal_lock;
|
||||
|
||||
int_lock->lockee_count = 0;
|
||||
ret = afr_init_entry_lockee(&int_lock->lockee[0], local,
|
||||
&local->transaction.parent_loc,
|
||||
local->transaction.basename, priv->child_count);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
int_lock->lockee_count++;
|
||||
ret = afr_transaction(transaction_frame, this, AFR_ENTRY_TRANSACTION);
|
||||
if (ret < 0) {
|
||||
op_errno = -ret;
|
||||
@ -1050,15 +980,10 @@ int
|
||||
afr_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
|
||||
dict_t *xdata)
|
||||
{
|
||||
afr_private_t *priv = NULL;
|
||||
afr_local_t *local = NULL;
|
||||
afr_internal_lock_t *int_lock = NULL;
|
||||
call_frame_t *transaction_frame = NULL;
|
||||
int ret = -1;
|
||||
int op_errno = ENOMEM;
|
||||
int nlockee = 0;
|
||||
|
||||
priv = this->private;
|
||||
|
||||
transaction_frame = copy_frame(frame);
|
||||
if (!transaction_frame) {
|
||||
@ -1101,35 +1026,6 @@ afr_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
|
||||
local->transaction.main_frame = frame;
|
||||
local->transaction.basename = AFR_BASENAME(oldloc->path);
|
||||
local->transaction.new_basename = AFR_BASENAME(newloc->path);
|
||||
int_lock = &local->internal_lock;
|
||||
|
||||
int_lock->lockee_count = nlockee = 0;
|
||||
ret = afr_init_entry_lockee(
|
||||
&int_lock->lockee[nlockee], local, &local->transaction.new_parent_loc,
|
||||
local->transaction.new_basename, priv->child_count);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
nlockee++;
|
||||
ret = afr_init_entry_lockee(&int_lock->lockee[nlockee], local,
|
||||
&local->transaction.parent_loc,
|
||||
local->transaction.basename, priv->child_count);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
nlockee++;
|
||||
if (local->newloc.inode && IA_ISDIR(local->newloc.inode->ia_type)) {
|
||||
ret = afr_init_entry_lockee(&int_lock->lockee[nlockee], local,
|
||||
&local->newloc, NULL, priv->child_count);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
nlockee++;
|
||||
}
|
||||
qsort(int_lock->lockee, nlockee, sizeof(*int_lock->lockee),
|
||||
afr_entry_lockee_cmp);
|
||||
int_lock->lockee_count = nlockee;
|
||||
|
||||
ret = afr_transaction(transaction_frame, this,
|
||||
AFR_ENTRY_RENAME_TRANSACTION);
|
||||
if (ret < 0) {
|
||||
@ -1198,15 +1094,11 @@ int
|
||||
afr_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
|
||||
dict_t *xdata)
|
||||
{
|
||||
afr_private_t *priv = NULL;
|
||||
afr_local_t *local = NULL;
|
||||
afr_internal_lock_t *int_lock = NULL;
|
||||
call_frame_t *transaction_frame = NULL;
|
||||
int ret = -1;
|
||||
int op_errno = ENOMEM;
|
||||
|
||||
priv = this->private;
|
||||
|
||||
transaction_frame = copy_frame(frame);
|
||||
if (!transaction_frame)
|
||||
goto out;
|
||||
@ -1239,16 +1131,6 @@ afr_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
|
||||
|
||||
local->transaction.main_frame = frame;
|
||||
local->transaction.basename = AFR_BASENAME(loc->path);
|
||||
int_lock = &local->internal_lock;
|
||||
|
||||
int_lock->lockee_count = 0;
|
||||
ret = afr_init_entry_lockee(&int_lock->lockee[0], local,
|
||||
&local->transaction.parent_loc,
|
||||
local->transaction.basename, priv->child_count);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
int_lock->lockee_count++;
|
||||
ret = afr_transaction(transaction_frame, this, AFR_ENTRY_TRANSACTION);
|
||||
if (ret < 0) {
|
||||
op_errno = -ret;
|
||||
@ -1315,15 +1197,10 @@ int
|
||||
afr_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
|
||||
dict_t *xdata)
|
||||
{
|
||||
afr_private_t *priv = NULL;
|
||||
afr_local_t *local = NULL;
|
||||
afr_internal_lock_t *int_lock = NULL;
|
||||
call_frame_t *transaction_frame = NULL;
|
||||
int ret = -1;
|
||||
int op_errno = ENOMEM;
|
||||
int nlockee = 0;
|
||||
|
||||
priv = this->private;
|
||||
|
||||
transaction_frame = copy_frame(frame);
|
||||
if (!transaction_frame)
|
||||
@ -1357,26 +1234,6 @@ afr_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
|
||||
|
||||
local->transaction.main_frame = frame;
|
||||
local->transaction.basename = AFR_BASENAME(loc->path);
|
||||
int_lock = &local->internal_lock;
|
||||
|
||||
int_lock->lockee_count = nlockee = 0;
|
||||
ret = afr_init_entry_lockee(&int_lock->lockee[nlockee], local,
|
||||
&local->transaction.parent_loc,
|
||||
local->transaction.basename, priv->child_count);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
nlockee++;
|
||||
ret = afr_init_entry_lockee(&int_lock->lockee[nlockee], local, &local->loc,
|
||||
NULL, priv->child_count);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
nlockee++;
|
||||
qsort(int_lock->lockee, nlockee, sizeof(*int_lock->lockee),
|
||||
afr_entry_lockee_cmp);
|
||||
int_lock->lockee_count = nlockee;
|
||||
|
||||
ret = afr_transaction(transaction_frame, this, AFR_ENTRY_TRANSACTION);
|
||||
if (ret < 0) {
|
||||
op_errno = -ret;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -30,7 +30,7 @@ GLFS_MSGID(AFR, AFR_MSG_QUORUM_FAIL, AFR_MSG_QUORUM_MET,
|
||||
AFR_MSG_GFID_NULL, AFR_MSG_FD_CREATE_FAILED, AFR_MSG_DICT_SET_FAILED,
|
||||
AFR_MSG_EXPUNGING_FILE_OR_DIR, AFR_MSG_MIGRATION_IN_PROGRESS,
|
||||
AFR_MSG_CHILD_MISCONFIGURED, AFR_MSG_VOL_MISCONFIGURED,
|
||||
AFR_MSG_BLOCKING_LKS_FAILED, AFR_MSG_INVALID_FD, AFR_MSG_LOCK_INFO,
|
||||
AFR_MSG_INTERNAL_LKS_FAILED, AFR_MSG_INVALID_FD, AFR_MSG_LOCK_INFO,
|
||||
AFR_MSG_LOCK_XLATOR_NOT_LOADED, AFR_MSG_FD_CTX_GET_FAILED,
|
||||
AFR_MSG_INVALID_SUBVOL, AFR_MSG_PUMP_XLATOR_ERROR,
|
||||
AFR_MSG_SELF_HEAL_INFO, AFR_MSG_READ_SUBVOL_ERROR,
|
||||
|
@ -797,21 +797,9 @@ afr_changelog_post_op_fail(call_frame_t *frame, xlator_t *this, int op_errno)
|
||||
unsigned char *
|
||||
afr_locked_nodes_get(afr_transaction_type type, afr_internal_lock_t *int_lock)
|
||||
{
|
||||
unsigned char *locked_nodes = NULL;
|
||||
switch (type) {
|
||||
case AFR_DATA_TRANSACTION:
|
||||
case AFR_METADATA_TRANSACTION:
|
||||
locked_nodes = int_lock->locked_nodes;
|
||||
break;
|
||||
|
||||
case AFR_ENTRY_TRANSACTION:
|
||||
case AFR_ENTRY_RENAME_TRANSACTION:
|
||||
/*Because same set of subvols participate in all lockee
|
||||
* entities*/
|
||||
locked_nodes = int_lock->lockee[0].locked_nodes;
|
||||
break;
|
||||
}
|
||||
return locked_nodes;
|
||||
/*Because same set of subvols participate in all lockee
|
||||
* entities*/
|
||||
return int_lock->lockee[0].locked_nodes;
|
||||
}
|
||||
|
||||
int
|
||||
@ -2057,7 +2045,7 @@ err:
|
||||
}
|
||||
|
||||
int
|
||||
afr_post_nonblocking_inodelk_cbk(call_frame_t *frame, xlator_t *this)
|
||||
afr_post_nonblocking_lock_cbk(call_frame_t *frame, xlator_t *this)
|
||||
{
|
||||
afr_internal_lock_t *int_lock = NULL;
|
||||
afr_local_t *local = NULL;
|
||||
@ -2068,36 +2056,12 @@ afr_post_nonblocking_inodelk_cbk(call_frame_t *frame, xlator_t *this)
|
||||
/* Initiate blocking locks if non-blocking has failed */
|
||||
if (int_lock->lock_op_ret < 0) {
|
||||
gf_msg_debug(this->name, 0,
|
||||
"Non blocking inodelks failed. Proceeding to blocking");
|
||||
"Non blocking locks failed. Proceeding to blocking");
|
||||
int_lock->lock_cbk = afr_internal_lock_finish;
|
||||
afr_blocking_lock(frame, this);
|
||||
} else {
|
||||
gf_msg_debug(this->name, 0,
|
||||
"Non blocking inodelks done. Proceeding to FOP");
|
||||
afr_internal_lock_finish(frame, this);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
afr_post_nonblocking_entrylk_cbk(call_frame_t *frame, xlator_t *this)
|
||||
{
|
||||
afr_internal_lock_t *int_lock = NULL;
|
||||
afr_local_t *local = NULL;
|
||||
|
||||
local = frame->local;
|
||||
int_lock = &local->internal_lock;
|
||||
|
||||
/* Initiate blocking locks if non-blocking has failed */
|
||||
if (int_lock->lock_op_ret < 0) {
|
||||
gf_msg_debug(this->name, 0,
|
||||
"Non blocking entrylks failed. Proceeding to blocking");
|
||||
int_lock->lock_cbk = afr_internal_lock_finish;
|
||||
afr_blocking_lock(frame, this);
|
||||
} else {
|
||||
gf_msg_debug(this->name, 0,
|
||||
"Non blocking entrylks done. Proceeding to FOP");
|
||||
"Non blocking locks done. Proceeding to FOP");
|
||||
|
||||
afr_internal_lock_finish(frame, this);
|
||||
}
|
||||
@ -2115,7 +2079,7 @@ afr_post_blocking_rename_cbk(call_frame_t *frame, xlator_t *this)
|
||||
int_lock = &local->internal_lock;
|
||||
|
||||
if (int_lock->lock_op_ret < 0) {
|
||||
gf_msg(this->name, GF_LOG_INFO, 0, AFR_MSG_BLOCKING_LKS_FAILED,
|
||||
gf_msg(this->name, GF_LOG_INFO, 0, AFR_MSG_INTERNAL_LKS_FAILED,
|
||||
"Blocking entrylks failed.");
|
||||
|
||||
afr_transaction_done(frame, this);
|
||||
@ -2146,25 +2110,26 @@ afr_post_lower_unlock_cbk(call_frame_t *frame, xlator_t *this)
|
||||
}
|
||||
|
||||
int
|
||||
afr_set_transaction_flock(xlator_t *this, afr_local_t *local)
|
||||
afr_set_transaction_flock(xlator_t *this, afr_local_t *local,
|
||||
afr_lockee_t *lockee)
|
||||
{
|
||||
afr_internal_lock_t *int_lock = NULL;
|
||||
afr_private_t *priv = NULL;
|
||||
struct gf_flock *flock = NULL;
|
||||
|
||||
int_lock = &local->internal_lock;
|
||||
priv = this->private;
|
||||
flock = &lockee->flock;
|
||||
|
||||
if ((priv->arbiter_count || local->transaction.eager_lock_on ||
|
||||
priv->full_lock) &&
|
||||
local->transaction.type == AFR_DATA_TRANSACTION) {
|
||||
/*Lock entire file to avoid network split brains.*/
|
||||
int_lock->flock.l_len = 0;
|
||||
int_lock->flock.l_start = 0;
|
||||
flock->l_len = 0;
|
||||
flock->l_start = 0;
|
||||
} else {
|
||||
int_lock->flock.l_len = local->transaction.len;
|
||||
int_lock->flock.l_start = local->transaction.start;
|
||||
flock->l_len = local->transaction.len;
|
||||
flock->l_start = local->transaction.start;
|
||||
}
|
||||
int_lock->flock.l_type = F_WRLCK;
|
||||
flock->l_type = F_WRLCK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2174,26 +2139,21 @@ afr_lock(call_frame_t *frame, xlator_t *this)
|
||||
{
|
||||
afr_internal_lock_t *int_lock = NULL;
|
||||
afr_local_t *local = NULL;
|
||||
int i = 0;
|
||||
|
||||
local = frame->local;
|
||||
int_lock = &local->internal_lock;
|
||||
|
||||
int_lock->lock_cbk = afr_post_nonblocking_lock_cbk;
|
||||
int_lock->domain = this->name;
|
||||
|
||||
switch (local->transaction.type) {
|
||||
case AFR_DATA_TRANSACTION:
|
||||
case AFR_METADATA_TRANSACTION:
|
||||
afr_set_transaction_flock(this, local);
|
||||
for (i = 0; i < int_lock->lockee_count; i++) {
|
||||
afr_set_transaction_flock(this, local, &int_lock->lockee[i]);
|
||||
}
|
||||
|
||||
int_lock->lock_cbk = afr_post_nonblocking_inodelk_cbk;
|
||||
|
||||
afr_nonblocking_inodelk(frame, this);
|
||||
break;
|
||||
|
||||
case AFR_ENTRY_RENAME_TRANSACTION:
|
||||
|
||||
int_lock->lock_cbk = afr_post_nonblocking_entrylk_cbk;
|
||||
afr_nonblocking_entrylk(frame, this);
|
||||
break;
|
||||
|
||||
case AFR_ENTRY_TRANSACTION:
|
||||
@ -2202,11 +2162,11 @@ afr_lock(call_frame_t *frame, xlator_t *this)
|
||||
int_lock->lk_loc = &local->transaction.parent_loc;
|
||||
else
|
||||
GF_ASSERT(local->fd);
|
||||
|
||||
int_lock->lock_cbk = afr_post_nonblocking_entrylk_cbk;
|
||||
afr_nonblocking_entrylk(frame, this);
|
||||
break;
|
||||
case AFR_ENTRY_RENAME_TRANSACTION:
|
||||
break;
|
||||
}
|
||||
afr_lock_nonblocking(frame, this);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2277,17 +2237,19 @@ afr_has_lock_conflict(afr_local_t *local, gf_boolean_t waitlist_check)
|
||||
/* }}} */
|
||||
static void
|
||||
afr_copy_inodelk_vars(afr_internal_lock_t *dst, afr_internal_lock_t *src,
|
||||
xlator_t *this)
|
||||
xlator_t *this, int lockee_num)
|
||||
{
|
||||
afr_private_t *priv = this->private;
|
||||
afr_lockee_t *sl = &src->lockee[lockee_num];
|
||||
afr_lockee_t *dl = &dst->lockee[lockee_num];
|
||||
|
||||
dst->domain = src->domain;
|
||||
dst->flock.l_len = src->flock.l_len;
|
||||
dst->flock.l_start = src->flock.l_start;
|
||||
dst->flock.l_type = src->flock.l_type;
|
||||
dst->lock_count = src->lock_count;
|
||||
memcpy(dst->locked_nodes, src->locked_nodes,
|
||||
priv->child_count * sizeof(*dst->locked_nodes));
|
||||
dl->flock.l_len = sl->flock.l_len;
|
||||
dl->flock.l_start = sl->flock.l_start;
|
||||
dl->flock.l_type = sl->flock.l_type;
|
||||
dl->locked_count = sl->locked_count;
|
||||
memcpy(dl->locked_nodes, sl->locked_nodes,
|
||||
priv->child_count * sizeof(*dl->locked_nodes));
|
||||
}
|
||||
|
||||
void
|
||||
@ -2308,7 +2270,7 @@ __afr_transaction_wake_shared(afr_local_t *local, struct list_head *shared)
|
||||
if (conflict && !list_empty(&lock->owners))
|
||||
return;
|
||||
afr_copy_inodelk_vars(&each->internal_lock, &local->internal_lock,
|
||||
each->transaction.frame->this);
|
||||
each->transaction.frame->this, 0);
|
||||
list_move_tail(&each->transaction.wait_list, shared);
|
||||
list_add_tail(&each->transaction.owner_list, &lock->owners);
|
||||
}
|
||||
@ -2785,7 +2747,7 @@ __afr_eager_lock_handle(afr_local_t *local, gf_boolean_t *take_lock,
|
||||
*timer_local = list_entry(lock->post_op.next, afr_local_t,
|
||||
transaction.owner_list);
|
||||
afr_copy_inodelk_vars(&local->internal_lock,
|
||||
&(*timer_local)->internal_lock, this);
|
||||
&(*timer_local)->internal_lock, this, 0);
|
||||
lock->delay_timer = NULL;
|
||||
*do_pre_op = _gf_true;
|
||||
list_add_tail(&local->transaction.owner_list, &lock->owners);
|
||||
@ -2802,7 +2764,7 @@ __afr_eager_lock_handle(afr_local_t *local, gf_boolean_t *take_lock,
|
||||
owner_local = list_entry(lock->owners.next, afr_local_t,
|
||||
transaction.owner_list);
|
||||
afr_copy_inodelk_vars(&local->internal_lock,
|
||||
&owner_local->internal_lock, this);
|
||||
&owner_local->internal_lock, this, 0);
|
||||
*take_lock = _gf_false;
|
||||
*do_pre_op = _gf_true;
|
||||
}
|
||||
@ -2871,6 +2833,62 @@ fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
afr_transaction_lockee_init(call_frame_t *frame)
|
||||
{
|
||||
afr_local_t *local = frame->local;
|
||||
afr_internal_lock_t *int_lock = &local->internal_lock;
|
||||
afr_private_t *priv = frame->this->private;
|
||||
int ret = 0;
|
||||
|
||||
switch (local->transaction.type) {
|
||||
case AFR_DATA_TRANSACTION:
|
||||
case AFR_METADATA_TRANSACTION:
|
||||
ret = afr_add_inode_lockee(local, priv->child_count);
|
||||
break;
|
||||
|
||||
case AFR_ENTRY_TRANSACTION:
|
||||
case AFR_ENTRY_RENAME_TRANSACTION:
|
||||
ret = afr_add_entry_lockee(local, &local->transaction.parent_loc,
|
||||
local->transaction.basename,
|
||||
priv->child_count);
|
||||
if (ret) {
|
||||
goto out;
|
||||
}
|
||||
if (local->op == GF_FOP_RENAME) {
|
||||
ret = afr_add_entry_lockee(
|
||||
local, &local->transaction.new_parent_loc,
|
||||
local->transaction.new_basename, priv->child_count);
|
||||
if (ret) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (local->newloc.inode &&
|
||||
IA_ISDIR(local->newloc.inode->ia_type)) {
|
||||
ret = afr_add_entry_lockee(local, &local->newloc, NULL,
|
||||
priv->child_count);
|
||||
if (ret) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
} else if (local->op == GF_FOP_RMDIR) {
|
||||
ret = afr_add_entry_lockee(local, &local->loc, NULL,
|
||||
priv->child_count);
|
||||
if (ret) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (int_lock->lockee_count > 1) {
|
||||
qsort(int_lock->lockee, int_lock->lockee_count,
|
||||
sizeof(*int_lock->lockee), afr_entry_lockee_cmp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
afr_transaction(call_frame_t *frame, xlator_t *this, afr_transaction_type type)
|
||||
{
|
||||
@ -2904,6 +2922,10 @@ afr_transaction(call_frame_t *frame, xlator_t *this, afr_transaction_type type)
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = afr_transaction_lockee_init(frame);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (type != AFR_METADATA_TRANSACTION) {
|
||||
goto txn_start;
|
||||
}
|
||||
|
@ -288,12 +288,14 @@ afr_index_from_ia_type(ia_type_t type)
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
struct gf_flock flock;
|
||||
loc_t loc;
|
||||
fd_t *fd;
|
||||
char *basename;
|
||||
unsigned char *locked_nodes;
|
||||
int locked_count;
|
||||
|
||||
} afr_entry_lockee_t;
|
||||
} afr_lockee_t;
|
||||
|
||||
int
|
||||
afr_entry_lockee_cmp(const void *l1, const void *l2);
|
||||
@ -302,20 +304,17 @@ typedef struct {
|
||||
loc_t *lk_loc;
|
||||
|
||||
int lockee_count;
|
||||
afr_entry_lockee_t lockee[AFR_LOCKEE_COUNT_MAX];
|
||||
afr_lockee_t lockee[AFR_LOCKEE_COUNT_MAX];
|
||||
|
||||
struct gf_flock flock;
|
||||
const char *lk_basename;
|
||||
const char *lower_basename;
|
||||
const char *higher_basename;
|
||||
char lower_locked;
|
||||
char higher_locked;
|
||||
|
||||
unsigned char *locked_nodes;
|
||||
unsigned char *lower_locked_nodes;
|
||||
|
||||
int32_t lock_count;
|
||||
int32_t entrylk_lock_count;
|
||||
|
||||
int32_t lk_call_count;
|
||||
int32_t lk_expected_count;
|
||||
@ -980,11 +979,14 @@ int
|
||||
xattr_is_equal(dict_t *this, char *key1, data_t *value1, void *data);
|
||||
|
||||
int
|
||||
afr_init_entry_lockee(afr_entry_lockee_t *lockee, afr_local_t *local,
|
||||
loc_t *loc, char *basename, int child_count);
|
||||
afr_add_entry_lockee(afr_local_t *local, loc_t *loc, char *basename,
|
||||
int child_count);
|
||||
|
||||
int
|
||||
afr_add_inode_lockee(afr_local_t *local, int child_count);
|
||||
|
||||
void
|
||||
afr_entry_lockee_cleanup(afr_internal_lock_t *int_lock);
|
||||
afr_lockees_cleanup(afr_internal_lock_t *int_lock);
|
||||
|
||||
int
|
||||
afr_attempt_lock_recovery(xlator_t *this, int32_t child_index);
|
||||
@ -1002,10 +1004,7 @@ int32_t
|
||||
afr_unlock(call_frame_t *frame, xlator_t *this);
|
||||
|
||||
int
|
||||
afr_nonblocking_entrylk(call_frame_t *frame, xlator_t *this);
|
||||
|
||||
int
|
||||
afr_nonblocking_inodelk(call_frame_t *frame, xlator_t *this);
|
||||
afr_lock_nonblocking(call_frame_t *frame, xlator_t *this);
|
||||
|
||||
int
|
||||
afr_blocking_lock(call_frame_t *frame, xlator_t *this);
|
||||
@ -1272,9 +1271,6 @@ afr_writev_copy_outvars(call_frame_t *src_frame, call_frame_t *dst_frame);
|
||||
void
|
||||
afr_update_uninodelk(afr_local_t *local, afr_internal_lock_t *int_lock,
|
||||
int32_t child_index);
|
||||
int
|
||||
afr_is_inodelk_transaction(afr_transaction_type type);
|
||||
|
||||
afr_fd_ctx_t *
|
||||
__afr_fd_ctx_get(fd_t *fd, xlator_t *this);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user