summaryrefslogtreecommitdiff
path: root/libdiskfs/diskfs.h
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2015-04-15 13:17:06 +0200
committerJustus Winter <4winter@informatik.uni-hamburg.de>2015-04-17 22:01:39 +0200
commitc234e34ad80801acd902c6d4892a7722fd084a87 (patch)
tree6fa1b1efbe734e1fbd8dd11625608e010c78db5c /libdiskfs/diskfs.h
parentbf06e6535f7e00a3711978fa7835a3394b82b547 (diff)
libdiskfs: implement a node cache
Previously, all users of libdiskfs implemented a node cache on their own. Move the node cache from ext2fs into libdiskfs. We preserve the previous API by marking all functions that we pull from ext2fs as weak, so that users like tmpfs can still implement their own node cache. * ext2fs/dir.c (diskfs_lookup_hard): Adjust accordingly. * ext2fs/ext2fs.c (main): Don't call `inode_init'. * ext2fs/ext2fs.h (struct disknode): Drop `hnext', `hprevp'. * ext2fs/inode.c: Move the node cache into diskfs. (diskfs_user_make_node): New function. (diskfs_try_dropping_softrefs): Rename to `diskfs_user_try_dropping_softrefs'. (read_node): Rename to `diskfs_user_read_node'. Also move a chunk of code dealing with generations from `diskfs_cached_lookup' here. * libdiskfs/Makefile (OTHERSRCS): Add `node-cache.c'. * libdiskfs/diskfs.h (struct node): Add `hnext', `hprevp'. Amend existing comments, add forward declarations. * libdiskfs/node-cache.c: New file.
Diffstat (limited to 'libdiskfs/diskfs.h')
-rw-r--r--libdiskfs/diskfs.h50
1 files changed, 47 insertions, 3 deletions
diff --git a/libdiskfs/diskfs.h b/libdiskfs/diskfs.h
index 8ab61420..82a16b4f 100644
--- a/libdiskfs/diskfs.h
+++ b/libdiskfs/diskfs.h
@@ -80,6 +80,9 @@ struct peropen
filesystem. */
struct node
{
+ /* Links on hash list. */
+ struct node *hnext, **hprevp;
+
struct disknode *dn;
io_statbuf_t dn_stat;
@@ -451,7 +454,8 @@ void diskfs_free_node (struct node *np, mode_t mode);
if it isn't to be retained. */
void diskfs_node_norefs (struct node *np);
-/* The user must define this function. Node NP has some light
+/* The user must define this function unless she wants to use the node
+ cache. See the section `Node cache' below. Node NP has some light
references, but has just lost its last hard references. Take steps
so that if any light references can be freed, they are. NP is locked
as is the pager refcount lock. This function will be called after
@@ -515,7 +519,8 @@ void diskfs_write_disknode (struct node *np, int wait);
then return only after the physical media has been completely updated. */
void diskfs_file_update (struct node *np, int wait);
-/* The user must define this function. For each active node, call
+/* The user must define this function unless she wants to use the node
+ cache. See the section `Node cache' below. For each active node, call
FUN. The node is to be locked around the call to FUN. If FUN
returns non-zero for any node, then immediately stop, and return
that value. */
@@ -587,6 +592,36 @@ error_t (*diskfs_read_symlink_hook)(struct node *np, char *target);
error_t diskfs_get_source (struct protid *cred,
char *source, size_t source_len);
+/* Libdiskfs contains a node cache.
+
+ Using it relieves the user of implementing diskfs_cached_lookup,
+ diskfs_node_iterate, and diskfs_try_dropping_softrefs.
+
+ In order to use it, she must implement the following functions with
+ the prefix `diskfs_user_'. */
+
+/* This can be used to provide additional context to
+ diskfs_user_make_node and diskfs_user_read_node in case of cache
+ misses. */
+struct lookup_context;
+
+/* The user must define this function if she wants to use the node
+ cache. Create and initialize a node. */
+error_t diskfs_user_make_node (struct node **npp, struct lookup_context *ctx);
+
+/* The user must define this function if she wants to use the node
+ cache. Read stat information out of the on-disk node. */
+error_t diskfs_user_read_node (struct node *np, struct lookup_context *ctx);
+
+/* The user must define this function if she wants to use the node
+ cache. The last hard reference to a node has gone away; arrange to
+ have all the weak references dropped that can be. */
+void diskfs_user_try_dropping_softrefs (struct node *np);
+
+/* Lookup node INUM (which must have a reference already) and return it
+ without allocating any new references. */
+struct node *diskfs_cached_ifind (ino_t inum);
+
/* The library exports the following functions for general use */
/* Call this after arguments have been parsed to initialize the library.
@@ -808,9 +843,18 @@ error_t diskfs_dirrewrite (struct node *dp, struct node *oldnp,
error_t diskfs_dirremove (struct node *dp, struct node *np,
const char *name, struct dirstat *ds);
-/* Return the node corresponding to CACHE_ID in *NPP. */
+/* The user must define this function unless she wants to use the node
+ cache. See the section `Node cache' above. Return the node
+ corresponding to CACHE_ID in *NPP. */
error_t diskfs_cached_lookup (ino64_t cache_id, struct node **npp);
+/* Return the node corresponding to CACHE_ID in *NPP. In case of a
+ cache miss, use CTX to create it and load it from the disk. See
+ the section `Node cache' above. */
+error_t diskfs_cached_lookup_context (ino_t inum, struct node **npp,
+ struct lookup_context *ctx);
+
+
/* Create a new node. Give it MODE; if that includes IFDIR, also
initialize `.' and `..' in the new directory. Return the node in NPP.
CRED identifies the user responsible for the call. If NAME is nonzero,