Merge "f2fs: avoid infinite GC loop due to stale atomic files"
This commit is contained in:
commit
da393190c1
2 changed files with 18 additions and 26 deletions
|
@ -1820,6 +1820,8 @@ static int f2fs_ioc_getversion(struct file *filp, unsigned long arg)
|
|||
static int f2fs_ioc_start_atomic_write(struct file *filp)
|
||||
{
|
||||
struct inode *inode = file_inode(filp);
|
||||
struct f2fs_inode_info *fi = F2FS_I(inode);
|
||||
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
|
||||
int ret;
|
||||
|
||||
if (!inode_owner_or_capable(inode))
|
||||
|
@ -1859,6 +1861,12 @@ static int f2fs_ioc_start_atomic_write(struct file *filp)
|
|||
goto out;
|
||||
}
|
||||
|
||||
spin_lock(&sbi->inode_lock[ATOMIC_FILE]);
|
||||
if (list_empty(&fi->inmem_ilist))
|
||||
list_add_tail(&fi->inmem_ilist, &sbi->inode_list[ATOMIC_FILE]);
|
||||
spin_unlock(&sbi->inode_lock[ATOMIC_FILE]);
|
||||
|
||||
/* add inode in inmem_list first and set atomic_file */
|
||||
set_inode_flag(inode, FI_ATOMIC_FILE);
|
||||
clear_inode_flag(inode, FI_ATOMIC_REVOKE_REQUEST);
|
||||
up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
|
||||
|
@ -1900,11 +1908,8 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp)
|
|||
goto err_out;
|
||||
|
||||
ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 0, true);
|
||||
if (!ret) {
|
||||
clear_inode_flag(inode, FI_ATOMIC_FILE);
|
||||
F2FS_I(inode)->i_gc_failures[GC_FAILURE_ATOMIC] = 0;
|
||||
stat_dec_atomic_write(inode);
|
||||
}
|
||||
if (!ret)
|
||||
f2fs_drop_inmem_pages(inode);
|
||||
} else {
|
||||
ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 1, false);
|
||||
}
|
||||
|
|
|
@ -185,8 +185,6 @@ bool f2fs_need_SSR(struct f2fs_sb_info *sbi)
|
|||
|
||||
void f2fs_register_inmem_page(struct inode *inode, struct page *page)
|
||||
{
|
||||
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
|
||||
struct f2fs_inode_info *fi = F2FS_I(inode);
|
||||
struct inmem_pages *new;
|
||||
|
||||
f2fs_trace_pid(page);
|
||||
|
@ -200,15 +198,11 @@ void f2fs_register_inmem_page(struct inode *inode, struct page *page)
|
|||
INIT_LIST_HEAD(&new->list);
|
||||
|
||||
/* increase reference count with clean state */
|
||||
mutex_lock(&fi->inmem_lock);
|
||||
get_page(page);
|
||||
list_add_tail(&new->list, &fi->inmem_pages);
|
||||
spin_lock(&sbi->inode_lock[ATOMIC_FILE]);
|
||||
if (list_empty(&fi->inmem_ilist))
|
||||
list_add_tail(&fi->inmem_ilist, &sbi->inode_list[ATOMIC_FILE]);
|
||||
spin_unlock(&sbi->inode_lock[ATOMIC_FILE]);
|
||||
mutex_lock(&F2FS_I(inode)->inmem_lock);
|
||||
list_add_tail(&new->list, &F2FS_I(inode)->inmem_pages);
|
||||
inc_page_count(F2FS_I_SB(inode), F2FS_INMEM_PAGES);
|
||||
mutex_unlock(&fi->inmem_lock);
|
||||
mutex_unlock(&F2FS_I(inode)->inmem_lock);
|
||||
|
||||
trace_f2fs_register_inmem_page(page, INMEM);
|
||||
}
|
||||
|
@ -330,19 +324,17 @@ void f2fs_drop_inmem_pages(struct inode *inode)
|
|||
mutex_lock(&fi->inmem_lock);
|
||||
__revoke_inmem_pages(inode, &fi->inmem_pages,
|
||||
true, false, true);
|
||||
|
||||
if (list_empty(&fi->inmem_pages)) {
|
||||
spin_lock(&sbi->inode_lock[ATOMIC_FILE]);
|
||||
if (!list_empty(&fi->inmem_ilist))
|
||||
list_del_init(&fi->inmem_ilist);
|
||||
spin_unlock(&sbi->inode_lock[ATOMIC_FILE]);
|
||||
}
|
||||
mutex_unlock(&fi->inmem_lock);
|
||||
}
|
||||
|
||||
clear_inode_flag(inode, FI_ATOMIC_FILE);
|
||||
fi->i_gc_failures[GC_FAILURE_ATOMIC] = 0;
|
||||
stat_dec_atomic_write(inode);
|
||||
|
||||
spin_lock(&sbi->inode_lock[ATOMIC_FILE]);
|
||||
if (!list_empty(&fi->inmem_ilist))
|
||||
list_del_init(&fi->inmem_ilist);
|
||||
spin_unlock(&sbi->inode_lock[ATOMIC_FILE]);
|
||||
}
|
||||
|
||||
void f2fs_drop_inmem_page(struct inode *inode, struct page *page)
|
||||
|
@ -471,11 +463,6 @@ int f2fs_commit_inmem_pages(struct inode *inode)
|
|||
|
||||
mutex_lock(&fi->inmem_lock);
|
||||
err = __f2fs_commit_inmem_pages(inode);
|
||||
|
||||
spin_lock(&sbi->inode_lock[ATOMIC_FILE]);
|
||||
if (!list_empty(&fi->inmem_ilist))
|
||||
list_del_init(&fi->inmem_ilist);
|
||||
spin_unlock(&sbi->inode_lock[ATOMIC_FILE]);
|
||||
mutex_unlock(&fi->inmem_lock);
|
||||
|
||||
clear_inode_flag(inode, FI_ATOMIC_COMMIT);
|
||||
|
|
Loading…
Add table
Reference in a new issue