aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2006-09-30 16:02:25 +0000
committerMiklos Szeredi <miklos@szeredi.hu>2006-09-30 16:02:25 +0000
commit708b4818f2d0b9a1e277de85a00a0355745a5cd0 (patch)
tree0e35c2d3906473f9b471eb4029a32e91e32d2480 /lib
parentff5fa7f8de978d56e8c334e746e08195ed25730d (diff)
downloadlibfuse-708b4818f2d0b9a1e277de85a00a0355745a5cd0.tar.gz
bmap support
Diffstat (limited to 'lib')
-rw-r--r--lib/fuse.c24
-rw-r--r--lib/fuse_lowlevel.c21
-rw-r--r--lib/mount.c2
3 files changed, 47 insertions, 0 deletions
diff --git a/lib/fuse.c b/lib/fuse.c
index 14789b7..0e3e1d1 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -2371,6 +2371,29 @@ static void fuse_setlk(fuse_req_t req, fuse_ino_t ino,
reply_err(req, err);
}
+static void fuse_bmap(fuse_req_t req, fuse_ino_t ino, size_t blocksize,
+ uint64_t idx)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ err = -ENOSYS;
+ if (f->op.bmap)
+ err = f->op.bmap(path, blocksize, &idx);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ if (!err)
+ fuse_reply_bmap(req, idx);
+ else
+ reply_err(req, err);
+}
+
static struct fuse_lowlevel_ops fuse_path_ops = {
.init = fuse_data_init,
.destroy = fuse_data_destroy,
@@ -2405,6 +2428,7 @@ static struct fuse_lowlevel_ops fuse_path_ops = {
.removexattr = fuse_removexattr,
.getlk = fuse_getlk,
.setlk = fuse_setlk,
+ .bmap = fuse_bmap,
};
static void free_cmd(struct fuse_cmd *cmd)
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
index f014e6e..8ea6779 100644
--- a/lib/fuse_lowlevel.c
+++ b/lib/fuse_lowlevel.c
@@ -403,6 +403,16 @@ int fuse_reply_lock(fuse_req_t req, struct flock *lock)
return send_reply_ok(req, &arg, sizeof(arg));
}
+int fuse_reply_bmap(fuse_req_t req, uint64_t idx)
+{
+ struct fuse_bmap_out arg;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.block = idx;
+
+ return send_reply_ok(req, &arg, sizeof(arg));
+}
+
static void do_lookup(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
char *name = (char *) inarg;
@@ -907,6 +917,16 @@ static struct fuse_req *check_interrupt(struct fuse_ll *f, struct fuse_req *req)
return NULL;
}
+static void do_bmap(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
+{
+ struct fuse_bmap_in *arg = (struct fuse_bmap_in *) inarg;
+
+ if (req->f->op.bmap)
+ req->f->op.bmap(req, nodeid, arg->blocksize, arg->block);
+ else
+ fuse_reply_err(req, ENOSYS);
+}
+
static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
struct fuse_init_in *arg = (struct fuse_init_in *) inarg;
@@ -1040,6 +1060,7 @@ static struct {
[FUSE_ACCESS] = { do_access, "ACCESS" },
[FUSE_CREATE] = { do_create, "CREATE" },
[FUSE_INTERRUPT] = { do_interrupt, "INTERRUPT" },
+ [FUSE_BMAP] = { do_bmap, "BMAP" },
};
#define FUSE_MAXOP (sizeof(fuse_ll_ops) / sizeof(fuse_ll_ops[0]))
diff --git a/lib/mount.c b/lib/mount.c
index 8ac9787..2ed0381 100644
--- a/lib/mount.c
+++ b/lib/mount.c
@@ -49,6 +49,8 @@ static const struct fuse_opt fuse_mount_opts[] = {
FUSE_OPT_KEY("allow_other", KEY_KERN),
FUSE_OPT_KEY("allow_root", KEY_ALLOW_ROOT),
FUSE_OPT_KEY("nonempty", KEY_KERN),
+ FUSE_OPT_KEY("blkdev", KEY_KERN),
+ FUSE_OPT_KEY("blksize=", KEY_KERN),
FUSE_OPT_KEY("default_permissions", KEY_KERN),
FUSE_OPT_KEY("fsname=", KEY_KERN),
FUSE_OPT_KEY("large_read", KEY_KERN),