Re: SEEK_HOLE second hole problem

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 10/12/16 11:15 AM, Benjamin Coddington wrote:
> While investigating generic/285 failure on NFS on an XFS export I think I
> found a seek hole bug.
> 
> For a file with a hole/data pattern of hole, data, hole, data; it appears
> that SEEK_HOLE for pattern chunks larger than 65536 will be incorrect for
> seeking the start of the next hole after the first hole.

[sandeen@sandeen ~]$ ./bcodding testfile
SEEK_HOLE found second hole at 196608, expecting 139264
[sandeen@sandeen ~]$ xfs_bmap testfile
testfile:
	0: [0..135]: hole
	1: [136..383]: 134432656..134432903
	2: [384..407]: hole
	3: [408..543]: 134432392..134432527

the numbers in brackets are sector numbers, so there is a hole
at 0, blocks at 69632, hole at 196608, and more blocks at 208896.

As bfoster mentioned on IRC, I think you are seeing xfs's speculative
preallocation at work; more data got written than you asked for,
but there's no guarantee about how a filesystem will allocate
blocks based on an IO pattern.

The /data/ is correct even if a zero-filled block ended up somewhere
you didn't expect:

[sandeen@sandeen ~]$ hexdump -C testfile
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00011000  61 61 61 61 61 61 61 61  61 61 61 61 61 61 61 61  |aaaaaaaaaaaaaaaa|
*
00022000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00033000  61 61 61 61 61 61 61 61  61 61 61 61 61 61 61 61  |aaaaaaaaaaaaaaaa|
*
00044000

(0x22000 is 139264 bytes)

-Eric

> Here's my little test program:
> 
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <fcntl.h>
> #include <unistd.h>
> 
> #define SEEK_HOLE      4
> //#define CHUNK 65536
> #define CHUNK 69632
> 
> int main(int argc, char **argv)
> {
>         int fd;
>         off_t pos;
>         char *buf = NULL;
> 
>         buf = malloc(4096);
>         memset(buf, 'a', 4096);
> 
>         fd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0644);
> 
>         for (pos = CHUNK; pos < CHUNK*2; pos += 4096)
>             pwrite(fd, buf, 4096, pos);
> 
>         for (pos = CHUNK*3; pos < CHUNK*4; pos += 4096)
>             pwrite(fd, buf, 4096, pos);
> 
>         pos = lseek(fd, CHUNK, SEEK_HOLE);
>         printf("SEEK_HOLE found second hole at %llu, expecting %llu\n", pos, CHUNK*2);
> 
>         close(fd);
> }
> 
> [root@fedora ~]# ./test /exports/scratch/foo
> SEEK_HOLE found second hole at 196608, expecting 139264
> 
> This is on 4.8, I did a bit of digging through XFS to see if I could find
> the problem, and it looks like XFS is interesting enough that I could spend
> all my time reading it... but I couldn't make serious progress and I have to
> go back to my actual job.
> 
> Let me know how I can help, or if I am just doing something exceedingly
> stupid..
> 
> Ben
> -- 
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux