]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/fs.c
New upstream release
[bcachefs-tools-debian] / libbcachefs / fs.c
index 91fa1897db98358c8d2f9f246002463d13df0822..186faa54b590f1e736c1b660d5c83d1bc56cdbda 100644 (file)
@@ -8,6 +8,7 @@
 #include "buckets.h"
 #include "chardev.h"
 #include "dirent.h"
+#include "errcode.h"
 #include "extents.h"
 #include "fs.h"
 #include "fs-common.h"
@@ -30,6 +31,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>
@@ -152,7 +154,7 @@ retry:
 
        bch2_trans_iter_exit(&trans, &iter);
 
-       if (ret == -EINTR)
+       if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                goto retry;
 
        bch2_trans_exit(&trans);
@@ -322,7 +324,7 @@ retry:
                bch2_quota_acct(c, bch_qid(&inode_u), Q_INO, -1,
                                KEY_TYPE_QUOTA_WARN);
 err_before_quota:
-               if (ret == -EINTR)
+               if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                        goto retry;
                goto err_trans;
        }
@@ -417,7 +419,7 @@ static int bch2_mknod(struct user_namespace *mnt_userns,
                              (subvol_inum) { 0 }, 0);
 
        if (IS_ERR(inode))
-               return PTR_ERR(inode);
+               return bch2_err_class(PTR_ERR(inode));
 
        d_instantiate(dentry, &inode->v);
        return 0;
