xref: /onnv-gate/usr/src/cmd/filebench/common/fb_localfs.c (revision 9513:5dc53d16bc1b)
18615SAndrew.W.Wilson@sun.com /*
28615SAndrew.W.Wilson@sun.com  * CDDL HEADER START
38615SAndrew.W.Wilson@sun.com  *
48615SAndrew.W.Wilson@sun.com  * The contents of this file are subject to the terms of the
58615SAndrew.W.Wilson@sun.com  * Common Development and Distribution License (the "License").
68615SAndrew.W.Wilson@sun.com  * You may not use this file except in compliance with the License.
78615SAndrew.W.Wilson@sun.com  *
88615SAndrew.W.Wilson@sun.com  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
98615SAndrew.W.Wilson@sun.com  * or http://www.opensolaris.org/os/licensing.
108615SAndrew.W.Wilson@sun.com  * See the License for the specific language governing permissions
118615SAndrew.W.Wilson@sun.com  * and limitations under the License.
128615SAndrew.W.Wilson@sun.com  *
138615SAndrew.W.Wilson@sun.com  * When distributing Covered Code, include this CDDL HEADER in each
148615SAndrew.W.Wilson@sun.com  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
158615SAndrew.W.Wilson@sun.com  * If applicable, add the following below this CDDL HEADER, with the
168615SAndrew.W.Wilson@sun.com  * fields enclosed by brackets "[]" replaced with your own identifying
178615SAndrew.W.Wilson@sun.com  * information: Portions Copyright [yyyy] [name of copyright owner]
188615SAndrew.W.Wilson@sun.com  *
198615SAndrew.W.Wilson@sun.com  * CDDL HEADER END
208615SAndrew.W.Wilson@sun.com  */
218615SAndrew.W.Wilson@sun.com /*
228615SAndrew.W.Wilson@sun.com  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
238615SAndrew.W.Wilson@sun.com  * Use is subject to license terms.
248615SAndrew.W.Wilson@sun.com  *
258615SAndrew.W.Wilson@sun.com  * Portions Copyright 2008 Denis Cheng
268615SAndrew.W.Wilson@sun.com  */
278615SAndrew.W.Wilson@sun.com 
288615SAndrew.W.Wilson@sun.com #include "config.h"
298615SAndrew.W.Wilson@sun.com #include "filebench.h"
308615SAndrew.W.Wilson@sun.com #include "flowop.h"
318615SAndrew.W.Wilson@sun.com #include "threadflow.h" /* For aiolist definition */
328615SAndrew.W.Wilson@sun.com 
338615SAndrew.W.Wilson@sun.com #ifndef HAVE_OFF64_T
348615SAndrew.W.Wilson@sun.com /*
358615SAndrew.W.Wilson@sun.com  * We are probably on linux.
368615SAndrew.W.Wilson@sun.com  * According to http://www.suse.de/~aj/linux_lfs.html, defining the
378615SAndrew.W.Wilson@sun.com  * above, automatically changes type of off_t to off64_t. so let
388615SAndrew.W.Wilson@sun.com  * us use only off_t as off64_t is not defined
398615SAndrew.W.Wilson@sun.com  */
40*9513SAndrew.W.Wilson@sun.com #define	off64_t off_t
418615SAndrew.W.Wilson@sun.com #endif /* HAVE_OFF64_T */
428615SAndrew.W.Wilson@sun.com 
438615SAndrew.W.Wilson@sun.com #include <fcntl.h>
448615SAndrew.W.Wilson@sun.com #include <stdio.h>
458615SAndrew.W.Wilson@sun.com #include <stdlib.h>
468615SAndrew.W.Wilson@sun.com #include <unistd.h>
478615SAndrew.W.Wilson@sun.com #include <libgen.h>
488615SAndrew.W.Wilson@sun.com #include <sys/mman.h>
498615SAndrew.W.Wilson@sun.com #include <sys/stat.h>
508615SAndrew.W.Wilson@sun.com #include <sys/types.h>
518615SAndrew.W.Wilson@sun.com #include <sys/param.h>
528615SAndrew.W.Wilson@sun.com #include <sys/resource.h>
538615SAndrew.W.Wilson@sun.com 
548615SAndrew.W.Wilson@sun.com #include "filebench.h"
558615SAndrew.W.Wilson@sun.com #include "fsplug.h"
568615SAndrew.W.Wilson@sun.com 
578615SAndrew.W.Wilson@sun.com #ifdef HAVE_AIO
588615SAndrew.W.Wilson@sun.com #include <aio.h>
598615SAndrew.W.Wilson@sun.com #endif /* HAVE_AIO */
608615SAndrew.W.Wilson@sun.com 
618615SAndrew.W.Wilson@sun.com #ifdef HAVE_LIBAIO_H
628615SAndrew.W.Wilson@sun.com #include <libaio.h>
638615SAndrew.W.Wilson@sun.com #endif /* HAVE_LIBAIO_H */
648615SAndrew.W.Wilson@sun.com 
658615SAndrew.W.Wilson@sun.com #ifndef HAVE_AIOCB64_T
668615SAndrew.W.Wilson@sun.com #define	aiocb64 aiocb
678615SAndrew.W.Wilson@sun.com #endif /* HAVE_AIOCB64_T */
688615SAndrew.W.Wilson@sun.com 
698615SAndrew.W.Wilson@sun.com /*
708615SAndrew.W.Wilson@sun.com  * These routines implement local file access. They are placed into a
718615SAndrew.W.Wilson@sun.com  * vector of functions that are called by all I/O operations in fileset.c
728615SAndrew.W.Wilson@sun.com  * and flowop_library.c. This represents the default file system plug-in,
738615SAndrew.W.Wilson@sun.com  * and may be replaced by vectors for other file system plug-ins.
748615SAndrew.W.Wilson@sun.com  */
758615SAndrew.W.Wilson@sun.com 
768615SAndrew.W.Wilson@sun.com static int fb_lfs_freemem(fb_fdesc_t *fd, off64_t size);
778615SAndrew.W.Wilson@sun.com static int fb_lfs_open(fb_fdesc_t *, char *, int, int);
788615SAndrew.W.Wilson@sun.com static int fb_lfs_pread(fb_fdesc_t *, caddr_t, fbint_t, off64_t);
798615SAndrew.W.Wilson@sun.com static int fb_lfs_read(fb_fdesc_t *, caddr_t, fbint_t);
808615SAndrew.W.Wilson@sun.com static int fb_lfs_pwrite(fb_fdesc_t *, caddr_t, fbint_t, off64_t);
818615SAndrew.W.Wilson@sun.com static int fb_lfs_write(fb_fdesc_t *, caddr_t, fbint_t);
828615SAndrew.W.Wilson@sun.com static int fb_lfs_lseek(fb_fdesc_t *, off64_t, int);
838615SAndrew.W.Wilson@sun.com static int fb_lfs_truncate(fb_fdesc_t *, off64_t);
848615SAndrew.W.Wilson@sun.com static int fb_lfs_rename(const char *, const char *);
858615SAndrew.W.Wilson@sun.com static int fb_lfs_close(fb_fdesc_t *);
868615SAndrew.W.Wilson@sun.com static int fb_lfs_link(const char *, const char *);
878615SAndrew.W.Wilson@sun.com static int fb_lfs_symlink(const char *, const char *);
888615SAndrew.W.Wilson@sun.com static int fb_lfs_unlink(char *);
898615SAndrew.W.Wilson@sun.com static ssize_t fb_lfs_readlink(const char *, char *, size_t);
908615SAndrew.W.Wilson@sun.com static int fb_lfs_mkdir(char *, int);
918615SAndrew.W.Wilson@sun.com static int fb_lfs_rmdir(char *);
928615SAndrew.W.Wilson@sun.com static DIR *fb_lfs_opendir(char *);
938615SAndrew.W.Wilson@sun.com static struct dirent *fb_lfs_readdir(DIR *);
948615SAndrew.W.Wilson@sun.com static int fb_lfs_closedir(DIR *);
958615SAndrew.W.Wilson@sun.com static int fb_lfs_fsync(fb_fdesc_t *);
968615SAndrew.W.Wilson@sun.com static int fb_lfs_stat(char *, struct stat64 *);
978615SAndrew.W.Wilson@sun.com static int fb_lfs_fstat(fb_fdesc_t *, struct stat64 *);
988615SAndrew.W.Wilson@sun.com static int fb_lfs_access(const char *, int);
999356SAndrew.W.Wilson@sun.com static void fb_lfs_recur_rm(char *);
1008615SAndrew.W.Wilson@sun.com 
1018615SAndrew.W.Wilson@sun.com static fsplug_func_t fb_lfs_funcs =
1028615SAndrew.W.Wilson@sun.com {
1038615SAndrew.W.Wilson@sun.com 	"locfs",
1048615SAndrew.W.Wilson@sun.com 	fb_lfs_freemem,		/* flush page cache */
1058615SAndrew.W.Wilson@sun.com 	fb_lfs_open,		/* open */
1068615SAndrew.W.Wilson@sun.com 	fb_lfs_pread,		/* pread */
1078615SAndrew.W.Wilson@sun.com 	fb_lfs_read,		/* read */
1088615SAndrew.W.Wilson@sun.com 	fb_lfs_pwrite,		/* pwrite */
1098615SAndrew.W.Wilson@sun.com 	fb_lfs_write,		/* write */
1108615SAndrew.W.Wilson@sun.com 	fb_lfs_lseek,		/* lseek */
1118615SAndrew.W.Wilson@sun.com 	fb_lfs_truncate,	/* ftruncate */
1128615SAndrew.W.Wilson@sun.com 	fb_lfs_rename,		/* rename */
1138615SAndrew.W.Wilson@sun.com 	fb_lfs_close,		/* close */
1148615SAndrew.W.Wilson@sun.com 	fb_lfs_link,		/* link */
1158615SAndrew.W.Wilson@sun.com 	fb_lfs_symlink,		/* symlink */
1168615SAndrew.W.Wilson@sun.com 	fb_lfs_unlink,		/* unlink */
1178615SAndrew.W.Wilson@sun.com 	fb_lfs_readlink,	/* readlink */
1188615SAndrew.W.Wilson@sun.com 	fb_lfs_mkdir,		/* mkdir */
1198615SAndrew.W.Wilson@sun.com 	fb_lfs_rmdir,		/* rmdir */
1208615SAndrew.W.Wilson@sun.com 	fb_lfs_opendir,		/* opendir */
1218615SAndrew.W.Wilson@sun.com 	fb_lfs_readdir,		/* readdir */
1228615SAndrew.W.Wilson@sun.com 	fb_lfs_closedir,	/* closedir */
1238615SAndrew.W.Wilson@sun.com 	fb_lfs_fsync,		/* fsync */
1248615SAndrew.W.Wilson@sun.com 	fb_lfs_stat,		/* stat */
1258615SAndrew.W.Wilson@sun.com 	fb_lfs_fstat,		/* fstat */
1269356SAndrew.W.Wilson@sun.com 	fb_lfs_access,		/* access */
1279356SAndrew.W.Wilson@sun.com 	fb_lfs_recur_rm		/* recursive rm */
1288615SAndrew.W.Wilson@sun.com };
1298615SAndrew.W.Wilson@sun.com 
1308615SAndrew.W.Wilson@sun.com #ifdef HAVE_AIO
1318615SAndrew.W.Wilson@sun.com /*
1328615SAndrew.W.Wilson@sun.com  * Local file system asynchronous IO flowops are in this module, as
1338615SAndrew.W.Wilson@sun.com  * they have a number of local file system specific features.
1348615SAndrew.W.Wilson@sun.com  */
1358615SAndrew.W.Wilson@sun.com static int fb_lfsflow_aiowrite(threadflow_t *threadflow, flowop_t *flowop);
1368615SAndrew.W.Wilson@sun.com static int fb_lfsflow_aiowait(threadflow_t *threadflow, flowop_t *flowop);
1378615SAndrew.W.Wilson@sun.com 
1388615SAndrew.W.Wilson@sun.com static flowop_proto_t fb_lfsflow_funcs[] = {
1398615SAndrew.W.Wilson@sun.com 	FLOW_TYPE_AIO, FLOW_ATTR_WRITE, "aiowrite", flowop_init_generic,
1408615SAndrew.W.Wilson@sun.com 	fb_lfsflow_aiowrite, flowop_destruct_generic,
1418615SAndrew.W.Wilson@sun.com 	FLOW_TYPE_AIO, 0, "aiowait", flowop_init_generic,
1428615SAndrew.W.Wilson@sun.com 	fb_lfsflow_aiowait, flowop_destruct_generic
1438615SAndrew.W.Wilson@sun.com };
1448615SAndrew.W.Wilson@sun.com 
1458615SAndrew.W.Wilson@sun.com #endif /* HAVE_AIO */
1468615SAndrew.W.Wilson@sun.com 
1478615SAndrew.W.Wilson@sun.com /*
1488615SAndrew.W.Wilson@sun.com  * Initialize this processes I/O functions vector to point to
1498615SAndrew.W.Wilson@sun.com  * the vector of local file system I/O functions
1508615SAndrew.W.Wilson@sun.com  */
1518615SAndrew.W.Wilson@sun.com void
fb_lfs_funcvecinit(void)1528615SAndrew.W.Wilson@sun.com fb_lfs_funcvecinit(void)
1538615SAndrew.W.Wilson@sun.com {
1548615SAndrew.W.Wilson@sun.com 	fs_functions_vec = &fb_lfs_funcs;
1558615SAndrew.W.Wilson@sun.com }
1568615SAndrew.W.Wilson@sun.com 
1578615SAndrew.W.Wilson@sun.com /*
1588615SAndrew.W.Wilson@sun.com  * Initialize those flowops whose implementation is file system
1598615SAndrew.W.Wilson@sun.com  * specific.
1608615SAndrew.W.Wilson@sun.com  */
1618615SAndrew.W.Wilson@sun.com void
fb_lfs_flowinit(void)1628615SAndrew.W.Wilson@sun.com fb_lfs_flowinit(void)
1638615SAndrew.W.Wilson@sun.com {
1648615SAndrew.W.Wilson@sun.com 	int nops;
1658615SAndrew.W.Wilson@sun.com 
1668615SAndrew.W.Wilson@sun.com 	/*
1678615SAndrew.W.Wilson@sun.com 	 * re-initialize the I/O functions vector while we are at
1688615SAndrew.W.Wilson@sun.com 	 * it as it may have been redefined since the process was
1698615SAndrew.W.Wilson@sun.com 	 * created, at least if this is the master processes
1708615SAndrew.W.Wilson@sun.com 	 */
1718615SAndrew.W.Wilson@sun.com 	fb_lfs_funcvecinit();
1728615SAndrew.W.Wilson@sun.com 
1738615SAndrew.W.Wilson@sun.com #ifdef HAVE_AIO
1748615SAndrew.W.Wilson@sun.com 	nops = sizeof (fb_lfsflow_funcs) / sizeof (flowop_proto_t);
1758615SAndrew.W.Wilson@sun.com 	flowop_flow_init(fb_lfsflow_funcs, nops);
1768615SAndrew.W.Wilson@sun.com #endif /* HAVE_AIO */
1778615SAndrew.W.Wilson@sun.com }
1788615SAndrew.W.Wilson@sun.com 
1798615SAndrew.W.Wilson@sun.com /*
1808615SAndrew.W.Wilson@sun.com  * Frees up memory mapped file region of supplied size. The
1818615SAndrew.W.Wilson@sun.com  * file descriptor "fd" indicates which memory mapped file.
1828615SAndrew.W.Wilson@sun.com  * If successful, returns 0. Otherwise returns -1 if "size"
1838615SAndrew.W.Wilson@sun.com  * is zero, or -1 times the number of times msync() failed.
1848615SAndrew.W.Wilson@sun.com  */
1858615SAndrew.W.Wilson@sun.com static int
fb_lfs_freemem(fb_fdesc_t * fd,off64_t size)1868615SAndrew.W.Wilson@sun.com fb_lfs_freemem(fb_fdesc_t *fd, off64_t size)
1878615SAndrew.W.Wilson@sun.com {
1888615SAndrew.W.Wilson@sun.com 	off64_t left;
1898615SAndrew.W.Wilson@sun.com 	int ret = 0;
1908615SAndrew.W.Wilson@sun.com 
1918615SAndrew.W.Wilson@sun.com 	for (left = size; left > 0; left -= MMAP_SIZE) {
1928615SAndrew.W.Wilson@sun.com 		off64_t thismapsize;
1938615SAndrew.W.Wilson@sun.com 		caddr_t addr;
1948615SAndrew.W.Wilson@sun.com 
1958615SAndrew.W.Wilson@sun.com 		thismapsize = MIN(MMAP_SIZE, left);
1968615SAndrew.W.Wilson@sun.com 		addr = mmap64(0, thismapsize, PROT_READ|PROT_WRITE,
1978615SAndrew.W.Wilson@sun.com 		    MAP_SHARED, fd->fd_num, size - left);
1988615SAndrew.W.Wilson@sun.com 		ret += msync(addr, thismapsize, MS_INVALIDATE);
1998615SAndrew.W.Wilson@sun.com 		(void) munmap(addr, thismapsize);
2008615SAndrew.W.Wilson@sun.com 	}
2018615SAndrew.W.Wilson@sun.com 	return (ret);
2028615SAndrew.W.Wilson@sun.com }
2038615SAndrew.W.Wilson@sun.com 
2048615SAndrew.W.Wilson@sun.com /*
2058615SAndrew.W.Wilson@sun.com  * Does a posix pread. Returns what the pread() returns.
2068615SAndrew.W.Wilson@sun.com  */
2078615SAndrew.W.Wilson@sun.com static int
fb_lfs_pread(fb_fdesc_t * fd,caddr_t iobuf,fbint_t iosize,off64_t fileoffset)2088615SAndrew.W.Wilson@sun.com fb_lfs_pread(fb_fdesc_t *fd, caddr_t iobuf, fbint_t iosize, off64_t fileoffset)
2098615SAndrew.W.Wilson@sun.com {
2108615SAndrew.W.Wilson@sun.com 	return (pread64(fd->fd_num, iobuf, iosize, fileoffset));
2118615SAndrew.W.Wilson@sun.com }
2128615SAndrew.W.Wilson@sun.com 
2138615SAndrew.W.Wilson@sun.com /*
2148615SAndrew.W.Wilson@sun.com  * Does a posix read. Returns what the read() returns.
2158615SAndrew.W.Wilson@sun.com  */
2168615SAndrew.W.Wilson@sun.com static int
fb_lfs_read(fb_fdesc_t * fd,caddr_t iobuf,fbint_t iosize)2178615SAndrew.W.Wilson@sun.com fb_lfs_read(fb_fdesc_t *fd, caddr_t iobuf, fbint_t iosize)
2188615SAndrew.W.Wilson@sun.com {
2198615SAndrew.W.Wilson@sun.com 	return (read(fd->fd_num, iobuf, iosize));
2208615SAndrew.W.Wilson@sun.com }
2218615SAndrew.W.Wilson@sun.com 
2228615SAndrew.W.Wilson@sun.com #ifdef HAVE_AIO
2238615SAndrew.W.Wilson@sun.com 
2248615SAndrew.W.Wilson@sun.com /*
2258615SAndrew.W.Wilson@sun.com  * Asynchronous write section. An Asynchronous IO element
2268615SAndrew.W.Wilson@sun.com  * (aiolist_t) is used to associate the asynchronous write request with
2278615SAndrew.W.Wilson@sun.com  * its subsequent completion. This element includes a aiocb64 struct
2288615SAndrew.W.Wilson@sun.com  * that is used by posix aio_xxx calls to track the asynchronous writes.
2298615SAndrew.W.Wilson@sun.com  * The flowops aiowrite and aiowait result in calls to these posix
2308615SAndrew.W.Wilson@sun.com  * aio_xxx system routines to do the actual asynchronous write IO
2318615SAndrew.W.Wilson@sun.com  * operations.
2328615SAndrew.W.Wilson@sun.com  */
2338615SAndrew.W.Wilson@sun.com 
2348615SAndrew.W.Wilson@sun.com 
2358615SAndrew.W.Wilson@sun.com /*
2368615SAndrew.W.Wilson@sun.com  * Allocates an asynchronous I/O list (aio, of type
2378615SAndrew.W.Wilson@sun.com  * aiolist_t) element. Adds it to the flowop thread's
2388615SAndrew.W.Wilson@sun.com  * threadflow aio list. Returns a pointer to the element.
2398615SAndrew.W.Wilson@sun.com  */
2408615SAndrew.W.Wilson@sun.com static aiolist_t *
aio_allocate(flowop_t * flowop)2418615SAndrew.W.Wilson@sun.com aio_allocate(flowop_t *flowop)
2428615SAndrew.W.Wilson@sun.com {
2438615SAndrew.W.Wilson@sun.com 	aiolist_t *aiolist;
2448615SAndrew.W.Wilson@sun.com 
2458615SAndrew.W.Wilson@sun.com 	if ((aiolist = malloc(sizeof (aiolist_t))) == NULL) {
2468615SAndrew.W.Wilson@sun.com 		filebench_log(LOG_ERROR, "malloc aiolist failed");
2478615SAndrew.W.Wilson@sun.com 		filebench_shutdown(1);
2488615SAndrew.W.Wilson@sun.com 	}
2498615SAndrew.W.Wilson@sun.com 
2508615SAndrew.W.Wilson@sun.com 	/* Add to list */
2518615SAndrew.W.Wilson@sun.com 	if (flowop->fo_thread->tf_aiolist == NULL) {
2528615SAndrew.W.Wilson@sun.com 		flowop->fo_thread->tf_aiolist = aiolist;
2538615SAndrew.W.Wilson@sun.com 		aiolist->al_next = NULL;
2548615SAndrew.W.Wilson@sun.com 	} else {
2558615SAndrew.W.Wilson@sun.com 		aiolist->al_next = flowop->fo_thread->tf_aiolist;
2568615SAndrew.W.Wilson@sun.com 		flowop->fo_thread->tf_aiolist = aiolist;
2578615SAndrew.W.Wilson@sun.com 	}
2588615SAndrew.W.Wilson@sun.com 	return (aiolist);
2598615SAndrew.W.Wilson@sun.com }
2608615SAndrew.W.Wilson@sun.com 
2618615SAndrew.W.Wilson@sun.com /*
2628615SAndrew.W.Wilson@sun.com  * Searches for the aiolist element that has a matching
2638615SAndrew.W.Wilson@sun.com  * completion block, aiocb. If none found returns FILEBENCH_ERROR. If
2648615SAndrew.W.Wilson@sun.com  * found, removes the aiolist element from flowop thread's
2658615SAndrew.W.Wilson@sun.com  * list and returns FILEBENCH_OK.
2668615SAndrew.W.Wilson@sun.com  */
2678615SAndrew.W.Wilson@sun.com static int
aio_deallocate(flowop_t * flowop,struct aiocb64 * aiocb)2688615SAndrew.W.Wilson@sun.com aio_deallocate(flowop_t *flowop, struct aiocb64 *aiocb)
2698615SAndrew.W.Wilson@sun.com {
2708615SAndrew.W.Wilson@sun.com 	aiolist_t *aiolist = flowop->fo_thread->tf_aiolist;
2718615SAndrew.W.Wilson@sun.com 	aiolist_t *previous = NULL;
2728615SAndrew.W.Wilson@sun.com 	aiolist_t *match = NULL;
2738615SAndrew.W.Wilson@sun.com 
2748615SAndrew.W.Wilson@sun.com 	if (aiocb == NULL) {
2758615SAndrew.W.Wilson@sun.com 		filebench_log(LOG_ERROR, "null aiocb deallocate");
2768615SAndrew.W.Wilson@sun.com 		return (FILEBENCH_OK);
2778615SAndrew.W.Wilson@sun.com 	}
2788615SAndrew.W.Wilson@sun.com 
2798615SAndrew.W.Wilson@sun.com 	while (aiolist) {
2808615SAndrew.W.Wilson@sun.com 		if (aiocb == &(aiolist->al_aiocb)) {
2818615SAndrew.W.Wilson@sun.com 			match = aiolist;
2828615SAndrew.W.Wilson@sun.com 			break;
2838615SAndrew.W.Wilson@sun.com 		}
2848615SAndrew.W.Wilson@sun.com 		previous = aiolist;
2858615SAndrew.W.Wilson@sun.com 		aiolist = aiolist->al_next;
2868615SAndrew.W.Wilson@sun.com 	}
2878615SAndrew.W.Wilson@sun.com 
2888615SAndrew.W.Wilson@sun.com 	if (match == NULL)
2898615SAndrew.W.Wilson@sun.com 		return (FILEBENCH_ERROR);
2908615SAndrew.W.Wilson@sun.com 
2918615SAndrew.W.Wilson@sun.com 	/* Remove from the list */
2928615SAndrew.W.Wilson@sun.com 	if (previous)
2938615SAndrew.W.Wilson@sun.com 		previous->al_next = match->al_next;
2948615SAndrew.W.Wilson@sun.com 	else
2958615SAndrew.W.Wilson@sun.com 		flowop->fo_thread->tf_aiolist = match->al_next;
2968615SAndrew.W.Wilson@sun.com 
2978615SAndrew.W.Wilson@sun.com 	return (FILEBENCH_OK);
2988615SAndrew.W.Wilson@sun.com }
2998615SAndrew.W.Wilson@sun.com 
3008615SAndrew.W.Wilson@sun.com /*
3018615SAndrew.W.Wilson@sun.com  * Emulate posix aiowrite(). Determines which file to use,
3028615SAndrew.W.Wilson@sun.com  * either one file of a fileset, or the file associated
3038615SAndrew.W.Wilson@sun.com  * with a fileobj, allocates and fills an aiolist_t element
3048615SAndrew.W.Wilson@sun.com  * for the write, and issues the asynchronous write. This
3058615SAndrew.W.Wilson@sun.com  * operation is only valid for random IO, and returns an
3068615SAndrew.W.Wilson@sun.com  * error if the flowop is set for sequential IO. Returns
3078615SAndrew.W.Wilson@sun.com  * FILEBENCH_OK on success, FILEBENCH_NORSC if iosetup can't
3088615SAndrew.W.Wilson@sun.com  * obtain a file to open, and FILEBENCH_ERROR on any
3098615SAndrew.W.Wilson@sun.com  * encountered error.
3108615SAndrew.W.Wilson@sun.com  */
3118615SAndrew.W.Wilson@sun.com static int
fb_lfsflow_aiowrite(threadflow_t * threadflow,flowop_t * flowop)3128615SAndrew.W.Wilson@sun.com fb_lfsflow_aiowrite(threadflow_t *threadflow, flowop_t *flowop)
3138615SAndrew.W.Wilson@sun.com {
3148615SAndrew.W.Wilson@sun.com 	caddr_t iobuf;
3158615SAndrew.W.Wilson@sun.com 	fbint_t wss;
3168615SAndrew.W.Wilson@sun.com 	fbint_t iosize;
3178615SAndrew.W.Wilson@sun.com 	fb_fdesc_t *fdesc;
3188615SAndrew.W.Wilson@sun.com 	int ret;
3198615SAndrew.W.Wilson@sun.com 
3208615SAndrew.W.Wilson@sun.com 	iosize = avd_get_int(flowop->fo_iosize);
3218615SAndrew.W.Wilson@sun.com 
3228615SAndrew.W.Wilson@sun.com 	if ((ret = flowoplib_iosetup(threadflow, flowop, &wss, &iobuf,
3238615SAndrew.W.Wilson@sun.com 	    &fdesc, iosize)) != FILEBENCH_OK)
3248615SAndrew.W.Wilson@sun.com 		return (ret);
3258615SAndrew.W.Wilson@sun.com 
3268615SAndrew.W.Wilson@sun.com 	if (avd_get_bool(flowop->fo_random)) {
3278615SAndrew.W.Wilson@sun.com 		uint64_t fileoffset;
3288615SAndrew.W.Wilson@sun.com 		struct aiocb64 *aiocb;
3298615SAndrew.W.Wilson@sun.com 		aiolist_t *aiolist;
3308615SAndrew.W.Wilson@sun.com 
3318615SAndrew.W.Wilson@sun.com 		if (filebench_randomno64(&fileoffset,
3328615SAndrew.W.Wilson@sun.com 		    wss, iosize, NULL) == -1) {
3338615SAndrew.W.Wilson@sun.com 			filebench_log(LOG_ERROR,
3348615SAndrew.W.Wilson@sun.com 			    "file size smaller than IO size for thread %s",
3358615SAndrew.W.Wilson@sun.com 			    flowop->fo_name);
3368615SAndrew.W.Wilson@sun.com 			return (FILEBENCH_ERROR);
3378615SAndrew.W.Wilson@sun.com 		}
3388615SAndrew.W.Wilson@sun.com 
3398615SAndrew.W.Wilson@sun.com 		aiolist = aio_allocate(flowop);
3408615SAndrew.W.Wilson@sun.com 		aiolist->al_type = AL_WRITE;
3418615SAndrew.W.Wilson@sun.com 		aiocb = &aiolist->al_aiocb;
3428615SAndrew.W.Wilson@sun.com 
3438615SAndrew.W.Wilson@sun.com 		aiocb->aio_fildes = fdesc->fd_num;
3448615SAndrew.W.Wilson@sun.com 		aiocb->aio_buf = iobuf;
3458615SAndrew.W.Wilson@sun.com 		aiocb->aio_nbytes = (size_t)iosize;
3468615SAndrew.W.Wilson@sun.com 		aiocb->aio_offset = (off64_t)fileoffset;
3478615SAndrew.W.Wilson@sun.com 		aiocb->aio_reqprio = 0;
3488615SAndrew.W.Wilson@sun.com 
3498615SAndrew.W.Wilson@sun.com 		filebench_log(LOG_DEBUG_IMPL,
3508615SAndrew.W.Wilson@sun.com 		    "aio fd=%d, bytes=%llu, offset=%llu",
3518615SAndrew.W.Wilson@sun.com 		    fdesc->fd_num, (u_longlong_t)iosize,
3528615SAndrew.W.Wilson@sun.com 		    (u_longlong_t)fileoffset);
3538615SAndrew.W.Wilson@sun.com 
3548615SAndrew.W.Wilson@sun.com 		flowop_beginop(threadflow, flowop);
3558615SAndrew.W.Wilson@sun.com 		if (aio_write64(aiocb) < 0) {
3568615SAndrew.W.Wilson@sun.com 			filebench_log(LOG_ERROR, "aiowrite failed: %s",
3578615SAndrew.W.Wilson@sun.com 			    strerror(errno));
3588615SAndrew.W.Wilson@sun.com 			filebench_shutdown(1);
3598615SAndrew.W.Wilson@sun.com 		}
3608615SAndrew.W.Wilson@sun.com 		flowop_endop(threadflow, flowop, iosize);
3618615SAndrew.W.Wilson@sun.com 	} else {
3628615SAndrew.W.Wilson@sun.com 		return (FILEBENCH_ERROR);
3638615SAndrew.W.Wilson@sun.com 	}
3648615SAndrew.W.Wilson@sun.com 
3658615SAndrew.W.Wilson@sun.com 	return (FILEBENCH_OK);
3668615SAndrew.W.Wilson@sun.com }
3678615SAndrew.W.Wilson@sun.com 
3688615SAndrew.W.Wilson@sun.com 
3698615SAndrew.W.Wilson@sun.com 
3708615SAndrew.W.Wilson@sun.com #define	MAXREAP 4096
3718615SAndrew.W.Wilson@sun.com 
3728615SAndrew.W.Wilson@sun.com /*
3738615SAndrew.W.Wilson@sun.com  * Emulate posix aiowait(). Waits for the completion of half the
3748615SAndrew.W.Wilson@sun.com  * outstanding asynchronous IOs, or a single IO, which ever is
3758615SAndrew.W.Wilson@sun.com  * larger. The routine will return after a sufficient number of
3768615SAndrew.W.Wilson@sun.com  * completed calls issued by any thread in the procflow have
3778615SAndrew.W.Wilson@sun.com  * completed, or a 1 second timout elapses. All completed
3788615SAndrew.W.Wilson@sun.com  * IO operations are deleted from the thread's aiolist.
3798615SAndrew.W.Wilson@sun.com  */
3808615SAndrew.W.Wilson@sun.com static int
fb_lfsflow_aiowait(threadflow_t * threadflow,flowop_t * flowop)3818615SAndrew.W.Wilson@sun.com fb_lfsflow_aiowait(threadflow_t *threadflow, flowop_t *flowop)
3828615SAndrew.W.Wilson@sun.com {
3838615SAndrew.W.Wilson@sun.com 	struct aiocb64 **worklist;
3848615SAndrew.W.Wilson@sun.com 	aiolist_t *aio = flowop->fo_thread->tf_aiolist;
3858615SAndrew.W.Wilson@sun.com 	int uncompleted = 0;
3868615SAndrew.W.Wilson@sun.com 
3878615SAndrew.W.Wilson@sun.com 	worklist = calloc(MAXREAP, sizeof (struct aiocb64 *));
3888615SAndrew.W.Wilson@sun.com 
3898615SAndrew.W.Wilson@sun.com 	/* Count the list of pending aios */
3908615SAndrew.W.Wilson@sun.com 	while (aio) {
3918615SAndrew.W.Wilson@sun.com 		uncompleted++;
3928615SAndrew.W.Wilson@sun.com 		aio = aio->al_next;
3938615SAndrew.W.Wilson@sun.com 	}
3948615SAndrew.W.Wilson@sun.com 
3958615SAndrew.W.Wilson@sun.com 	do {
3968615SAndrew.W.Wilson@sun.com 		uint_t ncompleted = 0;
3978615SAndrew.W.Wilson@sun.com 		uint_t todo;
3988615SAndrew.W.Wilson@sun.com 		struct timespec timeout;
3998615SAndrew.W.Wilson@sun.com 		int inprogress;
4008615SAndrew.W.Wilson@sun.com 		int i;
4018615SAndrew.W.Wilson@sun.com 
4028615SAndrew.W.Wilson@sun.com 		/* Wait for half of the outstanding requests */
4038615SAndrew.W.Wilson@sun.com 		timeout.tv_sec = 1;
4048615SAndrew.W.Wilson@sun.com 		timeout.tv_nsec = 0;
4058615SAndrew.W.Wilson@sun.com 
4068615SAndrew.W.Wilson@sun.com 		if (uncompleted > MAXREAP)
4078615SAndrew.W.Wilson@sun.com 			todo = MAXREAP;
4088615SAndrew.W.Wilson@sun.com 		else
4098615SAndrew.W.Wilson@sun.com 			todo = uncompleted / 2;
4108615SAndrew.W.Wilson@sun.com 
4118615SAndrew.W.Wilson@sun.com 		if (todo == 0)
4128615SAndrew.W.Wilson@sun.com 			todo = 1;
4138615SAndrew.W.Wilson@sun.com 
4148615SAndrew.W.Wilson@sun.com 		flowop_beginop(threadflow, flowop);
4158615SAndrew.W.Wilson@sun.com 
4168762SAndrew.W.Wilson@sun.com #if (defined(HAVE_AIOWAITN) && defined(USE_PROCESS_MODEL))
4178615SAndrew.W.Wilson@sun.com 		if (((aio_waitn64((struct aiocb64 **)worklist,
4188615SAndrew.W.Wilson@sun.com 		    MAXREAP, &todo, &timeout)) == -1) &&
4198615SAndrew.W.Wilson@sun.com 		    errno && (errno != ETIME)) {
4208615SAndrew.W.Wilson@sun.com 			filebench_log(LOG_ERROR,
4218615SAndrew.W.Wilson@sun.com 			    "aiowait failed: %s, outstanding = %d, "
4228615SAndrew.W.Wilson@sun.com 			    "ncompleted = %d ",
4238615SAndrew.W.Wilson@sun.com 			    strerror(errno), uncompleted, todo);
4248615SAndrew.W.Wilson@sun.com 		}
4258615SAndrew.W.Wilson@sun.com 
4268615SAndrew.W.Wilson@sun.com 		ncompleted = todo;
4278615SAndrew.W.Wilson@sun.com 		/* Take the  completed I/Os from the list */
4288615SAndrew.W.Wilson@sun.com 		inprogress = 0;
4298615SAndrew.W.Wilson@sun.com 		for (i = 0; i < ncompleted; i++) {
4308615SAndrew.W.Wilson@sun.com 			if ((aio_return64(worklist[i]) == -1) &&
4318615SAndrew.W.Wilson@sun.com 			    (errno == EINPROGRESS)) {
4328615SAndrew.W.Wilson@sun.com 				inprogress++;
4338615SAndrew.W.Wilson@sun.com 				continue;
4348615SAndrew.W.Wilson@sun.com 			}
4358615SAndrew.W.Wilson@sun.com 			if (aio_deallocate(flowop, worklist[i])
4368615SAndrew.W.Wilson@sun.com 			    == FILEBENCH_ERROR) {
4378615SAndrew.W.Wilson@sun.com 				filebench_log(LOG_ERROR, "Could not remove "
4388615SAndrew.W.Wilson@sun.com 				    "aio from list ");
4398615SAndrew.W.Wilson@sun.com 				flowop_endop(threadflow, flowop, 0);
4408615SAndrew.W.Wilson@sun.com 				return (FILEBENCH_ERROR);
4418615SAndrew.W.Wilson@sun.com 			}
4428615SAndrew.W.Wilson@sun.com 		}
4438615SAndrew.W.Wilson@sun.com 
4448615SAndrew.W.Wilson@sun.com 		uncompleted -= ncompleted;
4458615SAndrew.W.Wilson@sun.com 		uncompleted += inprogress;
4468615SAndrew.W.Wilson@sun.com 
4478615SAndrew.W.Wilson@sun.com #else
4488615SAndrew.W.Wilson@sun.com 
4498615SAndrew.W.Wilson@sun.com 		for (ncompleted = 0, inprogress = 0,
4508615SAndrew.W.Wilson@sun.com 		    aio = flowop->fo_thread->tf_aiolist;
4518615SAndrew.W.Wilson@sun.com 		    ncompleted < todo, aio != NULL; aio = aio->al_next) {
4528762SAndrew.W.Wilson@sun.com 			int result = aio_error64(&aio->al_aiocb);
4538615SAndrew.W.Wilson@sun.com 
4548615SAndrew.W.Wilson@sun.com 			if (result == EINPROGRESS) {
4558615SAndrew.W.Wilson@sun.com 				inprogress++;
4568615SAndrew.W.Wilson@sun.com 				continue;
4578615SAndrew.W.Wilson@sun.com 			}
4588615SAndrew.W.Wilson@sun.com 
4598762SAndrew.W.Wilson@sun.com 			if ((aio_return64(&aio->al_aiocb) == -1) || result) {
4608615SAndrew.W.Wilson@sun.com 				filebench_log(LOG_ERROR, "aio failed: %s",
4618615SAndrew.W.Wilson@sun.com 				    strerror(result));
4628615SAndrew.W.Wilson@sun.com 				continue;
4638615SAndrew.W.Wilson@sun.com 			}
4648615SAndrew.W.Wilson@sun.com 
4658615SAndrew.W.Wilson@sun.com 			ncompleted++;
4668615SAndrew.W.Wilson@sun.com 
4678615SAndrew.W.Wilson@sun.com 			if (aio_deallocate(flowop, &aio->al_aiocb) < 0) {
4688615SAndrew.W.Wilson@sun.com 				filebench_log(LOG_ERROR, "Could not remove "
4698762SAndrew.W.Wilson@sun.com 				    "aio from list ");
4708615SAndrew.W.Wilson@sun.com 				flowop_endop(threadflow, flowop, 0);
4718615SAndrew.W.Wilson@sun.com 				return (FILEBENCH_ERROR);
4728615SAndrew.W.Wilson@sun.com 			}
4738615SAndrew.W.Wilson@sun.com 		}
4748615SAndrew.W.Wilson@sun.com 
4758615SAndrew.W.Wilson@sun.com 		uncompleted -= ncompleted;
4768615SAndrew.W.Wilson@sun.com 
4778615SAndrew.W.Wilson@sun.com #endif
4788615SAndrew.W.Wilson@sun.com 		filebench_log(LOG_DEBUG_SCRIPT,
4798615SAndrew.W.Wilson@sun.com 		    "aio2 completed %d ios, uncompleted = %d, inprogress = %d",
4808615SAndrew.W.Wilson@sun.com 		    ncompleted, uncompleted, inprogress);
4818615SAndrew.W.Wilson@sun.com 
4828615SAndrew.W.Wilson@sun.com 	} while (uncompleted > MAXREAP);
4838615SAndrew.W.Wilson@sun.com 
4848615SAndrew.W.Wilson@sun.com 	flowop_endop(threadflow, flowop, 0);
4858615SAndrew.W.Wilson@sun.com 
4868615SAndrew.W.Wilson@sun.com 	free(worklist);
4878615SAndrew.W.Wilson@sun.com 
4888615SAndrew.W.Wilson@sun.com 	return (FILEBENCH_OK);
4898615SAndrew.W.Wilson@sun.com }
4908615SAndrew.W.Wilson@sun.com 
4918615SAndrew.W.Wilson@sun.com #endif /* HAVE_AIO */
4928615SAndrew.W.Wilson@sun.com 
4938615SAndrew.W.Wilson@sun.com /*
4948615SAndrew.W.Wilson@sun.com  * Does an open64 of a file. Inserts the file descriptor number returned
4958615SAndrew.W.Wilson@sun.com  * by open() into the supplied filebench fd. Returns FILEBENCH_OK on
4968615SAndrew.W.Wilson@sun.com  * successs, and FILEBENCH_ERROR on failure.
4978615SAndrew.W.Wilson@sun.com  */
4988615SAndrew.W.Wilson@sun.com 
4998615SAndrew.W.Wilson@sun.com static int
fb_lfs_open(fb_fdesc_t * fd,char * path,int flags,int perms)5008615SAndrew.W.Wilson@sun.com fb_lfs_open(fb_fdesc_t *fd, char *path, int flags, int perms)
5018615SAndrew.W.Wilson@sun.com {
5028615SAndrew.W.Wilson@sun.com 	if ((fd->fd_num = open64(path, flags, perms)) < 0)
5038615SAndrew.W.Wilson@sun.com 		return (FILEBENCH_ERROR);
5048615SAndrew.W.Wilson@sun.com 	else
5058615SAndrew.W.Wilson@sun.com 		return (FILEBENCH_OK);
5068615SAndrew.W.Wilson@sun.com }
5078615SAndrew.W.Wilson@sun.com 
5088615SAndrew.W.Wilson@sun.com /*
5098615SAndrew.W.Wilson@sun.com  * Does an unlink (delete) of a file.
5108615SAndrew.W.Wilson@sun.com  */
5118615SAndrew.W.Wilson@sun.com static int
fb_lfs_unlink(char * path)5128615SAndrew.W.Wilson@sun.com fb_lfs_unlink(char *path)
5138615SAndrew.W.Wilson@sun.com {
5148615SAndrew.W.Wilson@sun.com 	return (unlink(path));
5158615SAndrew.W.Wilson@sun.com }
5168615SAndrew.W.Wilson@sun.com 
5178615SAndrew.W.Wilson@sun.com /*
5188615SAndrew.W.Wilson@sun.com  * Does a readlink of a symbolic link.
5198615SAndrew.W.Wilson@sun.com  */
5208615SAndrew.W.Wilson@sun.com static ssize_t
fb_lfs_readlink(const char * path,char * buf,size_t buf_size)5218615SAndrew.W.Wilson@sun.com fb_lfs_readlink(const char *path, char *buf, size_t buf_size)
5228615SAndrew.W.Wilson@sun.com {
5238615SAndrew.W.Wilson@sun.com 	return (readlink(path, buf, buf_size));
5248615SAndrew.W.Wilson@sun.com }
5258615SAndrew.W.Wilson@sun.com 
5268615SAndrew.W.Wilson@sun.com /*
5278615SAndrew.W.Wilson@sun.com  * Does fsync of a file. Returns with fsync return info.
5288615SAndrew.W.Wilson@sun.com  */
5298615SAndrew.W.Wilson@sun.com static int
fb_lfs_fsync(fb_fdesc_t * fd)5308615SAndrew.W.Wilson@sun.com fb_lfs_fsync(fb_fdesc_t *fd)
5318615SAndrew.W.Wilson@sun.com {
5328615SAndrew.W.Wilson@sun.com 	return (fsync(fd->fd_num));
5338615SAndrew.W.Wilson@sun.com }
5348615SAndrew.W.Wilson@sun.com 
5358615SAndrew.W.Wilson@sun.com /*
5368615SAndrew.W.Wilson@sun.com  * Do a posix lseek of a file. Return what lseek() returns.
5378615SAndrew.W.Wilson@sun.com  */
5388615SAndrew.W.Wilson@sun.com static int
fb_lfs_lseek(fb_fdesc_t * fd,off64_t offset,int whence)5398615SAndrew.W.Wilson@sun.com fb_lfs_lseek(fb_fdesc_t *fd, off64_t offset, int whence)
5408615SAndrew.W.Wilson@sun.com {
5418615SAndrew.W.Wilson@sun.com 	return (lseek64(fd->fd_num, offset, whence));
5428615SAndrew.W.Wilson@sun.com }
5438615SAndrew.W.Wilson@sun.com 
5448615SAndrew.W.Wilson@sun.com /*
5458615SAndrew.W.Wilson@sun.com  * Do a posix rename of a file. Return what rename() returns.
5468615SAndrew.W.Wilson@sun.com  */
5478615SAndrew.W.Wilson@sun.com static int
fb_lfs_rename(const char * old,const char * new)5488615SAndrew.W.Wilson@sun.com fb_lfs_rename(const char *old, const char *new)
5498615SAndrew.W.Wilson@sun.com {
5508615SAndrew.W.Wilson@sun.com 	return (rename(old, new));
5518615SAndrew.W.Wilson@sun.com }
5528615SAndrew.W.Wilson@sun.com 
5538615SAndrew.W.Wilson@sun.com 
5548615SAndrew.W.Wilson@sun.com /*
5558615SAndrew.W.Wilson@sun.com  * Do a posix close of a file. Return what close() returns.
5568615SAndrew.W.Wilson@sun.com  */
5578615SAndrew.W.Wilson@sun.com static int
fb_lfs_close(fb_fdesc_t * fd)5588615SAndrew.W.Wilson@sun.com fb_lfs_close(fb_fdesc_t *fd)
5598615SAndrew.W.Wilson@sun.com {
5608615SAndrew.W.Wilson@sun.com 	return (close(fd->fd_num));
5618615SAndrew.W.Wilson@sun.com }
5628615SAndrew.W.Wilson@sun.com 
5638615SAndrew.W.Wilson@sun.com /*
5648615SAndrew.W.Wilson@sun.com  * Use mkdir to create a directory.
5658615SAndrew.W.Wilson@sun.com  */
5668615SAndrew.W.Wilson@sun.com static int
fb_lfs_mkdir(char * path,int perm)5678615SAndrew.W.Wilson@sun.com fb_lfs_mkdir(char *path, int perm)
5688615SAndrew.W.Wilson@sun.com {
5698615SAndrew.W.Wilson@sun.com 	return (mkdir(path, perm));
5708615SAndrew.W.Wilson@sun.com }
5718615SAndrew.W.Wilson@sun.com 
5728615SAndrew.W.Wilson@sun.com /*
5738615SAndrew.W.Wilson@sun.com  * Use rmdir to delete a directory. Returns what rmdir() returns.
5748615SAndrew.W.Wilson@sun.com  */
5758615SAndrew.W.Wilson@sun.com static int
fb_lfs_rmdir(char * path)5768615SAndrew.W.Wilson@sun.com fb_lfs_rmdir(char *path)
5778615SAndrew.W.Wilson@sun.com {
5788615SAndrew.W.Wilson@sun.com 	return (rmdir(path));
5798615SAndrew.W.Wilson@sun.com }
5808615SAndrew.W.Wilson@sun.com 
5818615SAndrew.W.Wilson@sun.com /*
5829356SAndrew.W.Wilson@sun.com  * does a recursive rm to remove an entire directory tree (i.e. a fileset).
5839356SAndrew.W.Wilson@sun.com  * Supplied with the path to the root of the tree.
5849356SAndrew.W.Wilson@sun.com  */
5859356SAndrew.W.Wilson@sun.com static void
fb_lfs_recur_rm(char * path)5869356SAndrew.W.Wilson@sun.com fb_lfs_recur_rm(char *path)
5879356SAndrew.W.Wilson@sun.com {
5889356SAndrew.W.Wilson@sun.com 	char cmd[MAXPATHLEN];
5899356SAndrew.W.Wilson@sun.com 
5909356SAndrew.W.Wilson@sun.com 	(void) snprintf(cmd, sizeof (cmd), "rm -rf %s", path);
5919356SAndrew.W.Wilson@sun.com 	(void) system(cmd);
5929356SAndrew.W.Wilson@sun.com }
5939356SAndrew.W.Wilson@sun.com 
5949356SAndrew.W.Wilson@sun.com /*
5958615SAndrew.W.Wilson@sun.com  * Does a posix opendir(), Returns a directory handle on success,
5968615SAndrew.W.Wilson@sun.com  * NULL on failure.
5978615SAndrew.W.Wilson@sun.com  */
5988615SAndrew.W.Wilson@sun.com static DIR *
fb_lfs_opendir(char * path)5998615SAndrew.W.Wilson@sun.com fb_lfs_opendir(char *path)
6008615SAndrew.W.Wilson@sun.com {
6018615SAndrew.W.Wilson@sun.com 	return (opendir(path));
6028615SAndrew.W.Wilson@sun.com }
6038615SAndrew.W.Wilson@sun.com 
6048615SAndrew.W.Wilson@sun.com /*
6058615SAndrew.W.Wilson@sun.com  * Does a readdir() call. Returns a pointer to a table of directory
6068615SAndrew.W.Wilson@sun.com  * information on success, NULL on failure.
6078615SAndrew.W.Wilson@sun.com  */
6088615SAndrew.W.Wilson@sun.com static struct dirent *
fb_lfs_readdir(DIR * dirp)6098615SAndrew.W.Wilson@sun.com fb_lfs_readdir(DIR *dirp)
6108615SAndrew.W.Wilson@sun.com {
6118615SAndrew.W.Wilson@sun.com 	return (readdir(dirp));
6128615SAndrew.W.Wilson@sun.com }
6138615SAndrew.W.Wilson@sun.com 
6148615SAndrew.W.Wilson@sun.com /*
6158615SAndrew.W.Wilson@sun.com  * Does a closedir() call.
6168615SAndrew.W.Wilson@sun.com  */
6178615SAndrew.W.Wilson@sun.com static int
fb_lfs_closedir(DIR * dirp)6188615SAndrew.W.Wilson@sun.com fb_lfs_closedir(DIR *dirp)
6198615SAndrew.W.Wilson@sun.com {
6208615SAndrew.W.Wilson@sun.com 	return (closedir(dirp));
6218615SAndrew.W.Wilson@sun.com }
6228615SAndrew.W.Wilson@sun.com 
6238615SAndrew.W.Wilson@sun.com /*
6248615SAndrew.W.Wilson@sun.com  * Does an fstat of a file.
6258615SAndrew.W.Wilson@sun.com  */
6268615SAndrew.W.Wilson@sun.com static int
fb_lfs_fstat(fb_fdesc_t * fd,struct stat64 * statbufp)6278615SAndrew.W.Wilson@sun.com fb_lfs_fstat(fb_fdesc_t *fd, struct stat64 *statbufp)
6288615SAndrew.W.Wilson@sun.com {
6298615SAndrew.W.Wilson@sun.com 	return (fstat64(fd->fd_num, statbufp));
6308615SAndrew.W.Wilson@sun.com }
6318615SAndrew.W.Wilson@sun.com 
6328615SAndrew.W.Wilson@sun.com /*
6338615SAndrew.W.Wilson@sun.com  * Does a stat of a file.
6348615SAndrew.W.Wilson@sun.com  */
6358615SAndrew.W.Wilson@sun.com static int
fb_lfs_stat(char * path,struct stat64 * statbufp)6368615SAndrew.W.Wilson@sun.com fb_lfs_stat(char *path, struct stat64 *statbufp)
6378615SAndrew.W.Wilson@sun.com {
6388615SAndrew.W.Wilson@sun.com 	return (stat64(path, statbufp));
6398615SAndrew.W.Wilson@sun.com }
6408615SAndrew.W.Wilson@sun.com 
6418615SAndrew.W.Wilson@sun.com /*
6428615SAndrew.W.Wilson@sun.com  * Do a pwrite64 to a file.
6438615SAndrew.W.Wilson@sun.com  */
6448615SAndrew.W.Wilson@sun.com static int
fb_lfs_pwrite(fb_fdesc_t * fd,caddr_t iobuf,fbint_t iosize,off64_t offset)6458615SAndrew.W.Wilson@sun.com fb_lfs_pwrite(fb_fdesc_t *fd, caddr_t iobuf, fbint_t iosize, off64_t offset)
6468615SAndrew.W.Wilson@sun.com {
6478615SAndrew.W.Wilson@sun.com 	return (pwrite64(fd->fd_num, iobuf, iosize, offset));
6488615SAndrew.W.Wilson@sun.com }
6498615SAndrew.W.Wilson@sun.com 
6508615SAndrew.W.Wilson@sun.com /*
6518615SAndrew.W.Wilson@sun.com  * Do a write to a file.
6528615SAndrew.W.Wilson@sun.com  */
6538615SAndrew.W.Wilson@sun.com static int
fb_lfs_write(fb_fdesc_t * fd,caddr_t iobuf,fbint_t iosize)6548615SAndrew.W.Wilson@sun.com fb_lfs_write(fb_fdesc_t *fd, caddr_t iobuf, fbint_t iosize)
6558615SAndrew.W.Wilson@sun.com {
6568615SAndrew.W.Wilson@sun.com 	return (write(fd->fd_num, iobuf, iosize));
6578615SAndrew.W.Wilson@sun.com }
6588615SAndrew.W.Wilson@sun.com 
6598615SAndrew.W.Wilson@sun.com /*
6608615SAndrew.W.Wilson@sun.com  * Does a truncate operation and returns the result
6618615SAndrew.W.Wilson@sun.com  */
6628615SAndrew.W.Wilson@sun.com static int
fb_lfs_truncate(fb_fdesc_t * fd,off64_t fse_size)6638615SAndrew.W.Wilson@sun.com fb_lfs_truncate(fb_fdesc_t *fd, off64_t fse_size)
6648615SAndrew.W.Wilson@sun.com {
6658615SAndrew.W.Wilson@sun.com #ifdef HAVE_FTRUNCATE64
6668615SAndrew.W.Wilson@sun.com 	return (ftruncate64(fd->fd_num, fse_size));
6678615SAndrew.W.Wilson@sun.com #else
6688615SAndrew.W.Wilson@sun.com 	return (ftruncate(fd->fd_num, (off_t)fse_size));
6698615SAndrew.W.Wilson@sun.com #endif
6708615SAndrew.W.Wilson@sun.com }
6718615SAndrew.W.Wilson@sun.com 
6728615SAndrew.W.Wilson@sun.com /*
6738615SAndrew.W.Wilson@sun.com  * Does a link operation and returns the result
6748615SAndrew.W.Wilson@sun.com  */
6758615SAndrew.W.Wilson@sun.com static int
fb_lfs_link(const char * existing,const char * new)6768615SAndrew.W.Wilson@sun.com fb_lfs_link(const char *existing, const char *new)
6778615SAndrew.W.Wilson@sun.com {
6788615SAndrew.W.Wilson@sun.com 	return (link(existing, new));
6798615SAndrew.W.Wilson@sun.com }
6808615SAndrew.W.Wilson@sun.com 
6818615SAndrew.W.Wilson@sun.com /*
6828615SAndrew.W.Wilson@sun.com  * Does a symlink operation and returns the result
6838615SAndrew.W.Wilson@sun.com  */
6848615SAndrew.W.Wilson@sun.com static int
fb_lfs_symlink(const char * existing,const char * new)6858615SAndrew.W.Wilson@sun.com fb_lfs_symlink(const char *existing, const char *new)
6868615SAndrew.W.Wilson@sun.com {
6878615SAndrew.W.Wilson@sun.com 	return (symlink(existing, new));
6888615SAndrew.W.Wilson@sun.com }
6898615SAndrew.W.Wilson@sun.com 
6908615SAndrew.W.Wilson@sun.com /*
6918615SAndrew.W.Wilson@sun.com  * Does an access() check on a file.
6928615SAndrew.W.Wilson@sun.com  */
6938615SAndrew.W.Wilson@sun.com static int
fb_lfs_access(const char * path,int amode)6948615SAndrew.W.Wilson@sun.com fb_lfs_access(const char *path, int amode)
6958615SAndrew.W.Wilson@sun.com {
6968615SAndrew.W.Wilson@sun.com 	return (access(path, amode));
6978615SAndrew.W.Wilson@sun.com }
698