+#ifdef BCACHEFS_FUSE
+
#include <errno.h>
#include <float.h>
#include <getopt.h>
#include "libbcachefs/btree_iter.h"
#include "libbcachefs/buckets.h"
#include "libbcachefs/dirent.h"
+#include "libbcachefs/errcode.h"
#include "libbcachefs/error.h"
#include "libbcachefs/fs-common.h"
#include "libbcachefs/inode.h"
inum = bch2_dirent_lookup(c, dir, &hash_info, &qstr);
if (!inum) {
- ret = -ENOENT;
- goto err;
+ struct fuse_entry_param e = {
+ .attr_timeout = DBL_MAX,
+ .entry_timeout = DBL_MAX,
+ };
+ fuse_reply_entry(req, &e);
+ return;
}
ret = bch2_inode_find_by_inum(c, inum, &bi);
struct bch_fs *c = fuse_req_userdata(req);
struct bch_inode_unpacked inode_u;
struct btree_trans trans;
- struct btree_iter *iter;
+ struct btree_iter iter;
u64 now;
int ret;
+ fuse_log(FUSE_LOG_DEBUG, "bcachefs_fuse_setattr(%llu, %x)\n",
+ inum, to_set);
+
inum = map_root_ino(inum);
bch2_trans_init(&trans, c, 0, 0);
bch2_trans_begin(&trans);
now = bch2_current_time(c);
- iter = bch2_inode_peek(&trans, &inode_u, inum, BTREE_ITER_INTENT);
- ret = PTR_ERR_OR_ZERO(iter);
+ ret = bch2_inode_peek(&trans, &iter, &inode_u, inum, BTREE_ITER_INTENT);
if (ret)
goto err;
inode_u.bi_mtime = now;
/* TODO: CTIME? */
- ret = bch2_inode_write(&trans, iter, &inode_u) ?:
+ ret = bch2_inode_write(&trans, &iter, &inode_u) ?:
bch2_trans_commit(&trans, NULL, NULL,
- BTREE_INSERT_ATOMIC|
BTREE_INSERT_NOFAIL);
err:
+ bch2_trans_iter_exit(&trans, &iter);
if (ret == -EINTR)
goto retry;
bch2_inode_init_early(c, new_inode);
- return bch2_trans_do(c, NULL, BTREE_INSERT_ATOMIC,
+ return bch2_trans_do(c, NULL, NULL, 0,
bch2_create_trans(&trans,
dir, &dir_u,
new_inode, &qstr,
struct bch_inode_unpacked new_inode;
int ret;
+ fuse_log(FUSE_LOG_DEBUG, "bcachefs_fuse_mknod(%llu, %s, %x, %x)\n",
+ dir, name, mode, rdev);
ret = do_create(c, dir, name, mode, rdev, &new_inode);
if (ret)
goto err;
static void bcachefs_fuse_mkdir(fuse_req_t req, fuse_ino_t dir,
const char *name, mode_t mode)
{
+ fuse_log(FUSE_LOG_DEBUG, "bcachefs_fuse_mkdir(%llu, %s, %x)\n",
+ dir, name, mode);
+
BUG_ON(mode & S_IFMT);
mode |= S_IFDIR;
struct qstr qstr = QSTR(name);
int ret;
+ fuse_log(FUSE_LOG_DEBUG, "bcachefs_fuse_unlink(%llu, %s)\n", dir, name);
+
dir = map_root_ino(dir);
- ret = bch2_trans_do(c, NULL, BTREE_INSERT_ATOMIC|BTREE_INSERT_NOFAIL,
+ ret = bch2_trans_do(c, NULL, NULL, BTREE_INSERT_NOFAIL,
bch2_unlink_trans(&trans, dir, &dir_u,
&inode_u, &qstr));
static void bcachefs_fuse_rmdir(fuse_req_t req, fuse_ino_t dir,
const char *name)
{
+ fuse_log(FUSE_LOG_DEBUG, "bcachefs_fuse_rmdir(%llu, %s)\n", dir, name);
+
dir = map_root_ino(dir);
bcachefs_fuse_unlink(req, dir, name);
struct qstr src_name = QSTR(dstname);
int ret;
+ fuse_log(FUSE_LOG_DEBUG,
+ "bcachefs_fuse_rename(%llu, %s, %llu, %s, %x)\n",
+ src_dir, srcname, dst_dir, dstname, flags);
+
src_dir = map_root_ino(src_dir);
dst_dir = map_root_ino(dst_dir);
/* XXX handle overwrites */
- ret = bch2_trans_do(c, NULL, BTREE_INSERT_ATOMIC,
+ ret = bch2_trans_do(c, NULL, NULL, 0,
bch2_rename_trans(&trans,
src_dir, &src_dir_u,
dst_dir, &dst_dir_u,
fuse_ino_t newparent, const char *newname)
{
struct bch_fs *c = fuse_req_userdata(req);
- struct bch_inode_unpacked inode_u;
+ struct bch_inode_unpacked dir_u, inode_u;
struct qstr qstr = QSTR(newname);
int ret;
+ fuse_log(FUSE_LOG_DEBUG, "bcachefs_fuse_link(%llu, %llu, %s)\n",
+ inum, newparent, newname);
+
newparent = map_root_ino(newparent);
- ret = bch2_trans_do(c, NULL, BTREE_INSERT_ATOMIC,
+ ret = bch2_trans_do(c, NULL, NULL, 0,
bch2_link_trans(&trans, newparent,
- inum, &inode_u, &qstr));
+ inum, &dir_u, &inode_u, &qstr));
if (!ret) {
struct fuse_entry_param e = inode_to_entry(c, &inode_u);
static int inode_update_times(struct bch_fs *c, fuse_ino_t inum)
{
struct btree_trans trans;
- struct btree_iter *iter;
+ struct btree_iter iter;
struct bch_inode_unpacked inode_u;
int ret = 0;
u64 now;
bch2_trans_begin(&trans);
now = bch2_current_time(c);
- iter = bch2_inode_peek(&trans, &inode_u, inum, BTREE_ITER_INTENT);
- ret = PTR_ERR_OR_ZERO(iter);
+ ret = bch2_inode_peek(&trans, &iter, &inode_u, inum, BTREE_ITER_INTENT);
if (ret)
goto err;
inode_u.bi_mtime = now;
inode_u.bi_ctime = now;
- ret = bch2_inode_write(&trans, iter, &inode_u);
+ ret = bch2_inode_write(&trans, &iter, &inode_u);
if (ret)
goto err;
ret = bch2_trans_commit(&trans, NULL, NULL,
- BTREE_INSERT_ATOMIC|BTREE_INSERT_NOFAIL);
+ BTREE_INSERT_NOFAIL);
err:
+ bch2_trans_iter_exit(&trans, &iter);
if (ret == -EINTR)
goto retry;
inum, size, offset);
struct fuse_align_io align = align_io(c, size, offset);
+ void *aligned_buf = aligned_alloc(PAGE_SIZE, align.size);
+ BUG_ON(!aligned_buf);
if (get_inode_io_opts(c, inum, &io_opts)) {
ret = -ENOENT;
}
/* Realign the data and read in start and end, if needed */
- void *aligned_buf = aligned_alloc(PAGE_SIZE, align.size);
/* Read partial start data. */
if (align.pad_start) {
if (!ret) {
BUG_ON(written == 0);
fuse_reply_write(req, written);
+ free(aligned_buf);
return;
}
err:
fuse_reply_err(req, -ret);
+ free(aligned_buf);
}
static void bcachefs_fuse_symlink(fuse_req_t req, const char *link,
size_t link_len = strlen(link);
int ret;
+ fuse_log(FUSE_LOG_DEBUG, "bcachefs_fuse_symlink(%s, %llu, %s)\n",
+ link, dir, name);
+
dir = map_root_ino(dir);
ret = do_create(c, dir, name, S_IFLNK|S_IRWXUGO, 0, &new_inode);
struct fuse_align_io align = align_io(c, link_len + 1, 0);
void *aligned_buf = aligned_alloc(PAGE_SIZE, align.size);
+ BUG_ON(!aligned_buf);
+
memset(aligned_buf, 0, align.size);
memcpy(aligned_buf, link, link_len); /* already terminated */
struct bch_fs *c = fuse_req_userdata(req);
char *buf = NULL;
+ fuse_log(FUSE_LOG_DEBUG, "bcachefs_fuse_readlink(%llu)\n", inum);
+
struct bch_inode_unpacked bi;
int ret = bch2_inode_find_by_inum(c, inum, &bi);
if (ret)
ctx->buf += len;
ctx->bufsize -= len;
+
return 0;
}
struct bch_inode_unpacked new_inode;
int ret;
+ fuse_log(FUSE_LOG_DEBUG, "bcachefs_fuse_create(%llu, %s, %x)\n",
+ dir, name, mode);
+
ret = do_create(c, dir, name, mode, 0, &new_inode);
if (ret)
goto err;
c = bch2_fs_open(ctx.devices, ctx.nr_devices, bch_opts);
if (IS_ERR(c))
die("error opening %s: %s", ctx.devices_str,
- strerror(-PTR_ERR(c)));
+ bch2_err_str(PTR_ERR(c)));
/* Fuse */
struct fuse_session *se =
if (fuse_session_mount(se, fuse_opts.mountpoint))
die("fuse_mount err: %m");
+ /* This print statement is a trigger for tests. */
+ printf("Fuse mount initialized.\n");
+
fuse_daemonize(fuse_opts.foreground);
ret = fuse_session_loop(se);
return ret ? 1 : 0;
}
+
+#endif /* BCACHEFS_FUSE */