]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/fs.c
Update bcachefs sources to e48731a188 bcachefs: Fix BTREE_TRIGGER_WANTS_OLD_AND_NEW
[bcachefs-tools-debian] / libbcachefs / fs.c
index fc29e6c4a296dd0c87442da6ec66304266ec58f7..9fc6c39eacdb6fb244efba8317dd2ceaec61abae 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/pagemap.h>
 #include <linux/posix_acl.h>
 #include <linux/random.h>
+#include <linux/seq_file.h>
 #include <linux/statfs.h>
 #include <linux/string.h>
 #include <linux/xattr.h>
@@ -38,7 +39,8 @@ static struct kmem_cache *bch2_inode_cache;
 
 static void bch2_vfs_inode_init(struct btree_trans *, subvol_inum,
                                struct bch_inode_info *,
-                               struct bch_inode_unpacked *);
+                               struct bch_inode_unpacked *,
+                               struct bch_subvolume *);
 
 static void __pagecache_lock_put(struct pagecache_lock *lock, long i)
 {
@@ -103,7 +105,7 @@ void bch2_inode_update_after_write(struct btree_trans *trans,
 
        bch2_assert_pos_locked(trans, BTREE_ID_inodes,
                               POS(0, bi->bi_inum),
-                              0 && c->opts.inodes_use_key_cache);
+                              c->opts.inodes_use_key_cache);
 
        set_nlink(&inode->v, bch2_inode_nlink_get(bi));
        i_uid_write(&inode->v, bi->bi_uid);
@@ -133,7 +135,6 @@ int __must_check bch2_write_inode(struct bch_fs *c,
        int ret;
 
        bch2_trans_init(&trans, c, 0, 512);
-       trans.ip = _RET_IP_;
 retry:
        bch2_trans_begin(&trans);
 
@@ -224,6 +225,7 @@ struct inode *bch2_vfs_inode_get(struct bch_fs *c, subvol_inum inum)
        struct bch_inode_unpacked inode_u;
        struct bch_inode_info *inode;
        struct btree_trans trans;
+       struct bch_subvolume subvol;
        int ret;
 
        inode = to_bch_ei(iget5_locked(c->vfs_sb,
@@ -238,10 +240,11 @@ struct inode *bch2_vfs_inode_get(struct bch_fs *c, subvol_inum inum)
 
        bch2_trans_init(&trans, c, 8, 0);
        ret = lockrestart_do(&trans,
+               bch2_subvolume_get(&trans, inum.subvol, true, 0, &subvol) ?:
                bch2_inode_find_by_inum_trans(&trans, inum, &inode_u));
 
        if (!ret)
-               bch2_vfs_inode_init(&trans, inum, inode, &inode_u);
+               bch2_vfs_inode_init(&trans, inum, inode, &inode_u, &subvol);
        bch2_trans_exit(&trans);
 
        if (ret) {
@@ -267,6 +270,7 @@ __bch2_create(struct user_namespace *mnt_userns,
        struct bch_inode_unpacked inode_u;
        struct posix_acl *default_acl = NULL, *acl = NULL;
        subvol_inum inum;
+       struct bch_subvolume subvol;
        u64 journal_seq = 0;
        int ret;
 
@@ -309,7 +313,12 @@ retry:
        if (unlikely(ret))
                goto err_before_quota;
 
-       ret   = bch2_trans_commit(&trans, NULL, &journal_seq, 0);
+       inum.subvol = inode_u.bi_subvol ?: dir->ei_subvol;
+       inum.inum = inode_u.bi_inum;
+
+       ret   = bch2_subvolume_get(&trans, inum.subvol, true,
+                                  BTREE_ITER_WITH_UPDATES, &subvol) ?:
+               bch2_trans_commit(&trans, NULL, &journal_seq, 0);
        if (unlikely(ret)) {
                bch2_quota_acct(c, bch_qid(&inode_u), Q_INO, -1,
                                KEY_TYPE_QUOTA_WARN);
@@ -325,11 +334,8 @@ err_before_quota:
                mutex_unlock(&dir->ei_update_lock);
        }
 
-       inum.subvol = inode_u.bi_subvol ?: dir->ei_subvol;
-       inum.inum = inode_u.bi_inum;
-
        bch2_iget5_set(&inode->v, &inum);
-       bch2_vfs_inode_init(&trans, inum, inode, &inode_u);
+       bch2_vfs_inode_init(&trans, inum, inode, &inode_u, &subvol);
 
        set_cached_acl(&inode->v, ACL_TYPE_ACCESS, acl);
        set_cached_acl(&inode->v, ACL_TYPE_DEFAULT, default_acl);
@@ -860,8 +866,8 @@ static int bch2_fill_extent(struct bch_fs *c,
                        else
                                offset += p.crc.offset;
 
-                       if ((offset & (c->opts.block_size - 1)) ||
-                           (k.k->size & (c->opts.block_size - 1)))
+                       if ((offset & (block_sectors(c) - 1)) ||
+                           (k.k->size & (block_sectors(c) - 1)))
                                flags2 |= FIEMAP_EXTENT_NOT_ALIGNED;
 
                        ret = fiemap_fill_next_extent(info,
@@ -928,9 +934,9 @@ retry:
        bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
                             SPOS(ei->v.i_ino, start, snapshot), 0);
 
-       while ((k = bch2_btree_iter_peek(&iter)).k &&
-              !(ret = bkey_err(k)) &&
-              bkey_cmp(iter.pos, end) < 0) {
+       while (!(ret = btree_trans_too_many_iters(&trans)) &&
+              (k = bch2_btree_iter_peek_upto(&iter, end)).k &&
+              !(ret = bkey_err(k))) {
                enum btree_id data_btree = BTREE_ID_extents;
 
                if (!bkey_extent_is_data(k.k) &&
@@ -1350,10 +1356,16 @@ static const struct export_operations bch_export_ops = {
 
 static void bch2_vfs_inode_init(struct btree_trans *trans, subvol_inum inum,
                                struct bch_inode_info *inode,
-                               struct bch_inode_unpacked *bi)
+                               struct bch_inode_unpacked *bi,
+                               struct bch_subvolume *subvol)
 {
        bch2_inode_update_after_write(trans, inode, bi, ~0);
 
+       if (BCH_SUBVOLUME_SNAP(subvol))
+               set_bit(EI_INODE_SNAPSHOT, &inode->ei_flags);
+       else
+               clear_bit(EI_INODE_SNAPSHOT, &inode->ei_flags);
+
        inode->v.i_blocks       = bi->bi_sectors;
        inode->v.i_ino          = bi->bi_inum;
        inode->v.i_rdev         = bi->bi_dev;
@@ -1460,7 +1472,7 @@ static void bch2_evict_inode(struct inode *vinode)
                                KEY_TYPE_QUOTA_WARN);
                bch2_quota_acct(c, inode->ei_qid, Q_INO, -1,
                                KEY_TYPE_QUOTA_WARN);
-               bch2_inode_rm(c, inode_inum(inode), true);
+               bch2_inode_rm(c, inode_inum(inode));
        }
 }
 
@@ -1663,25 +1675,30 @@ static int bch2_show_options(struct seq_file *seq, struct dentry *root)
 {
        struct bch_fs *c = root->d_sb->s_fs_info;
        enum bch_opt_id i;
-       char buf[512];
+       struct printbuf buf = PRINTBUF;
+       int ret = 0;
 
        for (i = 0; i < bch2_opts_nr; i++) {
                const struct bch_option *opt = &bch2_opt_table[i];
                u64 v = bch2_opt_get_by_id(&c->opts, i);
 
-               if (!(opt->mode & OPT_MOUNT))
+               if (!(opt->flags & OPT_MOUNT))
                        continue;
 
                if (v == bch2_opt_get_by_id(&bch2_opts_default, i))
                        continue;
 
-               bch2_opt_to_text(&PBUF(buf), c, opt, v,
+               printbuf_reset(&buf);
+               bch2_opt_to_text(&buf, c, c->disk_sb.sb, opt, v,
                                 OPT_SHOW_MOUNT_STYLE);
                seq_putc(seq, ',');
-               seq_puts(seq, buf);
+               seq_puts(seq, buf.buf);
        }
 
-       return 0;
+       if (buf.allocation_failure)
+               ret = -ENOMEM;
+       printbuf_exit(&buf);
+       return ret;
 }
 
 static void bch2_put_super(struct super_block *sb)