]> Zhao Yanbai Git Server - minix.git/commitdiff
libvtreefs: API changes/extensions, part 2 86/2886/2
authorDavid van Moolenbroek <david@minix3.org>
Sun, 9 Nov 2014 14:14:37 +0000 (14:14 +0000)
committerDavid van Moolenbroek <david@minix3.org>
Wed, 12 Nov 2014 12:13:43 +0000 (12:13 +0000)
- rename start_vtreefs to run_vtreefs, since the function returns upon
  termination these days;
- add get_inode_slots function to retrieve the number of indexed slots;
- add support for extra per-inode data for arbitrary storage.

Change-Id: If2d365d7b478a1cecc9e20fb2b3e70c1a1cf7243

minix/drivers/system/gpio/gpio.c
minix/fs/procfs/main.c
minix/include/minix/vtreefs.h
minix/lib/libvtreefs/Makefile
minix/lib/libvtreefs/extra.c [new file with mode: 0644]
minix/lib/libvtreefs/inode.c
minix/lib/libvtreefs/inode.h
minix/lib/libvtreefs/proto.h
minix/lib/libvtreefs/vtreefs.c
minix/servers/devman/main.c

index 9ddc19292eb1b642bc16355ed6a328c799c8c536..e6c2928fbfa49fa22dd9cbc391ad82c0798a1fa4 100644 (file)
@@ -283,8 +283,8 @@ main(int argc, char **argv)
        root_stat.size = 0;
        root_stat.dev = NO_DEV;
 
-       /* limit the number of indexed entries */
-       start_vtreefs(&hooks, 30, &root_stat, 0, DATA_SIZE);
+       /* run VTreeFS */
+       run_vtreefs(&hooks, 30, 0, &root_stat, 0, DATA_SIZE);
 
        return EXIT_SUCCESS;
 }
index 9e31fb5881036deb1c0889ecc094a451713479b4..3e416d494bf72126eed2c9d3e08b7ae6a5cf6fca 100644 (file)
@@ -87,8 +87,9 @@ int main(void)
        stat.size       = 0;
        stat.dev        = NO_DEV;
 
-       /* Start VTreeFS. */
-       start_vtreefs(&hooks, NR_INODES, &stat, NR_PROCS + NR_TASKS, BUF_SIZE);
+       /* Run VTreeFS. */
+       run_vtreefs(&hooks, NR_INODES, 0, &stat, NR_PROCS + NR_TASKS,
+           BUF_SIZE);
 
        return 0;
 }
