diff options
Diffstat (limited to 'xlators/features/locks')
-rw-r--r-- | xlators/features/locks/src/common.h | 2 | ||||
-rw-r--r-- | xlators/features/locks/src/entrylk.c | 26 | ||||
-rw-r--r-- | xlators/features/locks/src/locks.h | 1 | ||||
-rw-r--r-- | xlators/features/locks/src/posix.c | 34 |
4 files changed, 59 insertions, 4 deletions
diff --git a/xlators/features/locks/src/common.h b/xlators/features/locks/src/common.h index fe5ebada9a8..2cf9aa38093 100644 --- a/xlators/features/locks/src/common.h +++ b/xlators/features/locks/src/common.h @@ -149,4 +149,6 @@ pl_verify_reservelk (xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *lock, int can_block); int pl_reserve_unlock (xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *reqlock); +uint32_t +check_entrylk_on_basename (xlator_t *this, inode_t *parent, char *basename); #endif /* __COMMON_H__ */ diff --git a/xlators/features/locks/src/entrylk.c b/xlators/features/locks/src/entrylk.c index e034c37b325..2a47657dbbb 100644 --- a/xlators/features/locks/src/entrylk.c +++ b/xlators/features/locks/src/entrylk.c @@ -441,6 +441,32 @@ out: return ret_lock; } +uint32_t +check_entrylk_on_basename (xlator_t *this, inode_t *parent, char *basename) +{ + uint32_t entrylk = 0; + pl_inode_t *pinode = 0; + pl_dom_list_t *dom = NULL; + pl_entry_lock_t *conf = NULL; + + pinode = pl_inode_get (this, parent); + if (!pinode) + goto out; + pthread_mutex_lock (&pinode->mutex); + { + list_for_each_entry (dom, &pinode->dom_list, inode_list) { + conf = __lock_grantable (dom, basename, ENTRYLK_WRLCK); + if (conf && conf->basename) { + entrylk = 1; + break; + } + } + } + pthread_mutex_unlock (&pinode->mutex); + +out: + return entrylk; +} void __grant_blocked_entry_locks (xlator_t *this, pl_inode_t *pl_inode, diff --git a/xlators/features/locks/src/locks.h b/xlators/features/locks/src/locks.h index f855c07899c..f64c2690241 100644 --- a/xlators/features/locks/src/locks.h +++ b/xlators/features/locks/src/locks.h @@ -165,6 +165,7 @@ typedef struct { gf_boolean_t entrylk_count_req; gf_boolean_t inodelk_count_req; gf_boolean_t posixlk_count_req; + gf_boolean_t parent_entrylk_req; /* used by {f,}truncate */ loc_t loc; diff --git a/xlators/features/locks/src/posix.c b/xlators/features/locks/src/posix.c index 3e04c18f008..0bf022a943e 100644 --- a/xlators/features/locks/src/posix.c +++ b/xlators/features/locks/src/posix.c @@ -1508,6 +1508,24 @@ out: } void +pl_parent_entrylk_xattr_fill (xlator_t *this, inode_t *parent, + char *basename, dict_t *dict) +{ + uint32_t entrylk = 0; + int ret = -1; + + if (!parent || !basename || !strlen (basename)) + goto out; + entrylk = check_entrylk_on_basename (this, parent, basename); +out: + ret = dict_set_uint32 (dict, GLUSTERFS_PARENT_ENTRYLK, entrylk); + if (ret < 0) { + gf_log (this->name, GF_LOG_DEBUG, + " dict_set failed on key %s", GLUSTERFS_PARENT_ENTRYLK); + } +} + +void pl_entrylk_xattr_fill (xlator_t *this, inode_t *inode, dict_t *dict) { @@ -1570,12 +1588,14 @@ pl_lookup_cbk (call_frame_t *frame, GF_VALIDATE_OR_GOTO (this->name, frame->local, out); - if (op_ret) { + if (op_ret) goto out; - } local = frame->local; + if (local->parent_entrylk_req) + pl_parent_entrylk_xattr_fill (this, local->loc.parent, + (char*)local->loc.name, xdata); if (local->entrylk_count_req) pl_entrylk_xattr_fill (this, inode, xdata); if (local->inodelk_count_req) @@ -1584,12 +1604,15 @@ pl_lookup_cbk (call_frame_t *frame, pl_posixlk_xattr_fill (this, inode, xdata); +out: + local = frame->local; frame->local = NULL; - if (local != NULL) + if (local != NULL) { + loc_wipe (&local->loc); mem_put (local); + } -out: STACK_UNWIND_STRICT ( lookup, frame, @@ -1625,9 +1648,12 @@ pl_lookup (call_frame_t *frame, local->inodelk_count_req = 1; if (dict_get (xdata, GLUSTERFS_POSIXLK_COUNT)) local->posixlk_count_req = 1; + if (dict_get (xdata, GLUSTERFS_PARENT_ENTRYLK)) + local->parent_entrylk_req = 1; } frame->local = local; + loc_copy (&local->loc, loc); STACK_WIND (frame, pl_lookup_cbk, |