@@ -442,7 +444,7 @@ static int __bch2_link(struct bch_fs *c,
        mutex_lock(&inode->ei_update_lock);
        bch2_trans_init(&trans, c, 4, 1024);
 
-       ret = __bch2_trans_do(&trans, NULL, NULL, 0,
+       ret = commit_do(&trans, NULL, NULL, 0,
                        bch2_link_trans(&trans,
                                        inode_inum(dir),   &dir_u,
                                        inode_inum(inode), &inode_u,
@@ -491,7 +493,7 @@ int __bch2_unlink(struct inode *vdir, struct dentry *dentry,
        bch2_lock_inodes(INODE_UPDATE_LOCK, dir, inode);
        bch2_trans_init(&trans, c, 4, 1024);
 
-       ret = __bch2_trans_do(&trans, NULL, NULL,
+       ret = commit_do(&trans, NULL, NULL,
                              BTREE_INSERT_NOFAIL,
                        bch2_unlink_trans(&trans,
                                          inode_inum(dir), &dir_u,
@@ -526,8 +528,8 @@ static int bch2_symlink(struct user_namespace *mnt_userns,
 
        inode = __bch2_create(mnt_userns, dir, dentry, S_IFLNK|S_IRWXUGO, 0,
                              (subvol_inum) { 0 }, BCH_CREATE_TMPFILE);
-       if (unlikely(IS_ERR(inode)))
-               return PTR_ERR(inode);
+       if (IS_ERR(inode))
+               return bch2_err_class(PTR_ERR(inode));
 
        inode_lock(&inode->v);
        ret = page_symlink(&inode->v, symname, strlen(symname) + 1);
@@ -613,7 +615,7 @@ static int bch2_rename2(struct user_namespace *mnt_userns,
                        goto err;
        }
 
-       ret = __bch2_trans_do(&trans, NULL, NULL, 0,
+       ret = commit_do(&trans, NULL, NULL, 0,
                        bch2_rename_trans(&trans,
                                          inode_inum(src_dir), &src_dir_u,
                                          inode_inum(dst_dir), &dst_dir_u,
@@ -753,7 +755,7 @@ retry:
 btree_err:
        bch2_trans_iter_exit(&trans, &inode_iter);
 
-       if (ret == -EINTR)
+       if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                goto retry;
        if (unlikely(ret))
                goto err_trans;
@@ -767,7 +769,7 @@ err_trans:
 err:
        mutex_unlock(&inode->ei_update_lock);
 
-       return ret;
+       return bch2_err_class(ret);
 }
 
 static int bch2_getattr(struct user_namespace *mnt_userns,
@@ -836,7 +838,7 @@ static int bch2_tmpfile(struct user_namespace *mnt_userns,
                              (subvol_inum) { 0 }, BCH_CREATE_TMPFILE);
 
        if (IS_ERR(inode))
-               return PTR_ERR(inode);
+               return bch2_err_class(PTR_ERR(inode));
 
        d_mark_tmpfile(dentry, &inode->v);
        d_instantiate(dentry, &inode->v);
@@ -933,9 +935,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) &&
@@ -984,7 +986,7 @@ retry:
        start = iter.pos.offset;
        bch2_trans_iter_exit(&trans, &iter);
 err:
-       if (ret == -EINTR)
+       if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                goto retry;
 
        if (!ret && have_extent)
@@ -1111,18 +1113,17 @@ static const struct inode_operations bch_special_inode_operations = {
 };
 
 static const struct address_space_operations bch_address_space_operations = {
-       .writepage      = bch2_writepage,
-       .readpage       = bch2_readpage,
+       .read_folio     = bch2_read_folio,
        .writepages     = bch2_writepages,
        .readahead      = bch2_readahead,
-       .set_page_dirty = __set_page_dirty_nobuffers,
+       .dirty_folio    = filemap_dirty_folio,
        .write_begin    = bch2_write_begin,
        .write_end      = bch2_write_end,
-       .invalidatepage = bch2_invalidatepage,
-       .releasepage    = bch2_releasepage,
+       .invalidate_folio = bch2_invalidate_folio,
+       .release_folio  = bch2_release_folio,
        .direct_IO      = noop_direct_IO,
 #ifdef CONFIG_MIGRATION
-       .migratepage    = bch2_migrate_page,
+       .migrate_folio  = filemap_migrate_folio,
 #endif
        .error_remove_page = generic_error_remove_page,
 };
@@ -1335,7 +1336,7 @@ found:
        memcpy(name, d.v->d_name, name_len);
        name[name_len] = '\0';
 err:
-       if (ret == -EINTR)
+       if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                goto retry;
 
        bch2_trans_iter_exit(&trans, &iter1);
@@ -1452,7 +1453,7 @@ static int bch2_vfs_write_inode(struct inode *vinode,
                               ATTR_ATIME|ATTR_MTIME|ATTR_CTIME);
        mutex_unlock(&inode->ei_update_lock);
 
-       return ret;
+       return bch2_err_class(ret);
 }
 
 static void bch2_evict_inode(struct inode *vinode)
@@ -1476,7 +1477,7 @@ static void bch2_evict_inode(struct inode *vinode)
 }
 
 void bch2_evict_subvolume_inodes(struct bch_fs *c,
-                                struct snapshot_id_list *s)
+                                snapshot_id_list *s)
 {
        struct super_block *sb = c->vfs_sb;
        struct inode *inode;
@@ -1556,6 +1557,7 @@ static int bch2_statfs(struct dentry *dentry, struct kstatfs *buf)
 static int bch2_sync_fs(struct super_block *sb, int wait)
 {
        struct bch_fs *c = sb->s_fs_info;
+       int ret;
 
        if (c->opts.journal_flush_disabled)
                return 0;
@@ -1565,7 +1567,8 @@ static int bch2_sync_fs(struct super_block *sb, int wait)
                return 0;
        }
 
-       return bch2_journal_flush(&c->journal);
+       ret = bch2_journal_flush(&c->journal);
+       return bch2_err_class(ret);
 }
 
 static struct bch_fs *bch2_path_to_fs(const char *path)
@@ -1621,7 +1624,7 @@ static int bch2_remount(struct super_block *sb, int *flags, char *data)
 
        ret = bch2_parse_mount_opts(c, &opts, data);
        if (ret)
-               return ret;
+               goto err;
 
        if (opts.read_only != c->opts.read_only) {
                down_write(&c->state_lock);
@@ -1635,7 +1638,8 @@ static int bch2_remount(struct super_block *sb, int *flags, char *data)
                        if (ret) {
                                bch_err(c, "error going rw: %i", ret);
                                up_write(&c->state_lock);
-                               return -EINVAL;
+                               ret = -EINVAL;
+                               goto err;
                        }
 
                        sb->s_flags &= ~SB_RDONLY;
@@ -1648,8 +1652,8 @@ static int bch2_remount(struct super_block *sb, int *flags, char *data)
 
        if (opts.errors >= 0)
                c->opts.errors = opts.errors;
-
-       return ret;
+err:
+       return bch2_err_class(ret);
 }
 
 static int bch2_show_devname(struct seq_file *seq, struct dentry *root)
@@ -1674,7 +1678,8 @@ 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];
@@ -1686,13 +1691,17 @@ static int bch2_show_options(struct seq_file *seq, struct dentry *root)
                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)
@@ -1837,7 +1846,7 @@ got_sb:
        sb->s_time_min          = div_s64(S64_MIN, c->sb.time_units_per_sec) + 1;
        sb->s_time_max          = div_s64(S64_MAX, c->sb.time_units_per_sec);
        c->vfs_sb               = sb;
-       strlcpy(sb->s_id, c->name, sizeof(sb->s_id));
+       strscpy(sb->s_id, c->name, sizeof(sb->s_id));
 
        ret = super_setup_bdi(sb);
        if (ret)
@@ -1865,10 +1874,9 @@ got_sb:
        sb->s_shrink.seeks = 0;
 
        vinode = bch2_vfs_inode_get(c, BCACHEFS_ROOT_SUBVOL_INUM);
-       if (IS_ERR(vinode)) {
-               bch_err(c, "error mounting: error getting root inode %i",
-                       (int) PTR_ERR(vinode));
-               ret = PTR_ERR(vinode);
+       ret = PTR_ERR_OR_ZERO(vinode);
+       if (ret) {
+               bch_err(c, "error mounting: error getting root inode: %s", bch2_err_str(ret));
                goto err_put_super;
        }
 
@@ -1909,8 +1917,7 @@ MODULE_ALIAS_FS("bcachefs");
 void bch2_vfs_exit(void)
 {
        unregister_filesystem(&bcache_fs_type);
-       if (bch2_inode_cache)
-               kmem_cache_destroy(bch2_inode_cache);
+       kmem_cache_destroy(bch2_inode_cache);
 }
 
 int __init bch2_vfs_init(void)