1 /* 2 * Copyright (c) 2011 Cyril Hrubis <chrubis (at) suse.cz> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 12 * the GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19 #ifndef LTP_AIODIO_COMMON_SPARSE 20 #define LTP_AIODIO_COMMON_SPARSE 21 22 #include "common_checkzero.h" 23 24 /* 25 * This code tries to create dirty free blocks on 26 * the HDD so there is a chance that blocks to be allocated 27 * for a file are filled with something else than zeroes. 28 * 29 * The usefulness of this is IMHO questionable. 30 */ 31 static void dirty_freeblocks(int size) 32 { 33 int fd; 34 void *p; 35 int pg; 36 char *filename = "dirty_freeblocks"; 37 38 pg = getpagesize(); 39 size = ((size + pg - 1) / pg) * pg; 40 41 fd = open(filename, O_CREAT|O_RDWR|O_EXCL, 0600); 42 43 if (fd < 0) 44 tst_brkm(TBROK|TERRNO, cleanup, "failed to open '%s'", filename); 45 46 SAFE_FTRUNCATE(cleanup, fd, size); 47 48 p = SAFE_MMAP(cleanup, NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED|MAP_FILE, fd, 0); 49 50 memset(p, 0xaa, size); 51 msync(p, size, MS_SYNC); 52 munmap(p, size); 53 close(fd); 54 unlink(filename); 55 } 56 57 /* 58 * Scale value by kilo, mega, or giga. 59 */ 60 long long scale_by_kmg(long long value, char scale) 61 { 62 switch (scale) { 63 case 'g': 64 case 'G': 65 value *= 1024; 66 case 'm': 67 case 'M': 68 value *= 1024; 69 case 'k': 70 case 'K': 71 value *= 1024; 72 break; 73 case '\0': 74 break; 75 default: 76 usage(); 77 break; 78 } 79 return value; 80 } 81 82 /* 83 * Make sure we read only zeroes, 84 * either there is a hole in the file, 85 * or zeroes were actually written by parent. 86 */ 87 static void read_sparse(char *filename, int filesize) 88 { 89 int fd; 90 int i, j, r; 91 char buf[4096]; 92 93 fd = open(filename, O_RDONLY); 94 if (fd == -1) { 95 if (debug) 96 fprintf(stderr, "Child %i failed to open '%s'\n", 97 getpid(), filename); 98 exit(10); 99 } 100 101 if (debug) 102 fprintf(stderr, "Child %i has opened '%s' for reading\n", 103 getpid(), filename); 104 105 for (i = 0; i < 100000000; i++) { 106 off_t offset = 0; 107 char *badbuf; 108 109 if (debug) 110 fprintf(stderr, "Child %i loop %i\n", getpid(), i); 111 112 lseek(fd, SEEK_SET, 0); 113 for (j = 0; j < filesize+1; j += sizeof(buf)) { 114 r = read(fd, buf, sizeof(buf)); 115 if (r > 0) { 116 if ((badbuf = check_zero(buf, r))) { 117 fprintf(stderr, "non-zero read at offset %u\n", 118 (unsigned int)(offset + badbuf - buf)); 119 exit(10); 120 } 121 } 122 offset += r; 123 } 124 } 125 126 exit(0); 127 } 128 129 #endif /* LTP_AIODIO_COMMON_SPARSE */ 130