1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2012 Jilin Xpd <jilinxpd@gmail.com> 14 * Copyright 2018 Nexenta Systems, Inc. 15 */ 16 17 /* 18 * After close file but before munmap it, test if we can still write into 19 * mapped pages and the dirty pages are eventually synced to file, 20 * the result should be that we can do it as long as we dont munmap it. 21 * When userland attempts to close mapped file, smbfs will keep SMB FID 22 * alive if there are mapped pages(not unmapped yet), so the otW will stay 23 * open until last ref. to vnode goes away. 24 * This program tests if smbfs works as we said. 25 */ 26 27 #include <sys/mman.h> 28 #include <sys/types.h> 29 #include <sys/stat.h> 30 #include <fcntl.h> 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <unistd.h> 34 #include <string.h> 35 #include <errno.h> 36 37 int 38 main(int argc, char **argv) 39 { 40 char *file_addr; 41 char *p; 42 size_t filesize; 43 size_t blksize; 44 int fid; 45 int i; 46 char *c = "?#*%&"; 47 48 if (argc != 2) { 49 fprintf(stderr, "\tusage:\n\tclose_wr <filename>\n"); 50 return (1); 51 } 52 53 /* open test file */ 54 fid = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, 55 S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH); 56 if (fid == -1) { 57 fprintf(stderr, "open %s error=%d\n", argv[1], errno); 58 return (1); 59 } 60 61 /* extend file */ 62 filesize = 64 * 1024; 63 if (ftruncate(fid, filesize) == -1) { 64 fprintf(stderr, "ftrunc %s error=%d\n", argv[1], errno); 65 return (1); 66 } 67 68 /* map file */ 69 file_addr = mmap(NULL, filesize, 70 PROT_READ | PROT_WRITE, MAP_SHARED, fid, 0); 71 if (file_addr == MAP_FAILED) { 72 fprintf(stderr, "mmap %s error=%d\n", argv[1], errno); 73 return (1); 74 } 75 76 /* erase file */ 77 memset(file_addr, 0, filesize); 78 79 /* close file here! */ 80 if (close(fid) == -1) { 81 fprintf(stderr, "close %s error=%d\n", argv[1], errno); 82 return (1); 83 } 84 85 /* 86 * write somthing into mapped addr after close file, 87 * it should be ok before munmap 88 */ 89 blksize = filesize / 4; 90 for (i = 0, p = file_addr; i < 4; i++, p += blksize) { 91 memset(p, c[i], blksize); 92 } 93 94 /* sync pages to file */ 95 if (msync(file_addr, filesize, MS_SYNC) == -1) { 96 fprintf(stderr, "msync %s error=%d\n", argv[1], errno); 97 return (1); 98 } 99 100 /* unmap file */ 101 if (munmap(file_addr, filesize) == -1) { 102 fprintf(stderr, "munmap %s error=%d\n", argv[1], errno); 103 return (1); 104 } 105 106 return (0); 107 } 108