]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/fs-io.c
Update bcachefs sources to 7bfc741f64 bcachefs: Fix a null ptr deref during journal...
[bcachefs-tools-debian] / libbcachefs / fs-io.c
index bce25dde1172cc93cfb7524d0359d77cf10ae275..0aa3afade4ea03900518727f60e6b6949f8c073e 100644 (file)
@@ -602,7 +602,7 @@ int bch2_migrate_page(struct address_space *mapping, struct page *newpage,
        EBUG_ON(!PageLocked(page));
        EBUG_ON(!PageLocked(newpage));
 
-       ret = migrate_page_move_mapping(mapping, newpage, page, mode, 0);
+       ret = migrate_page_move_mapping(mapping, newpage, page, 0);
        if (ret != MIGRATEPAGE_SUCCESS)
                return ret;
 
@@ -837,8 +837,7 @@ retry:
                if (ret)
                        break;
 
-               bkey_on_stack_realloc(&sk, c, k.k->u64s);
-               bkey_reassemble(sk.k, k);
+               bkey_on_stack_reassemble(&sk, c, k);
                k = bkey_i_to_s_c(sk.k);
 
                offset_into_extent = iter->pos.offset -
@@ -1239,7 +1238,7 @@ do_io:
 
                if (w->io &&
                    (w->io->op.res.nr_replicas != nr_replicas_this_write ||
-                    bio_full(&w->io->op.wbio.bio) ||
+                    bio_full(&w->io->op.wbio.bio, PAGE_SIZE) ||
                     w->io->op.wbio.bio.bi_iter.bi_size >= (256U << 20) ||
                     bio_end_sector(&w->io->op.wbio.bio) != sector))
                        bch2_writepage_do_io(w);
@@ -1808,7 +1807,7 @@ static long bch2_dio_write_loop(struct dio_write *dio)
        struct bio_vec *bv;
        unsigned unaligned;
        u64 new_i_size;
-       bool sync;
+       bool sync = dio->sync;
        long ret;
 
        if (dio->loop)
@@ -1856,7 +1855,7 @@ static long bch2_dio_write_loop(struct dio_write *dio)
                                iov = kmalloc(dio->iter.nr_segs * sizeof(*iov),
                                              GFP_KERNEL);
                                if (unlikely(!iov)) {
-                                       dio->sync = true;
+                                       dio->sync = sync = true;
                                        goto do_io;
                                }
 
@@ -1870,7 +1869,7 @@ do_io:
                dio->loop = true;
                closure_call(&dio->op.cl, bch2_write, NULL, NULL);
 
-               if (dio->sync)
+               if (sync)
                        wait_for_completion(&dio->done);
                else
                        return -EIOCBQUEUED;
@@ -1904,7 +1903,6 @@ err:
        if (dio->free_iov)
                kfree(dio->iter.iov);
 
-       sync = dio->sync;
        bio_put(bio);
 
        /* inode->i_dio_count is our ref on inode and thus bch_fs */
@@ -2285,6 +2283,15 @@ int bch2_truncate(struct bch_inode_info *inode, struct iattr *iattr)
        ret = PTR_ERR_OR_ZERO(iter);
        bch2_trans_exit(&trans);
 
+       if (ret)
+               goto err;
+
+       /*
+        * check this before next assertion; on filesystem error our normal
+        * invariants are a bit broken (truncate has to truncate the page cache
+        * before the inode).
+        */
+       ret = bch2_journal_error(&c->journal);
        if (ret)
                goto err;
 
@@ -2403,7 +2410,7 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode,
        struct address_space *mapping = inode->v.i_mapping;
        struct bkey_on_stack copy;
        struct btree_trans trans;
-       struct btree_iter *src, *dst, *del = NULL;
+       struct btree_iter *src, *dst;
        loff_t shift, new_size;
        u64 src_start;
        int ret;
@@ -2485,9 +2492,7 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode,
                struct bpos next_pos;
                struct bpos move_pos = POS(inode->v.i_ino, offset >> 9);
                struct bpos atomic_end;
-               unsigned commit_flags = BTREE_INSERT_NOFAIL|
-                       BTREE_INSERT_ATOMIC|
-                       BTREE_INSERT_USE_RESERVE;
+               unsigned trigger_flags = 0;
 
                k = insert
                        ? bch2_btree_iter_peek_prev(src)
@@ -2504,14 +2509,11 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode,
                    bkey_cmp(k.k->p, POS(inode->v.i_ino, offset >> 9)) <= 0)
                        break;
 reassemble:
