summaryrefslogtreecommitdiffstats
path: root/fs/ext4/inline.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/inline.c')
-rw-r--r--fs/ext4/inline.c48
1 files changed, 43 insertions, 5 deletions
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index bf5f77803885..cec651e2646c 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -207,8 +207,8 @@ out:
207/* 207/*
208 * write the buffer to the inline inode. 208 * write the buffer to the inline inode.
209 * If 'create' is set, we don't need to do the extra copy in the xattr 209 * If 'create' is set, we don't need to do the extra copy in the xattr
210 * value since it is already handled by ext4_xattr_ibody_set. That saves 210 * value since it is already handled by ext4_xattr_ibody_inline_set.
211 * us one memcpy. 211 * That saves us one memcpy.
212 */ 212 */
213void ext4_write_inline_data(struct inode *inode, struct ext4_iloc *iloc, 213void ext4_write_inline_data(struct inode *inode, struct ext4_iloc *iloc,
214 void *buffer, loff_t pos, unsigned int len) 214 void *buffer, loff_t pos, unsigned int len)
@@ -285,7 +285,7 @@ static int ext4_create_inline_data(handle_t *handle,
285 285
286 BUG_ON(!is.s.not_found); 286 BUG_ON(!is.s.not_found);
287 287
288 error = ext4_xattr_ibody_set(handle, inode, &i, &is); 288 error = ext4_xattr_ibody_inline_set(handle, inode, &i, &is);
289 if (error) { 289 if (error) {
290 if (error == -ENOSPC) 290 if (error == -ENOSPC)
291 ext4_clear_inode_state(inode, 291 ext4_clear_inode_state(inode,
@@ -354,7 +354,7 @@ static int ext4_update_inline_data(handle_t *handle, struct inode *inode,
354 i.value = value; 354 i.value = value;
355 i.value_len = len; 355 i.value_len = len;
356 356
357 error = ext4_xattr_ibody_set(handle, inode, &i, &is); 357 error = ext4_xattr_ibody_inline_set(handle, inode, &i, &is);
358 if (error) 358 if (error)
359 goto out; 359 goto out;
360 360
@@ -427,7 +427,7 @@ static int ext4_destroy_inline_data_nolock(handle_t *handle,
427 if (error) 427 if (error)
428 goto out; 428 goto out;
429 429
430 error = ext4_xattr_ibody_set(handle, inode, &i, &is); 430 error = ext4_xattr_ibody_inline_set(handle, inode, &i, &is);
431 if (error) 431 if (error)
432 goto out; 432 goto out;
433 433
@@ -1715,3 +1715,41 @@ out:
1715 up_read(&EXT4_I(inode)->xattr_sem); 1715 up_read(&EXT4_I(inode)->xattr_sem);
1716 return (error < 0 ? error : 0); 1716 return (error < 0 ? error : 0);
1717} 1717}
1718
1719/*
1720 * Called during xattr set, and if we can sparse space 'needed',
1721 * just create the extent tree evict the data to the outer block.
1722 *
1723 * We use jbd2 instead of page cache to move data to the 1st block
1724 * so that the whole transaction can be committed as a whole and
1725 * the data isn't lost because of the delayed page cache write.
1726 */
1727int ext4_try_to_evict_inline_data(handle_t *handle,
1728 struct inode *inode,
1729 int needed)
1730{
1731 int error;
1732 struct ext4_xattr_entry *entry;
1733 struct ext4_xattr_ibody_header *header;
1734 struct ext4_inode *raw_inode;
1735 struct ext4_iloc iloc;
1736
1737 error = ext4_get_inode_loc(inode, &iloc);
1738 if (error)
1739 return error;
1740
1741 raw_inode = ext4_raw_inode(&iloc);
1742 header = IHDR(inode, raw_inode);
1743 entry = (struct ext4_xattr_entry *)((void *)raw_inode +
1744 EXT4_I(inode)->i_inline_off);
1745 if (EXT4_XATTR_LEN(entry->e_name_len) +
1746 EXT4_XATTR_SIZE(le32_to_cpu(entry->e_value_size)) < needed) {
1747 error = -ENOSPC;
1748 goto out;
1749 }
1750
1751 error = ext4_convert_inline_data_nolock(handle, inode, &iloc);
1752out:
1753 brelse(iloc.bh);
1754 return error;
1755}