From 409719608cf0f607635fca5fb66b84a2e4aa1d4f Mon Sep 17 00:00:00 2001 From: Bobi Jam Date: Thu, 26 Nov 2020 14:13:28 +0800 Subject: [PATCH] LU-11848 lov: FIEMAP support for PFL and FLR file * use the high 16 bits of fe_device to record the absolute stripe number from the beginning we are processing, so that continuous call can resume from the stripe specified by it. Signed-off-by: Bobi Jam Change-Id: Ie519a9361b2d3ae4977ed2ccf925c92065aa9787 Reviewed-on: https://review.whamcloud.com/40766 Tested-by: jenkins Tested-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Alex Zhuravlev --- lustre/include/uapi/linux/lustre/lustre_fiemap.h | 30 ++- lustre/lov/lov_object.c | 246 +++++++++++++++-------- lustre/lov/lov_offset.c | 8 +- lustre/ptlrpc/wiretest.c | 1 - lustre/tests/sanity-flr.sh | 63 ++++++ lustre/tests/sanity-pfl.sh | 64 ++++++ lustre/tests/sanity.sh | 65 +++--- lustre/utils/wirecheck.c | 1 - lustre/utils/wiretest.c | 1 - 9 files changed, 360 insertions(+), 119 deletions(-) diff --git a/lustre/include/uapi/linux/lustre/lustre_fiemap.h b/lustre/include/uapi/linux/lustre/lustre_fiemap.h index 8cdb05d..ddea799 100644 --- a/lustre/include/uapi/linux/lustre/lustre_fiemap.h +++ b/lustre/include/uapi/linux/lustre/lustre_fiemap.h @@ -43,9 +43,35 @@ #include #include -/* XXX: We use fiemap_extent::fe_reserved[0] */ +/** + * XXX: We use fiemap_extent::fe_reserved[0], notice the high 16bits of it + * is used to locate the stripe number starting from the very beginning to + * resume the fiemap call. + */ #define fe_device fe_reserved[0] +static inline int get_fe_device(struct fiemap_extent *fe) +{ + return fe->fe_device & 0xffff; +} +static inline void set_fe_device(struct fiemap_extent *fe, int devno) +{ + fe->fe_device = (fe->fe_device & 0xffff0000) | (devno & 0xffff); +} +static inline int get_fe_stripenr(struct fiemap_extent *fe) +{ + return fe->fe_device >> 16; +} +static inline void set_fe_stripenr(struct fiemap_extent *fe, int nr) +{ + fe->fe_device = (fe->fe_device & 0xffff) | (nr << 16); +} +static inline void set_fe_device_stripenr(struct fiemap_extent *fe, int devno, + int nr) +{ + fe->fe_device = (nr << 16) | (devno & 0xffff); +} + static inline __kernel_size_t fiemap_count_to_size(__kernel_size_t extent_count) { return sizeof(struct fiemap) + extent_count * @@ -64,8 +90,6 @@ static inline unsigned int fiemap_size_to_count(__kernel_size_t array_size) #undef FIEMAP_FLAGS_COMPAT #endif -/* Lustre specific flags - use a high bit, don't conflict with upstream flag */ -#define FIEMAP_EXTENT_NO_DIRECT 0x40000000 /* Data mapping undefined */ #define FIEMAP_EXTENT_NET 0x80000000 /* Data stored remotely. * Sets NO_DIRECT flag */ diff --git a/lustre/lov/lov_object.c b/lustre/lov/lov_object.c index 053aae7..eb385d3 100644 --- a/lustre/lov/lov_object.c +++ b/lustre/lov/lov_object.c @@ -1506,21 +1506,34 @@ static int fiemap_calc_last_stripe(struct lov_stripe_md *lsm, int index, int start_stripe, int *stripe_count) { struct lov_stripe_md_entry *lsme = lsm->lsm_entries[index]; + int init_stripe; int last_stripe; - u64 obd_start; - u64 obd_end; int i, j; + init_stripe = lov_stripe_number(lsm, index, ext->e_start); + if (ext->e_end - ext->e_start > lsme->lsme_stripe_size * lsme->lsme_stripe_count) { - last_stripe = (start_stripe < 1 ? lsme->lsme_stripe_count - 1 : - start_stripe - 1); - *stripe_count = lsme->lsme_stripe_count; + if (init_stripe == start_stripe) { + last_stripe = (start_stripe < 1) ? + lsme->lsme_stripe_count - 1 : start_stripe - 1; + *stripe_count = lsme->lsme_stripe_count; + } else if (init_stripe < start_stripe) { + last_stripe = (init_stripe < 1) ? + lsme->lsme_stripe_count - 1 : init_stripe - 1; + *stripe_count = lsme->lsme_stripe_count - + (start_stripe - init_stripe); + } else { + last_stripe = init_stripe - 1; + *stripe_count = init_stripe - start_stripe; + } } else { for (j = 0, i = start_stripe; j < lsme->lsme_stripe_count; i = (i + 1) % lsme->lsme_stripe_count, j++) { - if ((lov_stripe_intersects(lsm, index, i, ext, - &obd_start, &obd_end)) == 0) + if (!lov_stripe_intersects(lsm, index, i, ext, NULL, + NULL)) + break; + if ((start_stripe != init_stripe) && (i == init_stripe)) break; } *stripe_count = j; @@ -1543,13 +1556,14 @@ static int fiemap_calc_last_stripe(struct lov_stripe_md *lsm, int index, static void fiemap_prepare_and_copy_exts(struct fiemap *fiemap, struct fiemap_extent *lcl_fm_ext, int ost_index, unsigned int ext_count, - int current_extent) + int current_extent, int abs_stripeno) { char *to; unsigned int ext; for (ext = 0; ext < ext_count; ext++) { - lcl_fm_ext[ext].fe_device = ost_index; + set_fe_device_stripenr(&lcl_fm_ext[ext], ost_index, + abs_stripeno); lcl_fm_ext[ext].fe_flags |= FIEMAP_EXTENT_NET; } @@ -1584,39 +1598,24 @@ static u64 fiemap_calc_fm_end_offset(struct fiemap *fiemap, { struct lov_stripe_md_entry *lsme = lsm->lsm_entries[index]; u64 local_end = fiemap->fm_extents[0].fe_logical; - u64 lun_start; u64 lun_end; u64 fm_end_offset; int stripe_no = -1; - int i; if (fiemap->fm_extent_count == 0 || fiemap->fm_extents[0].fe_logical == 0) return 0; - /* Find out stripe_no from ost_index saved in the fe_device */ - for (i = 0; i < lsme->lsme_stripe_count; i++) { - struct lov_oinfo *oinfo = lsme->lsme_oinfo[i]; - - if (lov_oinfo_is_dummy(oinfo)) - continue; - - if (oinfo->loi_ost_idx == fiemap->fm_extents[0].fe_device) { - stripe_no = i; - break; - } - } + stripe_no = *start_stripe; if (stripe_no == -1) return -EINVAL; /* If we have finished mapping on previous device, shift logical * offset to start of next device */ - if (lov_stripe_intersects(lsm, index, stripe_no, ext, - &lun_start, &lun_end) != 0 && + if (lov_stripe_intersects(lsm, index, stripe_no, ext, NULL, &lun_end) && local_end < lun_end) { fm_end_offset = local_end; - *start_stripe = stripe_no; } else { /* This is a special value to indicate that caller should * calculate offset in next stripe. */ @@ -1629,16 +1628,16 @@ static u64 fiemap_calc_fm_end_offset(struct fiemap *fiemap, struct fiemap_state { struct fiemap *fs_fm; - struct lu_extent fs_ext; + struct lu_extent fs_ext; /* current entry extent */ u64 fs_length; - u64 fs_end_offset; - int fs_cur_extent; - int fs_cnt_need; + u64 fs_end_offset; /* last iteration offset */ + int fs_cur_extent; /* collected exts so far */ + int fs_cnt_need; /* # of extents buf can hold */ int fs_start_stripe; int fs_last_stripe; - bool fs_device_done; - bool fs_finish_stripe; - bool fs_enough; + bool fs_device_done; /* enough for this OST */ + bool fs_finish_stripe; /* reached fs_last_stripe */ + bool fs_enough; /* enough for this call */ }; static struct cl_object *lov_find_subobj(const struct lu_env *env, @@ -1681,17 +1680,17 @@ out: static int fiemap_for_stripe(const struct lu_env *env, struct cl_object *obj, struct lov_stripe_md *lsm, struct fiemap *fiemap, size_t *buflen, struct ll_fiemap_info_key *fmkey, - int index, int stripeno, struct fiemap_state *fs) + int index, int stripe_last, int stripeno, + struct fiemap_state *fs) { struct lov_stripe_md_entry *lsme = lsm->lsm_entries[index]; struct cl_object *subobj; struct lov_obd *lov = lu2lov_dev(obj->co_lu.lo_dev)->ld_lov; struct fiemap_extent *fm_ext = &fs->fs_fm->fm_extents[0]; - u64 req_fm_len; /* Stores length of required mapping */ + u64 req_fm_len; /* max requested extent coverage */ u64 len_mapped_single_call; - u64 lun_start; - u64 lun_end; - u64 obd_object_end; + u64 obd_start; + u64 obd_end; unsigned int ext_count; /* EOF for object */ bool ost_eof = false; @@ -1703,22 +1702,23 @@ static int fiemap_for_stripe(const struct lu_env *env, struct cl_object *obj, fs->fs_device_done = false; /* Find out range of mapping on this stripe */ if ((lov_stripe_intersects(lsm, index, stripeno, &fs->fs_ext, - &lun_start, &obd_object_end)) == 0) + &obd_start, &obd_end)) == 0) return 0; if (lov_oinfo_is_dummy(lsme->lsme_oinfo[stripeno])) return -EIO; /* If this is a continuation FIEMAP call and we are on - * starting stripe then lun_start needs to be set to + * starting stripe then obd_start needs to be set to * end_offset */ if (fs->fs_end_offset != 0 && stripeno == fs->fs_start_stripe) - lun_start = fs->fs_end_offset; - lun_end = lov_size_to_stripe(lsm, index, fs->fs_ext.e_end, stripeno); - if (lun_start == lun_end) + obd_start = fs->fs_end_offset; + + if (lov_size_to_stripe(lsm, index, fs->fs_ext.e_end, stripeno) == + obd_start) return 0; - req_fm_len = obd_object_end - lun_start + 1; + req_fm_len = obd_end - obd_start + 1; fs->fs_fm->fm_length = 0; len_mapped_single_call = 0; @@ -1738,7 +1738,7 @@ static int fiemap_for_stripe(const struct lu_env *env, struct cl_object *obj, fs->fs_cur_extent; } - lun_start += len_mapped_single_call; + obd_start += len_mapped_single_call; fs->fs_fm->fm_length = req_fm_len - len_mapped_single_call; req_fm_len = fs->fs_fm->fm_length; /** @@ -1760,14 +1760,14 @@ static int fiemap_for_stripe(const struct lu_env *env, struct cl_object *obj, fs->fs_fm->fm_flags |= FIEMAP_EXTENT_LAST; fs->fs_fm->fm_mapped_extents = 1; - fm_ext[0].fe_logical = lun_start; - fm_ext[0].fe_length = obd_object_end - lun_start + 1; + fm_ext[0].fe_logical = obd_start; + fm_ext[0].fe_length = obd_end - obd_start + 1; fm_ext[0].fe_flags |= FIEMAP_EXTENT_UNKNOWN; goto inactive_tgt; } - fs->fs_fm->fm_start = lun_start; + fs->fs_fm->fm_start = obd_start; fs->fs_fm->fm_flags &= ~FIEMAP_FLAG_DEVICE_ORDER; memcpy(&fmkey->lfik_fiemap, fs->fs_fm, sizeof(*fs->fs_fm)); *buflen = fiemap_count_to_size(fs->fs_fm->fm_extent_count); @@ -1805,7 +1805,7 @@ inactive_tgt: /* prepare to copy retrived map extents */ len_mapped_single_call = fm_ext[ext_count - 1].fe_logical + fm_ext[ext_count - 1].fe_length - - lun_start; + obd_start; /* Have we finished mapping on this device? */ if (req_fm_len <= len_mapped_single_call) { @@ -1826,7 +1826,8 @@ inactive_tgt: } fiemap_prepare_and_copy_exts(fiemap, fm_ext, ost_index, - ext_count, fs->fs_cur_extent); + ext_count, fs->fs_cur_extent, + stripe_last + stripeno); fs->fs_cur_extent += ext_count; /* Ran out of available extents? */ @@ -1866,13 +1867,18 @@ static int lov_object_fiemap(const struct lu_env *env, struct cl_object *obj, loff_t whole_start; loff_t whole_end; int entry; - int start_entry; + int start_entry = -1; int end_entry; int cur_stripe = 0; int stripe_count; unsigned int buffer_size = FIEMAP_BUFFER_SIZE; int rc = 0; struct fiemap_state fs = { 0 }; + struct lu_extent range; + int cur_ext; + int stripe_last; + int start_stripe = 0; + bool resume = false; ENTRY; lsm = lov_lsm_addref(cl2lov(obj)); @@ -1934,8 +1940,6 @@ static int lov_object_fiemap(const struct lu_env *env, struct cl_object *obj, */ if (fiemap_count_to_size(fiemap->fm_extent_count) > *buflen) fiemap->fm_extent_count = fiemap_size_to_count(*buflen); - if (fiemap->fm_extent_count == 0) - fs.fs_cnt_need = 0; fs.fs_enough = false; fs.fs_cur_extent = 0; @@ -1947,68 +1951,139 @@ static int lov_object_fiemap(const struct lu_env *env, struct cl_object *obj, if (whole_start > fmkey->lfik_oa.o_size) GOTO(out_fm_local, rc = -EINVAL); whole_end = (fiemap->fm_length == OBD_OBJECT_EOF) ? - fmkey->lfik_oa.o_size : - whole_start + fiemap->fm_length - 1; + fmkey->lfik_oa.o_size + 1 : + whole_start + fiemap->fm_length; /** * If fiemap->fm_length != OBD_OBJECT_EOF but whole_end exceeds file * size */ - if (whole_end > fmkey->lfik_oa.o_size) - whole_end = fmkey->lfik_oa.o_size; + if (whole_end > fmkey->lfik_oa.o_size + 1) + whole_end = fmkey->lfik_oa.o_size + 1; - start_entry = lov_lsm_entry(lsm, whole_start); - end_entry = lov_lsm_entry(lsm, whole_end); - if (end_entry == -1) - end_entry = lsm->lsm_entry_count - 1; + /** + * the high 16bits of fe_device remember which stripe the last + * call has been arrived, we'd continue from there in this call. + */ + if (fiemap->fm_extent_count && fiemap->fm_extents[0].fe_logical) + resume = true; + stripe_last = get_fe_stripenr(&fiemap->fm_extents[0]); + /** + * stripe_last records stripe number we've been processed in the last + * call + */ + end_entry = lsm->lsm_entry_count - 1; + cur_stripe = 0; + for (entry = 0; entry <= end_entry; entry++) { + lsme = lsm->lsm_entries[entry]; + if (cur_stripe + lsme->lsme_stripe_count >= stripe_last) { + start_entry = entry; + start_stripe = stripe_last - cur_stripe; + break; + } - if (start_entry == -1 || end_entry == -1) + cur_stripe += lsme->lsme_stripe_count; + } + if (start_entry == -1) { + CERROR(DFID": FIEMAP does not init start entry, cur_stripe=%d, " + "stripe_last=%d\n", PFID(lu_object_fid(&obj->co_lu)), + cur_stripe, stripe_last); GOTO(out_fm_local, rc = -EINVAL); + } + /** + * @start_entry & @start_stripe records the position of fiemap + * resumption @stripe_last keeps recording the absolution position + * we'are processing. @resume indicates we'd honor @start_stripe. + */ + + range.e_start = whole_start; + range.e_end = whole_end; - /* TODO: rewrite it with lov_foreach_io_layout() */ for (entry = start_entry; entry <= end_entry; entry++) { + /* remeber to update stripe_last accordingly */ lsme = lsm->lsm_entries[entry]; - if (!lsme_inited(lsme)) - break; + /* FLR could contain component holes between entries */ + if (!lsme_inited(lsme)) { + stripe_last += lsme->lsme_stripe_count; + resume = false; + continue; + } - if (entry == start_entry) - fs.fs_ext.e_start = whole_start; - else + if (!lu_extent_is_overlapped(&range, &lsme->lsme_extent)) { + stripe_last += lsme->lsme_stripe_count; + resume = false; + continue; + } + + /* prepare for a component entry iteration */ + if (lsme->lsme_extent.e_start > whole_start) fs.fs_ext.e_start = lsme->lsme_extent.e_start; - if (entry == end_entry) + else + fs.fs_ext.e_start = whole_start; + if (lsme->lsme_extent.e_end > whole_end) fs.fs_ext.e_end = whole_end; else - fs.fs_ext.e_end = lsme->lsme_extent.e_end - 1; - fs.fs_length = fs.fs_ext.e_end - fs.fs_ext.e_start + 1; + fs.fs_ext.e_end = lsme->lsme_extent.e_end; /* Calculate start stripe, last stripe and length of mapping */ - fs.fs_start_stripe = lov_stripe_number(lsm, entry, - fs.fs_ext.e_start); + if (resume) { + fs.fs_start_stripe = start_stripe; + /* put stripe_last to the first stripe of the comp */ + stripe_last -= start_stripe; + resume = false; + } else { + fs.fs_start_stripe = lov_stripe_number(lsm, entry, + fs.fs_ext.e_start); + } fs.fs_last_stripe = fiemap_calc_last_stripe(lsm, entry, &fs.fs_ext, fs.fs_start_stripe, &stripe_count); - fs.fs_end_offset = fiemap_calc_fm_end_offset(fiemap, lsm, entry, - &fs.fs_ext, &fs.fs_start_stripe); + /** + * A new mirror component is under process, reset + * fs.fs_end_offset and then fiemap_for_stripe() starts from + * the overlapping extent, otherwise starts from + * fs.fs_end_offset. + */ + if (entry > start_entry && lsme->lsme_extent.e_start == 0) { + /* new mirror */ + fs.fs_end_offset = 0; + } else { + fs.fs_end_offset = fiemap_calc_fm_end_offset(fiemap, + lsm, entry, &fs.fs_ext, + &fs.fs_start_stripe); + } + /* Check each stripe */ for (cur_stripe = fs.fs_start_stripe; stripe_count > 0; --stripe_count, cur_stripe = (cur_stripe + 1) % lsme->lsme_stripe_count) { + /* reset fs_finish_stripe */ + fs.fs_finish_stripe = false; rc = fiemap_for_stripe(env, obj, lsm, fiemap, buflen, - fmkey, entry, cur_stripe, &fs); + fmkey, entry, stripe_last, + cur_stripe, &fs); if (rc < 0) GOTO(out_fm_local, rc); - if (fs.fs_enough) + if (fs.fs_enough) { + stripe_last += cur_stripe; GOTO(finish, rc); + } if (fs.fs_finish_stripe) break; } /* for each stripe */ - } /* for covering layout component */ - /* - * We've traversed all components, set @entry to the last component - * entry, it's for the last stripe check. - */ - entry--; + stripe_last += lsme->lsme_stripe_count; + } /* for covering layout component entry */ + finish: + if (fs.fs_cur_extent > 0) + cur_ext = fs.fs_cur_extent - 1; + else + cur_ext = 0; + + /* done all the processing */ + if (entry > end_entry) + fiemap->fm_extents[cur_ext].fe_flags |= FIEMAP_EXTENT_LAST; + /* Indicate that we are returning device offsets unless file just has * single stripe */ if (lsm->lsm_entry_count > 1 || @@ -2019,11 +2094,6 @@ finish: if (fiemap->fm_extent_count == 0) goto skip_last_device_calc; - /* Check if we have reached the last stripe and whether mapping for that - * stripe is done. */ - if ((cur_stripe == fs.fs_last_stripe) && fs.fs_device_done) - fiemap->fm_extents[fs.fs_cur_extent - 1].fe_flags |= - FIEMAP_EXTENT_LAST; skip_last_device_calc: fiemap->fm_mapped_extents = fs.fs_cur_extent; out_fm_local: diff --git a/lustre/lov/lov_offset.c b/lustre/lov/lov_offset.c index 0c9d668..8540ccd 100644 --- a/lustre/lov/lov_offset.c +++ b/lustre/lov/lov_offset.c @@ -238,7 +238,7 @@ loff_t lov_size_to_stripe(struct lov_stripe_md *lsm, int index, u64 file_size, * that is contained within the lov extent. this returns true if the given * stripe does intersect with the lov extent. * - * Closed interval [@obd_start, @obd_end] will be returned. + * Closed interval [@obd_start, @obd_end] will be returned if caller needs them. */ int lov_stripe_intersects(struct lov_stripe_md *lsm, int index, int stripeno, struct lu_extent *ext, u64 *obd_start, u64 *obd_end) @@ -246,10 +246,16 @@ int lov_stripe_intersects(struct lov_stripe_md *lsm, int index, int stripeno, struct lov_stripe_md_entry *entry = lsm->lsm_entries[index]; u64 start, end; int start_side, end_side; + u64 loc_start, loc_end; if (!lu_extent_is_overlapped(ext, &entry->lsme_extent)) return 0; + if (!obd_start) + obd_start = &loc_start; + if (!obd_end) + obd_end = &loc_end; + start = max_t(__u64, ext->e_start, entry->lsme_extent.e_start); end = min_t(__u64, ext->e_end, entry->lsme_extent.e_end); if (end != OBD_OBJECT_EOF) diff --git a/lustre/ptlrpc/wiretest.c b/lustre/ptlrpc/wiretest.c index 99aa54a..1b4c051 100644 --- a/lustre/ptlrpc/wiretest.c +++ b/lustre/ptlrpc/wiretest.c @@ -4694,7 +4694,6 @@ void lustre_assert_wire_constants(void) BUILD_BUG_ON(FIEMAP_EXTENT_UNWRITTEN != 0x00000800); BUILD_BUG_ON(FIEMAP_EXTENT_MERGED != 0x00001000); BUILD_BUG_ON(FIEMAP_EXTENT_SHARED != 0x00002000); - BUILD_BUG_ON(FIEMAP_EXTENT_NO_DIRECT != 0x40000000); BUILD_BUG_ON(FIEMAP_EXTENT_NET != 0x80000000); #ifdef CONFIG_FS_POSIX_ACL diff --git a/lustre/tests/sanity-flr.sh b/lustre/tests/sanity-flr.sh index 858c2ce..6f089c9 100644 --- a/lustre/tests/sanity-flr.sh +++ b/lustre/tests/sanity-flr.sh @@ -23,6 +23,11 @@ if [[ $(uname -m) = ppc64 ]]; then skip "Skip FLR testing for PPC clients" fi +if [[ "$ost1_FSTYPE" == "zfs" ]]; then + # bug #: LU-1941 + ALWAYS_EXCEPT+="49a" +fi + build_test_filter [[ "$MDS1_VERSION" -ge $(version_code 2.10.56) ]] || @@ -2260,6 +2265,64 @@ test_48() { } run_test 48 "Verify snapshot mirror" +OLDIFS="$IFS" +cleanup_49() { + trap 0 + IFS="$OLDIFS" +} + +test_49a() { + [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs" + + trap cleanup_49 EXIT RETURN + + local file=$DIR/$tfile + + $LFS setstripe -N -E eof -c1 -o1 -N -E eof -c1 -o0 $file || + error "setstripe on $file" + + dd if=/dev/zero of=$file bs=1M count=1 || error "dd failed for $file" + $LFS mirror resync $file + + filefrag -ves $file || error "filefrag $file failed" + filefrag_op=$(filefrag -ve -k $file | + sed -n '/ext:/,/found/{/ext:/d; /found/d; p}') + +#Filesystem type is: bd00bd0 +#File size of /mnt/lustre/f49a.sanity-flr is 1048576 (1024 blocks of 1024 bytes) +# ext: device_logical: physical_offset: length: dev: flags: +# 0: 0.. 1023: 1572864.. 1573887: 1024: 0001: net,eof +# 1: 0.. 1023: 1572864.. 1573887: 1024: 0000: last,net,eof +#/mnt/lustre/f49a.sanity-flr: 2 extents found + + last_lun=$(echo $filefrag_op | cut -d: -f5) + IFS=$'\n' + tot_len=0 + num_luns=1 + for line in $filefrag_op; do + frag_lun=$(echo $line | cut -d: -f5) + ext_len=$(echo $line | cut -d: -f4) + if [[ "$frag_lun" != "$last_lun" ]]; then + if (( tot_len != 1024 )); then + cleanup_49 + error "$file: OST$last_lun $tot_len != 1024" + else + (( num_luns += 1 )) + tot_len=0 + fi + fi + (( tot_len += ext_len )) + last_lun=$frag_lun + done + if (( num_luns != 2 || tot_len != 1024 )); then + cleanup_49 + error "$file: $num_luns != 2, $tot_len != 1024 on OST$last_lun" + fi + + echo "FIEMAP on $file succeeded" +} +run_test 49a "FIEMAP upon FLR file" + ctrl_file=$(mktemp /tmp/CTRL.XXXXXX) lock_file=$(mktemp /var/lock/FLR.XXXXXX) diff --git a/lustre/tests/sanity-pfl.sh b/lustre/tests/sanity-pfl.sh index e83a9fe..b39ea7c 100644 --- a/lustre/tests/sanity-pfl.sh +++ b/lustre/tests/sanity-pfl.sh @@ -21,6 +21,10 @@ if [[ $(uname -m) = ppc64 ]]; then ALWAYS_EXCEPT+=" 14 16a 16b 17" fi +if [[ "$ost1_FSTYPE" == "zfs" ]]; then + # bug #: LU-1941 + ALWAYS_EXCEPT+="24a" +fi build_test_filter check_and_setup_lustre @@ -2206,6 +2210,66 @@ test_23f() { } run_test 23f "Append with low on space: repeat and remove EXT comp" +OLDIFS="$IFS" +cleanup_24() { + trap 0 + IFS="$OLDIFS" +} + +test_24a() { + [ "$OSTCOUNT" -lt "3" ] && skip_env "needs >= 3 OSTs" + + trap cleanup_24 EXIT RETURN + + local file=$DIR/$tfile + + $LFS setstripe -E 1m -c1 -o0 -E eof -c2 -o1,2 $file || + error "setstripe on $file" + + dd if=/dev/zero of=$file bs=1M count=3 || error "dd failed for $file" + sync + + filefrag -ves $file || error "filefrag $file failed" + filefrag_op=$(filefrag -ve -k $file | + sed -n '/ext:/,/found/{/ext:/d; /found/d; p}') + +#Filesystem type is: bd00bd0 +#File size of /mnt/lustre/f24a.sanity-pfl is 3145728 (3072 blocks of 1024 bytes) +# ext: device_logical: physical_offset: length: dev: flags: +# 0: 0.. 1023: 1572864.. 1573887: 1024: 0000: net +# 1: 0.. 1023: 1572864.. 1573887: 1024: 0002: net +# 2: 1024.. 2047: 1573888.. 1574911: 1024: 0001: last,net +#/mnt/lustre/f24a.sanity-pfl: 3 extents found + + last_lun=$(echo $filefrag_op | cut -d: -f5) + + IFS=$'\n' + tot_len=0 + num_luns=1 + for line in $filefrag_op; do + frag_lun=$(echo $line | cut -d: -f5) + ext_len=$(echo $line | cut -d: -f4) + if [[ "$frag_lun" != "$last_lun" ]]; then + if (( tot_len != 1024 )); then + cleanup_24 + error "$file: OST$last_lun $tot_len != 1024" + else + (( num_luns += 1 )) + tot_len=0 + fi + fi + (( tot_len += ext_len )) + last_lun=$frag_lun + done + if (( num_luns != 3 || tot_len != 1024 )); then + cleanup_24 + error "$file: $num_luns != 3, $tot_len != 1024 on OST$last_lun" + fi + + echo "FIEMAP on $file succeeded" +} +run_test 24a "FIEMAP upon PFL file" + complete $SECONDS check_and_cleanup_lustre exit_status diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index a590831..a79e409 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -82,11 +82,16 @@ fi if [ "$mds1_FSTYPE" = "zfs" ]; then # bug number for skipped test: - ALWAYS_EXCEPT="$ALWAYS_EXCEPT " + ALWAYS_EXCEPT+=" " # 13 (min)" [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b" fi +if [ "$ost1_FSTYPE" = "zfs" ]; then + # bug number for skipped test: LU-1941 LU-1941 LU-1941 LU-1941 + ALWAYS_EXCEPT+=" 130a 130b 130c 130d 130e 130f 130g" +fi + # Get the SLES distro version # # Returns a version string that should only be used in comparing @@ -12653,38 +12658,30 @@ test_130e() { local fm_file=$DIR/$tfile $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file" - [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] && - skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS" NUM_BLKS=512 EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 )) - for ((i = 0; i < $NUM_BLKS; i++)) - do - dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1 + for ((i = 0; i < $NUM_BLKS; i++)); do + dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \ + conv=notrunc > /dev/null 2>&1 done filefrag -ves $fm_file || error "filefrag $fm_file failed" filefrag_op=$(filefrag -ve -k $fm_file | sed -n '/ext:/,/found/{/ext:/d; /found/d; p}') - last_lun=$(echo $filefrag_op | cut -d: -f5 | - sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/') + last_lun=$(echo $filefrag_op | cut -d: -f5) IFS=$'\n' tot_len=0 num_luns=1 - for line in $filefrag_op - do - frag_lun=$(echo $line | cut -d: -f5 | - sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/') + for line in $filefrag_op; do + frag_lun=$(echo $line | cut -d: -f5) ext_len=$(echo $line | cut -d: -f4) - if (( $frag_lun != $last_lun )); then + if [[ "$frag_lun" != "$last_lun" ]]; then if (( tot_len != $EXPECTED_LEN )); then cleanup_130 - error "FIEMAP on $fm_file failed; returned " \ - "len $tot_len for OST $last_lun instead " \ - "of $EXPECTED_LEN" - return + error "OST$last_lun $tot_len != $EXPECTED_LEN" else (( num_luns += 1 )) tot_len=0 @@ -12695,13 +12692,9 @@ test_130e() { done if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then cleanup_130 - error "FIEMAP on $fm_file failed; returned wrong number " \ - "of luns or wrong len for OST $last_lun" - return + error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN" fi - cleanup_130 - echo "FIEMAP with continuation calls succeeded" } run_test 130e "FIEMAP (test continuation FIEMAP calls)" @@ -12718,14 +12711,38 @@ test_130f() { filefrag_extents=$(filefrag -vek $fm_file | awk '/extents? found/ { print $2 }') if [[ "$filefrag_extents" != "0" ]]; then - error "FIEMAP on $fm_file failed; " \ - "returned $filefrag_extents expected 0" + error "$fm_file: filefrag_extents=$filefrag_extents != 0" fi rm -f $fm_file } run_test 130f "FIEMAP (unstriped file)" +test_130g() { + local file=$DIR/$tfile + local nr=$((OSTCOUNT * 100)) + + $LFS setstripe -C $nr $file || + error "failed to setstripe -C $nr $file" + + dd if=/dev/zero of=$file count=$nr bs=1M + sync + nr=$($LFS getstripe -c $file) + + local extents=$(filefrag -v $file | + sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l) + + echo "filefrag list $extents extents in file with stripecount $nr" + if (( extents < nr )); then + $LFS getstripe $file + filefrag -v $file + error "filefrag printed $extents < $nr extents" + fi + + rm -f $file +} +run_test 130g "FIEMAP (overstripe file)" + # Test for writev/readv test_131a() { rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 || diff --git a/lustre/utils/wirecheck.c b/lustre/utils/wirecheck.c index 344ce65..312d37e 100644 --- a/lustre/utils/wirecheck.c +++ b/lustre/utils/wirecheck.c @@ -2167,7 +2167,6 @@ check_ll_fiemap_extent(void) CHECK_CDEFINE(FIEMAP_EXTENT_UNWRITTEN); CHECK_CDEFINE(FIEMAP_EXTENT_MERGED); CHECK_CDEFINE(FIEMAP_EXTENT_SHARED); - CHECK_CDEFINE(FIEMAP_EXTENT_NO_DIRECT); CHECK_CDEFINE(FIEMAP_EXTENT_NET); } diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index 62f02d5..80bc3c4 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -4726,7 +4726,6 @@ void lustre_assert_wire_constants(void) BUILD_BUG_ON(FIEMAP_EXTENT_UNWRITTEN != 0x00000800); BUILD_BUG_ON(FIEMAP_EXTENT_MERGED != 0x00001000); BUILD_BUG_ON(FIEMAP_EXTENT_SHARED != 0x00002000); - BUILD_BUG_ON(FIEMAP_EXTENT_NO_DIRECT != 0x40000000); BUILD_BUG_ON(FIEMAP_EXTENT_NET != 0x80000000); #ifdef CONFIG_FS_POSIX_ACL -- 1.8.3.1