xref: /original-bsd/usr.sbin/amd/amd/mntfs.c (revision 4092c5cc)
15d59b00cSbostic /*-
2398a5aebSmckusick  * Copyright (c) 1990 Jan-Simon Pendry
3398a5aebSmckusick  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
4*4092c5ccSbostic  * Copyright (c) 1990, 1993
5*4092c5ccSbostic  *	The Regents of the University of California.  All rights reserved.
6398a5aebSmckusick  *
7398a5aebSmckusick  * This code is derived from software contributed to Berkeley by
8398a5aebSmckusick  * Jan-Simon Pendry at Imperial College, London.
9398a5aebSmckusick  *
10398a5aebSmckusick  * %sccs.include.redist.c%
11398a5aebSmckusick  *
12cc0207dcSpendry  * $Id: mntfs.c,v 5.2.2.1 1992/02/09 15:08:42 jsp beta $
13398a5aebSmckusick  */
14398a5aebSmckusick 
155d59b00cSbostic #ifndef lint
16*4092c5ccSbostic static char sccsid[] = "@(#)mntfs.c	8.1 (Berkeley) 06/06/93";
175d59b00cSbostic #endif /* not lint */
185d59b00cSbostic 
195d59b00cSbostic 
20398a5aebSmckusick #include "am.h"
21398a5aebSmckusick 
22398a5aebSmckusick extern qelem mfhead;
23398a5aebSmckusick qelem mfhead = { &mfhead, &mfhead };
24398a5aebSmckusick 
25398a5aebSmckusick int mntfs_allocated;
26398a5aebSmckusick 
278a89c22cSpendry #ifdef notdef
28398a5aebSmckusick /*
29398a5aebSmckusick  * This is the default attributes field which
30398a5aebSmckusick  * is copied into every new node to be created.
31398a5aebSmckusick  * The individual filesystem fs_init() routines
32398a5aebSmckusick  * patch the copy to represent the particular
33398a5aebSmckusick  * details for the relevant filesystem type
34398a5aebSmckusick  */
35398a5aebSmckusick static struct fattr gen_fattr = {
36398a5aebSmckusick 	NFDIR,				/* type */
37398a5aebSmckusick 	NFSMODE_DIR | 0555,		/* mode */
38398a5aebSmckusick 	2,				/* nlink */
39398a5aebSmckusick 	0,				/* uid */
40398a5aebSmckusick 	0,				/* gid */
41398a5aebSmckusick 	512,				/* size */
42398a5aebSmckusick 	4096,				/* blocksize */
43398a5aebSmckusick 	0,				/* rdev */
44398a5aebSmckusick 	1,				/* blocks */
45398a5aebSmckusick 	0,				/* fsid */
46398a5aebSmckusick 	0,				/* fileid */
47398a5aebSmckusick 	{ 0, 0 },			/* atime */
48398a5aebSmckusick 	{ 0, 0 },			/* mtime */
49398a5aebSmckusick 	{ 0, 0 },			/* ctime */
50398a5aebSmckusick };
518a89c22cSpendry #endif /* notdef */
52398a5aebSmckusick 
dup_mntfs(mf)53398a5aebSmckusick mntfs *dup_mntfs(mf)
54398a5aebSmckusick mntfs *mf;
55398a5aebSmckusick {
56398a5aebSmckusick 	if (mf->mf_refc == 0) {
578a89c22cSpendry 		if (mf->mf_cid)
58398a5aebSmckusick 			untimeout(mf->mf_cid);
59398a5aebSmckusick 		mf->mf_cid = 0;
608a89c22cSpendry #ifdef notdef
61398a5aebSmckusick 		mf->mf_error = -1;
62398a5aebSmckusick 		mf->mf_flags &= ~MFF_ERROR;
638a89c22cSpendry #endif
64398a5aebSmckusick 	}
65398a5aebSmckusick 	mf->mf_refc++;
66398a5aebSmckusick 	return mf;
67398a5aebSmckusick }
68398a5aebSmckusick 
69cc0207dcSpendry static void init_mntfs P((mntfs *mf, am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts, char *remopts));
init_mntfs(mf,ops,mo,mp,info,auto_opts,mopts,remopts)70cc0207dcSpendry static void init_mntfs(mf, ops, mo, mp, info, auto_opts, mopts, remopts)
71398a5aebSmckusick mntfs *mf;
72398a5aebSmckusick am_ops *ops;
73398a5aebSmckusick am_opts *mo;
74398a5aebSmckusick char *mp;
75398a5aebSmckusick char *info;
768a89c22cSpendry char *auto_opts;
778a89c22cSpendry char *mopts;
78cc0207dcSpendry char *remopts;
79398a5aebSmckusick {
80398a5aebSmckusick 	mf->mf_ops = ops;
81398a5aebSmckusick 	mf->mf_fo = mo;
82398a5aebSmckusick 	mf->mf_mount = strdup(mp);
83398a5aebSmckusick 	mf->mf_info = strdup(info);
848a89c22cSpendry 	mf->mf_auto = strdup(auto_opts);
858a89c22cSpendry 	mf->mf_mopts = strdup(mopts);
86cc0207dcSpendry 	mf->mf_remopts = strdup(remopts);
87398a5aebSmckusick 	mf->mf_refc = 1;
88398a5aebSmckusick 	mf->mf_flags = 0;
89398a5aebSmckusick 	mf->mf_error = -1;
90398a5aebSmckusick 	mf->mf_cid = 0;
91398a5aebSmckusick 	mf->mf_private = 0;
92398a5aebSmckusick 	mf->mf_prfree = 0;
938a89c22cSpendry #ifdef notdef
94398a5aebSmckusick 	mf->mf_attr.status = NFS_OK;
95398a5aebSmckusick 	mf->mf_fattr = gen_fattr;
96398a5aebSmckusick 	mf->mf_fattr.fsid = 42;
97398a5aebSmckusick 	mf->mf_fattr.fileid = 0;
98398a5aebSmckusick 	mf->mf_fattr.atime.seconds = clocktime();
99398a5aebSmckusick 	mf->mf_fattr.atime.useconds = 0;
100398a5aebSmckusick 	mf->mf_fattr.mtime = mf->mf_fattr.ctime = mf->mf_fattr.atime;
1018a89c22cSpendry #endif
102398a5aebSmckusick 
103398a5aebSmckusick 	if (ops->ffserver)
104398a5aebSmckusick 		mf->mf_server = (*ops->ffserver)(mf);
105398a5aebSmckusick 	else
106398a5aebSmckusick 		mf->mf_server = 0;
107398a5aebSmckusick }
108398a5aebSmckusick 
109cc0207dcSpendry static mntfs *alloc_mntfs P((am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts, char *remopts));
alloc_mntfs(ops,mo,mp,info,auto_opts,mopts,remopts)110cc0207dcSpendry static mntfs *alloc_mntfs(ops, mo, mp, info, auto_opts, mopts, remopts)
111398a5aebSmckusick am_ops *ops;
112398a5aebSmckusick am_opts *mo;
113398a5aebSmckusick char *mp;
114398a5aebSmckusick char *info;
1158a89c22cSpendry char *auto_opts;
1168a89c22cSpendry char *mopts;
117cc0207dcSpendry char *remopts;
118398a5aebSmckusick {
119398a5aebSmckusick 	mntfs *mf = ALLOC(mntfs);
120cc0207dcSpendry 	init_mntfs(mf, ops, mo, mp, info, auto_opts, mopts, remopts);
121398a5aebSmckusick 	ins_que(&mf->mf_q, &mfhead);
122398a5aebSmckusick 	mntfs_allocated++;
123398a5aebSmckusick 
124398a5aebSmckusick 	return mf;
125398a5aebSmckusick }
126398a5aebSmckusick 
127cc0207dcSpendry mntfs *find_mntfs P((am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts, char *remopts));
find_mntfs(ops,mo,mp,info,auto_opts,mopts,remopts)128cc0207dcSpendry mntfs *find_mntfs(ops, mo, mp, info, auto_opts, mopts, remopts)
129398a5aebSmckusick am_ops *ops;
130398a5aebSmckusick am_opts *mo;
131398a5aebSmckusick char *mp;
132398a5aebSmckusick char *info;
1338a89c22cSpendry char *auto_opts;
1348a89c22cSpendry char *mopts;
135cc0207dcSpendry char *remopts;
136398a5aebSmckusick {
137398a5aebSmckusick 	mntfs *mf;
138398a5aebSmckusick 
139398a5aebSmckusick #ifdef DEBUG
140398a5aebSmckusick 	dlog("Locating mntfs reference to %s", mp);
141398a5aebSmckusick #endif /* DEBUG */
142398a5aebSmckusick 	ITER(mf, mntfs, &mfhead) {
143398a5aebSmckusick 		if (STREQ(mf->mf_mount, mp)) {
144398a5aebSmckusick 			/*
145398a5aebSmckusick 			 * Handle cases where error ops are involved
146398a5aebSmckusick 			 */
147398a5aebSmckusick 			if (ops == &efs_ops) {
148398a5aebSmckusick 				/*
149398a5aebSmckusick 				 * If the existing ops are not efs_ops
150398a5aebSmckusick 				 * then continue...
151398a5aebSmckusick 				 */
152398a5aebSmckusick 				if (mf->mf_ops != &efs_ops)
153398a5aebSmckusick 					continue;
154398a5aebSmckusick 			} else /* ops != &efs_ops */ {
155398a5aebSmckusick 				/*
156398a5aebSmckusick 				 * If the existing ops are efs_ops
157398a5aebSmckusick 				 * then continue...
158398a5aebSmckusick 				 */
159398a5aebSmckusick 				if (mf->mf_ops == &efs_ops)
160398a5aebSmckusick 					continue;
161398a5aebSmckusick 			}
162398a5aebSmckusick 
163398a5aebSmckusick 			if ((mf->mf_flags & MFF_RESTART) && amd_state == Run) {
164398a5aebSmckusick 				/*
165398a5aebSmckusick 				 * Restart a previously mounted filesystem.
166398a5aebSmckusick 				 */
167cc0207dcSpendry 				mntfs *mf2 = alloc_mntfs(&ifs_ops, mo, mp, info, auto_opts, mopts, remopts);
168398a5aebSmckusick #ifdef DEBUG
169398a5aebSmckusick 				dlog("Restarting filesystem %s", mf->mf_mount);
170398a5aebSmckusick #endif /* DEBUG */
171398a5aebSmckusick 				/*
172398a5aebSmckusick 				 * Remember who we are restarting
173398a5aebSmckusick 				 */
174398a5aebSmckusick 				mf2->mf_private = (voidp) dup_mntfs(mf);
175398a5aebSmckusick 				mf2->mf_prfree = free_mntfs;
176398a5aebSmckusick 				return mf2;
177398a5aebSmckusick 			}
178398a5aebSmckusick 			mf->mf_fo = mo;
179398a5aebSmckusick 			if (!(mf->mf_flags & (MFF_MOUNTED|MFF_MOUNTING|MFF_UNMOUNTING))) {
180398a5aebSmckusick 				fserver *fs;
1818a89c22cSpendry 				mf->mf_flags &= ~MFF_ERROR;
1828a89c22cSpendry 				mf->mf_error = -1;
1838a89c22cSpendry 				mf->mf_auto = strealloc(mf->mf_auto, auto_opts);
1848a89c22cSpendry 				mf->mf_mopts = strealloc(mf->mf_mopts, mopts);
185cc0207dcSpendry 				mf->mf_remopts = strealloc(mf->mf_remopts, remopts);
186398a5aebSmckusick 				mf->mf_info = strealloc(mf->mf_info, info);
1878a89c22cSpendry 				if (mf->mf_private && mf->mf_prfree) {
1888a89c22cSpendry 					(*mf->mf_prfree)(mf->mf_private);
1898a89c22cSpendry 					mf->mf_private = 0;
1908a89c22cSpendry 				}
191398a5aebSmckusick 				fs = ops->ffserver ? (*ops->ffserver)(mf) : (fserver *) 0;
192398a5aebSmckusick 				if (mf->mf_server)
193398a5aebSmckusick 					free_srvr(mf->mf_server);
194398a5aebSmckusick 				mf->mf_server = fs;
195398a5aebSmckusick 			}
196398a5aebSmckusick 			return dup_mntfs(mf);
197398a5aebSmckusick 		}
198398a5aebSmckusick 	}
199398a5aebSmckusick 
200cc0207dcSpendry 	return alloc_mntfs(ops, mo, mp, info, auto_opts, mopts, remopts);
201398a5aebSmckusick }
202398a5aebSmckusick 
new_mntfs()203398a5aebSmckusick mntfs *new_mntfs()
204398a5aebSmckusick {
205cc0207dcSpendry 	return alloc_mntfs(&efs_ops, (am_opts *) 0, "//nil//", ".", "", "", "");
206398a5aebSmckusick }
207398a5aebSmckusick 
uninit_mntfs(mf,rmd)208398a5aebSmckusick static void uninit_mntfs(mf, rmd)
209398a5aebSmckusick mntfs *mf;
210398a5aebSmckusick int rmd;
211398a5aebSmckusick {
212398a5aebSmckusick 	if (mf->mf_mount) free((voidp) mf->mf_mount);
2138a89c22cSpendry 	if (mf->mf_auto) free((voidp) mf->mf_auto);
2148a89c22cSpendry 	if (mf->mf_mopts) free((voidp) mf->mf_mopts);
215cc0207dcSpendry 	if (mf->mf_remopts) free((voidp) mf->mf_remopts);
216398a5aebSmckusick 	if (mf->mf_info) free((voidp) mf->mf_info);
217398a5aebSmckusick 	if (mf->mf_private && mf->mf_prfree)
218398a5aebSmckusick 		(*mf->mf_prfree)(mf->mf_private);
219398a5aebSmckusick 	/*
220398a5aebSmckusick 	 * Clean up any directories that were made
221398a5aebSmckusick 	 */
222398a5aebSmckusick 	if (rmd && (mf->mf_flags & MFF_MKMNT))
223398a5aebSmckusick 		rmdirs(mf->mf_mount);
224398a5aebSmckusick 
225398a5aebSmckusick 	/*
226398a5aebSmckusick 	 * Clean up the file server
227398a5aebSmckusick 	 */
228398a5aebSmckusick 	if (mf->mf_server)
229398a5aebSmckusick 		free_srvr(mf->mf_server);
230398a5aebSmckusick 
231398a5aebSmckusick 	/*
232398a5aebSmckusick 	 * Don't do a callback on this mount
233398a5aebSmckusick 	 */
234398a5aebSmckusick 	if (mf->mf_cid) {
235398a5aebSmckusick 		untimeout(mf->mf_cid);
236398a5aebSmckusick 		mf->mf_cid = 0;
237398a5aebSmckusick 	}
238398a5aebSmckusick }
239398a5aebSmckusick 
discard_mntfs(mf)240398a5aebSmckusick static void discard_mntfs(mf)
241398a5aebSmckusick mntfs *mf;
242398a5aebSmckusick {
243398a5aebSmckusick 	rem_que(&mf->mf_q);
244398a5aebSmckusick 	/*
245398a5aebSmckusick 	 * Free memory
246398a5aebSmckusick 	 */
247398a5aebSmckusick 	uninit_mntfs(mf, TRUE);
248398a5aebSmckusick 	free((voidp) mf);
249398a5aebSmckusick 
250398a5aebSmckusick 	--mntfs_allocated;
251398a5aebSmckusick }
252398a5aebSmckusick 
flush_mntfs()253398a5aebSmckusick void flush_mntfs()
254398a5aebSmckusick {
255398a5aebSmckusick 	mntfs *mf;
256398a5aebSmckusick 
257398a5aebSmckusick 	mf = FIRST(mntfs, &mfhead);
258398a5aebSmckusick 	while (mf != HEAD(mntfs, &mfhead)) {
259398a5aebSmckusick 		mntfs *mf2 = mf;
260398a5aebSmckusick 		mf = NEXT(mntfs, mf);
261398a5aebSmckusick 		if (mf2->mf_refc == 0 && mf2->mf_cid)
262398a5aebSmckusick 			discard_mntfs(mf2);
263398a5aebSmckusick 	}
264398a5aebSmckusick }
265398a5aebSmckusick 
free_mntfs(mf)266398a5aebSmckusick void free_mntfs(mf)
267398a5aebSmckusick mntfs *mf;
268398a5aebSmckusick {
269398a5aebSmckusick 	if (--mf->mf_refc == 0) {
270398a5aebSmckusick 		if (mf->mf_flags & MFF_MOUNTED) {
271398a5aebSmckusick 			int quoted;
272398a5aebSmckusick 			mf->mf_flags &= ~MFF_MOUNTED;
273398a5aebSmckusick 
274398a5aebSmckusick 			/*
275398a5aebSmckusick 			 * Record for posterity
276398a5aebSmckusick 			 */
277398a5aebSmckusick 			quoted = strchr(mf->mf_info, ' ') != 0;	/* cheap */
278398a5aebSmckusick 			plog(XLOG_INFO, "%s%s%s %sed fstype %s from %s",
279398a5aebSmckusick 				quoted ? "\"" : "",
280398a5aebSmckusick 				mf->mf_info,
281398a5aebSmckusick 				quoted ? "\"" : "",
282398a5aebSmckusick 				mf->mf_error ? "discard" : "unmount",
283398a5aebSmckusick 				mf->mf_ops->fs_type, mf->mf_mount);
284398a5aebSmckusick 		}
285398a5aebSmckusick 
286398a5aebSmckusick 		if (mf->mf_ops->fs_flags & FS_DISCARD) {
287398a5aebSmckusick #ifdef DEBUG
288398a5aebSmckusick 			dlog("Immediately discarding mntfs for %s", mf->mf_mount);
289398a5aebSmckusick #endif /* DEBUG */
290398a5aebSmckusick 			discard_mntfs(mf);
291398a5aebSmckusick 		} else {
292398a5aebSmckusick #ifdef DEBUG
293398a5aebSmckusick 			if (mf->mf_flags & MFF_RESTART) {
294398a5aebSmckusick 				dlog("Discarding remount hook for %s", mf->mf_mount);
295398a5aebSmckusick 			} else {
296398a5aebSmckusick 				dlog("Discarding last mntfs reference to %s fstype %s",
297398a5aebSmckusick 					mf->mf_mount, mf->mf_ops->fs_type);
298398a5aebSmckusick 			}
299398a5aebSmckusick 			if (mf->mf_flags & (MFF_MOUNTED|MFF_MOUNTING|MFF_UNMOUNTING))
300398a5aebSmckusick 				dlog("mntfs reference for %s still active", mf->mf_mount);
301398a5aebSmckusick #endif /* DEBUG */
302398a5aebSmckusick 			mf->mf_cid = timeout(ALLOWED_MOUNT_TIME, discard_mntfs, (voidp) mf);
303398a5aebSmckusick 		}
304398a5aebSmckusick 	}
305398a5aebSmckusick }
306398a5aebSmckusick 
307cc0207dcSpendry mntfs *realloc_mntfs P((mntfs *mf, am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts, char *remopts));
realloc_mntfs(mf,ops,mo,mp,info,auto_opts,mopts,remopts)308cc0207dcSpendry mntfs *realloc_mntfs(mf, ops, mo, mp, info, auto_opts, mopts, remopts)
309398a5aebSmckusick mntfs *mf;
310398a5aebSmckusick am_ops *ops;
311398a5aebSmckusick am_opts *mo;
312398a5aebSmckusick char *mp;
313398a5aebSmckusick char *info;
3148a89c22cSpendry char *auto_opts;
3158a89c22cSpendry char *mopts;
316cc0207dcSpendry char *remopts;
317398a5aebSmckusick {
318398a5aebSmckusick 	mntfs *mf2;
319398a5aebSmckusick 	if (mf->mf_refc == 1 && mf->mf_ops == &ifs_ops && STREQ(mf->mf_mount, mp)) {
320398a5aebSmckusick 		/*
321398a5aebSmckusick 		 * If we are inheriting then just return
322398a5aebSmckusick 		 * the same node...
323398a5aebSmckusick 		 */
324398a5aebSmckusick 		return mf;
325398a5aebSmckusick 	}
326c626267eSpendry 
327c626267eSpendry 	/*
328c626267eSpendry 	 * Re-use the existing mntfs if it is mounted.
329c626267eSpendry 	 * This traps a race in nfsx.
330c626267eSpendry 	 */
331c626267eSpendry 	if (mf->mf_ops != &efs_ops &&
332c626267eSpendry 			(mf->mf_flags & MFF_MOUNTED) &&
333c626267eSpendry 			!FSRV_ISDOWN(mf->mf_server)) {
334c626267eSpendry 		mf->mf_fo = mo;
335c626267eSpendry 		return mf;
336c626267eSpendry 	}
337c626267eSpendry 
338cc0207dcSpendry 	mf2 = find_mntfs(ops, mo, mp, info, auto_opts, mopts, remopts);
339398a5aebSmckusick 	free_mntfs(mf);
340398a5aebSmckusick 	return mf2;
341398a5aebSmckusick }
342