Annotation of src/sys/adosfs/advfsops.c, Revision 1.31
1.31 ! thorpej 1: /* $NetBSD: advfsops.c,v 1.30 1998/08/09 20:20:11 perry Exp $ */
1.4 cgd 2:
1.1 chopps 3: /*
4: * Copyright (c) 1994 Christian E. Hopps
1.17 mhitch 5: * Copyright (c) 1996 Matthias Scheler
1.1 chopps 6: * All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by Christian E. Hopps.
19: * 4. The name of the author may not be used to endorse or promote products
20: * derived from this software without specific prior written permission
21: *
22: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32: */
1.29 jonathan 33:
34: #if defined(_KERNEL) && !defined(_LKM)
35: #include "opt_compat_netbsd.h"
36: #endif
37:
1.1 chopps 38: #include <sys/param.h>
39: #include <sys/systm.h>
40: #include <sys/vnode.h>
41: #include <sys/mount.h>
1.2 chopps 42: #include <sys/proc.h>
1.1 chopps 43: #include <sys/time.h>
44: #include <sys/malloc.h>
1.31 ! thorpej 45: #include <sys/pool.h>
1.1 chopps 46: #include <sys/disklabel.h>
47: #include <miscfs/specfs/specdev.h> /* XXX */
48: #include <sys/fcntl.h>
49: #include <sys/namei.h>
50: #include <sys/ioctl.h>
51: #include <sys/queue.h>
52: #include <sys/buf.h>
53: #include <adosfs/adosfs.h>
54:
1.16 christos 55: void adosfs_init __P((void));
1.24 cgd 56: int adosfs_mount __P((struct mount *, const char *, void *, struct nameidata *,
1.16 christos 57: struct proc *));
58: int adosfs_start __P((struct mount *, int, struct proc *));
59: int adosfs_unmount __P((struct mount *, int, struct proc *));
60: int adosfs_root __P((struct mount *, struct vnode **));
61: int adosfs_quotactl __P((struct mount *, int, uid_t, caddr_t, struct proc *));
62: int adosfs_statfs __P((struct mount *, struct statfs *, struct proc *));
63: int adosfs_sync __P((struct mount *, int, struct ucred *, struct proc *));
64: int adosfs_vget __P((struct mount *, ino_t, struct vnode **));
65: int adosfs_fhtovp __P((struct mount *, struct fid *, struct mbuf *,
66: struct vnode **, int *, struct ucred **));
67: int adosfs_vptofh __P((struct vnode *, struct fid *));
68:
69: int adosfs_mountfs __P((struct vnode *, struct mount *, struct proc *));
1.17 mhitch 70: int adosfs_loadbitmap __P((struct adosfsmount *));
1.28 fvdl 71: int adosfs_sysctl __P((int *, u_int, void *, size_t *, void *, size_t,
72: struct proc *));
73:
74: struct simplelock adosfs_hashlock;
1.16 christos 75:
1.31 ! thorpej 76: struct pool adosfs_node_pool;
! 77:
1.1 chopps 78: int
79: adosfs_mount(mp, path, data, ndp, p)
80: struct mount *mp;
1.24 cgd 81: const char *path;
82: void *data;
1.1 chopps 83: struct nameidata *ndp;
84: struct proc *p;
85: {
1.9 mycroft 86: struct vnode *devvp;
1.1 chopps 87: struct adosfs_args args;
1.9 mycroft 88: struct adosfsmount *amp;
1.12 mycroft 89: size_t size;
1.1 chopps 90: int error;
1.9 mycroft 91: mode_t accessmode;
1.1 chopps 92:
1.16 christos 93: error = copyin(data, (caddr_t)&args, sizeof(struct adosfs_args));
94: if (error)
1.1 chopps 95: return(error);
96:
1.14 chopps 97: #if 0
1.1 chopps 98: if (mp->mnt_flag & MNT_UPDATE)
1.9 mycroft 99: return (EOPNOTSUPP);
1.14 chopps 100: #endif
1.9 mycroft 101: if ((mp->mnt_flag & MNT_RDONLY) == 0)
102: return (EROFS);
103: /*
1.14 chopps 104: * If updating, check whether changing from read-only to
105: * read/write; if there is no device name, that's all we do.
106: */
107: if (mp->mnt_flag & MNT_UPDATE) {
108: amp = VFSTOADOSFS(mp);
109: if (args.fspec == 0)
110: return (vfs_export(mp, &->export, &args.export));
111: }
112: /*
1.9 mycroft 113: * Not an update, or updating the name: look up the name
114: * and verify that it refers to a sensible block device.
1.1 chopps 115: */
1.2 chopps 116: NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p);
1.16 christos 117: if ((error = namei(ndp)) != 0)
1.2 chopps 118: return (error);
1.9 mycroft 119: devvp = ndp->ni_vp;
1.2 chopps 120:
1.9 mycroft 121: if (devvp->v_type != VBLK) {
122: vrele(devvp);
1.2 chopps 123: return (ENOTBLK);
1.1 chopps 124: }
1.9 mycroft 125: if (major(devvp->v_rdev) >= nblkdev) {
126: vrele(devvp);
1.2 chopps 127: return (ENXIO);
1.1 chopps 128: }
1.9 mycroft 129: /*
130: * If mount by non-root, then verify that user has necessary
131: * permissions on the device.
132: */
133: if (p->p_ucred->cr_uid != 0) {
134: accessmode = VREAD;
135: if ((mp->mnt_flag & MNT_RDONLY) == 0)
136: accessmode |= VWRITE;
1.28 fvdl 137: vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
1.16 christos 138: error = VOP_ACCESS(devvp, accessmode, p->p_ucred, p);
139: if (error) {
1.9 mycroft 140: vput(devvp);
141: return (error);
142: }
1.28 fvdl 143: VOP_UNLOCK(devvp, 0);
1.9 mycroft 144: }
1.14 chopps 145: /* MNT_UPDATE? */
1.16 christos 146: if ((error = adosfs_mountfs(devvp, mp, p)) != 0) {
1.9 mycroft 147: vrele(devvp);
148: return (error);
149: }
150: amp = VFSTOADOSFS(mp);
151: amp->uid = args.uid;
152: amp->gid = args.gid;
153: amp->mask = args.mask;
154: (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
1.30 perry 155: memset(mp->mnt_stat.f_mntonname + size, 0, MNAMELEN - size);
1.9 mycroft 156: (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
157: &size);
1.30 perry 158: memset(mp->mnt_stat.f_mntfromname + size, 0, MNAMELEN - size);
1.9 mycroft 159: return (0);
1.1 chopps 160: }
161:
162: int
1.9 mycroft 163: adosfs_mountfs(devvp, mp, p)
164: struct vnode *devvp;
1.1 chopps 165: struct mount *mp;
166: struct proc *p;
167: {
168: struct disklabel dl;
169: struct partition *parp;
1.10 mycroft 170: struct adosfsmount *amp;
1.17 mhitch 171: struct buf *bp;
1.2 chopps 172: struct vnode *rvp;
1.11 cgd 173: int error, part, i;
1.1 chopps 174:
1.9 mycroft 175: part = DISKPART(devvp->v_rdev);
1.2 chopps 176: amp = NULL;
1.9 mycroft 177:
1.1 chopps 178: /*
1.9 mycroft 179: * Disallow multiple mounts of the same device.
180: * Disallow mounting of a device that is currently in use
181: * (except for root, which might share swap device for miniroot).
182: * Flush out any old buffers remaining from a previous use.
1.1 chopps 183: */
1.16 christos 184: if ((error = vfs_mountedon(devvp)) != 0)
1.2 chopps 185: return (error);
1.9 mycroft 186: if (vcount(devvp) > 1 && devvp != rootvp)
1.2 chopps 187: return (EBUSY);
1.16 christos 188: if ((error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0)) != 0)
1.2 chopps 189: return (error);
1.1 chopps 190:
191: /*
1.2 chopps 192: * open blkdev and read root block
1.1 chopps 193: */
1.16 christos 194: if ((error = VOP_OPEN(devvp, FREAD, NOCRED, p)) != 0)
1.2 chopps 195: return (error);
1.16 christos 196: error = VOP_IOCTL(devvp, DIOCGDINFO,(caddr_t)&dl, FREAD, NOCRED, p);
197: if (error)
1.1 chopps 198: goto fail;
199:
200: parp = &dl.d_partitions[part];
1.10 mycroft 201: amp = malloc(sizeof(struct adosfsmount), M_ADOSFSMNT, M_WAITOK);
1.30 perry 202: memset((char *)amp, 0, (u_long)sizeof(struct adosfsmount));
1.1 chopps 203: amp->mp = mp;
1.17 mhitch 204: if (dl.d_type == DTYPE_FLOPPY) {
205: amp->bsize = dl.d_secsize;
206: amp->secsperblk = 1;
207: }
208: else {
209: amp->bsize = parp->p_fsize * parp->p_frag;
210: amp->secsperblk = parp->p_frag;
211: }
212: amp->rootb = (parp->p_size / amp->secsperblk - 1 + parp->p_cpg) >> 1;
213: amp->numblks = parp->p_size / amp->secsperblk - parp->p_cpg;
214:
215: bp = NULL;
216: if ((error = bread(devvp, (daddr_t)BBOFF,
217: amp->bsize, NOCRED, &bp)) != 0)
218: goto fail;
219:
220: amp->dostype = adoswordn(bp, 0);
221: brelse(bp);
222:
223: if (amp->dostype < 0x444f5300 || amp->dostype > 0x444f5305) {
224: error = EINVAL;
225: goto fail;
226: }
227:
1.1 chopps 228: amp->nwords = amp->bsize >> 2;
1.17 mhitch 229: amp->dbsize = amp->bsize - (IS_FFS(amp) ? 0 : OFS_DATA_OFFSET);
1.9 mycroft 230: amp->devvp = devvp;
1.1 chopps 231:
232: mp->mnt_data = (qaddr_t)amp;
1.9 mycroft 233: mp->mnt_stat.f_fsid.val[0] = (long)devvp->v_rdev;
1.1 chopps 234: mp->mnt_stat.f_fsid.val[1] = makefstype(MOUNT_ADOSFS);
1.9 mycroft 235: mp->mnt_flag |= MNT_LOCAL;
236: devvp->v_specflags |= SI_MOUNTEDON;
1.1 chopps 237:
238: /*
239: * init anode table.
240: */
241: for (i = 0; i < ANODEHASHSZ; i++)
242: LIST_INIT(&->anodetab[i]);
243:
244: /*
245: * get the root anode, if not a valid fs this will fail.
246: */
1.16 christos 247: if ((error = VFS_ROOT(mp, &rvp)) != 0)
1.1 chopps 248: goto fail;
1.17 mhitch 249: /* allocate and load bitmap, set free space */
250: amp->bitmap = malloc(((amp->numblks + 31) / 32) * sizeof(*amp->bitmap),
251: M_ADOSFSBITMAP, M_WAITOK);
252: if (amp->bitmap)
253: adosfs_loadbitmap(amp);
254: if (mp->mnt_flag & MNT_RDONLY && amp->bitmap) {
255: /*
256: * Don't need the bitmap any more if it's read-only.
257: */
258: free(amp->bitmap, M_ADOSFSBITMAP);
259: amp->bitmap = NULL;
260: }
1.2 chopps 261: vput(rvp);
262:
1.1 chopps 263: return(0);
1.9 mycroft 264:
1.1 chopps 265: fail:
1.9 mycroft 266: (void) VOP_CLOSE(devvp, FREAD, NOCRED, p);
1.17 mhitch 267: if (amp && amp->bitmap)
268: free(amp->bitmap, M_ADOSFSBITMAP);
1.2 chopps 269: if (amp)
270: free(amp, M_ADOSFSMNT);
1.9 mycroft 271: return (error);
1.1 chopps 272: }
273:
274: int
275: adosfs_start(mp, flags, p)
276: struct mount *mp;
277: int flags;
278: struct proc *p;
279: {
1.9 mycroft 280:
281: return (0);
1.1 chopps 282: }
283:
284: int
1.9 mycroft 285: adosfs_unmount(mp, mntflags, p)
1.1 chopps 286: struct mount *mp;
1.9 mycroft 287: int mntflags;
1.1 chopps 288: struct proc *p;
289: {
1.10 mycroft 290: struct adosfsmount *amp;
1.9 mycroft 291: int error, flags;
1.1 chopps 292:
1.9 mycroft 293: flags = 0;
294: if (mntflags & MNT_FORCE)
295: flags |= FORCECLOSE;
1.16 christos 296: if ((error = vflush(mp, NULLVP, flags)) != 0)
1.9 mycroft 297: return (error);
1.1 chopps 298: amp = VFSTOADOSFS(mp);
1.9 mycroft 299: amp->devvp->v_specflags &= ~SI_MOUNTEDON;
300: error = VOP_CLOSE(amp->devvp, FREAD, NOCRED, p);
1.1 chopps 301: vrele(amp->devvp);
1.17 mhitch 302: if (amp->bitmap)
303: free(amp->bitmap, M_ADOSFSBITMAP);
1.1 chopps 304: free(amp, M_ADOSFSMNT);
1.9 mycroft 305: mp->mnt_data = (qaddr_t)0;
1.2 chopps 306: mp->mnt_flag &= ~MNT_LOCAL;
307: return (error);
1.1 chopps 308: }
309:
310: int
311: adosfs_root(mp, vpp)
312: struct mount *mp;
313: struct vnode **vpp;
314: {
1.2 chopps 315: struct vnode *nvp;
316: int error;
1.1 chopps 317:
1.16 christos 318: if ((error = VFS_VGET(mp, (ino_t)VFSTOADOSFS(mp)->rootb, &nvp)) != 0)
1.2 chopps 319: return (error);
1.17 mhitch 320: /* XXX verify it's a root block? */
1.2 chopps 321: *vpp = nvp;
322: return (0);
1.1 chopps 323: }
324:
325: int
326: adosfs_statfs(mp, sbp, p)
327: struct mount *mp;
328: struct statfs *sbp;
329: struct proc *p;
330: {
1.10 mycroft 331: struct adosfsmount *amp;
1.9 mycroft 332:
1.1 chopps 333: amp = VFSTOADOSFS(mp);
1.28 fvdl 334: #ifdef COMPAT_09
335: sbp->f_type = 16;
336: #else
1.1 chopps 337: sbp->f_type = 0;
1.28 fvdl 338: #endif
1.1 chopps 339: sbp->f_bsize = amp->bsize;
1.17 mhitch 340: sbp->f_iosize = amp->dbsize;
341: sbp->f_blocks = amp->numblks;
342: sbp->f_bfree = amp->freeblks;
343: sbp->f_bavail = amp->freeblks;
1.1 chopps 344: sbp->f_files = 0; /* who knows */
345: sbp->f_ffree = 0; /* " " */
346: if (sbp != &mp->mnt_stat) {
1.30 perry 347: memcpy(sbp->f_mntonname, mp->mnt_stat.f_mntonname, MNAMELEN);
348: memcpy(sbp->f_mntfromname, mp->mnt_stat.f_mntfromname, MNAMELEN);
1.1 chopps 349: }
350: strncpy(sbp->f_fstypename, mp->mnt_op->vfs_name, MFSNAMELEN);
1.9 mycroft 351: return (0);
1.1 chopps 352: }
353:
1.2 chopps 354: /*
355: * lookup an anode, check mount's hash table if not found, create
356: * return locked and referenced al la vget(vp, 1);
357: */
1.1 chopps 358: int
1.2 chopps 359: adosfs_vget(mp, an, vpp)
1.1 chopps 360: struct mount *mp;
1.2 chopps 361: ino_t an;
362: struct vnode **vpp;
1.1 chopps 363: {
1.10 mycroft 364: struct adosfsmount *amp;
1.2 chopps 365: struct vnode *vp;
366: struct anode *ap;
367: struct buf *bp;
368: char *nam, *tmp;
1.17 mhitch 369: int namlen, error;
1.2 chopps 370:
371: error = 0;
372: amp = VFSTOADOSFS(mp);
373: bp = NULL;
374:
375: /*
376: * check hash table. we are done if found
377: */
1.16 christos 378: if ((*vpp = adosfs_ahashget(mp, an)) != NULL)
1.2 chopps 379: return (0);
380:
1.16 christos 381: error = getnewvnode(VT_ADOSFS, mp, adosfs_vnodeop_p, &vp);
382: if (error)
1.2 chopps 383: return (error);
384:
385: /*
386: * setup, insert in hash, and lock before io.
387: */
1.31 ! thorpej 388: vp->v_data = ap = pool_get(&adosfs_node_pool, PR_WAITOK);
1.30 perry 389: memset(ap, 0, sizeof(struct anode));
1.2 chopps 390: ap->vp = vp;
391: ap->amp = amp;
392: ap->block = an;
393: ap->nwords = amp->nwords;
394: adosfs_ainshash(amp, ap);
395:
1.17 mhitch 396: if ((error = bread(amp->devvp, an * amp->secsperblk,
397: amp->bsize, NOCRED, &bp)) != 0) {
1.2 chopps 398: vput(vp);
399: return (error);
400: }
401:
402: /*
403: * get type and fill rest in based on that.
404: */
405: switch (ap->type = adosfs_getblktype(amp, bp)) {
406: case AROOT:
407: vp->v_type = VDIR;
408: vp->v_flag |= VROOT;
409: ap->mtimev.days = adoswordn(bp, ap->nwords - 10);
410: ap->mtimev.mins = adoswordn(bp, ap->nwords - 9);
411: ap->mtimev.ticks = adoswordn(bp, ap->nwords - 8);
412: ap->created.days = adoswordn(bp, ap->nwords - 7);
413: ap->created.mins = adoswordn(bp, ap->nwords - 6);
414: ap->created.ticks = adoswordn(bp, ap->nwords - 5);
415: break;
416: case ALDIR:
417: case ADIR:
418: vp->v_type = VDIR;
419: break;
420: case ALFILE:
421: case AFILE:
422: vp->v_type = VREG;
423: ap->fsize = adoswordn(bp, ap->nwords - 47);
424: break;
425: case ASLINK: /* XXX soft link */
426: vp->v_type = VLNK;
427: /*
428: * convert from BCPL string and
429: * from: "part:dir/file" to: "/part/dir/file"
430: */
431: nam = bp->b_data + (6 * sizeof(long));
1.17 mhitch 432: namlen = strlen(nam);
1.2 chopps 433: tmp = nam;
1.17 mhitch 434: while (*tmp && *tmp != ':')
1.2 chopps 435: tmp++;
436: if (*tmp == 0) {
437: ap->slinkto = malloc(namlen + 1, M_ANODE, M_WAITOK);
1.30 perry 438: memcpy(ap->slinkto, nam, namlen);
1.2 chopps 439: } else if (*nam == ':') {
440: ap->slinkto = malloc(namlen + 1, M_ANODE, M_WAITOK);
1.30 perry 441: memcpy(ap->slinkto, nam, namlen);
1.2 chopps 442: ap->slinkto[0] = '/';
443: } else {
444: ap->slinkto = malloc(namlen + 2, M_ANODE, M_WAITOK);
445: ap->slinkto[0] = '/';
1.30 perry 446: memcpy(&ap->slinkto[1], nam, namlen);
1.2 chopps 447: ap->slinkto[tmp - nam + 1] = '/';
448: namlen++;
449: }
450: ap->slinkto[namlen] = 0;
1.19 mhitch 451: ap->fsize = namlen;
1.2 chopps 452: break;
453: default:
454: brelse(bp);
455: vput(vp);
456: return (EINVAL);
457: }
1.17 mhitch 458:
459: /*
460: * Get appropriate data from this block; hard link needs
461: * to get other data from the "real" block.
462: */
463:
464: /*
465: * copy in name (from original block)
466: */
1.20 thorpej 467: nam = bp->b_data + (ap->nwords - 20) * sizeof(u_int32_t);
1.17 mhitch 468: namlen = *(u_char *)nam++;
469: if (namlen > 30) {
470: #ifdef DIAGNOSTIC
1.23 christos 471: printf("adosfs: aget: name length too long blk %d\n", an);
1.17 mhitch 472: #endif
473: brelse(bp);
474: vput(vp);
475: return (EINVAL);
476: }
1.30 perry 477: memcpy(ap->name, nam, namlen);
1.17 mhitch 478: ap->name[namlen] = 0;
479:
1.2 chopps 480: /*
481: * if dir alloc hash table and copy it in
482: */
483: if (vp->v_type == VDIR) {
484: int i;
485:
486: ap->tab = malloc(ANODETABSZ(ap) * 2, M_ANODE, M_WAITOK);
487: ap->ntabent = ANODETABENT(ap);
488: ap->tabi = (int *)&ap->tab[ap->ntabent];
1.30 perry 489: memset(ap->tabi, 0, ANODETABSZ(ap));
1.2 chopps 490: for (i = 0; i < ap->ntabent; i++)
491: ap->tab[i] = adoswordn(bp, i + 6);
492: }
493:
494: /*
495: * misc.
496: */
497: ap->pblock = adoswordn(bp, ap->nwords - 3);
498: ap->hashf = adoswordn(bp, ap->nwords - 4);
499: ap->linknext = adoswordn(bp, ap->nwords - 10);
500: ap->linkto = adoswordn(bp, ap->nwords - 11);
1.5 chopps 501:
502: /*
503: * setup last indirect block cache.
504: */
505: ap->lastlindblk = 0;
1.17 mhitch 506: if (ap->type == AFILE) {
1.5 chopps 507: ap->lastindblk = ap->block;
1.17 mhitch 508: if (adoswordn(bp, ap->nwords - 10))
509: ap->linkto = ap->block;
510: } else if (ap->type == ALFILE) {
1.5 chopps 511: ap->lastindblk = ap->linkto;
1.17 mhitch 512: brelse(bp);
513: bp = NULL;
514: error = bread(amp->devvp, ap->linkto * amp->secsperblk,
515: amp->bsize, NOCRED, &bp);
516: ap->fsize = adoswordn(bp, ap->nwords - 47);
517: /*
518: * Should ap->block be set to the real file header block?
519: */
520: ap->block = ap->linkto;
521: }
1.5 chopps 522:
1.8 chopps 523: if (ap->type == AROOT) {
1.17 mhitch 524: ap->adprot = 15;
1.8 chopps 525: ap->uid = amp->uid;
526: ap->gid = amp->gid;
527: } else {
1.17 mhitch 528: ap->adprot = adoswordn(bp, ap->nwords - 48) ^ 15;
1.25 kleink 529: /*
530: * ADOS directories do not have a `x' protection bit as
531: * it is known in VFS; this functionality is fulfilled
532: * by the ADOS `r' bit.
533: *
534: * To retain the ADOS behaviour, fake execute permissions
535: * in that case.
536: */
1.26 kleink 537: if ((ap->type == ADIR || ap->type == ALDIR) &&
538: (ap->adprot & 0x00000008) == 0)
539: ap->adprot &= ~0x00000002;
1.25 kleink 540:
1.8 chopps 541: /*
542: * Get uid/gid from extensions in file header
543: * (really need to know if this is a muFS partition)
544: */
545: ap->uid = (adoswordn(bp, ap->nwords - 49) >> 16) & 0xffff;
546: ap->gid = adoswordn(bp, ap->nwords - 49) & 0xffff;
547: if (ap->uid || ap->gid) {
548: if (ap->uid == 0xffff)
549: ap->uid = 0;
550: if (ap->gid == 0xffff)
551: ap->gid = 0;
552: ap->adprot |= 0x40000000; /* Kludge */
553: }
554: else {
555: /*
556: * uid & gid extension don't exist,
557: * so use the mount-point uid/gid
558: */
559: ap->uid = amp->uid;
560: ap->gid = amp->gid;
561: }
562: }
1.2 chopps 563: ap->mtime.days = adoswordn(bp, ap->nwords - 23);
564: ap->mtime.mins = adoswordn(bp, ap->nwords - 22);
565: ap->mtime.ticks = adoswordn(bp, ap->nwords - 21);
566:
1.17 mhitch 567: *vpp = vp; /* return vp */
568: brelse(bp); /* release buffer */
569: return (0);
570: }
571:
572: /*
573: * Load the bitmap into memory, and count the number of available
574: * blocks.
575: * The bitmap will be released if the filesystem is read-only; it's
576: * only needed to find the free space.
577: */
578: int
579: adosfs_loadbitmap(amp)
580: struct adosfsmount *amp;
581: {
582: struct buf *bp, *mapbp;
583: u_long bn;
584: int blkix, endix, mapix;
585: int bmsize;
586: int error;
587:
588: bp = mapbp = NULL;
589: bn = amp->rootb;
590: if ((error = bread(amp->devvp, bn * amp->secsperblk, amp->bsize,
591: NOCRED, &bp)) != 0)
592: return (error);
593: blkix = amp->nwords - 49;
594: endix = amp->nwords - 24;
595: mapix = 0;
596: bmsize = (amp->numblks + 31) / 32;
597: while (mapix < bmsize) {
598: int n;
599: u_long bits;
600:
601: if (adoswordn(bp, blkix) == 0)
602: break;
603: if (mapbp != NULL)
604: brelse(mapbp);
605: if ((error = bread(amp->devvp,
606: adoswordn(bp, blkix) * amp->secsperblk, amp->bsize,
607: NOCRED, &mapbp)) != 0)
608: break;
609: if (adoscksum(mapbp, amp->nwords)) {
1.2 chopps 610: #ifdef DIAGNOSTIC
1.23 christos 611: printf("adosfs: loadbitmap - cksum of blk %d failed\n",
1.21 christos 612: adoswordn(bp, blkix));
1.1 chopps 613: #endif
1.17 mhitch 614: /* XXX Force read-only? Set free space 0? */
615: break;
616: }
617: n = 1;
618: while (n < amp->nwords && mapix < bmsize) {
619: amp->bitmap[mapix++] = bits = adoswordn(mapbp, n);
620: ++n;
621: if (mapix == bmsize && amp->numblks & 31)
622: bits &= ~(0xffffffff << (amp->numblks & 31));
623: while (bits) {
624: if (bits & 1)
625: ++amp->freeblks;
626: bits >>= 1;
627: }
628: }
629: ++blkix;
630: if (mapix < bmsize && blkix == endix) {
631: bn = adoswordn(bp, blkix);
632: brelse(bp);
633: if ((error = bread(amp->devvp, bn * amp->secsperblk,
634: amp->bsize, NOCRED, &bp)) != 0)
635: break;
636: /*
637: * Why is there no checksum on these blocks?
638: */
639: blkix = 0;
640: endix = amp->nwords - 1;
641: }
642: }
643: if (bp)
1.2 chopps 644: brelse(bp);
1.17 mhitch 645: if (mapbp)
646: brelse(mapbp);
647: return (error);
1.1 chopps 648: }
649:
1.14 chopps 650:
651: /*
652: * File handle to vnode
653: *
654: * Have to be really careful about stale file handles:
655: * - check that the inode number is in range
656: * - call iget() to get the locked inode
657: * - check for an unallocated inode (i_mode == 0)
658: * - check that the generation number matches
659: */
660:
661: struct ifid {
662: ushort ifid_len;
663: ushort ifid_pad;
664: int ifid_ino;
665: long ifid_start;
666: };
667:
1.1 chopps 668: int
1.14 chopps 669: adosfs_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
1.1 chopps 670: struct mount *mp;
671: struct fid *fhp;
1.14 chopps 672: struct mbuf *nam;
1.1 chopps 673: struct vnode **vpp;
1.14 chopps 674: int *exflagsp;
675: struct ucred **credanonp;
1.1 chopps 676: {
1.14 chopps 677: struct ifid *ifhp = (struct ifid *)fhp;
678: struct adosfsmount *amp = VFSTOADOSFS(mp);
1.16 christos 679: #if 0
1.14 chopps 680: struct anode *ap;
1.16 christos 681: #endif
1.14 chopps 682: struct netcred *np;
683: struct vnode *nvp;
684: int error;
685:
1.1 chopps 686: #ifdef ADOSFS_DIAGNOSTIC
1.23 christos 687: printf("adfhtovp(%x, %x, %x)\n", mp, fhp, vpp);
1.1 chopps 688: #endif
1.14 chopps 689:
690: /*
691: * Get the export permission structure for this <mp, client> tuple.
692: */
693: np = vfs_export_lookup(mp, &->export, nam);
694: if (np == NULL)
695: return (EACCES);
696:
1.16 christos 697: if ((error = VFS_VGET(mp, ifhp->ifid_ino, &nvp)) != 0) {
1.14 chopps 698: *vpp = NULLVP;
699: return (error);
700: }
701: #if 0
702: ap = VTOA(nvp);
703: if (ap->inode.iso_mode == 0) {
704: vput(nvp);
705: *vpp = NULLVP;
706: return (ESTALE);
707: }
708: #endif
709: *vpp = nvp;
710: *exflagsp = np->netc_exflags;
711: *credanonp = &np->netc_anon;
1.1 chopps 712: return(0);
713: }
714:
715: int
716: adosfs_vptofh(vp, fhp)
717: struct vnode *vp;
718: struct fid *fhp;
719: {
1.14 chopps 720: struct anode *ap = VTOA(vp);
721: struct ifid *ifhp;
722:
723: ifhp = (struct ifid *)fhp;
724: ifhp->ifid_len = sizeof(struct ifid);
725:
726: ifhp->ifid_ino = ap->block;
727: ifhp->ifid_start = ap->block;
728:
1.1 chopps 729: #ifdef ADOSFS_DIAGNOSTIC
1.23 christos 730: printf("advptofh(%x, %x)\n", vp, fhp);
1.1 chopps 731: #endif
732: return(0);
733: }
734:
735: int
1.2 chopps 736: adosfs_quotactl(mp, cmds, uid, arg, p)
737: struct mount *mp;
738: int cmds;
739: uid_t uid;
740: caddr_t arg;
741: struct proc *p;
742: {
743: return(EOPNOTSUPP);
744: }
745:
746: int
1.16 christos 747: adosfs_sync(mp, waitfor, uc, p)
1.2 chopps 748: struct mount *mp;
749: int waitfor;
1.16 christos 750: struct ucred *uc;
751: struct proc *p;
1.1 chopps 752: {
753: #ifdef ADOSFS_DIAGNOSTIC
1.23 christos 754: printf("ad_sync(%x, %x)\n", mp, waitfor);
1.1 chopps 755: #endif
756: return(0);
757: }
758:
1.16 christos 759: void
1.2 chopps 760: adosfs_init()
761: {
1.28 fvdl 762: simple_lock_init(&adosfs_hashlock);
1.31 ! thorpej 763:
! 764: pool_init(&adosfs_node_pool, sizeof(struct anode), 0, 0, 0,
! 765: "adosndpl", 0, pool_page_alloc_nointr, pool_page_free_nointr,
! 766: M_ANODE);
1.28 fvdl 767: }
768:
769: int
770: adosfs_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
771: int *name;
772: u_int namelen;
773: void *oldp;
774: size_t *oldlenp;
775: void *newp;
776: size_t newlen;
777: struct proc *p;
778: {
779: return (EOPNOTSUPP);
1.2 chopps 780: }
781:
1.1 chopps 782: /*
783: * vfs generic function call table
784: */
1.27 thorpej 785:
786: extern struct vnodeopv_desc adosfs_vnodeop_opv_desc;
787:
788: struct vnodeopv_desc *adosfs_vnodeopv_descs[] = {
789: &adosfs_vnodeop_opv_desc,
790: NULL,
791: };
792:
1.1 chopps 793: struct vfsops adosfs_vfsops = {
794: MOUNT_ADOSFS,
795: adosfs_mount,
796: adosfs_start,
797: adosfs_unmount,
798: adosfs_root,
799: adosfs_quotactl,
800: adosfs_statfs,
801: adosfs_sync,
1.2 chopps 802: adosfs_vget,
1.1 chopps 803: adosfs_fhtovp,
804: adosfs_vptofh,
805: adosfs_init,
1.28 fvdl 806: adosfs_sysctl,
1.27 thorpej 807: NULL, /* vfs_mountroot */
808: adosfs_vnodeopv_descs,
809: };
CVSweb <webmaster@jp.NetBSD.org>