do not use current iterator position as hash source for dot and dotdot.
instead just return 0 as hash for these entries.
Change-Id: I5ee439b237e8ed98d295f5672b1d0e8a6b48a55b
Signed-off-by: Alex Zhuravlev <bzzz@whamcloud.com>
Reviewed-on: https://review.whamcloud.com/34098
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: Jenkins
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Nathaniel Clark <nclark@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
it = (struct osd_zap_it *)osd_index_it_init(env, dt, unused);
if (!IS_ERR(it))
it = (struct osd_zap_it *)osd_index_it_init(env, dt, unused);
if (!IS_ERR(it))
+ it->ozi_pos = OZI_POS_INIT;
RETURN((struct dt_it *)it);
}
RETURN((struct dt_it *)it);
}
LASSERT(((const char *)key)[0] == 0);
if (name[0] == 0) {
LASSERT(((const char *)key)[0] == 0);
if (name[0] == 0) {
+ it->ozi_pos = OZI_POS_INIT;
RETURN(1);
}
if (name[0] == '.') {
if (name[1] == 0) {
RETURN(1);
}
if (name[0] == '.') {
if (name[1] == 0) {
+ it->ozi_pos = OZI_POS_DOT;
GOTO(out, rc = 1);
} else if (name[1] == '.' && name[2] == 0) {
GOTO(out, rc = 1);
} else if (name[1] == '.' && name[2] == 0) {
+ it->ozi_pos = OZI_POS_DOTDOT;
GOTO(out, rc = 1);
}
}
/* neither . nor .. - some real record */
GOTO(out, rc = 1);
}
}
/* neither . nor .. - some real record */
+ it->ozi_pos = OZI_POS_REAL;
* the second ->next() moves the cursor to ..
* then we get to the real records and have to verify any exist
*/
* the second ->next() moves the cursor to ..
* then we get to the real records and have to verify any exist
*/
- if (it->ozi_pos <= 2) {
+ if (it->ozi_pos <= OZI_POS_DOTDOT) {
+ if (it->ozi_pos <= OZI_POS_DOTDOT)
- if (it->ozi_pos <= 1) {
- it->ozi_pos = 1;
+ if (it->ozi_pos <= OZI_POS_DOT) {
+ it->ozi_pos = OZI_POS_DOT;
RETURN((struct dt_key *)".");
RETURN((struct dt_key *)".");
- } else if (it->ozi_pos == 2) {
+ } else if (it->ozi_pos == OZI_POS_DOTDOT) {
RETURN((struct dt_key *)"..");
}
RETURN((struct dt_key *)"..");
}
- if (it->ozi_pos <= 1) {
- it->ozi_pos = 1;
+ if (it->ozi_pos <= OZI_POS_DOT) {
+ it->ozi_pos = OZI_POS_DOT;
- } else if (it->ozi_pos == 2) {
+ } else if (it->ozi_pos == OZI_POS_DOTDOT) {
ENTRY;
lde->lde_attrs = 0;
ENTRY;
lde->lde_attrs = 0;
- if (it->ozi_pos <= 1) {
- lde->lde_hash = cpu_to_le64(1);
+ if (it->ozi_pos <= OZI_POS_DOT) {
+ /* notice hash=0 here, this is needed to avoid
+ * case when some real entry (after ./..) may
+ * have hash=0. in this case the client would
+ * be confused having records out of hash order. */
+ lde->lde_hash = cpu_to_le64(0);
strcpy(lde->lde_name, ".");
lde->lde_namelen = cpu_to_le16(1);
fid_cpu_to_le(&lde->lde_fid,
strcpy(lde->lde_name, ".");
lde->lde_namelen = cpu_to_le16(1);
fid_cpu_to_le(&lde->lde_fid,
/* append lustre attributes */
osd_it_append_attrs(lde, attr, 1, IFTODT(S_IFDIR));
lde->lde_reclen = cpu_to_le16(lu_dirent_calc_size(1, attr));
/* append lustre attributes */
osd_it_append_attrs(lde, attr, 1, IFTODT(S_IFDIR));
lde->lde_reclen = cpu_to_le16(lu_dirent_calc_size(1, attr));
+ it->ozi_pos = OZI_POS_DOT;
- } else if (it->ozi_pos == 2) {
- lde->lde_hash = cpu_to_le64(2);
+ } else if (it->ozi_pos == OZI_POS_DOTDOT) {
+ /* same as for . above */
+ lde->lde_hash = cpu_to_le64(0);
strcpy(lde->lde_name, "..");
lde->lde_namelen = cpu_to_le16(2);
rc = osd_find_parent_fid(env, &it->ozi_obj->oo_dt, fid, NULL);
strcpy(lde->lde_name, "..");
lde->lde_namelen = cpu_to_le16(2);
rc = osd_find_parent_fid(env, &it->ozi_obj->oo_dt, fid, NULL);
+ if (it->ozi_pos <= OZI_POS_DOT)
- else if (it->ozi_pos == 2)
+ else if (it->ozi_pos == OZI_POS_DOTDOT)
namelen = 2;
if (namelen > 0) {
namelen = 2;
if (namelen > 0) {
- if (it->ozi_pos <= 2)
- pos = it->ozi_pos;
+ if (it->ozi_pos <= OZI_POS_DOTDOT)
+ pos = 0;
else
pos = osd_zap_cursor_serialize(it->ozi_zc);
else
pos = osd_zap_cursor_serialize(it->ozi_zc);
zap_cursor_fini(it->ozi_zc);
osd_obj_cursor_init_serialized(it->ozi_zc, obj, hash);
zap_cursor_fini(it->ozi_zc);
osd_obj_cursor_init_serialized(it->ozi_zc, obj, hash);
- if (hash <= 2) {
- it->ozi_pos = hash;
- rc = +1;
+ if (hash == 0) {
+ it->ozi_pos = OZI_POS_INIT;
+ rc = +1; /* there will be ./.. at least */
+ it->ozi_pos = OZI_POS_REAL;
/* to return whether the end has been reached */
rc = osd_index_retrieve_skip_dots(it, za);
if (rc == 0)
/* to return whether the end has been reached */
rc = osd_index_retrieve_skip_dots(it, za);
if (rc == 0)
unsigned oiq_reset:1; /* 1 -- no need to advance */
};
unsigned oiq_reset:1; /* 1 -- no need to advance */
};
+enum osd_zap_pos {
+ OZI_POS_INIT = 0,
+ OZI_POS_DOT = 1, /* cursor at . */
+ OZI_POS_DOTDOT = 2, /* cursor at .. */
+ OZI_POS_REAL = 3, /* cursor at real entries */
+};
+
/**
* Iterator's in-memory data structure for ZAPs
*
/**
* Iterator's in-memory data structure for ZAPs
*
zap_cursor_t *ozi_zc;
struct osd_object *ozi_obj;
unsigned ozi_reset:1; /* 1 -- no need to advance */
zap_cursor_t *ozi_zc;
struct osd_object *ozi_obj;
unsigned ozi_reset:1; /* 1 -- no need to advance */
- /* ozi_pos - position of the cursor:
- * 0 - before any record
- * 1 - "."
- * 2 - ".."
- * 3 - real records */
- unsigned ozi_pos:3;
+ /* ozi_pos - position of the cursor */
+ enum osd_zap_pos ozi_pos;
union {
char ozi_name[MAXNAMELEN]; /* file name for dir */
__u64 ozi_key; /* binary key for index files */
union {
char ozi_name[MAXNAMELEN]; /* file name for dir */
__u64 ozi_key; /* binary key for index files */
if [ $(facet_fstype $SINGLEMDS) = "zfs" ]; then
# bug number for skipped test: LU-11388
ALWAYS_EXCEPT+="131b"
if [ $(facet_fstype $SINGLEMDS) = "zfs" ]; then
# bug number for skipped test: LU-11388
ALWAYS_EXCEPT+="131b"
- if [ $MDSCOUNT -gt 1 ]; then
-# bug number for skipped test: LU-11330
- ALWAYS_EXCEPT+=" 70d"
- fi
fi
if $SHARED_KEY; then
# bug number for skipped tests: LU-9795 (all below)
fi
if $SHARED_KEY; then
# bug number for skipped tests: LU-9795 (all below)
}
run_test 24E "cross MDT rename/link"
}
run_test 24E "cross MDT rename/link"
+test_24F () {
+ [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
+
+ local repeats=1000
+ [ "$SLOW" = "no" ] && repeats=100
+
+ mkdir -p $DIR/$tdir
+
+ echo "$repeats repeats"
+ for ((i = 0; i < repeats; i++)); do
+ $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
+ touch $DIR/$tdir/test/a || error "touch fails"
+ mkdir $DIR/$tdir/test/b || error "mkdir fails"
+ rm -rf $DIR/$tdir/test || error "rmdir fails"
+ done
+
+ true
+}
+run_test 24F "hash order vs readdir (LU-11330)"
+
test_25a() {
echo '== symlink sanity ============================================='
test_25a() {
echo '== symlink sanity ============================================='