f2fs: set fsync mark only for the last dnode
[linux-2.6-block.git] / fs / f2fs / data.c
index 53fec0872e60bf8b7fdc3b63ee0a9a36627edff6..e54489b970ae0297e98a3cc43d5a4da9af9a4774 100644 (file)
@@ -992,7 +992,7 @@ submit_and_realloc:
                        if (f2fs_encrypted_inode(inode) &&
                                        S_ISREG(inode->i_mode)) {
 
-                               ctx = fscrypt_get_ctx(inode);
+                               ctx = fscrypt_get_ctx(inode, GFP_NOFS);
                                if (IS_ERR(ctx))
                                        goto set_error_page;
 
@@ -1092,14 +1092,24 @@ int do_write_data_page(struct f2fs_io_info *fio)
        }
 
        if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) {
+               gfp_t gfp_flags = GFP_NOFS;
 
                /* wait for GCed encrypted page writeback */
                f2fs_wait_on_encrypted_page_writeback(F2FS_I_SB(inode),
                                                        fio->old_blkaddr);
-
-               fio->encrypted_page = fscrypt_encrypt_page(inode, fio->page);
+retry_encrypt:
+               fio->encrypted_page = fscrypt_encrypt_page(inode, fio->page,
+                                                               gfp_flags);
                if (IS_ERR(fio->encrypted_page)) {
                        err = PTR_ERR(fio->encrypted_page);
+                       if (err == -ENOMEM) {
+                               /* flush pending ios and wait for a while */
+                               f2fs_flush_merged_bios(F2FS_I_SB(inode));
+                               congestion_wait(BLK_RW_ASYNC, HZ/50);
+                               gfp_flags |= __GFP_NOFAIL;
+                               err = 0;
+                               goto retry_encrypt;
+                       }
                        goto out_writepage;
                }
        }
@@ -1167,8 +1177,10 @@ write:
                goto redirty_out;
        if (f2fs_is_drop_cache(inode))
                goto out;
-       if (f2fs_is_volatile_file(inode) && !wbc->for_reclaim &&
-                       available_free_memory(sbi, BASE_CHECK))
+       /* we should not write 0'th page having journal header */
+       if (f2fs_is_volatile_file(inode) && (!page->index ||
+                       (!wbc->for_reclaim &&
+                       available_free_memory(sbi, BASE_CHECK))))
                goto redirty_out;
 
        /* Dentry blocks are controlled by checkpoint */
@@ -1486,7 +1498,7 @@ restart:
                } else {
                        /* hole case */
                        err = get_dnode_of_data(&dn, index, LOOKUP_NODE);
-                       if (err || (!err && dn.data_blkaddr == NULL_ADDR)) {
+                       if (err || dn.data_blkaddr == NULL_ADDR) {
                                f2fs_put_dnode(&dn);
                                f2fs_lock_op(sbi);
                                locked = true;