]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - fs/f2fs/data.c
Merge tag 'pwm/for-4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry...
[karo-tx-linux.git] / fs / f2fs / data.c
index 72fc866cad1955a3391d4baab6904da768cb22a3..87c1f4150c645c83c64cd7f90243d347121f8886 100644 (file)
@@ -58,12 +58,12 @@ static void f2fs_read_end_io(struct bio *bio)
 #ifdef CONFIG_F2FS_FAULT_INJECTION
        if (time_to_inject(F2FS_P_SB(bio->bi_io_vec->bv_page), FAULT_IO)) {
                f2fs_show_injection_info(FAULT_IO);
-               bio->bi_error = -EIO;
+               bio->bi_status = BLK_STS_IOERR;
        }
 #endif
 
        if (f2fs_bio_encrypted(bio)) {
-               if (bio->bi_error) {
+               if (bio->bi_status) {
                        fscrypt_release_ctx(bio->bi_private);
                } else {
                        fscrypt_decrypt_bio_pages(bio->bi_private, bio);
@@ -74,7 +74,7 @@ static void f2fs_read_end_io(struct bio *bio)
        bio_for_each_segment_all(bvec, bio, i) {
                struct page *page = bvec->bv_page;
 
-               if (!bio->bi_error) {
+               if (!bio->bi_status) {
                        if (!PageUptodate(page))
                                SetPageUptodate(page);
                } else {
@@ -102,14 +102,14 @@ static void f2fs_write_end_io(struct bio *bio)
                        unlock_page(page);
                        mempool_free(page, sbi->write_io_dummy);
 
-                       if (unlikely(bio->bi_error))
+                       if (unlikely(bio->bi_status))
                                f2fs_stop_checkpoint(sbi, true);
                        continue;
                }
 
                fscrypt_pullback_bio_page(&page, true);
 
-               if (unlikely(bio->bi_error)) {
+               if (unlikely(bio->bi_status)) {
                        mapping_set_error(page->mapping, -EIO);
                        f2fs_stop_checkpoint(sbi, true);
                }
@@ -491,14 +491,15 @@ void f2fs_update_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr)
 int reserve_new_blocks(struct dnode_of_data *dn, blkcnt_t count)
 {
        struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
+       int err;
 
        if (!count)
                return 0;
 
        if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC)))
                return -EPERM;
-       if (unlikely(!inc_valid_block_count(sbi, dn->inode, &count)))
-               return -ENOSPC;
+       if (unlikely((err = inc_valid_block_count(sbi, dn->inode, &count))))
+               return err;
 
        trace_f2fs_reserve_new_blocks(dn->inode, dn->nid,
                                                dn->ofs_in_node, count);
@@ -749,6 +750,7 @@ static int __allocate_data_block(struct dnode_of_data *dn)
        struct node_info ni;
        pgoff_t fofs;
        blkcnt_t count = 1;
+       int err;
 
        if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC)))
                return -EPERM;
@@ -757,8 +759,8 @@ static int __allocate_data_block(struct dnode_of_data *dn)
        if (dn->data_blkaddr == NEW_ADDR)
                goto alloc;
 
-       if (unlikely(!inc_valid_block_count(sbi, dn->inode, &count)))
-               return -ENOSPC;
+       if (unlikely((err = inc_valid_block_count(sbi, dn->inode, &count))))
+               return err;
 
 alloc:
        get_node_info(sbi, dn->nid, &ni);
@@ -1404,8 +1406,9 @@ int do_write_data_page(struct f2fs_io_info *fio)
                }
        }
 
-       if (fio->need_lock == LOCK_REQ)
-               f2fs_lock_op(fio->sbi);
+       /* Deadlock due to between page->lock and f2fs_lock_op */
+       if (fio->need_lock == LOCK_REQ && !f2fs_trylock_op(fio->sbi))
+               return -EAGAIN;
 
        err = get_dnode_of_data(&dn, page->index, LOOKUP_NODE);
        if (err)
@@ -1667,7 +1670,7 @@ retry:
                        }
 
                        done_index = page->index;
-
+retry_write:
                        lock_page(page);
 
                        if (unlikely(page->mapping != mapping)) {
@@ -1703,6 +1706,15 @@ continue_unlock:
                                        unlock_page(page);
                                        ret = 0;
                                        continue;
+                               } else if (ret == -EAGAIN) {
+                                       ret = 0;
+                                       if (wbc->sync_mode == WB_SYNC_ALL) {
+                                               cond_resched();
+                                               congestion_wait(BLK_RW_ASYNC,
+                                                                       HZ/50);
+                                               goto retry_write;
+                                       }
+                                       continue;
                                }
                                done_index = page->index + 1;
                                done = 1;