Module Name: src Committed By: pooka Date: Sun Dec 13 20:52:36 UTC 2009
Modified Files: src/lib/libukfs: ukfs.c Log Message: Refcount ukfs_part. Otherwise it's not possible to call ukfs_mount() several times with only one ukfs_part_probe(). To generate a diff of this commit: cvs rdiff -u -r1.46 -r1.47 src/lib/libukfs/ukfs.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libukfs/ukfs.c diff -u src/lib/libukfs/ukfs.c:1.46 src/lib/libukfs/ukfs.c:1.47 --- src/lib/libukfs/ukfs.c:1.46 Sat Dec 12 00:46:04 2009 +++ src/lib/libukfs/ukfs.c Sun Dec 13 20:52:36 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: ukfs.c,v 1.46 2009/12/12 00:46:04 pooka Exp $ */ +/* $NetBSD: ukfs.c,v 1.47 2009/12/13 20:52:36 pooka Exp $ */ /* * Copyright (c) 2007, 2008, 2009 Antti Kantee. All Rights Reserved. @@ -164,6 +164,9 @@ } struct ukfs_part { + pthread_spinlock_t part_lck; + int part_refcount; + int part_type; char part_labelchar; off_t part_devoff; @@ -231,7 +234,14 @@ errno = ENOMEM; return -1; } + if (pthread_spin_init(&part->part_lck, PTHREAD_PROCESS_PRIVATE) == -1) { + error = errno; + free(part); + errno = error; + return -1; + } part->part_type = UKFS_PART_NONE; + part->part_refcount = 1; /* * Check for magic in pathname: @@ -338,7 +348,7 @@ part->part_devsize = val; part->part_type = UKFS_PART_OFFSET; } else { - free(part); + ukfs_part_release(part); part = ukfs_part_none; } @@ -395,6 +405,9 @@ { struct flock flarg; + if (part == ukfs_part_na) + return; + memset(&flarg, 0, sizeof(flarg)); flarg.l_type = F_UNLCK; flarg.l_whence = SEEK_SET; @@ -497,6 +510,9 @@ int mounted = 0; int regged = 0; + pthread_spin_lock(&part->part_lck); + part->part_refcount++; + pthread_spin_unlock(&part->part_lck); if (part != ukfs_part_na) { if ((rv = process_diskdevice(devpath, part, mntflags & MNT_RDONLY, &devfd)) != 0) @@ -621,7 +637,6 @@ rump_pub_lwp_release(rump_pub_lwp_curlwp()); } - ukfs_part_release(fs->ukfs_part); if (fs->ukfs_devpath) { rump_pub_etfs_remove(fs->ukfs_devpath); free(fs->ukfs_devpath); @@ -633,6 +648,7 @@ unlockdev(fs->ukfs_devfd, fs->ukfs_part); close(fs->ukfs_devfd); } + ukfs_part_release(fs->ukfs_part); free(fs); return 0; @@ -641,9 +657,17 @@ void ukfs_part_release(struct ukfs_part *part) { + int release; - if (part != ukfs_part_none && part != ukfs_part_na) - free(part); + if (part != ukfs_part_none && part != ukfs_part_na) { + pthread_spin_lock(&part->part_lck); + release = --part->part_refcount == 0; + pthread_spin_unlock(&part->part_lck); + if (release) { + pthread_spin_destroy(&part->part_lck); + free(part); + } + } } #define STDCALL(ukfs, thecall) \