• Jan Kara's avatar
    ext2: fix data corruption for racing writes · 316cb4ef
    Jan Kara authored
    If two writers allocating blocks to file race with each other (e.g.
    because writepages races with ordinary write or two writepages race with
    each other), ext2_getblock() can be called on the same inode in parallel.
    Before we are going to allocate new blocks, we have to recheck the block
    chain we have obtained so far without holding truncate_mutex.  Otherwise
    we could overwrite the indirect block pointer set by the other writer
    leading to data loss.
    
    The below test program by Ying is able to reproduce the data loss with ext2
    on in BRD in a few minutes if the machine is under memory pressure:
    
    long kMemSize  = 50 << 20;
    int kPageSize = 4096;
    
    int main(int argc, char **argv) {
    	int status;
    	int count = 0;
    	int i;
    	char *fname = "/mnt/test.mmap";
    	char *mem;
    	unlink(fname);
    	int fd = open(fname, O_CREAT | O_EXCL | O_RDWR, 0600);
    	status = ftruncate(fd, kMemSize);
    	mem = mmap(0, kMemSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    	// Fill the memory with 1s.
    	memset(mem, 1, kMemSize);
    	sleep(2);
    	for (i = 0; i < kMemSize; i++) {
    		int byte_good = mem[i] != 0;
    		if (!byte_good && ((i % kPageSize) == 0)) {
    			//printf("%d ", i / kPageSize);
    			count++;
    		}
    	}
    	munmap(mem, kMemSize);
    	close(fd);
    	unlink(fname);
    
    	if (count > 0) {
    		printf("Running %d bad page\n", count);
    		return 1;
    	}
    	return 0;
    }
    
    Cc: Ying Han <yinghan@google.com>
    Cc: Nick Piggin <nickpiggin@yahoo.com.au>
    Signed-off-by: default avatarJan Kara <jack@suse.cz>
    Cc: Mingming Cao <cmm@us.ibm.com>
    Cc: <linux-ext4@vger.kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    316cb4ef
inode.c 42.8 KB