summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/bugs/index/bug-1559004-EMLINK-handling.t52
-rw-r--r--xlators/features/index/src/index.c27
2 files changed, 61 insertions, 18 deletions
diff --git a/tests/bugs/index/bug-1559004-EMLINK-handling.t b/tests/bugs/index/bug-1559004-EMLINK-handling.t
new file mode 100644
index 00000000000..9aff93a367f
--- /dev/null
+++ b/tests/bugs/index/bug-1559004-EMLINK-handling.t
@@ -0,0 +1,52 @@
+#!/bin/bash
+
+. $(dirname $0)/../../include.rc
+. $(dirname $0)/../../volume.rc
+. $(dirname $0)/../../afr.rc
+
+cleanup
+TESTS_EXPECTED_IN_LOOP=30
+SCRIPT_TIMEOUT=1000
+
+TEST glusterd
+TEST pidof glusterd
+TEST $CLI volume info
+
+TEST touch $B0/ext4-1
+TEST touch $B0/ext4-2
+TEST touch $B0/ext4-3
+TEST truncate -s 2GB $B0/ext4-1
+TEST truncate -s 2GB $B0/ext4-2
+TEST truncate -s 2GB $B0/ext4-3
+
+TEST mkfs.ext4 -F $B0/ext4-1
+TEST mkfs.ext4 -F $B0/ext4-2
+TEST mkfs.ext4 -F $B0/ext4-3
+TEST mkdir $B0/ext41
+TEST mkdir $B0/ext42
+TEST mkdir $B0/ext43
+TEST mount -t ext4 -o loop $B0/ext4-1 $B0/ext41
+TEST mount -t ext4 -o loop $B0/ext4-2 $B0/ext42
+TEST mount -t ext4 -o loop $B0/ext4-3 $B0/ext43
+
+TEST $CLI volume create $V0 replica 3 $H0:$B0/ext4{1,2,3}
+TEST $CLI volume start $V0
+TEST $CLI volume heal $V0 granular-entry-heal enable
+TEST $GFS --volfile-id=$V0 --volfile-server=$H0 $M0;
+TEST kill_brick $V0 $H0 $B0/ext41
+for i in {1..15}
+do
+ TEST_IN_LOOP mkdir $M0/d${i}
+ TEST_IN_LOOP touch $M0/d${i}/{1..5000}
+done
+
+#On ext4 max number of hardlinks is ~65k, so there should be 2 base index files
+EXPECT "^2$" echo $(ls $B0/ext42/.glusterfs/indices/xattrop | grep xattrop | wc -l)
+EXPECT "^2$" echo $(ls $B0/ext42/.glusterfs/indices/entry-changes | grep entry-changes | wc -l)
+
+#Number of hardlinks: 75000 for files, 15 for dirs and 2 for base-indices
+#and root-dir for xattrop
+EXPECT "75018" echo $(ls -l $B0/ext42/.glusterfs/indices/xattrop | grep xattrop | awk '{sum+=$2} END{print sum}')
+EXPECT "75017" echo $(ls -l $B0/ext42/.glusterfs/indices/entry-changes | grep entry-changes | awk '{sum+=$2} END{print sum}')
+
+cleanup
diff --git a/xlators/features/index/src/index.c b/xlators/features/index/src/index.c
index 5e723e5e4c6..f39d901d624 100644
--- a/xlators/features/index/src/index.c
+++ b/xlators/features/index/src/index.c
@@ -574,14 +574,18 @@ out:
}
int
-index_link_to_base (xlator_t *this, char *base, size_t base_len,
- char *fpath, const char *subdir)
+index_link_to_base (xlator_t *this, char *fpath, const char *subdir)
{
int ret = 0;
int fd = 0;
int op_errno = 0;
uuid_t index = {0};
index_priv_t *priv = this->private;
+ char base[PATH_MAX] = {0};
+
+ index_get_index (priv, index);
+ make_index_path (priv->index_basepath, subdir,
+ index, base, sizeof (base));
ret = sys_link (base, fpath);
if (!ret || (errno == EEXIST)) {
@@ -599,7 +603,7 @@ index_link_to_base (xlator_t *this, char *base, size_t base_len,
} else if (op_errno == EMLINK) {
index_generate_index (priv, index);
make_index_path (priv->index_basepath, subdir,
- index, base, base_len);
+ index, base, sizeof (base));
} else {
goto out;
}
@@ -634,9 +638,7 @@ index_add (xlator_t *this, uuid_t gfid, const char *subdir,
index_xattrop_type_t type)
{
char gfid_path[PATH_MAX] = {0};
- char index_path[PATH_MAX] = {0};
int ret = -1;
- uuid_t index = {0};
index_priv_t *priv = NULL;
struct stat st = {0};
@@ -653,11 +655,7 @@ index_add (xlator_t *this, uuid_t gfid, const char *subdir,
ret = sys_stat (gfid_path, &st);
if (!ret)
goto out;
- index_get_index (priv, index);
- make_index_path (priv->index_basepath, subdir,
- index, index_path, sizeof (index_path));
- ret = index_link_to_base (this, index_path, sizeof (index_path),
- gfid_path, subdir);
+ ret = index_link_to_base (this, gfid_path, subdir);
out:
return ret;
}
@@ -810,8 +808,6 @@ index_entry_create (xlator_t *this, inode_t *inode, char *filename)
int op_errno = 0;
char pgfid_path[PATH_MAX] = {0};
char entry_path[PATH_MAX] = {0};
- char entry_base_index_path[PATH_MAX] = {0};
- uuid_t index = {0};
index_priv_t *priv = NULL;
index_inode_ctx_t *ctx = NULL;
@@ -849,12 +845,7 @@ index_entry_create (xlator_t *this, inode_t *inode, char *filename)
snprintf (entry_path, sizeof(entry_path), "%s/%s", pgfid_path,
filename);
- index_get_index (priv, index);
- make_index_path (priv->index_basepath, ENTRY_CHANGES_SUBDIR, index,
- entry_base_index_path, sizeof(entry_base_index_path));
- ret = index_link_to_base (this, entry_base_index_path,
- sizeof (entry_base_index_path),
- entry_path, ENTRY_CHANGES_SUBDIR);
+ ret = index_link_to_base (this, entry_path, ENTRY_CHANGES_SUBDIR);
out:
if (op_errno)
ret = -op_errno;