2008-03-11 05:47:32

by Aneesh Kumar K.V

[permalink] [raw]
Subject: [PATCH] ext4: Fix fallocate to update the file size in each transaction.

ext4_fallocate need to update file size in each transaction. Otherwise
ife we crash the file size won't be updated. We were also not marking
the inode dirty after updating file size before. Also when we try to
retry allocation due to ENOSPC make sure we reset the variable ret so
that we actually do a retry.

Signed-off-by: Aneesh Kumar K.V <[email protected]>
---
fs/ext4/extents.c | 89 ++++++++++++++++++++++------------------------------
1 files changed, 38 insertions(+), 51 deletions(-)

diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 0ad0042..69f1dee 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -2783,6 +2783,28 @@ int ext4_ext_writepage_trans_blocks(struct inode *inode, int num)
return needed;
}

+static void ext4_falloc_update_inode(struct inode *inode,
+ int mode, loff_t new_size, int update_ctime)
+{
+ struct timespec now;
+
+ if (update_ctime) {
+ now = current_fs_time(inode->i_sb);
+ if (!timespec_equal(&inode->i_ctime, &now))
+ inode->i_ctime = now;
+ }
+ /*
+ * Update only when preallocation was requested beyond
+ * the file size.
+ */
+ if (!(mode & FALLOC_FL_KEEP_SIZE) &&
+ new_size > i_size_read(inode)) {
+ i_size_write(inode, new_size);
+ EXT4_I(inode)->i_disksize = new_size;
+ }
+
+}
+
/*
* preallocate space for a file. This implements ext4's fallocate inode
* operation, which gets called from sys_fallocate system call.
@@ -2794,8 +2816,8 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len)
{
handle_t *handle;
ext4_lblk_t block;
+ loff_t new_size;
unsigned long max_blocks;
- ext4_fsblk_t nblocks = 0;
int ret = 0;
int ret2 = 0;
int retries = 0;
@@ -2814,9 +2836,12 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len)
return -ENODEV;

block = offset >> blkbits;
+ /*
+ * We can't just convert len to max_blocks because
+ * If blocksize = 4096 offset = 3072 and len = 2048
+ */
max_blocks = (EXT4_BLOCK_ALIGN(len + offset, blkbits) >> blkbits)
- - block;
-
+ - block;
/*
* credits to insert 1 extent into extent tree + buffers to be able to
* modify 1 super block, 1 block bitmap and 1 group descriptor.
@@ -2832,7 +2857,6 @@ retry:
ret = PTR_ERR(handle);
break;
}
-
ret = ext4_get_blocks_wrap(handle, inode, block,
max_blocks, &map_bh,
EXT4_CREATE_UNINITIALIZED_EXT, 0);
@@ -2848,61 +2872,24 @@ retry:
ret2 = ext4_journal_stop(handle);
break;
}
- if (ret > 0) {
- /* check wrap through sign-bit/zero here */
- if ((block + ret) < 0 || (block + ret) < block) {
- ret = -EIO;
- ext4_mark_inode_dirty(handle, inode);
- ret2 = ext4_journal_stop(handle);
- break;
- }
- if (buffer_new(&map_bh) && ((block + ret) >
- (EXT4_BLOCK_ALIGN(i_size_read(inode), blkbits)
- >> blkbits)))
- nblocks = nblocks + ret;
- }
-
- /* Update ctime if new blocks get allocated */
- if (nblocks) {
- struct timespec now;
-
- now = current_fs_time(inode->i_sb);
- if (!timespec_equal(&inode->i_ctime, &now))
- inode->i_ctime = now;
- }
+ if ((block + ret) >= (EXT4_BLOCK_ALIGN(offset + len,
+ blkbits) >> blkbits))
+ new_size = offset + len;
+ else
+ new_size = (block + ret) << blkbits;

