xref: /onnv-gate/usr/src/cmd/fs.d/cachefs/common/stats_create.c (revision 633:04519cb7de3b)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate /*
23*633Sgt29601  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
280Sstevel@tonic-gate 
290Sstevel@tonic-gate /*
300Sstevel@tonic-gate  *
310Sstevel@tonic-gate  *			stats_create.c
320Sstevel@tonic-gate  *
330Sstevel@tonic-gate  * Routines for the `clean interface' to cachefs statistics.
340Sstevel@tonic-gate  */
350Sstevel@tonic-gate 
360Sstevel@tonic-gate #include <stdarg.h>
370Sstevel@tonic-gate #include <libintl.h>
380Sstevel@tonic-gate #include <sys/types.h>
390Sstevel@tonic-gate #include <sys/stat.h>
400Sstevel@tonic-gate #include <assert.h>
410Sstevel@tonic-gate #include <sys/fs/cachefs_fs.h>
420Sstevel@tonic-gate #include <string.h>
430Sstevel@tonic-gate #include "stats.h"
440Sstevel@tonic-gate 
450Sstevel@tonic-gate void	*malloc(), *calloc();
460Sstevel@tonic-gate 
470Sstevel@tonic-gate /* forward declarations of statics */
480Sstevel@tonic-gate static stats_cookie_t *stats_create(char *);
490Sstevel@tonic-gate 
500Sstevel@tonic-gate static stats_cookie_t *
stats_create(char * progname)510Sstevel@tonic-gate stats_create(char *progname)
520Sstevel@tonic-gate {
530Sstevel@tonic-gate 	stats_cookie_t *rc;
540Sstevel@tonic-gate 
550Sstevel@tonic-gate 	if ((rc = (stats_cookie_t *)calloc(1, sizeof (*rc))) == NULL)
560Sstevel@tonic-gate 		goto out;
570Sstevel@tonic-gate 
580Sstevel@tonic-gate 	rc->st_magic = STATS_MAGIC;
590Sstevel@tonic-gate 	if (rc->st_progname = strrchr(progname, '/'))
600Sstevel@tonic-gate 		rc->st_progname++;
610Sstevel@tonic-gate 	else
620Sstevel@tonic-gate 		rc->st_progname = progname;
630Sstevel@tonic-gate 
640Sstevel@tonic-gate 	if ((rc->st_kstat_cookie = kstat_open()) == NULL) {
650Sstevel@tonic-gate 		stats_perror(rc, SE_KERNEL,
660Sstevel@tonic-gate 		    gettext("Cannot initialize kstats"));
670Sstevel@tonic-gate 		goto out;
680Sstevel@tonic-gate 	}
690Sstevel@tonic-gate 
700Sstevel@tonic-gate out:
710Sstevel@tonic-gate 	return (rc);
720Sstevel@tonic-gate }
730Sstevel@tonic-gate 
740Sstevel@tonic-gate stats_cookie_t *
stats_create_unbound(char * progname)750Sstevel@tonic-gate stats_create_unbound(char *progname)
760Sstevel@tonic-gate {
770Sstevel@tonic-gate 	stats_cookie_t *st;
780Sstevel@tonic-gate 
790Sstevel@tonic-gate 	if ((st = stats_create(progname)) == NULL)
800Sstevel@tonic-gate 		goto out;
810Sstevel@tonic-gate 
820Sstevel@tonic-gate 	st->st_flags |= ST_VALID;
830Sstevel@tonic-gate 
840Sstevel@tonic-gate out:
850Sstevel@tonic-gate 	return (st);
860Sstevel@tonic-gate }
870Sstevel@tonic-gate 
880Sstevel@tonic-gate stats_cookie_t *
stats_create_mountpath(char * mountpath,char * progname)890Sstevel@tonic-gate stats_create_mountpath(char *mountpath, char *progname)
900Sstevel@tonic-gate {
910Sstevel@tonic-gate 	stats_cookie_t *st;
920Sstevel@tonic-gate 	kstat_t *key;
930Sstevel@tonic-gate 	cachefs_kstat_key_t *k;
940Sstevel@tonic-gate 	dev_t dev;
950Sstevel@tonic-gate 	ino64_t ino;
960Sstevel@tonic-gate 	struct stat64 s;
970Sstevel@tonic-gate 	int i, n;
980Sstevel@tonic-gate 
990Sstevel@tonic-gate 	if ((st = stats_create(progname)) == NULL)
1000Sstevel@tonic-gate 		goto out;
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate 	if ((key = kstat_lookup(st->st_kstat_cookie, "cachefs", 0, "key"))
1030Sstevel@tonic-gate 	    == NULL) {
1040Sstevel@tonic-gate 		stats_perror(st, SE_KERNEL,
1050Sstevel@tonic-gate 		    gettext("Cannot lookup cachefs key kstat"));
1060Sstevel@tonic-gate 		goto out;
1070Sstevel@tonic-gate 	}
1080Sstevel@tonic-gate 	if (kstat_read(st->st_kstat_cookie, key, NULL) < 0) {
1090Sstevel@tonic-gate 		stats_perror(st, SE_KERNEL,
1100Sstevel@tonic-gate 		    gettext("Cannot read cachefs key kstat"));
1110Sstevel@tonic-gate 		goto out;
1120Sstevel@tonic-gate 	}
1130Sstevel@tonic-gate 	k = (cachefs_kstat_key_t *)key->ks_data;
1140Sstevel@tonic-gate 	n = key->ks_ndata;
1150Sstevel@tonic-gate 
1160Sstevel@tonic-gate 	if (stat64(mountpath, &s) != 0) {
1170Sstevel@tonic-gate 		stats_perror(st, SE_FILE,
1180Sstevel@tonic-gate 		    gettext("Cannot stat %s"), mountpath);
1190Sstevel@tonic-gate 		goto out;
1200Sstevel@tonic-gate 	}
1210Sstevel@tonic-gate 	ino = s.st_ino;
1220Sstevel@tonic-gate 	dev = s.st_dev;
1230Sstevel@tonic-gate 
1240Sstevel@tonic-gate 	for (i = 0; i < n; i++) {
1250Sstevel@tonic-gate 		k[i].ks_mountpoint += (uintptr_t)k;
1260Sstevel@tonic-gate 		k[i].ks_backfs += (uintptr_t)k;
1270Sstevel@tonic-gate 		k[i].ks_cachedir += (uintptr_t)k;
1280Sstevel@tonic-gate 		k[i].ks_cacheid += (uintptr_t)k;
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate 		if (! k[i].ks_mounted)
1310Sstevel@tonic-gate 			continue;
1320Sstevel@tonic-gate 
133*633Sgt29601 		if ((stat64((char *)(uintptr_t)k[i].ks_mountpoint, &s) == 0) &&
1340Sstevel@tonic-gate 		    (s.st_dev == dev) &&
1350Sstevel@tonic-gate 		    (s.st_ino == ino))
1360Sstevel@tonic-gate 			break;
1370Sstevel@tonic-gate 	}
1380Sstevel@tonic-gate 
1390Sstevel@tonic-gate 	if (i >= n) {
1400Sstevel@tonic-gate 		stats_perror(st, SE_FILE,
1410Sstevel@tonic-gate 		    gettext("%s: not a cachefs mountpoint"), mountpath);
1420Sstevel@tonic-gate 		goto out;
1430Sstevel@tonic-gate 	}
1440Sstevel@tonic-gate 
1450Sstevel@tonic-gate 	st->st_fsid = k[i].ks_id;
1460Sstevel@tonic-gate 
1470Sstevel@tonic-gate 	st->st_flags |= ST_VALID | ST_BOUND;
1480Sstevel@tonic-gate 
1490Sstevel@tonic-gate out:
1500Sstevel@tonic-gate 	return (st);
1510Sstevel@tonic-gate }
1520Sstevel@tonic-gate 
1530Sstevel@tonic-gate /*
1540Sstevel@tonic-gate  * stats_next - bind the cookie to the next valid cachefs mount.
1550Sstevel@tonic-gate  *
1560Sstevel@tonic-gate  * returns cachefs_kstat_key_t *, which gives all the info you need.
1570Sstevel@tonic-gate  * returns NULL if we're out of mounts, or if an error occured.
1580Sstevel@tonic-gate  * returns malloc()ed data, which the client has to free() itself.
1590Sstevel@tonic-gate  */
1600Sstevel@tonic-gate 
1610Sstevel@tonic-gate cachefs_kstat_key_t *
stats_next(stats_cookie_t * st)1620Sstevel@tonic-gate stats_next(stats_cookie_t *st)
1630Sstevel@tonic-gate {
1640Sstevel@tonic-gate 	kstat_t *key;
1650Sstevel@tonic-gate 	cachefs_kstat_key_t *k, *prc = NULL, *rc = NULL;
1660Sstevel@tonic-gate 	int i, n;
1670Sstevel@tonic-gate 
1680Sstevel@tonic-gate 	assert(stats_good(st));
1690Sstevel@tonic-gate 
1700Sstevel@tonic-gate 	if (((key = kstat_lookup(st->st_kstat_cookie, "cachefs", 0,
1710Sstevel@tonic-gate 	    "key")) == NULL) ||
1720Sstevel@tonic-gate 	    (kstat_read(st->st_kstat_cookie, key, NULL) < 0)) {
1730Sstevel@tonic-gate 		stats_perror(st, SE_KERNEL,
1740Sstevel@tonic-gate 		    gettext("Cannot get cachefs key kstat"));
1750Sstevel@tonic-gate 		goto out;
1760Sstevel@tonic-gate 	}
1770Sstevel@tonic-gate 	k = (cachefs_kstat_key_t *)key->ks_data;
1780Sstevel@tonic-gate 	n = key->ks_ndata;
1790Sstevel@tonic-gate 
1800Sstevel@tonic-gate 	if (st->st_flags & ST_BOUND) {
1810Sstevel@tonic-gate 		for (i = 0; i < n; i++)
1820Sstevel@tonic-gate 			if (st->st_fsid == k[i].ks_id)
1830Sstevel@tonic-gate 				break;
1840Sstevel@tonic-gate 		++i;
1850Sstevel@tonic-gate 		if (i < n) {
1860Sstevel@tonic-gate 			prc = k + i;
1870Sstevel@tonic-gate 			st->st_fsid = k[i].ks_id;
1880Sstevel@tonic-gate 		} else
1890Sstevel@tonic-gate 			st->st_flags &= ~ST_BOUND;
1900Sstevel@tonic-gate 	} else if (n > 0) {
1910Sstevel@tonic-gate 		st->st_fsid = k[0].ks_id;
1920Sstevel@tonic-gate 		st->st_flags |= ST_BOUND;
1930Sstevel@tonic-gate 		prc = k;
1940Sstevel@tonic-gate 	}
1950Sstevel@tonic-gate 
1960Sstevel@tonic-gate out:
1970Sstevel@tonic-gate 	if (prc != NULL) {
1980Sstevel@tonic-gate 		char *s;
1990Sstevel@tonic-gate 		int size;
2000Sstevel@tonic-gate 
2010Sstevel@tonic-gate 		prc->ks_mountpoint += (uintptr_t)k;
2020Sstevel@tonic-gate 		prc->ks_backfs += (uintptr_t)k;
2030Sstevel@tonic-gate 		prc->ks_cachedir += (uintptr_t)k;
2040Sstevel@tonic-gate 		prc->ks_cacheid += (uintptr_t)k;
2050Sstevel@tonic-gate 
2060Sstevel@tonic-gate 		size = sizeof (*rc);
207*633Sgt29601 		size += strlen((char *)(uintptr_t)prc->ks_mountpoint) + 1;
208*633Sgt29601 		size += strlen((char *)(uintptr_t)prc->ks_backfs) + 1;
209*633Sgt29601 		size += strlen((char *)(uintptr_t)prc->ks_cachedir) + 1;
210*633Sgt29601 		size += strlen((char *)(uintptr_t)prc->ks_cacheid) + 1;
2110Sstevel@tonic-gate 
2120Sstevel@tonic-gate 		if ((rc = (cachefs_kstat_key_t *)
2130Sstevel@tonic-gate 		    malloc(size)) == NULL) {
2140Sstevel@tonic-gate 			stats_perror(st, SE_NOMEM,
2150Sstevel@tonic-gate 			    gettext("Cannot malloc return code"));
2160Sstevel@tonic-gate 		} else {
2170Sstevel@tonic-gate 			memcpy(rc, prc, sizeof (*rc));
2180Sstevel@tonic-gate 			s = (char *)((uintptr_t)rc + sizeof (*rc));
2190Sstevel@tonic-gate 
220*633Sgt29601 			(void) strcpy(s, (char *)(uintptr_t)prc->ks_mountpoint);
2210Sstevel@tonic-gate 			rc->ks_mountpoint = (uintptr_t)s;
2220Sstevel@tonic-gate 			s += strlen(s) + 1;
223*633Sgt29601 			(void) strcpy(s, (char *)(uintptr_t)prc->ks_backfs);
2240Sstevel@tonic-gate 			rc->ks_backfs = (uintptr_t)s;
2250Sstevel@tonic-gate 			s += strlen(s) + 1;
226*633Sgt29601 			(void) strcpy(s, (char *)(uintptr_t)prc->ks_cachedir);
2270Sstevel@tonic-gate 			rc->ks_cachedir = (uintptr_t)s;
2280Sstevel@tonic-gate 			s += strlen(s) + 1;
229*633Sgt29601 			(void) strcpy(s, (char *)(uintptr_t)prc->ks_cacheid);
2300Sstevel@tonic-gate 			rc->ks_cacheid = (uintptr_t)s;
2310Sstevel@tonic-gate 		}
2320Sstevel@tonic-gate 	}
2330Sstevel@tonic-gate 
2340Sstevel@tonic-gate 	return (rc);
2350Sstevel@tonic-gate }
2360Sstevel@tonic-gate 
2370Sstevel@tonic-gate cachefs_kstat_key_t *
stats_getkey(stats_cookie_t * st)2380Sstevel@tonic-gate stats_getkey(stats_cookie_t *st)
2390Sstevel@tonic-gate {
2400Sstevel@tonic-gate 	kstat_t *ksp;
2410Sstevel@tonic-gate 	cachefs_kstat_key_t *k, *key, *rc = NULL;
2420Sstevel@tonic-gate 	int size;
2430Sstevel@tonic-gate 	char *s;
2440Sstevel@tonic-gate 
2450Sstevel@tonic-gate 	assert(stats_good(st));
2460Sstevel@tonic-gate 	assert(st->st_flags & ST_BOUND);
2470Sstevel@tonic-gate 
2480Sstevel@tonic-gate 	if (((ksp = kstat_lookup(st->st_kstat_cookie, "cachefs", 0,
2490Sstevel@tonic-gate 	    "key")) == NULL) ||
2500Sstevel@tonic-gate 	    (kstat_read(st->st_kstat_cookie, ksp, NULL) < 0)) {
2510Sstevel@tonic-gate 		stats_perror(st, SE_KERNEL,
2520Sstevel@tonic-gate 		    gettext("Cannot get cachefs key kstat"));
2530Sstevel@tonic-gate 		goto out;
2540Sstevel@tonic-gate 	}
2550Sstevel@tonic-gate 	key = (cachefs_kstat_key_t *)ksp->ks_data;
2560Sstevel@tonic-gate 	k = key + st->st_fsid - 1;
2570Sstevel@tonic-gate 	k->ks_mountpoint += (uintptr_t)key;
2580Sstevel@tonic-gate 	k->ks_backfs += (uintptr_t)key;
2590Sstevel@tonic-gate 	k->ks_cachedir += (uintptr_t)key;
2600Sstevel@tonic-gate 	k->ks_cacheid += (uintptr_t)key;
2610Sstevel@tonic-gate 	size = sizeof (*rc);
262*633Sgt29601 	size += strlen((char *)(uintptr_t)k->ks_mountpoint) + 1;
263*633Sgt29601 	size += strlen((char *)(uintptr_t)k->ks_backfs) + 1;
264*633Sgt29601 	size += strlen((char *)(uintptr_t)k->ks_cachedir) + 1;
265*633Sgt29601 	size += strlen((char *)(uintptr_t)k->ks_cacheid) + 1;
2660Sstevel@tonic-gate 
2670Sstevel@tonic-gate 	if ((rc = (cachefs_kstat_key_t *)malloc(size)) == NULL)
2680Sstevel@tonic-gate 		stats_perror(st, SE_NOMEM,
2690Sstevel@tonic-gate 		    gettext("Cannot malloc return code"));
2700Sstevel@tonic-gate 	else {
2710Sstevel@tonic-gate 		memcpy(rc, k, sizeof (*rc));
2720Sstevel@tonic-gate 		s = (char *)((uintptr_t)rc + sizeof (*rc));
2730Sstevel@tonic-gate 
274*633Sgt29601 		(void) strcpy(s, (char *)(uintptr_t)k->ks_mountpoint);
2750Sstevel@tonic-gate 		rc->ks_mountpoint = (uintptr_t)s;
2760Sstevel@tonic-gate 		s += strlen(s) + 1;
277*633Sgt29601 		(void) strcpy(s, (char *)(uintptr_t)k->ks_backfs);
2780Sstevel@tonic-gate 		rc->ks_backfs = (uintptr_t)s;
2790Sstevel@tonic-gate 		s += strlen(s) + 1;
280*633Sgt29601 		(void) strcpy(s, (char *)(uintptr_t)k->ks_cachedir);
2810Sstevel@tonic-gate 		rc->ks_cachedir = (uintptr_t)s;
2820Sstevel@tonic-gate 		s += strlen(s) + 1;
283*633Sgt29601 		(void) strcpy(s, (char *)(uintptr_t)k->ks_cacheid);
2840Sstevel@tonic-gate 		rc->ks_cacheid = (uintptr_t)s;
2850Sstevel@tonic-gate 		s += strlen(s) + 1;
2860Sstevel@tonic-gate 	}
2870Sstevel@tonic-gate 
2880Sstevel@tonic-gate 	assert(rc->ks_id == st->st_fsid);
2890Sstevel@tonic-gate 
2900Sstevel@tonic-gate out:
2910Sstevel@tonic-gate 	return (rc);
2920Sstevel@tonic-gate }
2930Sstevel@tonic-gate 
2940Sstevel@tonic-gate void
stats_destroy(stats_cookie_t * st)2950Sstevel@tonic-gate stats_destroy(stats_cookie_t *st)
2960Sstevel@tonic-gate {
2970Sstevel@tonic-gate 	void free();
2980Sstevel@tonic-gate 
2990Sstevel@tonic-gate 	if (st == NULL)
3000Sstevel@tonic-gate 		return;
3010Sstevel@tonic-gate 
3020Sstevel@tonic-gate 	if (st->st_kstat_cookie != NULL)
3030Sstevel@tonic-gate 		kstat_close(st->st_kstat_cookie);
3040Sstevel@tonic-gate 	if (st->st_logxdr.x_ops != NULL)
3050Sstevel@tonic-gate 		xdr_destroy(&st->st_logxdr);
3060Sstevel@tonic-gate 	if ((st->st_logstream != NULL) && (st->st_flags & ST_LFOPEN))
3070Sstevel@tonic-gate 		(void) fclose(st->st_logstream);
3080Sstevel@tonic-gate 
3090Sstevel@tonic-gate 	/*
3100Sstevel@tonic-gate 	 * we don't want to depend on dbm (or stats_dbm), so we don't
3110Sstevel@tonic-gate 	 * do a stats_dbm_close.  we do try to require the client to
3120Sstevel@tonic-gate 	 * have done it, via an assert(), however.
3130Sstevel@tonic-gate 	 */
3140Sstevel@tonic-gate 
3150Sstevel@tonic-gate 	assert(! (st->st_flags & ST_DBMOPEN));
3160Sstevel@tonic-gate 
3170Sstevel@tonic-gate 	st->st_magic++;
3180Sstevel@tonic-gate 
3190Sstevel@tonic-gate 	free(st);
3200Sstevel@tonic-gate }
3210Sstevel@tonic-gate 
3220Sstevel@tonic-gate int
stats_good(stats_cookie_t * st)3230Sstevel@tonic-gate stats_good(stats_cookie_t *st)
3240Sstevel@tonic-gate {
3250Sstevel@tonic-gate 	if (st == NULL)
3260Sstevel@tonic-gate 		return (0);
3270Sstevel@tonic-gate 	if (st->st_magic != STATS_MAGIC)
3280Sstevel@tonic-gate 		return (0);
3290Sstevel@tonic-gate 	if (! (st->st_flags & ST_VALID))
3300Sstevel@tonic-gate 		return (0);
3310Sstevel@tonic-gate 
3320Sstevel@tonic-gate 	return (1);
3330Sstevel@tonic-gate }
3340Sstevel@tonic-gate 
3350Sstevel@tonic-gate void
3360Sstevel@tonic-gate /*PRINTFLIKE3*/
stats_perror(stats_cookie_t * st,int Errno,char * fmt,...)3370Sstevel@tonic-gate stats_perror(stats_cookie_t *st, int Errno, char *fmt, ...)
3380Sstevel@tonic-gate {
3390Sstevel@tonic-gate 
3400Sstevel@tonic-gate 	va_list ap;
3410Sstevel@tonic-gate 
3420Sstevel@tonic-gate 	assert(st != NULL);
3430Sstevel@tonic-gate 	assert(st->st_magic == STATS_MAGIC);
3440Sstevel@tonic-gate 
3450Sstevel@tonic-gate 	va_start(ap, fmt);
3460Sstevel@tonic-gate 	(void) vsnprintf(st->st_errorstr, sizeof (st->st_errorstr), fmt, ap);
3470Sstevel@tonic-gate 	va_end(ap);
3480Sstevel@tonic-gate 
3490Sstevel@tonic-gate 	st->st_errno = Errno;
3500Sstevel@tonic-gate 
3510Sstevel@tonic-gate 	st->st_flags |= ST_ERROR;
3520Sstevel@tonic-gate }
3530Sstevel@tonic-gate 
3540Sstevel@tonic-gate char *
stats_errorstr(stats_cookie_t * st)3550Sstevel@tonic-gate stats_errorstr(stats_cookie_t *st)
3560Sstevel@tonic-gate {
3570Sstevel@tonic-gate 	assert(st != NULL);
3580Sstevel@tonic-gate 	assert(st->st_magic == STATS_MAGIC);
3590Sstevel@tonic-gate 
3600Sstevel@tonic-gate 	return (st->st_errorstr);
3610Sstevel@tonic-gate }
3620Sstevel@tonic-gate 
3630Sstevel@tonic-gate int
stats_errno(stats_cookie_t * st)3640Sstevel@tonic-gate stats_errno(stats_cookie_t *st)
3650Sstevel@tonic-gate {
3660Sstevel@tonic-gate 	assert(st != NULL);
3670Sstevel@tonic-gate 	assert(st->st_magic == STATS_MAGIC);
3680Sstevel@tonic-gate 
3690Sstevel@tonic-gate 	return (st->st_errno);
3700Sstevel@tonic-gate }
3710Sstevel@tonic-gate 
3720Sstevel@tonic-gate int
stats_inerror(stats_cookie_t * st)3730Sstevel@tonic-gate stats_inerror(stats_cookie_t *st)
3740Sstevel@tonic-gate {
3750Sstevel@tonic-gate 	assert(st != NULL);
3760Sstevel@tonic-gate 	assert(st->st_magic == STATS_MAGIC);
3770Sstevel@tonic-gate 
3780Sstevel@tonic-gate 	return (st->st_flags & ST_ERROR);
3790Sstevel@tonic-gate }
380