Ejemplo n.º 1
0
void
pefs_dircache_beginupdate(struct pefs_dircache *pd, u_long gen)
{
	if (sx_try_upgrade(&pd->pd_lock) == 0) {
		/* vnode should be locked to avoid races */
		sx_unlock(&pd->pd_lock);
		sx_xlock(&pd->pd_lock);
	}
	if (gen != 0 && pd->pd_gen != gen) {
		PEFSDEBUG("pefs_dircache_beginupdate: update: gen=%lu %p\n",
		    gen, pd);
		if (!LIST_EMPTY(DIRCACHE_ACTIVEHEAD(pd))) {
			/* Assert consistent state */
			MPASS(LIST_EMPTY(DIRCACHE_STALEHEAD(pd)));
			dircache_expire(pd);
		}
		pd->pd_gen = gen;
		pd->pd_flags |= PD_UPDATING;
		MPASS(LIST_EMPTY(DIRCACHE_ACTIVEHEAD(pd)));
	}
}
Ejemplo n.º 2
0
/*
    struct vnop_rename_args {
	struct vnode *a_fdvp;
	struct vnode *a_fvp;
	struct componentname *a_fcnp;
	struct vnode *a_tdvp;
	struct vnode *a_tvp;
	struct componentname *a_tcnp;
    };
*/
static int
fuse_vnop_rename(struct vop_rename_args *ap)
{
	struct vnode *fdvp = ap->a_fdvp;
	struct vnode *fvp = ap->a_fvp;
	struct componentname *fcnp = ap->a_fcnp;
	struct vnode *tdvp = ap->a_tdvp;
	struct vnode *tvp = ap->a_tvp;
	struct componentname *tcnp = ap->a_tcnp;
	struct fuse_data *data;

	int err = 0;

	FS_DEBUG2G("from: inode=%ju name=%*s -> to: inode=%ju name=%*s\n",
	    (uintmax_t)VTOI(fvp), (int)fcnp->cn_namelen, fcnp->cn_nameptr,
	    (uintmax_t)(tvp == NULL ? -1 : VTOI(tvp)),
	    (int)tcnp->cn_namelen, tcnp->cn_nameptr);

	if (fuse_isdeadfs(fdvp)) {
		return ENXIO;
	}
	if (fvp->v_mount != tdvp->v_mount ||
	    (tvp && fvp->v_mount != tvp->v_mount)) {
		FS_DEBUG("cross-device rename: %s -> %s\n",
		    fcnp->cn_nameptr, (tcnp != NULL ? tcnp->cn_nameptr : "(NULL)"));
		err = EXDEV;
		goto out;
	}
	cache_purge(fvp);

	/*
         * FUSE library is expected to check if target directory is not
         * under the source directory in the file system tree.
         * Linux performs this check at VFS level.
         */
	data = fuse_get_mpdata(vnode_mount(tdvp));
	sx_xlock(&data->rename_lock);
	err = fuse_internal_rename(fdvp, fcnp, tdvp, tcnp);
	if (err == 0) {
		if (tdvp != fdvp)
			fuse_vnode_setparent(fvp, tdvp);
		if (tvp != NULL)
			fuse_vnode_setparent(tvp, NULL);
	}
	sx_unlock(&data->rename_lock);

	if (tvp != NULL && tvp != fvp) {
		cache_purge(tvp);
	}
	if (vnode_isdir(fvp)) {
		if ((tvp != NULL) && vnode_isdir(tvp)) {
			cache_purge(tdvp);
		}
		cache_purge(fdvp);
	}
out:
	if (tdvp == tvp) {
		vrele(tdvp);
	} else {
		vput(tdvp);
	}
	if (tvp != NULL) {
		vput(tvp);
	}
	vrele(fdvp);
	vrele(fvp);

	return err;
}
Ejemplo n.º 3
0
static int
linux_common_open(struct thread *td, int dirfd, char *path, int l_flags, int mode)
{
    struct proc *p = td->td_proc;
    struct file *fp;
    int fd;
    int bsd_flags, error;

    bsd_flags = 0;
    switch (l_flags & LINUX_O_ACCMODE) {
    case LINUX_O_WRONLY:
	bsd_flags |= O_WRONLY;
	break;
    case LINUX_O_RDWR:
	bsd_flags |= O_RDWR;
	break;
    default:
	bsd_flags |= O_RDONLY;
    }
    if (l_flags & LINUX_O_NDELAY)
	bsd_flags |= O_NONBLOCK;
    if (l_flags & LINUX_O_APPEND)
	bsd_flags |= O_APPEND;
    if (l_flags & LINUX_O_SYNC)
	bsd_flags |= O_FSYNC;
    if (l_flags & LINUX_O_NONBLOCK)
	bsd_flags |= O_NONBLOCK;
    if (l_flags & LINUX_FASYNC)
	bsd_flags |= O_ASYNC;
    if (l_flags & LINUX_O_CREAT)
	bsd_flags |= O_CREAT;
    if (l_flags & LINUX_O_TRUNC)
	bsd_flags |= O_TRUNC;
    if (l_flags & LINUX_O_EXCL)
	bsd_flags |= O_EXCL;
    if (l_flags & LINUX_O_NOCTTY)
	bsd_flags |= O_NOCTTY;
    if (l_flags & LINUX_O_DIRECT)
	bsd_flags |= O_DIRECT;
    if (l_flags & LINUX_O_NOFOLLOW)
	bsd_flags |= O_NOFOLLOW;
    if (l_flags & LINUX_O_DIRECTORY)
	bsd_flags |= O_DIRECTORY;
    /* XXX LINUX_O_NOATIME: unable to be easily implemented. */

    error = kern_openat(td, dirfd, path, UIO_SYSSPACE, bsd_flags, mode);

    if (!error) {
	    fd = td->td_retval[0];
	    /*
	     * XXX In between kern_open() and fget(), another process
	     * having the same filedesc could use that fd without
	     * checking below.
	     */
	    error = fget(td, fd, CAP_IOCTL, &fp);
	    if (!error) {
		    sx_slock(&proctree_lock);
		    PROC_LOCK(p);
		    if (!(bsd_flags & O_NOCTTY) &&
			SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
			    PROC_UNLOCK(p);
			    sx_unlock(&proctree_lock);
			    if (fp->f_type == DTYPE_VNODE)
				    (void) fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0,
					     td->td_ucred, td);
		    } else {
			    PROC_UNLOCK(p);
			    sx_sunlock(&proctree_lock);
		    }
		    fdrop(fp, td);
		    /*
		     * XXX as above, fdrop()/kern_close() pair is racy.
		     */
		    if (error)
			    kern_close(td, fd);
	    }
    }

#ifdef DEBUG
    if (ldebug(open))
	    printf(LMSG("open returns error %d"), error);
#endif
    LFREEPATH(path);
    return (error);
}