[Pkg-ocaml-maint-commits] [SCM] libfuse-ocaml packaging branch, master, updated. upstream/0.0-13-g5e8da3e
Goswin von Brederlow
goswin-v-b at web.de
Fri Mar 6 18:52:34 UTC 2009
The following commit has been merged in the master branch:
commit c2dbd68a00e38413b1bf368dec3b1d2d020eb180
Author: Goswin von Brederlow <goswin-v-b at web.de>
Date: Fri Mar 6 19:45:16 2009 +0100
Merging upstream and debian for release of 0.1-1.
diff --git a/examples/fs.ml b/examples/fs.ml
index f79e471..6dd2953 100644
--- a/examples/fs.ml
+++ b/examples/fs.ml
@@ -55,10 +55,11 @@ let fs_getattr inode =
let fs_ops = {
- Fuse.init = fs_init;
- Fuse.destroy = fs_destroy;
- Fuse.lookup = fs_lookup;
- Fuse.getattr = fs_getattr;
+ Fuse.default_ops with
+ Fuse.init = Some fs_init;
+ Fuse.destroy = Some fs_destroy;
+ Fuse.lookup = Some fs_lookup;
+ Fuse.getattr = Some fs_getattr;
}
let main args =
diff --git a/lib/fuse.ml b/lib/fuse.ml
index 745d6d1..a0041a5 100644
--- a/lib/fuse.ml
+++ b/lib/fuse.ml
@@ -19,6 +19,7 @@
type error =
SUCCESS
| ENOENT
+ | EIO
exception Error of error
@@ -46,19 +47,131 @@ type entry = {
e_stats_timeout : float;
e_entry_timeout : float;
}
+type file_info
+type mode
+type dev
+type statfs
+type lock
+type lock_info
+ (*
+type bmap_info
+ *)
type ops = {
- init : unit -> unit;
- destroy : unit -> unit;
- lookup : int64 -> string -> entry;
- getattr : int64 -> (stats * float);
+ init : (unit -> unit) option;
+ destroy : (unit -> unit) option;
+ lookup : (inode -> string -> entry) option;
+ forget : (inode -> int64 -> unit) option;
+ getattr : (inode -> (stats * float)) option;
+ setattr : (inode -> stats -> int -> file_info -> (stats * float)) option;
+ readlink : (inode -> string) option;
+ mknod : (inode -> string -> mode -> dev -> entry) option;
+ mkdir : (inode -> string -> mode -> entry) option;
+ unlink : (inode -> string -> unit) option;
+ rmdir : (inode -> string -> unit) option;
+ symlink : (string -> inode -> string -> entry) option;
+ rename : (inode -> string -> inode -> string -> unit) option;
+ link : (inode -> inode -> string -> entry) option;
+ openfile : (inode -> file_info -> file_info) option;
+ read : (inode -> int -> int64 -> file_info -> string) option;
+ write : (inode -> string -> int64 -> file_info -> int) option;
+ flush : (inode -> file_info -> unit) option;
+ release : (inode -> file_info -> unit) option;
+ fsync : (inode -> bool -> file_info -> unit) option;
+ opendir : (inode -> file_info -> file_info) option;
+ readdir : (inode -> int -> int64 -> file_info -> string) option;
+ releasedir : (inode -> file_info -> unit) option;
+ fsyncdir : (inode -> bool -> file_info -> unit) option;
+ statfs : (inode -> statfs) option;
+ setxattr : (inode -> string -> string -> int -> unit) option;
+ getxattr : (inode -> string -> int -> string) option;
+ listxattr : (inode -> int -> string list) option;
+ removexattr : (inode -> string -> unit) option;
+ access : (inode -> int -> unit) option;
+ create : (inode -> string -> mode -> file_info -> entry) option;
+ getlk : (inode -> file_info -> lock -> lock_info) option;
+ setlk : (inode -> file_info -> lock -> bool -> unit) option;
+(*
+ bmap : (inode -> int64 -> int64 -> int64) option;
+*)
+}
+
+let default_ops = {
+ init = None;
+ destroy = None;
+ lookup = None;
+ forget = None;
+ getattr = None;
+ setattr = None;
+ readlink = None;
+ mknod = None;
+ mkdir = None;
+ unlink = None;
+ rmdir = None;
+ symlink = None;
+ rename = None;
+ link = None;
+ openfile = None;
+ read = None;
+ write = None;
+ flush = None;
+ release = None;
+ fsync = None;
+ opendir = None;
+ readdir = None;
+ releasedir = None;
+ fsyncdir = None;
+ statfs = None;
+ setxattr = None;
+ getxattr = None;
+ listxattr = None;
+ removexattr = None;
+ access = None;
+ create = None;
+ getlk = None;
+ setlk = None;
+(*
+ bmap = None;
+*)
}
type fuse_ops = {
- fuse_init : unit -> unit;
- fuse_destroy : unit -> unit;
- fuse_lookup : fuse_req -> int64 -> string -> unit;
- fuse_getattr : fuse_req -> int64 -> unit;
+ fuse_init : unit -> unit;
+ fuse_destroy : unit -> unit;
+ fuse_lookup : fuse_req -> inode -> string -> unit;
+ fuse_forget : fuse_req -> inode -> int64 -> unit;
+ fuse_getattr : fuse_req -> inode -> unit;
+ fuse_setattr : fuse_req -> inode -> stats -> int -> file_info -> unit;
+ fuse_readlink : fuse_req -> inode -> unit;
+ fuse_mknod : fuse_req -> inode -> string -> mode -> dev -> unit;
+ fuse_mkdir : fuse_req -> inode -> string -> mode -> unit;
+ fuse_unlink : fuse_req -> inode -> string -> unit;
+ fuse_rmdir : fuse_req -> inode -> string -> unit;
+ fuse_symlink : fuse_req -> string -> inode -> string -> unit;
+ fuse_rename : fuse_req -> inode -> string -> inode -> string -> unit;
+ fuse_link : fuse_req -> inode -> inode -> string -> unit;
+ fuse_openfile : fuse_req -> inode -> file_info -> unit;
+ fuse_read : fuse_req -> inode -> int -> int64 -> file_info -> unit;
+ fuse_write : fuse_req -> inode -> string -> int64 -> file_info -> unit;
+ fuse_flush : fuse_req -> inode -> file_info -> unit;
+ fuse_release : fuse_req -> inode -> file_info -> unit;
+ fuse_fsync : fuse_req -> inode -> bool -> file_info -> unit;
+ fuse_opendir : fuse_req -> inode -> file_info -> unit;
+ fuse_readdir : fuse_req -> inode -> int -> int64 -> file_info -> unit;
+ fuse_releasedir : fuse_req -> inode -> file_info -> unit;
+ fuse_fsyncdir : fuse_req -> inode -> bool -> file_info -> unit;
+ fuse_statfs : fuse_req -> inode -> unit;
+ fuse_setxattr : fuse_req -> inode -> string -> string -> int -> unit;
+ fuse_getxattr : fuse_req -> inode -> string -> int -> unit;
+ fuse_listxattr : fuse_req -> inode -> int -> unit;
+ fuse_removexattr : fuse_req -> inode -> string -> unit;
+ fuse_access : fuse_req -> inode -> int -> unit;
+ fuse_create : fuse_req -> inode -> string -> mode -> file_info -> unit;
+ fuse_getlk : fuse_req -> inode -> file_info -> lock -> unit;
+ fuse_setlk : fuse_req -> inode -> file_info -> lock -> bool -> unit;
+(*
+ fuse_bmap : fuse_req -> inode -> int64 -> int64 -> unit;
+*)
}
let root_inode = Int64.one
@@ -71,46 +184,525 @@ external fd : filesystem -> Unix.file_descr = "caml_fuse_fd_stub"
external process : filesystem -> unit = "caml_fuse_process_stub"
external reply_err : fuse_req -> error -> int = "caml_fuse_reply_err_stub"
+external reply_none : fuse_req -> unit = "caml_fuse_reply_none_stub"
external reply_entry : fuse_req -> entry -> int = "caml_fuse_reply_entry_stub"
+external reply_create : fuse_req -> entry -> file_info -> int = "caml_fuse_reply_create_stub"
external reply_attr : fuse_req -> stats -> float -> int = "caml_fuse_reply_attr_stub"
+external reply_readlink : fuse_req -> string -> int = "caml_fuse_reply_readlink_stub"
+external reply_open : fuse_req -> file_info -> int = "caml_fuse_reply_open_stub"
+external reply_write : fuse_req -> int -> int = "caml_fuse_reply_write_stub"
+external reply_buf : fuse_req -> string -> int = "caml_fuse_reply_buf_stub"
+external reply_iov : fuse_req -> string array -> int = "caml_fuse_reply_iov_stub"
+external reply_statfs : fuse_req -> statfs -> int = "caml_fuse_reply_statfs_stub"
+external reply_xattr : fuse_req -> int -> int = "caml_fuse_reply_xattr_stub"
+external reply_lock : fuse_req -> lock_info -> int = "caml_fuse_reply_lock_stub"
+(*
+external reply_bmap : fuse_req -> int64 -> int = "caml_fuse_reply_bmap_stub"
+*)
-let fuse_init ops = fun () ->
- Printf.printf "## init\n";
- ops.init ();
- flush_all ()
+let fuse_init init = fun () ->
+ Printf.printf "## init\n";
+ init ();
+ flush_all ()
-let fuse_destroy ops = fun () ->
+let fuse_destroy destroy = fun () ->
Printf.printf "## destroy\n";
- ops.destroy ();
+ destroy ();
flush_all ()
-let fuse_lookup ops = fun req inode name ->
+let fuse_lookup lookup = fun req inode name ->
Printf.printf "## lookup %Lu %s\n" inode name;
begin
try
- let entry = ops.lookup inode name
+ let entry = lookup inode name
in
assert((reply_entry req entry) = 0)
- with Error err -> assert((reply_err req err) = 0);
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_forget forget = fun req inode nlookup ->
+ Printf.printf "## forget %Lu\n" inode;
+ begin
+ try
+ let () = forget inode nlookup
+ in
+ reply_none req
+ with _ ->
+ Printf.printf " Error: unknown exception\n";
+ reply_none req;
end;
flush_all ()
-let fuse_getattr ops = fun req inode ->
+let fuse_getattr getattr = fun req inode ->
Printf.printf "## getattr %Lu\n" inode;
begin
try
- let (stats, timeout) = ops.getattr inode
+ let (stats, timeout) = getattr inode
+ in
+ assert((reply_attr req stats timeout) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_setattr setattr = fun req inode stats to_set file_info ->
+ Printf.printf "## setattr %Lu\n" inode;
+ begin
+ try
+ let (stats, timeout) = setattr inode stats to_set file_info
in
assert((reply_attr req stats timeout) = 0)
- with Error err -> assert((reply_err req err) = 0);
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_readlink readlink = fun req inode ->
+ Printf.printf "## readlink %Lu\n" inode;
+ begin
+ try
+ let dest = readlink inode
+ in
+ assert((reply_readlink req dest) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_mknod mknod = fun req parent name mode dev ->
+ Printf.printf "## mknod %Lu/%s\n" parent name;
+ begin
+ try
+ let entry = mknod parent name mode dev
+ in
+ assert((reply_entry req entry) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_mkdir mkdir = fun req parent name mode ->
+ Printf.printf "## mkdir %Lu/%s\n" parent name;
+ begin
+ try
+ let entry = mkdir parent name mode
+ in
+ assert((reply_entry req entry) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_unlink unlink = fun req parent name ->
+ Printf.printf "## unlink %Lu/%s\n" parent name;
+ begin
+ try
+ let () = unlink parent name
+ in
+ assert((reply_err req SUCCESS) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+
+let fuse_rmdir rmdir = fun req parent name ->
+ Printf.printf "## rmdir %Lu/%s\n" parent name;
+ begin
+ try
+ let () = rmdir parent name
+ in
+ assert((reply_err req SUCCESS) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_symlink symlink = fun req dest parent name ->
+ Printf.printf "## symlink %Lu/%s\n" parent name;
+ begin
+ try
+ let entry = symlink dest parent name
+ in
+ assert((reply_entry req entry) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_rename rename = fun req parent name newparent newname ->
+ Printf.printf "## rename %Lu/%s -> %Lu/%s\n" parent name newparent newname;
+ begin
+ try
+ let () = rename parent name newparent newname
+ in
+ assert((reply_err req SUCCESS) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_link link = fun req inode newparent newname ->
+ Printf.printf "## link %Lu -> %Lu/%s\n" inode newparent newname;
+ begin
+ try
+ let entry = link inode newparent newname
+ in
+ assert((reply_entry req entry) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_openfile openfile = fun req inode file_info ->
+ Printf.printf "## openfile %Lu\n" inode;
+ begin
+ try
+ let file_info = openfile inode file_info
+ in
+ assert((reply_open req file_info) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+
+let fuse_read read = fun req inode size off file_info ->
+ Printf.printf "## read %Lu\n" inode;
+ begin
+ try
+ let buf = read inode size off file_info
+ in
+ assert((reply_buf req buf) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_write write = fun req inode string off file_info ->
+ Printf.printf "## write %Lu\n" inode;
+ begin
+ try
+ let size = write inode string off file_info
+ in
+ assert((reply_write req size) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_flush flush = fun req inode file_info ->
+ Printf.printf "## flush %Lu\n" inode;
+ begin
+ try
+ let () = flush inode file_info
+ in
+ assert((reply_err req SUCCESS) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
end;
flush_all ()
+let fuse_release release = fun req inode file_info ->
+ Printf.printf "## release %Lu\n" inode;
+ begin
+ try
+ let () = release inode file_info
+ in
+ assert((reply_err req SUCCESS) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_fsync fsync = fun req inode datasync file_info ->
+ Printf.printf "## fsync %Lu\n" inode;
+ begin
+ try
+ let () = fsync inode datasync file_info
+ in
+ assert((reply_err req SUCCESS) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_opendir opendir = fun req inode file_info ->
+ Printf.printf "## opendir %Lu\n" inode;
+ begin
+ try
+ let file_info = opendir inode file_info
+ in
+ assert((reply_open req file_info) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_readdir readdir = fun req inode size offset file_info ->
+ Printf.printf "## readdir %Lu\n" inode;
+ begin
+ try
+ let buf = readdir inode size offset file_info
+ in
+ assert((reply_buf req buf) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_releasedir releasedir = fun req inode file_info ->
+ Printf.printf "## releasedir %Lu\n" inode;
+ begin
+ try
+ let () = releasedir inode file_info
+ in
+ assert((reply_err req SUCCESS) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_fsyncdir fsyncdir = fun req inode datasync file_info ->
+ Printf.printf "## fsyncdir %Lu\n" inode;
+ begin
+ try
+ let () = fsyncdir inode datasync file_info
+ in
+ assert((reply_err req SUCCESS) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_statfs statfs = fun req inode ->
+ Printf.printf "## statfs %Lu\n" inode;
+ begin
+ try
+ let statfs = statfs inode
+ in
+ assert((reply_statfs req statfs) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_setxattr setxattr = fun req inode name value flags ->
+ Printf.printf "## setxattr %Lu\n" inode;
+ begin
+ try
+ let () = setxattr inode name value flags
+ in
+ assert((reply_err req SUCCESS) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_getxattr getxattr = fun req inode name size ->
+ Printf.printf "## getxattr %Lu %s\n" inode name;
+ begin
+ try (* FIXME: add reply_xattr support *)
+ let buf = getxattr inode name size
+ in
+ assert((reply_buf req buf) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_listxattr listxattr = fun req inode size ->
+ Printf.printf "## readlink %Lu\n" inode;
+ begin
+ try (* FIXME: add reply_xattr support *)
+ let list = listxattr inode size in
+ let buf = List.fold_left (fun buf str -> buf ^ "\000" ^ str) "" list
+ in (* fixme: better list to string *)
+ assert((reply_buf req buf) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_removexattr removexattr = fun req inode name ->
+ Printf.printf "## removexattr %Lu %s\n" inode name;
+ begin
+ try
+ let () = removexattr inode name
+ in
+ assert((reply_err req SUCCESS) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_access access = fun req inode mask ->
+ Printf.printf "## access %Lu\n" inode;
+ begin
+ try
+ let () = access inode mask
+ in
+ assert((reply_err req SUCCESS) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_create create = fun req parent name mode file_info ->
+ Printf.printf "## create %Lu/%s\n" parent name;
+ begin
+ try
+ let entry = create parent name mode file_info
+ in
+ assert((reply_create req entry file_info) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_getlk getlk = fun req inode file_info lock ->
+ Printf.printf "## getlk %Lu\n" inode;
+ begin
+ try
+ let lock_info = getlk inode file_info lock
+ in
+ assert((reply_lock req lock_info) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+let fuse_setlk setlk = fun req inode file_info lock sleep ->
+ Printf.printf "## setlk %Lu\n" inode;
+ begin
+ try
+ let () = setlk inode file_info lock sleep
+ in
+ assert((reply_err req SUCCESS) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+
+(*
+let fuse_bmap bmap = fun req inode blocksize idx ->
+ Printf.printf "## bmap %Lu\n" inode;
+ begin
+ try
+ let bmap_info = bmap inode blocksize idx
+ in
+ assert((reply_bmap req bmap_info) = 0)
+ with Error err -> assert((reply_err req err) = 0)
+ | _ ->
+ Printf.printf " Error: unknown exception\n";
+ assert((reply_err req EIO) = 0);
+ end;
+ flush_all ()
+*)
+
+let morph wrapper = function
+ None -> Obj.magic 0
+ | Some fn -> wrapper fn
+
let fuse_ops ops = {
- fuse_init = fuse_init ops;
- fuse_destroy = fuse_destroy ops;
- fuse_lookup = fuse_lookup ops;
- fuse_getattr = fuse_getattr ops;
+ fuse_init = morph fuse_init ops.init;
+ fuse_destroy = morph fuse_destroy ops.destroy;
+ fuse_lookup = morph fuse_lookup ops.lookup;
+ fuse_forget = morph fuse_forget ops.forget;
+ fuse_getattr = morph fuse_getattr ops.getattr;
+ fuse_setattr = morph fuse_setattr ops.setattr;
+ fuse_readlink = morph fuse_readlink ops.readlink;
+ fuse_mknod = morph fuse_mknod ops.mknod;
+ fuse_mkdir = morph fuse_mkdir ops.mkdir;
+ fuse_unlink = morph fuse_unlink ops.unlink;
+ fuse_rmdir = morph fuse_rmdir ops.rmdir;
+ fuse_symlink = morph fuse_symlink ops.symlink;
+ fuse_rename = morph fuse_rename ops.rename;
+ fuse_link = morph fuse_link ops.link;
+ fuse_openfile = morph fuse_openfile ops.openfile;
+ fuse_read = morph fuse_read ops.read;
+ fuse_write = morph fuse_write ops.write;
+ fuse_flush = morph fuse_flush ops.flush;
+ fuse_release = morph fuse_release ops.release;
+ fuse_fsync = morph fuse_fsync ops.fsync;
+ fuse_opendir = morph fuse_opendir ops.opendir;
+ fuse_readdir = morph fuse_readdir ops.readdir;
+ fuse_releasedir = morph fuse_releasedir ops.releasedir;
+ fuse_fsyncdir = morph fuse_fsyncdir ops.fsyncdir;
+ fuse_statfs = morph fuse_statfs ops.statfs;
+ fuse_setxattr = morph fuse_setxattr ops.setxattr;
+ fuse_getxattr = morph fuse_getxattr ops.getxattr;
+ fuse_listxattr = morph fuse_listxattr ops.listxattr;
+ fuse_removexattr = morph fuse_removexattr ops.removexattr;
+ fuse_access = morph fuse_access ops.access;
+ fuse_create = morph fuse_create ops.create;
+ fuse_getlk = morph fuse_getlk ops.getlk;
+ fuse_setlk = morph fuse_setlk ops.setlk;
+(*
+ fuse_bmap = morph fuse_bmap ops.bmap;
+*)
}
let make mountpoint args ops =
diff --git a/lib/fuse.mli b/lib/fuse.mli
index 6eb823c..f75147f 100644
--- a/lib/fuse.mli
+++ b/lib/fuse.mli
@@ -29,6 +29,7 @@
type error =
SUCCESS
| ENOENT
+ | EIO
exception Error of error
(** Exception to report a failure of an operation *)
@@ -62,11 +63,53 @@ type entry = {
}
(** result of lookup operations *)
+type file_info
+type mode
+type dev
+type statfs
+type lock
+type lock_info
+(*
+type bmap_info
+*)
+
type ops = {
- init : unit -> unit;
- destroy : unit -> unit;
- lookup : int64 -> string -> entry;
- getattr : int64 -> (stats * float);
+ init : (unit -> unit) option;
+ destroy : (unit -> unit) option;
+ lookup : (inode -> string -> entry) option;
+ forget : (inode -> int64 -> unit) option;
+ getattr : (inode -> (stats * float)) option;
+ setattr : (inode -> stats -> int -> file_info -> (stats * float)) option;
+ readlink : (inode -> string) option;
+ mknod : (inode -> string -> mode -> dev -> entry) option;
+ mkdir : (inode -> string -> mode -> entry) option;
+ unlink : (inode -> string -> unit) option;
+ rmdir : (inode -> string -> unit) option;
+ symlink : (string -> inode -> string -> entry) option;
+ rename : (inode -> string -> inode -> string -> unit) option;
+ link : (inode -> inode -> string -> entry) option;
+ openfile : (inode -> file_info -> file_info) option;
+ read : (inode -> int -> int64 -> file_info -> string) option;
+ write : (inode -> string -> int64 -> file_info -> int) option;
+ flush : (inode -> file_info -> unit) option;
+ release : (inode -> file_info -> unit) option;
+ fsync : (inode -> bool -> file_info -> unit) option;
+ opendir : (inode -> file_info -> file_info) option;
+ readdir : (inode -> int -> int64 -> file_info -> string) option;
+ releasedir : (inode -> file_info -> unit) option;
+ fsyncdir : (inode -> bool -> file_info -> unit) option;
+ statfs : (inode -> statfs) option;
+ setxattr : (inode -> string -> string -> int -> unit) option;
+ getxattr : (inode -> string -> int -> string) option;
+ listxattr : (inode -> int -> string list) option;
+ removexattr : (inode -> string -> unit) option;
+ access : (inode -> int -> unit) option;
+ create : (inode -> string -> mode -> file_info -> entry) option;
+ getlk : (inode -> file_info -> lock -> lock_info) option;
+ setlk : (inode -> file_info -> lock -> bool -> unit) option;
+(*
+ bmap : (inode -> int64 -> int64 -> int64) option;
+*)
}
(** filesystem operation
init - start the filesystem
@@ -75,6 +118,8 @@ type ops = {
getattr - get stats for an inode
*)
+val default_ops : ops
+
type filesystem
(** abstract type representing a fuse filesystem *)
diff --git a/lib/fuse_stubs.c b/lib/fuse_stubs.c
index 6bdfbd6..cbd4441 100644
--- a/lib/fuse_stubs.c
+++ b/lib/fuse_stubs.c
@@ -30,10 +30,17 @@
#include <caml/signals.h>
#include <caml/custom.h>
-enum Callbacks {INIT, DESTROY, LOOKUP, GETATTR};
-int errors[] = {0, ENOENT};
+enum Callbacks {
+ INIT, DESTROY, LOOKUP, FORGET, GETATTR, SETATTR, READLINK, MKNOD, MKDIR,
+ UNLINK, RMDIR, SYMLINK, RENAME, LINK, OPENFILE, READ, WRITE, FLUSH,
+ RELEASE, FSYNC, OPENDIR, READDIR, RELEASEDIR, FSYNCDIR, STATFS, SETXATTR,
+ GETXATTR, LISTXATTR, REMOVEXATTR, ACCESS, CREATE, GETLK, SETLK, BMAP
+};
+
+int errors[] = {0, ENOENT, EIO};
typedef struct Filesystem {
+ struct fuse_lowlevel_ops fuse_ops;
struct fuse_chan *ch;
struct fuse_session *se;
value ops;
@@ -96,13 +103,6 @@ static void getattr_stub(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *
CAMLreturn0;
}
-struct fuse_lowlevel_ops fuse_ops = {
- .init = init_stub,
- .destroy = destroy_stub,
- .lookup = lookup_stub,
- .getattr = getattr_stub,
-};
-
static int alive(Filesystem *fs) {
return (fs->mountpoint != NULL);
@@ -186,11 +186,30 @@ CAMLprim value caml_fuse_mount_stub(value ml_mountpoint, value ml_args, value ml
fs->ops = ml_ops;
caml_register_global_root(&fs->ops);
+ // Fill in fuse_ops
+ if (Field(ml_ops, INIT) != 0) {
+ fs->fuse_ops.init = init_stub;
+ }
+ if (Field(ml_ops, DESTROY) != 0) {
+ fs->fuse_ops.destroy = destroy_stub;
+ }
+ if (Field(ml_ops, LOOKUP) != 0) {
+ fs->fuse_ops.lookup = lookup_stub;
+ }
+ if (Field(ml_ops, GETATTR) != 0) {
+ fs->fuse_ops.getattr = getattr_stub;
+ }
+/*
+ if (Field(ml_ops, ) != 0) {
+ fs->fuse_ops. = _stub;
+ }
+*/
+
enter_blocking_section();
// Mount filesystem
fs->ch = fuse_mount(String_val(ml_mountpoint), &fuse_args);
if (fs->ch == NULL) goto out2;
- fs->se = fuse_lowlevel_new(&fuse_args, &fuse_ops, sizeof(fuse_ops), (void*)fs);
+ fs->se = fuse_lowlevel_new(&fuse_args, &fs->fuse_ops, sizeof(fs->fuse_ops), (void*)fs);
if (fs->se == NULL) goto out2;
if (fuse_set_signal_handlers(fs->se) == -1) goto out2;
fuse_session_add_chan(fs->se, fs->ch);
@@ -342,7 +361,7 @@ static void stats_ml_to_c(value ml_stat, struct stat *stat) {
stat->st_ctime = Double_val(Field(ml_stat, 12));
}
-// external caml_fuse_reply_err : fuse_req -> int -> int = "fuse_reply_err_stub"
+// external fuse_reply_err : fuse_req -> int -> int = "caml_fuse_reply_err_stub"
value caml_fuse_reply_err_stub(value req, value error) {
int res;
CAMLparam2(req, error);
@@ -355,7 +374,16 @@ value caml_fuse_reply_err_stub(value req, value error) {
CAMLreturn(Val_int(res));
}
-// external caml_fuse_reply_entry : fuse_req -> entry -> int = "fuse_reply_entry_stub"
+// external fuse_reply_none : fuse_req -> unit = "caml_fuse_reply_none_stub"
+value caml_fuse_reply_none_stub(value req) {
+ CAMLparam1(req);
+
+ fuse_reply_none((fuse_req_t)Field(req, 0));
+
+ CAMLreturn(Val_unit);
+}
+
+// external fuse_reply_entry : fuse_req -> entry -> int = "caml_fuse_reply_entry_stub"
value caml_fuse_reply_entry_stub(value req, value entry) {
int res;
CAMLparam2(req, entry);
@@ -373,7 +401,26 @@ value caml_fuse_reply_entry_stub(value req, value entry) {
CAMLreturn(Val_int(res));
}
-// external caml_fuse_reply_attr : fuse_req -> stats -> int = "fuse_reply_attr_stub"
+// external fuse_reply_create : fuse_req -> entry -> int = "caml_fuse_reply_create_stub"
+value caml_fuse_reply_create_stub(value req, value entry, value file_info) {
+ int res;
+ CAMLparam3(req, entry, file_info);
+
+ struct fuse_entry_param fuse_entry = {
+ .ino = Int64_val(Field(entry, 0)),
+ .generation = Int64_val(Field(entry, 1)),
+ .attr_timeout = Double_val(Field(entry, 3)),
+ .entry_timeout = Double_val(Field(entry, 4)),
+ };
+ stats_ml_to_c(Field(entry, 2), &fuse_entry.attr);
+
+ res = fuse_reply_create((fuse_req_t)Field(req, 0), &fuse_entry,
+ (const struct fuse_file_info*)file_info);
+
+ CAMLreturn(Val_int(res));
+}
+
+// external fuse_reply_attr : fuse_req -> stats -> int = "caml_fuse_reply_attr_stub"
value caml_fuse_reply_attr_stub(value req, value ml_stats, value timeout) {
int res;
CAMLparam3(req, ml_stats, timeout);
@@ -385,3 +432,99 @@ value caml_fuse_reply_attr_stub(value req, value ml_stats, value timeout) {
printf("# fuse_reply_attr_stub(): ino = %lu, mode = 0%o, nlink = %lu, uid = %d, gid = %d, size = %lu, blocks = %lu\n", stats.st_ino, stats.st_mode, stats.st_nlink, stats.st_uid, stats.st_gid, stats.st_size, stats.st_blocks);
CAMLreturn(Val_int(res));
}
+
+// external fuse_reply_readlink : fuse_req -> string -> int = "caml_fuse_reply_readlink_stub"
+value caml_fuse_reply_readlink_stub(value ml_req, value ml_link) {
+ int res;
+ CAMLparam2(ml_req, ml_link);
+
+ res = fuse_reply_readlink((fuse_req_t)Field(ml_req, 0), (const char*)String_val(ml_link));
+
+ CAMLreturn(Val_int(res));
+}
+
+// external fuse_reply_open : fuse_req -> file_info -> int = "caml_fuse_reply_open_stub"
+value caml_fuse_reply_open_stub(value ml_req, value ml_file_info) {
+ int res;
+ CAMLparam2(ml_req, ml_file_info);
+
+ res = fuse_reply_open((fuse_req_t)Field(ml_req, 0), (const struct fuse_file_info*)Field(ml_file_info, 0));
+
+ CAMLreturn(Val_int(res));
+}
+
+// external fuse_reply_write : fuse_req -> int -> int = "caml_fuse_reply_write_stub"
+value caml_fuse_reply_write_stub(value ml_req, value ml_size) {
+ int res;
+ CAMLparam2(ml_req, ml_size);
+
+ res = fuse_reply_write((fuse_req_t)Field(ml_req, 0), Int_val(ml_size));
+
+ CAMLreturn(Val_int(res));
+}
+
+// external fuse_reply_buf : fuse_req -> string -> int = "caml_fuse_reply_buf_stub"
+value caml_fuse_reply_buf_stub(value ml_req, value ml_buf) {
+ int res;
+ CAMLparam2(ml_req, ml_buf);
+
+ res = fuse_reply_buf((fuse_req_t)Field(ml_req, 0), String_val(ml_buf), caml_string_length(ml_buf));
+
+ CAMLreturn(Val_int(res));
+}
+
+// external fuse_reply_iov : fuse_req -> string array -> int = "caml_fuse_reply_iov_stub"
+value caml_fuse_reply_iov_stub(value ml_req, value ml_bufs) {
+ int res;
+ CAMLparam2(ml_req, ml_bufs);
+//FIXME: create struct iovec
+// int fuse_reply_iov(fuse_req_t req, const struct iovec *iov, int count);
+// res = fuse_reply_iov((fuse_req_t)Field(ml_req, 0), Sting_val(ml_buf), caml_string_length(ml_buf));
+ assert(0);
+
+ CAMLreturn(Val_int(res));
+}
+
+// external fuse_reply_statfs : fuse_req -> statfs -> int = "caml_fuse_reply_statfs_stub"
+value caml_fuse_reply_statfs_stub(value ml_req, value ml_statfs) {
+ int res;
+ CAMLparam2(ml_req, ml_statfs);
+// FIXME:
+// int fuse_reply_statfs(fuse_req_t req, const struct statvfs *stbuf);
+// res = fuse_reply_buf((fuse_req_t)Field(ml_req, 0), Sting_val(ml_buf), caml_string_length(ml_buf));
+ assert(0);
+
+ CAMLreturn(Val_int(res));
+}
+
+// external fuse_reply_xattr : fuse_req -> int -> int = "caml_fuse_reply_xattr_stub"
+value caml_fuse_reply_xattr_stub(value ml_req, value ml_count) {
+ int res;
+ CAMLparam2(ml_req, ml_count);
+
+ res = fuse_reply_xattr((fuse_req_t)Field(ml_req, 0), Int_val(ml_count));
+
+ CAMLreturn(Val_int(res));
+}
+
+// external fuse_reply_lock : fuse_req -> lock_info -> int = "caml_fuse_reply_lock_stub"
+value caml_fuse_reply_lock_stub(value ml_req, value ml_lock_info) {
+ int res;
+ CAMLparam2(ml_req, ml_lock_info);
+
+ res = fuse_reply_lock((fuse_req_t)Field(ml_req, 0), (struct flock*)Field(ml_lock_info, 0));
+
+ CAMLreturn(Val_int(res));
+}
+
+/*
+// external fuse_reply_bmap : fuse_req -> int64 -> int = "caml_fuse_reply_bmap_stub"
+value caml_fuse_reply_bmap_stub(value ml_req, value ml_idx) {
+ int res;
+ CAMLparam2(ml_req, ml_idx);
+
+ res = fuse_reply_bmap((fuse_req_t)Field(ml_req, 0), Int64_val(ml_idx));
+
+ CAMLreturn(Val_int(res));
+}
+*/
--
libfuse-ocaml packaging
More information about the Pkg-ocaml-maint-commits
mailing list