summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libglusterfs/src/glusterfs.h1
-rw-r--r--xlators/features/locks/src/common.h2
-rw-r--r--xlators/features/locks/src/entrylk.c26
-rw-r--r--xlators/features/locks/src/locks.h1
-rw-r--r--xlators/features/locks/src/posix.c34
5 files changed, 60 insertions, 4 deletions
diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h
index d87451f68fd..213b57b6064 100644
--- a/libglusterfs/src/glusterfs.h
+++ b/libglusterfs/src/glusterfs.h
@@ -100,6 +100,7 @@
#define GLUSTERFS_INODELK_COUNT "glusterfs.inodelk-count"
#define GLUSTERFS_ENTRYLK_COUNT "glusterfs.entrylk-count"
#define GLUSTERFS_POSIXLK_COUNT "glusterfs.posixlk-count"
+#define GLUSTERFS_PARENT_ENTRYLK "glusterfs.parent-entrylk"
#define QUOTA_SIZE_KEY "trusted.glusterfs.quota.size"
#define GFID_TO_PATH_KEY "glusterfs.gfid2path"
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,