xref: /original-bsd/usr.sbin/amd/amd/mntfs.c (revision 95a66346)
1 /*
2  * $Id: mntfs.c,v 5.2.1.4 91/03/17 17:46:40 jsp Alpha $
3  *
4  * Copyright (c) 1990 Jan-Simon Pendry
5  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
6  * Copyright (c) 1990 The Regents of the University of California.
7  * All rights reserved.
8  *
9  * This code is derived from software contributed to Berkeley by
10  * Jan-Simon Pendry at Imperial College, London.
11  *
12  * %sccs.include.redist.c%
13  *
14  *	@(#)mntfs.c	5.2 (Berkeley) 03/17/91
15  */
16 
17 #include "am.h"
18 
19 extern qelem mfhead;
20 qelem mfhead = { &mfhead, &mfhead };
21 
22 int mntfs_allocated;
23 
24 #ifdef notdef
25 /*
26  * This is the default attributes field which
27  * is copied into every new node to be created.
28  * The individual filesystem fs_init() routines
29  * patch the copy to represent the particular
30  * details for the relevant filesystem type
31  */
32 static struct fattr gen_fattr = {
33 	NFDIR,				/* type */
34 	NFSMODE_DIR | 0555,		/* mode */
35 	2,				/* nlink */
36 	0,				/* uid */
37 	0,				/* gid */
38 	512,				/* size */
39 	4096,				/* blocksize */
40 	0,				/* rdev */
41 	1,				/* blocks */
42 	0,				/* fsid */
43 	0,				/* fileid */
44 	{ 0, 0 },			/* atime */
45 	{ 0, 0 },			/* mtime */
46 	{ 0, 0 },			/* ctime */
47 };
48 #endif /* notdef */
49 
50 mntfs *dup_mntfs(mf)
51 mntfs *mf;
52 {
53 	if (mf->mf_refc == 0) {
54 		if (mf->mf_cid)
55 			untimeout(mf->mf_cid);
56 		mf->mf_cid = 0;
57 #ifdef notdef
58 		mf->mf_error = -1;
59 		mf->mf_flags &= ~MFF_ERROR;
60 #endif
61 	}
62 	mf->mf_refc++;
63 	return mf;
64 }
65 
66 static int init_mntfs P((mntfs *mf, am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts));
67 static int init_mntfs(mf, ops, mo, mp, info, auto_opts, mopts)
68 mntfs *mf;
69 am_ops *ops;
70 am_opts *mo;
71 char *mp;
72 char *info;
73 char *auto_opts;
74 char *mopts;
75 {
76 	mf->mf_ops = ops;
77 	mf->mf_fo = mo;
78 	mf->mf_mount = strdup(mp);
79 	mf->mf_info = strdup(info);
80 	mf->mf_auto = strdup(auto_opts);
81 	mf->mf_mopts = strdup(mopts);
82 	mf->mf_refc = 1;
83 	mf->mf_flags = 0;
84 	mf->mf_error = -1;
85 	mf->mf_cid = 0;
86 	mf->mf_private = 0;
87 	mf->mf_prfree = 0;
88 #ifdef notdef
89 	mf->mf_attr.status = NFS_OK;
90 	mf->mf_fattr = gen_fattr;
91 	mf->mf_fattr.fsid = 42;
92 	mf->mf_fattr.fileid = 0;
93 	mf->mf_fattr.atime.seconds = clocktime();
94 	mf->mf_fattr.atime.useconds = 0;
95 	mf->mf_fattr.mtime = mf->mf_fattr.ctime = mf->mf_fattr.atime;
96 #endif
97 
98 	if (ops->ffserver)
99 		mf->mf_server = (*ops->ffserver)(mf);
100 	else
101 		mf->mf_server = 0;
102 }
103 
104 static mntfs *alloc_mntfs P((am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts));
105 static mntfs *alloc_mntfs(ops, mo, mp, info, auto_opts, mopts)
106 am_ops *ops;
107 am_opts *mo;
108 char *mp;
109 char *info;
110 char *auto_opts;
111 char *mopts;
112 {
113 	mntfs *mf = ALLOC(mntfs);
114 	init_mntfs(mf, ops, mo, mp, info, auto_opts, mopts);
115 	ins_que(&mf->mf_q, &mfhead);
116 	mntfs_allocated++;
117 
118 	return mf;
119 }
120 
121 mntfs *find_mntfs P((am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts));
122 mntfs *find_mntfs(ops, mo, mp, info, auto_opts, mopts)
123 am_ops *ops;
124 am_opts *mo;
125 char *mp;
126 char *info;
127 char *auto_opts;
128 char *mopts;
129 {
130 	mntfs *mf;
131 
132 #ifdef DEBUG
133 	dlog("Locating mntfs reference to %s", mp);
134 #endif /* DEBUG */
135 	ITER(mf, mntfs, &mfhead) {
136 		if (STREQ(mf->mf_mount, mp)) {
137 			/*
138 			 * Handle cases where error ops are involved
139 			 */
140 			if (ops == &efs_ops) {
141 				/*
142 				 * If the existing ops are not efs_ops
143 				 * then continue...
144 				 */
145 				if (mf->mf_ops != &efs_ops)
146 					continue;
147 			} else /* ops != &efs_ops */ {
148 				/*
149 				 * If the existing ops are efs_ops
150 				 * then continue...
151 				 */
152 				if (mf->mf_ops == &efs_ops)
153 					continue;
154 			}
155 
156 			if ((mf->mf_flags & MFF_RESTART) && amd_state == Run) {
157 				/*
158 				 * Restart a previously mounted filesystem.
159 				 */
160 				mntfs *mf2 = alloc_mntfs(&ifs_ops, mo, mp, info, auto_opts, mopts);
161 #ifdef DEBUG
162 				dlog("Restarting filesystem %s", mf->mf_mount);
163 #endif /* DEBUG */
164 				/*
165 				 * Remember who we are restarting
166 				 */
167 				mf2->mf_private = (voidp) dup_mntfs(mf);
168 				mf2->mf_prfree = free_mntfs;
169 				return mf2;
170 			}
171 			mf->mf_fo = mo;
172 			if (!(mf->mf_flags & (MFF_MOUNTED|MFF_MOUNTING|MFF_UNMOUNTING))) {
173 				fserver *fs;
174 				mf->mf_flags &= ~MFF_ERROR;
175 				mf->mf_error = -1;
176 				mf->mf_auto = strealloc(mf->mf_auto, auto_opts);
177 				mf->mf_mopts = strealloc(mf->mf_mopts, mopts);
178 				mf->mf_info = strealloc(mf->mf_info, info);
179 				if (mf->mf_private && mf->mf_prfree) {
180 					(*mf->mf_prfree)(mf->mf_private);
181 					mf->mf_private = 0;
182 				}
183 				fs = ops->ffserver ? (*ops->ffserver)(mf) : (fserver *) 0;
184 				if (mf->mf_server)
185 					free_srvr(mf->mf_server);
186 				mf->mf_server = fs;
187 			}
188 			return dup_mntfs(mf);
189 		}
190 	}
191 
192 	return alloc_mntfs(ops, mo, mp, info, auto_opts, mopts);
193 }
194 
195 mntfs *new_mntfs()
196 {
197 	return alloc_mntfs(&efs_ops, (am_opts *) 0, "//nil//", ".", "", "");
198 }
199 
200 static void uninit_mntfs(mf, rmd)
201 mntfs *mf;
202 int rmd;
203 {
204 	if (mf->mf_mount) free((voidp) mf->mf_mount);
205 	if (mf->mf_auto) free((voidp) mf->mf_auto);
206 	if (mf->mf_mopts) free((voidp) mf->mf_mopts);
207 	if (mf->mf_info) free((voidp) mf->mf_info);
208 	if (mf->mf_private && mf->mf_prfree)
209 		(*mf->mf_prfree)(mf->mf_private);
210 	/*
211 	 * Clean up any directories that were made
212 	 */
213 	if (rmd && (mf->mf_flags & MFF_MKMNT))
214 		rmdirs(mf->mf_mount);
215 
216 	/*
217 	 * Clean up the file server
218 	 */
219 	if (mf->mf_server)
220 		free_srvr(mf->mf_server);
221 
222 	/*
223 	 * Don't do a callback on this mount
224 	 */
225 	if (mf->mf_cid) {
226 		untimeout(mf->mf_cid);
227 		mf->mf_cid = 0;
228 	}
229 }
230 
231 static void discard_mntfs(mf)
232 mntfs *mf;
233 {
234 	rem_que(&mf->mf_q);
235 	/*
236 	 * Free memory
237 	 */
238 	uninit_mntfs(mf, TRUE);
239 	free((voidp) mf);
240 
241 	--mntfs_allocated;
242 }
243 
244 void flush_mntfs()
245 {
246 	mntfs *mf;
247 
248 	mf = FIRST(mntfs, &mfhead);
249 	while (mf != HEAD(mntfs, &mfhead)) {
250 		mntfs *mf2 = mf;
251 		mf = NEXT(mntfs, mf);
252 		if (mf2->mf_refc == 0 && mf2->mf_cid)
253 			discard_mntfs(mf2);
254 	}
255 }
256 
257 void free_mntfs(mf)
258 mntfs *mf;
259 {
260 	if (--mf->mf_refc == 0) {
261 		if (mf->mf_flags & MFF_MOUNTED) {
262 			int quoted;
263 			mf->mf_flags &= ~MFF_MOUNTED;
264 
265 			/*
266 			 * Record for posterity
267 			 */
268 			quoted = strchr(mf->mf_info, ' ') != 0;	/* cheap */
269 			plog(XLOG_INFO, "%s%s%s %sed fstype %s from %s",
270 				quoted ? "\"" : "",
271 				mf->mf_info,
272 				quoted ? "\"" : "",
273 				mf->mf_error ? "discard" : "unmount",
274 				mf->mf_ops->fs_type, mf->mf_mount);
275 		}
276 
277 		if (mf->mf_ops->fs_flags & FS_DISCARD) {
278 #ifdef DEBUG
279 			dlog("Immediately discarding mntfs for %s", mf->mf_mount);
280 #endif /* DEBUG */
281 			discard_mntfs(mf);
282 		} else {
283 #ifdef DEBUG
284 			if (mf->mf_flags & MFF_RESTART) {
285 				dlog("Discarding remount hook for %s", mf->mf_mount);
286 			} else {
287 				dlog("Discarding last mntfs reference to %s fstype %s",
288 					mf->mf_mount, mf->mf_ops->fs_type);
289 			}
290 			if (mf->mf_flags & (MFF_MOUNTED|MFF_MOUNTING|MFF_UNMOUNTING))
291 				dlog("mntfs reference for %s still active", mf->mf_mount);
292 #endif /* DEBUG */
293 			mf->mf_cid = timeout(ALLOWED_MOUNT_TIME, discard_mntfs, (voidp) mf);
294 		}
295 	}
296 }
297 
298 mntfs *realloc_mntfs P((mntfs *mf, am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts));
299 mntfs *realloc_mntfs(mf, ops, mo, mp, info, auto_opts, mopts)
300 mntfs *mf;
301 am_ops *ops;
302 am_opts *mo;
303 char *mp;
304 char *info;
305 char *auto_opts;
306 char *mopts;
307 {
308 	mntfs *mf2;
309 	if (mf->mf_refc == 1 && mf->mf_ops == &ifs_ops && STREQ(mf->mf_mount, mp)) {
310 		/*
311 		 * If we are inheriting then just return
312 		 * the same node...
313 		 */
314 		return mf;
315 	}
316 	mf2 = find_mntfs(ops, mo, mp, info, auto_opts, mopts);
317 	free_mntfs(mf);
318 	return mf2;
319 }
320