aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Lawrence <paullawrence@google.com>2020-05-04 10:55:19 -0700
committerAlistair Delva <adelva@google.com>2020-05-04 23:37:33 +0000
commit3e4fa206ce8ae4d3141af7514cb5d3d813cd4290 (patch)
tree92abb0f8dbe77a56a24ac79bda6295ccc9d289c0
parentfad68b8babdea151a76fb6fc9ac82521b3ef7b6d (diff)
ANDROID: Incremental fs: Fix issues with very large filesASB-2020-05-05_mainline
Test: incfs_test passes Bug: 155590527 Signed-off-by: Paul Lawrence <paullawrence@google.com> Change-Id: Iaecfcd40e8c089d11b34c7aff2090fbfe0c36219
-rw-r--r--fs/incfs/vfs.c7
-rw-r--r--tools/testing/selftests/filesystems/incfs/incfs_test.c60
2 files changed, 64 insertions, 3 deletions
diff --git a/fs/incfs/vfs.c b/fs/incfs/vfs.c
index 57346990acdf..b5b609bb74c1 100644
--- a/fs/incfs/vfs.c
+++ b/fs/incfs/vfs.c
@@ -894,7 +894,8 @@ static int init_new_file(struct mount_info *mi, struct dentry *dentry,
.mnt = mi->mi_backing_dir_path.mnt,
.dentry = dentry
};
- new_file = dentry_open(&path, O_RDWR | O_NOATIME, mi->mi_owner);
+ new_file = dentry_open(&path, O_RDWR | O_NOATIME | O_LARGEFILE,
+ mi->mi_owner);
if (IS_ERR(new_file)) {
error = PTR_ERR(new_file);
@@ -1902,8 +1903,8 @@ static int file_open(struct inode *inode, struct file *file)
int err = 0;
get_incfs_backing_path(file->f_path.dentry, &backing_path);
- backing_file = dentry_open(&backing_path, O_RDWR | O_NOATIME,
- mi->mi_owner);
+ backing_file = dentry_open(
+ &backing_path, O_RDWR | O_NOATIME | O_LARGEFILE, mi->mi_owner);
path_put(&backing_path);
if (IS_ERR(backing_file)) {
diff --git a/tools/testing/selftests/filesystems/incfs/incfs_test.c b/tools/testing/selftests/filesystems/incfs/incfs_test.c
index 248db59e1a49..c9bccc742bae 100644
--- a/tools/testing/selftests/filesystems/incfs/incfs_test.c
+++ b/tools/testing/selftests/filesystems/incfs/incfs_test.c
@@ -2609,6 +2609,65 @@ failure:
return TEST_FAILURE;
}
+static int large_file(char *mount_dir)
+{
+ char *backing_dir;
+ int cmd_fd = -1;
+ int i;
+ int result = TEST_FAILURE;
+ uint8_t data[INCFS_DATA_FILE_BLOCK_SIZE] = {};
+ int block_count = 3LL * 1024 * 1024 * 1024 / INCFS_DATA_FILE_BLOCK_SIZE;
+ struct incfs_fill_block *block_buf =
+ calloc(block_count, sizeof(struct incfs_fill_block));
+ struct incfs_fill_blocks fill_blocks = {
+ .count = block_count,
+ .fill_blocks = ptr_to_u64(block_buf),
+ };
+ incfs_uuid_t id;
+ int fd;
+
+ backing_dir = create_backing_dir(mount_dir);
+ if (!backing_dir)
+ goto failure;
+
+ if (mount_fs_opt(mount_dir, backing_dir, "readahead=0", false) != 0)
+ goto failure;
+
+ cmd_fd = open_commands_file(mount_dir);
+ if (cmd_fd < 0)
+ goto failure;
+
+ if (emit_file(cmd_fd, NULL, "very_large_file", &id,
+ (uint64_t)block_count * INCFS_DATA_FILE_BLOCK_SIZE,
+ NULL) < 0)
+ goto failure;
+
+ for (i = 0; i < block_count; i++) {
+ block_buf[i].compression = COMPRESSION_NONE;
+ block_buf[i].block_index = i;
+ block_buf[i].data_len = INCFS_DATA_FILE_BLOCK_SIZE;
+ block_buf[i].data = ptr_to_u64(data);
+ }
+
+ fd = open_file_by_id(mount_dir, id, true);
+ if (fd < 0)
+ goto failure;
+
+ if (ioctl(fd, INCFS_IOC_FILL_BLOCKS, &fill_blocks) != block_count)
+ goto failure;
+
+ if (emit_file(cmd_fd, NULL, "very_very_large_file", &id, 1LL << 40,
+ NULL) < 0)
+ goto failure;
+
+ result = TEST_SUCCESS;
+
+failure:
+ close(fd);
+ close(cmd_fd);
+ return result;
+}
+
static char *setup_mount_dir()
{
struct stat st;
@@ -2678,6 +2737,7 @@ int main(int argc, char *argv[])
MAKE_TEST(read_log_test),
MAKE_TEST(get_blocks_test),
MAKE_TEST(get_hash_blocks_test),
+ MAKE_TEST(large_file),
};
#undef MAKE_TEST