aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Barksdale <amatus.amongus@gmail.com>2012-05-14 22:59:13 -0500
committerDavid Barksdale <amatus.amongus@gmail.com>2012-05-14 22:59:13 -0500
commit8e006c53f030ea6cc9f3ce767bf02aca1aee4253 (patch)
tree4fd3c2ae09e7c44a6a639eb238ee6fd9dd6ff711 /src
parent5d5ff70d4e52a84139771b2de5df9ffcf0a59a05 (diff)
Implemented op-write.
Diffstat (limited to 'src')
-rw-r--r--src/clojure/foofs/filesystem.clj3
-rw-r--r--src/clojure/foofs/filesystembackend.clj2
-rw-r--r--src/clojure/foofs/fuse/bytebuffer.clj21
-rw-r--r--src/clojure/foofs/fuse/filesystem.clj1
-rw-r--r--src/clojure/foofs/fuse/protocol.clj24
-rw-r--r--src/clojure/foofs/memorybackend.clj26
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