aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/inline.c
diff options
context:
space:
mode:
authorTao Ma <boyu.mt@taobao.com>2012-12-10 14:06:02 -0500
committerTheodore Ts'o <tytso@mit.edu>2012-12-10 14:06:02 -0500
commit0d812f77b36c16dff692390508155de2c7f95ea3 (patch)
tree18bf309f2e7a9fb6637ae8385a07f86eb5c05afd /fs/ext4/inline.c
parent941919856c11d4dd11d4fcabb4dab58bd2b146bf (diff)
ext4: evict inline data out if we need to strore xattr in inode
Now we that store data in the inode, in case we need to store some xattrs and inode doesn't have enough space, Andreas suggested that we should keep the xattr(metadata) in and data should be pushed out. So this patch does the work. Signed-off-by: Tao Ma <boyu.mt@taobao.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
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}