|
@@ -381,7 +381,7 @@ out:
|
|
|
static int ext4_prepare_inline_data(handle_t *handle, struct inode *inode,
|
|
|
unsigned int len)
|
|
|
{
|
|
|
- int ret, size;
|
|
|
+ int ret, size, no_expand;
|
|
|
struct ext4_inode_info *ei = EXT4_I(inode);
|
|
|
|
|
|
if (!ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA))
|
|
@@ -391,15 +391,14 @@ static int ext4_prepare_inline_data(handle_t *handle, struct inode *inode,
|
|
|
if (size < len)
|
|
|
return -ENOSPC;
|
|
|
|
|
|
- down_write(&EXT4_I(inode)->xattr_sem);
|
|
|
+ ext4_write_lock_xattr(inode, &no_expand);
|
|
|
|
|
|
if (ei->i_inline_off)
|
|
|
ret = ext4_update_inline_data(handle, inode, len);
|
|
|
else
|
|
|
ret = ext4_create_inline_data(handle, inode, len);
|
|
|
|
|
|
- up_write(&EXT4_I(inode)->xattr_sem);
|
|
|
-
|
|
|
+ ext4_write_unlock_xattr(inode, &no_expand);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -533,7 +532,7 @@ static int ext4_convert_inline_data_to_extent(struct address_space *mapping,
|
|
|
struct inode *inode,
|
|
|
unsigned flags)
|
|
|
{
|
|
|
- int ret, needed_blocks;
|
|
|
+ int ret, needed_blocks, no_expand;
|
|
|
handle_t *handle = NULL;
|
|
|
int retries = 0, sem_held = 0;
|
|
|
struct page *page = NULL;
|
|
@@ -573,7 +572,7 @@ retry:
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
- down_write(&EXT4_I(inode)->xattr_sem);
|
|
|
+ ext4_write_lock_xattr(inode, &no_expand);
|
|
|
sem_held = 1;
|
|
|
/* If some one has already done this for us, just exit. */
|
|
|
if (!ext4_has_inline_data(inode)) {
|
|
@@ -610,7 +609,7 @@ retry:
|
|
|
put_page(page);
|
|
|
page = NULL;
|
|
|
ext4_orphan_add(handle, inode);
|
|
|
- up_write(&EXT4_I(inode)->xattr_sem);
|
|
|
+ ext4_write_unlock_xattr(inode, &no_expand);
|
|
|
sem_held = 0;
|
|
|
ext4_journal_stop(handle);
|
|
|
handle = NULL;
|
|
@@ -636,7 +635,7 @@ out:
|
|
|
put_page(page);
|
|
|
}
|
|
|
if (sem_held)
|
|
|
- up_write(&EXT4_I(inode)->xattr_sem);
|
|
|
+ ext4_write_unlock_xattr(inode, &no_expand);
|
|
|
if (handle)
|
|
|
ext4_journal_stop(handle);
|
|
|
brelse(iloc.bh);
|
|
@@ -729,7 +728,7 @@ convert:
|
|
|
int ext4_write_inline_data_end(struct inode *inode, loff_t pos, unsigned len,
|
|
|
unsigned copied, struct page *page)
|
|
|
{
|
|
|
- int ret;
|
|
|
+ int ret, no_expand;
|
|
|
void *kaddr;
|
|
|
struct ext4_iloc iloc;
|
|
|
|
|
@@ -747,7 +746,7 @@ int ext4_write_inline_data_end(struct inode *inode, loff_t pos, unsigned len,
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
- down_write(&EXT4_I(inode)->xattr_sem);
|
|
|
+ ext4_write_lock_xattr(inode, &no_expand);
|
|
|
BUG_ON(!ext4_has_inline_data(inode));
|
|
|
|
|
|
kaddr = kmap_atomic(page);
|
|
@@ -757,7 +756,7 @@ int ext4_write_inline_data_end(struct inode *inode, loff_t pos, unsigned len,
|
|
|
/* clear page dirty so that writepages wouldn't work for us. */
|
|
|
ClearPageDirty(page);
|
|
|
|
|
|
- up_write(&EXT4_I(inode)->xattr_sem);
|
|
|
+ ext4_write_unlock_xattr(inode, &no_expand);
|
|
|
brelse(iloc.bh);
|
|
|
out:
|
|
|
return copied;
|
|
@@ -768,7 +767,7 @@ ext4_journalled_write_inline_data(struct inode *inode,
|
|
|
unsigned len,
|
|
|
struct page *page)
|
|
|
{
|
|
|
- int ret;
|
|
|
+ int ret, no_expand;
|
|
|
void *kaddr;
|
|
|
struct ext4_iloc iloc;
|
|
|
|
|
@@ -778,11 +777,11 @@ ext4_journalled_write_inline_data(struct inode *inode,
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
- down_write(&EXT4_I(inode)->xattr_sem);
|
|
|
+ ext4_write_lock_xattr(inode, &no_expand);
|
|
|
kaddr = kmap_atomic(page);
|
|
|
ext4_write_inline_data(inode, &iloc, kaddr, 0, len);
|
|
|
kunmap_atomic(kaddr);
|
|
|
- up_write(&EXT4_I(inode)->xattr_sem);
|
|
|
+ ext4_write_unlock_xattr(inode, &no_expand);
|
|
|
|
|
|
return iloc.bh;
|
|
|
}
|
|
@@ -1259,7 +1258,7 @@ out:
|
|
|
int ext4_try_add_inline_entry(handle_t *handle, struct ext4_filename *fname,
|
|
|
struct inode *dir, struct inode *inode)
|
|
|
{
|
|
|
- int ret, inline_size;
|
|
|
+ int ret, inline_size, no_expand;
|
|
|
void *inline_start;
|
|
|
struct ext4_iloc iloc;
|
|
|
|
|
@@ -1267,7 +1266,7 @@ int ext4_try_add_inline_entry(handle_t *handle, struct ext4_filename *fname,
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
|
|
|
- down_write(&EXT4_I(dir)->xattr_sem);
|
|
|
+ ext4_write_lock_xattr(dir, &no_expand);
|
|
|
if (!ext4_has_inline_data(dir))
|
|
|
goto out;
|
|
|
|
|
@@ -1313,7 +1312,7 @@ int ext4_try_add_inline_entry(handle_t *handle, struct ext4_filename *fname,
|
|
|
|
|
|
out:
|
|
|
ext4_mark_inode_dirty(handle, dir);
|
|
|
- up_write(&EXT4_I(dir)->xattr_sem);
|
|
|
+ ext4_write_unlock_xattr(dir, &no_expand);
|
|
|
brelse(iloc.bh);
|
|
|
return ret;
|
|
|
}
|
|
@@ -1673,7 +1672,7 @@ int ext4_delete_inline_entry(handle_t *handle,
|
|
|
struct buffer_head *bh,
|
|
|
int *has_inline_data)
|
|
|
{
|
|
|
- int err, inline_size;
|
|
|
+ int err, inline_size, no_expand;
|
|
|
struct ext4_iloc iloc;
|
|
|
void *inline_start;
|
|
|
|
|
@@ -1681,7 +1680,7 @@ int ext4_delete_inline_entry(handle_t *handle,
|
|
|
if (err)
|
|
|
return err;
|
|
|
|
|
|
- down_write(&EXT4_I(dir)->xattr_sem);
|
|
|
+ ext4_write_lock_xattr(dir, &no_expand);
|
|
|
if (!ext4_has_inline_data(dir)) {
|
|
|
*has_inline_data = 0;
|
|
|
goto out;
|
|
@@ -1715,7 +1714,7 @@ int ext4_delete_inline_entry(handle_t *handle,
|
|
|
|
|
|
ext4_show_inline_dir(dir, iloc.bh, inline_start, inline_size);
|
|
|
out:
|
|
|
- up_write(&EXT4_I(dir)->xattr_sem);
|
|
|
+ ext4_write_unlock_xattr(dir, &no_expand);
|
|
|
brelse(iloc.bh);
|
|
|
if (err != -ENOENT)
|
|
|
ext4_std_error(dir->i_sb, err);
|
|
@@ -1814,11 +1813,11 @@ out:
|
|
|
|
|
|
int ext4_destroy_inline_data(handle_t *handle, struct inode *inode)
|
|
|
{
|
|
|
- int ret;
|
|
|
+ int ret, no_expand;
|
|
|
|
|
|
- down_write(&EXT4_I(inode)->xattr_sem);
|
|
|
+ ext4_write_lock_xattr(inode, &no_expand);
|
|
|
ret = ext4_destroy_inline_data_nolock(handle, inode);
|
|
|
- up_write(&EXT4_I(inode)->xattr_sem);
|
|
|
+ ext4_write_unlock_xattr(inode, &no_expand);
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
@@ -1903,7 +1902,7 @@ out:
|
|
|
void ext4_inline_data_truncate(struct inode *inode, int *has_inline)
|
|
|
{
|
|
|
handle_t *handle;
|
|
|
- int inline_size, value_len, needed_blocks;
|
|
|
+ int inline_size, value_len, needed_blocks, no_expand;
|
|
|
size_t i_size;
|
|
|
void *value = NULL;
|
|
|
struct ext4_xattr_ibody_find is = {
|
|
@@ -1920,7 +1919,7 @@ void ext4_inline_data_truncate(struct inode *inode, int *has_inline)
|
|
|
if (IS_ERR(handle))
|
|
|
return;
|
|
|
|
|
|
- down_write(&EXT4_I(inode)->xattr_sem);
|
|
|
+ ext4_write_lock_xattr(inode, &no_expand);
|
|
|
if (!ext4_has_inline_data(inode)) {
|
|
|
*has_inline = 0;
|
|
|
ext4_journal_stop(handle);
|
|
@@ -1978,7 +1977,7 @@ out_error:
|
|
|
up_write(&EXT4_I(inode)->i_data_sem);
|
|
|
out:
|
|
|
brelse(is.iloc.bh);
|
|
|
- up_write(&EXT4_I(inode)->xattr_sem);
|
|
|
+ ext4_write_unlock_xattr(inode, &no_expand);
|
|
|
kfree(value);
|
|
|
if (inode->i_nlink)
|
|
|
ext4_orphan_del(handle, inode);
|
|
@@ -1994,7 +1993,7 @@ out:
|
|
|
|
|
|
int ext4_convert_inline_data(struct inode *inode)
|
|
|
{
|
|
|
- int error, needed_blocks;
|
|
|
+ int error, needed_blocks, no_expand;
|
|
|
handle_t *handle;
|
|
|
struct ext4_iloc iloc;
|
|
|
|
|
@@ -2016,15 +2015,10 @@ int ext4_convert_inline_data(struct inode *inode)
|
|
|
goto out_free;
|
|
|
}
|
|
|
|
|
|
- down_write(&EXT4_I(inode)->xattr_sem);
|
|
|
- if (!ext4_has_inline_data(inode)) {
|
|
|
- up_write(&EXT4_I(inode)->xattr_sem);
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
- error = ext4_convert_inline_data_nolock(handle, inode, &iloc);
|
|
|
- up_write(&EXT4_I(inode)->xattr_sem);
|
|
|
-out:
|
|
|
+ ext4_write_lock_xattr(inode, &no_expand);
|
|
|
+ if (ext4_has_inline_data(inode))
|
|
|
+ error = ext4_convert_inline_data_nolock(handle, inode, &iloc);
|
|
|
+ ext4_write_unlock_xattr(inode, &no_expand);
|
|
|
ext4_journal_stop(handle);
|
|
|
out_free:
|
|
|
brelse(iloc.bh);
|