+ ext4_falloc_update_inode(inode, mode, new_size,
+ buffer_new(&map_bh));
ext4_mark_inode_dirty(handle, inode);
ret2 = ext4_journal_stop(handle);
if (ret2)
break;
}
-
- if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
+ if (ret == -ENOSPC &&
+ ext4_should_retry_alloc(inode->i_sb, &retries)) {
+ ret = 0;
goto retry;
-
- /*
- * Time to update the file size.
- * Update only when preallocation was requested beyond the file size.
- */
- if (!(mode & FALLOC_FL_KEEP_SIZE) &&
- (offset + len) > i_size_read(inode)) {
- if (ret > 0) {
- /*
- * if no error, we assume preallocation succeeded
- * completely
- */
- i_size_write(inode, offset + len);
- EXT4_I(inode)->i_disksize = i_size_read(inode);
- } else if (ret < 0 && nblocks) {
- /* Handle partial allocation scenario */
- loff_t newsize;
-
- newsize = (nblocks << blkbits) + i_size_read(inode);
- i_size_write(inode, EXT4_BLOCK_ALIGN(newsize, blkbits));
- EXT4_I(inode)->i_disksize = i_size_read(inode);
- }
}


2008-03-11 06:23:38

by Aneesh Kumar K.V

[permalink] [raw]
Subject: Re: [PATCH] ext4: Fix fallocate to update the file size in each transaction.

On Tue, Mar 11, 2008 at 11:17:25AM +0530, Aneesh Kumar K.V wrote:
> ext4_fallocate need to update file size in each transaction. Otherwise
> ife we crash the file size won't be updated. We were also not marking
> the inode dirty after updating file size before. Also when we try to
> retry allocation due to ENOSPC make sure we reset the variable ret so
> that we actually do a retry.
>
> Signed-off-by: Aneesh Kumar K.V <[email protected]>

Tested fallocate series with a modifed fsx-linux

/usr/local/fsx-linux/bin/fsx-linux -x 1 -n -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -n -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -n -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -n -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -n -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -n -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -n -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -n -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -n -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -n -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -r 4096 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -r 2048 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -b 1000 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -s 1 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -l 500000 -r 4096 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -l 500000 -r 2048 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -l 500000 -r 4096 -t 4096 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -l 500000 -r 2048 -t 2048 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -l 500000 -r 4096 -t 4096 -w 4096 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -l 500000 -r 4096 -t 2048 -w 2048 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -l 500000 -r 4096 -t 4096 -w 4096 -A -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -l 500000 -r 4096 -t 2048 -w 2048 -A -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -l 500000 -r 4096 -t 4096 -w 4096 -A -O -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -l 500000 -r 4096 -t 2048 -w 2048 -A -O -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -l 500000 -r 4096 -t 4096 -w 4096 -A -S 0 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -l 500000 -r 4096 -t 2048 -w 2048 -A -S 2000 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -l 500000 -r 4096 -t 4096 -w 4096 -W -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -l 500000 -r 4096 -t 2048 -w 2048 -W -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -l 500000 -r 4096 -t 4096 -w 4096 -W -A -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -l 500000 -r 4096 -t 2048 -w 2048 -W -A -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -l 500000 -r 4096 -t 4096 -w 4096 -A -R -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -l 500000 -r 4096 -t 2048 -w 2048 -A -R -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -l 500000 -r 4096 -t 4096 -w 4096 -Z -R -W -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -l 500000 -r 4096 -t 2048 -w 2048 -Z -R -W -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -l 500000 -r 4096 -w 4096 -Z -R -W -A -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -A -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 1024 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 2048 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 4096 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 8192 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 16384 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 32768 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 128000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 1024 -A /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 2048 -A /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 4096 -A /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 8192 -A /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 16384 -A /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 32768 -A /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 128000 -A /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 1024 -A -l 500000 -r 2048 -t 4096 -w 4096 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 2048 -A -l 500000 -r 512 -t 2048 -w 4096 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 4096 -A -l 500000 -r 512 -t 4096 -w 2048 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 8192 -A -l 500000 -r 1024 -t 2048 -w 2048 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 16384 -A -l 500000 -r 4096 -t 4096 -w 2048 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 32768 -A -l 500000 -r 2048 -t 2048 -w 2048 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 128000 -A -l 500000 -r 512 -t 4096 -w 1024 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 32768 -r 4096 -w 2048 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 128000 -r 2048 -w 4096 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 1024 -l 500000 -r 4096 -t 4096 -w 4096 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 2048 -l 500000 -r 4096 -t 2048 -w 2048 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 4096 -l 500000 -r 4096 -t 4096 -w 4096 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 8192 -l 500000 -r 4096 -t 2048 -w 2048 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 16384 -l 500000 -r 4096 -t 4096 -w 4096 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 32768 -l 500000 -r 4096 -t 2048 -w 2048 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 128000 -l 500000 -r 4096 -t 4096 -w 4096 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 128000 -l 500000 -r 4096 -t 4096 -w 4096 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 16384 -A -l 500000 -r 4096 -t 4096 -w 4096 /mnt/tmp/junkfile1 &
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 32768 -A -l 500000 -r 4096 -t 2048 -w 2048 /mnt/tmp/junkfile2 &
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 128000 -A -l 500000 -r 4096 -t 4096 -w 4096 /mnt/tmp/junkfile3 &
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 16384 -A -l 500000 -r 4096 -t 4096 -w 4096 /mnt/tmp/junkfile4 &
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 32768 -A -l 500000 -r 4096 -t 2048 -w 2048 /mnt/tmp/junkfile5 &
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 128000 -A -l 500000 -r 4096 -t 4096 -w 4096 /mnt/tmp/junkfile6 &
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -A /mnt/tmp/junkfile7 &
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 100000 -A /mnt/tmp/junkfile8 &
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 100000 -A /mnt/tmp/junkfile9 &
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 8192 -A -l 500000 -r 1024 -t 2048 -w 1024 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 1 -N 10000 -o 16384 -A -l 500000 -r 2048 -t 4096 -w 1024 -Z -R -W /mnt/tmp/junkfile

/usr/local/fsx-linux/bin/fsx-linux -x 2 -n -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -n -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -n -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -n -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -n -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -n -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -n -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -n -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -n -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -n -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -r 4096 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -r 2048 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -b 1000 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -s 1 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -l 500000 -r 4096 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -l 500000 -r 2048 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -l 500000 -r 4096 -t 4096 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -l 500000 -r 2048 -t 2048 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -l 500000 -r 4096 -t 4096 -w 4096 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -l 500000 -r 4096 -t 2048 -w 2048 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -l 500000 -r 4096 -t 4096 -w 4096 -A -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -l 500000 -r 4096 -t 2048 -w 2048 -A -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -l 500000 -r 4096 -t 4096 -w 4096 -A -O -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -l 500000 -r 4096 -t 2048 -w 2048 -A -O -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -l 500000 -r 4096 -t 4096 -w 4096 -A -S 0 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -l 500000 -r 4096 -t 2048 -w 2048 -A -S 2000 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -l 500000 -r 4096 -t 4096 -w 4096 -W -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -l 500000 -r 4096 -t 2048 -w 2048 -W -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -l 500000 -r 4096 -t 4096 -w 4096 -W -A -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -l 500000 -r 4096 -t 2048 -w 2048 -W -A -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -l 500000 -r 4096 -t 4096 -w 4096 -A -R -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -l 500000 -r 4096 -t 2048 -w 2048 -A -R -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -l 500000 -r 4096 -t 4096 -w 4096 -Z -R -W -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -l 500000 -r 4096 -t 2048 -w 2048 -Z -R -W -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -l 500000 -r 4096 -w 4096 -Z -R -W -A -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -A -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 1024 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 2048 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 4096 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 8192 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 16384 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 32768 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 128000 /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 1024 -A /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 2048 -A /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 4096 -A /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 8192 -A /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 16384 -A /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 32768 -A /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 128000 -A /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 1024 -A -l 500000 -r 2048 -t 4096 -w 4096 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 2048 -A -l 500000 -r 512 -t 2048 -w 4096 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 4096 -A -l 500000 -r 512 -t 4096 -w 2048 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 8192 -A -l 500000 -r 1024 -t 2048 -w 2048 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 16384 -A -l 500000 -r 4096 -t 4096 -w 2048 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 32768 -A -l 500000 -r 2048 -t 2048 -w 2048 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 128000 -A -l 500000 -r 512 -t 4096 -w 1024 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 32768 -r 4096 -w 2048 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 128000 -r 2048 -w 4096 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 1024 -l 500000 -r 4096 -t 4096 -w 4096 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 2048 -l 500000 -r 4096 -t 2048 -w 2048 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 4096 -l 500000 -r 4096 -t 4096 -w 4096 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 8192 -l 500000 -r 4096 -t 2048 -w 2048 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 16384 -l 500000 -r 4096 -t 4096 -w 4096 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 32768 -l 500000 -r 4096 -t 2048 -w 2048 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 128000 -l 500000 -r 4096 -t 4096 -w 4096 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 128000 -l 500000 -r 4096 -t 4096 -w 4096 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 16384 -A -l 500000 -r 4096 -t 4096 -w 4096 /mnt/tmp/junkfile1 &
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 32768 -A -l 500000 -r 4096 -t 2048 -w 2048 /mnt/tmp/junkfile2 &
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 128000 -A -l 500000 -r 4096 -t 4096 -w 4096 /mnt/tmp/junkfile3 &
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 16384 -A -l 500000 -r 4096 -t 4096 -w 4096 /mnt/tmp/junkfile4 &
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 32768 -A -l 500000 -r 4096 -t 2048 -w 2048 /mnt/tmp/junkfile5 &
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 128000 -A -l 500000 -r 4096 -t 4096 -w 4096 /mnt/tmp/junkfile6 &
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -A /mnt/tmp/junkfile7 &
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 100000 -A /mnt/tmp/junkfile8 &
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 100000 -A /mnt/tmp/junkfile9 &
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 8192 -A -l 500000 -r 1024 -t 2048 -w 1024 -Z -R -W /mnt/tmp/junkfile
/usr/local/fsx-linux/bin/fsx-linux -x 2 -N 10000 -o 16384 -A -l 500000 -r 2048 -t 4096 -w 1024 -Z -R -W /mnt/tmp/junkfile



--- /home/kvaneesh/tmp/autotest/client/tests/fsx/src/fsx-linux.c 2007-09-12 20:56:25.000000000 +0530
+++ fsx-linux.c 2008-03-09 17:03:56.000000000 +0530
@@ -114,10 +114,12 @@
int mapped_writes = 1; /* -W flag disables */
int mapped_reads = 1; /* -R flag disables it */
int fsxgoodfd = 0;
int o_direct; /* -Z */
int aio = 0;
+int prealloc = 0; /* -x [0|1]run test with prealloc default
+ disabled */

#ifdef AIO
int aio_rw(int rw, int fd, char *buf, unsigned len, unsigned offset);
#define READ 0
#define WRITE 1
@@ -849,10 +851,11 @@
-P: save .fsxlog and .fsxgood files in dirpath (default ./)\n\
-S seed: for random # generator (default 1) 0 gets timestamp\n\
-W: mapped write operations DISabled\n\
-R: read() system calls only (mapped reads disabled)\n\
-Z: O_DIRECT (use -R, -W, -r and -w too)\n\
+ -x: run test after preallocating the area (1|2) 2 to not update size.\n\
fname: this filename is REQUIRED (no default)\n");
exit(90);
}


