Date: Fri, 23 Dec 2011 00:07:56 +0100 From: Ed Schouten <ed@80386.nl> To: pjd@FreeBSD.org, freebsd-fs@FreeBSD.org Subject: Re: Changing refcount(9) to use a refcount_t Message-ID: <20111222230756.GW1771@hoeg.nl> In-Reply-To: <20111222214728.GV1771@hoeg.nl> References: <20111222214728.GV1771@hoeg.nl>
next in thread | previous in thread | raw e-mail | index | archive | help
--A2lxmwzFepEIu8KR Content-Type: multipart/mixed; boundary="XbyeA6tlA6gsyQxQ" Content-Disposition: inline --XbyeA6tlA6gsyQxQ Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable * Ed Schouten <ed@80386.nl>, 20111222 22:47: > Can any of you ZFS user please try the following patch? Whoops. It seems I forgot the ZFS source code is also built in userspace (libzpool). I have attached a new patch. Changes: - Remove the refcount.c file, as it has no use anymore. - Port the rrwlock code to not use refcount_t at all. It accesses internal members of the refcount_t and it seems we don't need to use atomics here anyway, as all operations on the counters are performed while holding the rr_lock. --=20 Ed Schouten <ed@80386.nl> WWW: http://80386.nl/ --XbyeA6tlA6gsyQxQ Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="refcount.diff" Content-Transfer-Encoding: quoted-printable Index: share/man/man9/refcount.9 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- share/man/man9/refcount.9 (revision 228798) +++ share/man/man9/refcount.9 (working copy) @@ -39,11 +39,11 @@ .In sys/param.h .In sys/refcount.h .Ft void -.Fn refcount_init "volatile u_int *count, u_int value" +.Fn refcount_init "refcount_t *count, u_int value" .Ft void -.Fn refcount_acquire "volatile u_int *count" +.Fn refcount_acquire "refcount_t *count" .Ft int -.Fn refcount_release "volatile u_int *count" +.Fn refcount_release "refcount_t *count" .Sh DESCRIPTION The .Nm Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/rrwlock.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/rrwlock.c (revision 2287= 98) +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/rrwlock.c (working copy) @@ -23,7 +23,6 @@ * Use is subject to license terms. */ =20 -#include <sys/refcount.h> #include <sys/rrwlock.h> =20 /* @@ -81,7 +80,7 @@ { rrw_node_t *rn; =20 - if (refcount_count(&rrl->rr_linked_rcount) =3D=3D 0) + if (rrl->rr_linked_rcount =3D=3D 0) return (NULL); =20 for (rn =3D tsd_get(rrw_tsd_key); rn !=3D NULL; rn =3D rn->rn_next) { @@ -115,7 +114,7 @@ rrw_node_t *rn; rrw_node_t *prev =3D NULL; =20 - if (refcount_count(&rrl->rr_linked_rcount) =3D=3D 0) + if (rrl->rr_linked_rcount =3D=3D 0) return (B_FALSE); =20 for (rn =3D tsd_get(rrw_tsd_key); rn !=3D NULL; rn =3D rn->rn_next) { @@ -138,8 +137,8 @@ mutex_init(&rrl->rr_lock, NULL, MUTEX_DEFAULT, NULL); cv_init(&rrl->rr_cv, NULL, CV_DEFAULT, NULL); rrl->rr_writer =3D NULL; - refcount_create(&rrl->rr_anon_rcount); - refcount_create(&rrl->rr_linked_rcount); + rrl->rr_anon_rcount =3D 0; + rrl->rr_linked_rcount =3D 0; rrl->rr_writer_wanted =3D B_FALSE; } =20 @@ -149,8 +148,8 @@ mutex_destroy(&rrl->rr_lock); cv_destroy(&rrl->rr_cv); ASSERT(rrl->rr_writer =3D=3D NULL); - refcount_destroy(&rrl->rr_anon_rcount); - refcount_destroy(&rrl->rr_linked_rcount); + rrl->rr_anon_rcount =3D 0; + rrl->rr_linked_rcount =3D 0; } =20 static void @@ -159,26 +158,26 @@ mutex_enter(&rrl->rr_lock); #if !defined(DEBUG) && defined(_KERNEL) if (!rrl->rr_writer && !rrl->rr_writer_wanted) { - rrl->rr_anon_rcount.rc_count++; + rrl->rr_anon_rcount++; mutex_exit(&rrl->rr_lock); return; } DTRACE_PROBE(zfs__rrwfastpath__rdmiss); #endif ASSERT(rrl->rr_writer !=3D curthread); - ASSERT(refcount_count(&rrl->rr_anon_rcount) >=3D 0); + ASSERT(rrl->rr_anon_rcount >=3D 0); =20 while (rrl->rr_writer || (rrl->rr_writer_wanted && - refcount_is_zero(&rrl->rr_anon_rcount) && + rrl->rr_anon_rcount =3D=3D 0 && rrn_find(rrl) =3D=3D NULL)) cv_wait(&rrl->rr_cv, &rrl->rr_lock); =20 if (rrl->rr_writer_wanted) { /* may or may not be a re-entrant enter */ rrn_add(rrl); - (void) refcount_add(&rrl->rr_linked_rcount, tag); + rrl->rr_linked_rcount++; } else { - (void) refcount_add(&rrl->rr_anon_rcount, tag); + rrl->rr_anon_rcount++; } ASSERT(rrl->rr_writer =3D=3D NULL); mutex_exit(&rrl->rr_lock); @@ -190,8 +189,8 @@ mutex_enter(&rrl->rr_lock); ASSERT(rrl->rr_writer !=3D curthread); =20 - while (refcount_count(&rrl->rr_anon_rcount) > 0 || - refcount_count(&rrl->rr_linked_rcount) > 0 || + while (rrl->rr_anon_rcount > 0 || + rrl->rr_linked_rcount > 0 || rrl->rr_writer !=3D NULL) { rrl->rr_writer_wanted =3D B_TRUE; cv_wait(&rrl->rr_cv, &rrl->rr_lock); @@ -224,22 +223,22 @@ } DTRACE_PROBE(zfs__rrwfastpath__exitmiss); #endif - ASSERT(!refcount_is_zero(&rrl->rr_anon_rcount) || - !refcount_is_zero(&rrl->rr_linked_rcount) || + ASSERT(rrl->rr_anon_rcount !=3D 0 || + rrl->rr_linked_rcount !=3D 0 || rrl->rr_writer !=3D NULL); =20 if (rrl->rr_writer =3D=3D NULL) { - int64_t count; + uint64_t count; if (rrn_find_and_remove(rrl)) - count =3D refcount_remove(&rrl->rr_linked_rcount, tag); + count =3D rrl->rr_linked_rcount--; else - count =3D refcount_remove(&rrl->rr_anon_rcount, tag); + count =3D rrl->rr_anon_rcount--; if (count =3D=3D 0) cv_broadcast(&rrl->rr_cv); } else { ASSERT(rrl->rr_writer =3D=3D curthread); - ASSERT(refcount_is_zero(&rrl->rr_anon_rcount) && - refcount_is_zero(&rrl->rr_linked_rcount)); + ASSERT(rrl->rr_anon_rcount =3D=3D 0 && + rrl->rr_linked_rcount =3D=3D 0); rrl->rr_writer =3D NULL; cv_broadcast(&rrl->rr_cv); } @@ -255,8 +254,8 @@ if (rw =3D=3D RW_WRITER) { held =3D (rrl->rr_writer =3D=3D curthread); } else { - held =3D (!refcount_is_zero(&rrl->rr_anon_rcount) || - !refcount_is_zero(&rrl->rr_linked_rcount)); + held =3D (rrl->rr_anon_rcount !=3D 0 || + rrl->rr_linked_rcount !=3D 0); } mutex_exit(&rrl->rr_lock); =20 Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/refcount.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/refcount.h (revision= 228798) +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/refcount.h (working = copy) @@ -31,10 +31,6 @@ #include <sys/list.h> #include <sys/zfs_context.h> =20 -#ifdef __cplusplus -extern "C" { -#endif - /* * If the reference is held only by the calling function and not any * particular object, use FTAG (which is a string) for the holder_tag. @@ -42,68 +38,21 @@ */ #define FTAG ((char *)__func__) =20 -#ifdef ZFS_DEBUG -typedef struct reference { - list_node_t ref_link; - void *ref_holder; - uint64_t ref_number; - uint8_t *ref_removed; -} reference_t; - -typedef struct refcount { - kmutex_t rc_mtx; - list_t rc_list; - list_t rc_removed; - int64_t rc_count; - int64_t rc_removed_count; -} refcount_t; - -/* Note: refcount_t must be initialized with refcount_create() */ - -void refcount_create(refcount_t *rc); -void refcount_destroy(refcount_t *rc); -void refcount_destroy_many(refcount_t *rc, uint64_t number); -int refcount_is_zero(refcount_t *rc); -int64_t refcount_count(refcount_t *rc); -int64_t refcount_add(refcount_t *rc, void *holder_tag); -int64_t refcount_remove(refcount_t *rc, void *holder_tag); -int64_t refcount_add_many(refcount_t *rc, uint64_t number, void *holder_ta= g); -int64_t refcount_remove_many(refcount_t *rc, uint64_t number, void *holder= _tag); -void refcount_transfer(refcount_t *dst, refcount_t *src); - -void refcount_sysinit(void); -void refcount_fini(void); - -#else /* ZFS_DEBUG */ - -typedef struct refcount { - uint64_t rc_count; -} refcount_t; - -#define refcount_create(rc) ((rc)->rc_count =3D 0) -#define refcount_destroy(rc) ((rc)->rc_count =3D 0) -#define refcount_destroy_many(rc, number) ((rc)->rc_count =3D 0) -#define refcount_is_zero(rc) ((rc)->rc_count =3D=3D 0) -#define refcount_count(rc) ((rc)->rc_count) -#define refcount_add(rc, holder) atomic_add_64_nv(&(rc)->rc_count, 1) -#define refcount_remove(rc, holder) atomic_add_64_nv(&(rc)->rc_count, -1) +#define refcount_create(rc) refcount_init(rc, 0) +#define refcount_destroy(rc) refcount_init(rc, 0) +#define refcount_destroy_many(rc, number) refcount_init(rc, 0) +#define refcount_is_zero(rc) ((*rc) =3D=3D 0) +#define refcount_count(rc) (uint64_t)(*rc) +#define refcount_add(rc, holder) refcount_add_many(rc, 1, holder) +#define refcount_remove(rc, holder) refcount_remove_many(rc, 1, holder) #define refcount_add_many(rc, number, holder) \ - atomic_add_64_nv(&(rc)->rc_count, number) + (uint64_t)(atomic_fetchadd_int(rc, number) + (number)) #define refcount_remove_many(rc, number, holder) \ - atomic_add_64_nv(&(rc)->rc_count, -number) -#define refcount_transfer(dst, src) { \ - uint64_t __tmp =3D (src)->rc_count; \ - atomic_add_64(&(src)->rc_count, -__tmp); \ - atomic_add_64(&(dst)->rc_count, __tmp); \ -} + (uint64_t)(atomic_fetchadd_int(rc, -(number)) - (number)) +#define refcount_transfer(dst, src) \ + atomic_add_int(dst, atomic_readandclear_int(src)) =20 #define refcount_sysinit() #define refcount_fini() =20 -#endif /* ZFS_DEBUG */ - -#ifdef __cplusplus -} -#endif - #endif /* _SYS_REFCOUNT_H */ Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/rrwlock.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/rrwlock.h (revision = 228798) +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/rrwlock.h (working c= opy) @@ -33,7 +33,6 @@ #endif =20 #include <sys/zfs_context.h> -#include <sys/refcount.h> =20 /* * A reader-writer lock implementation that allows re-entrant reads, but @@ -53,8 +52,8 @@ kmutex_t rr_lock; kcondvar_t rr_cv; kthread_t *rr_writer; - refcount_t rr_anon_rcount; - refcount_t rr_linked_rcount; + uint64_t rr_anon_rcount; + uint64_t rr_linked_rcount; boolean_t rr_writer_wanted; } rrwlock_t; =20 Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/refcount.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/refcount.c (revision 228= 798) +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/refcount.c (working copy) @@ -1,223 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights rese= rved. - */ - -#include <sys/zfs_context.h> -#include <sys/refcount.h> - -#ifdef ZFS_DEBUG - -#ifdef _KERNEL -int reference_tracking_enable =3D FALSE; /* runs out of memory too easily = */ -#else -int reference_tracking_enable =3D TRUE; -#endif -int reference_history =3D 4; /* tunable */ - -static kmem_cache_t *reference_cache; -static kmem_cache_t *reference_history_cache; - -void -refcount_sysinit(void) -{ - reference_cache =3D kmem_cache_create("reference_cache", - sizeof (reference_t), 0, NULL, NULL, NULL, NULL, NULL, 0); - - reference_history_cache =3D kmem_cache_create("reference_history_cache", - sizeof (uint64_t), 0, NULL, NULL, NULL, NULL, NULL, 0); -} - -void -refcount_fini(void) -{ - kmem_cache_destroy(reference_cache); - kmem_cache_destroy(reference_history_cache); -} - -void -refcount_create(refcount_t *rc) -{ - mutex_init(&rc->rc_mtx, NULL, MUTEX_DEFAULT, NULL); - list_create(&rc->rc_list, sizeof (reference_t), - offsetof(reference_t, ref_link)); - list_create(&rc->rc_removed, sizeof (reference_t), - offsetof(reference_t, ref_link)); - rc->rc_count =3D 0; - rc->rc_removed_count =3D 0; -} - -void -refcount_destroy_many(refcount_t *rc, uint64_t number) -{ - reference_t *ref; - - ASSERT(rc->rc_count =3D=3D number); - while (ref =3D list_head(&rc->rc_list)) { - list_remove(&rc->rc_list, ref); - kmem_cache_free(reference_cache, ref); - } - list_destroy(&rc->rc_list); - - while (ref =3D list_head(&rc->rc_removed)) { - list_remove(&rc->rc_removed, ref); - kmem_cache_free(reference_history_cache, ref->ref_removed); - kmem_cache_free(reference_cache, ref); - } - list_destroy(&rc->rc_removed); - mutex_destroy(&rc->rc_mtx); -} - -void -refcount_destroy(refcount_t *rc) -{ - refcount_destroy_many(rc, 0); -} - -int -refcount_is_zero(refcount_t *rc) -{ - ASSERT(rc->rc_count >=3D 0); - return (rc->rc_count =3D=3D 0); -} - -int64_t -refcount_count(refcount_t *rc) -{ - ASSERT(rc->rc_count >=3D 0); - return (rc->rc_count); -} - -int64_t -refcount_add_many(refcount_t *rc, uint64_t number, void *holder) -{ - reference_t *ref; - int64_t count; - - if (reference_tracking_enable) { - ref =3D kmem_cache_alloc(reference_cache, KM_SLEEP); - ref->ref_holder =3D holder; - ref->ref_number =3D number; - } - mutex_enter(&rc->rc_mtx); - ASSERT(rc->rc_count >=3D 0); - if (reference_tracking_enable) - list_insert_head(&rc->rc_list, ref); - rc->rc_count +=3D number; - count =3D rc->rc_count; - mutex_exit(&rc->rc_mtx); - - return (count); -} - -int64_t -refcount_add(refcount_t *rc, void *holder) -{ - return (refcount_add_many(rc, 1, holder)); -} - -int64_t -refcount_remove_many(refcount_t *rc, uint64_t number, void *holder) -{ - reference_t *ref; - int64_t count; - - mutex_enter(&rc->rc_mtx); - ASSERT(rc->rc_count >=3D number); - - if (!reference_tracking_enable) { - rc->rc_count -=3D number; - count =3D rc->rc_count; - mutex_exit(&rc->rc_mtx); - return (count); - } - - for (ref =3D list_head(&rc->rc_list); ref; - ref =3D list_next(&rc->rc_list, ref)) { - if (ref->ref_holder =3D=3D holder && ref->ref_number =3D=3D number) { - list_remove(&rc->rc_list, ref); - if (reference_history > 0) { - ref->ref_removed =3D - kmem_cache_alloc(reference_history_cache, - KM_SLEEP); - list_insert_head(&rc->rc_removed, ref); - rc->rc_removed_count++; - if (rc->rc_removed_count >=3D reference_history) { - ref =3D list_tail(&rc->rc_removed); - list_remove(&rc->rc_removed, ref); - kmem_cache_free(reference_history_cache, - ref->ref_removed); - kmem_cache_free(reference_cache, ref); - rc->rc_removed_count--; - } - } else { - kmem_cache_free(reference_cache, ref); - } - rc->rc_count -=3D number; - count =3D rc->rc_count; - mutex_exit(&rc->rc_mtx); - return (count); - } - } - panic("No such hold %p on refcount %llx", holder, - (u_longlong_t)(uintptr_t)rc); - return (-1); -} - -int64_t -refcount_remove(refcount_t *rc, void *holder) -{ - return (refcount_remove_many(rc, 1, holder)); -} - -void -refcount_transfer(refcount_t *dst, refcount_t *src) -{ - int64_t count, removed_count; - list_t list, removed; - - list_create(&list, sizeof (reference_t), - offsetof(reference_t, ref_link)); - list_create(&removed, sizeof (reference_t), - offsetof(reference_t, ref_link)); - - mutex_enter(&src->rc_mtx); - count =3D src->rc_count; - removed_count =3D src->rc_removed_count; - src->rc_count =3D 0; - src->rc_removed_count =3D 0; - list_move_tail(&list, &src->rc_list); - list_move_tail(&removed, &src->rc_removed); - mutex_exit(&src->rc_mtx); - - mutex_enter(&dst->rc_mtx); - dst->rc_count +=3D count; - dst->rc_removed_count +=3D removed_count; - list_move_tail(&dst->rc_list, &list); - list_move_tail(&dst->rc_removed, &removed); - mutex_exit(&dst->rc_mtx); - - list_destroy(&list); - list_destroy(&removed); -} - -#endif /* ZFS_DEBUG */ Index: sys/cddl/contrib/opensolaris/uts/common/Makefile.files =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- sys/cddl/contrib/opensolaris/uts/common/Makefile.files (revision 228798) +++ sys/cddl/contrib/opensolaris/uts/common/Makefile.files (working copy) @@ -55,7 +55,6 @@ gzip.o \ lzjb.o \ metaslab.o \ - refcount.o \ sa.o \ sha256.o \ spa.o \ Index: sys/sys/refcount.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- sys/sys/refcount.h (revision 228798) +++ sys/sys/refcount.h (working copy) @@ -40,22 +40,24 @@ #define KASSERT(exp, msg) /* */ #endif =20 +typedef volatile u_int refcount_t; + static __inline void -refcount_init(volatile u_int *count, u_int value) +refcount_init(refcount_t *count, u_int value) { =20 *count =3D value; } =20 static __inline void -refcount_acquire(volatile u_int *count) +refcount_acquire(refcount_t *count) { =20 atomic_add_acq_int(count, 1);=09 } =20 static __inline int -refcount_release(volatile u_int *count) +refcount_release(refcount_t *count) { u_int old; =20 --XbyeA6tlA6gsyQxQ-- --A2lxmwzFepEIu8KR Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (FreeBSD) iQIcBAEBAgAGBQJO87hMAAoJEG5e2P40kaK7QlsP/2IwTXHnvluHchYhqvRbWLfK U3wfk6PvmgoKMrXbnGTXuusTrg9I6fb1BtxkppVbe1U95G6gGZSwuejgeRqATRWV B2mDE+IOXRtOx159v7fqO16JHEDGNEHggMBo4WFI/g/YZXg8uX6MY5LC05Zwmj0L lPEX+SnNEUdeG977FM8MOIPxGghf02P+HXxux33/i2GFUV4gtB4CByVSOS50EGms YZXnhVJ+5MO6dxQkgg4ccc5ToRURKqL9i1uv6ziPlJQlLpH7dL4Bm4aECSPWbaKw StTGh9dg5zCQiMyQw6APPWmxzUoGYap7RDk/Vs7Wn39afevxUnDeATdkVXO2uq1X Io0W4v6yI1AkBxRsw+npPgRajTo5QxNAbZcdthDJJ17nrq4Pz9waKlKm1CRv9ibC Y9q6jj3qqLOoN55wQjTNyrqXSnh3/RRjej+rdyLZQEKDkajrpmojP8Y8zkDoh5Wn U6qgbqXKZmm+BVUJ1AMos+aXl03Khm+Eaq+lyl/W0b5w4Q33ic62REt3iXPiprF9 spohB0jF5izDZQttSooshfWddlwRwyGTMIsB6LhBvoqhQp53xMEmXZvHX5oi5kja vc6Itf9vVMPTLr+HTjnWRDy4XlMyiCpD0DXRAtFvsHRVjBbGEpD4MONMHoeShwRM stti4oTS9rlMjlJBhUtr =tHix -----END PGP SIGNATURE----- --A2lxmwzFepEIu8KR--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20111222230756.GW1771>