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) \