int udf_vget(struct mount *mp, ino_t ino, struct vnode **vpp) { struct buf *bp; struct vnode *devvp; struct umount *ump; struct proc *p; struct vnode *vp, *nvp; struct unode *up; struct extfile_entry *xfe; struct file_entry *fe; int error, sector, size; p = curproc; bp = NULL; *vpp = NULL; ump = VFSTOUDFFS(mp); /* See if we already have this in the cache */ if ((error = udf_hashlookup(ump, ino, LK_EXCLUSIVE, vpp)) != 0) return (error); if (*vpp != NULL) return (0); /* * Allocate memory and check the tag id's before grabbing a new * vnode, since it's hard to roll back if there is a problem. */ up = pool_get(&unode_pool, PR_WAITOK | PR_ZERO); /* * Copy in the file entry. Per the spec, the size can only be 1 block. */ sector = ino; devvp = ump->um_devvp; udf_vat_map(ump, §or); if ((error = RDSECTOR(devvp, sector, ump->um_bsize, &bp)) != 0) { printf("Cannot read sector %d\n", sector); pool_put(&unode_pool, up); if (bp != NULL) brelse(bp); return (error); } xfe = (struct extfile_entry *)bp->b_data; fe = (struct file_entry *)bp->b_data; error = udf_checktag(&xfe->tag, TAGID_EXTFENTRY); if (error == 0) { size = letoh32(xfe->l_ea) + letoh32(xfe->l_ad); } else { error = udf_checktag(&fe->tag, TAGID_FENTRY); if (error) { printf("Invalid file entry!\n"); pool_put(&unode_pool, up); if (bp != NULL) brelse(bp); return (ENOMEM); } else size = letoh32(fe->l_ea) + letoh32(fe->l_ad); } /* Allocate max size of FE/XFE. */ up->u_fentry = malloc(size + UDF_EXTFENTRY_SIZE, M_UDFFENTRY, M_NOWAIT | M_ZERO); if (up->u_fentry == NULL) { pool_put(&unode_pool, up); if (bp != NULL) brelse(bp); return (ENOMEM); /* Cannot allocate file entry block */ } if (udf_checktag(&xfe->tag, TAGID_EXTFENTRY) == 0) bcopy(bp->b_data, up->u_fentry, size + UDF_EXTFENTRY_SIZE); else bcopy(bp->b_data, up->u_fentry, size + UDF_FENTRY_SIZE); brelse(bp); bp = NULL; if ((error = udf_allocv(mp, &vp, p))) { free(up->u_fentry, M_UDFFENTRY); pool_put(&unode_pool, up); return (error); /* Error from udf_allocv() */ } up->u_vnode = vp; up->u_ino = ino; up->u_devvp = ump->um_devvp; up->u_dev = ump->um_dev; up->u_ump = ump; vp->v_data = up; vref(ump->um_devvp); lockinit(&up->u_lock, PINOD, "unode", 0, 0); /* * udf_hashins() will lock the vnode for us. */ udf_hashins(up); switch (up->u_fentry->icbtag.file_type) { default: printf("Unrecognized file type (%d)\n", vp->v_type); vp->v_type = VREG; break; case UDF_ICB_FILETYPE_DIRECTORY: vp->v_type = VDIR; break; case UDF_ICB_FILETYPE_BLOCKDEVICE: vp->v_type = VBLK; break; case UDF_ICB_FILETYPE_CHARDEVICE: vp->v_type = VCHR; break; case UDF_ICB_FILETYPE_FIFO: vp->v_type = VFIFO; break; case UDF_ICB_FILETYPE_SOCKET: vp->v_type = VSOCK; break; case UDF_ICB_FILETYPE_SYMLINK: vp->v_type = VLNK; break; case UDF_ICB_FILETYPE_RANDOMACCESS: case UDF_ICB_FILETYPE_REALTIME: case UDF_ICB_FILETYPE_UNKNOWN: vp->v_type = VREG; break; } /* check if this is a vnode alias */ if ((nvp = checkalias(vp, up->u_dev, ump->um_mountp)) != NULL) { printf("found a vnode alias\n"); /* * Discard unneeded vnode, but save its udf_node. * Note that the lock is carried over in the udf_node */ nvp->v_data = vp->v_data; vp->v_data = NULL; vp->v_op = spec_vnodeop_p; vrele(vp); vgone(vp); /* * Reinitialize aliased inode. */ vp = nvp; ump->um_devvp = vp; } *vpp = vp; return (0); }
/* ARGSUSED */ int mfs_mount(struct mount *mp, const char *path, void *data, struct nameidata *ndp, struct proc *p) { struct vnode *devvp; struct mfs_args args; struct ufsmount *ump; struct fs *fs; struct mfsnode *mfsp; char fspec[MNAMELEN]; int flags, error; error = copyin(data, &args, sizeof(struct mfs_args)); if (error) return (error); /* * If updating, check whether changing from read-only to * read/write; if there is no device name, that's all we do. */ if (mp->mnt_flag & MNT_UPDATE) { ump = VFSTOUFS(mp); fs = ump->um_fs; if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) { flags = WRITECLOSE; if (mp->mnt_flag & MNT_FORCE) flags |= FORCECLOSE; error = ffs_flushfiles(mp, flags, p); if (error) return (error); } if (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) fs->fs_ronly = 0; #ifdef EXPORTMFS if (args.fspec == NULL) return (vfs_export(mp, &ump->um_export, &args.export_info)); #endif return (0); } error = copyinstr(args.fspec, fspec, sizeof(fspec), NULL); if (error) return (error); error = getnewvnode(VT_MFS, NULL, &mfs_vops, &devvp); if (error) return (error); devvp->v_type = VBLK; if (checkalias(devvp, makedev(255, mfs_minor), NULL)) panic("mfs_mount: dup dev"); mfs_minor++; mfsp = malloc(sizeof *mfsp, M_MFSNODE, M_WAITOK | M_ZERO); devvp->v_data = mfsp; mfsp->mfs_baseoff = args.base; mfsp->mfs_size = args.size; mfsp->mfs_vnode = devvp; mfsp->mfs_pid = p->p_pid; bufq_init(&mfsp->mfs_bufq, BUFQ_FIFO); if ((error = ffs_mountfs(devvp, mp, p)) != 0) { mfsp->mfs_shutdown = 1; vrele(devvp); return (error); } ump = VFSTOUFS(mp); fs = ump->um_fs; memset(fs->fs_fsmnt, 0, sizeof(fs->fs_fsmnt)); strlcpy(fs->fs_fsmnt, path, sizeof(fs->fs_fsmnt)); memcpy(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN); memset(mp->mnt_stat.f_mntfromname, 0, MNAMELEN); strlcpy(mp->mnt_stat.f_mntfromname, fspec, MNAMELEN); memset(mp->mnt_stat.f_mntfromspec, 0, MNAMELEN); strlcpy(mp->mnt_stat.f_mntfromspec, fspec, MNAMELEN); memcpy(&mp->mnt_stat.mount_info.mfs_args, &args, sizeof(args)); return (0); }
/* * Initialize the vnode associated with a new inode, handle aliased * vnodes. */ int ufs_vinit(struct mount *mntp, struct vops *specops, struct vops *fifoops, struct vnode **vpp) { struct inode *ip; struct vnode *vp, *nvp; struct timeval mtv; vp = *vpp; ip = VTOI(vp); switch(vp->v_type = IFTOVT(DIP(ip, mode))) { case VCHR: case VBLK: vp->v_op = specops; if ((nvp = checkalias(vp, DIP(ip, rdev), mntp)) != NULL) { /* * Discard unneeded vnode, but save its inode. * Note that the lock is carried over in the inode * to the replacement vnode. */ nvp->v_data = vp->v_data; vp->v_data = NULL; vp->v_op = &spec_vops; #ifdef VFSLCKDEBUG vp->v_flag &= ~VLOCKSWORK; #endif vrele(vp); vgone(vp); /* * Reinitialize aliased inode. */ vp = nvp; ip->i_vnode = vp; } break; case VFIFO: #ifdef FIFO vp->v_op = fifoops; break; #else return (EOPNOTSUPP); #endif case VNON: case VBAD: case VSOCK: case VLNK: case VDIR: case VREG: break; } if (ip->i_number == ROOTINO) vp->v_flag |= VROOT; /* * Initialize modrev times */ getmicrouptime(&mtv); SETHIGH(ip->i_modrev, mtv.tv_sec); SETLOW(ip->i_modrev, mtv.tv_usec * 4294); *vpp = vp; return (0); }
int exalias(void) { Reswd rw; hwend(); if (interact && isset(SHINSTDIN) && !strin && !incasepat && tok == STRING && !nocorrect && !(inbufflags & INP_ALIAS) && (isset(CORRECTALL) || (isset(CORRECT) && incmdpos))) spckword(&tokstr, 1, incmdpos, 1); if (!tokstr) { zshlextext = tokstrings[tok]; if (tok == NEWLIN) return 0; return checkalias(); } else { VARARR(char, copy, (strlen(tokstr) + 1)); if (has_token(tokstr)) { char *p, *t; zshlextext = p = copy; for (t = tokstr; (*p++ = itok(*t) ? ztokens[*t++ - Pound] : *t++);); } else zshlextext = tokstr; if ((lexflags & LEXFLAGS_ZLE) && !(inbufflags & INP_ALIAS)) { int zp = lexflags; gotword(); if ((zp & LEXFLAGS_ZLE) && !lexflags) { if (zshlextext == copy) zshlextext = tokstr; return 0; } } if (tok == STRING) { /* Check for an alias */ if ((zshlextext != copy || !isset(POSIXALIASES)) && checkalias()) { if (zshlextext == copy) zshlextext = tokstr; return 1; } /* Then check for a reserved word */ if ((incmdpos || (unset(IGNOREBRACES) && unset(IGNORECLOSEBRACES) && zshlextext[0] == '}' && !zshlextext[1])) && (rw = (Reswd) reswdtab->getnode(reswdtab, zshlextext))) { tok = rw->token; inrepeat_ = (tok == REPEAT); if (tok == DINBRACK) incond = 1; } else if (incond && !strcmp(zshlextext, "]]")) { tok = DOUTBRACK; incond = 0; } else if (incond == 1 && zshlextext[0] == '!' && !zshlextext[1]) tok = BANG; } inalmore = 0; if (zshlextext == copy) zshlextext = tokstr; } return 0; }
/* ARGSUSED */ int mfs_mount(struct mount *mp, const char *path, void *data, struct nameidata *ndp, struct proc *p) { struct vnode *devvp; struct mfs_args args; struct ufsmount *ump; struct fs *fs; struct mfsnode *mfsp; size_t size; int flags, error; error = copyin(data, (caddr_t)&args, sizeof (struct mfs_args)); if (error) return (error); /* * If updating, check whether changing from read-only to * read/write; if there is no device name, that's all we do. */ if (mp->mnt_flag & MNT_UPDATE) { ump = VFSTOUFS(mp); fs = ump->um_fs; if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) { flags = WRITECLOSE; if (mp->mnt_flag & MNT_FORCE) flags |= FORCECLOSE; error = ffs_flushfiles(mp, flags, p); if (error) return (error); } if (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) fs->fs_ronly = 0; #ifdef EXPORTMFS if (args.fspec == 0) return (vfs_export(mp, &ump->um_export, &args.export_info)); #endif return (0); } error = getnewvnode(VT_MFS, (struct mount *)0, mfs_vnodeop_p, &devvp); if (error) return (error); devvp->v_type = VBLK; if (checkalias(devvp, makedev(255, mfs_minor), (struct mount *)0)) panic("mfs_mount: dup dev"); mfs_minor++; mfsp = malloc(sizeof *mfsp, M_MFSNODE, M_WAITOK); devvp->v_data = mfsp; mfsp->mfs_baseoff = args.base; mfsp->mfs_size = args.size; mfsp->mfs_vnode = devvp; mfsp->mfs_pid = p->p_pid; mfsp->mfs_buflist = (struct buf *)0; if ((error = ffs_mountfs(devvp, mp, p)) != 0) { mfsp->mfs_buflist = (struct buf *)-1; vrele(devvp); return (error); } ump = VFSTOUFS(mp); fs = ump->um_fs; (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size); bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size); bcopy(fs->fs_fsmnt, mp->mnt_stat.f_mntonname, MNAMELEN); (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size); bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); bcopy(&args, &mp->mnt_stat.mount_info.mfs_args, sizeof(args)); return (0); }