本文整理汇总了C++中VOP_UNLOCK函数的典型用法代码示例。如果您正苦于以下问题:C++ VOP_UNLOCK函数的具体用法?C++ VOP_UNLOCK怎么用?C++ VOP_UNLOCK使用的例子?那么, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了VOP_UNLOCK函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: vfs_relookup
//.........这里部分代码省略.........
* cnp->cn_nameptr for callers that need the name. Callers needing
* the name set the SAVENAME flag. When done, they assume
* responsibility for freeing the pathname buffer.
*/
#ifdef NAMEI_DIAGNOSTIC
/* XXX: Figure out the length of the last component. */
cp = cnp->cn_nameptr;
while (*cp && (*cp != '/')) {
cp++;
}
if (cnp->cn_namelen != cp - cnp->cn_nameptr)
panic("relookup: bad len");
if (*cp != 0)
panic("relookup: not last component");
printf("{%s}: ", cnp->cn_nameptr);
#endif
/*
* Check for degenerate name (e.g. / or "")
* which is a way of talking about a directory,
* e.g. like "/." or ".".
*/
if (cnp->cn_nameptr[0] == '\0')
panic("relookup: null name");
if (cnp->cn_flags & ISDOTDOT)
panic ("relookup: lookup on dot-dot");
/*
* We now have a segment name to search for, and a directory to search.
*/
if ((error = VOP_LOOKUP(dp, vpp, cnp)) != 0) {
#ifdef DIAGNOSTIC
if (*vpp != NULL)
panic("leaf should be empty");
#endif
if (error != EJUSTRETURN)
goto bad;
/*
* If creating and at end of pathname, then can consider
* allowing file to be created.
*/
if (rdonly || (dvp->v_mount->mnt_flag & MNT_RDONLY)) {
error = EROFS;
goto bad;
}
/* ASSERT(dvp == ndp->ni_startdir) */
if (cnp->cn_flags & SAVESTART)
vref(dvp);
/*
* We return with ni_vp NULL to indicate that the entry
* doesn't currently exist, leaving a pointer to the
* (possibly locked) directory inode in ndp->ni_dvp.
*/
return (0);
}
dp = *vpp;
#ifdef DIAGNOSTIC
/*
* Check for symbolic link
*/
if (dp->v_type == VLNK && (cnp->cn_flags & FOLLOW))
panic ("relookup: symlink found.");
#endif
/*
* Check for read-only file systems.
*/
if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME) {
/*
* Disallow directory write attempts on read-only
* file systems.
*/
if (rdonly || (dp->v_mount->mnt_flag & MNT_RDONLY) ||
(wantparent &&
(dvp->v_mount->mnt_flag & MNT_RDONLY))) {
error = EROFS;
goto bad2;
}
}
/* ASSERT(dvp == ndp->ni_startdir) */
if (cnp->cn_flags & SAVESTART)
vref(dvp);
if (!wantparent)
vrele(dvp);
if ((cnp->cn_flags & LOCKLEAF) == 0)
VOP_UNLOCK(dp, 0, p);
return (0);
bad2:
if ((cnp->cn_flags & LOCKPARENT) && (cnp->cn_flags & ISLASTCN))
VOP_UNLOCK(dvp, 0, p);
vrele(dvp);
bad:
vput(dp);
*vpp = NULL;
return (error);
}
示例2: v7fs_lookup
int
v7fs_lookup(void *v)
{
struct vop_lookup_v2_args /* {
struct vnode *a_dvp;
struct vnode **a_vpp;
struct componentname *a_cnp;
} */ *a = v;
struct vnode *dvp = a->a_dvp;
struct v7fs_node *parent_node = dvp->v_data;
struct v7fs_inode *parent = &parent_node->inode;
struct v7fs_self *fs = parent_node->v7fsmount->core;/* my filesystem */
struct vnode *vpp;
struct componentname *cnp = a->a_cnp;
int nameiop = cnp->cn_nameiop;
const char *name = cnp->cn_nameptr;
int namelen = cnp->cn_namelen;
int flags = cnp->cn_flags;
bool isdotdot = flags & ISDOTDOT;
bool islastcn = flags & ISLASTCN;
v7fs_ino_t ino;
int error;
#ifdef V7FS_VNOPS_DEBUG
const char *opname[] = { "LOOKUP", "CREATE", "DELETE", "RENAME" };
#endif
DPRINTF("'%s' op=%s flags=%d parent=%d %o %dbyte\n", name,
opname[nameiop], cnp->cn_flags, parent->inode_number, parent->mode,
parent->filesize);
*a->a_vpp = 0;
/* Check directory permission for search */
if ((error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred))) {
DPRINTF("***perm.\n");
return error;
}
/* Deny last component write operation on a read-only mount */
if (islastcn && (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
(nameiop == DELETE || nameiop == RENAME)) {
DPRINTF("***ROFS.\n");
return EROFS;
}
/* No lookup on removed directory */
if (v7fs_inode_nlink(parent) == 0)
return ENOENT;
/* "." */
if (namelen == 1 && name[0] == '.') {
if ((nameiop == RENAME) && islastcn) {
return EISDIR; /* t_vnops rename_dir(3) */
}
vref(dvp); /* v_usecount++ */
*a->a_vpp = dvp;
DPRINTF("done.(.)\n");
return 0;
}
/* ".." and reguler file. */
if ((error = v7fs_file_lookup_by_name(fs, parent, name, &ino))) {
/* Not found. Tell this entry be able to allocate. */
if (((nameiop == CREATE) || (nameiop == RENAME)) && islastcn) {
/* Check directory permission to allocate. */
if ((error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred))) {
DPRINTF("access denied. (%s)\n", name);
return error;
}
DPRINTF("EJUSTRETURN op=%d (%s)\n", nameiop, name);
return EJUSTRETURN;
}
DPRINTF("lastcn=%d\n", flags & ISLASTCN);
return error;
}
if ((nameiop == DELETE) && islastcn) {
if ((error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred))) {
DPRINTF("access denied. (%s)\n", name);
return error;
}
}
/* Entry found. Allocate v-node */
// Check permissions?
vpp = 0;
if (isdotdot) {
VOP_UNLOCK(dvp); /* preserve reference count. (not vput) */
}
DPRINTF("enter vget\n");
if ((error = v7fs_vget(dvp->v_mount, ino, &vpp))) {
DPRINTF("***can't get vnode.\n");
return error;
}
DPRINTF("exit vget\n");
if (isdotdot) {
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
}
if (vpp != dvp)
VOP_UNLOCK(vpp);
*a->a_vpp = vpp;
//.........这里部分代码省略.........
示例3: tmpfs_rename
//.........这里部分代码省略.........
TMPFS_UNLOCK(tmp);
if (n == NULL) {
error = EINVAL;
if (newname != NULL)
free(newname, M_TMPFSNAME);
goto out_locked;
}
TMPFS_NODE_UNLOCK(n);
/* Adjust the parent pointer. */
TMPFS_VALIDATE_DIR(fnode);
TMPFS_NODE_LOCK(de->td_node);
de->td_node->tn_dir.tn_parent = tdnode;
TMPFS_NODE_UNLOCK(de->td_node);
/* As a result of changing the target of the '..'
* entry, the link count of the source and target
* directories has to be adjusted. */
TMPFS_NODE_LOCK(tdnode);
TMPFS_ASSERT_LOCKED(tdnode);
tdnode->tn_links++;
TMPFS_NODE_UNLOCK(tdnode);
TMPFS_NODE_LOCK(fdnode);
TMPFS_ASSERT_LOCKED(fdnode);
fdnode->tn_links--;
TMPFS_NODE_UNLOCK(fdnode);
}
}
/* Do the move: just remove the entry from the source directory
* and insert it into the target one. */
tmpfs_dir_detach(fdvp, de);
if (fcnp->cn_flags & DOWHITEOUT)
tmpfs_dir_whiteout_add(fdvp, fcnp);
if (tcnp->cn_flags & ISWHITEOUT)
tmpfs_dir_whiteout_remove(tdvp, tcnp);
/* If the name has changed, we need to make it effective by changing
* it in the directory entry. */
if (newname != NULL) {
MPASS(tcnp->cn_namelen <= MAXNAMLEN);
free(de->ud.td_name, M_TMPFSNAME);
de->ud.td_name = newname;
tmpfs_dirent_init(de, tcnp->cn_nameptr, tcnp->cn_namelen);
fnode->tn_status |= TMPFS_NODE_CHANGED;
tdnode->tn_status |= TMPFS_NODE_MODIFIED;
}
/* If we are overwriting an entry, we have to remove the old one
* from the target directory. */
if (tvp != NULL) {
struct tmpfs_dirent *tde;
/* Remove the old entry from the target directory. */
tde = tmpfs_dir_lookup(tdnode, tnode, tcnp);
tmpfs_dir_detach(tdvp, tde);
/* Free the directory entry we just deleted. Note that the
* node referred by it will not be removed until the vnode is
* really reclaimed. */
tmpfs_free_dirent(VFS_TO_TMPFS(tvp->v_mount), tde);
}
tmpfs_dir_attach(tdvp, de);
cache_purge(fvp);
if (tvp != NULL)
cache_purge(tvp);
cache_purge_negative(tdvp);
error = 0;
out_locked:
if (fdvp != tdvp && fdvp != tvp)
VOP_UNLOCK(fdvp, 0);
out:
/* Release target nodes. */
/* XXX: I don't understand when tdvp can be the same as tvp, but
* other code takes care of this... */
if (tdvp == tvp)
vrele(tdvp);
else
vput(tdvp);
if (tvp != NULL)
vput(tvp);
/* Release source nodes. */
vrele(fdvp);
vrele(fvp);
if (mp != NULL)
vfs_unbusy(mp);
return error;
}
示例4: nandfs_get_segment_info_filter
int
nandfs_get_segment_info_filter(struct nandfs_device *fsdev,
struct nandfs_suinfo *nsi, uint32_t nmembs, uint64_t segment,
uint64_t *nsegs, uint32_t filter, uint32_t nfilter)
{
struct nandfs_segment_usage *su;
struct nandfs_node *su_node;
struct buf *bp;
uint64_t curr, blocknr, blockoff, i;
uint32_t flags;
int err = 0;
curr = ~(0);
lockmgr(&fsdev->nd_seg_const, LK_EXCLUSIVE, NULL);
su_node = fsdev->nd_su_node;
VOP_LOCK(NTOV(su_node), LK_SHARED);
bp = NULL;
if (nsegs != NULL)
*nsegs = 0;
for (i = 0; i < nmembs; segment++) {
if (segment == fsdev->nd_fsdata.f_nsegments)
break;
nandfs_seg_usage_blk_offset(fsdev, segment, &blocknr,
&blockoff);
if (i == 0 || curr != blocknr) {
if (bp != NULL)
brelse(bp);
err = nandfs_bread(su_node, blocknr, NOCRED,
0, &bp);
if (err) {
goto out;
}
curr = blocknr;
}
su = SU_USAGE_OFF(bp, blockoff);
flags = su->su_flags;
if (segment == fsdev->nd_seg_num ||
segment == fsdev->nd_next_seg_num)
flags |= NANDFS_SEGMENT_USAGE_ACTIVE;
if (nfilter != 0 && (flags & nfilter) != 0)
continue;
if (filter != 0 && (flags & filter) == 0)
continue;
nsi->nsi_num = segment;
nsi->nsi_lastmod = su->su_lastmod;
nsi->nsi_blocks = su->su_nblocks;
nsi->nsi_flags = flags;
nsi++;
i++;
if (nsegs != NULL)
(*nsegs)++;
}
out:
if (bp != NULL)
brelse(bp);
VOP_UNLOCK(NTOV(su_node), 0);
lockmgr(&fsdev->nd_seg_const, LK_RELEASE, NULL);
return (err);
}
示例5: ext2fs_gro_genealogy
/*
* ext2fs_gro_genealogy: Analyze the genealogy of the source and target
* directories.
*/
static int
ext2fs_gro_genealogy(struct mount *mp, kauth_cred_t cred,
struct vnode *fdvp, struct vnode *tdvp,
struct vnode **intermediate_node_ret)
{
struct vnode *vp, *dvp;
ino_t dotdot_ino = -1; /* XXX gcc 4.8.3: maybe-uninitialized */
int error;
KASSERT(mp != NULL);
KASSERT(fdvp != NULL);
KASSERT(tdvp != NULL);
KASSERT(fdvp != tdvp);
KASSERT(intermediate_node_ret != NULL);
KASSERT(fdvp->v_mount == mp);
KASSERT(tdvp->v_mount == mp);
KASSERT(fdvp->v_type == VDIR);
KASSERT(tdvp->v_type == VDIR);
/*
* We need to provisionally lock tdvp to keep rmdir from
* deleting it -- or any ancestor -- at an inopportune moment.
*/
error = ext2fs_gro_lock_directory(mp, tdvp);
if (error)
return error;
vp = tdvp;
vref(vp);
for (;;) {
KASSERT(vp != NULL);
KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE);
KASSERT(vp->v_mount == mp);
KASSERT(vp->v_type == VDIR);
KASSERT(!ext2fs_rmdired_p(vp));
/* Did we hit the root without finding fdvp? */
if (VTOI(vp)->i_number == UFS_ROOTINO) {
vput(vp);
*intermediate_node_ret = NULL;
return 0;
}
error = ext2fs_read_dotdot(vp, cred, &dotdot_ino);
if (error) {
vput(vp);
return error;
}
/* Did we find that fdvp is an ancestor of tdvp? */
if (VTOI(fdvp)->i_number == dotdot_ino) {
/* Unlock vp, but keep it referenced. */
VOP_UNLOCK(vp);
*intermediate_node_ret = vp;
return 0;
}
/* Neither -- keep ascending the family tree. */
error = vcache_get(mp, &dotdot_ino, sizeof(dotdot_ino), &dvp);
vput(vp);
if (error)
return error;
error = vn_lock(dvp, LK_EXCLUSIVE);
if (error) {
vrele(dvp);
return error;
}
KASSERT(dvp != NULL);
KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE);
vp = dvp;
if (vp->v_type != VDIR) {
/*
* XXX Panic? Print a warning? Can this
* happen if we lose the race I suspect to
* exist above, and the `..' inode number has
* been recycled?
*/
vput(vp);
return ENOTDIR;
}
if (ext2fs_rmdired_p(vp)) {
vput(vp);
return ENOENT;
}
}
}
示例6: unionfs_domount
/*
* Mount unionfs layer.
*/
static int
unionfs_domount(struct mount *mp)
{
int error;
struct vnode *lowerrootvp;
struct vnode *upperrootvp;
struct unionfs_mount *ump;
struct thread *td;
char *target;
char *tmp;
char *ep;
int len;
size_t done;
int below;
uid_t uid;
gid_t gid;
u_short udir;
u_short ufile;
unionfs_copymode copymode;
unionfs_whitemode whitemode;
struct nameidata nd, *ndp;
struct vattr va;
UNIONFSDEBUG("unionfs_mount(mp = %p)\n", (void *)mp);
error = 0;
below = 0;
uid = 0;
gid = 0;
udir = 0;
ufile = 0;
copymode = UNIONFS_TRANSPARENT; /* default */
whitemode = UNIONFS_WHITE_ALWAYS;
ndp = &nd;
td = curthread;
if (mp->mnt_flag & MNT_ROOTFS) {
vfs_mount_error(mp, "Cannot union mount root filesystem");
return (EOPNOTSUPP);
}
/*
* Update is a no operation.
*/
if (mp->mnt_flag & MNT_UPDATE) {
vfs_mount_error(mp, "unionfs does not support mount update");
return (EOPNOTSUPP);
}
/*
* Get argument
*/
error = vfs_getopt(mp->mnt_optnew, "target", (void **)&target, &len);
if (error)
error = vfs_getopt(mp->mnt_optnew, "from", (void **)&target,
&len);
if (error || target[len - 1] != '\0') {
vfs_mount_error(mp, "Invalid target");
return (EINVAL);
}
if (vfs_getopt(mp->mnt_optnew, "below", NULL, NULL) == 0)
below = 1;
if (vfs_getopt(mp->mnt_optnew, "udir", (void **)&tmp, NULL) == 0) {
if (tmp != NULL)
udir = (mode_t)strtol(tmp, &ep, 8);
if (tmp == NULL || *ep) {
vfs_mount_error(mp, "Invalid udir");
return (EINVAL);
}
udir &= S_IRWXU | S_IRWXG | S_IRWXO;
}
if (vfs_getopt(mp->mnt_optnew, "ufile", (void **)&tmp, NULL) == 0) {
if (tmp != NULL)
ufile = (mode_t)strtol(tmp, &ep, 8);
if (tmp == NULL || *ep) {
vfs_mount_error(mp, "Invalid ufile");
return (EINVAL);
}
ufile &= S_IRWXU | S_IRWXG | S_IRWXO;
}
/* check umask, uid and gid */
if (udir == 0 && ufile != 0)
udir = ufile;
if (ufile == 0 && udir != 0)
ufile = udir;
vn_lock(mp->mnt_vnodecovered, LK_SHARED | LK_RETRY);
error = VOP_GETATTR(mp->mnt_vnodecovered, &va, mp->mnt_cred);
if (!error) {
if (udir == 0)
udir = va.va_mode;
if (ufile == 0)
ufile = va.va_mode;
uid = va.va_uid;
gid = va.va_gid;
}
VOP_UNLOCK(mp->mnt_vnodecovered, LK_RELEASE);
//.........这里部分代码省略.........
示例7: exec_script_makecmds
//.........这里部分代码省略.........
;
if (*cp == '\0')
goto check_shell;
/*
* collect the shell argument. everything after the shell name
* is passed as ONE argument; that's the correct (historical)
* behaviour.
*/
shellarg = cp;
for ( /* cp = cp */ ; *cp != '\0'; cp++)
shellarglen++;
*cp++ = '\0';
check_shell:
/*
* MNT_NOSUID and STRC are already taken care of by check_exec,
* so we don't need to worry about them now or later.
*/
script_sbits = epp->ep_vap->va_mode & (VSUID | VSGID);
if (script_sbits != 0) {
script_uid = epp->ep_vap->va_uid;
script_gid = epp->ep_vap->va_gid;
}
/*
* if the script isn't readable, or it's set-id, then we've
* gotta supply a "/dev/fd/..." for the shell to read.
* Note that stupid shells (csh) do the wrong thing, and
* close all open fd's when they start. That kills this
* method of implementing "safe" set-id and x-only scripts.
*/
vn_lock(scriptvp, LK_EXCLUSIVE|LK_RETRY, p);
error = VOP_ACCESS(scriptvp, VREAD, p->p_ucred, p);
VOP_UNLOCK(scriptvp, 0, p);
if (error == EACCES || script_sbits) {
struct file *fp;
#ifdef DIAGNOSTIC
if (epp->ep_flags & EXEC_HASFD)
panic("exec_script_makecmds: epp already has a fd");
#endif
fdplock(p->p_fd);
error = falloc(p, &fp, &epp->ep_fd);
fdpunlock(p->p_fd);
if (error)
goto fail;
epp->ep_flags |= EXEC_HASFD;
fp->f_type = DTYPE_VNODE;
fp->f_ops = &vnops;
fp->f_data = (caddr_t) scriptvp;
fp->f_flag = FREAD;
FILE_SET_MATURE(fp, p);
}
/* set up the parameters for the recursive check_exec() call */
epp->ep_ndp->ni_dirfd = AT_FDCWD;
epp->ep_ndp->ni_dirp = shellname;
epp->ep_ndp->ni_segflg = UIO_SYSSPACE;
epp->ep_flags |= EXEC_INDIR;
/* and set up the fake args list, for later */
shellargp = mallocarray(4, sizeof(char *), M_EXEC, M_WAITOK);
tmpsap = shellargp;
*tmpsap = malloc(shellnamelen + 1, M_EXEC, M_WAITOK);
示例8: namei
//.........这里部分代码省略.........
if (cnp->cn_pnbuf[0] == '/') {
dp = ndp->ni_rootdir;
vref(dp);
} else if (ndp->ni_dirfd == AT_FDCWD) {
dp = fdp->fd_cdir;
vref(dp);
} else {
struct file *fp = fd_getfile(fdp, ndp->ni_dirfd);
if (fp == NULL) {
pool_put(&namei_pool, cnp->cn_pnbuf);
return (EBADF);
}
dp = (struct vnode *)fp->f_data;
if (fp->f_type != DTYPE_VNODE || dp->v_type != VDIR) {
pool_put(&namei_pool, cnp->cn_pnbuf);
return (ENOTDIR);
}
vref(dp);
}
for (;;) {
if (!dp->v_mount) {
/* Give up if the directory is no longer mounted */
pool_put(&namei_pool, cnp->cn_pnbuf);
return (ENOENT);
}
cnp->cn_nameptr = cnp->cn_pnbuf;
ndp->ni_startdir = dp;
if ((error = vfs_lookup(ndp)) != 0) {
pool_put(&namei_pool, cnp->cn_pnbuf);
return (error);
}
/*
* If not a symbolic link, return search result.
*/
if ((cnp->cn_flags & ISSYMLINK) == 0) {
if ((cnp->cn_flags & (SAVENAME | SAVESTART)) == 0)
pool_put(&namei_pool, cnp->cn_pnbuf);
else
cnp->cn_flags |= HASBUF;
return (0);
}
if ((cnp->cn_flags & LOCKPARENT) && (cnp->cn_flags & ISLASTCN))
VOP_UNLOCK(ndp->ni_dvp, 0, p);
if (ndp->ni_loopcnt++ >= SYMLOOP_MAX) {
error = ELOOP;
break;
}
if (ndp->ni_pathlen > 1)
cp = pool_get(&namei_pool, PR_WAITOK);
else
cp = cnp->cn_pnbuf;
aiov.iov_base = cp;
aiov.iov_len = MAXPATHLEN;
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_offset = 0;
auio.uio_rw = UIO_READ;
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_procp = cnp->cn_proc;
auio.uio_resid = MAXPATHLEN;
error = VOP_READLINK(ndp->ni_vp, &auio, cnp->cn_cred);
if (error) {
badlink:
if (ndp->ni_pathlen > 1)
pool_put(&namei_pool, cp);
break;
}
linklen = MAXPATHLEN - auio.uio_resid;
if (linklen == 0) {
error = ENOENT;
goto badlink;
}
if (linklen + ndp->ni_pathlen >= MAXPATHLEN) {
error = ENAMETOOLONG;
goto badlink;
}
if (ndp->ni_pathlen > 1) {
memcpy(cp + linklen, ndp->ni_next, ndp->ni_pathlen);
pool_put(&namei_pool, cnp->cn_pnbuf);
cnp->cn_pnbuf = cp;
} else
cnp->cn_pnbuf[linklen] = '\0';
ndp->ni_pathlen += linklen;
vput(ndp->ni_vp);
dp = ndp->ni_dvp;
/*
* Check if root directory should replace current directory.
*/
if (cnp->cn_pnbuf[0] == '/') {
vrele(dp);
dp = ndp->ni_rootdir;
vref(dp);
}
}
pool_put(&namei_pool, cnp->cn_pnbuf);
vrele(ndp->ni_dvp);
vput(ndp->ni_vp);
ndp->ni_vp = NULL;
return (error);
}
示例9: fifo_open
/* ARGSUSED */
int
fifo_open(void *v)
{
struct vop_open_args *ap = v;
struct vnode *vp = ap->a_vp;
struct fifoinfo *fip;
struct proc *p = ap->a_p;
struct socket *rso, *wso;
int error;
if ((fip = vp->v_fifoinfo) == NULL) {
fip = malloc(sizeof(*fip), M_VNODE, M_WAITOK);
vp->v_fifoinfo = fip;
if ((error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0)) != 0) {
free(fip, M_VNODE);
vp->v_fifoinfo = NULL;
return (error);
}
fip->fi_readsock = rso;
if ((error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0)) != 0) {
(void)soclose(rso);
free(fip, M_VNODE);
vp->v_fifoinfo = NULL;
return (error);
}
fip->fi_writesock = wso;
if ((error = unp_connect2(wso, rso)) != 0) {
(void)soclose(wso);
(void)soclose(rso);
free(fip, M_VNODE);
vp->v_fifoinfo = NULL;
return (error);
}
fip->fi_readers = fip->fi_writers = 0;
wso->so_snd.sb_lowat = PIPE_BUF;
rso->so_state |= SS_CANTRCVMORE;
}
if (ap->a_mode & FREAD) {
fip->fi_readers++;
if (fip->fi_readers == 1) {
fip->fi_writesock->so_state &= ~SS_CANTSENDMORE;
if (fip->fi_writers > 0)
wakeup(&fip->fi_writers);
}
}
if (ap->a_mode & FWRITE) {
fip->fi_writers++;
if ((ap->a_mode & O_NONBLOCK) && fip->fi_readers == 0) {
error = ENXIO;
goto bad;
}
if (fip->fi_writers == 1) {
fip->fi_readsock->so_state &= ~SS_CANTRCVMORE;
if (fip->fi_readers > 0)
wakeup(&fip->fi_readers);
}
}
if ((ap->a_mode & O_NONBLOCK) == 0) {
if ((ap->a_mode & FREAD) && fip->fi_writers == 0) {
VOP_UNLOCK(vp, 0, p);
error = tsleep(&fip->fi_readers,
PCATCH | PSOCK, "fifor", 0);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
if (error)
goto bad;
}
if ((ap->a_mode & FWRITE) && fip->fi_readers == 0) {
VOP_UNLOCK(vp, 0, p);
error = tsleep(&fip->fi_writers,
PCATCH | PSOCK, "fifow", 0);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
if (error)
goto bad;
}
}
return (0);
bad:
VOP_CLOSE(vp, ap->a_mode, ap->a_cred, ap->a_p);
return (error);
}
示例10: nfs_namei
//.........这里部分代码省略.........
*dposp += len;
else if ((error = nfs_adv(mdp, dposp, len, rem)) != 0)
goto out;
}
if (!pubflag && nfs_ispublicfh(fhp))
return (ESTALE);
/*
* Extract and set starting directory.
*/
error = nfsrv_fhtovp(fhp, 0, &dp, nfsd, slp, nam, &rdonly);
if (error)
goto out;
if (dp->v_type != VDIR) {
vput(dp);
error = ENOTDIR;
goto out;
}
if (rdonly)
cnp->cn_flags |= RDONLY;
/*
* Set return directory. Reference to dp is implicitly transfered
* to the returned pointer
*/
*retdirp = dp;
if (v3) {
*retdirattr_retp = VOP_GETATTR(dp, retdirattrp,
ndp->ni_cnd.cn_cred);
}
VOP_UNLOCK(dp, 0);
if (pubflag) {
/*
* Oh joy. For WebNFS, handle those pesky '%' escapes,
* and the 'native path' indicator.
*/
cp = uma_zalloc(namei_zone, M_WAITOK);
fromcp = cnp->cn_pnbuf;
tocp = cp;
if ((unsigned char)*fromcp >= WEBNFS_SPECCHAR_START) {
switch ((unsigned char)*fromcp) {
case WEBNFS_NATIVE_CHAR:
/*
* 'Native' path for us is the same
* as a path according to the NFS spec,
* just skip the escape char.
*/
fromcp++;
break;
/*
* More may be added in the future, range 0x80-0xff
*/
default:
error = EIO;
uma_zfree(namei_zone, cp);
goto out;
}
}
/*
* Translate the '%' escapes, URL-style.
*/
while (*fromcp != '\0') {
示例11: ext2fs_mount
/*
* VFS Operations.
*
* mount system call
*/
int
ext2fs_mount(struct mount *mp, const char *path, void *data,
struct nameidata *ndp, struct proc *p)
{
struct vnode *devvp;
struct ufs_args args;
struct ufsmount *ump = NULL;
struct m_ext2fs *fs;
char fname[MNAMELEN];
char fspec[MNAMELEN];
int error, flags;
mode_t accessmode;
error = copyin(data, &args, sizeof(struct ufs_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_e2fs;
if (fs->e2fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) {
flags = WRITECLOSE;
if (mp->mnt_flag & MNT_FORCE)
flags |= FORCECLOSE;
error = ext2fs_flushfiles(mp, flags, p);
if (error == 0 &&
ext2fs_cgupdate(ump, MNT_WAIT) == 0 &&
(fs->e2fs.e2fs_state & E2FS_ERRORS) == 0) {
fs->e2fs.e2fs_state = E2FS_ISCLEAN;
(void)ext2fs_sbupdate(ump, MNT_WAIT);
}
if (error)
return (error);
fs->e2fs_ronly = 1;
}
if (mp->mnt_flag & MNT_RELOAD) {
error = ext2fs_reload(mp, ndp->ni_cnd.cn_cred, p);
if (error)
return (error);
}
if (fs->e2fs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) {
/*
* If upgrade to read-write by non-root, then verify
* that user has necessary permissions on the device.
*/
if (suser(p, 0) != 0) {
devvp = ump->um_devvp;
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
error = VOP_ACCESS(devvp, VREAD | VWRITE,
p->p_ucred, p);
VOP_UNLOCK(devvp, p);
if (error)
return (error);
}
fs->e2fs_ronly = 0;
if (fs->e2fs.e2fs_state == E2FS_ISCLEAN)
fs->e2fs.e2fs_state = 0;
else
fs->e2fs.e2fs_state = E2FS_ERRORS;
fs->e2fs_fmod = 1;
}
if (args.fspec == NULL) {
/*
* Process export requests.
*/
return (vfs_export(mp, &ump->um_export,
&args.export_info));
}
}
/*
* Not an update, or updating the name: look up the name
* and verify that it refers to a sensible block device.
*/
error = copyinstr(args.fspec, fspec, sizeof(fspec), NULL);
if (error)
goto error;
if (disk_map(fspec, fname, MNAMELEN, DM_OPENBLCK) == -1)
memcpy(fname, fspec, sizeof(fname));
NDINIT(ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, fname, p);
if ((error = namei(ndp)) != 0)
goto error;
devvp = ndp->ni_vp;
if (devvp->v_type != VBLK) {
error = ENOTBLK;
goto error_devvp;
}
if (major(devvp->v_rdev) >= nblkdev) {
error = ENXIO;
//.........这里部分代码省略.........
示例12: ext2fs_mountfs
/*
* Common code for mount and mountroot
*/
int
ext2fs_mountfs(struct vnode *devvp, struct mount *mp, struct proc *p)
{
struct ufsmount *ump;
struct buf *bp;
struct ext2fs *fs;
dev_t dev;
int error, ronly;
struct ucred *cred;
dev = devvp->v_rdev;
cred = p ? p->p_ucred : NOCRED;
/*
* Disallow multiple mounts of the same device.
* Disallow mounting of a device that is currently in use
* (except for root, which might share swap device for miniroot).
* Flush out any old buffers remaining from a previous use.
*/
if ((error = vfs_mountedon(devvp)) != 0)
return (error);
if (vcount(devvp) > 1 && devvp != rootvp)
return (EBUSY);
if ((error = vinvalbuf(devvp, V_SAVE, cred, p, 0, 0)) != 0)
return (error);
ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p);
if (error)
return (error);
bp = NULL;
ump = NULL;
/*
* Read the superblock from disk.
*/
error = bread(devvp, (daddr_t)(SBOFF / DEV_BSIZE), SBSIZE, &bp);
if (error)
goto out;
fs = (struct ext2fs *)bp->b_data;
error = e2fs_sbcheck(fs, ronly);
if (error)
goto out;
ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK | M_ZERO);
ump->um_e2fs = malloc(sizeof(struct m_ext2fs), M_UFSMNT,
M_WAITOK | M_ZERO);
/*
* Copy in the superblock, compute in-memory values
* and load group descriptors.
*/
e2fs_sbload(fs, &ump->um_e2fs->e2fs);
if ((error = e2fs_sbfill(devvp, ump->um_e2fs)) != 0)
goto out;
brelse(bp);
bp = NULL;
fs = &ump->um_e2fs->e2fs;
ump->um_e2fs->e2fs_ronly = ronly;
ump->um_fstype = UM_EXT2FS;
if (ronly == 0) {
if (fs->e2fs_state == E2FS_ISCLEAN)
fs->e2fs_state = 0;
else
fs->e2fs_state = E2FS_ERRORS;
ump->um_e2fs->e2fs_fmod = 1;
}
mp->mnt_data = (qaddr_t)ump;
mp->mnt_stat.f_fsid.val[0] = (long)dev;
mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
mp->mnt_stat.f_namemax = MAXNAMLEN;
mp->mnt_flag |= MNT_LOCAL;
ump->um_mountp = mp;
ump->um_dev = dev;
ump->um_devvp = devvp;
ump->um_nindir = NINDIR(ump->um_e2fs);
ump->um_bptrtodb = ump->um_e2fs->e2fs_fsbtodb;
ump->um_seqinc = 1; /* no frags */
ump->um_maxsymlinklen = EXT2_MAXSYMLINKLEN;
devvp->v_specmountpoint = mp;
return (0);
out:
if (bp)
brelse(bp);
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
(void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, cred, p);
VOP_UNLOCK(devvp, p);
if (ump) {
free(ump->um_e2fs, M_UFSMNT, sizeof *ump->um_e2fs);
free(ump, M_UFSMNT, sizeof *ump);
mp->mnt_data = NULL;
}
return (error);
}
示例13: cd9660_mount
/*
* VFS Operations.
*
* mount system call
*/
int
cd9660_mount(struct mount *mp, const char *path, void *data, size_t *data_len)
{
struct lwp *l = curlwp;
struct vnode *devvp;
struct iso_args *args = data;
int error;
struct iso_mnt *imp = VFSTOISOFS(mp);
if (*data_len < sizeof *args)
return EINVAL;
if (mp->mnt_flag & MNT_GETARGS) {
if (imp == NULL)
return EIO;
args->fspec = NULL;
args->flags = imp->im_flags;
*data_len = sizeof (*args);
return 0;
}
if ((mp->mnt_flag & MNT_RDONLY) == 0)
return (EROFS);
if ((mp->mnt_flag & MNT_UPDATE) && args->fspec == NULL)
return EINVAL;
/*
* Not an update, or updating the name: look up the name
* and verify that it refers to a sensible block device.
*/
error = namei_simple_user(args->fspec,
NSM_FOLLOW_NOEMULROOT, &devvp);
if (error != 0)
return (error);
if (devvp->v_type != VBLK) {
vrele(devvp);
return ENOTBLK;
}
if (bdevsw_lookup(devvp->v_rdev) == NULL) {
vrele(devvp);
return ENXIO;
}
/*
* If mount by non-root, then verify that user has necessary
* permissions on the device.
*/
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_MOUNT,
KAUTH_REQ_SYSTEM_MOUNT_DEVICE, mp, devvp, KAUTH_ARG(VREAD));
VOP_UNLOCK(devvp);
if (error) {
vrele(devvp);
return (error);
}
if ((mp->mnt_flag & MNT_UPDATE) == 0) {
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
error = VOP_OPEN(devvp, FREAD, FSCRED);
VOP_UNLOCK(devvp);
if (error)
goto fail;
error = iso_mountfs(devvp, mp, l, args);
if (error) {
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
(void)VOP_CLOSE(devvp, FREAD, NOCRED);
VOP_UNLOCK(devvp);
goto fail;
}
} else {
vrele(devvp);
if (devvp != imp->im_devvp &&
devvp->v_rdev != imp->im_devvp->v_rdev)
return (EINVAL); /* needs translation */
}
return set_statvfs_info(path, UIO_USERSPACE, args->fspec, UIO_USERSPACE,
mp->mnt_op->vfs_name, mp, l);
fail:
vrele(devvp);
return (error);
}
示例14: coff_load_file
static int
coff_load_file(struct thread *td, char *name)
{
struct proc *p = td->td_proc;
struct vmspace *vmspace = p->p_vmspace;
int error;
struct nameidata nd;
struct vnode *vp;
struct vattr attr;
struct filehdr *fhdr;
struct aouthdr *ahdr;
struct scnhdr *scns;
char *ptr = 0;
int nscns;
unsigned long text_offset = 0, text_address = 0, text_size = 0;
unsigned long data_offset = 0, data_address = 0, data_size = 0;
unsigned long bss_size = 0;
int i, writecount;
NDINIT(&nd, LOOKUP, ISOPEN | LOCKLEAF | FOLLOW | SAVENAME,
UIO_SYSSPACE, name, td);
error = namei(&nd);
if (error)
return error;
vp = nd.ni_vp;
if (vp == NULL)
return ENOEXEC;
error = VOP_GET_WRITECOUNT(vp, &writecount);
if (error != 0)
goto fail;
if (writecount != 0) {
error = ETXTBSY;
goto fail;
}
if ((error = VOP_GETATTR(vp, &attr, td->td_ucred)) != 0)
goto fail;
if ((vp->v_mount->mnt_flag & MNT_NOEXEC)
|| ((attr.va_mode & 0111) == 0)
|| (attr.va_type != VREG))
goto fail;
if (attr.va_size == 0) {
error = ENOEXEC;
goto fail;
}
if ((error = VOP_ACCESS(vp, VEXEC, td->td_ucred, td)) != 0)
goto fail;
if ((error = VOP_OPEN(vp, FREAD, td->td_ucred, td, NULL)) != 0)
goto fail;
/*
* Lose the lock on the vnode. It's no longer needed, and must not
* exist for the pagefault paging to work below.
*/
VOP_UNLOCK(vp, 0);
if ((error = vm_mmap(exec_map,
(vm_offset_t *) &ptr,
PAGE_SIZE,
VM_PROT_READ,
VM_PROT_READ,
0,
OBJT_VNODE,
vp,
0)) != 0)
goto unlocked_fail;
fhdr = (struct filehdr *)ptr;
if (fhdr->f_magic != I386_COFF) {
error = ENOEXEC;
goto dealloc_and_fail;
}
nscns = fhdr->f_nscns;
if ((nscns * sizeof(struct scnhdr)) > PAGE_SIZE) {
/*
* XXX -- just fail. I'm so lazy.
*/
error = ENOEXEC;
goto dealloc_and_fail;
}
ahdr = (struct aouthdr*)(ptr + sizeof(struct filehdr));
scns = (struct scnhdr*)(ptr + sizeof(struct filehdr)
+ sizeof(struct aouthdr));
for (i = 0; i < nscns; i++) {
if (scns[i].s_flags & STYP_NOLOAD)
continue;
else if (scns[i].s_flags & STYP_TEXT) {
//.........这里部分代码省略.........
示例15: tmpfs_rename_relock
/*
* We acquire all but fdvp locks using non-blocking acquisitions. If we
* fail to acquire any lock in the path we will drop all held locks,
* acquire the new lock in a blocking fashion, and then release it and
* restart the rename. This acquire/release step ensures that we do not
* spin on a lock waiting for release. On error release all vnode locks
* and decrement references the way tmpfs_rename() would do.
*/
static int
tmpfs_rename_relock(struct vnode *fdvp, struct vnode **fvpp,
struct vnode *tdvp, struct vnode **tvpp,
struct componentname *fcnp, struct componentname *tcnp)
{
struct vnode *nvp;
struct mount *mp;
struct tmpfs_dirent *de;
int error, restarts = 0;
VOP_UNLOCK(tdvp, 0);
if (*tvpp != NULL && *tvpp != tdvp)
VOP_UNLOCK(*tvpp, 0);
mp = fdvp->v_mount;
relock:
restarts += 1;
error = vn_lock(fdvp, LK_EXCLUSIVE);
if (error)
goto releout;
if (vn_lock(tdvp, LK_EXCLUSIVE | LK_NOWAIT) != 0) {
VOP_UNLOCK(fdvp, 0);
error = vn_lock(tdvp, LK_EXCLUSIVE);
if (error)
goto releout;
VOP_UNLOCK(tdvp, 0);
goto relock;
}
/*
* Re-resolve fvp to be certain it still exists and fetch the
* correct vnode.
*/
de = tmpfs_dir_lookup(VP_TO_TMPFS_DIR(fdvp), NULL, fcnp);
if (de == NULL) {
VOP_UNLOCK(fdvp, 0);
VOP_UNLOCK(tdvp, 0);
if ((fcnp->cn_flags & ISDOTDOT) != 0 ||
(fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.'))
error = EINVAL;
else
error = ENOENT;
goto releout;
}
error = tmpfs_alloc_vp(mp, de->td_node, LK_EXCLUSIVE | LK_NOWAIT, &nvp);
if (error != 0) {
VOP_UNLOCK(fdvp, 0);
VOP_UNLOCK(tdvp, 0);
if (error != EBUSY)
goto releout;
error = tmpfs_alloc_vp(mp, de->td_node, LK_EXCLUSIVE, &nvp);
if (error != 0)
goto releout;
VOP_UNLOCK(nvp, 0);
/*
* Concurrent rename race.
*/
if (nvp == tdvp) {
vrele(nvp);
error = EINVAL;
goto releout;
}
vrele(*fvpp);
*fvpp = nvp;
goto relock;
}
vrele(*fvpp);
*fvpp = nvp;
VOP_UNLOCK(*fvpp, 0);
/*
* Re-resolve tvp and acquire the vnode lock if present.
*/
de = tmpfs_dir_lookup(VP_TO_TMPFS_DIR(tdvp), NULL, tcnp);
/*
* If tvp disappeared we just carry on.
*/
if (de == NULL && *tvpp != NULL) {
vrele(*tvpp);
*tvpp = NULL;
}
/*
* Get the tvp ino if the lookup succeeded. We may have to restart
* if the non-blocking acquire fails.
*/
if (de != NULL) {
nvp = NULL;
error = tmpfs_alloc_vp(mp, de->td_node,
LK_EXCLUSIVE | LK_NOWAIT, &nvp);
if (*tvpp != NULL)
vrele(*tvpp);
*tvpp = nvp;
if (error != 0) {
VOP_UNLOCK(fdvp, 0);
//.........这里部分代码省略.........