aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Barksdale <amatus.amongus@gmail.com>2012-06-03 15:24:04 -0500
committerDavid Barksdale <amatus.amongus@gmail.com>2012-06-03 15:24:04 -0500
commitfd689b625890fd4a2660a6aafcfbf6e5d36dfd29 (patch)
treef7de11e6fee6f36742f495e29eeff5b317e42b4f /src
parentdde3e1addf7ce9773923bb9c9da372668f09baf7 (diff)
Made mkdir a backend op, fixed link count bugs in rmdir.
Diffstat (limited to 'src')
-rw-r--r--src/clojure/foofs/filesystem.clj13
-rw-r--r--src/clojure/foofs/filesystembackend.clj2
-rw-r--r--src/clojure/foofs/memorybackend.clj31
3 files changed, 33 insertions, 13 deletions
diff --git a/src/clojure/foofs/filesystem.clj b/src/clojure/foofs/filesystem.clj
index b11dbc4..a6579de 100644
--- a/src/clojure/foofs/filesystem.clj
+++ b/src/clojure/foofs/filesystem.clj
@@ -132,19 +132,12 @@
(continuation! inode)
(continuation! (fill-entry inode))))))
(mkdir [_ {:keys [nodeid arg]} continuation!]
- ;; TODO: this probably should be a backend op. the parent dir could go
- ;; away before we can ref it with the .. link.
- (.mknod
- backend nodeid (:filename arg)
- (bit-or stat-type-directory (:mode arg))
+ (.mkdir
+ backend nodeid (:filename arg) (:mode arg)
(fn [inode]
(if (integer? inode)
(continuation! inode)
- (let [child-nodeid (:nodeid inode)]
- ;; do we need to wait for these to finish?
- (.link backend child-nodeid "." child-nodeid skip)
- (.link backend child-nodeid ".." nodeid skip)
- (continuation! (fill-entry inode)))))))
+ (continuation! (fill-entry inode))))))
(unlink [_ {:keys [nodeid arg]} continuation!]
(.unlink backend nodeid arg continuation!))
(rmdir [_ {:keys [nodeid arg]} continuation!]
diff --git a/src/clojure/foofs/filesystembackend.clj b/src/clojure/foofs/filesystembackend.clj
index 4b64a8b..ae61625 100644
--- a/src/clojure/foofs/filesystembackend.clj
+++ b/src/clojure/foofs/filesystembackend.clj
@@ -33,6 +33,8 @@
"Writes a ByteBuffer to a file.")
(mknod [this nodeid filename mode continuation!]
"Create an inode and return it.")
+ (mkdir [this nodeid filename mode continuation!]
+ "Create a directory and return its inode.")
(link [this nodeid filename target-nodeid continuation!]
"Create a hardlink and return the target inode.")
(unlink [this nodeid filename continuation!]
diff --git a/src/clojure/foofs/memorybackend.clj b/src/clojure/foofs/memorybackend.clj
index 24e6f13..3cbaddd 100644
--- a/src/clojure/foofs/memorybackend.clj
+++ b/src/clojure/foofs/memorybackend.clj
@@ -126,6 +126,30 @@
(agent-do state-agent
(continuation! (assoc inode :nodeid child-nodeid)))
state)))))
+ (mkdir [_ nodeid filename mode continuation!]
+ (send
+ state-agent
+ (fn [state]
+ (if (contains? (get-in state [:lookup-table nodeid]) filename)
+ (do (continuation! errno-exist) state)
+ (let [child-nodeid (next-key (:inode-table state)
+ (:next-nodeid state)
+ Long/MIN_VALUE Long/MAX_VALUE)
+ inode (assoc empty-inode
+ :mode (bit-or stat-type-directory mode)
+ :nlink 2)
+ state (assoc-in state [:inode-table child-nodeid] inode)
+ state (assoc-in state [:lookup-table nodeid filename]
+ child-nodeid)
+ state (assoc-in state [:lookup-table child-nodeid]
+ {"." child-nodeid ".." nodeid})
+ nlink (get-in state [:inode-table nodeid :nlink])
+ state (assoc-in state [:inode-table nodeid :nlink]
+ (inc nlink))
+ state (assoc state :next-nodeid (inc child-nodeid))]
+ (agent-do state-agent
+ (continuation! (assoc inode :nodeid child-nodeid)))
+ state)))))
(link [_ nodeid filename target-nodeid continuation!]
(send
state-agent
@@ -205,9 +229,7 @@
(not (empty? (dissoc child-children "." "..")))
(do (continuation! errno-notempty) state)
true
- ;; TODO: 3 is wrong if . or .. don't exist
- ;; and we need to (dec (:nlink inode))
- (let [nlink (- (:nlink child-inode) 3)
+ (let [nlink (- (:nlink child-inode) 2)
lookup-table (assoc lookup-table nodeid
(dissoc children filename))
lookup-table (dissoc lookup-table child-nodeid)
@@ -216,6 +238,9 @@
(dissoc inode-table child-nodeid)
(assoc-in inode-table [child-nodeid :nlink]
nlink))
+ inode-table (assoc-in inode-table [nodeid :nlink]
+ (dec (get-in inode-table
+ [nodeid :nlink])))
state (assoc state :inode-table inode-table)]
(agent-do state-agent (continuation! 0))
state))))))