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-2003 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_fscache class.
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 <string.h>
36*0Sstevel@tonic-gate #include <stddef.h>
37*0Sstevel@tonic-gate #include <thread.h>
38*0Sstevel@tonic-gate #include <synch.h>
39*0Sstevel@tonic-gate #include <errno.h>
40*0Sstevel@tonic-gate #include <unistd.h>
41*0Sstevel@tonic-gate #include <stdarg.h>
42*0Sstevel@tonic-gate #include <limits.h>
43*0Sstevel@tonic-gate #include <fcntl.h>
44*0Sstevel@tonic-gate #include <locale.h>
45*0Sstevel@tonic-gate #include <nfs/nfs.h>
46*0Sstevel@tonic-gate #include <sys/utsname.h>
47*0Sstevel@tonic-gate #include <sys/param.h>
48*0Sstevel@tonic-gate #include <sys/stat.h>
49*0Sstevel@tonic-gate #include <sys/mount.h>
50*0Sstevel@tonic-gate #include <sys/types.h>
51*0Sstevel@tonic-gate #include <sys/wait.h>
52*0Sstevel@tonic-gate #include <rpc/rpc.h>
53*0Sstevel@tonic-gate #include <mdbug/mdbug.h>
54*0Sstevel@tonic-gate #include <sys/fs/cachefs_fs.h>
55*0Sstevel@tonic-gate #include <sys/fs/cachefs_dlog.h>
56*0Sstevel@tonic-gate #include <sys/fs/cachefs_ioctl.h>
57*0Sstevel@tonic-gate #include "cfsd.h"
58*0Sstevel@tonic-gate #include "cfsd_kmod.h"
59*0Sstevel@tonic-gate #include "cfsd_maptbl.h"
60*0Sstevel@tonic-gate #include "cfsd_logfile.h"
61*0Sstevel@tonic-gate #include "cfsd_logelem.h"
62*0Sstevel@tonic-gate #include "cfsd_fscache.h"
63*0Sstevel@tonic-gate
64*0Sstevel@tonic-gate /*
65*0Sstevel@tonic-gate * -----------------------------------------------------------------
66*0Sstevel@tonic-gate * cfsd_fscache_create
67*0Sstevel@tonic-gate *
68*0Sstevel@tonic-gate * Description:
69*0Sstevel@tonic-gate * Arguments:
70*0Sstevel@tonic-gate * name
71*0Sstevel@tonic-gate * cachepath
72*0Sstevel@tonic-gate * Returns:
73*0Sstevel@tonic-gate * Preconditions:
74*0Sstevel@tonic-gate * precond(name)
75*0Sstevel@tonic-gate * precond(cachepath)
76*0Sstevel@tonic-gate */
77*0Sstevel@tonic-gate cfsd_fscache_object_t *
cfsd_fscache_create(const char * name,const char * cachepath,int fscacheid)78*0Sstevel@tonic-gate cfsd_fscache_create(const char *name, const char *cachepath,
79*0Sstevel@tonic-gate int fscacheid)
80*0Sstevel@tonic-gate {
81*0Sstevel@tonic-gate cfsd_fscache_object_t *fscache_object_p;
82*0Sstevel@tonic-gate int xx;
83*0Sstevel@tonic-gate
84*0Sstevel@tonic-gate dbug_enter("cfsd_fscache_create");
85*0Sstevel@tonic-gate
86*0Sstevel@tonic-gate dbug_precond(name);
87*0Sstevel@tonic-gate dbug_precond(cachepath);
88*0Sstevel@tonic-gate
89*0Sstevel@tonic-gate fscache_object_p = cfsd_calloc(sizeof (cfsd_fscache_object_t));
90*0Sstevel@tonic-gate strlcpy(fscache_object_p->i_name, name,
91*0Sstevel@tonic-gate sizeof (fscache_object_p->i_name));
92*0Sstevel@tonic-gate strlcpy(fscache_object_p->i_cachepath, cachepath,
93*0Sstevel@tonic-gate sizeof (fscache_object_p->i_cachepath));
94*0Sstevel@tonic-gate fscache_object_p->i_fscacheid = fscacheid;
95*0Sstevel@tonic-gate fscache_object_p->i_refcnt = 0;
96*0Sstevel@tonic-gate fscache_object_p->i_disconnectable = 0;
97*0Sstevel@tonic-gate fscache_object_p->i_mounted = 0;
98*0Sstevel@tonic-gate fscache_object_p->i_threaded = 0;
99*0Sstevel@tonic-gate fscache_object_p->i_connected = 0;
100*0Sstevel@tonic-gate fscache_object_p->i_reconcile = 0;
101*0Sstevel@tonic-gate fscache_object_p->i_changes = 0;
102*0Sstevel@tonic-gate fscache_object_p->i_simdis = 0;
103*0Sstevel@tonic-gate fscache_object_p->i_tryunmount = 0;
104*0Sstevel@tonic-gate fscache_object_p->i_backunmount = 0;
105*0Sstevel@tonic-gate fscache_object_p->i_time_state = 0;
106*0Sstevel@tonic-gate fscache_object_p->i_time_mnt = 0;
107*0Sstevel@tonic-gate fscache_object_p->i_modify = 1;
108*0Sstevel@tonic-gate
109*0Sstevel@tonic-gate fscache_object_p->i_threadid = 0;
110*0Sstevel@tonic-gate fscache_object_p->i_ofd = -1;
111*0Sstevel@tonic-gate
112*0Sstevel@tonic-gate fscache_object_p->i_next = NULL;
113*0Sstevel@tonic-gate
114*0Sstevel@tonic-gate /* initialize the locking mutex */
115*0Sstevel@tonic-gate xx = mutex_init(&fscache_object_p->i_lock, USYNC_THREAD, NULL);
116*0Sstevel@tonic-gate dbug_assert(xx == 0);
117*0Sstevel@tonic-gate
118*0Sstevel@tonic-gate xx = cond_init(&fscache_object_p->i_cvwait, USYNC_THREAD, 0);
119*0Sstevel@tonic-gate dbug_assert(xx == 0);
120*0Sstevel@tonic-gate
121*0Sstevel@tonic-gate dbug_leave("cfsd_fscache_create");
122*0Sstevel@tonic-gate return (fscache_object_p);
123*0Sstevel@tonic-gate }
124*0Sstevel@tonic-gate
125*0Sstevel@tonic-gate /*
126*0Sstevel@tonic-gate * -----------------------------------------------------------------
127*0Sstevel@tonic-gate * cfsd_fscache_destroy
128*0Sstevel@tonic-gate *
129*0Sstevel@tonic-gate * Description:
130*0Sstevel@tonic-gate * Arguments:
131*0Sstevel@tonic-gate * Returns:
132*0Sstevel@tonic-gate * Preconditions:
133*0Sstevel@tonic-gate */
134*0Sstevel@tonic-gate void
cfsd_fscache_destroy(cfsd_fscache_object_t * fscache_object_p)135*0Sstevel@tonic-gate cfsd_fscache_destroy(cfsd_fscache_object_t *fscache_object_p)
136*0Sstevel@tonic-gate {
137*0Sstevel@tonic-gate int xx;
138*0Sstevel@tonic-gate
139*0Sstevel@tonic-gate dbug_enter("cfsd_fscache_destroy");
140*0Sstevel@tonic-gate
141*0Sstevel@tonic-gate dbug_precond(fscache_object_p);
142*0Sstevel@tonic-gate /* dbug_assert(fscache_object_p->i_refcnt == 0); */
143*0Sstevel@tonic-gate
144*0Sstevel@tonic-gate /* close down the message file descriptor */
145*0Sstevel@tonic-gate if (fscache_object_p->i_ofd >= 0) {
146*0Sstevel@tonic-gate if (close(fscache_object_p->i_ofd))
147*0Sstevel@tonic-gate dbug_print(("error", "cannot close fscache fd error %d",
148*0Sstevel@tonic-gate errno));
149*0Sstevel@tonic-gate fscache_object_p->i_ofd = -1;
150*0Sstevel@tonic-gate }
151*0Sstevel@tonic-gate
152*0Sstevel@tonic-gate /* destroy the locking mutex */
153*0Sstevel@tonic-gate xx = mutex_destroy(&fscache_object_p->i_lock);
154*0Sstevel@tonic-gate dbug_assert(xx == 0);
155*0Sstevel@tonic-gate
156*0Sstevel@tonic-gate /* destroy the conditional variable */
157*0Sstevel@tonic-gate xx = cond_destroy(&fscache_object_p->i_cvwait);
158*0Sstevel@tonic-gate dbug_assert(xx == 0);
159*0Sstevel@tonic-gate
160*0Sstevel@tonic-gate cfsd_free(fscache_object_p);
161*0Sstevel@tonic-gate
162*0Sstevel@tonic-gate dbug_leave("cfsd_fscache_destroy");
163*0Sstevel@tonic-gate }
164*0Sstevel@tonic-gate
165*0Sstevel@tonic-gate /*
166*0Sstevel@tonic-gate * -----------------------------------------------------------------
167*0Sstevel@tonic-gate * fscache_lock
168*0Sstevel@tonic-gate *
169*0Sstevel@tonic-gate * Description:
170*0Sstevel@tonic-gate * Arguments:
171*0Sstevel@tonic-gate * Returns:
172*0Sstevel@tonic-gate * Preconditions:
173*0Sstevel@tonic-gate */
174*0Sstevel@tonic-gate void
fscache_lock(cfsd_fscache_object_t * fscache_object_p)175*0Sstevel@tonic-gate fscache_lock(cfsd_fscache_object_t *fscache_object_p)
176*0Sstevel@tonic-gate {
177*0Sstevel@tonic-gate dbug_enter("fscache_lock");
178*0Sstevel@tonic-gate
179*0Sstevel@tonic-gate dbug_precond(fscache_object_p);
180*0Sstevel@tonic-gate mutex_lock(&fscache_object_p->i_lock);
181*0Sstevel@tonic-gate dbug_leave("fscache_lock");
182*0Sstevel@tonic-gate }
183*0Sstevel@tonic-gate
184*0Sstevel@tonic-gate /*
185*0Sstevel@tonic-gate * -----------------------------------------------------------------
186*0Sstevel@tonic-gate * fscache_unlock
187*0Sstevel@tonic-gate *
188*0Sstevel@tonic-gate * Description:
189*0Sstevel@tonic-gate * Arguments:
190*0Sstevel@tonic-gate * Returns:
191*0Sstevel@tonic-gate * Preconditions:
192*0Sstevel@tonic-gate */
193*0Sstevel@tonic-gate void
fscache_unlock(cfsd_fscache_object_t * fscache_object_p)194*0Sstevel@tonic-gate fscache_unlock(cfsd_fscache_object_t *fscache_object_p)
195*0Sstevel@tonic-gate {
196*0Sstevel@tonic-gate dbug_enter("fscache_unlock");
197*0Sstevel@tonic-gate
198*0Sstevel@tonic-gate dbug_precond(fscache_object_p);
199*0Sstevel@tonic-gate mutex_unlock(&fscache_object_p->i_lock);
200*0Sstevel@tonic-gate dbug_leave("fscache_unlock");
201*0Sstevel@tonic-gate }
202*0Sstevel@tonic-gate
203*0Sstevel@tonic-gate /*
204*0Sstevel@tonic-gate * -----------------------------------------------------------------
205*0Sstevel@tonic-gate * fscache_setup
206*0Sstevel@tonic-gate *
207*0Sstevel@tonic-gate * Description:
208*0Sstevel@tonic-gate * Arguments:
209*0Sstevel@tonic-gate * Returns:
210*0Sstevel@tonic-gate * Preconditions:
211*0Sstevel@tonic-gate */
212*0Sstevel@tonic-gate void
fscache_setup(cfsd_fscache_object_t * fscache_object_p)213*0Sstevel@tonic-gate fscache_setup(cfsd_fscache_object_t *fscache_object_p)
214*0Sstevel@tonic-gate {
215*0Sstevel@tonic-gate char *tmp;
216*0Sstevel@tonic-gate char cfs_mnt_filename[MAXPATHLEN];
217*0Sstevel@tonic-gate FILE *fin;
218*0Sstevel@tonic-gate /*
219*0Sstevel@tonic-gate * Line input buffer allows for type field (magic number size
220*0Sstevel@tonic-gate * of 50 is historic), the field separator ": ", a large value
221*0Sstevel@tonic-gate * (again historic) and a '\n' character.
222*0Sstevel@tonic-gate */
223*0Sstevel@tonic-gate char type[50];
224*0Sstevel@tonic-gate char value[MAXPATHLEN * 4];
225*0Sstevel@tonic-gate char buf[sizeof (type) + 2 + sizeof (value) + 1];
226*0Sstevel@tonic-gate int err = 0;
227*0Sstevel@tonic-gate int xx;
228*0Sstevel@tonic-gate char *options[] = { "snr", "disconnectable", NULL };
229*0Sstevel@tonic-gate char *strp = buf;
230*0Sstevel@tonic-gate char *dummy;
231*0Sstevel@tonic-gate struct stat64 sinfo;
232*0Sstevel@tonic-gate time_t mtime;
233*0Sstevel@tonic-gate
234*0Sstevel@tonic-gate dbug_enter("fscache_setup");
235*0Sstevel@tonic-gate dbug_precond(fscache_object_p);
236*0Sstevel@tonic-gate
237*0Sstevel@tonic-gate fscache_object_p->i_modify++;
238*0Sstevel@tonic-gate fscache_object_p->i_disconnectable = 0;
239*0Sstevel@tonic-gate fscache_object_p->i_connected = 0;
240*0Sstevel@tonic-gate fscache_object_p->i_reconcile = 0;
241*0Sstevel@tonic-gate fscache_object_p->i_changes = 0;
242*0Sstevel@tonic-gate fscache_object_p->i_time_state = 0;
243*0Sstevel@tonic-gate fscache_object_p->i_time_mnt = 0;
244*0Sstevel@tonic-gate fscache_object_p->i_mntpt[0] = '\0';
245*0Sstevel@tonic-gate fscache_object_p->i_backfs[0] = '\0';
246*0Sstevel@tonic-gate fscache_object_p->i_backpath[0] = '\0';
247*0Sstevel@tonic-gate fscache_object_p->i_backfstype[0] = '\0';
248*0Sstevel@tonic-gate fscache_object_p->i_cfsopt[0] = '\0';
249*0Sstevel@tonic-gate fscache_object_p->i_bfsopt[0] = '\0';
250*0Sstevel@tonic-gate
251*0Sstevel@tonic-gate snprintf(cfs_mnt_filename, sizeof (cfs_mnt_filename), "%s/%s/%s",
252*0Sstevel@tonic-gate fscache_object_p->i_cachepath, fscache_object_p->i_name,
253*0Sstevel@tonic-gate CACHEFS_MNT_FILE);
254*0Sstevel@tonic-gate
255*0Sstevel@tonic-gate /* open for reading the file with the mount information */
256*0Sstevel@tonic-gate fin = fopen(cfs_mnt_filename, "r");
257*0Sstevel@tonic-gate if (fin == NULL) {
258*0Sstevel@tonic-gate dbug_print(("err", "could not open %s, %d", cfs_mnt_filename,
259*0Sstevel@tonic-gate errno));
260*0Sstevel@tonic-gate dbug_leave("fscache_setup");
261*0Sstevel@tonic-gate return;
262*0Sstevel@tonic-gate }
263*0Sstevel@tonic-gate /* get the modify time of the mount file */
264*0Sstevel@tonic-gate if (fstat64(fileno(fin), &sinfo) == -1) {
265*0Sstevel@tonic-gate dbug_print(("err", "could not stat %s, %d", cfs_mnt_filename,
266*0Sstevel@tonic-gate errno));
267*0Sstevel@tonic-gate if (fclose(fin))
268*0Sstevel@tonic-gate dbug_print(("err", "cannot close %s, %d",
269*0Sstevel@tonic-gate cfs_mnt_filename, errno));
270*0Sstevel@tonic-gate dbug_leave("fscache_setup");
271*0Sstevel@tonic-gate return;
272*0Sstevel@tonic-gate }
273*0Sstevel@tonic-gate mtime = sinfo.st_mtime;
274*0Sstevel@tonic-gate
275*0Sstevel@tonic-gate /* read the mount information from the file */
276*0Sstevel@tonic-gate while (fgets(buf, sizeof (buf), fin) != NULL) {
277*0Sstevel@tonic-gate tmp = strtok(buf, ":");
278*0Sstevel@tonic-gate if (strlcpy(type, tmp, sizeof (type)) >= sizeof (type)) {
279*0Sstevel@tonic-gate /* Buffer Overflow */
280*0Sstevel@tonic-gate dbug_print(("err", "overflow in type field"
281*0Sstevel@tonic-gate " of file %s", cfs_mnt_filename));
282*0Sstevel@tonic-gate if (fclose(fin))
283*0Sstevel@tonic-gate dbug_print(("err", "cannot close %s, %d",
284*0Sstevel@tonic-gate cfs_mnt_filename, errno));
285*0Sstevel@tonic-gate dbug_leave("fscache_setup");
286*0Sstevel@tonic-gate return;
287*0Sstevel@tonic-gate }
288*0Sstevel@tonic-gate tmp = strtok(NULL, "\n");
289*0Sstevel@tonic-gate if (tmp != NULL && *tmp == ' ') {
290*0Sstevel@tonic-gate /*
291*0Sstevel@tonic-gate * There is a valid value string so skip
292*0Sstevel@tonic-gate * the space after the ":".
293*0Sstevel@tonic-gate */
294*0Sstevel@tonic-gate tmp++;
295*0Sstevel@tonic-gate if (strlcpy(value, tmp, sizeof (value))
296*0Sstevel@tonic-gate >= sizeof (value)) {
297*0Sstevel@tonic-gate /* Buffer Overflow */
298*0Sstevel@tonic-gate dbug_print(("err",
299*0Sstevel@tonic-gate "overflow in value field"
300*0Sstevel@tonic-gate " of file %s", cfs_mnt_filename));
301*0Sstevel@tonic-gate if (fclose(fin))
302*0Sstevel@tonic-gate dbug_print(("err",
303*0Sstevel@tonic-gate "cannot close %s, %d",
304*0Sstevel@tonic-gate cfs_mnt_filename, errno));
305*0Sstevel@tonic-gate dbug_leave("fscache_setup");
306*0Sstevel@tonic-gate return;
307*0Sstevel@tonic-gate }
308*0Sstevel@tonic-gate } else {
309*0Sstevel@tonic-gate value[0] = '\0';
310*0Sstevel@tonic-gate }
311*0Sstevel@tonic-gate dbug_print(("info", "\"%s\" \"%s\"", type, value));
312*0Sstevel@tonic-gate if (strcmp(type, "cachedir") == 0) {
313*0Sstevel@tonic-gate if (strcmp(fscache_object_p->i_cachepath, value) != 0) {
314*0Sstevel@tonic-gate err = 1;
315*0Sstevel@tonic-gate dbug_print(("err", "caches do not match %s, %s",
316*0Sstevel@tonic-gate fscache_object_p->i_cachepath, buf));
317*0Sstevel@tonic-gate }
318*0Sstevel@tonic-gate } else if (strcmp(type, "mnt_point") == 0) {
319*0Sstevel@tonic-gate strlcpy(fscache_object_p->i_mntpt, value,
320*0Sstevel@tonic-gate sizeof (fscache_object_p->i_mntpt));
321*0Sstevel@tonic-gate } else if (strcmp(type, "special") == 0) {
322*0Sstevel@tonic-gate strlcpy(fscache_object_p->i_backfs, value,
323*0Sstevel@tonic-gate sizeof (fscache_object_p->i_backfs));
324*0Sstevel@tonic-gate } else if (strcmp(type, "backpath") == 0) {
325*0Sstevel@tonic-gate strlcpy(fscache_object_p->i_backpath, value,
326*0Sstevel@tonic-gate sizeof (fscache_object_p->i_backpath));
327*0Sstevel@tonic-gate } else if (strcmp(type, "backfstype") == 0) {
328*0Sstevel@tonic-gate strlcpy(fscache_object_p->i_backfstype, value,
329*0Sstevel@tonic-gate sizeof (fscache_object_p->i_backfstype));
330*0Sstevel@tonic-gate } else if (strcmp(type, "cacheid") == 0) {
331*0Sstevel@tonic-gate if (strcmp(fscache_object_p->i_name, value) != 0) {
332*0Sstevel@tonic-gate err = 1;
333*0Sstevel@tonic-gate dbug_print(("err", "ids do not match %s, %s",
334*0Sstevel@tonic-gate fscache_object_p->i_name, value));
335*0Sstevel@tonic-gate }
336*0Sstevel@tonic-gate } else if (strcmp(type, "cachefs_options") == 0) {
337*0Sstevel@tonic-gate strlcpy(fscache_object_p->i_cfsopt, value,
338*0Sstevel@tonic-gate sizeof (fscache_object_p->i_cfsopt));
339*0Sstevel@tonic-gate } else if (strcmp(type, "backfs_options") == 0) {
340*0Sstevel@tonic-gate strlcpy(fscache_object_p->i_bfsopt, value,
341*0Sstevel@tonic-gate sizeof (fscache_object_p->i_bfsopt));
342*0Sstevel@tonic-gate } else if (strcmp(type, "mount_time") == 0) {
343*0Sstevel@tonic-gate continue;
344*0Sstevel@tonic-gate } else {
345*0Sstevel@tonic-gate dbug_print(("err", "unknown keyword \"%s\"", type));
346*0Sstevel@tonic-gate err = 1;
347*0Sstevel@tonic-gate }
348*0Sstevel@tonic-gate }
349*0Sstevel@tonic-gate if (fclose(fin))
350*0Sstevel@tonic-gate dbug_print(("err", "cannot close %s, %d",
351*0Sstevel@tonic-gate cfs_mnt_filename, errno));
352*0Sstevel@tonic-gate
353*0Sstevel@tonic-gate /* see if this is a file system that is disconnectable */
354*0Sstevel@tonic-gate if ((err == 0) &&
355*0Sstevel@tonic-gate (fscache_object_p->i_backfs[0] &&
356*0Sstevel@tonic-gate fscache_object_p->i_cfsopt[0])) {
357*0Sstevel@tonic-gate strlcpy(buf, fscache_object_p->i_cfsopt, sizeof (buf));
358*0Sstevel@tonic-gate while (*strp != '\0') {
359*0Sstevel@tonic-gate xx = getsubopt(&strp, options, &dummy);
360*0Sstevel@tonic-gate if (xx != -1) {
361*0Sstevel@tonic-gate fscache_object_p->i_disconnectable = 1;
362*0Sstevel@tonic-gate break;
363*0Sstevel@tonic-gate }
364*0Sstevel@tonic-gate }
365*0Sstevel@tonic-gate }
366*0Sstevel@tonic-gate
367*0Sstevel@tonic-gate /*
368*0Sstevel@tonic-gate * open up a fd on the sysmsg so we have a place to write
369*0Sstevel@tonic-gate * log rolling errors
370*0Sstevel@tonic-gate */
371*0Sstevel@tonic-gate if (fscache_object_p->i_disconnectable) {
372*0Sstevel@tonic-gate if (fscache_object_p->i_ofd < 0)
373*0Sstevel@tonic-gate fscache_object_p->i_ofd = open("/dev/sysmsg",
374*0Sstevel@tonic-gate O_WRONLY);
375*0Sstevel@tonic-gate if (fscache_object_p->i_ofd < 0) {
376*0Sstevel@tonic-gate fprintf(stderr,
377*0Sstevel@tonic-gate gettext("cachefsd: File system %s cannot be"
378*0Sstevel@tonic-gate " disconnected.\n"),
379*0Sstevel@tonic-gate fscache_object_p->i_mntpt);
380*0Sstevel@tonic-gate fprintf(stderr,
381*0Sstevel@tonic-gate gettext("cachefsd: Cannot open /dev/sysmsg\n"));
382*0Sstevel@tonic-gate fscache_object_p->i_disconnectable = 0;
383*0Sstevel@tonic-gate }
384*0Sstevel@tonic-gate }
385*0Sstevel@tonic-gate
386*0Sstevel@tonic-gate /* see if the file system is mounted */
387*0Sstevel@tonic-gate snprintf(cfs_mnt_filename, sizeof (cfs_mnt_filename), "%s/%s/%s",
388*0Sstevel@tonic-gate fscache_object_p->i_cachepath, fscache_object_p->i_name,
389*0Sstevel@tonic-gate CACHEFS_UNMNT_FILE);
390*0Sstevel@tonic-gate if (stat64(cfs_mnt_filename, &sinfo) == 0) {
391*0Sstevel@tonic-gate fscache_object_p->i_mounted = 0;
392*0Sstevel@tonic-gate mtime = sinfo.st_mtime;
393*0Sstevel@tonic-gate } else
394*0Sstevel@tonic-gate fscache_object_p->i_mounted = 1;
395*0Sstevel@tonic-gate
396*0Sstevel@tonic-gate /* save the time of the last mount or unmount */
397*0Sstevel@tonic-gate fscache_object_p->i_time_mnt = mtime;
398*0Sstevel@tonic-gate
399*0Sstevel@tonic-gate dbug_print(("info", "disconnectable == %d, mounted == %d",
400*0Sstevel@tonic-gate fscache_object_p->i_disconnectable,
401*0Sstevel@tonic-gate fscache_object_p->i_mounted));
402*0Sstevel@tonic-gate dbug_leave("fscache_setup");
403*0Sstevel@tonic-gate }
404*0Sstevel@tonic-gate
405*0Sstevel@tonic-gate /*
406*0Sstevel@tonic-gate * -----------------------------------------------------------------
407*0Sstevel@tonic-gate * fscache_process
408*0Sstevel@tonic-gate *
409*0Sstevel@tonic-gate * Description:
410*0Sstevel@tonic-gate * Arguments:
411*0Sstevel@tonic-gate * Returns:
412*0Sstevel@tonic-gate * Preconditions:
413*0Sstevel@tonic-gate */
414*0Sstevel@tonic-gate void
fscache_process(cfsd_fscache_object_t * fscache_object_p)415*0Sstevel@tonic-gate fscache_process(cfsd_fscache_object_t *fscache_object_p)
416*0Sstevel@tonic-gate {
417*0Sstevel@tonic-gate int xx;
418*0Sstevel@tonic-gate int changes;
419*0Sstevel@tonic-gate cfsd_kmod_object_t *kmod_object_p;
420*0Sstevel@tonic-gate int setup = 1;
421*0Sstevel@tonic-gate int state;
422*0Sstevel@tonic-gate
423*0Sstevel@tonic-gate dbug_enter("fscache_process");
424*0Sstevel@tonic-gate dbug_precond(fscache_object_p);
425*0Sstevel@tonic-gate
426*0Sstevel@tonic-gate kmod_object_p = cfsd_kmod_create();
427*0Sstevel@tonic-gate for (;;) {
428*0Sstevel@tonic-gate fscache_lock(fscache_object_p);
429*0Sstevel@tonic-gate fscache_object_p->i_time_state = time(NULL);
430*0Sstevel@tonic-gate fscache_object_p->i_modify++;
431*0Sstevel@tonic-gate
432*0Sstevel@tonic-gate /* if we should try to unmount the file system */
433*0Sstevel@tonic-gate if (fscache_object_p->i_tryunmount) {
434*0Sstevel@tonic-gate /* shut down the interface to the kmod */
435*0Sstevel@tonic-gate if (setup == 0) {
436*0Sstevel@tonic-gate kmod_shutdown(kmod_object_p);
437*0Sstevel@tonic-gate setup = 1;
438*0Sstevel@tonic-gate }
439*0Sstevel@tonic-gate
440*0Sstevel@tonic-gate /* try to unmount the file system */
441*0Sstevel@tonic-gate if (umount(fscache_object_p->i_mntpt) == -1) {
442*0Sstevel@tonic-gate xx = errno;
443*0Sstevel@tonic-gate dbug_print(("info", "unmount failed %s",
444*0Sstevel@tonic-gate strerror(xx)));
445*0Sstevel@tonic-gate } else {
446*0Sstevel@tonic-gate fscache_object_p->i_mounted = 0;
447*0Sstevel@tonic-gate }
448*0Sstevel@tonic-gate
449*0Sstevel@tonic-gate /* wake up thread blocked in fscache_unmount */
450*0Sstevel@tonic-gate fscache_object_p->i_tryunmount = 0;
451*0Sstevel@tonic-gate xx = cond_broadcast(&fscache_object_p->i_cvwait);
452*0Sstevel@tonic-gate dbug_assert(xx == 0);
453*0Sstevel@tonic-gate
454*0Sstevel@tonic-gate /* all done if unmount succeeded */
455*0Sstevel@tonic-gate if (fscache_object_p->i_mounted == 0) {
456*0Sstevel@tonic-gate fscache_unlock(fscache_object_p);
457*0Sstevel@tonic-gate break;
458*0Sstevel@tonic-gate }
459*0Sstevel@tonic-gate }
460*0Sstevel@tonic-gate
461*0Sstevel@tonic-gate if (setup) {
462*0Sstevel@tonic-gate setup = 0;
463*0Sstevel@tonic-gate /*
464*0Sstevel@tonic-gate * make an interface into the cachefs kmod for
465*0Sstevel@tonic-gate * this fs
466*0Sstevel@tonic-gate */
467*0Sstevel@tonic-gate xx = kmod_setup(kmod_object_p,
468*0Sstevel@tonic-gate fscache_object_p->i_mntpt);
469*0Sstevel@tonic-gate if (xx != 0) {
470*0Sstevel@tonic-gate dbug_print(("err",
471*0Sstevel@tonic-gate "setup of kmod interface failed %d", xx));
472*0Sstevel@tonic-gate fscache_object_p->i_disconnectable = 0;
473*0Sstevel@tonic-gate fscache_object_p->i_modify++;
474*0Sstevel@tonic-gate fscache_unlock(fscache_object_p);
475*0Sstevel@tonic-gate break;
476*0Sstevel@tonic-gate }
477*0Sstevel@tonic-gate
478*0Sstevel@tonic-gate /* verify that we got the file system we expected XXX */
479*0Sstevel@tonic-gate }
480*0Sstevel@tonic-gate
481*0Sstevel@tonic-gate /* get the current state of the file system */
482*0Sstevel@tonic-gate state = kmod_stateget(kmod_object_p);
483*0Sstevel@tonic-gate
484*0Sstevel@tonic-gate if (fscache_object_p->i_simdis && (state == CFS_FS_CONNECTED)) {
485*0Sstevel@tonic-gate dbug_print(("simdis", "simulating disconnection on %s",
486*0Sstevel@tonic-gate fscache_object_p->i_mntpt));
487*0Sstevel@tonic-gate xx = kmod_stateset(kmod_object_p, CFS_FS_DISCONNECTED);
488*0Sstevel@tonic-gate dbug_assert(xx == 0);
489*0Sstevel@tonic-gate state = kmod_stateget(kmod_object_p);
490*0Sstevel@tonic-gate dbug_assert(state == CFS_FS_DISCONNECTED);
491*0Sstevel@tonic-gate }
492*0Sstevel@tonic-gate fscache_unlock(fscache_object_p);
493*0Sstevel@tonic-gate
494*0Sstevel@tonic-gate switch (state) {
495*0Sstevel@tonic-gate case CFS_FS_CONNECTED:
496*0Sstevel@tonic-gate fscache_lock(fscache_object_p);
497*0Sstevel@tonic-gate fscache_object_p->i_connected = 1;
498*0Sstevel@tonic-gate fscache_object_p->i_reconcile = 0;
499*0Sstevel@tonic-gate fscache_object_p->i_modify++;
500*0Sstevel@tonic-gate fscache_unlock(fscache_object_p);
501*0Sstevel@tonic-gate
502*0Sstevel@tonic-gate /* wait for fs to switch to disconnecting */
503*0Sstevel@tonic-gate dbug_print(("info", "about to xwait"));
504*0Sstevel@tonic-gate xx = kmod_xwait(kmod_object_p);
505*0Sstevel@tonic-gate if (xx == EINTR) {
506*0Sstevel@tonic-gate dbug_print(("info", "a. EINTR from xwait"));
507*0Sstevel@tonic-gate continue;
508*0Sstevel@tonic-gate }
509*0Sstevel@tonic-gate dbug_assert(xx == 0);
510*0Sstevel@tonic-gate state = kmod_stateget(kmod_object_p);
511*0Sstevel@tonic-gate dbug_assert(state == CFS_FS_DISCONNECTED);
512*0Sstevel@tonic-gate break;
513*0Sstevel@tonic-gate
514*0Sstevel@tonic-gate case CFS_FS_DISCONNECTED:
515*0Sstevel@tonic-gate fscache_lock(fscache_object_p);
516*0Sstevel@tonic-gate fscache_object_p->i_connected = 0;
517*0Sstevel@tonic-gate fscache_object_p->i_reconcile = 0;
518*0Sstevel@tonic-gate fscache_object_p->i_modify++;
519*0Sstevel@tonic-gate fscache_unlock(fscache_object_p);
520*0Sstevel@tonic-gate
521*0Sstevel@tonic-gate /* wait until we are reconnected */
522*0Sstevel@tonic-gate fscache_server_alive(fscache_object_p, kmod_object_p);
523*0Sstevel@tonic-gate if (fscache_object_p->i_tryunmount)
524*0Sstevel@tonic-gate continue;
525*0Sstevel@tonic-gate
526*0Sstevel@tonic-gate /* switch to reconnecting mode */
527*0Sstevel@tonic-gate xx = kmod_stateset(kmod_object_p, CFS_FS_RECONNECTING);
528*0Sstevel@tonic-gate dbug_assert(xx == 0);
529*0Sstevel@tonic-gate break;
530*0Sstevel@tonic-gate
531*0Sstevel@tonic-gate case CFS_FS_RECONNECTING:
532*0Sstevel@tonic-gate fscache_lock(fscache_object_p);
533*0Sstevel@tonic-gate fscache_object_p->i_connected = 1;
534*0Sstevel@tonic-gate fscache_object_p->i_reconcile = 1;
535*0Sstevel@tonic-gate fscache_object_p->i_modify++;
536*0Sstevel@tonic-gate changes = fscache_object_p->i_changes;
537*0Sstevel@tonic-gate fscache_unlock(fscache_object_p);
538*0Sstevel@tonic-gate
539*0Sstevel@tonic-gate /* roll the log */
540*0Sstevel@tonic-gate xx = fscache_roll(fscache_object_p, kmod_object_p);
541*0Sstevel@tonic-gate if (xx) {
542*0Sstevel@tonic-gate dbug_assert(xx == ETIMEDOUT);
543*0Sstevel@tonic-gate /* switch to disconnected */
544*0Sstevel@tonic-gate xx = kmod_stateset(kmod_object_p,
545*0Sstevel@tonic-gate CFS_FS_DISCONNECTED);
546*0Sstevel@tonic-gate dbug_assert(xx == 0);
547*0Sstevel@tonic-gate } else {
548*0Sstevel@tonic-gate /* switch to connected */
549*0Sstevel@tonic-gate xx = kmod_stateset(kmod_object_p,
550*0Sstevel@tonic-gate CFS_FS_CONNECTED);
551*0Sstevel@tonic-gate dbug_assert(xx == 0);
552*0Sstevel@tonic-gate changes = 0;
553*0Sstevel@tonic-gate }
554*0Sstevel@tonic-gate
555*0Sstevel@tonic-gate fscache_lock(fscache_object_p);
556*0Sstevel@tonic-gate fscache_object_p->i_reconcile = 0;
557*0Sstevel@tonic-gate fscache_changes(fscache_object_p, changes);
558*0Sstevel@tonic-gate fscache_object_p->i_modify++;
559*0Sstevel@tonic-gate fscache_unlock(fscache_object_p);
560*0Sstevel@tonic-gate
561*0Sstevel@tonic-gate break;
562*0Sstevel@tonic-gate
563*0Sstevel@tonic-gate default:
564*0Sstevel@tonic-gate dbug_assert(0);
565*0Sstevel@tonic-gate break;
566*0Sstevel@tonic-gate }
567*0Sstevel@tonic-gate }
568*0Sstevel@tonic-gate cfsd_kmod_destroy(kmod_object_p);
569*0Sstevel@tonic-gate dbug_leave("fscache_process");
570*0Sstevel@tonic-gate }
571*0Sstevel@tonic-gate
572*0Sstevel@tonic-gate /*
573*0Sstevel@tonic-gate * fscache_simdisconnect
574*0Sstevel@tonic-gate *
575*0Sstevel@tonic-gate * Description:
576*0Sstevel@tonic-gate * Simulates disconnection or reconnects from a simulated disconnection.
577*0Sstevel@tonic-gate * Arguments:
578*0Sstevel@tonic-gate * disconnect 1 means disconnect, !1 means connect
579*0Sstevel@tonic-gate * Returns:
580*0Sstevel@tonic-gate * Returns 0 for success, !0 on an error
581*0Sstevel@tonic-gate * Preconditions:
582*0Sstevel@tonic-gate */
583*0Sstevel@tonic-gate int
fscache_simdisconnect(cfsd_fscache_object_t * fscache_object_p,int disconnect)584*0Sstevel@tonic-gate fscache_simdisconnect(cfsd_fscache_object_t *fscache_object_p, int disconnect)
585*0Sstevel@tonic-gate {
586*0Sstevel@tonic-gate
587*0Sstevel@tonic-gate int xx;
588*0Sstevel@tonic-gate int ret = 0;
589*0Sstevel@tonic-gate char *strp;
590*0Sstevel@tonic-gate int tcon;
591*0Sstevel@tonic-gate int trec;
592*0Sstevel@tonic-gate
593*0Sstevel@tonic-gate dbug_enter("fscache_simdisconnect");
594*0Sstevel@tonic-gate dbug_precond(fscache_object_p);
595*0Sstevel@tonic-gate
596*0Sstevel@tonic-gate strp = disconnect ? "disconnection" : "reconnection";
597*0Sstevel@tonic-gate
598*0Sstevel@tonic-gate dbug_print(("simdis", "About to simulate %s", strp));
599*0Sstevel@tonic-gate
600*0Sstevel@tonic-gate fscache_lock(fscache_object_p);
601*0Sstevel@tonic-gate
602*0Sstevel@tonic-gate if (disconnect) {
603*0Sstevel@tonic-gate /* if file system cannot be disconnected */
604*0Sstevel@tonic-gate if (fscache_object_p->i_disconnectable == 0) {
605*0Sstevel@tonic-gate ret = 1;
606*0Sstevel@tonic-gate goto out;
607*0Sstevel@tonic-gate }
608*0Sstevel@tonic-gate
609*0Sstevel@tonic-gate /* if file system is already disconnected */
610*0Sstevel@tonic-gate if (fscache_object_p->i_connected == 0) {
611*0Sstevel@tonic-gate ret = 2;
612*0Sstevel@tonic-gate goto out;
613*0Sstevel@tonic-gate }
614*0Sstevel@tonic-gate fscache_object_p->i_simdis = 1;
615*0Sstevel@tonic-gate } else {
616*0Sstevel@tonic-gate /* if file system is already connected */
617*0Sstevel@tonic-gate if (fscache_object_p->i_connected) {
618*0Sstevel@tonic-gate ret = 1;
619*0Sstevel@tonic-gate goto out;
620*0Sstevel@tonic-gate }
621*0Sstevel@tonic-gate
622*0Sstevel@tonic-gate /* if file system is not "simulated" disconnected */
623*0Sstevel@tonic-gate if (fscache_object_p->i_simdis == 0) {
624*0Sstevel@tonic-gate ret = 2;
625*0Sstevel@tonic-gate goto out;
626*0Sstevel@tonic-gate }
627*0Sstevel@tonic-gate fscache_object_p->i_simdis = 0;
628*0Sstevel@tonic-gate }
629*0Sstevel@tonic-gate
630*0Sstevel@tonic-gate /* if fs thread not running */
631*0Sstevel@tonic-gate if (fscache_object_p->i_threaded == 0) {
632*0Sstevel@tonic-gate if (fscache_object_p->i_mounted) {
633*0Sstevel@tonic-gate dbug_print(("simdis", "thread not running"));
634*0Sstevel@tonic-gate ret = -1;
635*0Sstevel@tonic-gate } else {
636*0Sstevel@tonic-gate if (fscache_object_p->i_simdis)
637*0Sstevel@tonic-gate fscache_object_p->i_connected = 0;
638*0Sstevel@tonic-gate else
639*0Sstevel@tonic-gate fscache_object_p->i_connected = 1;
640*0Sstevel@tonic-gate }
641*0Sstevel@tonic-gate goto out;
642*0Sstevel@tonic-gate }
643*0Sstevel@tonic-gate
644*0Sstevel@tonic-gate /* get the attention of the thread */
645*0Sstevel@tonic-gate dbug_print(("info", "thread %d, killing %d with sigusr1",
646*0Sstevel@tonic-gate thr_self(), fscache_object_p->i_threadid));
647*0Sstevel@tonic-gate xx = thr_kill(fscache_object_p->i_threadid, SIGUSR1);
648*0Sstevel@tonic-gate if (xx) {
649*0Sstevel@tonic-gate dbug_print(("simdis", "thr_kill failed %d, threadid %d",
650*0Sstevel@tonic-gate xx, fscache_object_p->i_threadid));
651*0Sstevel@tonic-gate ret = -1;
652*0Sstevel@tonic-gate }
653*0Sstevel@tonic-gate
654*0Sstevel@tonic-gate out:
655*0Sstevel@tonic-gate fscache_unlock(fscache_object_p);
656*0Sstevel@tonic-gate
657*0Sstevel@tonic-gate if (ret == 0) {
658*0Sstevel@tonic-gate for (;;) {
659*0Sstevel@tonic-gate dbug_print(("simdis", " waiting for simulated %s",
660*0Sstevel@tonic-gate strp));
661*0Sstevel@tonic-gate fscache_lock(fscache_object_p);
662*0Sstevel@tonic-gate tcon = fscache_object_p->i_connected;
663*0Sstevel@tonic-gate trec = fscache_object_p->i_reconcile;
664*0Sstevel@tonic-gate fscache_unlock(fscache_object_p);
665*0Sstevel@tonic-gate if (disconnect) {
666*0Sstevel@tonic-gate if (tcon == 0)
667*0Sstevel@tonic-gate break;
668*0Sstevel@tonic-gate } else {
669*0Sstevel@tonic-gate if ((tcon == 1) && (trec == 0))
670*0Sstevel@tonic-gate break;
671*0Sstevel@tonic-gate }
672*0Sstevel@tonic-gate cfsd_sleep(1);
673*0Sstevel@tonic-gate }
674*0Sstevel@tonic-gate dbug_print(("simdis", "DONE waiting for simulated %s", strp));
675*0Sstevel@tonic-gate } else {
676*0Sstevel@tonic-gate dbug_print(("simdis", "simulated %s failed %d", strp, ret));
677*0Sstevel@tonic-gate }
678*0Sstevel@tonic-gate
679*0Sstevel@tonic-gate dbug_leave("fscache_simdisconnect");
680*0Sstevel@tonic-gate return (ret);
681*0Sstevel@tonic-gate }
682*0Sstevel@tonic-gate
683*0Sstevel@tonic-gate /*
684*0Sstevel@tonic-gate * fscache_unmount
685*0Sstevel@tonic-gate *
686*0Sstevel@tonic-gate * Description:
687*0Sstevel@tonic-gate * Called to unmount the file system.
688*0Sstevel@tonic-gate * Arguments:
689*0Sstevel@tonic-gate * Returns:
690*0Sstevel@tonic-gate * Returns 0 if the unmount is successful
691*0Sstevel@tonic-gate * EIO if an error
692*0Sstevel@tonic-gate * EBUSY if did not unmount because busy
693*0Sstevel@tonic-gate * EAGAIN if umounted but should not unmount nfs mount
694*0Sstevel@tonic-gate * ENOTSUP - forced unmount is not supported by cachefs
695*0Sstevel@tonic-gate * Preconditions:
696*0Sstevel@tonic-gate */
697*0Sstevel@tonic-gate
698*0Sstevel@tonic-gate int
fscache_unmount(cfsd_fscache_object_t * fscache_object_p,int flag)699*0Sstevel@tonic-gate fscache_unmount(cfsd_fscache_object_t *fscache_object_p, int flag)
700*0Sstevel@tonic-gate {
701*0Sstevel@tonic-gate int xx;
702*0Sstevel@tonic-gate int ret = 0;
703*0Sstevel@tonic-gate
704*0Sstevel@tonic-gate dbug_enter("fscache_unmount");
705*0Sstevel@tonic-gate dbug_precond(fscache_object_p);
706*0Sstevel@tonic-gate
707*0Sstevel@tonic-gate fscache_lock(fscache_object_p);
708*0Sstevel@tonic-gate
709*0Sstevel@tonic-gate /* if there is a thread running */
710*0Sstevel@tonic-gate if (fscache_object_p->i_threaded) {
711*0Sstevel@tonic-gate /* do not bother unmounting if rolling the log */
712*0Sstevel@tonic-gate if (fscache_object_p->i_reconcile) {
713*0Sstevel@tonic-gate ret = EBUSY;
714*0Sstevel@tonic-gate goto out;
715*0Sstevel@tonic-gate }
716*0Sstevel@tonic-gate
717*0Sstevel@tonic-gate /* inform the thread to try the unmount */
718*0Sstevel@tonic-gate fscache_object_p->i_tryunmount = 1;
719*0Sstevel@tonic-gate fscache_object_p->i_modify++;
720*0Sstevel@tonic-gate
721*0Sstevel@tonic-gate /* get the attention of the thread */
722*0Sstevel@tonic-gate dbug_print(("info", "about to do umount kill"));
723*0Sstevel@tonic-gate xx = thr_kill(fscache_object_p->i_threadid, SIGUSR1);
724*0Sstevel@tonic-gate if (xx) {
725*0Sstevel@tonic-gate dbug_print(("error", "thr_kill failed %d, threadid %d",
726*0Sstevel@tonic-gate xx, fscache_object_p->i_threadid));
727*0Sstevel@tonic-gate ret = EIO;
728*0Sstevel@tonic-gate goto out;
729*0Sstevel@tonic-gate }
730*0Sstevel@tonic-gate
731*0Sstevel@tonic-gate /* wait for the thread to wake us up */
732*0Sstevel@tonic-gate while (fscache_object_p->i_tryunmount) {
733*0Sstevel@tonic-gate xx = cond_wait(&fscache_object_p->i_cvwait,
734*0Sstevel@tonic-gate &fscache_object_p->i_lock);
735*0Sstevel@tonic-gate dbug_print(("info", "cond_wait woke up %d %d",
736*0Sstevel@tonic-gate xx, fscache_object_p->i_tryunmount));
737*0Sstevel@tonic-gate }
738*0Sstevel@tonic-gate
739*0Sstevel@tonic-gate /* if the file system is still mounted */
740*0Sstevel@tonic-gate if (fscache_object_p->i_mounted)
741*0Sstevel@tonic-gate ret = EBUSY;
742*0Sstevel@tonic-gate }
743*0Sstevel@tonic-gate
744*0Sstevel@tonic-gate /* else if there is no thread running */
745*0Sstevel@tonic-gate else {
746*0Sstevel@tonic-gate /* try to unmount the file system */
747*0Sstevel@tonic-gate if (umount2(fscache_object_p->i_mntpt, flag) == -1) {
748*0Sstevel@tonic-gate xx = errno;
749*0Sstevel@tonic-gate dbug_print(("info", "unmount failed %s",
750*0Sstevel@tonic-gate strerror(xx)));
751*0Sstevel@tonic-gate if (xx == EBUSY)
752*0Sstevel@tonic-gate ret = EBUSY;
753*0Sstevel@tonic-gate else if (xx == ENOTSUP)
754*0Sstevel@tonic-gate ret = ENOTSUP;
755*0Sstevel@tonic-gate else
756*0Sstevel@tonic-gate ret = EIO;
757*0Sstevel@tonic-gate } else {
758*0Sstevel@tonic-gate fscache_object_p->i_mounted = 0;
759*0Sstevel@tonic-gate fscache_object_p->i_modify++;
760*0Sstevel@tonic-gate }
761*0Sstevel@tonic-gate }
762*0Sstevel@tonic-gate out:
763*0Sstevel@tonic-gate fscache_unlock(fscache_object_p);
764*0Sstevel@tonic-gate dbug_leave("fscache_unmount");
765*0Sstevel@tonic-gate return (ret);
766*0Sstevel@tonic-gate }
767*0Sstevel@tonic-gate
768*0Sstevel@tonic-gate /*
769*0Sstevel@tonic-gate * -----------------------------------------------------------------
770*0Sstevel@tonic-gate * fscache_server_alive
771*0Sstevel@tonic-gate *
772*0Sstevel@tonic-gate * Description:
773*0Sstevel@tonic-gate * Arguments:
774*0Sstevel@tonic-gate * Returns:
775*0Sstevel@tonic-gate * Preconditions:
776*0Sstevel@tonic-gate */
777*0Sstevel@tonic-gate void
fscache_server_alive(cfsd_fscache_object_t * fscache_object_p,cfsd_kmod_object_t * kmod_object_p)778*0Sstevel@tonic-gate fscache_server_alive(cfsd_fscache_object_t *fscache_object_p,
779*0Sstevel@tonic-gate cfsd_kmod_object_t *kmod_object_p)
780*0Sstevel@tonic-gate {
781*0Sstevel@tonic-gate
782*0Sstevel@tonic-gate int xx;
783*0Sstevel@tonic-gate cfs_fid_t rootfid;
784*0Sstevel@tonic-gate dl_cred_t cr;
785*0Sstevel@tonic-gate cfs_vattr_t va;
786*0Sstevel@tonic-gate char cfsopt[CFS_MAXMNTOPTLEN];
787*0Sstevel@tonic-gate int child_pid;
788*0Sstevel@tonic-gate int stat_loc;
789*0Sstevel@tonic-gate
790*0Sstevel@tonic-gate dbug_enter("fscache_server_alive");
791*0Sstevel@tonic-gate
792*0Sstevel@tonic-gate dbug_precond(fscache_object_p);
793*0Sstevel@tonic-gate dbug_precond(kmod_object_p);
794*0Sstevel@tonic-gate
795*0Sstevel@tonic-gate for (;;) {
796*0Sstevel@tonic-gate /* wait for a little while */
797*0Sstevel@tonic-gate if (fscache_object_p->i_simdis == 0)
798*0Sstevel@tonic-gate cfsd_sleep(30);
799*0Sstevel@tonic-gate /* if simulating disconnect */
800*0Sstevel@tonic-gate fscache_lock(fscache_object_p);
801*0Sstevel@tonic-gate while (fscache_object_p->i_simdis &&
802*0Sstevel@tonic-gate !fscache_object_p->i_tryunmount) {
803*0Sstevel@tonic-gate dbug_print(("simdis", "before calling cond_wait"));
804*0Sstevel@tonic-gate xx = cond_wait(&fscache_object_p->i_cvwait,
805*0Sstevel@tonic-gate &fscache_object_p->i_lock);
806*0Sstevel@tonic-gate dbug_print(("simdis", "cond_wait woke up %d %d",
807*0Sstevel@tonic-gate xx, fscache_object_p->i_simdis));
808*0Sstevel@tonic-gate }
809*0Sstevel@tonic-gate fscache_unlock(fscache_object_p);
810*0Sstevel@tonic-gate
811*0Sstevel@tonic-gate if (fscache_object_p->i_tryunmount)
812*0Sstevel@tonic-gate break;
813*0Sstevel@tonic-gate
814*0Sstevel@tonic-gate /* see if the server is alive */
815*0Sstevel@tonic-gate if (fscache_pingserver(fscache_object_p) == -1) {
816*0Sstevel@tonic-gate /* dead server */
817*0Sstevel@tonic-gate continue;
818*0Sstevel@tonic-gate }
819*0Sstevel@tonic-gate
820*0Sstevel@tonic-gate /* try to mount the back file system if needed */
821*0Sstevel@tonic-gate if (fscache_object_p->i_backpath[0] == '\0') {
822*0Sstevel@tonic-gate dbug_precond(fscache_object_p->i_cfsopt[0]);
823*0Sstevel@tonic-gate dbug_precond(fscache_object_p->i_backfs[0]);
824*0Sstevel@tonic-gate dbug_precond(fscache_object_p->i_mntpt[0]);
825*0Sstevel@tonic-gate
826*0Sstevel@tonic-gate snprintf(cfsopt, sizeof (cfsopt), "%s,slide,remount",
827*0Sstevel@tonic-gate fscache_object_p->i_cfsopt);
828*0Sstevel@tonic-gate /*
829*0Sstevel@tonic-gate * Mounting of a cachefs file system is done by calling
830*0Sstevel@tonic-gate * out to /usr/lib/fs/cachefs/mount so that mounts
831*0Sstevel@tonic-gate * done by the user, autofs and by us here in cachefsd
832*0Sstevel@tonic-gate * are consistent.
833*0Sstevel@tonic-gate */
834*0Sstevel@tonic-gate switch ((child_pid = fork1())) {
835*0Sstevel@tonic-gate case -1:
836*0Sstevel@tonic-gate /*
837*0Sstevel@tonic-gate * The original code used system()
838*0Sstevel@tonic-gate * but never checked for an error
839*0Sstevel@tonic-gate * occurring. The rest of the code
840*0Sstevel@tonic-gate * would suggest that "continue" is
841*0Sstevel@tonic-gate * the correct thing to do.
842*0Sstevel@tonic-gate */
843*0Sstevel@tonic-gate dbug_print(("info", "unable to fork mount "
844*0Sstevel@tonic-gate "process for back fs %s %d",
845*0Sstevel@tonic-gate fscache_object_p->i_backfs, errno));
846*0Sstevel@tonic-gate continue;
847*0Sstevel@tonic-gate case 0:
848*0Sstevel@tonic-gate (void) setsid();
849*0Sstevel@tonic-gate execl("/usr/sbin/mount", "mount", "-F",
850*0Sstevel@tonic-gate "cachefs", "-o", cfsopt,
851*0Sstevel@tonic-gate fscache_object_p->i_backfs,
852*0Sstevel@tonic-gate fscache_object_p->i_mntpt, NULL);
853*0Sstevel@tonic-gate break;
854*0Sstevel@tonic-gate default:
855*0Sstevel@tonic-gate (void) waitpid(child_pid, &stat_loc, WUNTRACED);
856*0Sstevel@tonic-gate }
857*0Sstevel@tonic-gate
858*0Sstevel@tonic-gate }
859*0Sstevel@tonic-gate
860*0Sstevel@tonic-gate /* get the root fid of the file system */
861*0Sstevel@tonic-gate xx = kmod_rootfid(kmod_object_p, &rootfid);
862*0Sstevel@tonic-gate if (xx) {
863*0Sstevel@tonic-gate dbug_print(("info", "could not mount back fs %s %d",
864*0Sstevel@tonic-gate fscache_object_p->i_backfs, xx));
865*0Sstevel@tonic-gate continue;
866*0Sstevel@tonic-gate }
867*0Sstevel@tonic-gate
868*0Sstevel@tonic-gate /* dummy up a fake kcred */
869*0Sstevel@tonic-gate (void) memset(&cr, 0, sizeof (cr));
870*0Sstevel@tonic-gate
871*0Sstevel@tonic-gate /* try to get attrs on the root */
872*0Sstevel@tonic-gate xx = kmod_getattrfid(kmod_object_p, &rootfid, &cr, &va);
873*0Sstevel@tonic-gate if ((xx == ETIMEDOUT) || (xx == EIO)) {
874*0Sstevel@tonic-gate dbug_print(("info", "Bogus error %d", xx));
875*0Sstevel@tonic-gate continue;
876*0Sstevel@tonic-gate }
877*0Sstevel@tonic-gate break;
878*0Sstevel@tonic-gate }
879*0Sstevel@tonic-gate dbug_leave("fscache_server_alive");
880*0Sstevel@tonic-gate }
881*0Sstevel@tonic-gate
882*0Sstevel@tonic-gate /*
883*0Sstevel@tonic-gate * fscache_pingserver
884*0Sstevel@tonic-gate *
885*0Sstevel@tonic-gate * Description:
886*0Sstevel@tonic-gate * Trys to ping the nfs server to see if it is alive.
887*0Sstevel@tonic-gate * Arguments:
888*0Sstevel@tonic-gate * Returns:
889*0Sstevel@tonic-gate * Returns 0 if it is alive, -1 if no answer.
890*0Sstevel@tonic-gate * Preconditions:
891*0Sstevel@tonic-gate */
892*0Sstevel@tonic-gate
893*0Sstevel@tonic-gate int
fscache_pingserver(cfsd_fscache_object_t * fscache_object_p)894*0Sstevel@tonic-gate fscache_pingserver(cfsd_fscache_object_t *fscache_object_p)
895*0Sstevel@tonic-gate {
896*0Sstevel@tonic-gate
897*0Sstevel@tonic-gate static struct timeval TIMEOUT = { 25, 0 };
898*0Sstevel@tonic-gate CLIENT *clnt;
899*0Sstevel@tonic-gate enum clnt_stat retval;
900*0Sstevel@tonic-gate int ret = 0;
901*0Sstevel@tonic-gate char hostname[sizeof (fscache_object_p->i_backfs)];
902*0Sstevel@tonic-gate char *cptr;
903*0Sstevel@tonic-gate
904*0Sstevel@tonic-gate dbug_enter("fscache_pingserver");
905*0Sstevel@tonic-gate dbug_precond(fscache_object_p);
906*0Sstevel@tonic-gate
907*0Sstevel@tonic-gate strlcpy(hostname, fscache_object_p->i_backfs, sizeof (hostname));
908*0Sstevel@tonic-gate if (cptr = strchr(hostname, ':'))
909*0Sstevel@tonic-gate *cptr = '\0';
910*0Sstevel@tonic-gate
911*0Sstevel@tonic-gate dbug_assert(cptr != NULL);
912*0Sstevel@tonic-gate dbug_print(("info", "remote host '%s' before clnt_create", hostname));
913*0Sstevel@tonic-gate
914*0Sstevel@tonic-gate dbug_print(("info", "before clnt_create"));
915*0Sstevel@tonic-gate /* XXX this takes 75 seconds to time out */
916*0Sstevel@tonic-gate /* XXX should use lower level routines to reduce overhead */
917*0Sstevel@tonic-gate clnt = clnt_create(hostname, NFS_PROGRAM, NFS_VERSION, "udp");
918*0Sstevel@tonic-gate if (clnt == NULL) {
919*0Sstevel@tonic-gate /* XXX what if this fails other than TIMEDOUT */
920*0Sstevel@tonic-gate /* clnt_pcreateerror(hostname); */
921*0Sstevel@tonic-gate dbug_print(("info", "clnt_create failed"));
922*0Sstevel@tonic-gate ret = -1;
923*0Sstevel@tonic-gate } else {
924*0Sstevel@tonic-gate dbug_print(("info", "before null rpc"));
925*0Sstevel@tonic-gate /* XXX this takes 45 seconds to time out */
926*0Sstevel@tonic-gate retval = clnt_call(clnt, 0, xdr_void, NULL, xdr_void, NULL,
927*0Sstevel@tonic-gate TIMEOUT);
928*0Sstevel@tonic-gate if (retval != RPC_SUCCESS) {
929*0Sstevel@tonic-gate /* clnt_perror(clnt, "null rpc call failed"); */
930*0Sstevel@tonic-gate dbug_print(("info", "null rpc call failed %d", retval));
931*0Sstevel@tonic-gate ret = -1;
932*0Sstevel@tonic-gate }
933*0Sstevel@tonic-gate clnt_destroy(clnt);
934*0Sstevel@tonic-gate }
935*0Sstevel@tonic-gate dbug_leave("fscache_pingserver");
936*0Sstevel@tonic-gate return (ret);
937*0Sstevel@tonic-gate }
938*0Sstevel@tonic-gate
939*0Sstevel@tonic-gate /*
940*0Sstevel@tonic-gate * fscache_roll
941*0Sstevel@tonic-gate *
942*0Sstevel@tonic-gate * Description:
943*0Sstevel@tonic-gate * Rolls the contents of the log to the server.
944*0Sstevel@tonic-gate * Arguments:
945*0Sstevel@tonic-gate * kmodp interface to kernel functions
946*0Sstevel@tonic-gate * Returns:
947*0Sstevel@tonic-gate * Returns 0 for success or ETIMEDOUT if a timeout error occurred.
948*0Sstevel@tonic-gate * Preconditions:
949*0Sstevel@tonic-gate * precond(kmodp)
950*0Sstevel@tonic-gate */
951*0Sstevel@tonic-gate int
fscache_roll(cfsd_fscache_object_t * fscache_object_p,cfsd_kmod_object_t * kmod_object_p)952*0Sstevel@tonic-gate fscache_roll(cfsd_fscache_object_t *fscache_object_p,
953*0Sstevel@tonic-gate cfsd_kmod_object_t *kmod_object_p)
954*0Sstevel@tonic-gate {
955*0Sstevel@tonic-gate int error = 0;
956*0Sstevel@tonic-gate cfsd_logelem_object_t *logelem_object_p;
957*0Sstevel@tonic-gate char namebuf[MAXPATHLEN];
958*0Sstevel@tonic-gate char backupfile[MAXPATHLEN];
959*0Sstevel@tonic-gate int xx;
960*0Sstevel@tonic-gate cfs_dlog_entry_t *entp;
961*0Sstevel@tonic-gate off_t next_offset;
962*0Sstevel@tonic-gate ulong_t curseq = 0;
963*0Sstevel@tonic-gate int eof = 0;
964*0Sstevel@tonic-gate char *xp;
965*0Sstevel@tonic-gate cfsd_logfile_object_t *logfile_object_p;
966*0Sstevel@tonic-gate cfsd_maptbl_object_t *maptbl_object_p;
967*0Sstevel@tonic-gate
968*0Sstevel@tonic-gate dbug_enter("fscache_roll");
969*0Sstevel@tonic-gate
970*0Sstevel@tonic-gate dbug_precond(fscache_object_p);
971*0Sstevel@tonic-gate dbug_precond(kmod_object_p);
972*0Sstevel@tonic-gate
973*0Sstevel@tonic-gate /* map in the log file */
974*0Sstevel@tonic-gate logfile_object_p = cfsd_logfile_create();
975*0Sstevel@tonic-gate
976*0Sstevel@tonic-gate snprintf(namebuf, sizeof (namebuf), "%s/%s/%s",
977*0Sstevel@tonic-gate fscache_object_p->i_cachepath, fscache_object_p->i_name,
978*0Sstevel@tonic-gate CACHEFS_DLOG_FILE);
979*0Sstevel@tonic-gate xx = logfile_setup(logfile_object_p, namebuf, CFS_DLOG_ENTRY_MAXSIZE);
980*0Sstevel@tonic-gate if (xx) {
981*0Sstevel@tonic-gate if (xx == ENOENT) {
982*0Sstevel@tonic-gate cfsd_logfile_destroy(logfile_object_p);
983*0Sstevel@tonic-gate dbug_leave("fscache_roll");
984*0Sstevel@tonic-gate return (0);
985*0Sstevel@tonic-gate }
986*0Sstevel@tonic-gate fscache_fsproblem(fscache_object_p, kmod_object_p);
987*0Sstevel@tonic-gate cfsd_logfile_destroy(logfile_object_p);
988*0Sstevel@tonic-gate dbug_leave("fscache_roll");
989*0Sstevel@tonic-gate return (0);
990*0Sstevel@tonic-gate }
991*0Sstevel@tonic-gate
992*0Sstevel@tonic-gate fscache_lock(fscache_object_p);
993*0Sstevel@tonic-gate fscache_changes(fscache_object_p, 1);
994*0Sstevel@tonic-gate fscache_unlock(fscache_object_p);
995*0Sstevel@tonic-gate
996*0Sstevel@tonic-gate /* create a hashed mapping table for changes to cids */
997*0Sstevel@tonic-gate maptbl_object_p = cfsd_maptbl_create();
998*0Sstevel@tonic-gate snprintf(namebuf, sizeof (namebuf), "%s/%s/%s",
999*0Sstevel@tonic-gate fscache_object_p->i_cachepath, fscache_object_p->i_name,
1000*0Sstevel@tonic-gate CACHEFS_DMAP_FILE);
1001*0Sstevel@tonic-gate xx = maptbl_setup(maptbl_object_p, namebuf);
1002*0Sstevel@tonic-gate if (xx) {
1003*0Sstevel@tonic-gate fscache_fsproblem(fscache_object_p, kmod_object_p);
1004*0Sstevel@tonic-gate cfsd_logfile_destroy(logfile_object_p);
1005*0Sstevel@tonic-gate cfsd_maptbl_destroy(maptbl_object_p);
1006*0Sstevel@tonic-gate dbug_leave("fscache_roll");
1007*0Sstevel@tonic-gate return (0);
1008*0Sstevel@tonic-gate }
1009*0Sstevel@tonic-gate
1010*0Sstevel@tonic-gate /*
1011*0Sstevel@tonic-gate * lock is not needed because they are only used when
1012*0Sstevel@tonic-gate * rolling the log by fscache_roll and fscache_addagain
1013*0Sstevel@tonic-gate */
1014*0Sstevel@tonic-gate fscache_object_p->i_again_offset = 0;
1015*0Sstevel@tonic-gate fscache_object_p->i_again_seq = 0;
1016*0Sstevel@tonic-gate
1017*0Sstevel@tonic-gate /* Pass 1: collect all cid to fid mappings */
1018*0Sstevel@tonic-gate next_offset = LOGFILE_ENTRY_START;
1019*0Sstevel@tonic-gate for (;;) {
1020*0Sstevel@tonic-gate /* get a pointer to the next record */
1021*0Sstevel@tonic-gate xx = logfile_entry(logfile_object_p, next_offset, &entp);
1022*0Sstevel@tonic-gate if (xx == 1)
1023*0Sstevel@tonic-gate break;
1024*0Sstevel@tonic-gate if (xx == -1) {
1025*0Sstevel@tonic-gate fscache_fsproblem(fscache_object_p, kmod_object_p);
1026*0Sstevel@tonic-gate cfsd_logfile_destroy(logfile_object_p);
1027*0Sstevel@tonic-gate cfsd_maptbl_destroy(maptbl_object_p);
1028*0Sstevel@tonic-gate dbug_leave("fscache_roll");
1029*0Sstevel@tonic-gate return (0);
1030*0Sstevel@tonic-gate }
1031*0Sstevel@tonic-gate next_offset += entp->dl_len;
1032*0Sstevel@tonic-gate
1033*0Sstevel@tonic-gate /* skip record if not valid */
1034*0Sstevel@tonic-gate if (entp->dl_valid != CFS_DLOG_VAL_COMMITTED)
1035*0Sstevel@tonic-gate continue;
1036*0Sstevel@tonic-gate
1037*0Sstevel@tonic-gate /* create an object for the appropriate log type */
1038*0Sstevel@tonic-gate logelem_object_p = NULL;
1039*0Sstevel@tonic-gate switch (entp->dl_op) {
1040*0Sstevel@tonic-gate case CFS_DLOG_CREATE:
1041*0Sstevel@tonic-gate case CFS_DLOG_REMOVE:
1042*0Sstevel@tonic-gate case CFS_DLOG_LINK:
1043*0Sstevel@tonic-gate case CFS_DLOG_RENAME:
1044*0Sstevel@tonic-gate case CFS_DLOG_MKDIR:
1045*0Sstevel@tonic-gate case CFS_DLOG_RMDIR:
1046*0Sstevel@tonic-gate case CFS_DLOG_SYMLINK:
1047*0Sstevel@tonic-gate case CFS_DLOG_SETATTR:
1048*0Sstevel@tonic-gate case CFS_DLOG_SETSECATTR:
1049*0Sstevel@tonic-gate case CFS_DLOG_MODIFIED:
1050*0Sstevel@tonic-gate case CFS_DLOG_TRAILER:
1051*0Sstevel@tonic-gate break;
1052*0Sstevel@tonic-gate
1053*0Sstevel@tonic-gate case CFS_DLOG_MAPFID:
1054*0Sstevel@tonic-gate dbug_print(("info", "mapfid"));
1055*0Sstevel@tonic-gate logelem_object_p = cfsd_logelem_mapfid_create(
1056*0Sstevel@tonic-gate maptbl_object_p, logfile_object_p,
1057*0Sstevel@tonic-gate kmod_object_p);
1058*0Sstevel@tonic-gate break;
1059*0Sstevel@tonic-gate
1060*0Sstevel@tonic-gate default:
1061*0Sstevel@tonic-gate dbug_assert(0);
1062*0Sstevel@tonic-gate fscache_fsproblem(fscache_object_p, kmod_object_p);
1063*0Sstevel@tonic-gate break;
1064*0Sstevel@tonic-gate }
1065*0Sstevel@tonic-gate
1066*0Sstevel@tonic-gate /* do not bother if ignoring the record */
1067*0Sstevel@tonic-gate if (logelem_object_p == NULL)
1068*0Sstevel@tonic-gate continue;
1069*0Sstevel@tonic-gate
1070*0Sstevel@tonic-gate /* debuggging */
1071*0Sstevel@tonic-gate logelem_dump(logelem_object_p);
1072*0Sstevel@tonic-gate
1073*0Sstevel@tonic-gate /* roll the entry */
1074*0Sstevel@tonic-gate xx = logelem_roll(logelem_object_p, (ulong_t *)NULL);
1075*0Sstevel@tonic-gate if (xx) {
1076*0Sstevel@tonic-gate fscache_fsproblem(fscache_object_p, kmod_object_p);
1077*0Sstevel@tonic-gate cfsd_logelem_destroy(logelem_object_p);
1078*0Sstevel@tonic-gate cfsd_maptbl_destroy(maptbl_object_p);
1079*0Sstevel@tonic-gate cfsd_logfile_destroy(logfile_object_p);
1080*0Sstevel@tonic-gate dbug_leave("fscache_roll");
1081*0Sstevel@tonic-gate return (0);
1082*0Sstevel@tonic-gate }
1083*0Sstevel@tonic-gate
1084*0Sstevel@tonic-gate /* mark record as completed */
1085*0Sstevel@tonic-gate entp->dl_valid = CFS_DLOG_VAL_PROCESSED;
1086*0Sstevel@tonic-gate xx = logfile_sync(logfile_object_p);
1087*0Sstevel@tonic-gate if (xx) {
1088*0Sstevel@tonic-gate fscache_fsproblem(fscache_object_p, kmod_object_p);
1089*0Sstevel@tonic-gate cfsd_logelem_destroy(logelem_object_p);
1090*0Sstevel@tonic-gate cfsd_maptbl_destroy(maptbl_object_p);
1091*0Sstevel@tonic-gate cfsd_logfile_destroy(logfile_object_p);
1092*0Sstevel@tonic-gate dbug_leave("fscache_roll");
1093*0Sstevel@tonic-gate return (0);
1094*0Sstevel@tonic-gate }
1095*0Sstevel@tonic-gate
1096*0Sstevel@tonic-gate /* destroy the object */
1097*0Sstevel@tonic-gate cfsd_logelem_destroy(logelem_object_p);
1098*0Sstevel@tonic-gate }
1099*0Sstevel@tonic-gate
1100*0Sstevel@tonic-gate /* Pass 2: modify the back file system */
1101*0Sstevel@tonic-gate next_offset = LOGFILE_ENTRY_START;
1102*0Sstevel@tonic-gate for (;;) {
1103*0Sstevel@tonic-gate /* if we need the seq number of a deferred modify */
1104*0Sstevel@tonic-gate if (fscache_object_p->i_again_offset &&
1105*0Sstevel@tonic-gate (fscache_object_p->i_again_seq == 0)) {
1106*0Sstevel@tonic-gate
1107*0Sstevel@tonic-gate /* get a pointer to the next record */
1108*0Sstevel@tonic-gate xx = logfile_entry(logfile_object_p,
1109*0Sstevel@tonic-gate fscache_object_p->i_again_offset, &entp);
1110*0Sstevel@tonic-gate if (xx == 1)
1111*0Sstevel@tonic-gate break;
1112*0Sstevel@tonic-gate if (xx == -1) {
1113*0Sstevel@tonic-gate fscache_fsproblem(fscache_object_p,
1114*0Sstevel@tonic-gate kmod_object_p);
1115*0Sstevel@tonic-gate cfsd_logfile_destroy(logfile_object_p);
1116*0Sstevel@tonic-gate cfsd_maptbl_destroy(maptbl_object_p);
1117*0Sstevel@tonic-gate dbug_leave("fscache_roll");
1118*0Sstevel@tonic-gate return (0);
1119*0Sstevel@tonic-gate }
1120*0Sstevel@tonic-gate dbug_assert(entp->dl_op == CFS_DLOG_MODIFIED);
1121*0Sstevel@tonic-gate fscache_object_p->i_again_seq = entp->dl_seq;
1122*0Sstevel@tonic-gate dbug_assert(fscache_object_p->i_again_seq != 0);
1123*0Sstevel@tonic-gate }
1124*0Sstevel@tonic-gate
1125*0Sstevel@tonic-gate /* get a pointer to the next record to process */
1126*0Sstevel@tonic-gate if (!eof) {
1127*0Sstevel@tonic-gate xx = logfile_entry(logfile_object_p, next_offset,
1128*0Sstevel@tonic-gate &entp);
1129*0Sstevel@tonic-gate if (xx == 1) {
1130*0Sstevel@tonic-gate eof = 1;
1131*0Sstevel@tonic-gate curseq = ULONG_MAX;
1132*0Sstevel@tonic-gate } else if (xx) {
1133*0Sstevel@tonic-gate break;
1134*0Sstevel@tonic-gate } else {
1135*0Sstevel@tonic-gate curseq = entp->dl_seq;
1136*0Sstevel@tonic-gate }
1137*0Sstevel@tonic-gate }
1138*0Sstevel@tonic-gate
1139*0Sstevel@tonic-gate /* if its time to process a deferred modify entry */
1140*0Sstevel@tonic-gate if (fscache_object_p->i_again_seq &&
1141*0Sstevel@tonic-gate (eof || (fscache_object_p->i_again_seq < entp->dl_seq))) {
1142*0Sstevel@tonic-gate xx = logfile_entry(logfile_object_p,
1143*0Sstevel@tonic-gate fscache_object_p->i_again_offset, &entp);
1144*0Sstevel@tonic-gate if (xx)
1145*0Sstevel@tonic-gate break;
1146*0Sstevel@tonic-gate dbug_assert(entp->dl_op == CFS_DLOG_MODIFIED);
1147*0Sstevel@tonic-gate curseq = entp->dl_seq;
1148*0Sstevel@tonic-gate fscache_object_p->i_again_offset =
1149*0Sstevel@tonic-gate entp->dl_u.dl_modify.dl_next;
1150*0Sstevel@tonic-gate fscache_object_p->i_again_seq = 0;
1151*0Sstevel@tonic-gate entp->dl_u.dl_modify.dl_next = -1;
1152*0Sstevel@tonic-gate } else if (eof) {
1153*0Sstevel@tonic-gate xx = 0;
1154*0Sstevel@tonic-gate break;
1155*0Sstevel@tonic-gate }
1156*0Sstevel@tonic-gate
1157*0Sstevel@tonic-gate /* else move the offset to the next record */
1158*0Sstevel@tonic-gate else {
1159*0Sstevel@tonic-gate next_offset += entp->dl_len;
1160*0Sstevel@tonic-gate }
1161*0Sstevel@tonic-gate
1162*0Sstevel@tonic-gate /* skip record if not valid */
1163*0Sstevel@tonic-gate if (entp->dl_valid != CFS_DLOG_VAL_COMMITTED)
1164*0Sstevel@tonic-gate continue;
1165*0Sstevel@tonic-gate
1166*0Sstevel@tonic-gate /* process the record */
1167*0Sstevel@tonic-gate xx = fscache_rollone(fscache_object_p, kmod_object_p,
1168*0Sstevel@tonic-gate maptbl_object_p, logfile_object_p, curseq);
1169*0Sstevel@tonic-gate if (xx == ETIMEDOUT) {
1170*0Sstevel@tonic-gate /* timeout error, back to disconnected */
1171*0Sstevel@tonic-gate cfsd_maptbl_destroy(maptbl_object_p);
1172*0Sstevel@tonic-gate cfsd_logfile_destroy(logfile_object_p);
1173*0Sstevel@tonic-gate dbug_print(("info", "timeout error occurred"));
1174*0Sstevel@tonic-gate dbug_leave("fscache_roll");
1175*0Sstevel@tonic-gate return (xx);
1176*0Sstevel@tonic-gate } else if (xx == EIO) {
1177*0Sstevel@tonic-gate break;
1178*0Sstevel@tonic-gate } else if (xx == EAGAIN) {
1179*0Sstevel@tonic-gate continue;
1180*0Sstevel@tonic-gate } else if (xx) {
1181*0Sstevel@tonic-gate /* should never happen */
1182*0Sstevel@tonic-gate dbug_assert(0);
1183*0Sstevel@tonic-gate break;
1184*0Sstevel@tonic-gate } else {
1185*0Sstevel@tonic-gate /* mark record as completed */
1186*0Sstevel@tonic-gate entp->dl_valid = CFS_DLOG_VAL_PROCESSED;
1187*0Sstevel@tonic-gate xx = logfile_sync(logfile_object_p);
1188*0Sstevel@tonic-gate if (xx)
1189*0Sstevel@tonic-gate break;
1190*0Sstevel@tonic-gate }
1191*0Sstevel@tonic-gate }
1192*0Sstevel@tonic-gate
1193*0Sstevel@tonic-gate /* if an unrecoverable error occurred */
1194*0Sstevel@tonic-gate if (xx) {
1195*0Sstevel@tonic-gate dbug_print(("error", "error processing log file"));
1196*0Sstevel@tonic-gate fscache_fsproblem(fscache_object_p, kmod_object_p);
1197*0Sstevel@tonic-gate }
1198*0Sstevel@tonic-gate
1199*0Sstevel@tonic-gate /* dump stats about the hash table */
1200*0Sstevel@tonic-gate maptbl_dumpstats(maptbl_object_p);
1201*0Sstevel@tonic-gate
1202*0Sstevel@tonic-gate /* dump stats about the log file */
1203*0Sstevel@tonic-gate logfile_dumpstats(logfile_object_p);
1204*0Sstevel@tonic-gate
1205*0Sstevel@tonic-gate /* debugging hack, rename the log files */
1206*0Sstevel@tonic-gate
1207*0Sstevel@tonic-gate if (snprintf(namebuf, sizeof (namebuf), "%s/%s/%s",
1208*0Sstevel@tonic-gate fscache_object_p->i_cachepath, fscache_object_p->i_name,
1209*0Sstevel@tonic-gate CACHEFS_DLOG_FILE) > ((sizeof (backupfile)) - (sizeof (".bak")))) {
1210*0Sstevel@tonic-gate dbug_print(("error", "unable to create backup dlog_file "
1211*0Sstevel@tonic-gate "for %s, path name is too long", namebuf));
1212*0Sstevel@tonic-gate } else {
1213*0Sstevel@tonic-gate /*
1214*0Sstevel@tonic-gate * No need to check return value from snprintf() as
1215*0Sstevel@tonic-gate * the previous check should suffice.
1216*0Sstevel@tonic-gate */
1217*0Sstevel@tonic-gate snprintf(backupfile, sizeof (backupfile), "%s.bak", namebuf);
1218*0Sstevel@tonic-gate if (rename(namebuf, backupfile) == -1) {
1219*0Sstevel@tonic-gate dbug_print(("error",
1220*0Sstevel@tonic-gate "unable to create backup dlog_file"));
1221*0Sstevel@tonic-gate }
1222*0Sstevel@tonic-gate }
1223*0Sstevel@tonic-gate
1224*0Sstevel@tonic-gate if (snprintf(namebuf, sizeof (namebuf), "%s/%s/%s",
1225*0Sstevel@tonic-gate fscache_object_p->i_cachepath, fscache_object_p->i_name,
1226*0Sstevel@tonic-gate CACHEFS_DMAP_FILE) > ((sizeof (backupfile)) - (sizeof (".bak")))) {
1227*0Sstevel@tonic-gate dbug_print(("error", "unable to create backup dmap_file "
1228*0Sstevel@tonic-gate "for %s, path name is too long", namebuf));
1229*0Sstevel@tonic-gate } else {
1230*0Sstevel@tonic-gate /*
1231*0Sstevel@tonic-gate * No need to check return value from snprintf() as
1232*0Sstevel@tonic-gate * the previous check should suffice.
1233*0Sstevel@tonic-gate */
1234*0Sstevel@tonic-gate snprintf(backupfile, sizeof (backupfile), "%s.bak", namebuf);
1235*0Sstevel@tonic-gate if (rename(namebuf, backupfile) == -1) {
1236*0Sstevel@tonic-gate dbug_print(("error",
1237*0Sstevel@tonic-gate "unable to create backup dmap_file"));
1238*0Sstevel@tonic-gate }
1239*0Sstevel@tonic-gate }
1240*0Sstevel@tonic-gate
1241*0Sstevel@tonic-gate /* delete the log file */
1242*0Sstevel@tonic-gate /* XXX */
1243*0Sstevel@tonic-gate
1244*0Sstevel@tonic-gate cfsd_maptbl_destroy(maptbl_object_p);
1245*0Sstevel@tonic-gate cfsd_logfile_destroy(logfile_object_p);
1246*0Sstevel@tonic-gate dbug_leave("fscache_roll");
1247*0Sstevel@tonic-gate return (error);
1248*0Sstevel@tonic-gate }
1249*0Sstevel@tonic-gate
1250*0Sstevel@tonic-gate /*
1251*0Sstevel@tonic-gate * fscache_rollone
1252*0Sstevel@tonic-gate *
1253*0Sstevel@tonic-gate * Description:
1254*0Sstevel@tonic-gate * Arguments:
1255*0Sstevel@tonic-gate * kmodp
1256*0Sstevel@tonic-gate * tblp
1257*0Sstevel@tonic-gate * lfp
1258*0Sstevel@tonic-gate * Returns:
1259*0Sstevel@tonic-gate * Returns ...
1260*0Sstevel@tonic-gate * Preconditions:
1261*0Sstevel@tonic-gate * precond(kmodp)
1262*0Sstevel@tonic-gate * precond(tblp)
1263*0Sstevel@tonic-gate * precond(lfp)
1264*0Sstevel@tonic-gate */
1265*0Sstevel@tonic-gate int
fscache_rollone(cfsd_fscache_object_t * fscache_object_p,cfsd_kmod_object_t * kmod_object_p,cfsd_maptbl_object_t * maptbl_object_p,cfsd_logfile_object_t * logfile_object_p,ulong_t seq)1266*0Sstevel@tonic-gate fscache_rollone(cfsd_fscache_object_t *fscache_object_p,
1267*0Sstevel@tonic-gate cfsd_kmod_object_t *kmod_object_p,
1268*0Sstevel@tonic-gate cfsd_maptbl_object_t *maptbl_object_p,
1269*0Sstevel@tonic-gate cfsd_logfile_object_t *logfile_object_p,
1270*0Sstevel@tonic-gate ulong_t seq)
1271*0Sstevel@tonic-gate {
1272*0Sstevel@tonic-gate cfsd_logelem_object_t *logelem_object_p = NULL;
1273*0Sstevel@tonic-gate cfs_dlog_entry_t *entp;
1274*0Sstevel@tonic-gate int xx;
1275*0Sstevel@tonic-gate char *strp;
1276*0Sstevel@tonic-gate
1277*0Sstevel@tonic-gate dbug_enter("fscache_rollone");
1278*0Sstevel@tonic-gate
1279*0Sstevel@tonic-gate dbug_precond(fscache_object_p);
1280*0Sstevel@tonic-gate dbug_precond(kmod_object_p);
1281*0Sstevel@tonic-gate dbug_precond(maptbl_object_p);
1282*0Sstevel@tonic-gate dbug_precond(logfile_object_p);
1283*0Sstevel@tonic-gate
1284*0Sstevel@tonic-gate entp = logfile_object_p->i_cur_entry;
1285*0Sstevel@tonic-gate
1286*0Sstevel@tonic-gate /* create an object for the appropriate log type */
1287*0Sstevel@tonic-gate switch (entp->dl_op) {
1288*0Sstevel@tonic-gate case CFS_DLOG_CREATE:
1289*0Sstevel@tonic-gate dbug_print(("info", "create"));
1290*0Sstevel@tonic-gate logelem_object_p = cfsd_logelem_create_create(maptbl_object_p,
1291*0Sstevel@tonic-gate logfile_object_p, kmod_object_p);
1292*0Sstevel@tonic-gate break;
1293*0Sstevel@tonic-gate
1294*0Sstevel@tonic-gate case CFS_DLOG_REMOVE:
1295*0Sstevel@tonic-gate dbug_print(("info", "remove"));
1296*0Sstevel@tonic-gate logelem_object_p = cfsd_logelem_remove_create(maptbl_object_p,
1297*0Sstevel@tonic-gate logfile_object_p, kmod_object_p);
1298*0Sstevel@tonic-gate break;
1299*0Sstevel@tonic-gate
1300*0Sstevel@tonic-gate case CFS_DLOG_LINK:
1301*0Sstevel@tonic-gate dbug_print(("info", "link"));
1302*0Sstevel@tonic-gate logelem_object_p = cfsd_logelem_link_create(maptbl_object_p,
1303*0Sstevel@tonic-gate logfile_object_p, kmod_object_p);
1304*0Sstevel@tonic-gate break;
1305*0Sstevel@tonic-gate
1306*0Sstevel@tonic-gate case CFS_DLOG_RENAME:
1307*0Sstevel@tonic-gate dbug_print(("info", "rename"));
1308*0Sstevel@tonic-gate logelem_object_p = cfsd_logelem_rename_create(maptbl_object_p,
1309*0Sstevel@tonic-gate logfile_object_p, kmod_object_p);
1310*0Sstevel@tonic-gate break;
1311*0Sstevel@tonic-gate
1312*0Sstevel@tonic-gate case CFS_DLOG_MKDIR:
1313*0Sstevel@tonic-gate dbug_print(("info", "mkdir"));
1314*0Sstevel@tonic-gate logelem_object_p = cfsd_logelem_mkdir_create(maptbl_object_p,
1315*0Sstevel@tonic-gate logfile_object_p, kmod_object_p);
1316*0Sstevel@tonic-gate break;
1317*0Sstevel@tonic-gate
1318*0Sstevel@tonic-gate case CFS_DLOG_RMDIR:
1319*0Sstevel@tonic-gate dbug_print(("info", "rmdir"));
1320*0Sstevel@tonic-gate logelem_object_p = cfsd_logelem_rmdir_create(maptbl_object_p,
1321*0Sstevel@tonic-gate logfile_object_p, kmod_object_p);
1322*0Sstevel@tonic-gate break;
1323*0Sstevel@tonic-gate
1324*0Sstevel@tonic-gate case CFS_DLOG_SYMLINK:
1325*0Sstevel@tonic-gate dbug_print(("info", "symlink"));
1326*0Sstevel@tonic-gate logelem_object_p = cfsd_logelem_symlink_create(maptbl_object_p,
1327*0Sstevel@tonic-gate logfile_object_p, kmod_object_p);
1328*0Sstevel@tonic-gate break;
1329*0Sstevel@tonic-gate
1330*0Sstevel@tonic-gate case CFS_DLOG_SETATTR:
1331*0Sstevel@tonic-gate dbug_print(("info", "setattr"));
1332*0Sstevel@tonic-gate logelem_object_p = cfsd_logelem_setattr_create(maptbl_object_p,
1333*0Sstevel@tonic-gate logfile_object_p, kmod_object_p);
1334*0Sstevel@tonic-gate break;
1335*0Sstevel@tonic-gate
1336*0Sstevel@tonic-gate case CFS_DLOG_SETSECATTR:
1337*0Sstevel@tonic-gate dbug_print(("info", "setsecattr"));
1338*0Sstevel@tonic-gate logelem_object_p = cfsd_logelem_setsecattr_create(
1339*0Sstevel@tonic-gate maptbl_object_p, logfile_object_p, kmod_object_p);
1340*0Sstevel@tonic-gate break;
1341*0Sstevel@tonic-gate
1342*0Sstevel@tonic-gate case CFS_DLOG_MODIFIED:
1343*0Sstevel@tonic-gate dbug_print(("info", "modified"));
1344*0Sstevel@tonic-gate logelem_object_p = cfsd_logelem_modified_create(maptbl_object_p,
1345*0Sstevel@tonic-gate logfile_object_p, kmod_object_p);
1346*0Sstevel@tonic-gate break;
1347*0Sstevel@tonic-gate
1348*0Sstevel@tonic-gate case CFS_DLOG_MAPFID:
1349*0Sstevel@tonic-gate dbug_print(("info", "mapfid"));
1350*0Sstevel@tonic-gate break;
1351*0Sstevel@tonic-gate
1352*0Sstevel@tonic-gate case CFS_DLOG_TRAILER:
1353*0Sstevel@tonic-gate dbug_print(("info", "trailer"));
1354*0Sstevel@tonic-gate break;
1355*0Sstevel@tonic-gate
1356*0Sstevel@tonic-gate default:
1357*0Sstevel@tonic-gate dbug_assert(0);
1358*0Sstevel@tonic-gate dbug_leave("fscache_rollone");
1359*0Sstevel@tonic-gate return (EIO);
1360*0Sstevel@tonic-gate }
1361*0Sstevel@tonic-gate
1362*0Sstevel@tonic-gate /* do not bother if ignoring the record */
1363*0Sstevel@tonic-gate if (logelem_object_p == NULL) {
1364*0Sstevel@tonic-gate dbug_print(("info", "record ignored"));
1365*0Sstevel@tonic-gate dbug_leave("fscache_rollone");
1366*0Sstevel@tonic-gate return (0);
1367*0Sstevel@tonic-gate }
1368*0Sstevel@tonic-gate
1369*0Sstevel@tonic-gate /* XXX debugging */
1370*0Sstevel@tonic-gate logelem_dump(logelem_object_p);
1371*0Sstevel@tonic-gate
1372*0Sstevel@tonic-gate /* roll the entry */
1373*0Sstevel@tonic-gate xx = logelem_roll(logelem_object_p, &seq);
1374*0Sstevel@tonic-gate
1375*0Sstevel@tonic-gate strp = logelem_object_p->i_messagep;
1376*0Sstevel@tonic-gate if (strp) {
1377*0Sstevel@tonic-gate write(fscache_object_p->i_ofd, strp, strlen(strp));
1378*0Sstevel@tonic-gate dbug_print(("conflict", "%s", strp));
1379*0Sstevel@tonic-gate }
1380*0Sstevel@tonic-gate
1381*0Sstevel@tonic-gate if (xx == EAGAIN) {
1382*0Sstevel@tonic-gate dbug_assert(entp->dl_op == CFS_DLOG_MODIFIED);
1383*0Sstevel@tonic-gate xx = fscache_addagain(fscache_object_p, logfile_object_p, seq);
1384*0Sstevel@tonic-gate if (xx == 0)
1385*0Sstevel@tonic-gate xx = EAGAIN;
1386*0Sstevel@tonic-gate }
1387*0Sstevel@tonic-gate
1388*0Sstevel@tonic-gate /* destroy the object */
1389*0Sstevel@tonic-gate cfsd_logelem_destroy(logelem_object_p);
1390*0Sstevel@tonic-gate
1391*0Sstevel@tonic-gate dbug_leave("fscache_rollone");
1392*0Sstevel@tonic-gate return (xx);
1393*0Sstevel@tonic-gate }
1394*0Sstevel@tonic-gate
1395*0Sstevel@tonic-gate /*
1396*0Sstevel@tonic-gate * fscache_addagain
1397*0Sstevel@tonic-gate *
1398*0Sstevel@tonic-gate * Description:
1399*0Sstevel@tonic-gate * Arguments:
1400*0Sstevel@tonic-gate * lfp
1401*0Sstevel@tonic-gate * Returns:
1402*0Sstevel@tonic-gate * Returns ...
1403*0Sstevel@tonic-gate * Preconditions:
1404*0Sstevel@tonic-gate * precond(lfp)
1405*0Sstevel@tonic-gate */
1406*0Sstevel@tonic-gate int
fscache_addagain(cfsd_fscache_object_t * fscache_object_p,cfsd_logfile_object_t * logfile_object_p,ulong_t nseq)1407*0Sstevel@tonic-gate fscache_addagain(cfsd_fscache_object_t *fscache_object_p,
1408*0Sstevel@tonic-gate cfsd_logfile_object_t *logfile_object_p,
1409*0Sstevel@tonic-gate ulong_t nseq)
1410*0Sstevel@tonic-gate {
1411*0Sstevel@tonic-gate int xx;
1412*0Sstevel@tonic-gate cfs_dlog_entry_t *entp;
1413*0Sstevel@tonic-gate off_t noffset;
1414*0Sstevel@tonic-gate off_t prevoff = 0;
1415*0Sstevel@tonic-gate off_t toff;
1416*0Sstevel@tonic-gate
1417*0Sstevel@tonic-gate dbug_enter("fscache_addagain");
1418*0Sstevel@tonic-gate
1419*0Sstevel@tonic-gate dbug_precond(fscache_object_p);
1420*0Sstevel@tonic-gate dbug_precond(logfile_object_p);
1421*0Sstevel@tonic-gate
1422*0Sstevel@tonic-gate entp = logfile_object_p->i_cur_entry;
1423*0Sstevel@tonic-gate
1424*0Sstevel@tonic-gate noffset = logfile_object_p->i_cur_offset;
1425*0Sstevel@tonic-gate
1426*0Sstevel@tonic-gate dbug_assert(entp->dl_op == CFS_DLOG_MODIFIED);
1427*0Sstevel@tonic-gate dbug_assert(nseq);
1428*0Sstevel@tonic-gate
1429*0Sstevel@tonic-gate /* both set or both zero */
1430*0Sstevel@tonic-gate dbug_assert((!fscache_object_p->i_again_seq ^
1431*0Sstevel@tonic-gate !fscache_object_p->i_again_offset) == 0);
1432*0Sstevel@tonic-gate
1433*0Sstevel@tonic-gate entp->dl_seq = nseq;
1434*0Sstevel@tonic-gate /* simple case, first one on list */
1435*0Sstevel@tonic-gate if ((fscache_object_p->i_again_seq == 0) ||
1436*0Sstevel@tonic-gate (nseq < fscache_object_p->i_again_seq)) {
1437*0Sstevel@tonic-gate entp->dl_u.dl_modify.dl_next = fscache_object_p->i_again_offset;
1438*0Sstevel@tonic-gate fscache_object_p->i_again_seq = nseq;
1439*0Sstevel@tonic-gate fscache_object_p->i_again_offset = noffset;
1440*0Sstevel@tonic-gate dbug_leave("fscache_addagain");
1441*0Sstevel@tonic-gate return (0);
1442*0Sstevel@tonic-gate }
1443*0Sstevel@tonic-gate
1444*0Sstevel@tonic-gate /* Search until we find the element on the list prior to the */
1445*0Sstevel@tonic-gate /* insertion point. */
1446*0Sstevel@tonic-gate for (toff = fscache_object_p->i_again_offset; toff != 0;
1447*0Sstevel@tonic-gate toff = entp->dl_u.dl_modify.dl_next) {
1448*0Sstevel@tonic-gate /* get pointer to next element on the list */
1449*0Sstevel@tonic-gate xx = logfile_entry(logfile_object_p, toff, &entp);
1450*0Sstevel@tonic-gate if (xx) {
1451*0Sstevel@tonic-gate dbug_leave("fscache_addagain");
1452*0Sstevel@tonic-gate return (xx);
1453*0Sstevel@tonic-gate }
1454*0Sstevel@tonic-gate dbug_assert(entp->dl_op == CFS_DLOG_MODIFIED);
1455*0Sstevel@tonic-gate
1456*0Sstevel@tonic-gate /* done if we found the element after the insertion point */
1457*0Sstevel@tonic-gate if (nseq < entp->dl_seq)
1458*0Sstevel@tonic-gate break;
1459*0Sstevel@tonic-gate prevoff = toff;
1460*0Sstevel@tonic-gate }
1461*0Sstevel@tonic-gate dbug_assert(prevoff);
1462*0Sstevel@tonic-gate
1463*0Sstevel@tonic-gate /* get pointer to element prior to the insertion point */
1464*0Sstevel@tonic-gate xx = logfile_entry(logfile_object_p, prevoff, &entp);
1465*0Sstevel@tonic-gate if (xx) {
1466*0Sstevel@tonic-gate dbug_leave("fscache_addagain");
1467*0Sstevel@tonic-gate return (xx);
1468*0Sstevel@tonic-gate }
1469*0Sstevel@tonic-gate dbug_assert(entp->dl_op == CFS_DLOG_MODIFIED);
1470*0Sstevel@tonic-gate dbug_assert(entp->dl_u.dl_modify.dl_next == toff);
1471*0Sstevel@tonic-gate
1472*0Sstevel@tonic-gate /* set element to point to our new element */
1473*0Sstevel@tonic-gate entp->dl_u.dl_modify.dl_next = noffset;
1474*0Sstevel@tonic-gate
1475*0Sstevel@tonic-gate /* get pointer to our new element */
1476*0Sstevel@tonic-gate xx = logfile_entry(logfile_object_p, noffset, &entp);
1477*0Sstevel@tonic-gate if (xx) {
1478*0Sstevel@tonic-gate dbug_leave("fscache_addagain");
1479*0Sstevel@tonic-gate return (xx);
1480*0Sstevel@tonic-gate }
1481*0Sstevel@tonic-gate dbug_assert(entp->dl_op == CFS_DLOG_MODIFIED);
1482*0Sstevel@tonic-gate
1483*0Sstevel@tonic-gate /* set it to point to next link or end of list */
1484*0Sstevel@tonic-gate entp->dl_u.dl_modify.dl_next = toff;
1485*0Sstevel@tonic-gate
1486*0Sstevel@tonic-gate /* return success */
1487*0Sstevel@tonic-gate dbug_leave("fscache_addagain");
1488*0Sstevel@tonic-gate return (0);
1489*0Sstevel@tonic-gate }
1490*0Sstevel@tonic-gate
1491*0Sstevel@tonic-gate /*
1492*0Sstevel@tonic-gate * fscache_fsproblem
1493*0Sstevel@tonic-gate *
1494*0Sstevel@tonic-gate * Description:
1495*0Sstevel@tonic-gate * Arguments:
1496*0Sstevel@tonic-gate * kmodp
1497*0Sstevel@tonic-gate * Returns:
1498*0Sstevel@tonic-gate * Preconditions:
1499*0Sstevel@tonic-gate * precond(kmodp)
1500*0Sstevel@tonic-gate */
1501*0Sstevel@tonic-gate void
fscache_fsproblem(cfsd_fscache_object_t * fscache_object_p,cfsd_kmod_object_t * kmod_object_p)1502*0Sstevel@tonic-gate fscache_fsproblem(cfsd_fscache_object_t *fscache_object_p,
1503*0Sstevel@tonic-gate cfsd_kmod_object_t *kmod_object_p)
1504*0Sstevel@tonic-gate {
1505*0Sstevel@tonic-gate #if 0
1506*0Sstevel@tonic-gate int xx;
1507*0Sstevel@tonic-gate #endif
1508*0Sstevel@tonic-gate
1509*0Sstevel@tonic-gate dbug_enter("fscache_fsproblem");
1510*0Sstevel@tonic-gate
1511*0Sstevel@tonic-gate dbug_precond(fscache_object_p);
1512*0Sstevel@tonic-gate dbug_precond(kmod_object_p);
1513*0Sstevel@tonic-gate
1514*0Sstevel@tonic-gate #if 0
1515*0Sstevel@tonic-gate /* first try to put all modified files in lost+found */
1516*0Sstevel@tonic-gate xx = kmod_lostfoundall(kmod_object_p);
1517*0Sstevel@tonic-gate if (xx) {
1518*0Sstevel@tonic-gate /* if that failed, put file system in read-only mode */
1519*0Sstevel@tonic-gate kmod_rofs(kmod_object_p);
1520*0Sstevel@tonic-gate #endif
1521*0Sstevel@tonic-gate fscache_lock(fscache_object_p);
1522*0Sstevel@tonic-gate fscache_object_p->i_disconnectable = 0;
1523*0Sstevel@tonic-gate fscache_object_p->i_modify++;
1524*0Sstevel@tonic-gate fscache_unlock(fscache_object_p);
1525*0Sstevel@tonic-gate #if 0
1526*0Sstevel@tonic-gate }
1527*0Sstevel@tonic-gate #endif
1528*0Sstevel@tonic-gate dbug_leave("fscache_fsproblem");
1529*0Sstevel@tonic-gate }
1530*0Sstevel@tonic-gate
1531*0Sstevel@tonic-gate /*
1532*0Sstevel@tonic-gate * fscache_changes
1533*0Sstevel@tonic-gate *
1534*0Sstevel@tonic-gate * Description:
1535*0Sstevel@tonic-gate * Used to specify whether or not there are changes to roll to the
1536*0Sstevel@tonic-gate * server.
1537*0Sstevel@tonic-gate * Arguments:
1538*0Sstevel@tonic-gate * tt
1539*0Sstevel@tonic-gate * Returns:
1540*0Sstevel@tonic-gate * Preconditions:
1541*0Sstevel@tonic-gate */
1542*0Sstevel@tonic-gate void
fscache_changes(cfsd_fscache_object_t * fscache_object_p,int tt)1543*0Sstevel@tonic-gate fscache_changes(cfsd_fscache_object_t *fscache_object_p, int tt)
1544*0Sstevel@tonic-gate {
1545*0Sstevel@tonic-gate dbug_enter("fscache_changes");
1546*0Sstevel@tonic-gate dbug_precond(fscache_object_p);
1547*0Sstevel@tonic-gate fscache_object_p->i_changes = tt;
1548*0Sstevel@tonic-gate fscache_object_p->i_modify++;
1549*0Sstevel@tonic-gate dbug_leave("fscache_changes");
1550*0Sstevel@tonic-gate }
1551