Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751718Ab1EEURr (ORCPT ); Thu, 5 May 2011 16:17:47 -0400 Received: from mx1.redhat.com ([209.132.183.28]:44513 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752223Ab1EEURH (ORCPT ); Thu, 5 May 2011 16:17:07 -0400 From: Josef Bacik To: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-btrfs@vger.kernel.org, linux-ext4@vger.kernel.org, viro@ZenIV.linux.org.uk Subject: [TEST] test the seek_hole/seek_data functionality Date: Thu, 5 May 2011 16:16:59 -0400 Message-Id: <1304626619-1588-4-git-send-email-josef@redhat.com> In-Reply-To: <1304626619-1588-1-git-send-email-josef@redhat.com> References: <1304626619-1588-1-git-send-email-josef@redhat.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5779 Lines: 271 This is my very rough tester for testing seek_hole/seek_data. Please look over it and make sure we all agree that the semantics are correct. My btrfs patch passes with this and ext3 passes as well. I still have to added fallocate() to it, but for now this seems to cover most of the corner cases. Thanks, Josef #include #include #include #include #include #include #include #define SEEK_HOLE 3 #define SEEK_DATA 4 #define ERROR(str) \ fprintf(stderr, "%s: pos=%lu, errno=%d\n", str, pos, errno) static int reset_file(int fd) { int ret; ret = ftruncate(fd, 0); if (ret < 0) { fprintf(stderr, "Truncate failed: %d\n", errno); return 1; } return 0; } int main(int argc, char **argv) { char buf[4096 * 4]; ssize_t bytes; off_t pos; int prealloc_is_hole = 0; int whole_file_is_data = 0; int ret; int i; int fd; fd = open("testfile", O_RDWR|O_CREAT|O_TRUNC, 0644); if (fd < 0) { fprintf(stderr, "Failed to open testfile: %d\n", errno); return 1; } /* Empty file */ printf("Testing an empty file\n"); pos = lseek(fd, 0, SEEK_DATA); if (pos != -1) { if (errno == EINVAL) { fprintf(stderr, "Kernel does not support seek " "hole/data\n"); close(fd); return 1; } if (errno != ENXIO) ERROR("Seek data did not return a proper error"); close(fd); return 1; } pos = lseek(fd, 0, SEEK_HOLE); if (pos != -1 && errno != ENXIO) { ERROR("Seek hole did not return a proper error"); close(fd); return 1; } memset(&buf, 'a', 4096 * 4); /* * All data file */ printf("Testing a normal data filled file\n"); for (i = 0; i < 4; i++) { bytes = write(fd, &buf, 4096); if (bytes < 4096) { fprintf(stderr, "Failed to write to testfile: %d\n", errno); close(fd); return 1; } } pos = lseek(fd, 0, SEEK_HOLE); if (pos != (4096 * 4) || pos == -1) { ERROR("Seek hole failed to dump us out at the end of the file"); close(fd); return 1; } pos = lseek(fd, 0, SEEK_DATA); if (pos != 0) { ERROR("Seek data failed to dump us out at the beginning of the" " file"); close(fd); return 1; } /* * File with a hole at the front and data at the end */ printf("Testing file with hole at the start and data in the rest\n"); if (reset_file(fd)) { close(fd); return 1; } bytes = pwrite(fd, &buf, 4096 * 3, 4096); if (bytes < (4096 * 3)) { fprintf(stderr, "Failed to write to testfile: %d\n"); close(fd); return 1; } pos = lseek(fd, 0, SEEK_HOLE); if (pos != 0 && pos != (4096 * 4)) { ERROR("Seek hole failed to return 0"); close(fd); return 1; } else if (pos == (4096 * 4)) { whole_file_is_data = 1; printf("Current file system views treats the entire file as " "data\n"); } pos = lseek(fd, 0, SEEK_DATA); if (pos != 4096 && (pos != 0 && whole_file_is_data)) { if (whole_file_is_data) ERROR("Seek data failed to return 0"); else ERROR("Seek data failed to return 4096"); close(fd); return 1; } if (whole_file_is_data) { pos = lseek(fd, 1, SEEK_DATA); if (pos != -1 && errno != ENXIO) { ERROR("Seek data failed to retun an error"); close(fd); return 1; } } /* * File with a hole at the end and data at the beginning */ printf("Testing file with hole at the end and data at the beginning\n"); if (reset_file(fd)) { close(fd); return 1; } ret = ftruncate(fd, 4096 * 4); if (ret < 0) { fprintf(stderr, "Truncate failed: %d\n", errno); close(fd); return 1; } pwrite(fd, &buf, 4096 * 3, 0); if (bytes < (4096 * 3)) { fprintf(stderr, "Failed to write to testfile: %d\n", errno); close(fd); return 1; } pos = lseek(fd, 0, SEEK_HOLE); if (pos != (4096 * 3) && (pos != (4096 * 4) && whole_file_is_data)) { ERROR("Seeking hole didn't work right"); close(fd); return 1; } if (whole_file_is_data) { pos = lseek(fd, pos, SEEK_HOLE); if (pos != -1 && errno != ENXIO) { ERROR("Seeking hole didn't return error"); close(fd); return 1; } printf("No more tests to run since we treat the whole file as " "data\n"); goto out; } pos = lseek(fd, pos, SEEK_HOLE); if (pos != (4096 * 3)) { ERROR("Seek hole didn't return same position"); close(fd); return 1; } pos = lseek(fd, pos+1, SEEK_HOLE); if (pos != (4096 * 4)) { ERROR("Seek hole didn't return the end of the file"); close(fd); return 1; } pos = lseek(fd, pos, SEEK_DATA); if (pos != -1 && errno != ENXIO) { ERROR("Seek data didn't return ENXIO"); close(fd); return 1; } /* * Hole - Data - Hole - Data file */ printf("Testing file [Hole][Data][Hole][Data]\n"); if (reset_file(fd)) { close(fd); return 1; } ret = ftruncate(fd, 4096 * 4); if (ret < 0) { fprintf(stderr, "ftruncate failed: %d\n", errno); close(fd); return 1; } bytes = pwrite(fd, &buf, 4096, 4096); if (bytes < 4096) { fprintf(stderr, "Failed to write: %d\n", errno); close(fd); return 1; } bytes = pwrite(fd, &buf, 4096, 4096 * 3); if (bytes < 4096) { fprintf(stderr, "Failed to write: %d\n", errno); close(fd); return 1; } pos = lseek(fd, 0, SEEK_DATA); if (pos != 4096) { ERROR("Seek data did not return 4096"); close(fd); return 1; } pos = lseek(fd, pos, SEEK_HOLE); if (pos != (4096 * 2)) { ERROR("Seek hole did not return 4096*2"); close(fd); return 1; } pos = lseek(fd, pos, SEEK_DATA); if (pos != (4096 * 3)) { ERROR("Seek data did not return 4096*3"); close(fd); return 1; } out: close(fd); return 0; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/