diff options
author | David Barksdale <amatus.amongus@gmail.com> | 2012-06-03 15:24:04 -0500 |
---|---|---|
committer | David Barksdale <amatus.amongus@gmail.com> | 2012-06-03 15:24:04 -0500 |
commit | fd689b625890fd4a2660a6aafcfbf6e5d36dfd29 (patch) | |
tree | f7de11e6fee6f36742f495e29eeff5b317e42b4f /src | |
parent | dde3e1addf7ce9773923bb9c9da372668f09baf7 (diff) |
Made mkdir a backend op, fixed link count bugs in rmdir.
Diffstat (limited to 'src')
-rw-r--r-- | src/clojure/foofs/filesystem.clj | 13 | ||||
-rw-r--r-- | src/clojure/foofs/filesystembackend.clj | 2 | ||||
-rw-r--r-- | src/clojure/foofs/memorybackend.clj | 31 |
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)))))) |