|
|
@@ -186,6 +186,7 @@ bool need_SSR(struct f2fs_sb_info *sbi)
|
|
|
|
|
|
void 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;
|
|
|
|
|
|
@@ -204,6 +205,10 @@ void register_inmem_page(struct inode *inode, struct page *page)
|
|
|
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]);
|
|
|
inc_page_count(F2FS_I_SB(inode), F2FS_INMEM_PAGES);
|
|
|
mutex_unlock(&fi->inmem_lock);
|
|
|
|
|
|
@@ -262,12 +267,41 @@ next:
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+void drop_inmem_pages_all(struct f2fs_sb_info *sbi)
|
|
|
+{
|
|
|
+ struct list_head *head = &sbi->inode_list[ATOMIC_FILE];
|
|
|
+ struct inode *inode;
|
|
|
+ struct f2fs_inode_info *fi;
|
|
|
+next:
|
|
|
+ spin_lock(&sbi->inode_lock[ATOMIC_FILE]);
|
|
|
+ if (list_empty(head)) {
|
|
|
+ spin_unlock(&sbi->inode_lock[ATOMIC_FILE]);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ fi = list_first_entry(head, struct f2fs_inode_info, inmem_ilist);
|
|
|
+ inode = igrab(&fi->vfs_inode);
|
|
|
+ spin_unlock(&sbi->inode_lock[ATOMIC_FILE]);
|
|
|
+
|
|
|
+ if (inode) {
|
|
|
+ drop_inmem_pages(inode);
|
|
|
+ iput(inode);
|
|
|
+ }
|
|
|
+ congestion_wait(BLK_RW_ASYNC, HZ/50);
|
|
|
+ cond_resched();
|
|
|
+ goto next;
|
|
|
+}
|
|
|
+
|
|
|
void drop_inmem_pages(struct inode *inode)
|
|
|
{
|
|
|
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
|
|
|
struct f2fs_inode_info *fi = F2FS_I(inode);
|
|
|
|
|
|
mutex_lock(&fi->inmem_lock);
|
|
|
__revoke_inmem_pages(inode, &fi->inmem_pages, true, false);
|
|
|
+ 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);
|
|
|
@@ -399,6 +433,10 @@ int commit_inmem_pages(struct inode *inode)
|
|
|
/* drop all uncommitted pages */
|
|
|
__revoke_inmem_pages(inode, &fi->inmem_pages, true, false);
|
|
|
}
|
|
|
+ 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);
|