FreeBSD Bugzilla – Attachment 239910 Details for
Bug 269328
nfs client: data corruption using fspacectl and mmap
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
Test program that triggers the error on the NFS client
fspace-and-mmap.c (text/plain), 3.72 KB, created by
Alan Somers
on 2023-02-04 22:02:18 UTC
(
hide
)
Description:
Test program that triggers the error on the NFS client
Filename:
MIME Type:
Creator:
Alan Somers
Created:
2023-02-04 22:02:18 UTC
Size:
3.72 KB
patch
obsolete
>#include <sys/mman.h> >#include <sys/param.h> >#include <assert.h> >#include <err.h> >#include <fcntl.h> >#include <malloc_np.h> >#include <stdlib.h> >#include <string.h> >#include <strings.h> >#include <unistd.h> > > >off_t filesize = 0; >int fd = -1; >unsigned char *control_buf = NULL; >const off_t MAX_FILESIZE = 0x100000; > >static void >do_ftruncate(off_t offs) >{ > if (ftruncate(fd, offs) != 0) > err(1, "ftruncate"); > filesize = offs; >} > >static void >do_fspacectl(ssize_t size, off_t offs) >{ > struct spacectl_range rqsr = { > .r_offset = offs, > .r_len = size, > }; > struct spacectl_range rmsr; > > if (0 != fspacectl(fd, SPACECTL_DEALLOC, &rqsr, 0, &rmsr)) > err(1, "fspacectl"); > assert(0 == rmsr.r_len); > assert(offs + size == rmsr.r_offset); > memset(control_buf + offs, 0, size); >} > >static void >do_mapread(ssize_t size, off_t offs) >{ > unsigned char *p; > off_t pg_offset, page_mask; > size_t map_size; > int i; > > page_mask = getpagesize() - 1; > pg_offset = offs & page_mask; > map_size = pg_offset + size; > > p = mmap(NULL, map_size, PROT_READ, MAP_FILE | MAP_SHARED, fd, > offs - pg_offset); > if (p == MAP_FAILED) > err(1, "mmap"); > > for (i=0; i < size; i++) { > if (*(p + pg_offset + i) != *(control_buf + offs + i)) { > errx(1, "miscompare at offset %#lx. " > "expected %#02x got %#02x", > offs + i, > *(control_buf + offs + i), > *(p + pg_offset + i)); > } > > } > > if (munmap(p, map_size) != 0) > err(1, "munmap"); >} > >static void >do_mapwrite(ssize_t size, off_t offs) >{ > char *buf; > void *p; > off_t pg_offset, page_mask; > size_t map_size; > long i; > > assert(offs + size <= MAX_FILESIZE); > > page_mask = getpagesize() - 1; > pg_offset = offs & page_mask; > map_size = pg_offset + size; > > buf = (char*)malloc(size); > if (buf == NULL) > err(1, "malloc"); > for (i=0; i < size; i++) > buf[i] = random(); > > if (offs + size > filesize) { > /* > * Must manually extend. vm_mmap_vnode will not implicitly > * extend a vnode > */ > do_ftruncate(offs + size); > } > > p = mmap(NULL, map_size, PROT_READ | PROT_WRITE, > MAP_FILE | MAP_SHARED, fd, offs - pg_offset); > if (p == MAP_FAILED) > err(1, "mmap"); > > bcopy(buf, (char*)p + pg_offset, size); > bcopy(buf, control_buf + offs, size); > > free(buf); > // Uncomment to enable msync, which masks the bug > /*if (msync(p, map_size, MS_SYNC) != 0) err(1, "msync");*/ > if (munmap(p, map_size) != 0) > err(1, "munmap"); >} > >void do_write(ssize_t size, off_t offs) >{ > long i; > > for (i=0; i < size; i++) > control_buf[offs + i] = random(); > > if (pwrite(fd, control_buf + offs, size, offs ) != size) > err(1, "pwrite"); > filesize = MAX(filesize, offs + size); >} > > >int main(int argc, char **argv) { > const char *filename; > > if (argc != 2) { > errx(1, "usage: %s <FILENAME>", argv[0]); > } > > filename = argv[1]; > > fd = open(filename, O_CREAT | O_RDWR | O_TRUNC, 0644); > if (fd < 0) > err(1, "open"); > > srandom(12345); > > control_buf = calloc(MAX_FILESIZE, 1); > if (control_buf == NULL) > err(1, "calloc"); > > /* > * These three operations suffice to produce miscompare on either > * fusefs or UFS, albeit at different offsets. > * ZFS, msdosfs, and tmpfs do not seem to be affected. > * PR 269261 fixes it for UFS > */ > /*do_mapwrite(0xd052, 0xee29);*/ > /*do_fspacectl(0x55b0, 0x16166);*/ > /*do_mapread(0xea1f, 0xbb4e);*/ > > /* > * Alternate method also produces failure on fusefs: > * mmapwrite, directwrite, mmapread > */ > /*do_mapwrite(0xd052, 0xee29);*/ > /*if (fcntl(fd, F_SETFL, O_DIRECT) != 0)*/ > /*err(1, "fcntl");*/ > /*do_write(0x55b0, 0x16166);*/ > /*if (fcntl(fd, F_SETFL, 0) != 0)*/ > /*err(1, "fcntl");*/ > /*do_mapread(0xea1f, 0xbb4e);*/ > > /* This sequence produces a failure on NFS */ > do_mapwrite(0x9708, 0xb65af); > do_fspacectl(0x5f4d6,0x492cd); > do_mapwrite(0x13a13, 0x775cb); > do_mapwrite(0x47c8, 0x40d57); > do_mapwrite(0x2c4b5, 0xd3b4b); > do_mapread( 0x5e5a7, 0x34ba5); >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 269328
: 239910 |
239937
|
239981