aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Barksdale <amatus.amongus@gmail.com>2012-04-25 22:54:36 -0500
committerDavid Barksdale <amatus.amongus@gmail.com>2012-04-25 22:54:36 -0500
commit8676dfc01504a0ec27c52621ad0ebb6836a6702a (patch)
treebdfba61f530e5809f0eea184c4885aefcf2d4842 /src
parent0d1d674f600a52f1c926fde3fbd66537e8ccd90a (diff)
Implemented op-create.
Diffstat (limited to 'src')
-rw-r--r--src/clojure/foofs/filesystem.clj36
-rw-r--r--src/clojure/foofs/filesystembackend.clj2
-rw-r--r--src/clojure/foofs/fuse/filesystem.clj3
-rw-r--r--src/clojure/foofs/fuse/protocol.clj30
-rw-r--r--src/clojure/foofs/memorybackend.clj43
-rw-r--r--src/clojure/foofs/util.clj5
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)))))