Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/vfs_mount.c
Show First 20 Lines • Show All 620 Lines • ▼ Show 20 Lines | vfs_donmount(struct thread *td, uint64_t fsflags, struct uio *fsoptions) | ||||
/* | /* | ||||
* We need to see if we have the "update" option | * We need to see if we have the "update" option | ||||
* before we call vfs_domount(), since vfs_domount() has special | * before we call vfs_domount(), since vfs_domount() has special | ||||
* logic based on MNT_UPDATE. This is very important | * logic based on MNT_UPDATE. This is very important | ||||
* when we want to update the root filesystem. | * when we want to update the root filesystem. | ||||
*/ | */ | ||||
TAILQ_FOREACH_SAFE(opt, optlist, link, tmp_opt) { | TAILQ_FOREACH_SAFE(opt, optlist, link, tmp_opt) { | ||||
int do_freeopt = 0; | |||||
if (strcmp(opt->name, "update") == 0) { | if (strcmp(opt->name, "update") == 0) { | ||||
fsflags |= MNT_UPDATE; | fsflags |= MNT_UPDATE; | ||||
vfs_freeopt(optlist, opt); | do_freeopt = 1; | ||||
} | } | ||||
else if (strcmp(opt->name, "async") == 0) | else if (strcmp(opt->name, "async") == 0) | ||||
fsflags |= MNT_ASYNC; | fsflags |= MNT_ASYNC; | ||||
else if (strcmp(opt->name, "force") == 0) { | else if (strcmp(opt->name, "force") == 0) { | ||||
fsflags |= MNT_FORCE; | fsflags |= MNT_FORCE; | ||||
vfs_freeopt(optlist, opt); | do_freeopt = 1; | ||||
} | } | ||||
else if (strcmp(opt->name, "reload") == 0) { | else if (strcmp(opt->name, "reload") == 0) { | ||||
fsflags |= MNT_RELOAD; | fsflags |= MNT_RELOAD; | ||||
vfs_freeopt(optlist, opt); | do_freeopt = 1; | ||||
} | } | ||||
else if (strcmp(opt->name, "multilabel") == 0) | else if (strcmp(opt->name, "multilabel") == 0) | ||||
fsflags |= MNT_MULTILABEL; | fsflags |= MNT_MULTILABEL; | ||||
else if (strcmp(opt->name, "noasync") == 0) | else if (strcmp(opt->name, "noasync") == 0) | ||||
fsflags &= ~MNT_ASYNC; | fsflags &= ~MNT_ASYNC; | ||||
else if (strcmp(opt->name, "noatime") == 0) | else if (strcmp(opt->name, "noatime") == 0) | ||||
fsflags |= MNT_NOATIME; | fsflags |= MNT_NOATIME; | ||||
else if (strcmp(opt->name, "atime") == 0) { | else if (strcmp(opt->name, "atime") == 0) { | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | TAILQ_FOREACH_SAFE(opt, optlist, link, tmp_opt) { | ||||
} | } | ||||
else if (strcmp(opt->name, "rdonly") == 0) { | else if (strcmp(opt->name, "rdonly") == 0) { | ||||
free(opt->name, M_MOUNT); | free(opt->name, M_MOUNT); | ||||
opt->name = strdup("ro", M_MOUNT); | opt->name = strdup("ro", M_MOUNT); | ||||
fsflags |= MNT_RDONLY; | fsflags |= MNT_RDONLY; | ||||
autoro = false; | autoro = false; | ||||
} | } | ||||
else if (strcmp(opt->name, "autoro") == 0) { | else if (strcmp(opt->name, "autoro") == 0) { | ||||
vfs_freeopt(optlist, opt); | do_freeopt = 1; | ||||
autoro = true; | autoro = true; | ||||
} | } | ||||
else if (strcmp(opt->name, "suiddir") == 0) | else if (strcmp(opt->name, "suiddir") == 0) | ||||
fsflags |= MNT_SUIDDIR; | fsflags |= MNT_SUIDDIR; | ||||
else if (strcmp(opt->name, "sync") == 0) | else if (strcmp(opt->name, "sync") == 0) | ||||
fsflags |= MNT_SYNCHRONOUS; | fsflags |= MNT_SYNCHRONOUS; | ||||
else if (strcmp(opt->name, "union") == 0) | else if (strcmp(opt->name, "union") == 0) | ||||
fsflags |= MNT_UNION; | fsflags |= MNT_UNION; | ||||
else if (strcmp(opt->name, "automounted") == 0) { | else if (strcmp(opt->name, "automounted") == 0) { | ||||
fsflags |= MNT_AUTOMOUNTED; | fsflags |= MNT_AUTOMOUNTED; | ||||
vfs_freeopt(optlist, opt); | vfs_freeopt(optlist, opt); | ||||
allanjude: Is there a reason you didn't move this vfs_freeopt() call to do_freeopt=1? | |||||
sefAuthorUnsubmitted Done Inline ActionsBecause it wasn't a line I changed and it ended up completely invisible to me as a result :). I just verified it was the only one, and have fixed it. sef: Because it wasn't a line I changed and it ended up completely invisible to me as a result :). | |||||
} else if (strcmp(opt->name, "nocover") == 0) { | |||||
fsflags |= MNT_NOCOVER; | |||||
do_freeopt = 1; | |||||
} else if (strcmp(opt->name, "cover") == 0) { | |||||
fsflags &= ~MNT_NOCOVER; | |||||
do_freeopt = 1; | |||||
} else if (strcmp(opt->name, "emptydir") == 0) { | |||||
fsflags |= MNT_EMPTYDIR; | |||||
do_freeopt = 1; | |||||
} else if (strcmp(opt->name, "noemptydir") == 0) { | |||||
fsflags &= ~MNT_EMPTYDIR; | |||||
do_freeopt = 1; | |||||
} | } | ||||
if (do_freeopt) | |||||
vfs_freeopt(optlist, opt); | |||||
} | } | ||||
/* | /* | ||||
* Be ultra-paranoid about making sure the type and fspath | * Be ultra-paranoid about making sure the type and fspath | ||||
* variables will fit in our mp buffers, including the | * variables will fit in our mp buffers, including the | ||||
* terminating NUL. | * terminating NUL. | ||||
*/ | */ | ||||
if (fstypelen > MFSNAMELEN || fspathlen > MNAMELEN) { | if (fstypelen > MFSNAMELEN || fspathlen > MNAMELEN) { | ||||
▲ Show 20 Lines • Show All 119 Lines • ▼ Show 20 Lines | vfs_domount_first( | ||||
struct vattr va; | struct vattr va; | ||||
struct mount *mp; | struct mount *mp; | ||||
struct vnode *newdp; | struct vnode *newdp; | ||||
int error, error1; | int error, error1; | ||||
ASSERT_VOP_ELOCKED(vp, __func__); | ASSERT_VOP_ELOCKED(vp, __func__); | ||||
KASSERT((fsflags & MNT_UPDATE) == 0, ("MNT_UPDATE shouldn't be here")); | KASSERT((fsflags & MNT_UPDATE) == 0, ("MNT_UPDATE shouldn't be here")); | ||||
if ((fsflags & MNT_EMPTYDIR) != 0) { | |||||
error = vfs_emptydir(vp, td); | |||||
if (error) { | |||||
Done Inline Actionserror != 0 kib: `error != 0` | |||||
vput(vp); | |||||
return (error); | |||||
} | |||||
} | |||||
/* | /* | ||||
* If the jail of the calling thread lacks permission for this type of | * If the jail of the calling thread lacks permission for this type of | ||||
* file system, deny immediately. | * file system, deny immediately. | ||||
*/ | */ | ||||
if (jailed(td->td_ucred) && !prison_allow(td->td_ucred, | if (jailed(td->td_ucred) && !prison_allow(td->td_ucred, | ||||
vfsp->vfc_prison_flag)) { | vfsp->vfc_prison_flag)) { | ||||
vput(vp); | vput(vp); | ||||
return (EPERM); | return (EPERM); | ||||
▲ Show 20 Lines • Show All 263 Lines • ▼ Show 20 Lines | vfs_domount( | ||||
) | ) | ||||
{ | { | ||||
struct vfsconf *vfsp; | struct vfsconf *vfsp; | ||||
struct nameidata nd; | struct nameidata nd; | ||||
struct vnode *vp; | struct vnode *vp; | ||||
char *pathbuf; | char *pathbuf; | ||||
int error; | int error; | ||||
// printf("%s(%p, %s, %s, %#lx, %p)\n", __FUNCTION__, td, fstype, fspath, fsflags, optlist); | |||||
allanjudeUnsubmitted Done Inline ActionsLikely you meant to clean this up allanjude: Likely you meant to clean this up | |||||
sefAuthorUnsubmitted Done Inline ActionsYes, done. sef: Yes, done. | |||||
/* | /* | ||||
* Be ultra-paranoid about making sure the type and fspath | * Be ultra-paranoid about making sure the type and fspath | ||||
* variables will fit in our mp buffers, including the | * variables will fit in our mp buffers, including the | ||||
* terminating NUL. | * terminating NUL. | ||||
*/ | */ | ||||
if (strlen(fstype) >= MFSNAMELEN || strlen(fspath) >= MNAMELEN) | if (strlen(fstype) >= MFSNAMELEN || strlen(fspath) >= MNAMELEN) | ||||
return (ENAMETOOLONG); | return (ENAMETOOLONG); | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | // printf("%s(%p, %s, %s, %#lx, %p)\n", __FUNCTION__, td, fstype, fspath, fsflags, optlist); | ||||
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1, | NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1, | ||||
UIO_SYSSPACE, fspath, td); | UIO_SYSSPACE, fspath, td); | ||||
error = namei(&nd); | error = namei(&nd); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
NDFREE(&nd, NDF_ONLY_PNBUF); | NDFREE(&nd, NDF_ONLY_PNBUF); | ||||
vp = nd.ni_vp; | vp = nd.ni_vp; | ||||
if ((fsflags & MNT_UPDATE) == 0) { | if ((fsflags & MNT_UPDATE) == 0) { | ||||
if ((vp->v_vflag & VV_ROOT) && | |||||
Done Inline Actions!= 0 kib: `!= 0` | |||||
Not Done Inline ActionsI'll change them, but I'll also point out there are places in the code that do NOT do that. See sys_mount for an example of both. sef: I'll change them, but I'll also point out there are places in the code that do NOT do that. | |||||
(fsflags & MNT_NOCOVER)) { | |||||
vput(vp); | |||||
error = EBUSY; | |||||
Done Inline Actionsreturn (EBUSY); Assigning to error is not useful. kib: `return (EBUSY);` Assigning to error is not useful. | |||||
return (error); | |||||
} | |||||
pathbuf = malloc(MNAMELEN, M_TEMP, M_WAITOK); | pathbuf = malloc(MNAMELEN, M_TEMP, M_WAITOK); | ||||
strcpy(pathbuf, fspath); | strcpy(pathbuf, fspath); | ||||
error = vn_path_to_global_path(td, vp, pathbuf, MNAMELEN); | error = vn_path_to_global_path(td, vp, pathbuf, MNAMELEN); | ||||
/* debug.disablefullpath == 1 results in ENODEV */ | /* debug.disablefullpath == 1 results in ENODEV */ | ||||
if (error == 0 || error == ENODEV) { | if (error == 0 || error == ENODEV) { | ||||
error = vfs_domount_first(td, vfsp, pathbuf, vp, | error = vfs_domount_first(td, vfsp, pathbuf, vp, | ||||
fsflags, optlist); | fsflags, optlist); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 875 Lines • Show Last 20 Lines |
Is there a reason you didn't move this vfs_freeopt() call to do_freeopt=1?