-               bkey_on_stack_realloc(&copy, c, k.k->u64s);
-               bkey_reassemble(copy.k, k);
+               bkey_on_stack_reassemble(&copy, c, k);
 
                if (insert &&
-                   bkey_cmp(bkey_start_pos(k.k), move_pos) < 0) {
+                   bkey_cmp(bkey_start_pos(k.k), move_pos) < 0)
                        bch2_cut_front(move_pos, copy.k);
-                       bch2_btree_iter_set_pos(src, bkey_start_pos(&copy.k->k));
-               }
 
                copy.k->k.p.offset += shift >> 9;
                bch2_btree_iter_set_pos(dst, bkey_start_pos(&copy.k->k));
@@ -2531,43 +2533,18 @@ reassemble:
                }
 
                bkey_init(&delete.k);
-               delete.k.p = src->pos;
-               bch2_key_resize(&delete.k, copy.k->k.size);
+               delete.k.p = copy.k->k.p;
+               delete.k.size = copy.k->k.size;
+               delete.k.p.offset -= shift >> 9;
 
                next_pos = insert ? bkey_start_pos(&delete.k) : delete.k.p;
 
-               /*
-                * If the new and old keys overlap (because we're moving an
-                * extent that's bigger than the amount we're collapsing by),
-                * we need to trim the delete key here so they don't overlap
-                * because overlaps on insertions aren't handled before
-                * triggers are run, so the overwrite will get double counted
-                * by the triggers machinery:
-                */
-               if (insert &&
-                   bkey_cmp(bkey_start_pos(&copy.k->k), delete.k.p) < 0) {
-                       bch2_cut_back(bkey_start_pos(&copy.k->k), &delete);
-               } else if (!insert &&
-                          bkey_cmp(copy.k->k.p,
-                                   bkey_start_pos(&delete.k)) > 0) {
-                       bch2_cut_front(copy.k->k.p, &delete);
-
-                       del = bch2_trans_copy_iter(&trans, src);
-                       BUG_ON(IS_ERR_OR_NULL(del));
-
-                       bch2_btree_iter_set_pos(del,
-                               bkey_start_pos(&delete.k));
-               }
-
-               bch2_trans_update(&trans, dst, copy.k);
-               bch2_trans_update(&trans, del ?: src, &delete);
-
                if (copy.k->k.size == k.k->size) {
                        /*
                         * If we're moving the entire extent, we can skip
                         * running triggers:
                         */
-                       commit_flags |= BTREE_INSERT_NOMARK;
+                       trigger_flags |= BTREE_TRIGGER_NORUN;
                } else {
                        /* We might end up splitting compressed extents: */
                        unsigned nr_ptrs =
@@ -2579,15 +2556,15 @@ reassemble:
                        BUG_ON(ret);
                }
 
-               ret = bch2_trans_commit(&trans, &disk_res,
-                                       &inode->ei_journal_seq,
-                                       commit_flags);
+               bch2_btree_iter_set_pos(src, bkey_start_pos(&delete.k));
+
+               ret =   bch2_trans_update(&trans, src, &delete, trigger_flags) ?:
+                       bch2_trans_update(&trans, dst, copy.k, trigger_flags) ?:
+                       bch2_trans_commit(&trans, &disk_res,
+                                         &inode->ei_journal_seq,
+                                         BTREE_INSERT_NOFAIL);
                bch2_disk_reservation_put(c, &disk_res);
 bkey_err:
-               if (del)
-                       bch2_trans_iter_put(&trans, del);
-               del = NULL;
-
                if (!ret)
                        bch2_btree_iter_set_pos(src, next_pos);
 
@@ -2671,6 +2648,8 @@ static long bchfs_fallocate(struct bch_inode_info *inode, int mode,
                struct bkey_i_reservation reservation;
                struct bkey_s_c k;
 
+               bch2_trans_begin(&trans);
+
                k = bch2_btree_iter_peek_slot(iter);
                if ((ret = bkey_err(k)))
                        goto bkey_err;
@@ -2717,8 +2696,6 @@ static long bchfs_fallocate(struct bch_inode_info *inode, int mode,
                        reservation.v.nr_replicas = disk_res.nr_replicas;
                }
 
-               bch2_trans_begin_updates(&trans);
-
                ret = bch2_extent_update(&trans, iter, &reservation.k_i,
                                &disk_res, &inode->ei_journal_seq,
                                0, &i_sectors_delta);