[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