Thread: [Libsysio-commit] HEAD: libsysio/src inode.c
Brought to you by:
lward
From: Ruth K. <rk...@us...> - 2003-07-26 05:21:22
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs1:/tmp/cvs-serv25000/src Modified Files: inode.c Log Message: Add capability of checking inode generation numbers, if a field for it exists in the stat struct. Bug fix for unlink/creat failure: Changes allow re-use of an inode which is no longer in use, but still exists in the inode cache. If the stat info for the new use matches cached info, the inode is re-used. If not, the old inode is marked 'zombie' and removed from the inode cache to make way for the new inode. Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -w -b -B -p -r1.7 -r1.8 --- inode.c 23 Apr 2003 19:45:52 -0000 1.7 +++ inode.c 25 Jul 2003 14:45:34 -0000 1.8 @@ -265,6 +265,7 @@ _sysio_i_gone(struct inode *ino) if (ino->i_ref) abort(); + if (!ino->i_zombie) LIST_REMOVE(ino, i_link); TAILQ_REMOVE(&_sysio_inodes, ino, i_nodes); (*ino->i_ops.inop_gone)(ino); @@ -272,6 +273,17 @@ _sysio_i_gone(struct inode *ino) assert(n_inodes); n_inodes--; +} + +/* + * Stale inode, zombie it and move it out of the way + */ +void +_sysio_i_undead(struct inode *ino) +{ + + LIST_REMOVE(ino, i_link); + ino->i_zombie = 1; } /* |
From: Lee W. <lw...@us...> - 2003-09-09 04:23:31
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs1:/tmp/cvs-serv19786/src Modified Files: inode.c Log Message: Jim Schutt found a bug where orphaned path base nodes were not being reclaimed. This would manifest itself with an abort on a busy inode during FS unmount. He presented it this way... ./test_copy -r /tmp/jaschut tst.dat tst2.dat I altered _sysio_p_prune to check for path base nodes that have no aliases. If found, a new routine called _sysio_prune is called. This just descends the given sub-tree releasing orphaned path-base nodes. Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -w -b -B -p -r1.9 -r1.10 --- inode.c 26 Aug 2003 15:53:59 -0000 1.9 +++ inode.c 8 Sep 2003 15:43:21 -0000 1.10 @@ -606,6 +606,30 @@ _sysio_p_find_alias(struct pnode *parent } /* + * Prune idle path base nodes freom the passed sub-tree, including the root. + */ +static void +_sysio_prune(struct pnode_base *rpb) +{ + struct pnode_base *nxtpb, *pb; + + nxtpb = rpb->pb_children.lh_first; + while ((pb = nxtpb)) { + nxtpb = pb->pb_sibs.le_next; + if (pb->pb_aliases.lh_first) + continue; + if (pb->pb_children.lh_first) { + _sysio_prune(pb); + continue; + } + _sysio_pb_gone(pb); + } + if (rpb->pb_children.lh_first) + return; + _sysio_pb_gone(rpb); +} + +/* * Prune idle nodes from the passed sub-tree, including the root. * * Returns the number of aliases on the same mount that could not be pruned. @@ -623,6 +647,10 @@ _sysio_p_prune(struct pnode *root) while ((pb = nxtpb)) { nxtpb = pb->pb_sibs.le_next; nxtpno = pb->pb_aliases.lh_first; + if (!nxtpno) { + _sysio_prune(pb); + continue; + } while ((pno = nxtpno)) { nxtpno = pno->p_links.le_next; if (pno->p_mount != root->p_mount) { @@ -664,10 +692,10 @@ _sysio_p_prune(struct pnode *root) if (_sysio_do_unmount(pno->p_mount) != 0) { P_RELE(pno); count++; - continue; } + continue; #endif - } else + } _sysio_p_gone(pno); } } @@ -682,9 +710,9 @@ _sysio_p_prune(struct pnode *root) /* * All that is left is the root. Try for it too. */ - if (root->p_ref) + if (root->p_ref) { count++; - else if (root->p_mount->mnt_root == root) { + } else if (root->p_mount->mnt_root == root) { #ifndef AUTOMOUNT_FILE_NAME count++; #else |
From: Lee W. <lw...@us...> - 2003-10-15 18:01:02
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs1:/tmp/cvs-serv9577/src Modified Files: inode.c Log Message: Eliminated the i-node number field from the inode structure. We already carry the file identifier so it was redundant. Problematic too, in that it can be 32 or 64 bits in size. This forced _sysio_i_new() and _sysio_i_find() to change -- They no longer take the i-node number as an argument. Updated the driver calls to reflect the new usage. The i-node cache is now indexed by hashing the file identifier as opposed to just using the, no longer maintained, i-node number. This caused _sysio_i_find to become 2+ percent more expensive to use. Acceptable for me. Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -w -b -B -p -r1.10 -r1.11 --- inode.c 8 Sep 2003 15:43:21 -0000 1.10 +++ inode.c 15 Oct 2003 18:00:57 -0000 1.11 @@ -171,6 +171,23 @@ i_reclaim() max_inodes += t; } +static unsigned +hash(struct file_identifier *fid) +{ + size_t n; + void *p; + unsigned hkey; + + n = fid->fid_len; + p = fid->fid_data; + hkey = 0; + do { + hkey <<= 1; + hkey += *(unsigned char *)p++; + } while (--n); + return hkey; +} + /* * Allocate and initialize a new i-node. Returned i-node is referenced. * @@ -179,7 +196,6 @@ i_reclaim() */ struct inode * _sysio_i_new(struct filesys *fs, - ino_t inum, struct file_identifier *fid, mode_t type, dev_t rdev, @@ -217,10 +233,10 @@ _sysio_i_new(struct filesys *fs, ino->i_ops.inop_datasync = o->inop_datasync; ino->i_ops.inop_ioctl = o->inop_ioctl; } - I_INIT(ino, fs, inum, type, rdev, &ino->i_ops, fid, immunity, private); + I_INIT(ino, fs, type, rdev, &ino->i_ops, fid, immunity, private); ino->i_ref = 1; TAILQ_INSERT_TAIL(&_sysio_inodes, ino, i_nodes); - head = &fs->fs_itbl[inum % FS_ITBLSIZ]; + head = &fs->fs_itbl[hash(fid) % FS_ITBLSIZ]; LIST_INSERT_HEAD(head, ino, i_link); n_inodes++; @@ -234,18 +250,17 @@ _sysio_i_new(struct filesys *fs, * and identifier. */ struct inode * -_sysio_i_find(struct filesys *fs, ino_t inum, struct file_identifier *fid) +_sysio_i_find(struct filesys *fs, struct file_identifier *fid) { struct inode *ino; struct itable_entry *head; - head = &fs->fs_itbl[inum % FS_ITBLSIZ]; + head = &fs->fs_itbl[hash(fid) % FS_ITBLSIZ]; /* * Look for existing. */ for (ino = head->lh_first; ino; ino = ino->i_link.le_next) - if (ino->i_num == inum && - ino->i_fid->fid_len == fid->fid_len && + if (ino->i_fid->fid_len == fid->fid_len && memcmp(ino->i_fid->fid_data, fid->fid_data, fid->fid_len) == 0) { |
From: Lee W. <lw...@us...> - 2004-04-20 07:20:30
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25512 Modified Files: inode.c Log Message: Copy the operation for inop_pos too. Forgot to make this change in the original pass. Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.15 retrieving revision 1.16 diff -u -w -b -B -p -r1.15 -r1.16 --- inode.c 16 Apr 2004 20:38:34 -0000 1.15 +++ inode.c 20 Apr 2004 07:20:19 -0000 1.16 @@ -252,6 +252,7 @@ _sysio_i_new(struct filesys *fs, operations.inop_close = o->inop_close; operations.inop_read = o->inop_read; operations.inop_write = o->inop_write; + operations.inop_pos = o->inop_pos; operations.inop_iodone = o->inop_iodone; operations.inop_datasync = o->inop_datasync; operations.inop_ioctl = o->inop_ioctl; |
From: Sonja T. <so...@us...> - 2004-07-21 21:22:33
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv514/src Modified Files: inode.c Log Message: Fixing bugs to do with device files. Now, you cant open devices that do not have an associated driver. Also, you can now do an fstat() on a device Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.17 retrieving revision 1.18 diff -u -w -b -B -p -r1.17 -r1.18 --- inode.c 3 Jul 2004 05:47:13 -0000 1.17 +++ inode.c 21 Jul 2004 21:22:24 -0000 1.18 @@ -957,3 +957,14 @@ _sysio_do_enosys() return -ENOSYS; } + + +/* + * Return -ENODEV + */ +int +_sysio_do_enodev() +{ + + return -ENODEV; +} |
From: Lee W. <lw...@us...> - 2004-08-27 18:10:15
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31039/src Modified Files: inode.c Log Message: Added fcntl call. It was, inappropriately, going to the supporting file system driver. Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.19 retrieving revision 1.20 diff -u -w -b -B -p -r1.19 -r1.20 --- inode.c 27 Jul 2004 15:00:43 -0000 1.19 +++ inode.c 27 Aug 2004 18:10:05 -0000 1.20 @@ -254,6 +254,7 @@ _sysio_i_new(struct filesys *fs, operations.inop_write = o->inop_write; operations.inop_pos = o->inop_pos; operations.inop_iodone = o->inop_iodone; + operations.inop_fcntl = o->inop_fcntl; operations.inop_datasync = o->inop_datasync; operations.inop_ioctl = o->inop_ioctl; } |
From: Lee W. <lw...@us...> - 2007-08-28 17:42:00
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv25553/src Modified Files: inode.c Log Message: Removed the free inodes and pnodes cache and allocators. Replaced with simple malloc/free. Performance tests showed that malloc/free was very nearly as fast; Less than 1% slower. Might as well keep it simple, then. Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.27 retrieving revision 1.28 diff -u -w -b -B -p -r1.27 -r1.28 --- inode.c 1 May 2007 16:33:53 -0000 1.27 +++ inode.c 28 Aug 2007 17:41:56 -0000 1.28 @@ -96,34 +96,11 @@ static size_t n_names = 0; static size_t max_names = (2 * NAMES_TABLE_LEN); /* - * Number of pnodes to grab per memory allocation when filling the - * free list. - */ -#define PNODES_PER_CHUNK ((8 * 1024) / sizeof(struct pnode) - 2) - -#ifdef ZERO_SUM_MEMORY -/* - * Allocation information for pnodes bulk allocation. - */ -struct pnodes_block { - LIST_ENTRY(pnodes_block) pnblk_links; - struct pnode pnblk_nodes[PNODES_PER_CHUNK]; -}; - -static LIST_HEAD( ,pnodes_block) pnblocks; -#endif - -/* * List of all path-nodes (aliases) referenced by any tree. */ struct pnodes_head _sysio_pnodes; /* - * Free path-nodes -- Not referenced by any tree for fas reuse. - */ -static LIST_HEAD( ,pnode) free_pnodes; - -/* * The system root -- Aka `/'. */ struct pnode *_sysio_root = NULL; @@ -142,11 +119,7 @@ _sysio_i_init() for (i = 0; i < NAMES_TABLE_LEN; i++) LIST_INIT(&names[i]); -#ifdef ZERO_SUM_MEMORY - LIST_INIT(&pnblocks); -#endif TAILQ_INIT(&_sysio_pnodes); - LIST_INIT(&free_pnodes); return 0; } @@ -470,37 +443,6 @@ _sysio_pb_disconnect(struct pnode_base * pb->pb_name.len = 0; } -/* - * Generate more path (alias) nodes for the fast allocator. - */ -static void -more_pnodes() -{ - size_t n; -#ifdef ZERO_SUM_MEMORY - struct pnodes_block *pnblk; -#endif - struct pnode *pno; - -#ifdef ZERO_SUM_MEMORY - pnblk = malloc(sizeof(struct pnodes_block)); - pno = NULL; - if (pnblk) { - LIST_INSERT_HEAD(&pnblocks, pnblk, pnblk_links); - pno = pnblk->pnblk_nodes; - } -#else - pno = malloc(PNODES_PER_CHUNK * sizeof(struct pnode)); -#endif - if (!pno) - return; - n = PNODES_PER_CHUNK; - do { - LIST_INSERT_HEAD(&free_pnodes, pno, p_links); - pno++; - } while (--n); -} - #ifdef ZERO_SUM_MEMORY /* * Shutdown @@ -508,12 +450,8 @@ more_pnodes() void _sysio_i_shutdown() { - struct pnodes_block *pnblk; - while ((pnblk = pnblocks.lh_first)) { - LIST_REMOVE(pnblk, pnblk_links); - free(pnblk); - } + return; } #endif @@ -528,14 +466,9 @@ _sysio_p_new_alias(struct pnode *parent, { struct pnode *pno; - pno = free_pnodes.lh_first; - if (!pno) { - more_pnodes(); - pno = free_pnodes.lh_first; - } + pno = malloc(sizeof(struct pnode)); if (!pno) return NULL; - LIST_REMOVE(pno, p_links); pno->p_ref = 1; pno->p_parent = parent; @@ -562,7 +495,7 @@ _sysio_p_gone(struct pnode *pno) TAILQ_REMOVE(&_sysio_pnodes, pno, p_nodes); LIST_REMOVE(pno, p_links); - LIST_INSERT_HEAD(&free_pnodes, pno, p_links); + free(pno); } /* |
From: Lee W. <lw...@us...> - 2007-09-21 20:12:58
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv14759/src Modified Files: inode.c Log Message: - No longer maintain a list of all pnodes in the system. + Introduce a list of idle pnodes for use by the garbage collector. Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.29 retrieving revision 1.30 diff -u -w -b -B -p -r1.29 -r1.30 --- inode.c 21 Sep 2007 19:41:37 -0000 1.29 +++ inode.c 21 Sep 2007 20:12:55 -0000 1.30 @@ -93,9 +93,9 @@ static size_t desired_names = (3 * NAMES static size_t max_names; /* - * List of all path-nodes (aliases) referenced by any tree. + * List of all path-nodes (aliases) that are not currently referenced. */ -struct pnodes_head _sysio_pnodes; +struct pnodes_head _sysio_idle_pnodes; /* * The system root -- Aka `/'. @@ -122,7 +122,7 @@ _sysio_i_init() for (i = 0; i < NAMES_TABLE_LEN; i++) names[i] = NULL; - TAILQ_INIT(&_sysio_pnodes); + TAILQ_INIT(&_sysio_idle_pnodes); max_names = desired_names; @@ -335,7 +335,7 @@ p_reclaim(unsigned count) #ifdef I_STATS p_reclaims++; #endif - next = _sysio_pnodes.tqh_first; + next = _sysio_idle_pnodes.tqh_first; if (!next) return; t = n_names / 2; @@ -344,9 +344,9 @@ p_reclaim(unsigned count) p_examined++; #endif pno = next; - next = pno->p_nodes.tqe_next; + next = pno->p_idle.tqe_next; if (pno->p_ref) - continue; + abort(); if (pno->p_mount->mnt_root == pno) { /* * We never reclaim mount points, here. @@ -586,7 +586,6 @@ _sysio_p_new_alias(struct pnode *parent, pno->p_mount = mnt; pno->p_cover = NULL; LIST_INSERT_HEAD(&pb->pb_aliases, pno, p_links); - TAILQ_INSERT_TAIL(&_sysio_pnodes, pno, p_nodes); return pno; } @@ -600,7 +599,7 @@ _sysio_p_gone(struct pnode *pno) assert(!pno->p_ref); assert(!pno->p_cover); - TAILQ_REMOVE(&_sysio_pnodes, pno, p_nodes); + TAILQ_REMOVE(&_sysio_idle_pnodes, pno, p_idle); LIST_REMOVE(pno, p_links); free(pno); |
From: Lee W. <lw...@us...> - 2007-09-24 18:00:43
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv19475 Modified Files: inode.c Log Message: Oops. Don't want I_STATS defined in the tree. That should only be enabled per site. Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.31 retrieving revision 1.32 diff -u -w -b -B -p -r1.31 -r1.32 --- inode.c 24 Sep 2007 17:33:00 -0000 1.31 +++ inode.c 24 Sep 2007 18:00:39 -0000 1.32 @@ -58,7 +58,7 @@ #include "inode.h" #include "dev.h" -#define I_STATS +/* #define I_STATS */ /* * Support for path and index nodes. |
From: Lee W. <lw...@us...> - 2007-09-24 18:04:06
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv8912 Modified Files: inode.c Log Message: The path base node disconnect routine was passing the wrong pointer to the tree deletion routine. Fixed this by abstracting the name cache manipulation everywhere and crafting the necessary routines. Added ncache_insert, ncache_delete, and ncache_lookup. Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.30 retrieving revision 1.31 diff -u -w -b -B -p -r1.30 -r1.31 --- inode.c 21 Sep 2007 20:12:55 -0000 1.30 +++ inode.c 24 Sep 2007 17:33:00 -0000 1.31 @@ -58,7 +58,7 @@ #include "inode.h" #include "dev.h" -/* #define I_STATS */ +#define I_STATS /* * Support for path and index nodes. @@ -83,6 +83,18 @@ static size_t n_inodes = 0; static struct tree_node *names[NAMES_TABLE_LEN]; /* + * Return slot index in names table given pointer to path base key. + */ +#define ncache_key_index(pbk) \ + ((pbk)->pbk_name.hashval % NAMES_TABLE_LEN) + +/* + * Return ptr to slot in names table given hash value. + */ +#define ncache_slot(h) \ + (names[(h)] % NAMES_TABLE_LEN) + +/* * Number of names tracked by the system. */ static size_t n_names = 0; @@ -411,6 +423,52 @@ compar_pb_key(const struct pnode_base_ke } /* + * Insert a path base node into the system name cache. + */ +static void +ncache_insert(struct pnode_base *pb) +{ + + if (_sysio_tree_search(&pb->pb_tentry, + &names[ncache_key_index(&pb->pb_key)], + (int (*)(const void *, + const void *))compar_pb_key) != + &pb->pb_tentry) + abort(); +} + +/* + * Delete path base node from the system name cache. + */ +static void +ncache_delete(struct pnode_base *pb) +{ + + if (_sysio_tree_delete(&pb->pb_key, + &names[ncache_key_index(&pb->pb_key)], + (int (*)(const void *, + const void *))compar_pb_key) != + &pb->pb_tentry) + abort(); +} + +/* + * Lookup path base node in the system name cache given key info. + */ +static struct pnode_base * +ncache_lookup(struct pnode_base_key *pbk) +{ + struct tree_node *tn; + + tn = + _sysio_tree_find(pbk, + &names[ncache_key_index(pbk)], + (int (*)(const void *, + const void *))compar_pb_key); + return tn ? TREE_ENTRY(tn, pnode_base, pb_tentry) : NULL; +} + +/* * Allocate and initialize a new base path node. */ struct pnode_base * @@ -446,13 +504,7 @@ _sysio_pb_new(struct qstr *name, struct (void )strncpy(cp, name->name, name->len); pb->pb_key.pbk_name.name = cp; pb->pb_key.pbk_name.hashval = name->hashval; - if (_sysio_tree_search(&pb->pb_tentry, - &names[pb->pb_key.pbk_name.hashval % - NAMES_TABLE_LEN], - (int (*)(const void *, - const void *))compar_pb_key) != - &pb->pb_tentry) - abort(); + ncache_insert(pb); } pb->pb_ino = ino; @@ -475,7 +527,6 @@ _sysio_pb_new(struct qstr *name, struct static void pb_destroy(struct pnode_base *pb) { - struct tree_node *tn; assert(n_names); n_names--; @@ -483,16 +534,8 @@ pb_destroy(struct pnode_base *pb) assert(!pb->pb_aliases.lh_first); assert(!pb->pb_children.lh_first); assert(!pb->pb_ino); - if (pb->pb_key.pbk_name.len) { - tn = - _sysio_tree_delete(&pb->pb_key, - &names[pb->pb_key.pbk_name.hashval % - NAMES_TABLE_LEN], - (int (*)(const void *, - const void *))compar_pb_key); - if (TREE_ENTRY(tn, pnode_base, pb_tentry) != pb) - abort(); - } + if (pb->pb_key.pbk_name.len) + ncache_delete(pb); if (pb->pb_key.pbk_parent) LIST_REMOVE(pb, pb_sibs); @@ -523,7 +566,6 @@ static void _sysio_pb_disconnect(struct pnode_base *pb) { struct pnode *pno; - struct tree_node *tn; /* * Disconnect all aliases associated with the referenced base node. @@ -536,16 +578,10 @@ _sysio_pb_disconnect(struct pnode_base * * Remove name from the names cache so that it can't * be found anymore. */ - if (pb->pb_key.pbk_name.len) { - tn = - _sysio_tree_delete(&pb->pb_tentry, - &names[pb->pb_key.pbk_name.hashval % - NAMES_TABLE_LEN], - (int (*)(const void *, - const void *))compar_pb_key); - if (TREE_ENTRY(tn, pnode_base, pb_tentry) != pb) + if (pb->pb_key.pbk_name.len) + ncache_delete(pb); + else abort(); - } pb->pb_key.pbk_name.len = 0; } @@ -557,6 +593,12 @@ void _sysio_i_shutdown() { +#ifdef I_STATS + _sysio_cprintf("inode: probe %lu, hit %lu\n", i_probes, i_hits); + _sysio_cprintf("pbnode: probe %lu, hit %lu\n", pb_probes, pb_hits); + _sysio_cprintf("pnode: reclaims %lu, examined %lu dismissed %lu\n", + p_reclaims, p_examined, p_dismissed); +#endif max_names = desired_names; return; @@ -649,7 +691,6 @@ _sysio_p_find_alias(struct pnode *parent { struct pnode_base *pb; struct pnode_base_key key; - struct tree_node *tn; int err; struct pnode *pno; @@ -669,19 +710,12 @@ _sysio_p_find_alias(struct pnode *parent #endif key.pbk_name = *name; key.pbk_parent = parent->p_base; - tn = - _sysio_tree_find(&key, - &names[key.pbk_name.hashval % - NAMES_TABLE_LEN], - (int (*)(const void *, - const void *))compar_pb_key); - if (tn) { - pb = TREE_ENTRY(tn, pnode_base, pb_tentry); + pb = ncache_lookup(&key); #ifdef I_STATS + if (pb) pb_hits++; #endif } - } if (!pb) { /* * None found, create new child. |
From: Lee W. <lw...@us...> - 2008-03-04 15:24:13
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4108/src Modified Files: inode.c Log Message: All cache stats now kept in a record instead of as separate file-scoped globals. Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.34 retrieving revision 1.35 diff -u -w -b -B -p -r1.34 -r1.35 --- inode.c 20 Nov 2007 18:01:42 -0000 1.34 +++ inode.c 4 Mar 2008 15:24:05 -0000 1.35 @@ -115,9 +115,35 @@ struct pnodes_head _sysio_idle_pnodes; struct pnode *_sysio_root = NULL; #ifdef I_STATS -static unsigned long i_probes, i_hits; -static unsigned long pb_probes, pb_hits; -static unsigned long p_reclaims, p_examined, p_dismissed; +#define INO_CACHE_STATS +#endif + +#ifdef INO_CACHE_STATS +static struct { + unsigned long long cst_iprobes; + unsigned long long cst_ihits; + unsigned long long cst_pbprobes; + unsigned long long cst_pbhits; + unsigned long long cst_preclaims; + unsigned long long cst_pexamined; + unsigned long long cst_pdismissed; +} cstats; + +static void +ino_cstats_init() +{ + + cstats.cst_iprobes = cstats.cst_ihits = 0; + cstats.cst_pbprobes = cstats.cst_pbhits = 0; + cstats.cst_preclaims = + cstats.cst_pexamined = + cstats.cst_pdismissed = 0; +} + +#define INO_CST_UPDCNT(__which) \ + do { \ + (cstats.cst_##__which)++; \ + } while (0) #endif /* @@ -138,10 +164,8 @@ _sysio_i_init() max_names = desired_names; -#ifdef I_STATS - i_probes = i_hits = 0; - pb_probes = pb_hits = 0; - p_reclaims = p_examined = p_dismissed = 0; +#ifdef INO_CACHE_STATS + ino_cstats_init(); #endif return 0; @@ -270,15 +294,11 @@ _sysio_i_find(struct filesys *fs, struct fid->fid_data, fid->fid_len) == 0) { I_REF(ino); -#ifdef I_STATS - i_hits++; -#endif + INO_CST_UPDCNT(ihits); break; } -#ifdef I_STATS - i_probes++; -#endif + INO_CST_UPDCNT(iprobes); return ino; } @@ -344,17 +364,13 @@ p_reclaim(unsigned count) if (count) adjust = 1; -#ifdef I_STATS - p_reclaims++; -#endif + INO_CST_UPDCNT(preclaims); next = _sysio_idle_pnodes.tqh_first; if (!next) return; t = n_names / 2; do { -#ifdef I_STATS - p_examined++; -#endif + INO_CST_UPDCNT(pexamined); pno = next; next = pno->p_idle.tqe_next; if (pno->p_ref) @@ -366,9 +382,7 @@ p_reclaim(unsigned count) continue; } nxtpb = pno->p_base; -#ifdef I_STATS - p_dismissed++; -#endif + INO_CST_UPDCNT(pdismissed); _sysio_p_gone(pno); /* * Have to run up the tree, too. We might @@ -593,11 +607,17 @@ void _sysio_i_shutdown() { -#ifdef I_STATS - _sysio_cprintf("inode: probe %lu, hit %lu\n", i_probes, i_hits); - _sysio_cprintf("pbnode: probe %lu, hit %lu\n", pb_probes, pb_hits); - _sysio_cprintf("pnode: reclaims %lu, examined %lu dismissed %lu\n", - p_reclaims, p_examined, p_dismissed); +#ifdef INO_CACHE_STATS + _sysio_cprintf("inode: probe %llu, hit %llu\n", + cstats.cst_iprobes, + cstats.cst_ihits); + _sysio_cprintf("pbnode: probe %llu, hit %llu\n", + cstats.cst_pbprobes, + cstats.cst_pbhits); + _sysio_cprintf("pnode: reclaims %llu, examined %llu dismissed %llu\n", + cstats.cst_preclaims, + cstats.cst_pexamined, + cstats.cst_pdismissed); #endif max_names = desired_names; @@ -705,16 +725,12 @@ _sysio_p_find_alias(struct pnode *parent /* * Try the names table. */ -#ifdef I_STATS - pb_probes++; -#endif + INO_CST_UPDCNT(pbprobes); key.pbk_name = *name; key.pbk_parent = parent->p_base; pb = ncache_lookup(&key); -#ifdef I_STATS if (pb) - pb_hits++; -#endif + INO_CST_UPDCNT(pbhits); } if (!pb) { /* |
From: Lee W. <lw...@us...> - 2008-03-04 18:30:09
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20548 Modified Files: inode.c Log Message: Changed definition of I_STATS to INO_CACHE_STATS. It's more descriptive. Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.35 retrieving revision 1.36 diff -u -w -b -B -p -r1.35 -r1.36 --- inode.c 4 Mar 2008 15:24:05 -0000 1.35 +++ inode.c 4 Mar 2008 18:30:04 -0000 1.36 @@ -58,8 +58,6 @@ #include "inode.h" #include "dev.h" -/* #define I_STATS */ - /* * Support for path and index nodes. */ @@ -114,10 +112,6 @@ struct pnodes_head _sysio_idle_pnodes; */ struct pnode *_sysio_root = NULL; -#ifdef I_STATS -#define INO_CACHE_STATS -#endif - #ifdef INO_CACHE_STATS static struct { unsigned long long cst_iprobes; |
From: Lee W. <lw...@us...> - 2008-03-31 16:34:01
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21262 Modified Files: inode.c Log Message: If INO_CACHE_STATS was not defined at build time then neither was INO_CST_UPDCNT. IT is now, as a no-op, of course. Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.36 retrieving revision 1.37 diff -u -w -b -B -p -r1.36 -r1.37 --- inode.c 4 Mar 2008 18:30:04 -0000 1.36 +++ inode.c 31 Mar 2008 16:33:55 -0000 1.37 @@ -138,6 +138,9 @@ ino_cstats_init() do { \ (cstats.cst_##__which)++; \ } while (0) +#else +#define INO_CST_UPDCNT(__which) \ + while (0) #endif /* |
From: Lee W. <lw...@us...> - 2008-04-14 23:28:44
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1705 Modified Files: inode.c Log Message: Four changes: 1) The routine _sysio_p_path was moved here from chdir.c 2) A new routine, _sysio_p_show, is implemented when P_DEBUG is defined. 3) _sysio_p_find_alias prints the pnode when P_DEBUG is defined, using _sysio_p_show. 4) _sysio_gone prints the pnode when P_DEBUG is defined, using _sysio_p_show. Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.37 retrieving revision 1.38 diff -u -w -b -B -p -r1.37 -r1.38 --- inode.c 31 Mar 2008 16:33:55 -0000 1.37 +++ inode.c 14 Apr 2008 23:28:41 -0000 1.38 @@ -623,6 +623,100 @@ _sysio_i_shutdown() #endif /* + * Return path tracked by the path ancestor chain. + * + * If the buf pointer is NULL, a buffer large enough to hold the path + * is allocated from the heap. + */ + +int +_sysio_p_path(struct pnode *pno, char **bufp, size_t size) +{ + struct pnode *cur; + size_t len; + size_t n; + char *cp; + + cur = pno; + + if (!size && bufp && *bufp) + return -EINVAL; + + /* + * Walk up the tree to the root, summing the component name + * lengths and counting the vertices. + */ + len = 0; + n = 0; + do { + /* + * If this is a covering path-node then the name should be + * the *covered* nodes name, not this one unless we are at + * the root of the name-space. + */ + while (pno == pno->p_mount->mnt_root && + pno != pno->p_parent) + pno = pno->p_mount->mnt_covers; + + /* + * Add length of this component to running sum and + * account for this vertex. + */ + assert((len >= pno->p_base->pb_key.pbk_name.len && + (size_t )~0 - pno->p_base->pb_key.pbk_name.len > len) || + (size_t )~0 - len > pno->p_base->pb_key.pbk_name.len); + len += pno->p_base->pb_key.pbk_name.len; + n++; + assert(n); + pno = pno->p_parent; + } while (pno && pno != pno->p_parent); + if (!pno) + return -ENOENT; + + if (!*bufp) + size = len + n + 1; + if (len >= size || n >= size - len) + return -ERANGE; + if (!*bufp) { + /* + * Allocate path buffer from the heap. + */ + *bufp = malloc(size * sizeof(char)); + if (!*bufp) + return -ENOMEM; + } + + /* + * Fill in the path buffer. + */ + pno = cur; + cp = *bufp + len + n; + *cp = '\0'; /* NUL terminate */ + do { + /* + * If this is a covering path-node then the name should be + * the *covered* nodes name, not this one unless we are at + * the root of the name-space. + */ + while (pno == pno->p_mount->mnt_root && + pno != pno->p_parent ) + pno = pno->p_mount->mnt_covers; + + /* + * Add component and separator. + */ + cp -= pno->p_base->pb_key.pbk_name.len; + (void )memcpy(cp, pno->p_base->pb_key.pbk_name.name, + pno->p_base->pb_key.pbk_name.len); + + *--cp = PATH_SEPARATOR; + pno = pno->p_parent; + } while (pno != pno->p_parent); + + return 0; +} + +/* * Allocate, initialize and establish appropriate links for new path (alias) * node. */ @@ -649,6 +743,88 @@ _sysio_p_new_alias(struct pnode *parent, return pno; } +#ifdef P_DEBUG +/* + * Thread-safe strerror. + * + * Returns string describing the passed error number or NULL on failure. + */ +static char * +x_strerror(int err) +{ + char *s; + size_t buflen; + void *p; + int myerr; + + s = NULL; + buflen = 16; + for (;;) { + buflen <<= 1; + p = realloc(s, buflen); + if (!p) + free(s); + s = p; + if (!s) + break; + myerr = 0; +#if defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600 + if (strerror_r(err, s, buflen) != 0) + myerr = errno; +#elif defined(__GNU__) + { + p = strerror_r(err, s, buflen); + if (!p) + myerr = EINVAL; + else if (p != s) { + (void )strncpy(s, (char *)p, buflen - 1); + s[buflen = 1] = '\0'; + } + if (!myerr && strlen(s) == buflen - 1) + myerr = ERANGE; + } +#else +#error I do not know whtat strerror_r returns +#endif + if (!myerr) + break; + if (myerr == ERANGE) + continue; + free(s); + s = NULL; + errno = myerr; + break; + } + return s; +} + +void +_sysio_p_show(const char *pre, struct pnode *pno) +{ + int err; + char *path; + static char error_message[] = "<ERROR>"; + + path = NULL; + if ((err = _sysio_p_path(pno, &path, 0)) != 0) { + char *s; + + s = x_strerror(-err); + if (!s ||(path = malloc(strlen(s) + 2 + 1)) == NULL) { + if (s) + free(s); + path = error_message; + } else { + (void )sprintf(path, "<%s>", s); + free(s); + } + } + _sysio_diag_printf(pre, "%x:%x %s\n", pno->p_mount, pno, path); + if (path != error_message) + free(path); +} +#endif + /* * For reclamation of idle path (alias) node. */ @@ -658,6 +834,9 @@ _sysio_p_gone(struct pnode *pno) assert(!pno->p_ref); assert(!pno->p_cover); +#ifdef P_DEBUG + _sysio_p_show("P_GONE", pno); +#endif TAILQ_REMOVE(&_sysio_idle_pnodes, pno, p_idle); LIST_REMOVE(pno, p_links); @@ -758,8 +937,12 @@ _sysio_p_find_alias(struct pnode *parent if (!pno) err = -ENOMEM; } - if (!err) + if (!err) { +#ifdef P_DEBUG + _sysio_p_show("P_FIND_ALIAS", pno); +#endif *pnop = pno; + } return err; } |
From: Lee W. <lw...@us...> - 2008-04-15 16:24:56
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3459 Modified Files: inode.c Log Message: In _sysio_pb_disocnnect, when disconnecting the aliases, no alias should be the root of a file system. Added an assert to check for this. Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.38 retrieving revision 1.39 diff -u -w -b -B -p -r1.38 -r1.39 --- inode.c 14 Apr 2008 23:28:41 -0000 1.38 +++ inode.c 15 Apr 2008 16:24:42 -0000 1.39 @@ -583,6 +583,7 @@ _sysio_pb_disconnect(struct pnode_base * */ pno = pb->pb_aliases.lh_first; do { + assert(pno->p_parent != pno) pno->p_parent = NULL; } while ((pno = pno->p_links.le_next)); /* |
From: Lee W. <lw...@us...> - 2008-04-15 16:26:22
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4391 Modified Files: inode.c Log Message: That was dumb. I forgot a semi-colon. Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.39 retrieving revision 1.40 diff -u -w -b -B -p -r1.39 -r1.40 --- inode.c 15 Apr 2008 16:24:42 -0000 1.39 +++ inode.c 15 Apr 2008 16:26:19 -0000 1.40 @@ -583,7 +583,7 @@ _sysio_pb_disconnect(struct pnode_base * */ pno = pb->pb_aliases.lh_first; do { - assert(pno->p_parent != pno) + assert(pno->p_parent != pno); pno->p_parent = NULL; } while ((pno = pno->p_links.le_next)); /* |
From: Lee W. <lw...@us...> - 2008-04-23 00:24:53
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11947/src Modified Files: inode.c Log Message: Lots of changes to try to eliminate the potential for dangling references. Notable changes in the way the pnode graphs are maintained; 1) Now, mnt->mnt_root->p_parent == mnt->mnt_root->p_parent 2) An automount now causes mnt->mnt_root to be referenced, meaning automounts have to be unmounted by hand, currently -- Will fix that. 3) Disconnects do not make pno->p_parent NULL any longer as we must maintain the chain to the root. 4) One must not blindly release a pnode, please. They should only be removed from the leaves, up. Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.40 retrieving revision 1.41 diff -u -w -b -B -p -r1.40 -r1.41 --- inode.c 15 Apr 2008 16:26:19 -0000 1.40 +++ inode.c 23 Apr 2008 00:24:50 -0000 1.41 @@ -332,21 +332,6 @@ _sysio_i_undead(struct inode *ino) } /* - * Destroy path node and, if path base node is no longer referenced that - * node as well. - */ -static void -_sysio_p_kill(struct pnode *pno) -{ - struct pnode_base *pb; - - pb = pno->p_base; - _sysio_p_gone(pno); - if (!(pb->pb_aliases.lh_first || pb->pb_children.lh_first)) - _sysio_pb_gone(pb); -} - -/* * Garbage collect idle path (and base path) nodes tracked by the system. */ static void @@ -355,7 +340,7 @@ p_reclaim(unsigned count) int adjust; struct pnode *next, *pno; size_t t; - struct pnode_base *nxtpb, *pb; + struct pnode_base *pb; adjust = 0; if (count) @@ -378,22 +363,19 @@ p_reclaim(unsigned count) */ continue; } - nxtpb = pno->p_base; - INO_CST_UPDCNT(pdismissed); - _sysio_p_gone(pno); + if (pno->p_base->pb_children.lh_first) { /* - * Have to run up the tree, too. We might - * have removed the last child from the parent - * as well. + * Must not dismiss from interior nodes. There + * might be aliases on the child pointing + * at this one. */ - while ((pb = nxtpb)) { - nxtpb = NULL; - if (!(pb->pb_aliases.lh_first || - pb->pb_children.lh_first)) { - nxtpb = pb->pb_key.pbk_parent; - _sysio_pb_gone(pb); - } + continue; } + INO_CST_UPDCNT(pdismissed); + pb = pno->p_base; + _sysio_p_gone(pno); + if (!(pb->pb_children.lh_first || pb->pb_aliases.lh_first)) + _sysio_pb_gone(pb); } while ((!count || --count) && n_names > t && next); if (!adjust) @@ -576,24 +558,14 @@ _sysio_pb_gone(struct pnode_base *pb) static void _sysio_pb_disconnect(struct pnode_base *pb) { - struct pnode *pno; /* - * Disconnect all aliases associated with the referenced base node. - */ - pno = pb->pb_aliases.lh_first; - do { - assert(pno->p_parent != pno); - pno->p_parent = NULL; - } while ((pno = pno->p_links.le_next)); - /* * Remove name from the names cache so that it can't * be found anymore. */ - if (pb->pb_key.pbk_name.len) - ncache_delete(pb); - else + if (!pb->pb_key.pbk_name.len) abort(); + ncache_delete(pb); pb->pb_key.pbk_name.len = 0; } @@ -656,8 +628,10 @@ _sysio_p_path(struct pnode *pno, char ** * the root of the name-space. */ while (pno == pno->p_mount->mnt_root && - pno != pno->p_parent) + pno != pno->p_mount->mnt_covers) { pno = pno->p_mount->mnt_covers; + assert(pno); + } /* * Add length of this component to running sum and @@ -670,9 +644,10 @@ _sysio_p_path(struct pnode *pno, char ** n++; assert(n); pno = pno->p_parent; - } while (pno && pno != pno->p_parent); - if (!pno) - return -ENOENT; + assert(pno); + } while (pno != pno->p_parent || + (pno != pno->p_mount->mnt_covers && + pno->p_mount->mnt_covers)); if (!*bufp) size = len + n + 1; @@ -700,8 +675,9 @@ _sysio_p_path(struct pnode *pno, char ** * the root of the name-space. */ while (pno == pno->p_mount->mnt_root && - pno != pno->p_parent ) + pno != pno->p_mount->mnt_covers) { pno = pno->p_mount->mnt_covers; + } /* * Add component and separator. @@ -712,7 +688,9 @@ _sysio_p_path(struct pnode *pno, char ** *--cp = PATH_SEPARATOR; pno = pno->p_parent; - } while (pno != pno->p_parent); + } while (pno != pno->p_parent || + (pno != pno->p_mount->mnt_covers && + pno->p_mount->mnt_covers)); return 0; } @@ -740,6 +718,9 @@ _sysio_p_new_alias(struct pnode *parent, pno->p_mount = mnt; pno->p_cover = NULL; LIST_INSERT_HEAD(&pb->pb_aliases, pno, p_links); +#ifdef P_DEBUG + _sysio_p_show("P_CREATE_ALIAS", pno); +#endif return pno; } @@ -835,12 +816,12 @@ _sysio_p_gone(struct pnode *pno) assert(!pno->p_ref); assert(!pno->p_cover); -#ifdef P_DEBUG - _sysio_p_show("P_GONE", pno); -#endif TAILQ_REMOVE(&_sysio_idle_pnodes, pno, p_idle); LIST_REMOVE(pno, p_links); +#ifdef P_DEBUG + _sysio_p_show("P_GONE", pno); +#endif free(pno); } @@ -890,6 +871,9 @@ _sysio_p_find_alias(struct pnode *parent struct pnode_base_key key; int err; struct pnode *pno; +#ifdef P_DEBUG + int isnew; +#endif if (!parent) return -ENOENT; @@ -930,7 +914,13 @@ _sysio_p_find_alias(struct pnode *parent } pno = pno->p_links.le_next; } +#ifdef P_DEBUG + isnew = 0; +#endif if (!pno) { +#ifdef P_DEBUG + isnew = 1; +#endif /* * Hmm. No alias. Create one. */ @@ -940,6 +930,7 @@ _sysio_p_find_alias(struct pnode *parent } if (!err) { #ifdef P_DEBUG + if (!isnew) _sysio_p_show("P_FIND_ALIAS", pno); #endif *pnop = pno; @@ -973,45 +964,22 @@ _sysio_prune(struct pnode_base *rpb) } #endif -/* - * Prune idle nodes from the passed sub-tree, including the root. - * - * Returns the number of aliases on the same mount that could not be pruned. - * i.e. a zero return means the entire sub-tree is gone. - */ -size_t -_sysio_p_prune(struct pnode *root) +static size_t +p_remove_aliases(struct mount *mnt, struct pnode_base *pb) { size_t count; - struct pnode_base *nxtpb, *pb; struct pnode *nxtpno, *pno; count = 0; - nxtpb = root->p_base->pb_children.lh_first; - while ((pb = nxtpb)) { - nxtpb = pb->pb_sibs.le_next; nxtpno = pb->pb_aliases.lh_first; -#if 0 - if (!nxtpno) { - _sysio_prune(pb); - continue; - } -#endif while ((pno = nxtpno)) { nxtpno = pno->p_links.le_next; - if (pno->p_mount != root->p_mount) { + if (pno->p_mount != mnt) { /* * Not the alias we were looking for. */ continue; } - if (pno->p_base->pb_children.lh_first) { - /* - * Node is interior. Recurse. - */ - count += _sysio_p_prune(pno); - continue; - } if (pno->p_ref) { /* * Can't prune; It's active. @@ -1019,63 +987,55 @@ _sysio_p_prune(struct pnode *root) count++; continue; } - assert(!pno->p_cover); /* covered => ref'd! */ + if (pno->p_cover) { /* - * Ok to prune. + * Mounted on. */ - if (pno->p_mount->mnt_root == pno) { -#ifndef AUTOMOUNT_FILE_NAME count++; continue; -#else - /* - * This is an automount-point. Must - * unmount before reclaim. - */ - P_REF(pno); - if (_sysio_do_unmount(pno->p_mount) != 0) { - P_RELE(pno); - count++; } +#ifdef AUTOMOUNT_FILE_NAME + if (pno->p_mount->mnt_root == pno) { + count++; continue; -#endif } - _sysio_p_kill(pno); +#endif + _sysio_p_gone(pno); } + + return count; } - if (count) { - /* - * Can't get the root or we disconnect the sub-trees. - */ - if (root->p_ref) - count++; +static size_t +pb_prune(struct mount *mnt, struct pnode_base *pb) +{ + size_t count; + struct pnode_base *nxt, *child; + + count = 0; + nxt = pb->pb_children.lh_first; + while ((child = nxt)) { + nxt = child->pb_sibs.le_next; + count += pb_prune(mnt, child); + } + if (!count) { + count += p_remove_aliases(mnt, pb); + if (!(pb->pb_aliases.lh_first || pb->pb_children.lh_first)) + _sysio_pb_gone(pb); + } return count; } /* - * All that is left is the root. Try for it too. - */ - if (root->p_ref) { - count++; - } else if (root->p_mount->mnt_root == root) { -#ifndef AUTOMOUNT_FILE_NAME - count++; -#else - /* - * This is an automount-point. Must - * unmount before reclaim. + * Prune idle nodes from the passed sub-tree, including the root. + * + * Returns the number of aliases on the same mount that could not be pruned. + * i.e. a zero return means the entire sub-tree is gone. */ - P_REF(root); - if (_sysio_do_unmount(root->p_mount) != 0) { - P_RELE(root); - count++; - } -#endif - } else - _sysio_p_kill(root); - - return count; +size_t +_sysio_p_prune(struct pnode *pno) +{ + return pb_prune(pno->p_mount, pno->p_base); } /* |
From: Lee W. <lw...@us...> - 2008-04-23 16:46:43
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27174/src Modified Files: inode.c Log Message: If P_RECLAIM_DEBUG is definded then at each reclaim a count of the number of pnode_base nodes present in the system is printed along with the number of those that are leaves and the number of interior nodes without aliases (orphpans). Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.41 retrieving revision 1.42 diff -u -w -b -B -p -r1.41 -r1.42 --- inode.c 23 Apr 2008 00:24:50 -0000 1.41 +++ inode.c 23 Apr 2008 16:46:40 -0000 1.42 @@ -107,6 +107,10 @@ static size_t max_names; */ struct pnodes_head _sysio_idle_pnodes; +#ifdef P_RECLAIM_DEBUG +static LIST_HEAD(, pnode_base) pbnodes; +#endif + /* * The system root -- Aka `/'. */ @@ -331,6 +335,33 @@ _sysio_i_undead(struct inode *ino) ino->i_zombie = 1; } +#ifdef P_RECLAIM_DEBUG +static void +p_reclaim_debug() +{ + struct pnode_base *nxt, *pb; + unsigned long npb, npbleaves, npborphans; + + npb = 0; + npbleaves = 0; + npborphans = 0; + + nxt = pbnodes.lh_first; + while ((pb = nxt)) { + nxt = pb->pb_links.le_next; + npb++; + if (!pb->pb_children.lh_first) + npbleaves++; + else if (!pb->pb_aliases.lh_first) + npborphans++; + } + _sysio_cprintf("PBSTATS: n %lu, leaves %lu, orphans %lu\n", + npb, + npbleaves, + npborphans); +} +#endif + /* * Garbage collect idle path (and base path) nodes tracked by the system. */ @@ -346,6 +377,10 @@ p_reclaim(unsigned count) if (count) adjust = 1; +#ifdef P_RECLAIM_DEBUG + p_reclaim_debug(); +#endif + INO_CST_UPDCNT(preclaims); next = _sysio_idle_pnodes.tqh_first; if (!next) @@ -505,6 +540,9 @@ _sysio_pb_new(struct qstr *name, struct LIST_INIT(&pb->pb_aliases); if (parent) LIST_INSERT_HEAD(&parent->pb_children, pb, pb_sibs); +#ifdef P_RECLAIM_DEBUG + LIST_INSERT_HEAD(&pbnodes, pb, pb_links); +#endif n_names++; assert(n_names); @@ -531,6 +569,9 @@ pb_destroy(struct pnode_base *pb) ncache_delete(pb); if (pb->pb_key.pbk_parent) LIST_REMOVE(pb, pb_sibs); +#ifdef P_RECLAIM_DEBUG + LIST_REMOVE(pb, pb_links); +#endif free(pb); } |
From: Lee W. <lw...@us...> - 2008-07-11 16:48:05
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8234/src Modified Files: inode.c Log Message: Added per-directory name cache, replacing the global names cache. This involved: 1) Adding a root node for the binary tree to the path_base record. 2) Removing the global names cache from inode.c 3) Altering the implementation of ncache_{insert,delete} to use the parent node's names root as root. 4) Altering ncache_lookup to take the parent node and use it's root to find the key. Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.43 retrieving revision 1.44 diff -u -w -b -B -p -r1.43 -r1.44 --- inode.c 17 Jun 2008 17:18:57 -0000 1.43 +++ inode.c 11 Jul 2008 16:48:01 -0000 1.44 @@ -76,23 +76,6 @@ struct inodes_head _sysio_inodes; static size_t n_inodes = 0; /* - * System table for rapid access to component names. - */ -static struct tree_node *names[NAMES_TABLE_LEN]; - -/* - * Return slot index in names table given pointer to path base key. - */ -#define ncache_key_index(pbk) \ - ((pbk)->pbk_name.hashval % NAMES_TABLE_LEN) - -/* - * Return ptr to slot in names table given hash value. - */ -#define ncache_slot(h) \ - (names[(h)] % NAMES_TABLE_LEN) - -/* * Number of names tracked by the system. */ static size_t n_names = 0; @@ -154,13 +137,9 @@ ino_cstats_init() int _sysio_i_init() { - unsigned i; TAILQ_INIT(&_sysio_inodes); - for (i = 0; i < NAMES_TABLE_LEN; i++) - names[i] = NULL; - TAILQ_INIT(&_sysio_idle_pnodes); max_names = desired_names; @@ -467,8 +446,9 @@ static void ncache_insert(struct pnode_base *pb) { + assert(pb->pb_key.pbk_parent); if (_sysio_tree_search(&pb->pb_tentry, - &names[ncache_key_index(&pb->pb_key)], + &pb->pb_key.pbk_parent->pb_ncache, (int (*)(const void *, const void *))compar_pb_key) != &pb->pb_tentry) @@ -482,8 +462,9 @@ static void ncache_delete(struct pnode_base *pb) { + assert(pb->pb_key.pbk_parent); if (_sysio_tree_delete(&pb->pb_key, - &names[ncache_key_index(&pb->pb_key)], + &pb->pb_key.pbk_parent->pb_ncache, (int (*)(const void *, const void *))compar_pb_key) != &pb->pb_tentry) @@ -494,13 +475,13 @@ ncache_delete(struct pnode_base *pb) * Lookup path base node in the system name cache given key info. */ static struct pnode_base * -ncache_lookup(struct pnode_base_key *pbk) +ncache_lookup(struct pnode_base *pb, struct pnode_base_key *pbk) { struct tree_node *tn; tn = _sysio_tree_find(pbk, - &names[ncache_key_index(pbk)], + &pb->pb_ncache, (int (*)(const void *, const void *))compar_pb_key); return tn ? TREE_ENTRY(tn, pnode_base, pb_tentry) : NULL; @@ -936,7 +917,7 @@ _sysio_p_find_alias(struct pnode *parent INO_CST_UPDCNT(pbprobes); key.pbk_name = *name; key.pbk_parent = parent->p_base; - pb = ncache_lookup(&key); + pb = ncache_lookup(key.pbk_parent, &key); if (pb) { PB_GET(pb); INO_CST_UPDCNT(pbhits); |
From: Lee W. <lw...@us...> - 2008-07-14 19:15:04
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13306/src Modified Files: inode.c Log Message: Directory name cache comparison routine no longer needs parent node as a key. Removed that test. Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.44 retrieving revision 1.45 diff -u -w -b -B -p -r1.44 -r1.45 --- inode.c 11 Jul 2008 16:48:01 -0000 1.44 +++ inode.c 14 Jul 2008 19:15:00 -0000 1.45 @@ -419,19 +419,21 @@ compar_pb_key(const struct pnode_base_ke const struct pnode_base_key *pbk2) { +#ifdef notdef if (pbk1->pbk_parent < pbk2->pbk_parent) return -1; if (pbk1->pbk_parent > pbk2->pbk_parent) return 1; +#endif - if (pbk1->pbk_name.len < pbk2->pbk_name.len) + if (pbk1->pbk_name.hashval < pbk2->pbk_name.hashval) return -1; - if (pbk1->pbk_name.len > pbk2->pbk_name.len) + if (pbk1->pbk_name.hashval > pbk2->pbk_name.hashval) return 1; - if (pbk1->pbk_name.hashval < pbk2->pbk_name.hashval) + if (pbk1->pbk_name.len < pbk2->pbk_name.len) return -1; - if (pbk1->pbk_name.hashval > pbk2->pbk_name.hashval) + if (pbk1->pbk_name.len > pbk2->pbk_name.len) return 1; return strncmp(pbk1->pbk_name.name, |
From: Lee W. <lw...@us...> - 2008-07-26 01:31:44
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8078 Modified Files: inode.c Log Message: The file system record now maintains the list of associated i-nodes as a tree. This speeds up _sysio_i_find greatly when the names table cache is allowed to become large. Removed deprecated function named _sysio_prune Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.45 retrieving revision 1.46 diff -u -w -b -B -p -r1.45 -r1.46 --- inode.c 14 Jul 2008 19:15:00 -0000 1.45 +++ inode.c 26 Jul 2008 01:31:40 -0000 1.46 @@ -68,6 +67,10 @@ #ifndef NAMES_TABLE_LEN #define NAMES_TABLE_LEN 251 #endif +/* + * Desired high-water mark. + */ +#define P_RECLAIM_MIN 16 /* * Active i-nodes in the system and the number of same. @@ -79,11 +82,6 @@ static size_t n_inodes = 0; * Number of names tracked by the system. */ static size_t n_names = 0; -/* - * Desired number of base path nodes to maintain. - */ -static size_t desired_names = (3 * NAMES_TABLE_LEN); -static size_t max_names; /* * List of all path-nodes (aliases) that are not currently referenced. @@ -103,6 +101,9 @@ struct pnode *_sysio_root = NULL; static struct { unsigned long long cst_iprobes; unsigned long long cst_ihits; + unsigned long long cst_ireclaims; + unsigned long long cst_iexamined; + unsigned long long cst_idismissed; unsigned long long cst_pbprobes; unsigned long long cst_pbhits; unsigned long long cst_preclaims; @@ -115,6 +116,9 @@ ino_cstats_init() { cstats.cst_iprobes = cstats.cst_ihits = 0; + cstats.cst_ireclaims = + cstats.cst_iexamined = + cstats.cst_idismissed = 0; cstats.cst_pbprobes = cstats.cst_pbhits = 0; cstats.cst_preclaims = cstats.cst_pexamined = @@ -142,8 +146,6 @@ _sysio_i_init() TAILQ_INIT(&_sysio_idle_pnodes); - max_names = desired_names; - #ifdef INO_CACHE_STATS ino_cstats_init(); #endif @@ -160,34 +162,88 @@ i_reclaim() struct inode *next, *ino; size_t t; - t = n_inodes / 2; + INO_CST_UPDCNT(ireclaims); + t = n_inodes - n_inodes / 10; next = _sysio_inodes.tqh_first; while (next) { ino = next; next = ino->i_nodes.tqe_next; + INO_CST_UPDCNT(iexamined); if (ino->i_ref || ino->i_immune) continue; + INO_CST_UPDCNT(idismissed); _sysio_i_gone(ino); if (n_inodes < t) break; } } -static unsigned -hash(struct file_identifier *fid) +/* + * Compare two file identifiers, returning -1 if length of first is + * less than the second, or 1 if length of first greater than then the + * second, or the result of a memory compare if lengths are the same. + */ +static int +compar_fid(const struct file_identifier *fid1, + const struct file_identifier *fid2) { - size_t n; - unsigned char *ucp; - unsigned hkey; - n = fid->fid_len; - ucp = fid->fid_data; - hkey = 0; - do { - hkey <<= 1; - hkey += *ucp++; - } while (--n); - return hkey; + if (fid1->fid_len < fid2->fid_len) + return -1; + if (fid1->fid_len > fid2->fid_len) + return 1; + return memcmp(fid1->fid_data, fid2->fid_data, fid1->fid_len); +} + +/* + * Insert inode into per-fs inode cache. + * + * NB: The given inode must not already be in the cache. + */ +static void +icache_insert(struct inode *ino) +{ + + if (_sysio_tree_search(&ino->i_tnode, + &ino->i_fs->fs_icache, + (int (*)(const void *, + const void *))compar_fid) != + &ino->i_tnode) + abort(); +} + +/* + * Remove inode from inode cache. + * + * NB: The inode must be present in the cache. + */ +static void +icache_delete(struct inode *ino) +{ + + if (_sysio_tree_delete(ino->i_fid, + &ino->i_fs->fs_icache, + (int (*)(const void *, + const void *))compar_fid) != + &ino->i_tnode) + abort(); +} + +/* + * Find, and return, inode with given file identifier. If not found, NULL is + * returned instead. + */ +static struct inode * +icache_lookup(struct filesys *fs, struct file_identifier *fid) +{ + struct tree_node *tn; + + tn = + _sysio_tree_find(fid, + &fs->fs_icache, + (int (*)(const void *, + const void *))compar_fid); + return tn ? TREE_ENTRY(tn, inode, i_tnode) : NULL; } /* @@ -206,7 +262,6 @@ _sysio_i_new(struct filesys *fs, { struct inode *ino; struct inode_ops operations; - struct itable_entry *head; if (n_inodes > n_names) { /* @@ -244,10 +299,9 @@ _sysio_i_new(struct filesys *fs, I_INIT(ino, fs, stat, &operations, fid, immunity, private); ino->i_ref = 1; TAILQ_INSERT_TAIL(&_sysio_inodes, ino, i_nodes); - head = &fs->fs_itbl[hash(fid) % FS_ITBLSIZ]; - LIST_INSERT_HEAD(head, ino, i_link); I_GET(ino); + icache_insert(ino); I_RELE(ino); n_inodes++; @@ -264,23 +318,13 @@ struct inode * _sysio_i_find(struct filesys *fs, struct file_identifier *fid) { struct inode *ino; - struct itable_entry *head; - head = &fs->fs_itbl[hash(fid) % FS_ITBLSIZ]; - /* - * Look for existing. - */ - for (ino = head->lh_first; ino; ino = ino->i_link.le_next) - if (ino->i_fid->fid_len == fid->fid_len && - memcmp(ino->i_fid->fid_data, - fid->fid_data, - fid->fid_len) == 0) { + INO_CST_UPDCNT(iprobes); + ino = icache_lookup(fs, fid); + if (!ino) + return NULL; I_GET(ino); INO_CST_UPDCNT(ihits); - break; - } - - INO_CST_UPDCNT(iprobes); return ino; } @@ -294,7 +338,7 @@ _sysio_i_gone(struct inode *ino) if (ino->i_ref) abort(); if (!ino->i_zombie) - LIST_REMOVE(ino, i_link); + icache_delete(ino); TAILQ_REMOVE(&_sysio_inodes, ino, i_nodes); (*ino->i_ops.inop_gone)(ino); I_UNLOCK(ino); @@ -314,8 +358,8 @@ _sysio_i_undead(struct inode *ino) if (ino->i_zombie) return; - LIST_REMOVE(ino, i_link); ino->i_zombie = 1; + icache_delete(ino); } #ifdef P_RECLAIM_DEBUG @@ -349,17 +393,11 @@ p_reclaim_debug() * Garbage collect idle path (and base path) nodes tracked by the system. */ static void -p_reclaim(unsigned count) +p_reclaim(unsigned limit) { - int adjust; struct pnode *next, *pno; - size_t t; struct pnode_base *pb; - adjust = 0; - if (count) - adjust = 1; - #ifdef P_RECLAIM_DEBUG p_reclaim_debug(); #endif @@ -368,7 +406,6 @@ p_reclaim(unsigned count) next = _sysio_idle_pnodes.tqh_first; if (!next) return; - t = n_names / 2; do { INO_CST_UPDCNT(pexamined); pno = next; @@ -400,18 +437,7 @@ p_reclaim(unsigned count) _sysio_pb_gone(pb); else PB_UNLOCK(pb); - } while ((!count || --count) && n_names > t && next); - - if (!adjust) - return; - - if (n_names > t) - max_names += t; - else { - max_names = t; - if (max_names < desired_names) - max_names = desired_names; - } + } while ((!limit || limit-- > 1) && next); } static int @@ -498,13 +524,6 @@ _sysio_pb_new(struct qstr *name, struct struct pnode_base *pb; static struct qstr noname = { NULL, 0, 0 }; - if (n_names > max_names) { - /* - * Try to limit growth. - */ - p_reclaim(0); - } - pb = malloc(sizeof(struct pnode_base) + name->len); if (!pb) return NULL; @@ -532,12 +551,23 @@ _sysio_pb_new(struct qstr *name, struct ncache_insert(pb); } + n_names++; + assert(n_names); + #ifdef P_RECLAIM_DEBUG LIST_INSERT_HEAD(&pbnodes, pb, pb_links); #endif - n_names++; - assert(n_names); + if (n_names > NAMES_TABLE_LEN) { + unsigned n; + /* + * Limit growth. + */ + n = n_names - NAMES_TABLE_LEN; + if (n < P_RECLAIM_MIN) + n = P_RECLAIM_MIN; + p_reclaim(n); + } return pb; } @@ -609,6 +639,10 @@ _sysio_i_shutdown() _sysio_cprintf("inode: probe %llu, hit %llu\n", cstats.cst_iprobes, cstats.cst_ihits); + _sysio_cprintf("inode: reclaims %llu, examined %llu dismissed %llu\n", + cstats.cst_ireclaims, + cstats.cst_iexamined, + cstats.cst_idismissed); _sysio_cprintf("pbnode: probe %llu, hit %llu\n", cstats.cst_pbprobes, cstats.cst_pbhits); @@ -617,7 +651,6 @@ _sysio_i_shutdown() cstats.cst_pexamined, cstats.cst_pdismissed); #endif - max_names = desired_names; return; } @@ -971,32 +1004,6 @@ _sysio_p_find_alias(struct pnode *parent return err; } -#if 0 -/* - * Prune idle path base nodes from the passed sub-tree, including the root. - */ -static void -_sysio_prune(struct pnode_base *rpb) -{ - struct pnode_base *nxtpb, *pb; - - nxtpb = rpb->pb_children.lh_first; - while ((pb = nxtpb)) { - nxtpb = pb->pb_sibs.le_next; - if (pb->pb_aliases.lh_first) - continue; - if (pb->pb_children.lh_first) { - _sysio_prune(pb); - continue; - } - _sysio_pb_gone(pb); - } - if (rpb->pb_children.lh_first) - return; - _sysio_pb_gone(rpb); -} -#endif - static size_t p_remove_aliases(struct mount *mnt, struct pnode_base *pb) { |
From: Lee W. <lw...@us...> - 2008-12-06 23:28:26
|
Update of /cvsroot/libsysio/libsysio/src In directory ddv4jf1.ch3.sourceforge.com:/tmp/cvs-serv8101 Modified Files: inode.c Log Message: When removing file system objects, make them undead. Go ahead and kill inodes marked immune if they are also zombies. Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.47 retrieving revision 1.48 diff -u -w -b -B -p -r1.47 -r1.48 --- inode.c 6 Dec 2008 21:56:25 -0000 1.47 +++ inode.c 6 Dec 2008 23:28:19 -0000 1.48 @@ -169,7 +169,7 @@ i_reclaim() ino = next; next = ino->i_nodes.tqe_next; INO_CST_UPDCNT(iexamined); - if (ino->i_ref || ino->i_immune) + if (ino->i_ref || (ino->i_immune && !ino->i_zombie)) continue; INO_CST_UPDCNT(idismissed); _sysio_i_gone(ino); @@ -1321,6 +1321,7 @@ _sysio_p_unlink(struct pnode *pno) /* * Clean the namespace graphs to reflect the unlink. */ + _sysio_i_undead(pno->p_base->pb_ino); _sysio_pb_disconnect(pno->p_base); return 0; } @@ -1367,6 +1368,7 @@ _sysio_p_rmdir(struct pnode *pno) /* * Clean the namespace graphs to reflect the unlink. */ + _sysio_i_undead(pno->p_base->pb_ino); _sysio_pb_disconnect(pno->p_base); return 0; } |
From: Lee W. <lw...@us...> - 2008-12-12 22:28:22
|
Update of /cvsroot/libsysio/libsysio/src In directory ddv4jf1.ch3.sourceforge.com:/tmp/cvs-serv13919/src Modified Files: inode.c Log Message: Removed inode reclaim functionality. This is handled, now, by the base node reclamation; It kills idle inodes. Also, set the minimum reclaim for base nodes to 511 or 1/4 or NAMES_TABLE_LEN, whichever is smaller. Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.48 retrieving revision 1.49 diff -u -w -b -B -p -r1.48 -r1.49 --- inode.c 6 Dec 2008 23:28:19 -0000 1.48 +++ inode.c 12 Dec 2008 22:28:15 -0000 1.49 @@ -70,7 +71,10 @@ /* * Desired high-water mark. */ -#define P_RECLAIM_MIN 16 +#define P_RECLAIM_MIN 511 +#if P_RECLAIM_MIN > (NAMES_TABLE_LEN / 4) +#define P_RECLAIM_MIN (NAMES_TABLE_LEN / 4) +#endif /* * Active i-nodes in the system and the number of same. @@ -101,9 +105,11 @@ struct pnode *_sysio_root = NULL; static struct { unsigned long long cst_iprobes; unsigned long long cst_ihits; +#if 0 unsigned long long cst_ireclaims; unsigned long long cst_iexamined; unsigned long long cst_idismissed; +#endif unsigned long long cst_pbprobes; unsigned long long cst_pbhits; unsigned long long cst_preclaims; @@ -116,9 +122,11 @@ ino_cstats_init() { cstats.cst_iprobes = cstats.cst_ihits = 0; +#if 0 cstats.cst_ireclaims = cstats.cst_iexamined = cstats.cst_idismissed = 0; +#endif cstats.cst_pbprobes = cstats.cst_pbhits = 0; cstats.cst_preclaims = cstats.cst_pexamined = @@ -153,6 +161,7 @@ _sysio_i_init() return 0; } +#if 0 /* * Garbage-collect idle i-nodes. */ @@ -177,6 +186,7 @@ i_reclaim() break; } } +#endif /* * Compare two file identifiers, returning -1 if length of first is @@ -263,6 +273,7 @@ _sysio_i_new(struct filesys *fs, struct inode *ino; struct inode_ops operations; +#if 0 if (n_inodes > n_names) { /* * This has become pretty badly skewed relative to @@ -271,6 +282,7 @@ _sysio_i_new(struct filesys *fs, */ i_reclaim(); } +#endif ino = malloc(sizeof(struct inode)); if (!ino) @@ -639,10 +651,12 @@ _sysio_i_shutdown() _sysio_cprintf("inode: probe %llu, hit %llu\n", cstats.cst_iprobes, cstats.cst_ihits); +#if 0 _sysio_cprintf("inode: reclaims %llu, examined %llu dismissed %llu\n", cstats.cst_ireclaims, cstats.cst_iexamined, cstats.cst_idismissed); +#endif _sysio_cprintf("pbnode: probe %llu, hit %llu\n", cstats.cst_pbprobes, cstats.cst_pbhits); |
From: Lee W. <lw...@us...> - 2008-12-15 19:56:02
|
Update of /cvsroot/libsysio/libsysio/src In directory ddv4jf1.ch3.sourceforge.com:/tmp/cvs-serv20145/src Modified Files: inode.c Log Message: The all-pbnodes list is changed to be maintained as a tailq, instead of a simple linked list. Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.49 retrieving revision 1.50 diff -u -w -b -B -p -r1.49 -r1.50 --- inode.c 12 Dec 2008 22:28:15 -0000 1.49 +++ inode.c 15 Dec 2008 19:55:54 -0000 1.50 @@ -93,7 +93,7 @@ static size_t n_names = 0; struct pnodes_head _sysio_idle_pnodes; #ifdef P_RECLAIM_DEBUG -static LIST_HEAD(, pnode_base) pbnodes; +static TAILQ_HEAD(, pnode_base) pbnodes; #endif /* @@ -385,9 +385,9 @@ p_reclaim_debug() npbleaves = 0; npborphans = 0; - nxt = pbnodes.lh_first; + nxt = pbnodes.tqh_first; while ((pb = nxt)) { - nxt = pb->pb_links.le_next; + nxt = pb->pb_links.tqe_next; npb++; if (!pb->pb_children.lh_first) npbleaves++; @@ -545,7 +545,8 @@ _sysio_pb_new(struct qstr *name, struct PB_INIT(pb, name, parent, ino); if (ino) I_REF(ino); - PB_GET(pb); + PB_LOCK(pb); + if (parent) LIST_INSERT_HEAD(&parent->pb_children, pb, pb_sibs); if (pb->pb_key.pbk_name.len) { @@ -562,14 +563,15 @@ _sysio_pb_new(struct qstr *name, struct pb->pb_key.pbk_name.name = cp; ncache_insert(pb); } +#ifdef P_RECLAIM_DEBUG + TAILQ_INSERT_HEAD(&pbnodes, pb, pb_links); +#endif + PB_GET(pb); + PB_UNLOCK(pb); n_names++; assert(n_names); -#ifdef P_RECLAIM_DEBUG - LIST_INSERT_HEAD(&pbnodes, pb, pb_links); -#endif - if (n_names > NAMES_TABLE_LEN) { unsigned n; /* @@ -603,7 +605,7 @@ _sysio_pb_gone(struct pnode_base *pb) if (pb->pb_key.pbk_parent) LIST_REMOVE(pb, pb_sibs); #ifdef P_RECLAIM_DEBUG - LIST_REMOVE(pb, pb_links); + TAILQ_REMOVE(&pbnodes, pb, pb_links); #endif ino = pb->pb_ino; if (ino) |
From: Lee W. <lw...@us...> - 2009-01-05 19:19:37
|
Update of /cvsroot/libsysio/libsysio/src In directory ddv4jf1.ch3.sourceforge.com:/tmp/cvs-serv10773/src Modified Files: inode.c Log Message: We no longer reclaim i_nodes directly. Instead, as path-base nodes are released by the path node reclamation, the i-node is dismissed directly. It served no useful purpose to retain these beyond the life of the set of associated path-base nodes. As well, if PB_DEBUG is defined then a list of leaf path-base nodes is kept and reported when we are dbugging reclamation. Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.50 retrieving revision 1.51 diff -u -w -b -B -p -r1.50 -r1.51 --- inode.c 15 Dec 2008 19:55:54 -0000 1.50 +++ inode.c 5 Jan 2009 19:19:29 -0000 1.51 @@ -73,6 +73,7 @@ */ #define P_RECLAIM_MIN 511 #if P_RECLAIM_MIN > (NAMES_TABLE_LEN / 4) +#undef P_RECLAIM_MIN #define P_RECLAIM_MIN (NAMES_TABLE_LEN / 4) #endif @@ -92,8 +93,8 @@ static size_t n_names = 0; */ struct pnodes_head _sysio_idle_pnodes; -#ifdef P_RECLAIM_DEBUG -static TAILQ_HEAD(, pnode_base) pbnodes; +#ifdef PB_DEBUG +static TAILQ_HEAD(, pnode_base) pb_leaf_nodes; #endif /* @@ -105,11 +106,6 @@ struct pnode *_sysio_root = NULL; static struct { unsigned long long cst_iprobes; unsigned long long cst_ihits; -#if 0 - unsigned long long cst_ireclaims; - unsigned long long cst_iexamined; - unsigned long long cst_idismissed; -#endif unsigned long long cst_pbprobes; unsigned long long cst_pbhits; unsigned long long cst_preclaims; @@ -122,11 +118,6 @@ ino_cstats_init() { cstats.cst_iprobes = cstats.cst_ihits = 0; -#if 0 - cstats.cst_ireclaims = - cstats.cst_iexamined = - cstats.cst_idismissed = 0; -#endif cstats.cst_pbprobes = cstats.cst_pbhits = 0; cstats.cst_preclaims = cstats.cst_pexamined = @@ -151,7 +142,9 @@ _sysio_i_init() { TAILQ_INIT(&_sysio_inodes); - +#ifdef PB_DEBUG + TAILQ_INIT(&pb_leaf_nodes); +#endif TAILQ_INIT(&_sysio_idle_pnodes); #ifdef INO_CACHE_STATS @@ -161,33 +154,6 @@ _sysio_i_init() return 0; } -#if 0 -/* - * Garbage-collect idle i-nodes. - */ -static void -i_reclaim() -{ - struct inode *next, *ino; - size_t t; - - INO_CST_UPDCNT(ireclaims); - t = n_inodes - n_inodes / 10; - next = _sysio_inodes.tqh_first; - while (next) { - ino = next; - next = ino->i_nodes.tqe_next; - INO_CST_UPDCNT(iexamined); - if (ino->i_ref || (ino->i_immune && !ino->i_zombie)) - continue; - INO_CST_UPDCNT(idismissed); - _sysio_i_gone(ino); - if (n_inodes < t) - break; - } -} -#endif - /* * Compare two file identifiers, returning -1 if length of first is * less than the second, or 1 if length of first greater than then the @@ -273,17 +239,6 @@ _sysio_i_new(struct filesys *fs, struct inode *ino; struct inode_ops operations; -#if 0 - if (n_inodes > n_names) { - /* - * This has become pretty badly skewed relative to - * the number of active nodes in the system. Try to - * correct that, now. - */ - i_reclaim(); - } -#endif - ino = malloc(sizeof(struct inode)); if (!ino) return NULL; @@ -374,7 +329,7 @@ _sysio_i_undead(struct inode *ino) icache_delete(ino); } -#ifdef P_RECLAIM_DEBUG +#ifdef PB_DEBUG static void p_reclaim_debug() { @@ -385,7 +340,7 @@ p_reclaim_debug() npbleaves = 0; npborphans = 0; - nxt = pbnodes.tqh_first; + nxt = pb_leaf_nodes.tqh_first; while ((pb = nxt)) { nxt = pb->pb_links.tqe_next; npb++; @@ -410,10 +365,6 @@ p_reclaim(unsigned limit) struct pnode *next, *pno; struct pnode_base *pb; -#ifdef P_RECLAIM_DEBUG - p_reclaim_debug(); -#endif - INO_CST_UPDCNT(preclaims); next = _sysio_idle_pnodes.tqh_first; if (!next) @@ -536,6 +487,17 @@ _sysio_pb_new(struct qstr *name, struct struct pnode_base *pb; static struct qstr noname = { NULL, 0, 0 }; + if (n_names > NAMES_TABLE_LEN) { + unsigned n; + /* + * Limit growth. + */ + n = n_names - NAMES_TABLE_LEN; + if (n < P_RECLAIM_MIN) + n = P_RECLAIM_MIN; + p_reclaim(n); + } + pb = malloc(sizeof(struct pnode_base) + name->len); if (!pb) return NULL; @@ -547,8 +509,18 @@ _sysio_pb_new(struct qstr *name, struct I_REF(ino); PB_LOCK(pb); - if (parent) + if (pb->pb_key.pbk_parent) { +#if defined(PB_DEBUG) + if (!parent->pb_children.lh_first) { + /* + * The parent is no longer a leaf. We + * need to remove it from that list. + */ + TAILQ_REMOVE(&pb_leaf_nodes, parent, pb_links); + } +#endif LIST_INSERT_HEAD(&parent->pb_children, pb, pb_sibs); + } if (pb->pb_key.pbk_name.len) { char *cp; @@ -563,8 +535,8 @@ _sysio_pb_new(struct qstr *name, struct pb->pb_key.pbk_name.name = cp; ncache_insert(pb); } -#ifdef P_RECLAIM_DEBUG - TAILQ_INSERT_HEAD(&pbnodes, pb, pb_links); +#ifdef PB_DEBUG + TAILQ_INSERT_TAIL(&pb_leaf_nodes, pb, pb_links); #endif PB_GET(pb); PB_UNLOCK(pb); @@ -572,17 +544,6 @@ _sysio_pb_new(struct qstr *name, struct n_names++; assert(n_names); - if (n_names > NAMES_TABLE_LEN) { - unsigned n; - /* - * Limit growth. - */ - n = n_names - NAMES_TABLE_LEN; - if (n < P_RECLAIM_MIN) - n = P_RECLAIM_MIN; - p_reclaim(n); - } - return pb; } @@ -602,10 +563,22 @@ _sysio_pb_gone(struct pnode_base *pb) if (pb->pb_key.pbk_name.len) ncache_delete(pb); - if (pb->pb_key.pbk_parent) + if (pb->pb_key.pbk_parent) { LIST_REMOVE(pb, pb_sibs); -#ifdef P_RECLAIM_DEBUG - TAILQ_REMOVE(&pbnodes, pb, pb_links); +#if defined(PB_DEBUG) + /* + * If we just removed the last child, put the parent on + * the list of leaves. + */ + if (!pb->pb_key.pbk_parent->pb_children.lh_first) { + TAILQ_INSERT_TAIL(&pb_leaf_nodes, + pb->pb_key.pbk_parent, + pb_links); + } +#endif + } +#ifdef PB_DEBUG + TAILQ_REMOVE(&pb_leaf_nodes, pb, pb_links); #endif ino = pb->pb_ino; if (ino) @@ -653,12 +626,6 @@ _sysio_i_shutdown() _sysio_cprintf("inode: probe %llu, hit %llu\n", cstats.cst_iprobes, cstats.cst_ihits); -#if 0 - _sysio_cprintf("inode: reclaims %llu, examined %llu dismissed %llu\n", - cstats.cst_ireclaims, - cstats.cst_iexamined, - cstats.cst_idismissed); -#endif _sysio_cprintf("pbnode: probe %llu, hit %llu\n", cstats.cst_pbprobes, cstats.cst_pbhits); |