@@ -973,12 +976,12 @@
goodfile[0] = 0;
logfile[0] = 0;

setvbuf(stdout, (char *)0, _IOLBF, 0); /* line buffered stdout */

- while ((ch = getopt(argc, argv, "b:c:dfl:m:no:p:qr:s:t:w:AD:LN:OP:RS:WZ"))
- != EOF)
+ while ((ch = getopt(argc, argv,
+ "b:c:dfl:m:no:p:qr:s:t:w:AD:LN:OP:RS:WZx:")) != EOF)
switch (ch) {
case 'b':
simulatedopcount = getnum(optarg, &endp);
if (!quiet)
fprintf(stdout, "Will begin at operation %ld\n",
@@ -1098,10 +1101,15 @@
fprintf(stdout, "mapped writes DISABLED\n");
break;
case 'Z':
o_direct = O_DIRECT;
break;
+ case 'x':
+ prealloc = getnum(optarg, &endp);
+ if (prealloc <= 0)
+ usage();
+ break;
default:
usage();
/* NOTREACHED */
}
argc -= optind;
@@ -1128,10 +1136,43 @@
O_RDWR|(lite ? 0 : O_CREAT|O_TRUNC)|o_direct, 0666);
if (fd < 0) {
prterr(fname);
exit(91);
}
+#define FALLOC_FL_KEEP_SIZE 0x01
+#ifdef __i386__
+#define __NR_fallocate 324
+ loff_t offset, maxlen;
+ offset = 0;
+ maxlen = maxfilelen;
+ if (prealloc == 1) {
+ if (syscall(__NR_fallocate, fd, 0, offset, maxlen) < 0) {
+ prterr(fname);
+ exit(97);
+ }
+ } else if (prealloc == 2) {
+ if (syscall(__NR_fallocate, fd, FALLOC_FL_KEEP_SIZE, offset, maxlen) < 0) {
+ prterr(fname);
+ exit(97);
+ }
+ }
+#elif defined (__powerpc__)
+#define __NR_fallocate 309
+ /* Work only with 32 bit user space */
+ unsigned int maxlen = maxfilelen;
+ if (prealloc == 1) {
+ if (syscall(__NR_fallocate, fd, 0, 0, 0, 0, maxlen) < 0) {
+ prterr(fname);
+ exit(97);
+ }
+ } else if (prealloc == 2) {
+ if (syscall(__NR_fallocate, fd, FALLOC_FL_KEEP_SIZE, 0, 0, 0, maxlen) < 0) {
+ prterr(fname);
+ exit(97);
+ }
+ }
+#endif
strncat(goodfile, fname, 256);
strcat (goodfile, ".fsxgood");
fsxgoodfd = open(goodfile, O_RDWR|O_CREAT|O_TRUNC, 0666);
if (fsxgoodfd < 0) {
prterr(goodfile);

2008-03-13 07:53:00

by Andreas Dilger

[permalink] [raw]
Subject: Re: [PATCH] ext4: Fix fallocate to update the file size in each transaction.

On Mar 11, 2008 11:25 +0530, Aneesh Kumar K.V wrote:
> + -x: run test after preallocating the area (1|2) 2 to not update size.\n\

The issue with preallocating just a single area in fsx is that this isn't
much different than starting the test with a single large write or truncate.

What would be a lot more useful is to have fsx continually do fallocate
requests of variable sizes during the test. This would be quite similar
to a "write" operation, except that it wouldn't change any existing data
and holes would still read back as zero. The only difference is in the
"do not update size" test any fallocate at the end of the file would not
increase the file size.

This would exercise the fallocate code a LOT because it would put unwritten
extents in the middle of the file, map a single fallocate to multiple
discontiguous holes of the file (not overwriting existing allocated data
in the middle of the file), verify fallocate of an overlapping unwritten
extent works, etc.

> +#define FALLOC_FL_KEEP_SIZE 0x01
> +#ifdef __i386__
> +#define __NR_fallocate 324
> + loff_t offset, maxlen;
> + offset = 0;
> + maxlen = maxfilelen;
> + if (prealloc == 1) {
> + if (syscall(__NR_fallocate, fd, 0, offset, maxlen) < 0) {
> + prterr(fname);
> + exit(97);
> + }
> + } else if (prealloc == 2) {
> + if (syscall(__NR_fallocate, fd, FALLOC_FL_KEEP_SIZE, offset, maxlen) < 0) {
> + prterr(fname);
> + exit(97);
> + }
> + }
> +#elif defined (__powerpc__)
> +#define __NR_fallocate 309
> + /* Work only with 32 bit user space */
> + unsigned int maxlen = maxfilelen;
> + if (prealloc == 1) {
> + if (syscall(__NR_fallocate, fd, 0, 0, 0, 0, maxlen) < 0) {
> + prterr(fname);
> + exit(97);
> + }
> + } else if (prealloc == 2) {
> + if (syscall(__NR_fallocate, fd, FALLOC_FL_KEEP_SIZE, 0, 0, 0, maxlen) < 0) {
> + prterr(fname);
> + exit(97);
> + }
> + }
> +#endif

This should be moved into a separate "do_fallocate()" wrapper function
that takes normal fallocate parameters fd, offset, len. In the future it
would just call "fallocate()" directly.

Cheers, Andreas
--
Andreas Dilger
Sr. Staff Engineer, Lustre Group
Sun Microsystems of Canada, Inc.


2008-03-13 14:12:14

by Eric Sandeen

[permalink] [raw]
Subject: Re: [PATCH] ext4: Fix fallocate to update the file size in each transaction.

Andreas Dilger wrote:
> On Mar 11, 2008 11:25 +0530, Aneesh Kumar K.V wrote:
>> + -x: run test after preallocating the area (1|2) 2 to not update size.\n\
>
> The issue with preallocating just a single area in fsx is that this isn't
> much different than starting the test with a single large write or truncate.

except that the filesystem does still have to manage the unwritten
extent splits properly... but I agree that ongoing extending and
non-extending fallocates of various sizes would be very interesting.

-Eric

> What would be a lot more useful is to have fsx continually do fallocate
> requests of variable sizes during the test. This would be quite similar
> to a "write" operation, except that it wouldn't change any existing data
> and holes would still read back as zero. The only difference is in the
> "do not update size" test any fallocate at the end of the file would not
> increase the file size.
>
> This would exercise the fallocate code a LOT because it would put unwritten
> extents in the middle of the file, map a single fallocate to multiple
> discontiguous holes of the file (not overwriting existing allocated data
> in the middle of the file), verify fallocate of an overlapping unwritten
> extent works, etc.
>