summaryrefslogtreecommitdiff
path: root/libbcachefs
diff options
context:
space:
mode:
Diffstat (limited to 'libbcachefs')
-rw-r--r--libbcachefs/acl.c5
-rw-r--r--libbcachefs/acl.h2
-rw-r--r--libbcachefs/alloc_background.c2
-rw-r--r--libbcachefs/bcachefs.h1
-rw-r--r--libbcachefs/btree_iter.c4
-rw-r--r--libbcachefs/btree_iter.h3
-rw-r--r--libbcachefs/btree_update_leaf.c14
-rw-r--r--libbcachefs/fs-io.c5
-rw-r--r--libbcachefs/fsck.c36
-rw-r--r--libbcachefs/super-io.c3
-rw-r--r--libbcachefs/util.h1
11 files changed, 60 insertions, 16 deletions
diff --git a/libbcachefs/acl.c b/libbcachefs/acl.c
index f92b52e4..d0c6878b 100644
--- a/libbcachefs/acl.c
+++ b/libbcachefs/acl.c
@@ -212,7 +212,7 @@ bch2_acl_to_xattr(struct btree_trans *trans,
return xattr;
}
-struct posix_acl *bch2_get_acl(struct inode *vinode, int type)
+struct posix_acl *bch2_get_acl(struct inode *vinode, int type, bool rcu)
{
struct bch_inode_info *inode = to_bch_ei(vinode);
struct bch_fs *c = inode->v.i_sb->s_fs_info;
@@ -224,6 +224,9 @@ struct posix_acl *bch2_get_acl(struct inode *vinode, int type)
struct bkey_s_c k;
int ret;
+ if (rcu)
+ return ERR_PTR(-ECHILD);
+
bch2_trans_init(&trans, c, 0, 0);
retry:
bch2_trans_begin(&trans);
diff --git a/libbcachefs/acl.h b/libbcachefs/acl.h
index 2ad214bd..2d76a489 100644
--- a/libbcachefs/acl.h
+++ b/libbcachefs/acl.h
@@ -26,7 +26,7 @@ typedef struct {
__le32 a_version;
} bch_acl_header;
-struct posix_acl *bch2_get_acl(struct inode *, int);
+struct posix_acl *bch2_get_acl(struct inode *, int, bool);
int bch2_set_acl_trans(struct btree_trans *, subvol_inum,
struct bch_inode_unpacked *,
diff --git a/libbcachefs/alloc_background.c b/libbcachefs/alloc_background.c
index 67b24576..022c905d 100644
--- a/libbcachefs/alloc_background.c
+++ b/libbcachefs/alloc_background.c
@@ -1018,7 +1018,7 @@ void bch2_recalc_capacity(struct bch_fs *c)
lockdep_assert_held(&c->state_lock);
for_each_online_member(ca, c, i) {
- struct backing_dev_info *bdi = ca->disk_sb.bdev->bd_bdi;
+ struct backing_dev_info *bdi = ca->disk_sb.bdev->bd_disk->bdi;
ra_pages += bdi->ra_pages;
}
diff --git a/libbcachefs/bcachefs.h b/libbcachefs/bcachefs.h
index 0c13fa19..131d0f7b 100644
--- a/libbcachefs/bcachefs.h
+++ b/libbcachefs/bcachefs.h
@@ -179,6 +179,7 @@
#undef pr_fmt
#define pr_fmt(fmt) "bcachefs: %s() " fmt "\n", __func__
+#include <linux/backing-dev-defs.h>
#include <linux/bug.h>
#include <linux/bio.h>
#include <linux/closure.h>
diff --git a/libbcachefs/btree_iter.c b/libbcachefs/btree_iter.c
index 8c7fc74f..f5d8a730 100644
--- a/libbcachefs/btree_iter.c
+++ b/libbcachefs/btree_iter.c
@@ -175,8 +175,8 @@ bool __bch2_btree_node_relock(struct btree_trans *trans,
}
}
-static bool bch2_btree_node_upgrade(struct btree_trans *trans,
- struct btree_path *path, unsigned level)
+bool bch2_btree_node_upgrade(struct btree_trans *trans,
+ struct btree_path *path, unsigned level)
{
struct btree *b = path->l[level].b;
diff --git a/libbcachefs/btree_iter.h b/libbcachefs/btree_iter.h
index 61bbb7bc..2dc58828 100644
--- a/libbcachefs/btree_iter.h
+++ b/libbcachefs/btree_iter.h
@@ -166,6 +166,9 @@ static inline int btree_trans_restart(struct btree_trans *trans)
return -EINTR;
}
+bool bch2_btree_node_upgrade(struct btree_trans *,
+ struct btree_path *, unsigned);
+
bool __bch2_btree_path_upgrade(struct btree_trans *,
struct btree_path *, unsigned);
diff --git a/libbcachefs/btree_update_leaf.c b/libbcachefs/btree_update_leaf.c
index c4054667..b9c777cc 100644
--- a/libbcachefs/btree_update_leaf.c
+++ b/libbcachefs/btree_update_leaf.c
@@ -507,6 +507,15 @@ err:
return ret;
}
+static inline void path_upgrade_readers(struct btree_trans *trans, struct btree_path *path)
+{
+ unsigned l;
+
+ for (l = 0; l < BTREE_MAX_DEPTH; l++)
+ if (btree_node_read_locked(path, l))
+ BUG_ON(!bch2_btree_node_upgrade(trans, path, l));
+}
+
static inline void upgrade_readers(struct btree_trans *trans, struct btree_path *path)
{
struct btree *b = path_l(path)->b;
@@ -514,7 +523,7 @@ static inline void upgrade_readers(struct btree_trans *trans, struct btree_path
do {
if (path->nodes_locked &&
path->nodes_locked != path->nodes_intent_locked)
- BUG_ON(!bch2_btree_path_upgrade(trans, path, path->level + 1));
+ path_upgrade_readers(trans, path);
} while ((path = prev_btree_path(trans, path)) &&
path_l(path)->b == b);
}
@@ -560,7 +569,8 @@ static inline bool have_conflicting_read_lock(struct btree_trans *trans, struct
//if (path == pos)
// break;
- if (path->nodes_locked != path->nodes_intent_locked)
+ if (path->nodes_locked != path->nodes_intent_locked &&
+ !bch2_btree_path_upgrade(trans, path, path->level + 1))
return true;
}
diff --git a/libbcachefs/fs-io.c b/libbcachefs/fs-io.c
index 3a3f6c7d..684488ef 100644
--- a/libbcachefs/fs-io.c
+++ b/libbcachefs/fs-io.c
@@ -1509,8 +1509,8 @@ retry_reservation:
unsigned pg_offset = (offset + copied) & (PAGE_SIZE - 1);
unsigned pg_len = min_t(unsigned, len - copied,
PAGE_SIZE - pg_offset);
- unsigned pg_copied = iov_iter_copy_from_user_atomic(page,
- iter, pg_offset, pg_len);
+ unsigned pg_copied = copy_page_from_iter_atomic(page,
+ pg_offset, pg_len,iter);
if (!pg_copied)
break;
@@ -1523,7 +1523,6 @@ retry_reservation:
}
flush_dcache_page(page);
- iov_iter_advance(iter, pg_copied);
copied += pg_copied;
if (pg_copied != pg_len)
diff --git a/libbcachefs/fsck.c b/libbcachefs/fsck.c
index 5bc04c7b..9519ced9 100644
--- a/libbcachefs/fsck.c
+++ b/libbcachefs/fsck.c
@@ -113,6 +113,35 @@ static int subvol_lookup(struct btree_trans *trans, u32 subvol,
return lockrestart_do(trans, __subvol_lookup(trans, subvol, snapshot, inum));
}
+static int lookup_first_inode(struct btree_trans *trans, u64 inode_nr,
+ struct bch_inode_unpacked *inode)
+{
+ struct btree_iter iter;
+ struct bkey_s_c k;
+ int ret;
+
+ bch2_trans_iter_init(trans, &iter, BTREE_ID_inodes,
+ POS(0, inode_nr),
+ BTREE_ITER_ALL_SNAPSHOTS);
+ k = bch2_btree_iter_peek(&iter);
+ ret = bkey_err(k);
+ if (ret)
+ goto err;
+
+ if (!k.k || bkey_cmp(k.k->p, POS(0, inode_nr))) {
+ ret = -ENOENT;
+ goto err;
+ }
+
+ ret = bch2_inode_unpack(bkey_s_c_to_inode(k), inode);
+err:
+ if (ret && ret != -EINTR)
+ bch_err(trans->c, "error %i fetching inode %llu",
+ ret, inode_nr);
+ bch2_trans_iter_exit(trans, &iter);
+ return ret;
+}
+
static int __lookup_inode(struct btree_trans *trans, u64 inode_nr,
struct bch_inode_unpacked *inode,
u32 *snapshot)
@@ -272,7 +301,7 @@ static int __remove_dirent(struct btree_trans *trans, struct bpos pos)
struct bch_hash_info dir_hash_info;
int ret;
- ret = __lookup_inode(trans, pos.inode, &dir_inode, NULL);
+ ret = lookup_first_inode(trans, pos.inode, &dir_inode);
if (ret)
return ret;
@@ -669,7 +698,7 @@ static int check_key_has_snapshot(struct btree_trans *trans,
char buf[200];
int ret = 0;
- if (fsck_err_on(!snapshot_t(c, k.k->p.snapshot)->equiv, c,
+ if (mustfix_fsck_err_on(!snapshot_t(c, k.k->p.snapshot)->equiv, c,
"key in missing snapshot: %s",
(bch2_bkey_val_to_text(&PBUF(buf), c, k), buf)))
return bch2_btree_delete_at(trans, iter,
@@ -918,8 +947,7 @@ static int check_inodes(struct bch_fs *c, bool full)
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
- bch2_trans_iter_init(&trans, &iter, BTREE_ID_inodes,
- POS(BCACHEFS_ROOT_INO, 0),
+ bch2_trans_iter_init(&trans, &iter, BTREE_ID_inodes, POS_MIN,
BTREE_ITER_INTENT|
BTREE_ITER_PREFETCH|
BTREE_ITER_ALL_SNAPSHOTS);
diff --git a/libbcachefs/super-io.c b/libbcachefs/super-io.c
index 3903b730..33d832bc 100644
--- a/libbcachefs/super-io.c
+++ b/libbcachefs/super-io.c
@@ -807,7 +807,8 @@ int bch2_write_super(struct bch_fs *c)
!can_mount_with_written ||
(can_mount_without_written &&
!can_mount_with_written), c,
- "Unable to write superblock to sufficient devices"))
+ "Unable to write superblock to sufficient devices (from %ps)",
+ (void *) _RET_IP_))
ret = -1;
out:
/* Make new options visible after they're persistent: */
diff --git a/libbcachefs/util.h b/libbcachefs/util.h
index 84ef4d6d..bec84d8a 100644
--- a/libbcachefs/util.h
+++ b/libbcachefs/util.h
@@ -19,7 +19,6 @@
#include <linux/workqueue.h>
#define PAGE_SECTOR_SHIFT (PAGE_SHIFT - 9)
-#define PAGE_SECTORS (1UL << PAGE_SECTOR_SHIFT)
struct closure;