diff options
Diffstat (limited to 'libbcachefs/fs.c')
-rw-r--r-- | libbcachefs/fs.c | 69 |
1 files changed, 36 insertions, 33 deletions
diff --git a/libbcachefs/fs.c b/libbcachefs/fs.c index a35f34eb..f9ee4ac2 100644 --- a/libbcachefs/fs.c +++ b/libbcachefs/fs.c @@ -1124,6 +1124,7 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info, struct btree_iter *iter; struct bkey_s_c k; BKEY_PADDED(k) cur, prev; + struct bpos end = POS(ei->v.i_ino, (start + len) >> 9); unsigned offset_into_extent, sectors; bool have_extent = false; int ret = 0; @@ -1134,14 +1135,16 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info, bch2_trans_init(&trans, c, 0, 0); iter = bch2_trans_get_iter(&trans, BTREE_ID_EXTENTS, - POS(ei->v.i_ino, start >> 9), - BTREE_ITER_SLOTS); - - while (bkey_cmp(iter->pos, POS(ei->v.i_ino, (start + len) >> 9)) < 0) { - k = bch2_btree_iter_peek_slot(iter); - ret = bkey_err(k); - if (ret) - goto err; + POS(ei->v.i_ino, start >> 9), 0); +retry: + while ((k = bch2_btree_iter_peek(iter)).k && + !(ret = bkey_err(k)) && + bkey_cmp(iter->pos, end) < 0) { + if (!bkey_extent_is_data(k.k) && + k.k->type != KEY_TYPE_reservation) { + bch2_btree_iter_next(iter); + continue; + } bkey_reassemble(&cur.k, k); k = bkey_i_to_s_c(&cur.k); @@ -1150,41 +1153,44 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info, bkey_start_offset(k.k); sectors = k.k->size - offset_into_extent; - ret = bch2_read_indirect_extent(&trans, iter, + ret = bch2_read_indirect_extent(&trans, &offset_into_extent, &cur.k); if (ret) break; sectors = min(sectors, k.k->size - offset_into_extent); - bch2_cut_front(POS(k.k->p.inode, - bkey_start_offset(k.k) + offset_into_extent), - &cur.k); + if (offset_into_extent) + bch2_cut_front(POS(k.k->p.inode, + bkey_start_offset(k.k) + + offset_into_extent), + &cur.k); bch2_key_resize(&cur.k.k, sectors); cur.k.k.p.offset = iter->pos.offset + cur.k.k.size; - if (bkey_extent_is_data(k.k) || - k.k->type == KEY_TYPE_reservation) { - if (have_extent) { - ret = bch2_fill_extent(c, info, - bkey_i_to_s_c(&prev.k), 0); - if (ret) - break; - } - - bkey_copy(&prev.k, &cur.k); - have_extent = true; + if (have_extent) { + ret = bch2_fill_extent(c, info, + bkey_i_to_s_c(&prev.k), 0); + if (ret) + break; } - bch2_btree_iter_set_pos(iter, - POS(iter->pos.inode, - iter->pos.offset + sectors)); + bkey_copy(&prev.k, &cur.k); + have_extent = true; + + if (k.k->type == KEY_TYPE_reflink_v) + bch2_btree_iter_set_pos(iter, k.k->p); + else + bch2_btree_iter_next(iter); } + if (ret == -EINTR) + goto retry; + if (!ret && have_extent) ret = bch2_fill_extent(c, info, bkey_i_to_s_c(&prev.k), FIEMAP_EXTENT_LAST); -err: + ret = bch2_trans_exit(&trans) ?: ret; return ret < 0 ? ret : 0; } @@ -1449,12 +1455,6 @@ static int bch2_vfs_write_inode(struct inode *vinode, ATTR_ATIME|ATTR_MTIME|ATTR_CTIME); mutex_unlock(&inode->ei_update_lock); - if (c->opts.journal_flush_disabled) - return ret; - - if (!ret && wbc->sync_mode == WB_SYNC_ALL) - ret = bch2_journal_flush_seq(&c->journal, inode->ei_journal_seq); - return ret; } @@ -1511,6 +1511,9 @@ static int bch2_sync_fs(struct super_block *sb, int wait) { struct bch_fs *c = sb->s_fs_info; + if (c->opts.journal_flush_disabled) + return 0; + if (!wait) { bch2_journal_flush_async(&c->journal, NULL); return 0; |