本文整理汇总了C++中MNT_IUNLOCK函数的典型用法代码示例。如果您正苦于以下问题:C++ MNT_IUNLOCK函数的具体用法?C++ MNT_IUNLOCK怎么用?C++ MNT_IUNLOCK使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了MNT_IUNLOCK函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: pfs_mount
/*
* Mount a pseudofs instance
*/
int
pfs_mount(struct pfs_info *pi, struct mount *mp)
{
struct statfs *sbp;
if (mp->mnt_flag & MNT_UPDATE)
return (EOPNOTSUPP);
MNT_ILOCK(mp);
mp->mnt_flag |= MNT_LOCAL;
mp->mnt_kern_flag |= MNTK_MPSAFE;
MNT_IUNLOCK(mp);
mp->mnt_data = pi;
vfs_getnewfsid(mp);
sbp = &mp->mnt_stat;
vfs_mountedfrom(mp, pi->pi_name);
sbp->f_bsize = PAGE_SIZE;
sbp->f_iosize = PAGE_SIZE;
sbp->f_blocks = 1;
sbp->f_bfree = 0;
sbp->f_bavail = 0;
sbp->f_files = 1;
sbp->f_ffree = 0;
return (0);
}
示例2: vfs_setmntopt
void
vfs_setmntopt(vfs_t *vfsp, const char *name, const char *arg,
int flags __unused)
{
struct vfsopt *opt;
size_t namesize;
int locked;
if (!(locked = mtx_owned(MNT_MTX(vfsp))))
MNT_ILOCK(vfsp);
if (vfsp->mnt_opt == NULL) {
void *opts;
MNT_IUNLOCK(vfsp);
opts = malloc(sizeof(*vfsp->mnt_opt), M_MOUNT, M_WAITOK);
MNT_ILOCK(vfsp);
if (vfsp->mnt_opt == NULL) {
vfsp->mnt_opt = opts;
TAILQ_INIT(vfsp->mnt_opt);
} else {
free(opts, M_MOUNT);
}
}
MNT_IUNLOCK(vfsp);
opt = malloc(sizeof(*opt), M_MOUNT, M_WAITOK);
namesize = strlen(name) + 1;
opt->name = malloc(namesize, M_MOUNT, M_WAITOK);
strlcpy(opt->name, name, namesize);
opt->pos = -1;
opt->seen = 1;
if (arg == NULL) {
opt->value = NULL;
opt->len = 0;
} else {
opt->len = strlen(arg) + 1;
opt->value = malloc(opt->len, M_MOUNT, M_WAITOK);
bcopy(arg, opt->value, opt->len);
}
MNT_ILOCK(vfsp);
TAILQ_INSERT_TAIL(vfsp->mnt_opt, opt, link);
if (!locked)
MNT_IUNLOCK(vfsp);
}
示例3: vfs_clearmntopt
void
vfs_clearmntopt(vfs_t *vfsp, const char *name)
{
int locked;
if (!(locked = mtx_owned(MNT_MTX(vfsp))))
MNT_ILOCK(vfsp);
vfs_deleteopt(vfsp->mnt_opt, name);
if (!locked)
MNT_IUNLOCK(vfsp);
}
示例4: smbfs_unmount
/* Unmount the filesystem described by mp. */
static int
smbfs_unmount(struct mount *mp, int mntflags)
{
struct thread *td;
struct smbmount *smp = VFSTOSMBFS(mp);
struct smb_cred *scred;
struct smb_dev *dev;
int error, flags;
SMBVDEBUG("smbfs_unmount: flags=%04x\n", mntflags);
td = curthread;
flags = 0;
if (mntflags & MNT_FORCE)
flags |= FORCECLOSE;
/*
* Keep trying to flush the vnode list for the mount while
* some are still busy and we are making progress towards
* making them not busy. This is needed because smbfs vnodes
* reference their parent directory but may appear after their
* parent in the list; one pass over the vnode list is not
* sufficient in this case.
*/
do {
smp->sm_didrele = 0;
/* There is 1 extra root vnode reference from smbfs_mount(). */
error = vflush(mp, 1, flags, td);
} while (error == EBUSY && smp->sm_didrele != 0);
if (error)
return error;
scred = smbfs_malloc_scred();
smb_makescred(scred, td, td->td_ucred);
error = smb_share_lock(smp->sm_share);
if (error)
goto out;
smb_share_put(smp->sm_share, scred);
SMB_LOCK();
dev = smp->sm_dev;
if (!dev)
panic("No private data for mount point");
sdp_trydestroy(dev);
mp->mnt_data = NULL;
SMB_UNLOCK();
free(smp, M_SMBFSDATA);
MNT_ILOCK(mp);
mp->mnt_flag &= ~MNT_LOCAL;
MNT_IUNLOCK(mp);
out:
smbfs_free_scred(scred);
return error;
}
示例5: devfs_mount
/*
* Mount the filesystem
*/
static int
devfs_mount(struct mount *mp)
{
int error;
struct devfs_mount *fmp;
struct vnode *rvp;
if (devfs_unr == NULL)
devfs_unr = new_unrhdr(0, INT_MAX, NULL);
error = 0;
if (mp->mnt_flag & (MNT_UPDATE | MNT_ROOTFS))
return (EOPNOTSUPP);
fmp = malloc(sizeof *fmp, M_DEVFS, M_WAITOK | M_ZERO);
fmp->dm_idx = alloc_unr(devfs_unr);
sx_init(&fmp->dm_lock, "devfsmount");
fmp->dm_holdcnt = 1;
MNT_ILOCK(mp);
mp->mnt_flag |= MNT_LOCAL;
mp->mnt_kern_flag |= MNTK_MPSAFE | MNTK_LOOKUP_SHARED |
MNTK_EXTENDED_SHARED;
#ifdef MAC
mp->mnt_flag |= MNT_MULTILABEL;
#endif
MNT_IUNLOCK(mp);
fmp->dm_mount = mp;
mp->mnt_data = (void *) fmp;
vfs_getnewfsid(mp);
fmp->dm_rootdir = devfs_vmkdir(fmp, NULL, 0, NULL, DEVFS_ROOTINO);
error = devfs_root(mp, LK_EXCLUSIVE, &rvp);
if (error) {
sx_destroy(&fmp->dm_lock);
free_unr(devfs_unr, fmp->dm_idx);
free(fmp, M_DEVFS);
return (error);
}
VOP_UNLOCK(rvp, 0);
vfs_mountedfrom(mp, "devfs");
return (0);
}
示例6: afs_omount
afs_omount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
THREAD_OR_PROC)
#endif
{
/* ndp contains the mounted-from device. Just ignore it.
* we also don't care about our proc struct. */
size_t size;
if (mp->mnt_flag & MNT_UPDATE)
return EINVAL;
AFS_GLOCK();
AFS_STATCNT(afs_mount);
if (afs_globalVFS) { /* Don't allow remounts. */
AFS_GUNLOCK();
return EBUSY;
}
afs_globalVFS = mp;
mp->vfs_bsize = 8192;
vfs_getnewfsid(mp);
#ifdef AFS_FBSD70_ENV /* XXX 70? */
MNT_ILOCK(mp);
mp->mnt_flag &= ~MNT_LOCAL;
mp->mnt_kern_flag |= MNTK_MPSAFE; /* solid steel */
#endif
mp->mnt_stat.f_iosize = 8192;
if (path != NULL)
copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
else
bcopy("/afs", mp->mnt_stat.f_mntonname, size = 4);
memset(mp->mnt_stat.f_mntonname + size, 0, MNAMELEN - size);
memset(mp->mnt_stat.f_mntfromname, 0, MNAMELEN);
strcpy(mp->mnt_stat.f_mntfromname, "AFS");
/* null terminated string "AFS" will fit, just leave it be. */
strcpy(mp->mnt_stat.f_fstypename, "afs");
#ifdef AFS_FBSD70_ENV
MNT_IUNLOCK(mp);
#endif
AFS_GUNLOCK();
afs_statfs(mp, &mp->mnt_stat, p);
return 0;
}
示例7: udf_unmount
static int
udf_unmount(struct mount *mp, int mntflags)
{
struct udf_mnt *udfmp;
int error, flags = 0;
udfmp = VFSTOUDFFS(mp);
if (mntflags & MNT_FORCE)
flags |= FORCECLOSE;
if ((error = vflush(mp, 0, flags, curthread)))
return (error);
if (udfmp->im_flags & UDFMNT_KICONV && udf_iconv) {
if (udfmp->im_d2l)
udf_iconv->close(udfmp->im_d2l);
#if 0
if (udfmp->im_l2d)
udf_iconv->close(udfmp->im_l2d);
#endif
}
DROP_GIANT();
g_topology_lock();
g_vfs_close(udfmp->im_cp);
g_topology_unlock();
PICKUP_GIANT();
vrele(udfmp->im_devvp);
dev_rel(udfmp->im_dev);
if (udfmp->s_table != NULL)
free(udfmp->s_table, M_UDFMOUNT);
free(udfmp, M_UDFMOUNT);
mp->mnt_data = NULL;
MNT_ILOCK(mp);
mp->mnt_flag &= ~MNT_LOCAL;
MNT_IUNLOCK(mp);
return (0);
}
示例8: quotaoff_inchange
/*
* Turns off quotas, assumes that ump->um_qflags are already checked
* and QTF_CLOSING is set to indicate operation in progress. Fixes
* ump->um_qflags and mp->mnt_flag after.
*/
int
quotaoff_inchange(struct thread *td, struct mount *mp, int type)
{
struct ufsmount *ump;
int i;
int error;
error = quotaoff1(td, mp, type);
ump = VFSTOUFS(mp);
UFS_LOCK(ump);
ump->um_qflags[type] &= ~QTF_CLOSING;
for (i = 0; i < MAXQUOTAS; i++)
if (ump->um_quotas[i] != NULLVP)
break;
if (i == MAXQUOTAS) {
MNT_ILOCK(mp);
mp->mnt_flag &= ~MNT_QUOTA;
MNT_IUNLOCK(mp);
}
UFS_UNLOCK(ump);
return (error);
}
示例9: quotaon
/*
* Q_QUOTAON - set up a quota file for a particular filesystem.
*/
int
quotaon(struct thread *td, struct mount *mp, int type, void *fname)
{
struct ufsmount *ump;
struct vnode *vp, **vpp;
struct vnode *mvp;
struct dquot *dq;
int error, flags;
struct nameidata nd;
error = priv_check(td, PRIV_UFS_QUOTAON);
if (error != 0) {
vfs_unbusy(mp);
return (error);
}
if ((mp->mnt_flag & MNT_RDONLY) != 0) {
vfs_unbusy(mp);
return (EROFS);
}
ump = VFSTOUFS(mp);
dq = NODQUOT;
NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, fname, td);
flags = FREAD | FWRITE;
vfs_ref(mp);
vfs_unbusy(mp);
error = vn_open(&nd, &flags, 0, NULL);
if (error != 0) {
vfs_rel(mp);
return (error);
}
NDFREE(&nd, NDF_ONLY_PNBUF);
vp = nd.ni_vp;
error = vfs_busy(mp, MBF_NOWAIT);
vfs_rel(mp);
if (error == 0) {
if (vp->v_type != VREG) {
error = EACCES;
vfs_unbusy(mp);
}
}
if (error != 0) {
VOP_UNLOCK(vp, 0);
(void) vn_close(vp, FREAD|FWRITE, td->td_ucred, td);
return (error);
}
UFS_LOCK(ump);
if ((ump->um_qflags[type] & (QTF_OPENING|QTF_CLOSING)) != 0) {
UFS_UNLOCK(ump);
VOP_UNLOCK(vp, 0);
(void) vn_close(vp, FREAD|FWRITE, td->td_ucred, td);
vfs_unbusy(mp);
return (EALREADY);
}
ump->um_qflags[type] |= QTF_OPENING|QTF_CLOSING;
UFS_UNLOCK(ump);
if ((error = dqopen(vp, ump, type)) != 0) {
VOP_UNLOCK(vp, 0);
UFS_LOCK(ump);
ump->um_qflags[type] &= ~(QTF_OPENING|QTF_CLOSING);
UFS_UNLOCK(ump);
(void) vn_close(vp, FREAD|FWRITE, td->td_ucred, td);
vfs_unbusy(mp);
return (error);
}
VOP_UNLOCK(vp, 0);
MNT_ILOCK(mp);
mp->mnt_flag |= MNT_QUOTA;
MNT_IUNLOCK(mp);
vpp = &ump->um_quotas[type];
if (*vpp != vp)
quotaoff1(td, mp, type);
/*
* When the directory vnode containing the quota file is
* inactivated, due to the shared lookup of the quota file
* vput()ing the dvp, the qsyncvp() call for the containing
* directory would try to acquire the quota lock exclusive.
* At the same time, lookup already locked the quota vnode
* shared. Mark the quota vnode lock as allowing recursion
* and automatically converting shared locks to exclusive.
*
* Also mark quota vnode as system.
*/
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
vp->v_vflag |= VV_SYSTEM;
VN_LOCK_AREC(vp);
VN_LOCK_DSHARE(vp);
VOP_UNLOCK(vp, 0);
*vpp = vp;
/*
* Save the credential of the process that turned on quotas.
* Set up the time limits for this quota.
//.........这里部分代码省略.........
示例10: vfs_hang_addrlist
/*
* Build hash lists of net addresses and hang them off the mount point.
* Called by vfs_export() to set up the lists of export addresses.
*/
static int
vfs_hang_addrlist(struct mount *mp, struct netexport *nep,
struct export_args *argp)
{
register struct netcred *np;
register struct radix_node_head *rnh;
register int i;
struct radix_node *rn;
struct sockaddr *saddr, *smask = 0;
struct domain *dom;
int error;
/*
* XXX: This routine converts from a `struct xucred'
* (argp->ex_anon) to a `struct ucred' (np->netc_anon). This
* operation is questionable; for example, what should be done
* with fields like cr_uidinfo and cr_prison? Currently, this
* routine does not touch them (leaves them as NULL).
*/
if (argp->ex_anon.cr_version != XUCRED_VERSION) {
vfs_mount_error(mp, "ex_anon.cr_version: %d != %d",
argp->ex_anon.cr_version, XUCRED_VERSION);
return (EINVAL);
}
if (argp->ex_addrlen == 0) {
if (mp->mnt_flag & MNT_DEFEXPORTED) {
vfs_mount_error(mp,
"MNT_DEFEXPORTED already set for mount %p", mp);
return (EPERM);
}
np = &nep->ne_defexported;
np->netc_exflags = argp->ex_flags;
np->netc_anon = crget();
np->netc_anon->cr_uid = argp->ex_anon.cr_uid;
crsetgroups(np->netc_anon, argp->ex_anon.cr_ngroups,
argp->ex_anon.cr_groups);
np->netc_anon->cr_prison = &prison0;
prison_hold(np->netc_anon->cr_prison);
np->netc_numsecflavors = argp->ex_numsecflavors;
bcopy(argp->ex_secflavors, np->netc_secflavors,
sizeof(np->netc_secflavors));
MNT_ILOCK(mp);
mp->mnt_flag |= MNT_DEFEXPORTED;
MNT_IUNLOCK(mp);
return (0);
}
#if MSIZE <= 256
if (argp->ex_addrlen > MLEN) {
vfs_mount_error(mp, "ex_addrlen %d is greater than %d",
argp->ex_addrlen, MLEN);
return (EINVAL);
}
#endif
i = sizeof(struct netcred) + argp->ex_addrlen + argp->ex_masklen;
np = (struct netcred *) malloc(i, M_NETADDR, M_WAITOK | M_ZERO);
saddr = (struct sockaddr *) (np + 1);
if ((error = copyin(argp->ex_addr, saddr, argp->ex_addrlen)))
goto out;
if (saddr->sa_family == AF_UNSPEC || saddr->sa_family > AF_MAX) {
error = EINVAL;
vfs_mount_error(mp, "Invalid saddr->sa_family: %d");
goto out;
}
if (saddr->sa_len > argp->ex_addrlen)
saddr->sa_len = argp->ex_addrlen;
if (argp->ex_masklen) {
smask = (struct sockaddr *)((caddr_t)saddr + argp->ex_addrlen);
error = copyin(argp->ex_mask, smask, argp->ex_masklen);
if (error)
goto out;
if (smask->sa_len > argp->ex_masklen)
smask->sa_len = argp->ex_masklen;
}
i = saddr->sa_family;
if ((rnh = nep->ne_rtable[i]) == NULL) {
/*
* Seems silly to initialize every AF when most are not used,
* do so on demand here
*/
for (dom = domains; dom; dom = dom->dom_next) {
KASSERT(((i == AF_INET) || (i == AF_INET6)),
("unexpected protocol in vfs_hang_addrlist"));
if (dom->dom_family == i && dom->dom_rtattach) {
/*
* XXX MRT
* The INET and INET6 domains know the
* offset already. We don't need to send it
* So we just use it as a flag to say that
* we are or are not setting up a real routing
* table. Only IP and IPV6 need have this
* be 0 so all other protocols can stay the
* same (ABI compatible).
*/
//.........这里部分代码省略.........
示例11: udf_mountfs
static int
udf_mountfs(struct vnode *devvp, struct mount *mp)
{
struct buf *bp = NULL;
struct cdev *dev;
struct anchor_vdp avdp;
struct udf_mnt *udfmp = NULL;
struct part_desc *pd;
struct logvol_desc *lvd;
struct fileset_desc *fsd;
struct file_entry *root_fentry;
uint32_t sector, size, mvds_start, mvds_end;
uint32_t logical_secsize;
uint32_t fsd_offset = 0;
uint16_t part_num = 0, fsd_part = 0;
int error = EINVAL;
int logvol_found = 0, part_found = 0, fsd_found = 0;
int bsize;
struct g_consumer *cp;
struct bufobj *bo;
dev = devvp->v_rdev;
dev_ref(dev);
DROP_GIANT();
g_topology_lock();
error = g_vfs_open(devvp, &cp, "udf", 0);
g_topology_unlock();
PICKUP_GIANT();
VOP_UNLOCK(devvp, 0);
if (error)
goto bail;
bo = &devvp->v_bufobj;
if (devvp->v_rdev->si_iosize_max != 0)
mp->mnt_iosize_max = devvp->v_rdev->si_iosize_max;
if (mp->mnt_iosize_max > MAXPHYS)
mp->mnt_iosize_max = MAXPHYS;
/* XXX: should be M_WAITOK */
udfmp = malloc(sizeof(struct udf_mnt), M_UDFMOUNT,
M_NOWAIT | M_ZERO);
if (udfmp == NULL) {
printf("Cannot allocate UDF mount struct\n");
error = ENOMEM;
goto bail;
}
mp->mnt_data = udfmp;
mp->mnt_stat.f_fsid.val[0] = dev2udev(devvp->v_rdev);
mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
MNT_ILOCK(mp);
mp->mnt_flag |= MNT_LOCAL;
mp->mnt_kern_flag |= MNTK_LOOKUP_SHARED | MNTK_EXTENDED_SHARED;
MNT_IUNLOCK(mp);
udfmp->im_mountp = mp;
udfmp->im_dev = dev;
udfmp->im_devvp = devvp;
udfmp->im_d2l = NULL;
udfmp->im_cp = cp;
udfmp->im_bo = bo;
#if 0
udfmp->im_l2d = NULL;
#endif
/*
* The UDF specification defines a logical sectorsize of 2048
* for DVD media.
*/
logical_secsize = 2048;
if (((logical_secsize % cp->provider->sectorsize) != 0) ||
(logical_secsize < cp->provider->sectorsize)) {
error = EINVAL;
goto bail;
}
bsize = cp->provider->sectorsize;
/*
* Get the Anchor Volume Descriptor Pointer from sector 256.
* XXX Should also check sector n - 256, n, and 512.
*/
sector = 256;
if ((error = bread(devvp, sector * btodb(logical_secsize), bsize,
NOCRED, &bp)) != 0)
goto bail;
if ((error = udf_checktag((struct desc_tag *)bp->b_data, TAGID_ANCHOR)))
goto bail;
bcopy(bp->b_data, &avdp, sizeof(struct anchor_vdp));
brelse(bp);
bp = NULL;
/*
* Extract the Partition Descriptor and Logical Volume Descriptor
* from the Volume Descriptor Sequence.
* XXX Should we care about the partition type right now?
* XXX What about multiple partitions?
*/
//.........这里部分代码省略.........
示例12: nfs_mount
//.........这里部分代码省略.........
*/
if (args.sotype == SOCK_DGRAM && nmp->nm_sotype == SOCK_STREAM)
tprintf(curthread->td_proc, LOG_WARNING,
"Warning: mount -u that changes TCP->UDP can result in hung threads\n");
/*
* When doing an update, we can't change from or to
* v3, switch lockd strategies or change cookie translation
*/
args.flags = (args.flags &
~(NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) |
(nmp->nm_flag &
(NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
nfs_decode_args(mp, nmp, &args, NULL);
goto out;
}
/*
* Make the nfs_ip_paranoia sysctl serve as the default connection
* or no-connection mode for those protocols that support
* no-connection mode (the flag will be cleared later for protocols
* that do not support no-connection mode). This will allow a client
* to receive replies from a different IP then the request was
* sent to. Note: default value for nfs_ip_paranoia is 1 (paranoid),
* not 0.
*/
if (nfs_ip_paranoia == 0)
args.flags |= NFSMNT_NOCONN;
if (has_nfs_args_opt) {
/*
* In the 'nfs_args' case, the pointers in the args
* structure are in userland - we copy them in here.
*/
if (!has_fh_opt) {
error = copyin((caddr_t)args.fh, (caddr_t)nfh,
args.fhsize);
if (error) {
goto out;
}
args.fh = nfh;
}
if (!has_hostname_opt) {
error = copyinstr(args.hostname, hst, MNAMELEN-1, &len);
if (error) {
goto out;
}
bzero(&hst[len], MNAMELEN - len);
args.hostname = hst;
}
if (!has_addr_opt) {
/* sockargs() call must be after above copyin() calls */
error = getsockaddr(&nam, (caddr_t)args.addr,
args.addrlen);
if (error) {
goto out;
}
}
} else if (has_addr_opt == 0) {
vfs_mount_error(mp, "No server address");
error = EINVAL;
goto out;
}
error = mountnfs(&args, mp, nam, args.hostname, &vp,
curthread->td_ucred, nametimeo, negnametimeo);
out:
if (!error) {
MNT_ILOCK(mp);
mp->mnt_kern_flag |= MNTK_LOOKUP_SHARED;
MNT_IUNLOCK(mp);
}
return (error);
}
/*
* VFS Operations.
*
* mount system call
* It seems a bit dumb to copyinstr() the host and path here and then
* bcopy() them in mountnfs(), but I wanted to detect errors before
* doing the sockargs() call because sockargs() allocates an mbuf and
* an error after that means that I have to release the mbuf.
*/
/* ARGSUSED */
static int
nfs_cmount(struct mntarg *ma, void *data, uint64_t flags)
{
int error;
struct nfs_args args;
error = copyin(data, &args, sizeof (struct nfs_args));
if (error)
return error;
ma = mount_arg(ma, "nfs_args", &args, sizeof args);
error = kernel_mount(ma, flags);
return (error);
}
示例13: msdosfs_unmount
/*
* Unmount the filesystem described by mp.
*/
static int
msdosfs_unmount(struct mount *mp, int mntflags)
{
struct msdosfsmount *pmp;
int error, flags;
error = flags = 0;
pmp = VFSTOMSDOSFS(mp);
if ((pmp->pm_flags & MSDOSFSMNT_RONLY) == 0)
error = msdosfs_sync(mp, MNT_WAIT);
if ((mntflags & MNT_FORCE) != 0)
flags |= FORCECLOSE;
else if (error != 0)
return (error);
error = vflush(mp, 0, flags, curthread);
if (error != 0 && error != ENXIO)
return (error);
if ((pmp->pm_flags & MSDOSFSMNT_RONLY) == 0) {
error = markvoldirty(pmp, 0);
if (error && error != ENXIO) {
(void)markvoldirty(pmp, 1);
return (error);
}
}
if (pmp->pm_flags & MSDOSFSMNT_KICONV && msdosfs_iconv) {
if (pmp->pm_w2u)
msdosfs_iconv->close(pmp->pm_w2u);
if (pmp->pm_u2w)
msdosfs_iconv->close(pmp->pm_u2w);
if (pmp->pm_d2u)
msdosfs_iconv->close(pmp->pm_d2u);
if (pmp->pm_u2d)
msdosfs_iconv->close(pmp->pm_u2d);
}
#ifdef MSDOSFS_DEBUG
{
struct vnode *vp = pmp->pm_devvp;
struct bufobj *bo;
bo = &vp->v_bufobj;
BO_LOCK(bo);
VI_LOCK(vp);
vn_printf(vp,
"msdosfs_umount(): just before calling VOP_CLOSE()\n");
printf("freef %p, freeb %p, mount %p\n",
TAILQ_NEXT(vp, v_actfreelist), vp->v_actfreelist.tqe_prev,
vp->v_mount);
printf("cleanblkhd %p, dirtyblkhd %p, numoutput %ld, type %d\n",
TAILQ_FIRST(&vp->v_bufobj.bo_clean.bv_hd),
TAILQ_FIRST(&vp->v_bufobj.bo_dirty.bv_hd),
vp->v_bufobj.bo_numoutput, vp->v_type);
VI_UNLOCK(vp);
BO_UNLOCK(bo);
}
#endif
DROP_GIANT();
if (pmp->pm_devvp->v_type == VCHR && pmp->pm_devvp->v_rdev != NULL)
pmp->pm_devvp->v_rdev->si_mountpt = NULL;
g_topology_lock();
g_vfs_close(pmp->pm_cp);
g_topology_unlock();
PICKUP_GIANT();
vrele(pmp->pm_devvp);
dev_rel(pmp->pm_dev);
free(pmp->pm_inusemap, M_MSDOSFSFAT);
if (pmp->pm_flags & MSDOSFS_LARGEFS)
msdosfs_fileno_free(mp);
lockdestroy(&pmp->pm_fatlock);
free(pmp, M_MSDOSFSMNT);
mp->mnt_data = NULL;
MNT_ILOCK(mp);
mp->mnt_flag &= ~MNT_LOCAL;
MNT_IUNLOCK(mp);
return (error);
}
示例14: udf_mount
static int
udf_mount(struct mount *mp)
{
struct vnode *devvp; /* vnode of the mount device */
struct thread *td;
struct udf_mnt *imp = NULL;
struct vfsoptlist *opts;
char *fspec, *cs_disk, *cs_local;
int error, len, *udf_flags;
struct nameidata nd, *ndp = &nd;
td = curthread;
opts = mp->mnt_optnew;
/*
* Unconditionally mount as read-only.
*/
MNT_ILOCK(mp);
mp->mnt_flag |= MNT_RDONLY;
MNT_IUNLOCK(mp);
/*
* No root filesystem support. Probably not a big deal, since the
* bootloader doesn't understand UDF.
*/
if (mp->mnt_flag & MNT_ROOTFS)
return (ENOTSUP);
fspec = NULL;
error = vfs_getopt(opts, "from", (void **)&fspec, &len);
if (!error && fspec[len - 1] != '\0')
return (EINVAL);
if (mp->mnt_flag & MNT_UPDATE) {
return (0);
}
/* Check that the mount device exists */
if (fspec == NULL)
return (EINVAL);
NDINIT(ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, fspec, td);
if ((error = namei(ndp)))
return (error);
NDFREE(ndp, NDF_ONLY_PNBUF);
devvp = ndp->ni_vp;
if (vn_isdisk(devvp, &error) == 0) {
vput(devvp);
return (error);
}
/* Check the access rights on the mount device */
error = VOP_ACCESS(devvp, VREAD, td->td_ucred, td);
if (error)
error = priv_check(td, PRIV_VFS_MOUNT_PERM);
if (error) {
vput(devvp);
return (error);
}
if ((error = udf_mountfs(devvp, mp))) {
vrele(devvp);
return (error);
}
imp = VFSTOUDFFS(mp);
udf_flags = NULL;
error = vfs_getopt(opts, "flags", (void **)&udf_flags, &len);
if (error || len != sizeof(int))
return (EINVAL);
imp->im_flags = *udf_flags;
if (imp->im_flags & UDFMNT_KICONV && udf_iconv) {
cs_disk = NULL;
error = vfs_getopt(opts, "cs_disk", (void **)&cs_disk, &len);
if (!error && cs_disk[len - 1] != '\0')
return (EINVAL);
cs_local = NULL;
error = vfs_getopt(opts, "cs_local", (void **)&cs_local, &len);
if (!error && cs_local[len - 1] != '\0')
return (EINVAL);
udf_iconv->open(cs_local, cs_disk, &imp->im_d2l);
#if 0
udf_iconv->open(cs_disk, cs_local, &imp->im_l2d);
#endif
}
vfs_mountedfrom(mp, fspec);
return 0;
};
示例15: msdosfs_mount
/*
* mp - path - addr in user space of mount point (ie /usr or whatever)
* data - addr in user space of mount params including the name of the block
* special file to treat as a filesystem.
*/
static int
msdosfs_mount(struct mount *mp)
{
struct vnode *devvp; /* vnode for blk device to mount */
struct thread *td;
/* msdosfs specific mount control block */
struct msdosfsmount *pmp = NULL;
struct nameidata ndp;
int error, flags;
accmode_t accmode;
char *from;
td = curthread;
if (vfs_filteropt(mp->mnt_optnew, msdosfs_opts))
return (EINVAL);
/*
* 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) {
pmp = VFSTOMSDOSFS(mp);
if (vfs_flagopt(mp->mnt_optnew, "export", NULL, 0)) {
/*
* Forbid export requests if filesystem has
* MSDOSFS_LARGEFS flag set.
*/
if ((pmp->pm_flags & MSDOSFS_LARGEFS) != 0) {
vfs_mount_error(mp,
"MSDOSFS_LARGEFS flag set, cannot export");
return (EOPNOTSUPP);
}
}
if (!(pmp->pm_flags & MSDOSFSMNT_RONLY) &&
vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0)) {
error = VFS_SYNC(mp, MNT_WAIT);
if (error)
return (error);
flags = WRITECLOSE;
if (mp->mnt_flag & MNT_FORCE)
flags |= FORCECLOSE;
error = vflush(mp, 0, flags, td);
if (error)
return (error);
/*
* Now the volume is clean. Mark it so while the
* device is still rw.
*/
error = markvoldirty(pmp, 0);
if (error) {
(void)markvoldirty(pmp, 1);
return (error);
}
/* Downgrade the device from rw to ro. */
DROP_GIANT();
g_topology_lock();
error = g_access(pmp->pm_cp, 0, -1, 0);
g_topology_unlock();
PICKUP_GIANT();
if (error) {
(void)markvoldirty(pmp, 1);
return (error);
}
/*
* Backing out after an error was painful in the
* above. Now we are committed to succeeding.
*/
pmp->pm_fmod = 0;
pmp->pm_flags |= MSDOSFSMNT_RONLY;
MNT_ILOCK(mp);
mp->mnt_flag |= MNT_RDONLY;
MNT_IUNLOCK(mp);
} else if ((pmp->pm_flags & MSDOSFSMNT_RONLY) &&
!vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0)) {
/*
* If upgrade to read-write by non-root, then verify
* that user has necessary permissions on the device.
*/
devvp = pmp->pm_devvp;
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
error = VOP_ACCESS(devvp, VREAD | VWRITE,
td->td_ucred, td);
if (error)
error = priv_check(td, PRIV_VFS_MOUNT_PERM);
if (error) {
VOP_UNLOCK(devvp, 0);
return (error);
}
VOP_UNLOCK(devvp, 0);
DROP_GIANT();
g_topology_lock();
error = g_access(pmp->pm_cp, 0, 1, 0);
//.........这里部分代码省略.........