diff options
author | David Barksdale <amatus.amongus@gmail.com> | 2012-05-14 22:59:13 -0500 |
---|---|---|
committer | David Barksdale <amatus.amongus@gmail.com> | 2012-05-14 22:59:13 -0500 |
commit | 8e006c53f030ea6cc9f3ce767bf02aca1aee4253 (patch) | |
tree | 4fd3c2ae09e7c44a6a639eb238ee6fd9dd6ff711 /src | |
parent | 5d5ff70d4e52a84139771b2de5df9ffcf0a59a05 (diff) |
Implemented op-write.
Diffstat (limited to 'src')
-rw-r--r-- | src/clojure/foofs/filesystem.clj | 3 | ||||
-rw-r--r-- | src/clojure/foofs/filesystembackend.clj | 2 | ||||
-rw-r--r-- | src/clojure/foofs/fuse/bytebuffer.clj | 21 | ||||
-rw-r--r-- | src/clojure/foofs/fuse/filesystem.clj | 1 | ||||
-rw-r--r-- | src/clojure/foofs/fuse/protocol.clj | 24 | ||||
-rw-r--r-- | src/clojure/foofs/memorybackend.clj | 26 |
6 files changed, 73 insertions, 4 deletions
diff --git a/src/clojure/foofs/filesystem.clj b/src/clojure/foofs/filesystem.clj index 2258d85..63302bc 100644 --- a/src/clojure/foofs/filesystem.clj +++ b/src/clojure/foofs/filesystem.clj @@ -172,6 +172,9 @@ (if (nil? buffer) (continuation! errno-noent) (continuation! buffer)))))) + (writefile [this {:keys [nodeid arg]} continuation!] + (.writefile + backend nodeid (:offset arg) (:size arg) (:data arg) continuation!)) (statfs [this request continuation!] (continuation! {:blocks 0 diff --git a/src/clojure/foofs/filesystembackend.clj b/src/clojure/foofs/filesystembackend.clj index ef82955..cfaa1a2 100644 --- a/src/clojure/foofs/filesystembackend.clj +++ b/src/clojure/foofs/filesystembackend.clj @@ -29,6 +29,8 @@ "Return a lazy sequence of directory entries.") (readfile [this inode offset size continuation!] "Return a ByteBuffer or sequence of bytes.") + (writefile [this inode offset size data continuation!] + "Writes a ByteBuffer to a file.") (mknod [this inode filename mode continuation!] "Create an inode and return its attributes.") (link [this inode filename target-inode continuation!] diff --git a/src/clojure/foofs/fuse/bytebuffer.clj b/src/clojure/foofs/fuse/bytebuffer.clj index 1e3ecee..3428dc2 100644 --- a/src/clojure/foofs/fuse/bytebuffer.clj +++ b/src/clojure/foofs/fuse/bytebuffer.clj @@ -51,7 +51,22 @@ [(.and (biginteger 0xffffffffffffffff) (biginteger (.getLong buffer2))) buffer2]))) -(defn skip +(defn parse-bytes + [x] + (fn byte-parser + [buffer] + (when (<= x (.remaining buffer)) + (let [buffer-tail (.duplicate buffer) + buffer-head (.duplicate buffer) + order (.order buffer) + position (+ x (.position buffer))] + (.order buffer-tail order) + (.order buffer-head order) + (.position buffer-tail position) + (.limit buffer-head position) + [buffer-head buffer-tail])))) + +(defn skip-bytes [x] (fn parse-skip [buffer] @@ -60,10 +75,10 @@ [nil (.position buffer2 (+ x (.position buffer)))]))) (def skip-32 - (skip 4)) + (skip-bytes 4)) (def skip-64 - (skip 8)) + (skip-bytes 8)) (def parse-nothing (with-monad parser-m (m-result nil))) diff --git a/src/clojure/foofs/fuse/filesystem.clj b/src/clojure/foofs/fuse/filesystem.clj index b600c03..4430dce 100644 --- a/src/clojure/foofs/fuse/filesystem.clj +++ b/src/clojure/foofs/fuse/filesystem.clj @@ -28,6 +28,7 @@ (link [this request continuation!] "Create hardlink.") (open [this request continuation!] "Open file.") (readfile [this request continuation!] "Read file.") + (writefile [this request continuation!] "Write file.") (statfs [this request continuation!] "Get file system statistics.") (release [this request continuation!] "Release file.") (init [this request] "Initialize filesystem.") diff --git a/src/clojure/foofs/fuse/protocol.clj b/src/clojure/foofs/fuse/protocol.clj index e799d1e..3635252 100644 --- a/src/clojure/foofs/fuse/protocol.clj +++ b/src/clojure/foofs/fuse/protocol.clj @@ -208,6 +208,20 @@ :size size :read-flags read-flags})) +(def parse-write-in + (domonad + parser-m + [handle parse-opaque64 + offset parse-uint64 + size parse-uint32 + write-flags parse-opaque32 + data (parse-bytes size)] + {:handle handle + :offset offset + :size size + :write-flags write-flags + :data data})) + (def parse-release-in (domonad parser-m @@ -296,6 +310,13 @@ _ (pad 4)] nil)) +(defn write-write-out + [write-out] + (domonad + state-m + [_ (write-int32 (:size write-out))] + nil)) + (defn write-statfs-out [statfs-out] (domonad @@ -421,6 +442,9 @@ op-read {:arg-parser parse-read-in :processor! (partial process-generic! #(.readfile %1 %2 %3) write-bytes)} + op-write {:arg-parser parse-write-in + :processor! (partial process-generic! + #(.writefile %1 %2 %3) write-write-out)} op-statfs {:arg-parser parse-nothing :processor! (partial process-generic! #(.statfs %1 %2 %3) write-statfs-out)} diff --git a/src/clojure/foofs/memorybackend.clj b/src/clojure/foofs/memorybackend.clj index c922f43..d03c262 100644 --- a/src/clojure/foofs/memorybackend.clj +++ b/src/clojure/foofs/memorybackend.clj @@ -15,7 +15,7 @@ (ns foofs.memorybackend (:use [foofs.filesystembackend :only [FilesystemBackend]] - foofs.fuse.jna + [foofs.fuse bytebuffer jna] foofs.util)) (def new-attr @@ -95,6 +95,30 @@ (if (nil? file) (continuation! nil) (continuation! (take size (drop offset file)))))) + (writefile [this inode offset size data continuation!] + (send + state-agent + (fn [state] + (let [attr-table (:attr-table state) + file-table (:file-table state) + attr (get attr-table inode) + file (get file-table inode)] + (if (nil? attr) + (do (continuation! errno-noent) state) + (let [tail-offset (+ offset size) + tail-size (- (max tail-offset (:size attr)) tail-offset) + file-extended (concat file (repeat (byte 0))) + file-written (concat + (take offset file-extended) + (buffer-seq! data) + (take tail-size + (drop tail-offset file-extended))) + new-size (count file-written)] + (agent-do state-agent + (continuation! {:size (.limit data)})) + (assoc state + :attr-table (assoc-deep attr-table new-size inode :size) + :file-table (assoc file-table inode file-written)))))))) (mknod [this inode filename mode continuation!] (send state-agent |