Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libukfs Refcount ukfs_part. Otherwise it's not possible...



details:   https://anonhg.NetBSD.org/src/rev/e274181a7667
branches:  trunk
changeset: 749965:e274181a7667
user:      pooka <pooka%NetBSD.org@localhost>
date:      Sun Dec 13 20:52:36 2009 +0000

description:
Refcount ukfs_part.  Otherwise it's not possible to call ukfs_mount()
several times with only one ukfs_part_probe().

diffstat:

 lib/libukfs/ukfs.c |  34 +++++++++++++++++++++++++++++-----
 1 files changed, 29 insertions(+), 5 deletions(-)

diffs (99 lines):

diff -r 9fc560e73a00 -r e274181a7667 lib/libukfs/ukfs.c
--- a/lib/libukfs/ukfs.c        Sun Dec 13 20:46:10 2009 +0000
+++ b/lib/libukfs/ukfs.c        Sun Dec 13 20:52:36 2009 +0000
@@ -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)                                         \



Home | Main Index | Thread Index | Old Index