int ext2fs_mountroot(void) { extern struct vnode *rootvp; struct m_ext2fs *fs; struct mount *mp; struct ufsmount *ump; int error; if (device_class(root_device) != DV_DISK) return ENODEV; if ((error = vfs_rootmountalloc(MOUNT_EXT2FS, "root_device", &mp))) { vrele(rootvp); return error; } if ((error = ext2fs_mountfs(rootvp, mp)) != 0) { vfs_unbusy(mp, false, NULL); vfs_destroy(mp); return error; } mountlist_append(mp); ump = VFSTOUFS(mp); fs = ump->um_e2fs; ext2fs_sb_setmountinfo(fs, mp); (void)ext2fs_statvfs(mp, &mp->mnt_stat); vfs_unbusy(mp, false, NULL); setrootfstime((time_t)fs->e2fs.e2fs_wtime); return 0; }
static int ntfs_mountroot(void) { struct mount *mp; struct lwp *l = curlwp; /* XXX */ int error; struct ntfs_args args; if (device_class(root_device) != DV_DISK) return (ENODEV); if ((error = vfs_rootmountalloc(MOUNT_NTFS, "root_device", &mp))) { vrele(rootvp); return (error); } args.flag = 0; args.uid = 0; args.gid = 0; args.mode = 0777; if ((error = ntfs_mountfs(rootvp, mp, &args, l)) != 0) { vfs_unbusy(mp, false, NULL); vfs_destroy(mp); return (error); } mountlist_append(mp); (void)ntfs_statvfs(mp, &mp->mnt_stat); vfs_unbusy(mp, false, NULL); return (0); }
int cd9660_mountroot(void) { struct mount *mp; struct lwp *l = curlwp; int error; struct iso_args args; if (device_class(root_device) != DV_DISK) return (ENODEV); if ((error = vfs_rootmountalloc(MOUNT_CD9660, "root_device", &mp)) != 0) { vrele(rootvp); return (error); } args.flags = ISOFSMNT_ROOT; if ((error = iso_mountfs(rootvp, mp, l, &args)) != 0) { vfs_unbusy(mp, false, NULL); vfs_destroy(mp); return (error); } mountlist_append(mp); (void)cd9660_statvfs(mp, &mp->mnt_stat); vfs_unbusy(mp, false, NULL); return (0); }
/* * Called by main() when ufs is going to be mounted as root. */ lfs_mountroot() { extern struct vnode *rootvp; struct fs *fs; struct mount *mp; struct proc *p = curproc; /* XXX */ int error; /* * Get vnodes for swapdev and rootdev. */ if ((error = bdevvp(swapdev, &swapdev_vp)) || (error = bdevvp(rootdev, &rootvp))) { printf("lfs_mountroot: can't setup bdevvp's"); return (error); } if (error = vfs_rootmountalloc("lfs", "root_device", &mp)) return (error); if (error = lfs_mountfs(rootvp, mp, p)) { mp->mnt_vfc->vfc_refcount--; vfs_unbusy(mp, p); free(mp, M_MOUNT); return (error); } simple_lock(&mountlist_slock); CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); simple_unlock(&mountlist_slock); (void)lfs_statfs(mp, &mp->mnt_stat, p); vfs_unbusy(mp, p); return (0); }
int v7fs_mountroot(void) { struct mount *mp; int error; DPRINTF(""); /* On mountroot, devvp (rootdev) is opened by vfs_mountroot */ if ((error = is_v7fs_partition (rootvp))) return error; if ((error = vfs_rootmountalloc(MOUNT_V7FS, "root_device", &mp))) { DPRINTF("mountalloc error=%d\n", error); vrele(rootvp); return error; } if ((error = v7fs_mountfs(rootvp, mp, _BYTE_ORDER))) { DPRINTF("mountfs error=%d\n", error); vfs_unbusy(mp, false, NULL); vfs_destroy(mp); return error; } mountlist_append(mp); vfs_unbusy(mp, false, NULL); return 0; }
int cd9660_mountroot(void) { struct mount *mp; extern struct vnode *rootvp; struct proc *p = curproc; /* XXX */ int error; struct iso_args args; /* * Get vnodes for swapdev and rootdev. */ if ((error = bdevvp(swapdev, &swapdev_vp)) || (error = bdevvp(rootdev, &rootvp))) { printf("cd9660_mountroot: can't setup bdevvp's"); return (error); } if ((error = vfs_rootmountalloc("cd9660", "root_device", &mp)) != 0) return (error); args.flags = ISOFSMNT_ROOT; if ((error = iso_mountfs(rootvp, mp, p, &args)) != 0) { mp->mnt_vfc->vfc_refcount--; vfs_unbusy(mp); free(mp, M_MOUNT, 0); return (error); } TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list); (void)cd9660_statfs(mp, &mp->mnt_stat, p); vfs_unbusy(mp); inittodr(0); return (0); }
int compat_20_netbsd32_getfsstat(struct lwp *l, const struct compat_20_netbsd32_getfsstat_args *uap, register_t *retval) { /* { syscallarg(netbsd32_statfsp_t) buf; syscallarg(netbsd32_long) bufsize; syscallarg(int) flags; } */ struct mount *mp, *nmp; struct statvfs *sp; struct netbsd32_statfs sb32; void *sfsp; long count, maxcount, error; maxcount = SCARG(uap, bufsize) / sizeof(struct netbsd32_statfs); sfsp = SCARG_P32(uap, buf); mutex_enter(&mountlist_lock); count = 0; for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { if (vfs_busy(mp, &nmp)) { continue; } if (sfsp && count < maxcount) { sp = &mp->mnt_stat; /* * If MNT_NOWAIT or MNT_LAZY is specified, do not * refresh the fsstat cache. MNT_WAIT or MNT_LAZY * overrides MNT_NOWAIT. */ if (SCARG(uap, flags) != MNT_NOWAIT && SCARG(uap, flags) != MNT_LAZY && (SCARG(uap, flags) == MNT_WAIT || SCARG(uap, flags) == 0) && (error = VFS_STATVFS(mp, sp)) != 0) { mutex_enter(&mountlist_lock); vfs_unbusy(mp, false, &nmp); continue; } sp->f_flag = mp->mnt_flag & MNT_VISFLAGMASK; compat_20_netbsd32_from_statvfs(sp, &sb32); error = copyout(&sb32, sfsp, sizeof(sb32)); if (error) { vfs_unbusy(mp, false, NULL); return (error); } sfsp = (char *)sfsp + sizeof(sb32); } count++; mutex_enter(&mountlist_lock); vfs_unbusy(mp, false, &nmp); } mutex_exit(&mountlist_lock); if (sfsp && count > maxcount) *retval = maxcount; else *retval = count; return (0); }
/* * Called by main() when ufs is going to be mounted as root. */ ffs_mountroot() { extern struct vnode *rootvp; struct fs *fs; struct mount *mp; struct proc *p = current_proc(); /* XXX */ struct ufsmount *ump; u_int size; int error; /* * Get vnode for rootdev. */ if (error = bdevvp(rootdev, &rootvp)) { printf("ffs_mountroot: can't setup bdevvp"); return (error); } if (error = vfs_rootmountalloc("ufs", "root_device", &mp)) { vrele(rootvp); /* release the reference from bdevvp() */ return (error); } /* Must set the MNT_ROOTFS flag before doing the actual mount */ mp->mnt_flag |= MNT_ROOTFS; /* Set asynchronous flag by default */ mp->mnt_flag |= MNT_ASYNC; if (error = ffs_mountfs(rootvp, mp, p)) { mp->mnt_vfc->vfc_refcount--; if (mp->mnt_kern_flag & MNTK_IO_XINFO) FREE(mp->mnt_xinfo_ptr, M_TEMP); vfs_unbusy(mp, p); vrele(rootvp); /* release the reference from bdevvp() */ FREE_ZONE(mp, sizeof (struct mount), M_MOUNT); return (error); } simple_lock(&mountlist_slock); CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); simple_unlock(&mountlist_slock); ump = VFSTOUFS(mp); fs = ump->um_fs; (void) copystr(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN - 1, 0); (void)ffs_statfs(mp, &mp->mnt_stat, p); vfs_unbusy(mp, p); inittodr(fs->fs_time); return (0); }
static OSKIT_COMDECL filesystem_sync(oskit_filesystem_t *f, oskit_bool_t wait) { struct gfilesystem *fs = (struct gfilesystem *) f; struct mount *mp; struct proc *p; oskit_error_t ferror; int error, asyncflag; if (!fs || !fs->count || !fs->mp) return OSKIT_E_INVALIDARG; ferror = getproc(&p); if (ferror) return ferror; mp = fs->mp; error = 0; if ((mp->mnt_flag & (MNT_MLOCK|MNT_RDONLY|MNT_MPBUSY)) == 0 && !vfs_busy(mp)) { asyncflag = mp->mnt_flag & MNT_ASYNC; mp->mnt_flag &= ~MNT_ASYNC; error = VFS_SYNC(mp, wait ? MNT_WAIT : MNT_NOWAIT, p->p_ucred, p); if (asyncflag) mp->mnt_flag |= MNT_ASYNC; vfs_unbusy(mp); } prfree(p); if (error) return errno_to_oskit_error(error); return 0; }
/* * Do operations associated with quotas */ int ulfs_quotactl(struct mount *mp, struct quotactl_args *args) { #if !defined(LFS_QUOTA) && !defined(LFS_QUOTA2) (void) mp; (void) args; return (EOPNOTSUPP); #else struct lwp *l = curlwp; int error; /* Mark the mount busy, as we're passing it to kauth(9). */ error = vfs_busy(mp, NULL); if (error) { return (error); } mutex_enter(&mp->mnt_updating); error = lfsquota_handle_cmd(mp, l, args); mutex_exit(&mp->mnt_updating); vfs_unbusy(mp, false, NULL); return (error); #endif }
static int vfs_getrealpath(const char * path, char * realpath, size_t bufsize, vfs_context_t ctx) { vnode_t vp; struct mount *mp = NULL; char *str; char ch; uint32_t id; ino64_t ino; int error; int length; /* Get file system id and move str to next component. */ id = strtoul(path, &str, 10); if (id == 0 || str[0] != '/') { return (EINVAL); } while (*str == '/') { str++; } ch = *str; mp = mount_lookupby_volfsid(id, 1); if (mp == NULL) { return (EINVAL); /* unexpected failure */ } /* Check for an alias to a file system root. */ if (ch == '@' && str[1] == '\0') { ino = 2; str++; } else { /* Get file id and move str to next component. */ ino = strtouq(str, &str, 10); } /* Get the target vnode. */ if (ino == 2) { error = VFS_ROOT(mp, &vp, ctx); } else { error = VFS_VGET(mp, ino, &vp, ctx); } vfs_unbusy(mp); if (error) { goto out; } realpath[0] = '\0'; /* Get the absolute path to this vnode. */ error = build_path(vp, realpath, bufsize, &length, 0, ctx); vnode_put(vp); if (error == 0 && *str != '\0') { int attempt = strlcat(realpath, str, MAXPATHLEN); if (attempt > MAXPATHLEN){ error = ENAMETOOLONG; } } out: return (error); }
/* * Do a lazy sync of the filesystem. */ int sync_fsync(void *v) { struct vop_fsync_args *ap = v; struct vnode *syncvp = ap->a_vp; struct mount *mp = syncvp->v_mount; int asyncflag; /* * We only need to do something if this is a lazy evaluation. */ if (ap->a_waitfor != MNT_LAZY) return (0); /* * Move ourselves to the back of the sync list. */ vn_syncer_add_to_worklist(syncvp, syncdelay); /* * Walk the list of vnodes pushing all that are dirty and * not already on the sync list. */ if (vfs_busy(mp, VB_READ|VB_NOWAIT) == 0) { asyncflag = mp->mnt_flag & MNT_ASYNC; mp->mnt_flag &= ~MNT_ASYNC; VFS_SYNC(mp, MNT_LAZY, ap->a_cred, ap->a_p); if (asyncflag) mp->mnt_flag |= MNT_ASYNC; vfs_unbusy(mp); } return (0); }
static int msdosfs_deget_dotdot(struct vnode *vp, u_long cluster, int blkoff, struct vnode **rvp) { struct mount *mp; struct msdosfsmount *pmp; struct denode *rdp; int ltype, error; mp = vp->v_mount; pmp = VFSTOMSDOSFS(mp); ltype = VOP_ISLOCKED(vp); KASSERT(ltype == LK_EXCLUSIVE || ltype == LK_SHARED, ("msdosfs_deget_dotdot: vp not locked")); error = vfs_busy(mp, MBF_NOWAIT); if (error != 0) { vfs_ref(mp); VOP_UNLOCK(vp, 0); error = vfs_busy(mp, 0); vn_lock(vp, ltype | LK_RETRY); vfs_rel(mp); if (error != 0) return (ENOENT); if (vp->v_iflag & VI_DOOMED) { vfs_unbusy(mp); return (ENOENT); } } VOP_UNLOCK(vp, 0); error = deget(pmp, cluster, blkoff, &rdp); vfs_unbusy(mp); if (error == 0) *rvp = DETOV(rdp); if (*rvp != vp) vn_lock(vp, ltype | LK_RETRY); if (vp->v_iflag & VI_DOOMED) { if (error == 0) { if (*rvp == vp) vunref(*rvp); else vput(*rvp); } error = ENOENT; } return (error); }
int ffs_mountroot(void) { struct fs *fs; struct mount *mp; struct proc *p = curproc; /* XXX */ struct ufsmount *ump; int error; /* * Get vnodes for swapdev and rootdev. */ swapdev_vp = NULL; if ((error = bdevvp(swapdev, &swapdev_vp)) || (error = bdevvp(rootdev, &rootvp))) { printf("ffs_mountroot: can't setup bdevvp's\n"); if (swapdev_vp) vrele(swapdev_vp); return (error); } if ((error = vfs_rootmountalloc("ffs", "root_device", &mp)) != 0) { vrele(swapdev_vp); vrele(rootvp); return (error); } if ((error = ffs_mountfs(rootvp, mp, p)) != 0) { mp->mnt_vfc->vfc_refcount--; vfs_unbusy(mp); free(mp, M_MOUNT); vrele(swapdev_vp); vrele(rootvp); return (error); } CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); ump = VFSTOUFS(mp); fs = ump->um_fs; (void) copystr(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN - 1, 0); (void)ffs_statfs(mp, &mp->mnt_stat, p); vfs_unbusy(mp); inittodr(fs->fs_time); return (0); }
int mfs_mountroot(void) { struct fs *fs; struct mount *mp; struct lwp *l = curlwp; /* XXX */ struct ufsmount *ump; struct mfsnode *mfsp; int error = 0; if ((error = vfs_rootmountalloc(MOUNT_MFS, "mfs_root", &mp))) { vrele(rootvp); return (error); } mfsp = kmem_alloc(sizeof(*mfsp), KM_SLEEP); rootvp->v_data = mfsp; rootvp->v_op = mfs_vnodeop_p; rootvp->v_tag = VT_MFS; mfsp->mfs_baseoff = mfs_rootbase; mfsp->mfs_size = mfs_rootsize; mfsp->mfs_vnode = rootvp; mfsp->mfs_proc = NULL; /* indicate kernel space */ mfsp->mfs_shutdown = 0; cv_init(&mfsp->mfs_cv, "mfs"); mfsp->mfs_refcnt = 1; bufq_alloc(&mfsp->mfs_buflist, "fcfs", 0); if ((error = ffs_mountfs(rootvp, mp, l)) != 0) { vfs_unbusy(mp, false, NULL); bufq_free(mfsp->mfs_buflist); vfs_destroy(mp); kmem_free(mfsp, sizeof(*mfsp)); return (error); } mutex_enter(&mountlist_lock); CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); mutex_exit(&mountlist_lock); mp->mnt_vnodecovered = NULLVP; ump = VFSTOUFS(mp); fs = ump->um_fs; (void) copystr(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN - 1, 0); (void)ffs_statvfs(mp, &mp->mnt_stat); vfs_unbusy(mp, false, NULL); return (0); }
__private_extern__ int fuse_internal_remove(vnode_t dvp, vnode_t vp, struct componentname *cnp, enum fuse_opcode op, vfs_context_t context) { struct fuse_dispatcher fdi; struct vnode_attr *vap = VTOVA(vp); int need_invalidate = 0; uint64_t target_nlink = 0; mount_t mp = vnode_mount(vp); int err = 0; fdisp_init(&fdi, cnp->cn_namelen + 1); fdisp_make_vp(&fdi, op, dvp, context); memcpy(fdi.indata, cnp->cn_nameptr, cnp->cn_namelen); ((char *)fdi.indata)[cnp->cn_namelen] = '\0'; if ((vap->va_nlink > 1) && vnode_isreg(vp)) { need_invalidate = 1; target_nlink = vap->va_nlink; } if (!(err = fdisp_wait_answ(&fdi))) { fuse_ticket_drop(fdi.tick); } fuse_invalidate_attr(dvp); fuse_invalidate_attr(vp); /* * XXX: M_MACFUSE_INVALIDATE_CACHED_VATTRS_UPON_UNLINK * * Consider the case where vap->va_nlink > 1 for the entity being * removed. In our world, other in-memory vnodes that share a link * count each with this one may not know right way that this one just * got deleted. We should let them know, say, through a vnode_iterate() * here and a callback that does fuse_invalidate_attr(vp) on each * relevant vnode. */ if (need_invalidate && !err) { if (!vfs_busy(mp, LK_NOWAIT)) { vnode_iterate(mp, 0, fuse_internal_remove_callback, (void *)&target_nlink); vfs_unbusy(mp); } else { IOLog("MacFUSE: skipping link count fixup upon remove\n"); } } return err; }
int mfs_mountroot(void) { struct fs *fs; struct mount *mp; struct proc *p = curproc; struct ufsmount *ump; struct mfsnode *mfsp; int error; if ((error = bdevvp(swapdev, &swapdev_vp)) || (error = bdevvp(rootdev, &rootvp))) { printf("mfs_mountroot: can't setup bdevvp's"); return (error); } if ((error = vfs_rootmountalloc("mfs", "mfs_root", &mp)) != 0) return (error); mfsp = malloc(sizeof *mfsp, M_MFSNODE, M_WAITOK); rootvp->v_data = mfsp; rootvp->v_op = mfs_vnodeop_p; rootvp->v_tag = VT_MFS; mfsp->mfs_baseoff = mfs_rootbase; mfsp->mfs_size = mfs_rootsize; mfsp->mfs_vnode = rootvp; mfsp->mfs_pid = p->p_pid; mfsp->mfs_buflist = (struct buf *)0; if ((error = ffs_mountfs(rootvp, mp, p)) != 0) { mp->mnt_vfc->vfc_refcount--; vfs_unbusy(mp); free(mp, M_MOUNT); free(mfsp, M_MFSNODE); return (error); } CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); ump = VFSTOUFS(mp); fs = ump->um_fs; (void) copystr(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN - 1, 0); (void)ffs_statfs(mp, &mp->mnt_stat, p); vfs_unbusy(mp); inittodr((time_t)0); return (0); }
int procfs_domounts(struct lwp *curl, struct proc *p, struct pfsnode *pfs, struct uio *uio) { char *bf, *mtab = NULL; const char *fsname; size_t len, mtabsz = 0; struct mount *mp, *nmp; struct statvfs *sfs; int error = 0; bf = malloc(LBFSZ, M_TEMP, M_WAITOK); mutex_enter(&mountlist_lock); for (mp = CIRCLEQ_FIRST(&mountlist); mp != (void *)&mountlist; mp = nmp) { if (vfs_busy(mp, &nmp)) { continue; } sfs = &mp->mnt_stat; /* Linux uses different names for some filesystems */ fsname = sfs->f_fstypename; if (strcmp(fsname, "procfs") == 0) fsname = "proc"; else if (strcmp(fsname, "ext2fs") == 0) fsname = "ext2"; len = snprintf(bf, LBFSZ, "%s %s %s %s%s%s%s%s%s 0 0\n", sfs->f_mntfromname, sfs->f_mntonname, fsname, (mp->mnt_flag & MNT_RDONLY) ? "ro" : "rw", (mp->mnt_flag & MNT_NOSUID) ? ",nosuid" : "", (mp->mnt_flag & MNT_NOEXEC) ? ",noexec" : "", (mp->mnt_flag & MNT_NODEV) ? ",nodev" : "", (mp->mnt_flag & MNT_SYNCHRONOUS) ? ",sync" : "", (mp->mnt_flag & MNT_NOATIME) ? ",noatime" : "" ); mtab = realloc(mtab, mtabsz + len, M_TEMP, M_WAITOK); memcpy(mtab + mtabsz, bf, len); mtabsz += len; vfs_unbusy(mp, false, &nmp); } mutex_exit(&mountlist_lock); free(bf, M_TEMP); if (mtabsz > 0) { error = uiomove_frombuf(mtab, mtabsz, uio); free(mtab, M_TEMP); } return error; }
int ext2fs_mountroot(void) { struct m_ext2fs *fs; struct mount *mp; struct proc *p = curproc; /* XXX */ struct ufsmount *ump; int error; /* * Get vnodes for swapdev and rootdev. */ if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp)) panic("ext2fs_mountroot: can't setup bdevvp's"); if ((error = vfs_rootmountalloc("ext2fs", "root_device", &mp)) != 0) { vrele(rootvp); return (error); } if ((error = ext2fs_mountfs(rootvp, mp, p)) != 0) { mp->mnt_vfc->vfc_refcount--; vfs_unbusy(mp); free(mp, M_MOUNT); vrele(rootvp); return (error); } TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list); ump = VFSTOUFS(mp); fs = ump->um_e2fs; memset(fs->e2fs_fsmnt, 0, sizeof(fs->e2fs_fsmnt)); strlcpy(fs->e2fs_fsmnt, mp->mnt_stat.f_mntonname, sizeof(fs->e2fs_fsmnt)); if (fs->e2fs.e2fs_rev > E2FS_REV0) { memset(fs->e2fs.e2fs_fsmnt, 0, sizeof(fs->e2fs.e2fs_fsmnt)); strlcpy(fs->e2fs.e2fs_fsmnt, mp->mnt_stat.f_mntonname, sizeof(fs->e2fs.e2fs_fsmnt)); } (void)ext2fs_statfs(mp, &mp->mnt_stat, p); vfs_unbusy(mp); inittodr(fs->e2fs.e2fs_wtime); return (0); }
int msdosfs_mountroot(void) { struct mount *mp; struct lwp *l = curlwp; /* XXX */ int error; struct msdosfs_args args; if (device_class(root_device) != DV_DISK) return (ENODEV); if ((error = vfs_rootmountalloc(MOUNT_MSDOS, "root_device", &mp))) { vrele(rootvp); return (error); } args.flags = MSDOSFSMNT_VERSIONED; args.uid = 0; args.gid = 0; args.mask = 0777; args.version = MSDOSFSMNT_VERSION; args.dirmask = 0777; if ((error = msdosfs_mountfs(rootvp, mp, l, &args)) != 0) { vfs_unbusy(mp, false, NULL); vfs_destroy(mp); return (error); } if ((error = update_mp(mp, &args)) != 0) { (void)msdosfs_unmount(mp, 0); vfs_unbusy(mp, false, NULL); vfs_destroy(mp); vrele(rootvp); return (error); } mountlist_append(mp); (void)msdosfs_statvfs(mp, &mp->mnt_stat); vfs_unbusy(mp, false, NULL); return (0); }
int ext2fs_mountroot(void) { // printf("ext2fs_mountroot\n"); extern struct vnode *rootvp; struct m_ext2fs *fs; struct mount *mp; struct ufsmount *ump; int error; if (device_class(root_device) != DV_DISK) return (ENODEV); if ((error = vfs_rootmountalloc(MOUNT_EXT2FS, "root_device", &mp))) { vrele(rootvp); return (error); } if ((error = ext2fs_mountfs(rootvp, mp)) != 0) { vfs_unbusy(mp, false, NULL); vfs_destroy(mp); return (error); } mountlist_append(mp); ump = VFSTOUFS(mp); fs = ump->um_e2fs; memset(fs->e2fs_fsmnt, 0, sizeof(fs->e2fs_fsmnt)); (void) copystr(mp->mnt_stat.f_mntonname, fs->e2fs_fsmnt, sizeof(fs->e2fs_fsmnt) - 1, 0); if (fs->e2fs.e2fs_rev > E2FS_REV0) { memset(fs->e2fs.e2fs_fsmnt, 0, sizeof(fs->e2fs.e2fs_fsmnt)); (void) copystr(mp->mnt_stat.f_mntonname, fs->e2fs.e2fs_fsmnt, sizeof(fs->e2fs.e2fs_fsmnt) - 1, 0); } (void)ext2fs_statvfs(mp, &mp->mnt_stat); vfs_unbusy(mp, false, NULL); setrootfstime((time_t)fs->e2fs.e2fs_wtime); return (0); }
int #define struct ext2fs_mountroot(struct mount *mp) { struct vnode *rootvp; #undef struct struct m_ext2fs *fs; // struct mount *mp; int error; DEBUG ((EFI_D_INFO, "mountroot 1\n")); if (device_class(root_device) != DV_DISK) return (ENONDEV); DEBUG ((EFI_D_INFO, "mountroot 2\n")); if ((error = vfs_rootmountalloc(MOUNT_EXT2FS, "root_device", &mp))) { vrele(rootvp); return (error); } DEBUG ((EFI_D_INFO, "mountroot 3\n")); if ((error = ext2fs_mountfs(rootvp, mp)) != 0) { vfs_unbusy(mp,false,NULL); vfs_destroy(mp); return (error); } DEBUG ((EFI_D_INFO, "mountroot 4\n")); fs = mp->fs; memset(fs->e2fs_fsmnt, 0, sizeof(fs->e2fs_fsmnt)); (void) copystr(mp->f_mntonname, fs->e2fs_fsmnt, sizeof(fs->e2fs_fsmnt) - 1, 0); if (fs->e2fs.e2fs_rev > E2FS_REV0) { memset(fs->e2fs.e2fs_fsmnt, 0, sizeof(fs->e2fs.e2fs_fsmnt)); (void) copystr(mp->f_mntonname, fs->e2fs.e2fs_fsmnt, sizeof(fs->e2fs.e2fs_fsmnt) - 1, 0); } vfs_unbusy(mp, false, NULL); return (0);
int traverse(vnode_t **cvpp, int lktype) { vnode_t *cvp; vnode_t *tvp; vfs_t *vfsp; int error; cvp = *cvpp; tvp = NULL; /* * If this vnode is mounted on, then we transparently indirect * to the vnode which is the root of the mounted file system. * Before we do this we must check that an unmount is not in * progress on this vnode. */ for (;;) { /* * Reached the end of the mount chain? */ vfsp = vn_mountedvfs(cvp); if (vfsp == NULL) break; error = vfs_busy(vfsp, 0); /* * tvp is NULL for *cvpp vnode, which we can't unlock. */ if (tvp != NULL) vput(cvp); else vrele(cvp); if (error) return (error); /* * The read lock must be held across the call to VFS_ROOT() to * prevent a concurrent unmount from destroying the vfs. */ error = VFS_ROOT(vfsp, lktype, &tvp); vfs_unbusy(vfsp); if (error != 0) return (error); cvp = tvp; } *cvpp = cvp; return (0); }
/* * Do operations associated with quotas */ int ufs_quotactl(struct mount *mp, prop_dictionary_t dict) { struct lwp *l = curlwp; #if !defined(QUOTA) && !defined(QUOTA2) (void) mp; (void) dict; (void) l; return (EOPNOTSUPP); #else int error; prop_dictionary_t cmddict; prop_array_t commands; prop_object_iterator_t iter; /* Mark the mount busy, as we're passing it to kauth(9). */ error = vfs_busy(mp, NULL); if (error) return (error); error = quota_get_cmds(dict, &commands); if (error) goto out_vfs; iter = prop_array_iterator(commands); if (iter == NULL) { error = ENOMEM; goto out_vfs; } mutex_enter(&mp->mnt_updating); while ((cmddict = prop_object_iterator_next(iter)) != NULL) { if (prop_object_type(cmddict) != PROP_TYPE_DICTIONARY) continue; error = quota_handle_cmd(mp, l, cmddict); if (error) break; } prop_object_iterator_release(iter); mutex_exit(&mp->mnt_updating); out_vfs: vfs_unbusy(mp, false, NULL); return (error); #endif }
int procfs_domounts(struct lwp *curl, struct proc *p, struct pfsnode *pfs, struct uio *uio) { char *bf, *mtab = NULL; size_t mtabsz = 0; struct mount *mp, *nmp; int error = 0, root = 0; struct cwdinfo *cwdi = curl->l_proc->p_cwdi; bf = malloc(LBFSZ, M_TEMP, M_WAITOK); mutex_enter(&mountlist_lock); for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { struct statvfs sfs; if (vfs_busy(mp, &nmp)) continue; if ((error = dostatvfs(mp, &sfs, curl, MNT_WAIT, 0)) == 0) root |= procfs_format_sfs(&mtab, &mtabsz, bf, LBFSZ, &sfs, curl, 0); vfs_unbusy(mp, false, &nmp); } mutex_exit(&mountlist_lock); /* * If we are inside a chroot that is not itself a mount point, * fake a root entry. */ if (!root && cwdi->cwdi_rdir) (void)procfs_format_sfs(&mtab, &mtabsz, bf, LBFSZ, &cwdi->cwdi_rdir->v_mount->mnt_stat, curl, 1); free(bf, M_TEMP); if (mtabsz > 0) { error = uiomove_frombuf(mtab, mtabsz, uio); free(mtab, M_TEMP); } return error; }
int vfs_getbyid(fsid_t *fsid, ino64_t ino, vnode_t *vpp, vfs_context_t ctx) { mount_t mp; int error; mp = mount_lookupby_volfsid(fsid->val[0], 1); if (mp == NULL) { return EINVAL; } /* Get the target vnode. */ if (ino == 2) { error = VFS_ROOT(mp, vpp, ctx); } else { error = VFS_VGET(mp, ino, vpp, ctx); } vfs_unbusy(mp); return error; }
/* * Do a lazy sync of the filesystem. * * sync_fsync { struct vnode *a_vp, int a_waitfor } */ static int sync_fsync(struct vop_fsync_args *ap) { struct vnode *syncvp = ap->a_vp; struct mount *mp = syncvp->v_mount; int asyncflag; /* * We only need to do something if this is a lazy evaluation. */ if ((ap->a_waitfor & MNT_LAZY) == 0) return (0); /* * Move ourselves to the back of the sync list. */ vn_syncer_add(syncvp, syncdelay); /* * Walk the list of vnodes pushing all that are dirty and * not already on the sync list, and freeing vnodes which have * no refs and whos VM objects are empty. vfs_msync() handles * the VM issues and must be called whether the mount is readonly * or not. */ if (vfs_busy(mp, LK_NOWAIT) != 0) return (0); if (mp->mnt_flag & MNT_RDONLY) { vfs_msync(mp, MNT_NOWAIT); } else { asyncflag = mp->mnt_flag & MNT_ASYNC; mp->mnt_flag &= ~MNT_ASYNC; /* ZZZ hack */ vfs_msync(mp, MNT_NOWAIT); VFS_SYNC(mp, MNT_NOWAIT | MNT_LAZY); if (asyncflag) mp->mnt_flag |= MNT_ASYNC; } vfs_unbusy(mp); return (0); }
/* * Resolve a mount point's glue ncp. This ncp connects creates the illusion * of continuity in the namecache tree by connecting the ncp related to the * vnode under the mount to the ncp related to the mount's root vnode. * * If no error occured a locked, ref'd ncp is stored in *ncpp. */ int nlookup_mp(struct mount *mp, struct nchandle *nch) { struct vnode *vp; int error; error = 0; cache_get(&mp->mnt_ncmountpt, nch); if (nch->ncp->nc_flag & NCF_UNRESOLVED) { while (vfs_busy(mp, 0)) ; error = VFS_ROOT(mp, &vp); vfs_unbusy(mp); if (error) { cache_put(nch); } else { cache_setvp(nch, vp); vput(vp); } } return(error); }
/* * Internal version of mount system call for diskless setup. * Separate function because we used to call it twice. * (once for root and once for swap) */ static int nfs_mount_diskless(struct nfs_dlmount *ndmntp, const char *mntname, struct mount **mpp, struct vnode **vpp, struct lwp *l) /* mntname: mount point name */ { struct mount *mp; struct mbuf *m; int error; vfs_rootmountalloc(MOUNT_NFS, mntname, &mp); mp->mnt_op = &nfs_vfsops; /* * Historical practice expects NFS root file systems to * be initially mounted r/w. */ mp->mnt_flag &= ~MNT_RDONLY; /* Get mbuf for server sockaddr. */ m = m_get(M_WAIT, MT_SONAME); if (m == NULL) panic("nfs_mountroot: mget soname for %s", mntname); MCLAIM(m, &nfs_mowner); memcpy(mtod(m, void *), (void *)ndmntp->ndm_args.addr, (m->m_len = ndmntp->ndm_args.addr->sa_len)); error = mountnfs(&ndmntp->ndm_args, mp, m, mntname, ndmntp->ndm_args.hostname, vpp, l); if (error) { vfs_unbusy(mp, false, NULL); vfs_destroy(mp); printf("nfs_mountroot: mount %s failed: %d\n", mntname, error); } else *mpp = mp; return (error); }
/* * sys_lfs_segclean: * * Mark the segment clean. * * 0 on success * -1/errno is return on error. */ int sys_lfs_segclean(struct lwp *l, const struct sys_lfs_segclean_args *uap, register_t *retval) { /* { syscallarg(fsid_t *) fsidp; syscallarg(u_long) segment; } */ struct lfs *fs; struct mount *mntp; fsid_t fsid; int error; unsigned long segnum; error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_LFS, KAUTH_REQ_SYSTEM_LFS_SEGCLEAN, NULL, NULL, NULL); if (error) return (error); if ((error = copyin(SCARG(uap, fsidp), &fsid, sizeof(fsid_t))) != 0) return (error); if ((mntp = vfs_getvfs(&fsid)) == NULL) return (ENOENT); fs = VFSTOULFS(mntp)->um_lfs; segnum = SCARG(uap, segment); if ((error = vfs_busy(mntp, NULL)) != 0) return (error); KERNEL_LOCK(1, NULL); lfs_seglock(fs, SEGM_PROT); error = lfs_do_segclean(fs, segnum); lfs_segunlock(fs); KERNEL_UNLOCK_ONE(NULL); vfs_unbusy(mntp, false, NULL); return error; }