From: Dave Chinner Date: Fri, 2 Mar 2012 08:34:58 +0000 (+0000) Subject: xfs_io: fix fiemap loop continuation X-Git-Tag: v3.1.8~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ef45fa5e892a8f267c24f0e244082c36102d9347;p=thirdparty%2Fxfsprogs-dev.git xfs_io: fix fiemap loop continuation When the fiemap command needs to retrieve more extents from the kernel via a subsequent IO, it calculates the next logical block to retrieve in file system block units. the fiemap needs the start offset in bytes, not filesystem blocks. Hence if the fiemap command can loop forever retrieving the same blocks if the logical offset offset of the next block in filesystem block units is smaller than the number of bytes in a filessytem block. i.e. it will just loop retreiving the first 32 extents from offset block zero. Signed-off-by: Dave Chinner Signed-off-by: Christoph Hellwig --- diff --git a/io/fiemap.c b/io/fiemap.c index 99296ddba..e32a41668 100644 --- a/io/fiemap.c +++ b/io/fiemap.c @@ -75,12 +75,14 @@ print_verbose( __u64 *last_logical) { __u64 lstart; + __u64 llast; __u64 len; __u64 block; char lbuf[48]; char bbuf[48]; char flgbuf[16]; + llast = *last_logical / blocksize; lstart = extent->fe_logical / blocksize; len = extent->fe_length / blocksize; block = extent->fe_physical / blocksize; @@ -88,11 +90,11 @@ print_verbose( memset(lbuf, 0, sizeof(lbuf)); memset(bbuf, 0, sizeof(bbuf)); - if (lstart != *last_logical) { - snprintf(lbuf, sizeof(lbuf), "[%llu..%llu]:", *last_logical, + if (lstart != llast) { + snprintf(lbuf, sizeof(lbuf), "[%llu..%llu]:", llast, lstart - 1ULL); printf("%4d: %-*s %-*s %*llu\n", *cur_extent, foff_w, lbuf, - boff_w, _("hole"), tot_w, lstart - *last_logical); + boff_w, _("hole"), tot_w, lstart - llast); (*cur_extent)++; memset(lbuf, 0, sizeof(lbuf)); } @@ -121,19 +123,20 @@ print_plain( __u64 *last_logical) { __u64 lstart; + __u64 llast; __u64 block; __u64 len; + llast = *last_logical / blocksize; lstart = extent->fe_logical / blocksize; len = extent->fe_length / blocksize; block = extent->fe_physical / blocksize; - if (lstart != *last_logical) { + if (lstart != llast) { printf("\t%d: [%llu..%llu]: hole", *cur_extent, - *last_logical, lstart - 1ULL); + llast, lstart - 1ULL); if (lflag) - printf(_(" %llu blocks\n"), - lstart - *last_logical); + printf(_(" %llu blocks\n"), lstart - llast); else printf("\n"); (*cur_extent)++; @@ -281,6 +284,7 @@ fiemap_f( print_plain(extent, lflag, blocksize, max_extents, &cur_extent, &last_logical); + if (extent->fe_flags & FIEMAP_EXTENT_LAST) { last = 1; break; @@ -303,22 +307,21 @@ fiemap_f( return 0; } - if (cur_extent && last_logical < (st.st_size / blocksize)) { + if (cur_extent && last_logical < st.st_size) { char lbuf[32]; snprintf(lbuf, sizeof(lbuf), "[%llu..%llu]:", - last_logical, (st.st_size / blocksize) - 1); + last_logical / blocksize, (st.st_size / blocksize) - 1); if (vflag) { printf("%4d: %-*s %-*s %*llu\n", cur_extent, foff_w, lbuf, boff_w, _("hole"), tot_w, - (st.st_size / blocksize) - last_logical); + (st.st_size - last_logical) / blocksize); } else { printf("\t%d: %s %s", cur_extent, lbuf, _("hole")); if (lflag) printf(_(" %llu blocks\n"), - (st.st_size / blocksize) - - last_logical); + (st.st_size - last_logical) / blocksize); else printf("\n"); }