index 91c340f849cbd75efed3a46367609f56f26804ca..00e6db0d3e5cabf39cf6be1b441ce11b92168d2d 100644 (file)
@@ -44,7 +44,7 @@ struct fs_hooks {
 
 extern struct inode *add_inode(struct inode *parent, const char *name,
        index_t index, const struct inode_stat *stat,
-       index_t nr_indexed_entries, cbdata_t cbdata);
+       index_t nr_indexed_slots, cbdata_t cbdata);
 extern void delete_inode(struct inode *inode);
 
 extern struct inode *get_inode_by_name(const struct inode *parent,
@@ -54,7 +54,9 @@ extern struct inode *get_inode_by_index(const struct inode *parent,
 
 extern const char *get_inode_name(const struct inode *inode);
 extern index_t get_inode_index(const struct inode *inode);
+extern index_t get_inode_slots(const struct inode *inode);
 extern cbdata_t get_inode_cbdata(const struct inode *inode);
+extern void *get_inode_extra(const struct inode *inode);
 
 extern struct inode *get_root_inode(void);
 extern struct inode *get_parent_inode(const struct inode *inode);
@@ -64,7 +66,8 @@ extern struct inode *get_next_inode(const struct inode *previous);
 extern void get_inode_stat(const struct inode *inode, struct inode_stat *stat);
 extern void set_inode_stat(struct inode *inode, struct inode_stat *stat);
 
-extern void start_vtreefs(struct fs_hooks *hooks, unsigned int nr_inodes,
-       struct inode_stat *stat, index_t nr_indexed_entries, size_t buf_size);
+extern void run_vtreefs(struct fs_hooks *hooks, unsigned int nr_inodes,
+       size_t inode_extra, struct inode_stat *stat, index_t nr_indexed_slots,
+       size_t buf_size);
 
 #endif /* _MINIX_VTREEFS_H */
index 181b053c0efef61331b4063e87327f0e97921b83..d533fdb5dc33b6d2b32b39dd905eb4146d6735a3 100644 (file)
@@ -7,6 +7,7 @@ CPPFLAGS+= -D_MINIX_SYSTEM
 LIB=   vtreefs
 
 SRCS=  \
+       extra.c \
        file.c \
        inode.c \
        link.c \
diff --git a/minix/lib/libvtreefs/extra.c b/minix/lib/libvtreefs/extra.c
new file mode 100644 (file)
index 0000000..f283bfd
--- /dev/null
@@ -0,0 +1,56 @@
+/* VTreeFS - extra.c - per-inode storage of arbitrary extra data */
+
+#include "inc.h"
+
+/*
+ * Right now, we maintain the extra data (if requested) as a separate buffer,
+ * so that we don't have to make the inode structure variable in size.  Later,
+ * if for example the maximum node name length becomes a runtime setting, we
+ * could reconsider this.
+ */
+static char *extra_ptr = NULL;
+static size_t extra_size = 0; /* per inode */
+
+/*
+ * Initialize memory to store extra data.
+ */
+int
+init_extra(unsigned int nr_inodes, size_t inode_extra)
+{
+
+       if (extra_size == 0)
+               return OK;
+
+       if ((extra_ptr = malloc(nr_inodes * inode_extra)) == NULL)
+               return ENOMEM;
+
+       extra_size = inode_extra;
+
+       return OK;
+}
+
+/*
+ * Initialize the extra data for the given inode to zero.
+ */
+void
+clear_inode_extra(struct inode * node)
+{
+
+       if (extra_size == 0)
+               return;
+
+       memset(&extra_ptr[node->i_num * extra_size], 0, extra_size);
+}
+
+/*
+ * Retrieve a pointer to the extra data for the given inode.
+ */
+void *
+get_inode_extra(const struct inode * node)
+{
+
+       if (extra_size == 0)
+               return NULL;
+
+       return (void *)&extra_ptr[node->i_num * extra_size];
+}
index 0363dc595704e07533e82f7b8fc7f10005633ef5..59328d9b913f755942235138ec95cc81be456982 100644 (file)
@@ -19,6 +19,7 @@ static LIST_HEAD(index_head, inode) *parent_index_head;
 #define CHECK_INODE(node)                                              \
        do {                                                            \
                assert(node >= &inode[0] && node < &inode[nr_inodes]);  \
+               assert((unsigned int)(node - &inode[0]) == node->i_num);\
                assert(node == &inode[0] || node->i_parent != NULL ||   \
                    (node->i_flags & I_DELETED));                       \
        } while (0);
@@ -68,7 +69,7 @@ init_inodes(unsigned int inodes, struct inode_stat * stat,
        /* Add free inodes to the unused/free list.  Skip the root inode. */
        for (i = 1; i < nr_inodes; i++) {
                node = &inode[i];
-
+               node->i_num = i;
                node->i_parent = NULL;
                node->i_count = 0;
                TAILQ_INIT(&node->i_children);
@@ -83,6 +84,7 @@ init_inodes(unsigned int inodes, struct inode_stat * stat,
 
        /* Initialize the root inode. */
        node = &inode[0];
+       node->i_num = 0;
        node->i_parent = NULL;
        node->i_count = 0;
        TAILQ_INIT(&node->i_children);
@@ -114,15 +116,13 @@ cleanup_inodes(void)
 static int
 parent_name_hash(const struct inode * parent, const char *name)
 {
-       unsigned int name_hash, parent_hash;
-
-       /* The parent hash is a simple array entry; find its index. */
-       parent_hash = (unsigned int)(parent - &inode[0]);
+       unsigned int name_hash;
 
        /* Use the sdbm algorithm to hash the name. */
        name_hash = sdbm_hash(name, strlen(name));
 
-       return (parent_hash ^ name_hash) % nr_inodes;
+       /* The parent hash is a simple array entry. */
+       return (parent->i_num ^ name_hash) % nr_inodes;
 }
 
 /*
@@ -132,7 +132,7 @@ static int
 parent_index_hash(const struct inode * parent, index_t index)
 {
 
-       return ((int)(parent - &inode[0]) ^ index) % nr_inodes;
+       return (parent->i_num ^ index) % nr_inodes;
 }
 
 /*
@@ -217,6 +217,9 @@ add_inode(struct inode * parent, const char * name, index_t index,
        newnode->i_cbdata = cbdata;
        strlcpy(newnode->i_name, name, sizeof(newnode->i_name));
 
+       /* Clear the extra data for this inode, if present. */
+       clear_inode_extra(newnode);
+
        /* Add the inode to the list of children inodes of the parent. */
        TAILQ_INSERT_HEAD(&parent->i_children, newnode, i_siblings);
 
@@ -268,6 +271,18 @@ get_inode_index(const struct inode * node)
        return node->i_index;
 }
 
+/*
+ * Return the number of indexed slots for the given (directory) inode.
+ */
+index_t
+get_inode_slots(const struct inode * node)
+{
+
+       CHECK_INODE(node);
+
+       return node->i_indexed;
+}
+
 /*
  * Return the callback data associated with the given inode.
  */
@@ -342,7 +357,7 @@ get_inode_number(const struct inode * node)
 
        CHECK_INODE(node);
 
-       return (int)(node - &inode[0]) + 1;
+       return node->i_num + 1;
 }
 
 /*
index a1788ecd71a23eef9d7bb265b824df00d26972d7..01716edd8d1713af8069f2c58d0c1ee8ca5823ac 100644 (file)
  * unused inodes.
  */
 struct inode {
+       /* Inode identity */
+       unsigned int i_num;             /* index number into the inode array */
+       /* Note that the actual inode number (of type ino_t) is (i_num + 1). */
+
        /* Inode metadata */
        struct inode_stat i_stat;       /* POSIX attributes */
        char i_name[PNAME_MAX + 1];     /* name of the inode in the parent */
index acead73cb3ef901860ec3fc4266c44dd8abec40b..c6d2d8881b228b7d492384aeac2020065f8e8904 100644 (file)
@@ -1,6 +1,10 @@
 #ifndef _VTREEFS_PROTO_H
 #define _VTREEFS_PROTO_H
 
+/* extra.c */
+int init_extra(unsigned int inodes, size_t inode_extra);
+void clear_inode_extra(struct inode *node);
+
 /* file.c */
 int init_buf(size_t size);
 void cleanup_buf(void);
index f63d1064a525ec70c8f02fd6ec932c764b9b8958..dc5fbe80a7310e22d317abdd6020ff2cf1ae3090 100644 (file)
@@ -6,6 +6,7 @@ static unsigned int inodes;
 static struct inode_stat *root_stat;
 static index_t root_entries;
 static size_t buf_size;
+static size_t extra_size;
 
 /*
  * Initialize internal state.  This is the only place where dynamic memory
@@ -20,6 +21,10 @@ init_server(int __unused type, sef_init_info_t * __unused info)
        if ((r = init_inodes(inodes, root_stat, root_entries)) != OK)
                panic("init_inodes failed: %d", r);
 
+       /* Initialize extra data. */
+       if ((r = init_extra(inodes, extra_size)) != OK)
+               panic("init_extra failed: %d", r);
+
        /* Initialize the I/O buffer. */
        if ((r = init_buf(buf_size)) != OK)
                panic("init_buf failed: %d", r);
@@ -83,8 +88,9 @@ fs_other(const message * m_ptr, int ipc_status)
  * unmounted and the process is signaled to exit.
  */
 void
-start_vtreefs(struct fs_hooks * hooks, unsigned int nr_inodes,
-       struct inode_stat * stat, index_t nr_indexed_entries, size_t bufsize)
+run_vtreefs(struct fs_hooks * hooks, unsigned int nr_inodes,
+       size_t inode_extra, struct inode_stat * stat,
+       index_t nr_indexed_entries, size_t bufsize)
 {
 
        /*
@@ -93,6 +99,7 @@ start_vtreefs(struct fs_hooks * hooks, unsigned int nr_inodes,
         */
        vtreefs_hooks = hooks;
        inodes = nr_inodes;
+       extra_size = inode_extra;
        root_stat = stat;
        root_entries = nr_indexed_entries;
        buf_size = bufsize;
index 924d6fb706d6247141a7d2b0e9e7563a1ce1e301..09e683adcb8b8dd4f31203493730fa7f2f825361 100644 (file)
@@ -85,8 +85,9 @@ int main (int argc, char* argv[])
        root_stat.size  = 0;
        root_stat.dev   = NO_DEV;
 
-       /* limit the number of indexed entries */
-       start_vtreefs(&hooks, 1024, &root_stat, 0, BUF_SIZE);
+       /* run VTreeFS */
+       run_vtreefs(&hooks, 1024, 0, &root_stat, 0, BUF_SIZE);
+
        return 0;
 }