]> err.no Git - linux-2.6/blobdiff - fs/fuse/file.c
[PATCH] fuse: add bmap support
[linux-2.6] / fs / fuse / file.c
index 763a50daf1c0a7cc7c336a0d2ba99a64e7baeb1c..128f79c40803fb43381da3d56370c74b3a5bff48 100644 (file)
@@ -754,6 +754,42 @@ static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl)
        return err;
 }
 
+static sector_t fuse_bmap(struct address_space *mapping, sector_t block)
+{
+       struct inode *inode = mapping->host;
+       struct fuse_conn *fc = get_fuse_conn(inode);
+       struct fuse_req *req;
+       struct fuse_bmap_in inarg;
+       struct fuse_bmap_out outarg;
+       int err;
+
+       if (!inode->i_sb->s_bdev || fc->no_bmap)
+               return 0;
+
+       req = fuse_get_req(fc);
+       if (IS_ERR(req))
+               return 0;
+
+       memset(&inarg, 0, sizeof(inarg));
+       inarg.block = block;
+       inarg.blocksize = inode->i_sb->s_blocksize;
+       req->in.h.opcode = FUSE_BMAP;
+       req->in.h.nodeid = get_node_id(inode);
+       req->in.numargs = 1;
+       req->in.args[0].size = sizeof(inarg);
+       req->in.args[0].value = &inarg;
+       req->out.numargs = 1;
+       req->out.args[0].size = sizeof(outarg);
+       req->out.args[0].value = &outarg;
+       request_send(fc, req);
+       err = req->out.h.error;
+       fuse_put_request(fc, req);
+       if (err == -ENOSYS)
+               fc->no_bmap = 1;
+
+       return err ? 0 : outarg.block;
+}
+
 static const struct file_operations fuse_file_operations = {
        .llseek         = generic_file_llseek,
        .read           = do_sync_read,
@@ -787,6 +823,7 @@ static const struct address_space_operations fuse_file_aops  = {
        .commit_write   = fuse_commit_write,
        .readpages      = fuse_readpages,
        .set_page_dirty = fuse_set_page_dirty,
+       .bmap           = fuse_bmap,
 };
 
 void fuse_init_file_inode(struct inode *inode)