diff options
author | David Barksdale <amatus.amongus@gmail.com> | 2012-04-25 22:54:36 -0500 |
---|---|---|
committer | David Barksdale <amatus.amongus@gmail.com> | 2012-04-25 22:54:36 -0500 |
commit | 8676dfc01504a0ec27c52621ad0ebb6836a6702a (patch) | |
tree | bdfba61f530e5809f0eea184c4885aefcf2d4842 /src | |
parent | 0d1d674f600a52f1c926fde3fbd66537e8ccd90a (diff) |
Implemented op-create.
Diffstat (limited to 'src')
-rw-r--r-- | src/clojure/foofs/filesystem.clj | 36 | ||||
-rw-r--r-- | src/clojure/foofs/filesystembackend.clj | 2 | ||||
-rw-r--r-- | src/clojure/foofs/fuse/filesystem.clj | 3 | ||||
-rw-r--r-- | src/clojure/foofs/fuse/protocol.clj | 30 | ||||
-rw-r--r-- | src/clojure/foofs/memorybackend.clj | 43 | ||||
-rw-r--r-- | src/clojure/foofs/util.clj | 5 |
6 files changed, 110 insertions, 9 deletions
diff --git a/src/clojure/foofs/filesystem.clj b/src/clojure/foofs/filesystem.clj index e5fc7f7..ac1c20b 100644 --- a/src/clojure/foofs/filesystem.clj +++ b/src/clojure/foofs/filesystem.clj @@ -16,6 +16,7 @@ (ns foofs.filesystem (:use [foofs.filesystembackend :only [FilesystemBackend]] [foofs.fuse.filesystem :only [Filesystem]] + foofs.util (foofs.fuse jna protocol))) (defrecord FooFilesystem @@ -106,13 +107,8 @@ (fn [state] (let [opendirs (:opendirs state) next-handle (:next-handle state) - handle (first - (remove - (partial contains? opendirs) - (concat - (range next-handle Long/MAX_VALUE) - (range Long/MIN_VALUE next-handle))))] - (.println *err* (str "got handle " handle)) + handle (next-key opendirs next-handle Long/MIN_VALUE + Long/MAX_VALUE)] (if (nil? handle) (do (continuation! errno-nomem) @@ -162,5 +158,31 @@ (fn [state] {:opendirs (dissoc (:opendirs state) (:handle (:arg request))) :next-handle (:next-handle state)}))))) + (create [this request continuation!] + ;; is create supposed to be atomic? + (let [arg (:arg request) + flags (:flags arg) + mode (:mode arg) + filename (:filename arg)] + (.mknod + backend (:nodeid request) filename mode flags + (fn [attr] + (if (nil? attr) + (continuation! errno-noent) ;; other errors? + (.reference + backend (:inode attr) + (fn [result] + (if (nil? result) + (continuation! errno-noent) + (continuation! + {:nodeid (:inode attr) + :generation 0 + :entry-valid 0 + :attr-valid 0 + :entry-valid-nsec 0 + :attr-valid-nsec 0 + :attr attr + :handle 0 + :flags 0}))))))))) (destroy [this request] nil)) diff --git a/src/clojure/foofs/filesystembackend.clj b/src/clojure/foofs/filesystembackend.clj index f7a9814..0202527 100644 --- a/src/clojure/foofs/filesystembackend.clj +++ b/src/clojure/foofs/filesystembackend.clj @@ -29,5 +29,7 @@ "Return a lazy sequence of directory entries.") (readfile [this inode offset size continuation!] "Return a ByteBuffer or sequence of bytes.") + (mknod [this inode filename mode flags continuation!] + "Create an inode and return its attributes.") ;; and so on ) diff --git a/src/clojure/foofs/fuse/filesystem.clj b/src/clojure/foofs/fuse/filesystem.clj index 42431ce..0684004 100644 --- a/src/clojure/foofs/fuse/filesystem.clj +++ b/src/clojure/foofs/fuse/filesystem.clj @@ -27,7 +27,8 @@ (init [this request] "Initialize filesystem.") (opendir [this request continuation!] "Open directory.") (readdir [this request continuation!] "Read directory.") - (releasedir [this request continuation!] "Release Directory.") + (releasedir [this request continuation!] "Release directory.") + (create [this request continuation!] "Create file.") (destroy [this request] "Clean up filesystem.") ;; and so on ) diff --git a/src/clojure/foofs/fuse/protocol.clj b/src/clojure/foofs/fuse/protocol.clj index 3fb4ad8..c19cece 100644 --- a/src/clojure/foofs/fuse/protocol.clj +++ b/src/clojure/foofs/fuse/protocol.clj @@ -424,6 +424,34 @@ (reply-error! fuse request result) (reply-error! fuse request 0))))) +(def parse-create-in + (domonad + parser-m + [flags parse-opaque32 + mode parse-opaque32 + filename parse-utf8] + {:flags flags + :mode mode + :filename filename})) + +(defn write-create-out + [create-out] + (domonad state-m + [_ (write-entry-out create-out) + _ (write-open-out create-out)] + nil)) + +(defn process-create! + [fuse request] + (.create + (:filesystem fuse) + request + (fn [result] + (cond + (map? result) (reply-ok! fuse request (write-create-out result)) + (integer? result) (reply-error! fuse request result) + true (reply-error! fuse request errno-nosys))))) + (defn process-destroy! [fuse request] (.destroy (:filesystem fuse) request) @@ -452,6 +480,8 @@ :processor! process-readdir!} op-releasedir {:arg-parser parse-release-in :processor! process-releasedir!} + op-create {:arg-parser parse-create-in + :processor! process-create!} op-destroy {:arg-parser parse-nothing :processor! process-destroy!}}) diff --git a/src/clojure/foofs/memorybackend.clj b/src/clojure/foofs/memorybackend.clj index b71c223..fe56eec 100644 --- a/src/clojure/foofs/memorybackend.clj +++ b/src/clojure/foofs/memorybackend.clj @@ -17,6 +17,21 @@ (:use [foofs.filesystembackend :only [FilesystemBackend]] foofs.util)) +(def new-attr + {:size 0 + :blocks 0 + :atime 0 + :mtime 0 + :ctime 0 + :atimensec 0 + :mtimensec 0 + :ctimensec 0 + :mode 0 + :nlink 0 + :uid 0 + :gid 0 + :rdev 0}) + (defn link-modifier! [state-agent f inode continuation! state] (let [attr-table (:attr-table state) @@ -81,4 +96,30 @@ file (get (:file-table state) inode)] (if (nil? file) (continuation! nil) - (continuation! (take size (drop offset file))))))) + (continuation! (take size (drop offset file)))))) + (mknod [this inode filename mode flags continuation!] + (send + state-agent + (fn [state] + (let [lookup-table (:lookup-table state) + children (get lookup-table inode) + attr-table (:attr-table state)] + (if (contains? children filename) + (do + (continuation! nil) ;; EEXIST? + state) + (let [child-inode (next-key attr-table (:next-inode state) + Long/MIN_VALUE Long/MAX_VALUE) + attr (conj new-attr + {:mode mode + :nlink 1})] + (send + state-agent + (fn [state] + (continuation! (assoc attr :inode child-inode)) + state)) + (assoc state + :attr-table (assoc attr-table child-inode attr) + :lookup-table (assoc lookup-table inode + (assoc children filename child-inode)) + :next-inode (inc child-inode))))))))) diff --git a/src/clojure/foofs/util.clj b/src/clojure/foofs/util.clj index 1cf70b2..d0c8743 100644 --- a/src/clojure/foofs/util.clj +++ b/src/clojure/foofs/util.clj @@ -21,3 +21,8 @@ (if (nil? _keys) (assoc _map _key _val) (assoc _map _key (apply assoc-deep (get _map _key) _val _keys)))) + +(defn next-key + [_map _key _min _max] + (first (remove (partial contains? _map) (concat (range _key _max) + (range _min _key))))) |