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