1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate * CDDL HEADER START
3*0Sstevel@tonic-gate *
4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*0Sstevel@tonic-gate * with the License.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate * and limitations under the License.
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate *
20*0Sstevel@tonic-gate * CDDL HEADER END
21*0Sstevel@tonic-gate */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate * Copyright 1994-2002 Sun Microsystems, Inc. All rights reserved.
24*0Sstevel@tonic-gate * Use is subject to license terms.
25*0Sstevel@tonic-gate */
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
28*0Sstevel@tonic-gate
29*0Sstevel@tonic-gate /*
30*0Sstevel@tonic-gate * Methods of the cfsd_maptbl classes.
31*0Sstevel@tonic-gate */
32*0Sstevel@tonic-gate
33*0Sstevel@tonic-gate #include <stdio.h>
34*0Sstevel@tonic-gate #include <stdlib.h>
35*0Sstevel@tonic-gate #include <stddef.h>
36*0Sstevel@tonic-gate #include <string.h>
37*0Sstevel@tonic-gate #include <synch.h>
38*0Sstevel@tonic-gate #include <unistd.h>
39*0Sstevel@tonic-gate #include <fcntl.h>
40*0Sstevel@tonic-gate #include <errno.h>
41*0Sstevel@tonic-gate #include <sys/utsname.h>
42*0Sstevel@tonic-gate #include <sys/vfs.h>
43*0Sstevel@tonic-gate #include <sys/cred.h>
44*0Sstevel@tonic-gate #include <sys/param.h>
45*0Sstevel@tonic-gate #include <sys/types.h>
46*0Sstevel@tonic-gate #include <sys/stat.h>
47*0Sstevel@tonic-gate #include <sys/mman.h>
48*0Sstevel@tonic-gate #include <sys/fs/cachefs_fs.h>
49*0Sstevel@tonic-gate #include <sys/fs/cachefs_dlog.h>
50*0Sstevel@tonic-gate #include <mdbug/mdbug.h>
51*0Sstevel@tonic-gate #include "cfsd.h"
52*0Sstevel@tonic-gate #include "cfsd_logfile.h"
53*0Sstevel@tonic-gate
54*0Sstevel@tonic-gate /*
55*0Sstevel@tonic-gate * cfsd_logfile_create
56*0Sstevel@tonic-gate *
57*0Sstevel@tonic-gate * Description:
58*0Sstevel@tonic-gate * Arguments:
59*0Sstevel@tonic-gate * Returns:
60*0Sstevel@tonic-gate * Preconditions:
61*0Sstevel@tonic-gate */
62*0Sstevel@tonic-gate cfsd_logfile_object_t *
cfsd_logfile_create(void)63*0Sstevel@tonic-gate cfsd_logfile_create(void)
64*0Sstevel@tonic-gate {
65*0Sstevel@tonic-gate cfsd_logfile_object_t *logfile_object_p;
66*0Sstevel@tonic-gate
67*0Sstevel@tonic-gate dbug_enter("cfsd_logfile_create");
68*0Sstevel@tonic-gate
69*0Sstevel@tonic-gate logfile_object_p = cfsd_calloc(sizeof (cfsd_logfile_object_t));
70*0Sstevel@tonic-gate logfile_object_p->i_fid = -1;
71*0Sstevel@tonic-gate logfile_object_p->i_map_entry.i_pa = NULL;
72*0Sstevel@tonic-gate logfile_object_p->i_map_entry.i_paoff = 0;
73*0Sstevel@tonic-gate logfile_object_p->i_map_entry.i_paend = 0;
74*0Sstevel@tonic-gate logfile_object_p->i_map_entry.i_palen = 0;
75*0Sstevel@tonic-gate logfile_object_p->i_map_offset.i_pa = NULL;
76*0Sstevel@tonic-gate logfile_object_p->i_map_offset.i_paoff = 0;
77*0Sstevel@tonic-gate logfile_object_p->i_map_offset.i_paend = 0;
78*0Sstevel@tonic-gate logfile_object_p->i_map_offset.i_palen = 0;
79*0Sstevel@tonic-gate logfile_object_p->i_cur_offset = 0;
80*0Sstevel@tonic-gate logfile_object_p->i_cur_entry = NULL;
81*0Sstevel@tonic-gate dbug_leave("cfsd_logfile_create");
82*0Sstevel@tonic-gate return (logfile_object_p);
83*0Sstevel@tonic-gate }
84*0Sstevel@tonic-gate
85*0Sstevel@tonic-gate /*
86*0Sstevel@tonic-gate * cfsd_logfile_destroy
87*0Sstevel@tonic-gate *
88*0Sstevel@tonic-gate * Description:
89*0Sstevel@tonic-gate * Arguments:
90*0Sstevel@tonic-gate * Returns:
91*0Sstevel@tonic-gate * Preconditions:
92*0Sstevel@tonic-gate */
93*0Sstevel@tonic-gate void
cfsd_logfile_destroy(cfsd_logfile_object_t * logfile_object_p)94*0Sstevel@tonic-gate cfsd_logfile_destroy(cfsd_logfile_object_t *logfile_object_p)
95*0Sstevel@tonic-gate {
96*0Sstevel@tonic-gate dbug_enter("cfsd_logfile_destroy");
97*0Sstevel@tonic-gate logfile_sync(logfile_object_p);
98*0Sstevel@tonic-gate logfile_teardown(logfile_object_p);
99*0Sstevel@tonic-gate cfsd_free(logfile_object_p);
100*0Sstevel@tonic-gate dbug_leave("cfsd_logfile_destroy");
101*0Sstevel@tonic-gate }
102*0Sstevel@tonic-gate
103*0Sstevel@tonic-gate /*
104*0Sstevel@tonic-gate * logfile_domap
105*0Sstevel@tonic-gate *
106*0Sstevel@tonic-gate * Description:
107*0Sstevel@tonic-gate * Maps in the specified section of the file.
108*0Sstevel@tonic-gate * Arguments:
109*0Sstevel@tonic-gate * off The offset to map in. Must be i_pagesize aligned.
110*0Sstevel@tonic-gate * map 0 means use map_entry, 1 means use map_offset
111*0Sstevel@tonic-gate * Returns:
112*0Sstevel@tonic-gate * Returns 0 for success or an errno value on failure.
113*0Sstevel@tonic-gate * Preconditions:
114*0Sstevel@tonic-gate */
115*0Sstevel@tonic-gate int
logfile_domap(cfsd_logfile_object_t * logfile_object_p,off_t off,int map)116*0Sstevel@tonic-gate logfile_domap(cfsd_logfile_object_t *logfile_object_p, off_t off, int map)
117*0Sstevel@tonic-gate {
118*0Sstevel@tonic-gate int xx;
119*0Sstevel@tonic-gate int len;
120*0Sstevel@tonic-gate mmap_info_t *mmp;
121*0Sstevel@tonic-gate
122*0Sstevel@tonic-gate dbug_enter("logfile_domap");
123*0Sstevel@tonic-gate dbug_precond(logfile_object_p->i_fid >= 0);
124*0Sstevel@tonic-gate
125*0Sstevel@tonic-gate len = logfile_object_p->i_maplen;
126*0Sstevel@tonic-gate mmp = (map == 0) ?
127*0Sstevel@tonic-gate &logfile_object_p->i_map_entry :
128*0Sstevel@tonic-gate &logfile_object_p->i_map_offset;
129*0Sstevel@tonic-gate
130*0Sstevel@tonic-gate logfile_object_p->i_stat_mapmove++;
131*0Sstevel@tonic-gate
132*0Sstevel@tonic-gate /* destroy old mapping if it exists */
133*0Sstevel@tonic-gate if (mmp->i_pa) {
134*0Sstevel@tonic-gate /* determine how far we have to move the map */
135*0Sstevel@tonic-gate logfile_object_p->i_stat_mapdist += abs(mmp->i_paoff - off);
136*0Sstevel@tonic-gate
137*0Sstevel@tonic-gate /* remove the map */
138*0Sstevel@tonic-gate xx = munmap(mmp->i_pa, mmp->i_palen);
139*0Sstevel@tonic-gate if (xx == -1) {
140*0Sstevel@tonic-gate xx = errno;
141*0Sstevel@tonic-gate dbug_print(("error", "Could not unmap %s, %d, %p, %d",
142*0Sstevel@tonic-gate logfile_object_p->i_name, xx, mmp->i_pa,
143*0Sstevel@tonic-gate mmp->i_palen));
144*0Sstevel@tonic-gate }
145*0Sstevel@tonic-gate mmp->i_pa = NULL;
146*0Sstevel@tonic-gate mmp->i_palen = 0;
147*0Sstevel@tonic-gate mmp->i_paoff = 0;
148*0Sstevel@tonic-gate mmp->i_paend = 0;
149*0Sstevel@tonic-gate }
150*0Sstevel@tonic-gate
151*0Sstevel@tonic-gate /* do the mapping */
152*0Sstevel@tonic-gate mmp->i_pa = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED,
153*0Sstevel@tonic-gate logfile_object_p->i_fid, off);
154*0Sstevel@tonic-gate if (mmp->i_pa == MAP_FAILED) {
155*0Sstevel@tonic-gate xx = errno;
156*0Sstevel@tonic-gate dbug_print(("error",
157*0Sstevel@tonic-gate "Could not map %s, error %d, off %d, len %d",
158*0Sstevel@tonic-gate logfile_object_p->i_name, xx, off, len));
159*0Sstevel@tonic-gate mmp->i_pa = NULL;
160*0Sstevel@tonic-gate dbug_leave("logfile_domap");
161*0Sstevel@tonic-gate return (xx);
162*0Sstevel@tonic-gate }
163*0Sstevel@tonic-gate
164*0Sstevel@tonic-gate mmp->i_palen = len;
165*0Sstevel@tonic-gate mmp->i_paoff = off;
166*0Sstevel@tonic-gate mmp->i_paend = off + len - 1;
167*0Sstevel@tonic-gate dbug_leave("logfile_domap");
168*0Sstevel@tonic-gate return (0);
169*0Sstevel@tonic-gate }
170*0Sstevel@tonic-gate
171*0Sstevel@tonic-gate /*
172*0Sstevel@tonic-gate * logfile_getaddr
173*0Sstevel@tonic-gate *
174*0Sstevel@tonic-gate * Description:
175*0Sstevel@tonic-gate * Returns an address of a particular offset in the file.
176*0Sstevel@tonic-gate * The size of the item to map is i_maxmap
177*0Sstevel@tonic-gate * This routine assumes that if we have to remap that i_maxmap
178*0Sstevel@tonic-gate * will fit inside the default mapping size.
179*0Sstevel@tonic-gate * Arguments:
180*0Sstevel@tonic-gate * start offset in the file to map
181*0Sstevel@tonic-gate * map 0 means use map_entry, 1 means use map_offset
182*0Sstevel@tonic-gate * Returns:
183*0Sstevel@tonic-gate * Returns NULL for a failure with the mapping file.
184*0Sstevel@tonic-gate * Preconditions:
185*0Sstevel@tonic-gate */
186*0Sstevel@tonic-gate caddr_t
logfile_getaddr(cfsd_logfile_object_t * logfile_object_p,off_t start,int map)187*0Sstevel@tonic-gate logfile_getaddr(cfsd_logfile_object_t *logfile_object_p, off_t start, int map)
188*0Sstevel@tonic-gate {
189*0Sstevel@tonic-gate mmap_info_t *mmp;
190*0Sstevel@tonic-gate caddr_t pa;
191*0Sstevel@tonic-gate off_t end;
192*0Sstevel@tonic-gate
193*0Sstevel@tonic-gate dbug_enter("logfile_getaddr");
194*0Sstevel@tonic-gate
195*0Sstevel@tonic-gate mmp = (map == 0) ?
196*0Sstevel@tonic-gate &logfile_object_p->i_map_entry :
197*0Sstevel@tonic-gate &logfile_object_p->i_map_offset;
198*0Sstevel@tonic-gate
199*0Sstevel@tonic-gate /* determine the end of the item */
200*0Sstevel@tonic-gate end = start + logfile_object_p->i_maxmap - 1;
201*0Sstevel@tonic-gate
202*0Sstevel@tonic-gate /* map the entry in if necessary */
203*0Sstevel@tonic-gate if ((start < mmp->i_paoff) || (mmp->i_paend < end)) {
204*0Sstevel@tonic-gate if (logfile_domap(logfile_object_p,
205*0Sstevel@tonic-gate start & logfile_object_p->i_pagemask, map)) {
206*0Sstevel@tonic-gate dbug_leave("logfile_getaddr");
207*0Sstevel@tonic-gate return (NULL);
208*0Sstevel@tonic-gate }
209*0Sstevel@tonic-gate dbug_assert((mmp->i_paoff <= start) && (end <= mmp->i_paend));
210*0Sstevel@tonic-gate }
211*0Sstevel@tonic-gate
212*0Sstevel@tonic-gate /* make an address and return it */
213*0Sstevel@tonic-gate pa = mmp->i_pa + (start - mmp->i_paoff);
214*0Sstevel@tonic-gate dbug_leave("logfile_getaddr");
215*0Sstevel@tonic-gate return (pa);
216*0Sstevel@tonic-gate }
217*0Sstevel@tonic-gate
218*0Sstevel@tonic-gate /*
219*0Sstevel@tonic-gate * logfile_setup
220*0Sstevel@tonic-gate *
221*0Sstevel@tonic-gate * Description:
222*0Sstevel@tonic-gate * Sets up to use the specified file.
223*0Sstevel@tonic-gate * Call this routine before using any of the other routines.
224*0Sstevel@tonic-gate * Arguments:
225*0Sstevel@tonic-gate * filename file to use
226*0Sstevel@tonic-gate * maxmap max amount needed after a map
227*0Sstevel@tonic-gate * Returns:
228*0Sstevel@tonic-gate * Returns 0 for success or an errno value.
229*0Sstevel@tonic-gate * Preconditions:
230*0Sstevel@tonic-gate * precond(filename)
231*0Sstevel@tonic-gate */
232*0Sstevel@tonic-gate int
logfile_setup(cfsd_logfile_object_t * logfile_object_p,const char * filename,int maxmap)233*0Sstevel@tonic-gate logfile_setup(cfsd_logfile_object_t *logfile_object_p,
234*0Sstevel@tonic-gate const char *filename, int maxmap)
235*0Sstevel@tonic-gate {
236*0Sstevel@tonic-gate int xx;
237*0Sstevel@tonic-gate struct stat sinfo;
238*0Sstevel@tonic-gate long *versionp;
239*0Sstevel@tonic-gate
240*0Sstevel@tonic-gate dbug_enter("logfile_setup");
241*0Sstevel@tonic-gate dbug_precond(filename);
242*0Sstevel@tonic-gate
243*0Sstevel@tonic-gate /* clean up from a previous setup */
244*0Sstevel@tonic-gate logfile_teardown(logfile_object_p);
245*0Sstevel@tonic-gate
246*0Sstevel@tonic-gate strlcpy(logfile_object_p->i_name, filename,
247*0Sstevel@tonic-gate sizeof (logfile_object_p->i_name));
248*0Sstevel@tonic-gate dbug_print(("info", "filename %s", logfile_object_p->i_name));
249*0Sstevel@tonic-gate logfile_object_p->i_maxmap = maxmap;
250*0Sstevel@tonic-gate
251*0Sstevel@tonic-gate /* get the page info */
252*0Sstevel@tonic-gate logfile_object_p->i_pagesize = PAGESIZE;
253*0Sstevel@tonic-gate logfile_object_p->i_pagemask = PAGEMASK;
254*0Sstevel@tonic-gate logfile_object_p->i_maplen = logfile_object_p->i_pagesize * 100;
255*0Sstevel@tonic-gate
256*0Sstevel@tonic-gate /* open the file */
257*0Sstevel@tonic-gate logfile_object_p->i_fid = open(logfile_object_p->i_name,
258*0Sstevel@tonic-gate O_RDWR | O_NONBLOCK);
259*0Sstevel@tonic-gate if (logfile_object_p->i_fid == -1) {
260*0Sstevel@tonic-gate xx = errno;
261*0Sstevel@tonic-gate dbug_print(("error", "Could not open %s, %d",
262*0Sstevel@tonic-gate logfile_object_p->i_name, xx));
263*0Sstevel@tonic-gate dbug_leave("logfile_setup");
264*0Sstevel@tonic-gate return (xx);
265*0Sstevel@tonic-gate }
266*0Sstevel@tonic-gate
267*0Sstevel@tonic-gate /* get the size and type of file */
268*0Sstevel@tonic-gate xx = fstat(logfile_object_p->i_fid, &sinfo);
269*0Sstevel@tonic-gate if (xx) {
270*0Sstevel@tonic-gate xx = errno;
271*0Sstevel@tonic-gate if (xx == ENOENT) {
272*0Sstevel@tonic-gate dbug_print(("info", "No log file to roll"));
273*0Sstevel@tonic-gate } else {
274*0Sstevel@tonic-gate dbug_print(("error", "Could not stat %s, %d",
275*0Sstevel@tonic-gate logfile_object_p->i_name, xx));
276*0Sstevel@tonic-gate }
277*0Sstevel@tonic-gate dbug_leave("logfile_setup");
278*0Sstevel@tonic-gate return (xx);
279*0Sstevel@tonic-gate }
280*0Sstevel@tonic-gate logfile_object_p->i_size = sinfo.st_size;
281*0Sstevel@tonic-gate
282*0Sstevel@tonic-gate /* sanity check, better be a regular file */
283*0Sstevel@tonic-gate if (!S_ISREG(sinfo.st_mode)) {
284*0Sstevel@tonic-gate xx = ENOTSUP;
285*0Sstevel@tonic-gate dbug_print(("error", "%s Not a regular file.",
286*0Sstevel@tonic-gate logfile_object_p->i_name));
287*0Sstevel@tonic-gate dbug_leave("logfile_setup");
288*0Sstevel@tonic-gate return (xx);
289*0Sstevel@tonic-gate }
290*0Sstevel@tonic-gate
291*0Sstevel@tonic-gate /* better not be too small */
292*0Sstevel@tonic-gate if (logfile_object_p->i_size < LOGFILE_ENTRY_START) {
293*0Sstevel@tonic-gate dbug_print(("error", "File %s is too small %d.",
294*0Sstevel@tonic-gate logfile_object_p->i_name, logfile_object_p->i_size));
295*0Sstevel@tonic-gate dbug_leave("logfile_setup");
296*0Sstevel@tonic-gate return (EINVAL);
297*0Sstevel@tonic-gate }
298*0Sstevel@tonic-gate
299*0Sstevel@tonic-gate /* initialize statistic gathering */
300*0Sstevel@tonic-gate logfile_object_p->i_stat_mapmove = 0;
301*0Sstevel@tonic-gate logfile_object_p->i_stat_mapdist = 0;
302*0Sstevel@tonic-gate
303*0Sstevel@tonic-gate /* check the version number */
304*0Sstevel@tonic-gate versionp = (long *)logfile_getaddr(logfile_object_p, 0, 1);
305*0Sstevel@tonic-gate if (versionp == NULL) {
306*0Sstevel@tonic-gate dbug_leave("logfile_setup");
307*0Sstevel@tonic-gate return (EIO);
308*0Sstevel@tonic-gate }
309*0Sstevel@tonic-gate if (*versionp != CFS_DLOG_VERSION) {
310*0Sstevel@tonic-gate dbug_print(("error", "Log file version mismatch %d != %d",
311*0Sstevel@tonic-gate *versionp, CFS_DLOG_VERSION));
312*0Sstevel@tonic-gate dbug_leave("logfile_setup");
313*0Sstevel@tonic-gate return (EINVAL);
314*0Sstevel@tonic-gate }
315*0Sstevel@tonic-gate
316*0Sstevel@tonic-gate /* return success */
317*0Sstevel@tonic-gate dbug_leave("logfile_setup");
318*0Sstevel@tonic-gate return (0);
319*0Sstevel@tonic-gate }
320*0Sstevel@tonic-gate
321*0Sstevel@tonic-gate /*
322*0Sstevel@tonic-gate * logfile_teardown
323*0Sstevel@tonic-gate *
324*0Sstevel@tonic-gate * Description:
325*0Sstevel@tonic-gate * Uninitializes the object.
326*0Sstevel@tonic-gate * Call logfile_setup before using this object again.
327*0Sstevel@tonic-gate * Arguments:
328*0Sstevel@tonic-gate * Returns:
329*0Sstevel@tonic-gate * Preconditions:
330*0Sstevel@tonic-gate */
331*0Sstevel@tonic-gate void
logfile_teardown(cfsd_logfile_object_t * logfile_object_p)332*0Sstevel@tonic-gate logfile_teardown(cfsd_logfile_object_t *logfile_object_p)
333*0Sstevel@tonic-gate {
334*0Sstevel@tonic-gate int xx;
335*0Sstevel@tonic-gate
336*0Sstevel@tonic-gate dbug_enter("logfile_teardown");
337*0Sstevel@tonic-gate
338*0Sstevel@tonic-gate if (logfile_object_p->i_map_entry.i_pa) {
339*0Sstevel@tonic-gate xx = munmap(logfile_object_p->i_map_entry.i_pa,
340*0Sstevel@tonic-gate logfile_object_p->i_map_entry.i_palen);
341*0Sstevel@tonic-gate if (xx == -1) {
342*0Sstevel@tonic-gate xx = errno;
343*0Sstevel@tonic-gate dbug_print(("error", "Could not unmap %s, %d, %p, %d",
344*0Sstevel@tonic-gate logfile_object_p->i_name, xx,
345*0Sstevel@tonic-gate logfile_object_p->i_map_entry.i_pa,
346*0Sstevel@tonic-gate logfile_object_p->i_map_entry.i_palen));
347*0Sstevel@tonic-gate }
348*0Sstevel@tonic-gate logfile_object_p->i_map_entry.i_pa = NULL;
349*0Sstevel@tonic-gate }
350*0Sstevel@tonic-gate logfile_object_p->i_map_entry.i_paoff = 0;
351*0Sstevel@tonic-gate logfile_object_p->i_map_entry.i_paend = 0;
352*0Sstevel@tonic-gate logfile_object_p->i_map_entry.i_palen = 0;
353*0Sstevel@tonic-gate
354*0Sstevel@tonic-gate if (logfile_object_p->i_map_offset.i_pa) {
355*0Sstevel@tonic-gate xx = munmap(logfile_object_p->i_map_offset.i_pa,
356*0Sstevel@tonic-gate logfile_object_p->i_map_offset.i_palen);
357*0Sstevel@tonic-gate if (xx == -1) {
358*0Sstevel@tonic-gate xx = errno;
359*0Sstevel@tonic-gate dbug_print(("error", "Could not unmap %s, %d, %p, %d",
360*0Sstevel@tonic-gate logfile_object_p->i_name, xx,
361*0Sstevel@tonic-gate logfile_object_p->i_map_offset.i_pa,
362*0Sstevel@tonic-gate logfile_object_p->i_map_offset.i_palen));
363*0Sstevel@tonic-gate }
364*0Sstevel@tonic-gate logfile_object_p->i_map_offset.i_pa = NULL;
365*0Sstevel@tonic-gate }
366*0Sstevel@tonic-gate logfile_object_p->i_map_offset.i_paoff = 0;
367*0Sstevel@tonic-gate logfile_object_p->i_map_offset.i_paend = 0;
368*0Sstevel@tonic-gate logfile_object_p->i_map_offset.i_palen = 0;
369*0Sstevel@tonic-gate
370*0Sstevel@tonic-gate if (logfile_object_p->i_fid != -1) {
371*0Sstevel@tonic-gate if (close(logfile_object_p->i_fid))
372*0Sstevel@tonic-gate dbug_print(("error", "Could not close %s, %d",
373*0Sstevel@tonic-gate logfile_object_p->i_name, errno));
374*0Sstevel@tonic-gate logfile_object_p->i_fid = -1;
375*0Sstevel@tonic-gate }
376*0Sstevel@tonic-gate logfile_object_p->i_cur_offset = 0;
377*0Sstevel@tonic-gate logfile_object_p->i_cur_entry = NULL;
378*0Sstevel@tonic-gate dbug_leave("logfile_teardown");
379*0Sstevel@tonic-gate }
380*0Sstevel@tonic-gate
381*0Sstevel@tonic-gate /*
382*0Sstevel@tonic-gate * logfile_entry
383*0Sstevel@tonic-gate *
384*0Sstevel@tonic-gate * Description:
385*0Sstevel@tonic-gate * Sets addrp to the address of the log entry at offset
386*0Sstevel@tonic-gate * The mapping remains in effect until:
387*0Sstevel@tonic-gate * a) this routine is called again
388*0Sstevel@tonic-gate * b) logfile_teardown is called
389*0Sstevel@tonic-gate * c) this object is destroyed
390*0Sstevel@tonic-gate * Arguments:
391*0Sstevel@tonic-gate * offset offset to start of entry
392*0Sstevel@tonic-gate * entpp place to store address
393*0Sstevel@tonic-gate * Returns:
394*0Sstevel@tonic-gate * Returns 0 for success, 1 for EOF, -1 if a fatal error occurs.
395*0Sstevel@tonic-gate * Preconditions:
396*0Sstevel@tonic-gate * precond(addrp)
397*0Sstevel@tonic-gate */
398*0Sstevel@tonic-gate int
logfile_entry(cfsd_logfile_object_t * logfile_object_p,off_t offset,cfs_dlog_entry_t ** entpp)399*0Sstevel@tonic-gate logfile_entry(cfsd_logfile_object_t *logfile_object_p,
400*0Sstevel@tonic-gate off_t offset,
401*0Sstevel@tonic-gate cfs_dlog_entry_t **entpp)
402*0Sstevel@tonic-gate {
403*0Sstevel@tonic-gate cfs_dlog_entry_t *entp;
404*0Sstevel@tonic-gate
405*0Sstevel@tonic-gate dbug_enter("logfile_entry");
406*0Sstevel@tonic-gate dbug_precond(entpp);
407*0Sstevel@tonic-gate dbug_precond(offset >= sizeof (long));
408*0Sstevel@tonic-gate
409*0Sstevel@tonic-gate
410*0Sstevel@tonic-gate logfile_object_p->i_stat_nextcnt++;
411*0Sstevel@tonic-gate
412*0Sstevel@tonic-gate /* check for eof */
413*0Sstevel@tonic-gate if (offset >= logfile_object_p->i_size) {
414*0Sstevel@tonic-gate dbug_leave("logfile_entry");
415*0Sstevel@tonic-gate return (1);
416*0Sstevel@tonic-gate }
417*0Sstevel@tonic-gate dbug_assert((offset & 3) == 0);
418*0Sstevel@tonic-gate
419*0Sstevel@tonic-gate /* get the address of the entry */
420*0Sstevel@tonic-gate entp = (cfs_dlog_entry_t *)logfile_getaddr(logfile_object_p, offset, 0);
421*0Sstevel@tonic-gate if (entp == NULL) {
422*0Sstevel@tonic-gate dbug_leave("logfile_entry");
423*0Sstevel@tonic-gate return (-1);
424*0Sstevel@tonic-gate }
425*0Sstevel@tonic-gate /* sanity check, record should be alligned */
426*0Sstevel@tonic-gate if (entp->dl_len & 3) {
427*0Sstevel@tonic-gate dbug_print(("error",
428*0Sstevel@tonic-gate "Record at offset %d length is not alligned %d",
429*0Sstevel@tonic-gate offset, entp->dl_len));
430*0Sstevel@tonic-gate dbug_leave("logfile_entry");
431*0Sstevel@tonic-gate return (-1);
432*0Sstevel@tonic-gate }
433*0Sstevel@tonic-gate
434*0Sstevel@tonic-gate /* sanity check record should a reasonable size */
435*0Sstevel@tonic-gate if ((entp->dl_len < CFS_DLOG_ENTRY_MINSIZE) ||
436*0Sstevel@tonic-gate (entp->dl_len > CFS_DLOG_ENTRY_MAXSIZE)) {
437*0Sstevel@tonic-gate dbug_print(("error",
438*0Sstevel@tonic-gate "Record at offset %d has an invalid size %d", offset,
439*0Sstevel@tonic-gate entp->dl_len));
440*0Sstevel@tonic-gate dbug_leave("logfile_entry");
441*0Sstevel@tonic-gate return (-1);
442*0Sstevel@tonic-gate }
443*0Sstevel@tonic-gate
444*0Sstevel@tonic-gate /* preserve offset and pointer */
445*0Sstevel@tonic-gate logfile_object_p->i_cur_offset = offset;
446*0Sstevel@tonic-gate logfile_object_p->i_cur_entry = entp;
447*0Sstevel@tonic-gate
448*0Sstevel@tonic-gate /* return success */
449*0Sstevel@tonic-gate *entpp = entp;
450*0Sstevel@tonic-gate dbug_leave("logfile_entry");
451*0Sstevel@tonic-gate return (0);
452*0Sstevel@tonic-gate }
453*0Sstevel@tonic-gate
454*0Sstevel@tonic-gate /*
455*0Sstevel@tonic-gate * logfile_offset
456*0Sstevel@tonic-gate *
457*0Sstevel@tonic-gate * Description:
458*0Sstevel@tonic-gate * Sets addrp to the address of the specified offset.
459*0Sstevel@tonic-gate * The mapping remains in effect until:
460*0Sstevel@tonic-gate * a) this routine is called again
461*0Sstevel@tonic-gate * b) logfile_teardown is called
462*0Sstevel@tonic-gate * c) this object is destroyed
463*0Sstevel@tonic-gate * Arguments:
464*0Sstevel@tonic-gate * offset offset into file, must be 0 <= offset < i_size
465*0Sstevel@tonic-gate * addrp returns mapped address
466*0Sstevel@tonic-gate * Returns:
467*0Sstevel@tonic-gate * Returns 0 for success, -1 if a fatal error occurs.
468*0Sstevel@tonic-gate * Preconditions:
469*0Sstevel@tonic-gate * precond(addrp)
470*0Sstevel@tonic-gate */
471*0Sstevel@tonic-gate int
logfile_offset(cfsd_logfile_object_t * logfile_object_p,off_t offset,caddr_t * addrp)472*0Sstevel@tonic-gate logfile_offset(cfsd_logfile_object_t *logfile_object_p,
473*0Sstevel@tonic-gate off_t offset,
474*0Sstevel@tonic-gate caddr_t *addrp)
475*0Sstevel@tonic-gate {
476*0Sstevel@tonic-gate caddr_t pa;
477*0Sstevel@tonic-gate
478*0Sstevel@tonic-gate dbug_enter("logfile_offset");
479*0Sstevel@tonic-gate dbug_precond(addrp);
480*0Sstevel@tonic-gate dbug_precond((0 <= offset) && (offset < logfile_object_p->i_size));
481*0Sstevel@tonic-gate
482*0Sstevel@tonic-gate logfile_object_p->i_stat_offcnt++;
483*0Sstevel@tonic-gate
484*0Sstevel@tonic-gate /* get the address for the offset */
485*0Sstevel@tonic-gate pa = logfile_getaddr(logfile_object_p, offset, 1);
486*0Sstevel@tonic-gate if (pa == NULL) {
487*0Sstevel@tonic-gate dbug_leave("logfile_offset");
488*0Sstevel@tonic-gate return (-1);
489*0Sstevel@tonic-gate }
490*0Sstevel@tonic-gate /* return success */
491*0Sstevel@tonic-gate *addrp = pa;
492*0Sstevel@tonic-gate dbug_leave("logfile_offset");
493*0Sstevel@tonic-gate return (0);
494*0Sstevel@tonic-gate }
495*0Sstevel@tonic-gate
496*0Sstevel@tonic-gate /*
497*0Sstevel@tonic-gate * logfile_sync
498*0Sstevel@tonic-gate *
499*0Sstevel@tonic-gate * Description:
500*0Sstevel@tonic-gate * Performs an fsync on the log file.
501*0Sstevel@tonic-gate * Arguments:
502*0Sstevel@tonic-gate * Returns:
503*0Sstevel@tonic-gate * Returns 0 for success or an errno value on failure.
504*0Sstevel@tonic-gate * Preconditions:
505*0Sstevel@tonic-gate */
506*0Sstevel@tonic-gate int
logfile_sync(cfsd_logfile_object_t * logfile_object_p)507*0Sstevel@tonic-gate logfile_sync(cfsd_logfile_object_t *logfile_object_p)
508*0Sstevel@tonic-gate {
509*0Sstevel@tonic-gate int xx;
510*0Sstevel@tonic-gate
511*0Sstevel@tonic-gate dbug_enter("logfile_sync");
512*0Sstevel@tonic-gate
513*0Sstevel@tonic-gate if (logfile_object_p->i_fid == -1) {
514*0Sstevel@tonic-gate dbug_leave("logfile_sync");
515*0Sstevel@tonic-gate return (0);
516*0Sstevel@tonic-gate }
517*0Sstevel@tonic-gate xx = fsync(logfile_object_p->i_fid);
518*0Sstevel@tonic-gate if (xx) {
519*0Sstevel@tonic-gate xx = errno;
520*0Sstevel@tonic-gate dbug_print(("error", "fsync failed %d", xx));
521*0Sstevel@tonic-gate }
522*0Sstevel@tonic-gate dbug_leave("logfile_sync");
523*0Sstevel@tonic-gate return (xx);
524*0Sstevel@tonic-gate }
525*0Sstevel@tonic-gate
526*0Sstevel@tonic-gate /*
527*0Sstevel@tonic-gate * logfile_dumpstats
528*0Sstevel@tonic-gate *
529*0Sstevel@tonic-gate * Description:
530*0Sstevel@tonic-gate * Prints out various stats about the hashing.
531*0Sstevel@tonic-gate * Arguments:
532*0Sstevel@tonic-gate * Returns:
533*0Sstevel@tonic-gate * Preconditions:
534*0Sstevel@tonic-gate */
535*0Sstevel@tonic-gate void
logfile_dumpstats(cfsd_logfile_object_t * logfile_object_p)536*0Sstevel@tonic-gate logfile_dumpstats(cfsd_logfile_object_t *logfile_object_p)
537*0Sstevel@tonic-gate {
538*0Sstevel@tonic-gate int xx;
539*0Sstevel@tonic-gate double dd;
540*0Sstevel@tonic-gate
541*0Sstevel@tonic-gate dbug_enter("logfile_dumpstats");
542*0Sstevel@tonic-gate
543*0Sstevel@tonic-gate dbug_print(("dump", "Request - next %d",
544*0Sstevel@tonic-gate logfile_object_p->i_stat_nextcnt));
545*0Sstevel@tonic-gate dbug_print(("dump", "Request - offset %d",
546*0Sstevel@tonic-gate logfile_object_p->i_stat_offcnt));
547*0Sstevel@tonic-gate dbug_print(("dump", "Map Moves %d", logfile_object_p->i_stat_mapmove));
548*0Sstevel@tonic-gate dbug_print(("dump", "Mapping Size %d", logfile_object_p->i_maplen));
549*0Sstevel@tonic-gate dbug_print(("dump", "Item Size %d", logfile_object_p->i_maxmap));
550*0Sstevel@tonic-gate dbug_print(("dump", "File Size %d", logfile_object_p->i_size));
551*0Sstevel@tonic-gate if (logfile_object_p->i_stat_mapmove == 0) {
552*0Sstevel@tonic-gate dbug_leave("logfile_dumpstats");
553*0Sstevel@tonic-gate return;
554*0Sstevel@tonic-gate }
555*0Sstevel@tonic-gate
556*0Sstevel@tonic-gate dd = (double)logfile_object_p->i_stat_mapmove /
557*0Sstevel@tonic-gate (logfile_object_p->i_stat_nextcnt +
558*0Sstevel@tonic-gate logfile_object_p->i_stat_offcnt);
559*0Sstevel@tonic-gate dbug_print(("dump", "Mmap moves per Request %.2f", dd));
560*0Sstevel@tonic-gate
561*0Sstevel@tonic-gate xx = logfile_object_p->i_stat_mapdist /
562*0Sstevel@tonic-gate logfile_object_p->i_stat_mapmove;
563*0Sstevel@tonic-gate dbug_print(("dump", "Average distance per mmap moves %d", xx));
564*0Sstevel@tonic-gate dbug_leave("logfile_dumpstats");
565*0Sstevel@tonic-gate }
566