f2fs: rename f2fs_set/clear_bit to f2fs_test_and_set/clear_bit
[firefly-linux-kernel-4.4.55.git] / fs / f2fs / segment.c
index 923cb76fdc46e1e9f26b3a5014690e5c58d59fd0..19de23b119fa99b787530b752d4d9dc6f9acd5d3 100644 (file)
@@ -178,7 +178,8 @@ void register_inmem_page(struct inode *inode, struct page *page)
 {
        struct f2fs_inode_info *fi = F2FS_I(inode);
        struct inmem_pages *new;
-
+       int err;
+retry:
        new = f2fs_kmem_cache_alloc(inmem_entry_slab, GFP_NOFS);
 
        /* add atomic page indices to the list */
@@ -187,11 +188,37 @@ void register_inmem_page(struct inode *inode, struct page *page)
 
        /* increase reference count with clean state */
        mutex_lock(&fi->inmem_lock);
+       err = radix_tree_insert(&fi->inmem_root, page->index, new);
+       if (err == -EEXIST) {
+               mutex_unlock(&fi->inmem_lock);
+               kmem_cache_free(inmem_entry_slab, new);
+               return;
+       } else if (err) {
+               mutex_unlock(&fi->inmem_lock);
+               kmem_cache_free(inmem_entry_slab, new);
+               goto retry;
+       }
        get_page(page);
        list_add_tail(&new->list, &fi->inmem_pages);
        mutex_unlock(&fi->inmem_lock);
 }
 
+void invalidate_inmem_page(struct inode *inode, struct page *page)
+{
+       struct f2fs_inode_info *fi = F2FS_I(inode);
+       struct inmem_pages *cur;
+
+       mutex_lock(&fi->inmem_lock);
+       cur = radix_tree_lookup(&fi->inmem_root, page->index);
+       if (cur) {
+               radix_tree_delete(&fi->inmem_root, cur->page->index);
+               f2fs_put_page(cur->page, 0);
+               list_del(&cur->list);
+               kmem_cache_free(inmem_entry_slab, cur);
+       }
+       mutex_unlock(&fi->inmem_lock);
+}
+
 void commit_inmem_pages(struct inode *inode, bool abort)
 {
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
@@ -216,6 +243,7 @@ void commit_inmem_pages(struct inode *inode, bool abort)
                        do_write_data_page(cur->page, &fio);
                        submit_bio = true;
                }
+               radix_tree_delete(&fi->inmem_root, cur->page->index);
                f2fs_put_page(cur->page, 1);
                list_del(&cur->list);
                kmem_cache_free(inmem_entry_slab, cur);
@@ -620,10 +648,10 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del)
 
        /* Update valid block bitmap */
        if (del > 0) {
-               if (f2fs_set_bit(offset, se->cur_valid_map))
+               if (f2fs_test_and_set_bit(offset, se->cur_valid_map))
                        f2fs_bug_on(sbi, 1);
        } else {
-               if (!f2fs_clear_bit(offset, se->cur_valid_map))
+               if (!f2fs_test_and_clear_bit(offset, se->cur_valid_map))
                        f2fs_bug_on(sbi, 1);
        }
        if (!f2fs_test_bit(offset, se->ckpt_valid_map))
@@ -1004,6 +1032,7 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range)
                                                range->len < sbi->blocksize)
                return -EINVAL;
 
+       cpc.trimmed = 0;
        if (end <= MAIN_BLKADDR(sbi))
                goto out;
 
@@ -1015,7 +1044,6 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range)
        cpc.trim_start = start_segno;
        cpc.trim_end = end_segno;
        cpc.trim_minlen = range->minlen >> sbi->log_blocksize;
-       cpc.trimmed = 0;
 
        /* do checkpoint to issue discard commands safely */
        write_checkpoint(sbi, &cpc);
@@ -1687,7 +1715,7 @@ void flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
         * #2, flush sit entries to sit page.
         */
        list_for_each_entry_safe(ses, tmp, head, set_list) {
-               struct page *page;
+               struct page *page = NULL;
                struct f2fs_sit_block *raw_sit = NULL;
                unsigned int start_segno = ses->start_segno;
                unsigned int end = min(start_segno + SIT_ENTRY_PER_BLOCK,