]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - fs/f2fs/data.c
Merge remote-tracking branch 'f2fs/dev'
[karo-tx-linux.git] / fs / f2fs / data.c
index a903423e4cd5cdab1814f44d9924e29ae5625abb..972eab7ac07193da485df3efc6b6c11c99dacd97 100644 (file)
@@ -275,7 +275,8 @@ int f2fs_get_block(struct dnode_of_data *dn, pgoff_t index)
        return f2fs_reserve_block(dn, index);
 }
 
-struct page *get_read_data_page(struct inode *inode, pgoff_t index, int rw)
+struct page *get_read_data_page(struct inode *inode, pgoff_t index,
+                                               int rw, bool for_write)
 {
        struct address_space *mapping = inode->i_mapping;
        struct dnode_of_data dn;
@@ -292,7 +293,7 @@ struct page *get_read_data_page(struct inode *inode, pgoff_t index, int rw)
        if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode))
                return read_mapping_page(mapping, index, NULL);
 
-       page = grab_cache_page(mapping, index);
+       page = f2fs_grab_cache_page(mapping, index, for_write);
        if (!page)
                return ERR_PTR(-ENOMEM);
 
@@ -352,7 +353,7 @@ struct page *find_data_page(struct inode *inode, pgoff_t index)
                return page;
        f2fs_put_page(page, 0);
 
-       page = get_read_data_page(inode, index, READ_SYNC);
+       page = get_read_data_page(inode, index, READ_SYNC, false);
        if (IS_ERR(page))
                return page;
 
@@ -372,12 +373,13 @@ struct page *find_data_page(struct inode *inode, pgoff_t index)
  * Because, the callers, functions in dir.c and GC, should be able to know
  * whether this page exists or not.
  */
-struct page *get_lock_data_page(struct inode *inode, pgoff_t index)
+struct page *get_lock_data_page(struct inode *inode, pgoff_t index,
+                                                       bool for_write)
 {
        struct address_space *mapping = inode->i_mapping;
        struct page *page;
 repeat:
-       page = get_read_data_page(inode, index, READ_SYNC);
+       page = get_read_data_page(inode, index, READ_SYNC, for_write);
        if (IS_ERR(page))
                return page;
 
@@ -411,7 +413,7 @@ struct page *get_new_data_page(struct inode *inode,
        struct dnode_of_data dn;
        int err;
 repeat:
-       page = grab_cache_page(mapping, index);
+       page = f2fs_grab_cache_page(mapping, index, true);
        if (!page) {
                /*
                 * before exiting, we should make sure ipage will be released
@@ -439,7 +441,7 @@ repeat:
        } else {
                f2fs_put_page(page, 1);
 
-               page = get_read_data_page(inode, index, READ_SYNC);
+               page = get_read_data_page(inode, index, READ_SYNC, true);
                if (IS_ERR(page))
                        goto repeat;
 
@@ -769,6 +771,12 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
        if (ret)
                return ret;
 
+       if (f2fs_has_inline_data(inode)) {
+               ret = f2fs_inline_data_fiemap(inode, fieinfo, start, len);
+               if (ret != -EAGAIN)
+                       return ret;
+       }
+
        mutex_lock(&inode->i_mutex);
 
        if (len >= isize) {
@@ -954,21 +962,14 @@ submit_and_realloc:
 
                        if (f2fs_encrypted_inode(inode) &&
                                        S_ISREG(inode->i_mode)) {
-                               struct page *cpage;
 
                                ctx = f2fs_get_crypto_ctx(inode);
                                if (IS_ERR(ctx))
                                        goto set_error_page;
 
                                /* wait the page to be moved by cleaning */
-                               cpage = find_lock_page(
-                                               META_MAPPING(F2FS_I_SB(inode)),
-                                               block_nr);
-                               if (cpage) {
-                                       f2fs_wait_on_page_writeback(cpage,
-                                                                       DATA);
-                                       f2fs_put_page(cpage, 1);
-                               }
+                               f2fs_wait_on_encrypted_page_writeback(
+                                               F2FS_I_SB(inode), block_nr);
                        }
 
                        bio = bio_alloc(GFP_KERNEL,
@@ -1030,6 +1031,9 @@ static int f2fs_read_data_pages(struct file *file,
                        struct list_head *pages, unsigned nr_pages)
 {
        struct inode *inode = file->f_mapping->host;
+       struct page *page = list_entry(pages->prev, struct page, lru);
+
+       trace_f2fs_readpages(inode, page, nr_pages);
 
        /* If the file has inline data, skip readpages */
        if (f2fs_has_inline_data(inode))
@@ -1059,6 +1063,11 @@ int do_write_data_page(struct f2fs_io_info *fio)
        }
 
        if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) {
+
+               /* wait for GCed encrypted page writeback */
+               f2fs_wait_on_encrypted_page_writeback(F2FS_I_SB(inode),
+                                                       fio->blk_addr);
+
                fio->encrypted_page = f2fs_encrypt(inode, fio->page);
                if (IS_ERR(fio->encrypted_page)) {
                        err = PTR_ERR(fio->encrypted_page);
@@ -1340,6 +1349,11 @@ static int f2fs_write_data_pages(struct address_space *mapping,
        if (!get_dirty_pages(inode) && wbc->sync_mode == WB_SYNC_NONE)
                return 0;
 
+       if (S_ISDIR(inode->i_mode) && wbc->sync_mode == WB_SYNC_NONE &&
+                       get_dirty_pages(inode) < nr_pages_to_skip(sbi, DATA) &&
+                       available_free_memory(sbi, DIRTY_DENTS))
+               goto skip_write;
+
        /* during POR, we don't need to trigger writepage at all. */
        if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
                goto skip_write;
@@ -1442,6 +1456,10 @@ put_next:
 
        f2fs_wait_on_page_writeback(page, DATA);
 
+       /* wait for GCed encrypted page writeback */
+       if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode))
+               f2fs_wait_on_encrypted_page_writeback(sbi, dn.data_blkaddr);
+
        if (len == PAGE_CACHE_SIZE)
                goto out_update;
        if (PageUptodate(page))
@@ -1655,12 +1673,13 @@ static sector_t f2fs_bmap(struct address_space *mapping, sector_t block)
 {
        struct inode *inode = mapping->host;
 
-       /* we don't need to use inline_data strictly */
-       if (f2fs_has_inline_data(inode)) {
-               int err = f2fs_convert_inline_inode(inode);
-               if (err)
-                       return err;
-       }
+       if (f2fs_has_inline_data(inode))
+               return 0;
+
+       /* make sure allocating whole blocks */
+       if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY))
+               filemap_write_and_wait(mapping);
+
        return generic_block_bmap(mapping, block, get_data_block_bmap);
 }