|
@@ -849,15 +849,16 @@ int ext4_da_write_inline_data_begin(struct address_space *mapping,
|
|
|
handle_t *handle;
|
|
|
struct page *page;
|
|
|
struct ext4_iloc iloc;
|
|
|
+ int retries;
|
|
|
|
|
|
ret = ext4_get_inode_loc(inode, &iloc);
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
|
|
|
+retry_journal:
|
|
|
handle = ext4_journal_start(inode, EXT4_HT_INODE, 1);
|
|
|
if (IS_ERR(handle)) {
|
|
|
ret = PTR_ERR(handle);
|
|
|
- handle = NULL;
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
@@ -867,7 +868,7 @@ int ext4_da_write_inline_data_begin(struct address_space *mapping,
|
|
|
if (inline_size >= pos + len) {
|
|
|
ret = ext4_prepare_inline_data(handle, inode, pos + len);
|
|
|
if (ret && ret != -ENOSPC)
|
|
|
- goto out;
|
|
|
+ goto out_journal;
|
|
|
}
|
|
|
|
|
|
if (ret == -ENOSPC) {
|
|
@@ -875,6 +876,10 @@ int ext4_da_write_inline_data_begin(struct address_space *mapping,
|
|
|
inode,
|
|
|
flags,
|
|
|
fsdata);
|
|
|
+ ext4_journal_stop(handle);
|
|
|
+ if (ret == -ENOSPC &&
|
|
|
+ ext4_should_retry_alloc(inode->i_sb, &retries))
|
|
|
+ goto retry_journal;
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
@@ -887,7 +892,7 @@ int ext4_da_write_inline_data_begin(struct address_space *mapping,
|
|
|
page = grab_cache_page_write_begin(mapping, 0, flags);
|
|
|
if (!page) {
|
|
|
ret = -ENOMEM;
|
|
|
- goto out;
|
|
|
+ goto out_journal;
|
|
|
}
|
|
|
|
|
|
down_read(&EXT4_I(inode)->xattr_sem);
|
|
@@ -904,16 +909,15 @@ int ext4_da_write_inline_data_begin(struct address_space *mapping,
|
|
|
|
|
|
up_read(&EXT4_I(inode)->xattr_sem);
|
|
|
*pagep = page;
|
|
|
- handle = NULL;
|
|
|
brelse(iloc.bh);
|
|
|
return 1;
|
|
|
out_release_page:
|
|
|
up_read(&EXT4_I(inode)->xattr_sem);
|
|
|
unlock_page(page);
|
|
|
page_cache_release(page);
|
|
|
+out_journal:
|
|
|
+ ext4_journal_stop(handle);
|
|
|
out:
|
|
|
- if (handle)
|
|
|
- ext4_journal_stop(handle);
|
|
|
brelse(iloc.bh);
|
|
|
return ret;
|
|
|
}
|
|
@@ -1837,7 +1841,6 @@ int ext4_try_to_evict_inline_data(handle_t *handle,
|
|
|
{
|
|
|
int error;
|
|
|
struct ext4_xattr_entry *entry;
|
|
|
- struct ext4_xattr_ibody_header *header;
|
|
|
struct ext4_inode *raw_inode;
|
|
|
struct ext4_iloc iloc;
|
|
|
|
|
@@ -1846,7 +1849,6 @@ int ext4_try_to_evict_inline_data(handle_t *handle,
|
|
|
return error;
|
|
|
|
|
|
raw_inode = ext4_raw_inode(&iloc);
|
|
|
- header = IHDR(inode, raw_inode);
|
|
|
entry = (struct ext4_xattr_entry *)((void *)raw_inode +
|
|
|
EXT4_I(inode)->i_inline_off);
|
|
|
if (EXT4_XATTR_LEN(entry->e_name_len) +
|
|
@@ -1924,9 +1926,11 @@ void ext4_inline_data_truncate(struct inode *inode, int *has_inline)
|
|
|
}
|
|
|
|
|
|
/* Clear the content within i_blocks. */
|
|
|
- if (i_size < EXT4_MIN_INLINE_DATA_SIZE)
|
|
|
- memset(ext4_raw_inode(&is.iloc)->i_block + i_size, 0,
|
|
|
- EXT4_MIN_INLINE_DATA_SIZE - i_size);
|
|
|
+ if (i_size < EXT4_MIN_INLINE_DATA_SIZE) {
|
|
|
+ void *p = (void *) ext4_raw_inode(&is.iloc)->i_block;
|
|
|
+ memset(p + i_size, 0,
|
|
|
+ EXT4_MIN_INLINE_DATA_SIZE - i_size);
|
|
|
+ }
|
|
|
|
|
|
EXT4_I(inode)->i_inline_size = i_size <
|
|
|
EXT4_MIN_INLINE_DATA_SIZE ?
|