mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
A very large number of cleanups and bug fixes --- in particular for
the ext4 encryption patches, which is a new feature added in the last merge window. Also fix a number of long-standing xfstest failures. (Quota writes failing due to ENOSPC, a race between truncate and writepage in data=journalled mode that was causing generic/068 to fail, and other corner cases.) Also add support for FALLOC_FL_INSERT_RANGE, and improve jbd2 performance eliminating locking when a buffer is modified more than once during a transaction (which is very common for allocation bitmaps, for example), in which case the state of the journalled buffer head doesn't need to change. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQEcBAABCAAGBQJVi3PeAAoJEPL5WVaVDYGj+I0H/jRPexvyvnGfxiqs1sxIlbSk cwewFJSsuKsy/pGYdmHvozWZyWGGORc89NrxoNwdbG+axvHbgUWt/3+vF+rzmaek vX4v9QvCEo4PfpRgzbnYJFhbxGMJtwci887sq1o/UoNXikFYT2kz8rpdf0++eO5W /GJNRA5ZUY0L0eeloUILAMrBr7KjtkI2oXwOZt5q68jh7B3n3XdNQXyEiQS/28aK QYcFrqA/e2Fiuk6l5OSGBCP38mySu+x0nBTLT5LFwwrUBnoZvGtdjM6Sj/yADDDn uP/Zpq56aLzkFRwwItrDaF26BIf2MhIH/WUYs65CraEGxjMaiPuzAudGA/iUVL8= =1BdR -----END PGP SIGNATURE----- Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4 Pull ext4 updates from Ted Ts'o: "A very large number of cleanups and bug fixes --- in particular for the ext4 encryption patches, which is a new feature added in the last merge window. Also fix a number of long-standing xfstest failures. (Quota writes failing due to ENOSPC, a race between truncate and writepage in data=journalled mode that was causing generic/068 to fail, and other corner cases.) Also add support for FALLOC_FL_INSERT_RANGE, and improve jbd2 performance eliminating locking when a buffer is modified more than once during a transaction (which is very common for allocation bitmaps, for example), in which case the state of the journalled buffer head doesn't need to change" [ I renamed "ext4_follow_link()" to "ext4_encrypted_follow_link()" in the merge resolution, to make it clear that that function is _only_ used for encrypted symlinks. The function doesn't actually work for non-encrypted symlinks at all, and they use the generic helpers - Linus ] * tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (52 commits) ext4: set lazytime on remount if MS_LAZYTIME is set by mount ext4: only call ext4_truncate when size <= isize ext4: make online defrag error reporting consistent ext4: minor cleanup of ext4_da_reserve_space() ext4: don't retry file block mapping on bigalloc fs with non-extent file ext4: prevent ext4_quota_write() from failing due to ENOSPC ext4: call sync_blockdev() before invalidate_bdev() in put_super() jbd2: speedup jbd2_journal_dirty_metadata() jbd2: get rid of open coded allocation retry loop ext4: improve warning directory handling messages jbd2: fix ocfs2 corrupt when updating journal superblock fails ext4: mballoc: avoid 20-argument function call ext4: wait for existing dio workers in ext4_alloc_file_blocks() ext4: recalculate journal credits as inode depth changes jbd2: use GFP_NOFS in jbd2_cleanup_journal_tail() ext4: use swap() in mext_page_double_lock() ext4: use swap() in memswap() ext4: fix race between truncate and __ext4_journalled_writepage() ext4 crypto: fail the mount if blocksize != pagesize ext4: Add support FALLOC_FL_INSERT_RANGE for fallocate ...
This commit is contained in:
commit
d857da7b70
29 changed files with 1498 additions and 1365 deletions
|
@ -731,18 +731,18 @@ int ext4_get_block(struct inode *inode, sector_t iblock,
|
|||
* `handle' can be NULL if create is zero
|
||||
*/
|
||||
struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode,
|
||||
ext4_lblk_t block, int create)
|
||||
ext4_lblk_t block, int map_flags)
|
||||
{
|
||||
struct ext4_map_blocks map;
|
||||
struct buffer_head *bh;
|
||||
int create = map_flags & EXT4_GET_BLOCKS_CREATE;
|
||||
int err;
|
||||
|
||||
J_ASSERT(handle != NULL || create == 0);
|
||||
|
||||
map.m_lblk = block;
|
||||
map.m_len = 1;
|
||||
err = ext4_map_blocks(handle, inode, &map,
|
||||
create ? EXT4_GET_BLOCKS_CREATE : 0);
|
||||
err = ext4_map_blocks(handle, inode, &map, map_flags);
|
||||
|
||||
if (err == 0)
|
||||
return create ? ERR_PTR(-ENOSPC) : NULL;
|
||||
|
@ -788,11 +788,11 @@ errout:
|
|||
}
|
||||
|
||||
struct buffer_head *ext4_bread(handle_t *handle, struct inode *inode,
|
||||
ext4_lblk_t block, int create)
|
||||
ext4_lblk_t block, int map_flags)
|
||||
{
|
||||
struct buffer_head *bh;
|
||||
|
||||
bh = ext4_getblk(handle, inode, block, create);
|
||||
bh = ext4_getblk(handle, inode, block, map_flags);
|
||||
if (IS_ERR(bh))
|
||||
return bh;
|
||||
if (!bh || buffer_uptodate(bh))
|
||||
|
@ -1261,13 +1261,12 @@ static int ext4_journalled_write_end(struct file *file,
|
|||
}
|
||||
|
||||
/*
|
||||
* Reserve a single cluster located at lblock
|
||||
* Reserve space for a single cluster
|
||||
*/
|
||||
static int ext4_da_reserve_space(struct inode *inode, ext4_lblk_t lblock)
|
||||
static int ext4_da_reserve_space(struct inode *inode)
|
||||
{
|
||||
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
|
||||
struct ext4_inode_info *ei = EXT4_I(inode);
|
||||
unsigned int md_needed;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
|
@ -1279,25 +1278,14 @@ static int ext4_da_reserve_space(struct inode *inode, ext4_lblk_t lblock)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* recalculate the amount of metadata blocks to reserve
|
||||
* in order to allocate nrblocks
|
||||
* worse case is one extent per block
|
||||
*/
|
||||
spin_lock(&ei->i_block_reservation_lock);
|
||||
/*
|
||||
* ext4_calc_metadata_amount() has side effects, which we have
|
||||
* to be prepared undo if we fail to claim space.
|
||||
*/
|
||||
md_needed = 0;
|
||||
trace_ext4_da_reserve_space(inode, 0);
|
||||
|
||||
if (ext4_claim_free_clusters(sbi, 1, 0)) {
|
||||
spin_unlock(&ei->i_block_reservation_lock);
|
||||
dquot_release_reservation_block(inode, EXT4_C2B(sbi, 1));
|
||||
return -ENOSPC;
|
||||
}
|
||||
ei->i_reserved_data_blocks++;
|
||||
trace_ext4_da_reserve_space(inode);
|
||||
spin_unlock(&ei->i_block_reservation_lock);
|
||||
|
||||
return 0; /* success */
|
||||
|
@ -1566,9 +1554,9 @@ add_delayed:
|
|||
* then we don't need to reserve it again. However we still need
|
||||
* to reserve metadata for every block we're going to write.
|
||||
*/
|
||||
if (EXT4_SB(inode->i_sb)->s_cluster_ratio <= 1 ||
|
||||
if (EXT4_SB(inode->i_sb)->s_cluster_ratio == 1 ||
|
||||
!ext4_find_delalloc_cluster(inode, map->m_lblk)) {
|
||||
ret = ext4_da_reserve_space(inode, iblock);
|
||||
ret = ext4_da_reserve_space(inode);
|
||||
if (ret) {
|
||||
/* not enough space to reserve */
|
||||
retval = ret;
|
||||
|
@ -1701,19 +1689,32 @@ static int __ext4_journalled_writepage(struct page *page,
|
|||
ext4_walk_page_buffers(handle, page_bufs, 0, len,
|
||||
NULL, bget_one);
|
||||
}
|
||||
/* As soon as we unlock the page, it can go away, but we have
|
||||
* references to buffers so we are safe */
|
||||
/*
|
||||
* We need to release the page lock before we start the
|
||||
* journal, so grab a reference so the page won't disappear
|
||||
* out from under us.
|
||||
*/
|
||||
get_page(page);
|
||||
unlock_page(page);
|
||||
|
||||
handle = ext4_journal_start(inode, EXT4_HT_WRITE_PAGE,
|
||||
ext4_writepage_trans_blocks(inode));
|
||||
if (IS_ERR(handle)) {
|
||||
ret = PTR_ERR(handle);
|
||||
put_page(page);
|
||||
goto out_no_pagelock;
|
||||
}
|
||||
BUG_ON(!ext4_handle_valid(handle));
|
||||
|
||||
lock_page(page);
|
||||
put_page(page);
|
||||
if (page->mapping != mapping) {
|
||||
/* The page got truncated from under us */
|
||||
ext4_journal_stop(handle);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
BUG_ON(!ext4_handle_valid(handle));
|
||||
|
||||
if (inline_data) {
|
||||
BUFFER_TRACE(inode_bh, "get write access");
|
||||
ret = ext4_journal_get_write_access(handle, inode_bh);
|
||||
|
@ -1739,6 +1740,8 @@ static int __ext4_journalled_writepage(struct page *page,
|
|||
NULL, bput_one);
|
||||
ext4_set_inode_state(inode, EXT4_STATE_JDATA);
|
||||
out:
|
||||
unlock_page(page);
|
||||
out_no_pagelock:
|
||||
brelse(inode_bh);
|
||||
return ret;
|
||||
}
|
||||
|
@ -4681,8 +4684,10 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
ext4_journal_stop(handle);
|
||||
}
|
||||
|
||||
if (attr->ia_valid & ATTR_SIZE && attr->ia_size != inode->i_size) {
|
||||
if (attr->ia_valid & ATTR_SIZE) {
|
||||
handle_t *handle;
|
||||
loff_t oldsize = inode->i_size;
|
||||
int shrink = (attr->ia_size <= inode->i_size);
|
||||
|
||||
if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
|
||||
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
|
||||
|
@ -4690,24 +4695,26 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
if (attr->ia_size > sbi->s_bitmap_maxbytes)
|
||||
return -EFBIG;
|
||||
}
|
||||
if (!S_ISREG(inode->i_mode))
|
||||
return -EINVAL;
|
||||
|
||||
if (IS_I_VERSION(inode) && attr->ia_size != inode->i_size)
|
||||
inode_inc_iversion(inode);
|
||||
|
||||
if (S_ISREG(inode->i_mode) &&
|
||||
if (ext4_should_order_data(inode) &&
|
||||
(attr->ia_size < inode->i_size)) {
|
||||
if (ext4_should_order_data(inode)) {
|
||||
error = ext4_begin_ordered_truncate(inode,
|
||||
error = ext4_begin_ordered_truncate(inode,
|
||||
attr->ia_size);
|
||||
if (error)
|
||||
goto err_out;
|
||||
}
|
||||
if (error)
|
||||
goto err_out;
|
||||
}
|
||||
if (attr->ia_size != inode->i_size) {
|
||||
handle = ext4_journal_start(inode, EXT4_HT_INODE, 3);
|
||||
if (IS_ERR(handle)) {
|
||||
error = PTR_ERR(handle);
|
||||
goto err_out;
|
||||
}
|
||||
if (ext4_handle_valid(handle)) {
|
||||
if (ext4_handle_valid(handle) && shrink) {
|
||||
error = ext4_orphan_add(handle, inode);
|
||||
orphan = 1;
|
||||
}
|
||||
|
@ -4726,15 +4733,13 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
up_write(&EXT4_I(inode)->i_data_sem);
|
||||
ext4_journal_stop(handle);
|
||||
if (error) {
|
||||
ext4_orphan_del(NULL, inode);
|
||||
if (orphan)
|
||||
ext4_orphan_del(NULL, inode);
|
||||
goto err_out;
|
||||
}
|
||||
} else {
|
||||
loff_t oldsize = inode->i_size;
|
||||
|
||||
i_size_write(inode, attr->ia_size);
|
||||
pagecache_isize_extended(inode, oldsize, inode->i_size);
|
||||
}
|
||||
if (!shrink)
|
||||
pagecache_isize_extended(inode, oldsize, inode->i_size);
|
||||
|
||||
/*
|
||||
* Blocks are going to be removed from the inode. Wait
|
||||
|
@ -4754,13 +4759,9 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
* in data=journal mode to make pages freeable.
|
||||
*/
|
||||
truncate_pagecache(inode, inode->i_size);
|
||||
if (shrink)
|
||||
ext4_truncate(inode);
|
||||
}
|
||||
/*
|
||||
* We want to call ext4_truncate() even if attr->ia_size ==
|
||||
* inode->i_size for cases like truncation of fallocated space
|
||||
*/
|
||||
if (attr->ia_valid & ATTR_SIZE)
|
||||
ext4_truncate(inode);
|
||||
|
||||
if (!rc) {
|
||||
setattr_copy(inode, attr);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue