Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 95031
b: refs/heads/master
c: fd28784
h: refs/heads/master
i:
  95029: 35981fe
  95027: f7a7cea
  95023: dc9a8c3
v: v3
  • Loading branch information
Aneesh Kumar K.V authored and Theodore Ts'o committed Apr 29, 2008
1 parent a63e001 commit fdeec2f
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 52 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 267e4db9ac28a09973476e7ec2cb6807e609d35a
refs/heads/master: fd28784adc079afa905df56204b1298ddb4d0bfe
89 changes: 38 additions & 51 deletions trunk/fs/ext4/extents.c
Original file line number Diff line number Diff line change
Expand Up @@ -2785,6 +2785,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.
Expand All @@ -2796,8 +2818,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;
Expand All @@ -2816,9 +2838,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.
Expand All @@ -2834,7 +2859,6 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len)
ret = PTR_ERR(handle);
break;
}

ret = ext4_get_blocks_wrap(handle, inode, block,
max_blocks, &map_bh,
EXT4_CREATE_UNINITIALIZED_EXT, 0);
Expand All @@ -2850,61 +2874,24 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len)
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);
}
}

mutex_unlock(&inode->i_mutex);
return ret > 0 ? ret2 : ret;
}

0 comments on commit fdeec2f

Please sign in to comment.