Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Page
Library
Module
Module type
Parameter
Class
Class type
Source
ceph.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
open Ctypes module C = Bindings.C(Generated) module S = Structs.C(Structs_generated) open S exception Error of (string * int) exception Enoent of (string * string option) (* function * filename *) let () = Printexc.register_printer begin function | Error (func,error) -> Some (Printf.sprintf "Ceph.Error(%s,%d)" func error) | Enoent (func,None) -> Some (Printf.sprintf "Ceph.Enoent(%s)" func) | Enoent (func,Some fname) -> Some (Printf.sprintf "Ceph.Enoent(%s,%S)" func fname) | _ -> None end let check ?path func ret = match ret with | n when n < 0 -> if n = -enoent then raise (Enoent (func,path)) else raise (Error (func,n)) | _ -> () let check1 func f = fun a1 -> check func (f a1) let check2 func f = fun a1 a2 -> check func (f a1 a2) let check3 func f = fun a1 path a3 -> check ~path func (f a1 path a3) type t = C.mount_info Ctypes.structure Ctypes_static.ptr type fd = int let version () = let major = allocate int 0 in let minor = allocate int 0 in let patch = allocate int 0 in let s = C.version major minor patch in s, (!@major, !@minor, !@patch ) let version_headers = (libcephfs_VER_MAJOR,libcephfs_VER_MINOR,libcephfs_VER_EXTRA) let version_string () = fst @@ version () let version_number () = snd @@ version () let create ?id () = let mi = allocate C.handle (from_voidp C.struct_mount_info null) in check "create" @@ C.create mi id; !@mi let release = check1 "release" C.release let init = check1 "init" C.init let mount ?root mi = check "mount" @@ C.mount mi root let unmount = check1 "unmount" C.unmount let conf_read_file ?path mi = check ?path "conf_read_file" @@ C.conf_read_file mi path let conf_parse_env ?var mi = check "conf_parse_env" @@ C.conf_parse_env mi var let chdir mi path = check ~path "chdir" @@ C.chdir mi path let mkdir = check3 "mkdir" C.mkdir let mkdirs = check3 "mkdirs" C.mkdirs let rmdir mi path = check ~path "rmdir" @@ C.rmdir mi path let getcwd = C.getcwd let conf_set = check3 "conf_set" C.conf_set let link mi ~target ~from = check ~path:target "link" @@ C.link mi target from let symlink mi ~target ~from = check "symlink" @@ C.symlink mi target from let unlink mi path = check ~path "unlink" @@ C.unlink mi path let rename mi ~from ~target = check ~path:from "rename" @@ C.rename mi from target let chmod = check3 "chmod" C.chmod let chown mi path ~uid ~gid = check ~path "chown" @@ C.chown mi path uid gid let lchown mi path ~uid ~gid = check ~path "lchown" @@ C.lchown mi path uid gid let opendir mi path = let dir = allocate C.dir_result (from_voidp C.struct_dir_result null) in check ~path "opendir" @@ C.opendir mi path dir; !@dir let closedir = check2 "closedir" C.closedir type file_type = | BLK (** This is a block device. *) | CHR (** This is a character device. *) | DIR (** This is a directory. *) | FIFO (** This is a named pipe (FIFO). *) | LNK (** This is a symbolic link. *) | REG (** This is a regular file. *) | SOCK (** This is a UNIX domain socket. *) | UNKNOWN (** The file type could not be determined. *) type dirent = { inode : int64; typ : file_type; name : string; } module Dirent = struct let typ d = let c = getf !@d d_type in if c = dt_REG then REG else if c = dt_DIR then DIR else if c = dt_LNK then LNK else if c = dt_FIFO then FIFO else if c = dt_SOCK then SOCK else if c = dt_CHR then CHR else if c = dt_BLK then BLK else if c = dt_UNKNOWN then UNKNOWN else UNKNOWN let inode d = getf !@d d_inode let name d = coerce (ptr char) string (d |-> d_name) let make d = { inode = inode d; typ = typ d; name = name d } end let readdir mi dir = match C.readdir mi dir with | None -> None | Some d -> Some (Dirent.make d) type open_flag = O_RDONLY | O_WRONLY | O_RDWR |O_CREAT | O_EXCL | O_TRUNC | O_DIRECTORY | O_NOFOLLOW let int_of_open_flag = function | O_RDONLY -> o_RDONLY | O_WRONLY -> o_WRONLY | O_RDWR -> o_RDWR | O_CREAT -> o_CREAT | O_EXCL -> o_EXCL | O_TRUNC -> o_TRUNC | O_DIRECTORY -> o_DIRECTORY | O_NOFOLLOW -> o_NOFOLLOW let int_of_open_flags = List.fold_left (fun acc x -> acc lor int_of_open_flag x) 0 let openfile mi path flags mode = let fd = C.openfile mi path (int_of_open_flags flags) mode in check ~path "open" fd; fd let close = check2 "close" C.close let fallocate mi fd ofs len = check "fallocate" @@ C.fallocate mi fd 0 ofs len let fsync mi fd ~dataonly = check "fsync" @@ C.fsync mi fd (if dataonly then 1 else 0) type statx = { stx_type : file_type; stx_size : int64; stx_mtime : int; stx_btime : int; } module Statx = struct let mode st = getf !@st stx_mode let size st = getf !@st stx_size let mtime st = getf (getf !@st stx_mtime) tv_sec let btime st = getf (getf !@st stx_btime) tv_sec let get_file_type mode = let open Unsigned.UInt16 in let t = logand mode s_IFMT in if t = s_IFREG then REG else if t = s_IFDIR then DIR else if t = s_IFLNK then LNK else if t = s_IFIFO then FIFO else if t = s_IFSOCK then SOCK else if t = s_IFCHR then CHR else if t = s_IFBLK then BLK else UNKNOWN let want = Unsigned.UInt.(statx_MODE |> logor statx_SIZE |> logor statx_MTIME |> logor statx_BTIME) let make st = { stx_type = get_file_type @@ mode st; stx_size = Unsigned.UInt64.to_int64 @@ size st; stx_mtime = PosixTypes.Time.to_int @@ mtime st; stx_btime = PosixTypes.Time.to_int @@ btime st; } end let statx mi path = let st = allocate_n struct_statx ~count:1 in check ~path "statx" @@ C.statx mi path st Statx.want Unsigned.UInt.zero; Statx.make st let fstatx mi fd = let st = allocate_n struct_statx ~count:1 in check "fstatx" @@ C.fstatx mi fd st Statx.want Unsigned.UInt.zero; Statx.make st let readdirplus mi dir = (* TODO allocate once per mount because result immediately copied *) let st = allocate_n struct_statx ~count:1 in let d = allocate_n struct_dirent ~count:1 in let r = C.readdirplus mi dir d st Statx.want Unsigned.UInt.zero null in check "readdirplus" r; if r = 0 then None else Some (Dirent.make d, Statx.make st)