diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-05-14 11:19:35 +0200 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2015-04-17 14:06:46 +0200 |
commit | c16eed2cb64089bf7d958db0fe85352f4ceefb4d (patch) | |
tree | 3240f6e025fa4c4fb47d7d270f285a7f0f9612e4 /fatfs/inode.c | |
parent | 8c050fb080c6e1981dc8e5a97a2313cd24e9b4b4 (diff) |
libdiskfs: lock-less reference counting of nodes
* libdiskfs/diskfs.h (struct node): Use refcounts_t for reference counting.
(diskfs_node_refcnt_lock): Remove.
(diskfs_node_norefs,diskfs_drop_node): Change comments accordingly.
* libdiskfs/init-init.c: Adjust accordingly.
* libdiskfs/node-drop.c: Likewise.
* libdiskfs/node-make.c: Likewise.
* libdiskfs/node-nput.c: Likewise.
* libdiskfs/node-nputl.c: Likewise.
* libdiskfs/node-nref.c: Likewise.
* libdiskfs/node-nrefl.c: Likewise.
* libdiskfs/node-nrele.c: Likewise.
* libdiskfs/node-nrelel.c: Likewise.
* ext2fs/inode.c: Likewise.
* fatfs/inode.c: Likewise.
* isofs/inode.c: Likewise.
* tmpfs/node.c: Likewise.
* doc/hurd.texi: Likewise.
Diffstat (limited to 'fatfs/inode.c')
-rw-r--r-- | fatfs/inode.c | 27 |
1 files changed, 8 insertions, 19 deletions
diff --git a/fatfs/inode.c b/fatfs/inode.c index 1d670f53..f228618d 100644 --- a/fatfs/inode.c +++ b/fatfs/inode.c @@ -55,7 +55,6 @@ through the nodehash. */ static struct node *nodehash[INOHSZ]; static size_t nodehash_nr_items; -/* nodecache_lock must be acquired before diskfs_node_refcnt_lock. */ static pthread_rwlock_t nodecache_lock = PTHREAD_RWLOCK_INITIALIZER; static error_t read_node (struct node *np, vm_address_t buf); @@ -254,14 +253,8 @@ diskfs_node_norefs (struct node *np) if (np->dn->translator) free (np->dn->translator); - /* It is safe to unlock diskfs_node_refcnt_lock here for a while because - all references to the node have been deleted. */ if (np->dn->dirnode) - { - pthread_spin_unlock (&diskfs_node_refcnt_lock); - diskfs_nrele (np->dn->dirnode); - pthread_spin_lock (&diskfs_node_refcnt_lock); - } + diskfs_nrele (np->dn->dirnode); assert (!np->dn->pager); @@ -279,14 +272,10 @@ diskfs_try_dropping_softrefs (struct node *np) { /* Check if someone reacquired a reference through the nodehash. */ - unsigned int references; - pthread_spin_lock (&diskfs_node_refcnt_lock); - references = np->references; - pthread_spin_unlock (&diskfs_node_refcnt_lock); - - /* An additional reference is acquired by libdiskfs across calls - to diskfs_try_dropping_softrefs. */ - if (references > 1) + struct references result; + refcounts_references (&np->refcounts, &result); + + if (result.hard > 0) { /* A reference was reacquired through a hash table lookup. It's fine, we didn't touch anything yet. */ @@ -392,7 +381,7 @@ read_node (struct node *np, vm_address_t buf) /* Files in fatfs depend on the directory that hold the file. */ np->dn->dirnode = dp; if (dp) - dp->references++; + refcounts_ref (&dp->refcounts, NULL); pthread_rwlock_rdlock (&np->dn->dirent_lock); @@ -627,7 +616,7 @@ diskfs_node_iterate (error_t (*fun)(struct node *)) /* We acquire a hard reference for node, but without using diskfs_nref. We do this so that diskfs_new_hardrefs will not get called. */ - node->references++; + refcounts_ref (&node->refcounts, NULL); } pthread_rwlock_unlock (&nodecache_lock); @@ -838,7 +827,7 @@ diskfs_alloc_node (struct node *dir, mode_t mode, struct node **node) /* FIXME: We know that readnode couldn't put this in. */ np->dn->dirnode = dir; - dir->references++; + refcounts_ref (&dir->refcounts, NULL); *node = np; return 0; |