Ejemplo n.º 1
0
int
osi_UFSTruncate(struct osi_file *afile, afs_int32 asize)
{
    afs_ucred_t *oldCred;
    struct vattr tvattr;
    afs_int32 code;
    struct osi_stat tstat;
    AFS_STATCNT(osi_Truncate);

    /* This routine only shrinks files, and most systems
     * have very slow truncates, even when the file is already
     * small enough.  Check now and save some time.
     */
    code = afs_osi_Stat(afile, &tstat);
    if (code || tstat.size <= asize)
	return code;
    ObtainWriteLock(&afs_xosi, 321);
    tvattr.va_mask = AT_SIZE;
    tvattr.va_size = asize;
    /*
     * The only time a flag is used (ATTR_UTIME) is when we're changing the time 
     */
    AFS_GUNLOCK();
#ifdef AFS_SUN510_ENV
    code = VOP_SETATTR(afile->vnode, &tvattr, 0, afs_osi_credp, NULL);
#else
    code = VOP_SETATTR(afile->vnode, &tvattr, 0, afs_osi_credp);
#endif
    AFS_GLOCK();
    ReleaseWriteLock(&afs_xosi);
    return code;
}
Ejemplo n.º 2
0
int
osi_UFSTruncate(register struct osi_file *afile, afs_int32 asize)
{
    struct vattr tvattr;
    struct vnode *vp;
    register afs_int32 code, glocked;
    AFS_STATCNT(osi_Truncate);

    ObtainWriteLock(&afs_xosi, 321);
    vp = afile->vnode;
    /*
     * This routine only shrinks files, and most systems
     * have very slow truncates, even when the file is already
     * small enough.  Check now and save some time.
     */
    glocked = ISAFS_GLOCK();
    if (glocked)
      AFS_GUNLOCK();
#if defined(AFS_FBSD80_ENV)
    vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
    code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp);
#elif defined(AFS_FBSD50_ENV)
    vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread);
    code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, curthread);
#else
    vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc);
    code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, curproc);
#endif
    if (code != 0 || tvattr.va_size <= asize)
	goto out;

    VATTR_NULL(&tvattr);
    tvattr.va_size = asize;
#if defined(AFS_FBSD80_ENV)
    code = VOP_SETATTR(vp, &tvattr, afs_osi_credp);
#elif defined(AFS_FBSD50_ENV)
    code = VOP_SETATTR(vp, &tvattr, afs_osi_credp, curthread);
#else
    code = VOP_SETATTR(vp, &tvattr, afs_osi_credp, curproc);
#endif

out:
#if defined(AFS_FBSD80_ENV)
    VOP_UNLOCK(vp, 0);
#elif defined(AFS_FBSD50_ENV)
    VOP_UNLOCK(vp, LK_EXCLUSIVE, curthread);
#else
    VOP_UNLOCK(vp, LK_EXCLUSIVE, curproc);
#endif
    if (glocked)
      AFS_GLOCK();
    ReleaseWriteLock(&afs_xosi);
    return code;
}
Ejemplo n.º 3
0
/*
 * smb_vop_setattr()
 *
 * smb_fsop_setattr()/smb_vop_setattr() should always be used instead of
 * VOP_SETATTR() when calling from the CIFS service, due to special processing
 * for streams files.
 *
 * Streams have a size but otherwise do not have separate attributes from
 * the (unnamed stream) file, i.e., the security and ownership of the file
 * applies to the stream.  In contrast, extended attribute files, which are
 * used to implement streams, are independent objects with their own
 * attributes.
 *
 * For compatibility with streams, we set the size on the extended attribute
 * file and apply other attributes to the (unnamed stream) file.  The one
 * exception is that the UID and GID can be set on the stream by passing a
 * NULL unnamed_vp, which allows callers to synchronize stream ownership
 * with the (unnamed stream) file.
 */
int
smb_vop_setattr(vnode_t *vp, vnode_t *unnamed_vp, smb_attr_t *attr,
    int flags, cred_t *cr)
{
	int error = 0;
	int at_size = 0;
	vnode_t *use_vp;
	xvattr_t xvattr;
	vattr_t *vap;

	if (attr->sa_mask & SMB_AT_DOSATTR) {
		attr->sa_dosattr &=
		    (FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_READONLY |
		    FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM);
	}

	if (unnamed_vp) {
		use_vp = unnamed_vp;
		if (attr->sa_mask & SMB_AT_SIZE) {
			at_size = 1;
			attr->sa_mask &= ~SMB_AT_SIZE;
		}
	} else {
		use_vp = vp;
	}

	/*
	 * The caller should not be setting sa_vattr.va_mask,
	 * but rather sa_mask.
	 */

	attr->sa_vattr.va_mask = 0;

	if (vfs_has_feature(use_vp->v_vfsp, VFSFT_XVATTR)) {
		smb_vop_setup_xvattr(attr, &xvattr);
		vap = &xvattr.xva_vattr;
	} else {
		smb_sa_to_va_mask(attr->sa_mask,
		    &attr->sa_vattr.va_mask);
		vap = &attr->sa_vattr;
	}

	if ((error = VOP_SETATTR(use_vp, vap, flags, cr, &smb_ct)) != 0)
		return (error);

	if (at_size) {
		attr->sa_vattr.va_mask = AT_SIZE;
		error = VOP_SETATTR(vp, &attr->sa_vattr, flags, kcred, &smb_ct);
	}

	return (error);
}
Ejemplo n.º 4
0
STATIC int
linvfs_file_mmap(
	struct file	*filp,
	struct vm_area_struct *vma)
{
	struct inode	*ip = filp->f_dentry->d_inode;
	vnode_t		*vp = LINVFS_GET_VP(ip);
	vattr_t		va = { .va_mask = XFS_AT_UPDATIME };
	int		error;

	if (vp->v_vfsp->vfs_flag & VFS_DMI) {
		xfs_mount_t	*mp = XFS_VFSTOM(vp->v_vfsp);

		error = -XFS_SEND_MMAP(mp, vma, 0);
		if (error)
			return error;
	}

	vma->vm_ops = &linvfs_file_vm_ops;

	VOP_SETATTR(vp, &va, XFS_AT_UPDATIME, NULL, error);
	if (!error)
		vn_revalidate(vp);	/* update Linux inode flags */
	return 0;
}
Ejemplo n.º 5
0
int
osi_UFSTruncate(struct osi_file *afile, afs_int32 asize)
{
    struct vattr tvattr;
    afs_int32 code;
    struct osi_stat tstat;

    AFS_STATCNT(osi_Truncate);

    /*
     * This routine only shrinks files, and most systems
     * have very slow truncates, even when the file is already
     * small enough.  Check now and save some time.
     */
    code = afs_osi_Stat(afile, &tstat);
    if (code || tstat.size <= asize)
	return code;

    ObtainWriteLock(&afs_xosi, 321);
    VATTR_NULL(&tvattr);
    tvattr.va_size = asize;
    AFS_GUNLOCK();
    VOP_LOCK(afile->vnode, LK_EXCLUSIVE | LK_RETRY, curproc);
    code = VOP_SETATTR(afile->vnode, &tvattr, afs_osi_credp, curproc);
    VOP_UNLOCK(afile->vnode, 0, curproc);
    AFS_GLOCK();
    if (code == 0)
	afile->size = asize;
    ReleaseWriteLock(&afs_xosi);
    return code;
}
Ejemplo n.º 6
0
int
osi_UFSTruncate(struct osi_file *afile, afs_int32 asize)
{
    afs_ucred_t *oldCred;
    struct vattr tvattr;
    afs_int32 code;
    struct osi_stat tstat;
    AFS_STATCNT(osi_Truncate);

    /* This routine only shrinks files, and most systems
     * have very slow truncates, even when the file is already
     * small enough.  Check now and save some time.
     */
    code = afs_osi_Stat(afile, &tstat);
    if (code || tstat.size <= asize)
	return code;
    ObtainWriteLock(&afs_xosi, 321);
    VATTR_NULL(&tvattr);
    /* note that this credential swapping stuff is only necessary because
     * of ufs's references directly to u.u_cred instead of to
     * credentials parameter.  Probably should fix ufs some day. */
    oldCred = p_cred(u.u_procp);
    set_p_cred(u.u_procp, &afs_osi_cred);
    tvattr.va_size = asize;
    AFS_GUNLOCK();
    code = VOP_SETATTR(afile->vnode, &tvattr, &afs_osi_cred, 0);
    AFS_GLOCK();
    set_p_cred(u.u_procp, oldCred);	/* restore */
    ReleaseWriteLock(&afs_xosi);
    return code;
}
Ejemplo n.º 7
0
int
osi_UFSTruncate(struct osi_file *afile, afs_int32 asize)
{
    afs_ucred_t *oldCred;
    struct vattr tvattr;
    afs_int32 code;
    struct osi_stat tstat;
    AFS_STATCNT(osi_Truncate);

    /* This routine only shrinks files, and most systems
     * have very slow truncates, even when the file is already
     * small enough.  Check now and save some time.
     */
    code = afs_osi_Stat(afile, &tstat);
    if (code || tstat.size <= asize)
	return code;
    ObtainWriteLock(&afs_xosi, 321);
    AFS_GUNLOCK();
#ifdef AFS_DARWIN80_ENV
    VATTR_INIT(&tvattr);
    VATTR_SET(&tvattr, va_size, asize);
    code = vnode_setattr(afile->vnode, &tvattr, afs_osi_ctxtp);
#else
    VATTR_NULL(&tvattr);
    tvattr.va_size = asize;
    code = VOP_SETATTR(afile->vnode, &tvattr, &afs_osi_cred, current_proc());
#endif
    AFS_GLOCK();
    ReleaseWriteLock(&afs_xosi);
    return code;
}
Ejemplo n.º 8
0
/*ARGSUSED4*/
static int
auto_setattr(
	vnode_t *vp,
	struct vattr *vap,
	int flags,
	cred_t *cred,
	caller_context_t *ct)
{
	vnode_t *newvp;
	int error;

	AUTOFS_DPRINT((4, "auto_setattr vp %p\n", (void *)vp));

	if (error = auto_trigger_mount(vp, cred, &newvp))
		goto done;

	if (newvp != NULL) {
		/*
		 * Node is mounted on.
		 */
		if (vn_is_readonly(newvp))
			error = EROFS;
		else
			error = VOP_SETATTR(newvp, vap, flags, cred, ct);
		VN_RELE(newvp);
	} else
		error = ENOSYS;

done:
	AUTOFS_DPRINT((5, "auto_setattr: error=%d\n", error));
	return (error);
}
Ejemplo n.º 9
0
/*
 * Drops reference to the log file.
 */
void
cachefs_dlog_teardown(fscache_t *fscp)
{
	vattr_t va;
	/*LINTED: set but not used */
	int error;

	mutex_enter(&fscp->fs_dlock);

	/* clean up the log file */
	if (fscp->fs_dlogfile) {
		VN_RELE(fscp->fs_dlogfile);
		fscp->fs_dlogfile = NULL;
	}

	/* clean up the map file */
	if (fscp->fs_dmapfile) {
		/* set the map file to the actual size needed */
		va.va_mask = AT_SIZE;
		va.va_size = fscp->fs_dmapoff;
		error = VOP_SETATTR(fscp->fs_dmapfile, &va, 0, kcred, NULL);
#ifdef CFSDEBUG
		if (error) {
			cmn_err(CE_WARN, "cachefs: map setattr failed %d",
			    error);
		}
#endif
		VN_RELE(fscp->fs_dmapfile);
		fscp->fs_dmapfile = NULL;
	}
	mutex_exit(&fscp->fs_dlock);
}
Ejemplo n.º 10
0
Archivo: chmod.c Proyecto: akat1/impala
int
sc_chmod(thread_t *t, syscall_result_t *r, chmod_args_t *args)
{
    int res=0;
    proc_t *p = t->thr_proc;
    vnode_t *node;
    char pname[PATH_MAX];
    if((res = copyinstr(pname, args->fname, PATH_MAX)))
        return res;

    res = vfs_lookup(p->p_curdir, &node, pname, t, LKP_NORMAL);
    if(res)
        return res;
    vattr_t va;
    va.va_mask=VATTR_ALL;
    if((res = VOP_GETATTR(node, &va)))
        goto err;
    res = -EPERM;
    if(p->p_cred->p_euid != 0 && p->p_cred->p_euid != va.va_uid)
        goto err;
    mode_t mode = args->mode & 07777;
    if(ISSET(mode, S_ISGID) && p->p_cred->p_euid!=0 
        && va.va_gid!=p->p_cred->p_egid)
        UNSET(mode, S_ISGID); //mamy prawo kasować bit suid/sgid?
    va.va_mask = VATTR_MODE;
    va.va_mode = mode;
    if((res = VOP_SETATTR(node, &va)))
        goto err;
    vrele(node);    
    return 0;
err:
    vrele(node);
    return res;
}
Ejemplo n.º 11
0
static int
zfs_replay_setattr(zfsvfs_t *zfsvfs, lr_setattr_t *lr, boolean_t byteswap)
{
	znode_t *zp;
	xvattr_t xva;
	vattr_t *vap = &xva.xva_vattr;
	int error;
	void *start;

	xva_init(&xva);
	if (byteswap) {
		byteswap_uint64_array(lr, sizeof (*lr));

		if ((lr->lr_mask & AT_XVATTR) &&
		    zfsvfs->z_version >= ZPL_VERSION_INITIAL)
			zfs_replay_swap_attrs((lr_attr_t *)(lr + 1));
	}

	if ((error = zfs_zget(zfsvfs, lr->lr_foid, &zp)) != 0) {
		/*
		 * As we can log setattrs out of order, it's possible the
		 * file has been removed. In this case just drop the setattr
		 * and return success.
		 */
		if (error == ENOENT)
			error = 0;
		return (error);
	}

	zfs_init_vattr(vap, lr->lr_mask, lr->lr_mode,
	    lr->lr_uid, lr->lr_gid, 0, lr->lr_foid);

	vap->va_size = lr->lr_size;
	ZFS_TIME_DECODE(&vap->va_atime, lr->lr_atime);
	ZFS_TIME_DECODE(&vap->va_mtime, lr->lr_mtime);

	/*
	 * Fill in xvattr_t portions if necessary.
	 */

	start = (lr_setattr_t *)(lr + 1);
	if (vap->va_mask & AT_XVATTR) {
		zfs_replay_xvattr((lr_attr_t *)start, &xva);
		start = (caddr_t)start +
		    ZIL_XVAT_SIZE(((lr_attr_t *)start)->lr_attr_masksize);
	} else
		xva.xva_vattr.va_mask &= ~AT_XVATTR;

	zfsvfs->z_fuid_replay = zfs_replay_fuid_domain(start, &start,
	    lr->lr_uid, lr->lr_gid);

	error = VOP_SETATTR(ZTOV(zp), vap, 0, kcred, NULL);

	zfs_fuid_info_free(zfsvfs->z_fuid_replay);
	zfsvfs->z_fuid_replay = NULL;
	VN_RELE(ZTOV(zp));

	return (error);
}
STATIC int
linvfs_setattr(
	struct dentry	*dentry,
	struct iattr	*attr)
{
	struct inode	*inode = dentry->d_inode;
	unsigned int	ia_valid = attr->ia_valid;
	vnode_t		*vp = LINVFS_GET_VP(inode);
	vattr_t		vattr;
	int		flags = 0;
	int		error;

	memset(&vattr, 0, sizeof(vattr_t));
	if (ia_valid & ATTR_UID) {
		vattr.va_mask |= XFS_AT_UID;
		vattr.va_uid = attr->ia_uid;
	}
	if (ia_valid & ATTR_GID) {
		vattr.va_mask |= XFS_AT_GID;
		vattr.va_gid = attr->ia_gid;
	}
	if (ia_valid & ATTR_SIZE) {
		vattr.va_mask |= XFS_AT_SIZE;
		vattr.va_size = attr->ia_size;
	}
	if (ia_valid & ATTR_ATIME) {
		vattr.va_mask |= XFS_AT_ATIME;
		vattr.va_atime = attr->ia_atime;
		inode->i_atime = attr->ia_atime;
	}
	if (ia_valid & ATTR_MTIME) {
		vattr.va_mask |= XFS_AT_MTIME;
		vattr.va_mtime = attr->ia_mtime;
	}
	if (ia_valid & ATTR_CTIME) {
		vattr.va_mask |= XFS_AT_CTIME;
		vattr.va_ctime = attr->ia_ctime;
	}
	if (ia_valid & ATTR_MODE) {
		vattr.va_mask |= XFS_AT_MODE;
		vattr.va_mode = attr->ia_mode;
		if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
			inode->i_mode &= ~S_ISGID;
	}

	if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET))
		flags |= ATTR_UTIME;
#ifdef ATTR_NO_BLOCK
	if ((ia_valid & ATTR_NO_BLOCK))
		flags |= ATTR_NONBLOCK;
#endif

	VOP_SETATTR(vp, &vattr, flags, NULL, error);
	if (error)
		return -error;
	vn_revalidate(vp);
	return error;
}
Ejemplo n.º 13
0
/*
 * Set up the correct mode on the file based on the supplied ACL.  This
 * makes sure that the mode on the file reflects the state of the
 * u::,g::[m::], and o:: entries in the ACL.  Since the mode is where
 * the ACL is going to get the permissions for these entries, we must
 * synchronize the mode whenever we set the ACL on a file.
 */
STATIC int
xfs_acl_setmode(
	vnode_t		*vp,
	xfs_acl_t	*acl,
	int		*basicperms)
{
	vattr_t		va;
	xfs_acl_entry_t	*ap;
	xfs_acl_entry_t	*gap = NULL;
	int		i, error, nomask = 1;

	*basicperms = 1;

	if (acl->acl_cnt == XFS_ACL_NOT_PRESENT)
		return 0;

	/*
	 * Copy the u::, g::, o::, and m:: bits from the ACL into the
	 * mode.  The m:: bits take precedence over the g:: bits.
	 */
	va.va_mask = XFS_AT_MODE;
	VOP_GETATTR(vp, &va, 0, sys_cred, error);
	if (error)
		return error;

	va.va_mask = XFS_AT_MODE;
	va.va_mode &= ~(S_IRWXU|S_IRWXG|S_IRWXO);
	ap = acl->acl_entry;
	for (i = 0; i < acl->acl_cnt; ++i) {
		switch (ap->ae_tag) {
		case ACL_USER_OBJ:
			va.va_mode |= ap->ae_perm << 6;
			break;
		case ACL_GROUP_OBJ:
			gap = ap;
			break;
		case ACL_MASK:	/* more than just standard modes */
			nomask = 0;
			va.va_mode |= ap->ae_perm << 3;
			*basicperms = 0;
			break;
		case ACL_OTHER:
			va.va_mode |= ap->ae_perm;
			break;
		default:	/* more than just standard modes */
			*basicperms = 0;
			break;
		}
		ap++;
	}

	/* Set the group bits from ACL_GROUP_OBJ if there's no ACL_MASK */
	if (gap && nomask)
		va.va_mode |= gap->ae_perm << 3;

	VOP_SETATTR(vp, &va, 0, sys_cred, error);
	return error;
}
Ejemplo n.º 14
0
static int
zfs_replay_setattr(void *arg1, void *arg2, boolean_t byteswap)
{
	zfsvfs_t *zfsvfs = arg1;
	lr_setattr_t *lr = arg2;
	znode_t *zp;
	xvattr_t xva;
	vattr_t *vap = &xva.xva_vattr;
	vnode_t *vp;
	int error;
	void *start;

	xva_init(&xva);
	if (byteswap) {
		byteswap_uint64_array(lr, sizeof (*lr));

		if ((lr->lr_mask & AT_XVATTR) &&
		    zfsvfs->z_version >= ZPL_VERSION_INITIAL)
			zfs_replay_swap_attrs((lr_attr_t *)(lr + 1));
	}

	if ((error = zfs_zget(zfsvfs, lr->lr_foid, &zp)) != 0)
		return (error);

	zfs_init_vattr(vap, lr->lr_mask, lr->lr_mode,
	    lr->lr_uid, lr->lr_gid, 0, lr->lr_foid);

	vap->va_size = lr->lr_size;
	ZFS_TIME_DECODE(&vap->va_atime, lr->lr_atime);
	ZFS_TIME_DECODE(&vap->va_mtime, lr->lr_mtime);

	/*
	 * Fill in xvattr_t portions if necessary.
	 */

	start = (lr_setattr_t *)(lr + 1);
	if (vap->va_mask & AT_XVATTR) {
		zfs_replay_xvattr((lr_attr_t *)start, &xva);
		start = (caddr_t)start +
		    ZIL_XVAT_SIZE(((lr_attr_t *)start)->lr_attr_masksize);
	} else
		xva.xva_vattr.va_mask &= ~AT_XVATTR;

	zfsvfs->z_fuid_replay = zfs_replay_fuid_domain(start, &start,
	    lr->lr_uid, lr->lr_gid);

	vp = ZTOV(zp);
	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
	error = VOP_SETATTR(vp, vap, kcred);
	VOP_UNLOCK(vp, 0);

	zfs_fuid_info_free(zfsvfs->z_fuid_replay);
	zfsvfs->z_fuid_replay = NULL;
	VN_RELE(vp);

	return (error);
}
Ejemplo n.º 15
0
/*
 * exacct_vn_write() is a vn_rdwr wrapper that protects us from corrupting the
 * accounting file in case of an I/O or filesystem error.  acctctl() prevents
 * the two accounting vnodes from being equal, and the appropriate ac_lock is
 * held across the call, so we're single threaded through this code for each
 * file.
 */
static int
exacct_vn_write(ac_info_t *info, void *buf, ssize_t bufsize)
{
	int error = 0;
	ssize_t resid;
	struct vattr va;

	if (info == NULL)
		return (0);

	mutex_enter(&info->ac_lock);

	/*
	 * Don't do anything unless accounting file is set.
	 */
	if (info->ac_vnode == NULL) {
		mutex_exit(&info->ac_lock);
		return (0);
	}

	/*
	 * Save the size. If vn_rdwr fails, reset the size to avoid corrupting
	 * the present accounting file.
	 */
	va.va_mask = AT_SIZE;
	error = VOP_GETATTR(info->ac_vnode, &va, 0, kcred, NULL);
	if (error == 0) {
		error = vn_rdwr(UIO_WRITE, info->ac_vnode, (caddr_t)buf,
		    bufsize, 0LL, UIO_SYSSPACE, FAPPEND, (rlim64_t)MAXOFFSET_T,
		    kcred, &resid);
		if (error) {
			(void) VOP_SETATTR(info->ac_vnode, &va, 0, kcred, NULL);
		} else if (resid != 0) {
			(void) VOP_SETATTR(info->ac_vnode, &va, 0, kcred, NULL);
			error = ENOSPC;
		}
	}
	mutex_exit(&info->ac_lock);

	return (error);
}
Ejemplo n.º 16
0
int
RUMP_VOP_SETATTR(struct vnode *vp,
    struct vattr *vap,
    struct kauth_cred *cred)
{
	int error;

	rump_schedule();
	error = VOP_SETATTR(vp, vap, cred);
	rump_unschedule();

	return error;
}
Ejemplo n.º 17
0
static int
fdesc_setattr(struct vop_setattr_args *ap)
{
	struct vattr *vap = ap->a_vap;
	struct vnode *vp;
	struct mount *mp;
	struct file *fp;
	struct thread *td = curthread;
	cap_rights_t rights;
	unsigned fd;
	int error;

	/*
	 * Can't mess with the root vnode
	 */
	if (VTOFDESC(ap->a_vp)->fd_type == Froot)
		return (EACCES);

	fd = VTOFDESC(ap->a_vp)->fd_fd;

	/*
	 * Allow setattr where there is an underlying vnode.
	 */
	error = getvnode(td, fd,
	    cap_rights_init(&rights, CAP_EXTATTR_SET), &fp);
	if (error) {
		/*
		 * getvnode() returns EINVAL if the file descriptor is not
		 * backed by a vnode.  Silently drop all changes except
		 * chflags(2) in this case.
		 */
		if (error == EINVAL) {
			if (vap->va_flags != VNOVAL)
				error = EOPNOTSUPP;
			else
				error = 0;
		}
		return (error);
	}
	vp = fp->f_vnode;
	if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) == 0) {
		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
		error = VOP_SETATTR(vp, ap->a_vap, ap->a_cred);
		VOP_UNLOCK(vp, 0);
		vn_finished_write(mp);
	}
	fdrop(fp, td);
	return (error);
}
Ejemplo n.º 18
0
int
spec_setattr(void *v)
{
	struct vop_getattr_args	*ap = v;
	struct vnode		*vp = ap->a_vp;
	int			 error;

	if (!(vp->v_flag & VCLONE))
		return (EBADF);

	vn_lock(vp->v_specparent, LK_EXCLUSIVE|LK_RETRY, curproc);
	error = VOP_SETATTR(vp->v_specparent, ap->a_vap, ap->a_cred);
	VOP_UNLOCK(vp, 0);

	return (error);
}
Ejemplo n.º 19
0
/*
 * union_setattr(struct vnode *a_vp, struct vattr *a_vap,
 *		 struct ucred *a_cred, struct thread *a_td)
 */
static int
union_setattr(struct vop_setattr_args *ap)
{
	struct union_node *un = VTOUNION(ap->a_vp);
	struct thread *td = ap->a_td;
	struct vattr *vap = ap->a_vap;
	struct vnode *uppervp;
	int error;

	/*
	 * Disallow write attempts on filesystems mounted read-only.
	 */
	if ((ap->a_vp->v_mount->mnt_flag & MNT_RDONLY) &&
	    (vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL ||
	     vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL ||
	     vap->va_mtime.tv_sec != VNOVAL || 
	     vap->va_mode != (mode_t)VNOVAL)) {
		return (EROFS);
	}

	/*
	 * Handle case of truncating lower object to zero size,
	 * by creating a zero length upper object.  This is to
	 * handle the case of open with O_TRUNC and O_CREAT.
	 */
	if (un->un_uppervp == NULLVP && (un->un_lowervp->v_type == VREG)) {
		error = union_copyup(un, (ap->a_vap->va_size != 0),
			    ap->a_cred, ap->a_td);
		if (error)
			return (error);
	}

	/*
	 * Try to set attributes in upper layer,
	 * otherwise return read-only filesystem error.
	 */
	error = EROFS;
	if ((uppervp = union_lock_upper(un, td)) != NULLVP) {
		error = VOP_SETATTR(un->un_uppervp, ap->a_vap, ap->a_cred);
		if ((error == 0) && (ap->a_vap->va_size != VNOVAL))
			union_newsize(ap->a_vp, ap->a_vap->va_size, VNOVAL);
		union_unlock_upper(uppervp, td);
	}
	return (error);
}
Ejemplo n.º 20
0
/*
 * Hacked up version of vn_open. We _only_ handle ptys and only open
 * them with FREAD|FWRITE and never deal with creat or stuff like that.
 *
 * We need it because we have to fake up root credentials to open the pty.
 */
static int
ptm_vn_open(struct nameidata *ndp)
{
	struct proc *p = ndp->ni_cnd.cn_proc;
	struct ucred *cred;
	struct vattr vattr;
	struct vnode *vp;
	int error;

	if ((error = namei(ndp)) != 0)
		return (error);
	vp = ndp->ni_vp;
	if (vp->v_type != VCHR) {
		error = EINVAL;
		goto bad;
	}

	/*
	 * Get us a fresh cred with root privileges.
	 */
	cred = crget();
	error = VOP_OPEN(vp, FREAD|FWRITE, cred, p);
	if (!error) {
		/* update atime/mtime */
		VATTR_NULL(&vattr);
		getnanotime(&vattr.va_atime);
		vattr.va_mtime = vattr.va_atime;
		vattr.va_vaflags |= VA_UTIMES_NULL;
		(void)VOP_SETATTR(vp, &vattr, p->p_ucred, p);
	}
	crfree(cred);

	if (error)
		goto bad;

	vp->v_writecount++;

	return (0);
bad:
	vput(vp);
	return (error);
}
Ejemplo n.º 21
0
int
pty_grant_slave(struct lwp *l, dev_t dev, struct mount *mp)
{
	int error;
	struct vnode *vp;

	/*
	 * Open the slave.
	 * namei -> setattr -> unlock -> revoke -> vrele ->
	 * namei -> open -> unlock
	 * Three stage rocket:
	 * 1. Change the owner and permissions on the slave.
	 * 2. Revoke all the users of the slave.
	 * 3. open the slave.
	 */
	if (ptm == NULL)
		return EOPNOTSUPP;
	if ((error = (*ptm->allocvp)(mp, l, &vp, dev, 't')) != 0)
		return error;

	if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
		struct vattr vattr;
		(*ptm->getvattr)(mp, l, &vattr);
		/* Do the VOP_SETATTR() as root. */
		error = VOP_SETATTR(vp, &vattr, lwp0.l_cred);
		if (error) {
			DPRINTF(("setattr %d\n", error));
			VOP_UNLOCK(vp);
			vrele(vp);
			return error;
		}
	}
	VOP_UNLOCK(vp);
	VOP_REVOKE(vp, REVOKEALL);

	/*
	 * The vnode is useless after the revoke, we need to get it again.
	 */
	vrele(vp);
	return 0;
}
Ejemplo n.º 22
0
static int
xattr_dir_setattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
    caller_context_t *ct)
{
	vnode_t *realvp;
	int error;

	/*
	 * If there is a real xattr directory, do the setattr there.
	 * Otherwise, just return success.  The GFS directory is transient,
	 * and any setattr changes can disappear anyway.
	 */
	error = xattr_dir_realdir(vp, &realvp, LOOKUP_XATTR, cr, ct);
	if (error == 0) {
		error = VOP_SETATTR(realvp, vap, flags, cr, ct);
	}
	if (error == ENOENT) {
		error = 0;
	}
	return (error);
}
Ejemplo n.º 23
0
int linvfs_generic_file_mmap(struct file *filp, struct vm_area_struct *vma)
{
	vnode_t	*vp;
	int	ret;

	/* this will return a (-) error so flip */
	ret = -generic_file_mmap(filp, vma);
	if (!ret) {
		vattr_t va, *vap;

		vap = &va;
		vap->va_mask = AT_UPDATIME;

		vp = LINVFS_GET_VP(filp->f_dentry->d_inode);

		ASSERT(vp);

		VOP_SETATTR(vp, vap, AT_UPDATIME, NULL, ret);
	}
	return(-ret);
}
Ejemplo n.º 24
0
static int
xattr_copy(vnode_t *sdvp, char *snm, vnode_t *tdvp, char *tnm,
    cred_t *cr, caller_context_t *ct)
{
	xvattr_t xvattr;
	vnode_t *pdvp;
	int error;

	/*
	 * Only copy system attrs if the views are the same
	 */
	if (strcmp(snm, tnm) != 0)
		return (EINVAL);

	xva_init(&xvattr);

	XVA_SET_REQ(&xvattr, XAT_SYSTEM);
	XVA_SET_REQ(&xvattr, XAT_READONLY);
	XVA_SET_REQ(&xvattr, XAT_HIDDEN);
	XVA_SET_REQ(&xvattr, XAT_ARCHIVE);
	XVA_SET_REQ(&xvattr, XAT_APPENDONLY);
	XVA_SET_REQ(&xvattr, XAT_NOUNLINK);
	XVA_SET_REQ(&xvattr, XAT_IMMUTABLE);
	XVA_SET_REQ(&xvattr, XAT_NODUMP);
	XVA_SET_REQ(&xvattr, XAT_AV_MODIFIED);
	XVA_SET_REQ(&xvattr, XAT_AV_QUARANTINED);
	XVA_SET_REQ(&xvattr, XAT_CREATETIME);
	XVA_SET_REQ(&xvattr, XAT_REPARSE);
	XVA_SET_REQ(&xvattr, XAT_OFFLINE);
	XVA_SET_REQ(&xvattr, XAT_SPARSE);

	pdvp = gfs_file_parent(sdvp);
	error = VOP_GETATTR(pdvp, &xvattr.xva_vattr, 0, cr, ct);
	if (error)
		return (error);

	pdvp = gfs_file_parent(tdvp);
	error = VOP_SETATTR(pdvp, &xvattr.xva_vattr, 0, cr, ct);
	return (error);
}
Ejemplo n.º 25
0
static int
unionfs_setattr(void *v)
{
	struct vop_setattr_args *ap = v;
	int		error;
	struct unionfs_node *unp;
	struct vnode   *uvp;
	struct vnode   *lvp;
	struct vattr   *vap;

	UNIONFS_INTERNAL_DEBUG("unionfs_setattr: enter\n");

	error = EROFS;
	unp = VTOUNIONFS(ap->a_vp);
	uvp = unp->un_uppervp;
	lvp = unp->un_lowervp;
	vap = ap->a_vap;

	if ((ap->a_vp->v_mount->mnt_flag & MNT_RDONLY) &&
	    (vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL ||
	     vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL ||
	     vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL))
		return (EROFS);

	if (uvp == NULLVP && lvp->v_type == VREG) {
		error = unionfs_copyfile(unp, (vap->va_size != 0),
		    ap->a_cred);
		if (error != 0)
			return (error);
		uvp = unp->un_uppervp;
	}

	if (uvp != NULLVP)
		error = VOP_SETATTR(uvp, vap, ap->a_cred);

	UNIONFS_INTERNAL_DEBUG("unionfs_setattr: leave (%d)\n", error);

	return (error);
}
Ejemplo n.º 26
0
Archivo: chown.c Proyecto: akat1/impala
int
sc_chown(thread_t *t, syscall_result_t *r, chown_args_t *args)
{
   int res=0;
    proc_t *p = t->thr_proc;
    vnode_t *node;
    char pname[PATH_MAX];
    if((res = copyinstr(pname, args->fname, PATH_MAX)))
        return res;

    res = vfs_lookup(p->p_curdir, &node, pname, t, LKP_NORMAL);
    if(res)
        return res;
    vattr_t va;
    va.va_mask=VATTR_ALL;
    if((res = VOP_GETATTR(node, &va)))
        goto err;
    res = -EPERM;
    if(p->p_cred->p_euid != 0 && p->p_cred->p_euid != va.va_uid)
        goto err;
    if(p->p_cred->p_euid != 0)  //tak... póki co nie ma zmian dla nie roota
        goto err;
    va.va_mask = VATTR_UID | VATTR_GID | VATTR_MODE;
    if(args->uid!=-1)
        va.va_uid = args->uid;
    if(args->gid!=-1)
        va.va_gid = args->gid;
    if(p->p_cred->p_euid!=0)   //tymczasowo niemożliwe
        UNSET(va.va_mode, S_ISUID | S_ISGID);
    if((res = VOP_SETATTR(node, &va)))
        goto err;
    vrele(node);    
    return 0;
err:
    vrele(node);
    return res;
}
Ejemplo n.º 27
0
STATIC int
xfs_file_mmap(
	struct file	*filp,
	struct vm_area_struct *vma)
{
	struct inode	*ip = filp->f_dentry->d_inode;
	vnode_t		*vp = vn_from_inode(ip);
	vattr_t		vattr;
	int		error;

	vma->vm_ops = &xfs_file_vm_ops;

#ifdef CONFIG_XFS_DMAPI
	if (vp->v_vfsp->vfs_flag & VFS_DMI) {
		vma->vm_ops = &xfs_dmapi_file_vm_ops;
	}
#endif /* CONFIG_XFS_DMAPI */

	vattr.va_mask = XFS_AT_UPDATIME;
	VOP_SETATTR(vp, &vattr, XFS_AT_UPDATIME, NULL, error);
	if (likely(!error))
		__vn_revalidate(vp, &vattr);	/* update flags */
	return 0;
}
Ejemplo n.º 28
0
/*
 * Common code for vnode open operations.
 * Check permissions, and call the VOP_OPEN or VOP_CREATE routine.
 */
int
vn_open(struct nameidata *ndp, int fmode, int cmode)
{
	struct vnode *vp;
	struct proc *p = ndp->ni_cnd.cn_proc;
	struct ucred *cred = p->p_ucred;
	struct vattr va;
	int error;

	if ((fmode & (FREAD|FWRITE)) == 0)
		return (EINVAL);
	if ((fmode & (O_TRUNC | FWRITE)) == O_TRUNC)
		return (EINVAL);
	if (fmode & O_CREAT) {
		ndp->ni_cnd.cn_nameiop = CREATE;
		ndp->ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF;
		if ((fmode & O_EXCL) == 0 && (fmode & O_NOFOLLOW) == 0)
			ndp->ni_cnd.cn_flags |= FOLLOW;
		if ((error = namei(ndp)) != 0)
			return (error);

		if (ndp->ni_vp == NULL) {
			VATTR_NULL(&va);
			va.va_type = VREG;
			va.va_mode = cmode;
			error = VOP_CREATE(ndp->ni_dvp, &ndp->ni_vp,
					   &ndp->ni_cnd, &va);
			if (error)
				return (error);
			fmode &= ~O_TRUNC;
			vp = ndp->ni_vp;
		} else {
			VOP_ABORTOP(ndp->ni_dvp, &ndp->ni_cnd);
			if (ndp->ni_dvp == ndp->ni_vp)
				vrele(ndp->ni_dvp);
			else
				vput(ndp->ni_dvp);
			ndp->ni_dvp = NULL;
			vp = ndp->ni_vp;
			if (fmode & O_EXCL) {
				error = EEXIST;
				goto bad;
			}
			fmode &= ~O_CREAT;
		}
	} else {
		ndp->ni_cnd.cn_nameiop = LOOKUP;
		ndp->ni_cnd.cn_flags =
		    ((fmode & O_NOFOLLOW) ? NOFOLLOW : FOLLOW) | LOCKLEAF;
		if ((error = namei(ndp)) != 0)
			return (error);
		vp = ndp->ni_vp;
	}
	if (vp->v_type == VSOCK) {
		error = EOPNOTSUPP;
		goto bad;
	}
	if (vp->v_type == VLNK) {
		error = EMLINK;
		goto bad;
	}
	if ((fmode & O_CREAT) == 0) {
		if (fmode & FREAD) {
			if ((error = VOP_ACCESS(vp, VREAD, cred, p)) != 0)
				goto bad;
		}
		if (fmode & FWRITE) {
			if (vp->v_type == VDIR) {
				error = EISDIR;
				goto bad;
			}
			if ((error = vn_writechk(vp)) != 0 ||
			    (error = VOP_ACCESS(vp, VWRITE, cred, p)) != 0)
				goto bad;
		}
	}
	if ((fmode & O_TRUNC) && vp->v_type == VREG) {
		VATTR_NULL(&va);
		va.va_size = 0;
		if ((error = VOP_SETATTR(vp, &va, cred, p)) != 0)
			goto bad;
	}
	if ((error = VOP_OPEN(vp, fmode, cred, p)) != 0)
		goto bad;

	if (vp->v_flag & VCLONED) {
		struct cloneinfo *cip = (struct cloneinfo *) vp->v_data;

		vp->v_flag &= ~VCLONED;
		ndp->ni_vp = cip->ci_vp; /* return cloned vnode */
		vp->v_data = cip->ci_data; /* restore v_data */
		VOP_UNLOCK(vp, 0, p); /* keep a reference */
		vp = ndp->ni_vp; /* for the increment below */

		free(cip, M_TEMP);
	}

	if (fmode & FWRITE)
		vp->v_writecount++;
	return (0);
bad:
	vput(vp);
	return (error);
}
Ejemplo n.º 29
0
STATIC int
xfs_ioc_xattr(
	vnode_t			*vp,
	xfs_inode_t		*ip,
	struct file		*filp,
	unsigned int		cmd,
	unsigned long		arg)
{
	struct fsxattr		fa;
	vattr_t			va;
	int			error;
	int			attr_flags;
	unsigned int		flags;

	switch (cmd) {
	case XFS_IOC_FSGETXATTR: {
		va.va_mask = XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_NEXTENTS;
		VOP_GETATTR(vp, &va, 0, NULL, error);
		if (error)
			return -error;

		fa.fsx_xflags	= va.va_xflags;
		fa.fsx_extsize	= va.va_extsize;
		fa.fsx_nextents = va.va_nextents;

		if (copy_to_user((struct fsxattr *)arg, &fa, sizeof(fa)))
			return -XFS_ERROR(EFAULT);
		return 0;
	}

	case XFS_IOC_FSSETXATTR: {
		if (copy_from_user(&fa, (struct fsxattr *)arg, sizeof(fa)))
			return -XFS_ERROR(EFAULT);

		attr_flags = 0;
		if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
			attr_flags |= ATTR_NONBLOCK;

		va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE;
		va.va_xflags  = fa.fsx_xflags;
		va.va_extsize = fa.fsx_extsize;

		VOP_SETATTR(vp, &va, attr_flags, NULL, error);
		if (!error)
			vn_revalidate(vp);	/* update Linux inode flags */
		return -error;
	}

	case XFS_IOC_FSGETXATTRA: {
		va.va_mask = XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_ANEXTENTS;
		VOP_GETATTR(vp, &va, 0, NULL, error);
		if (error)
			return -error;

		fa.fsx_xflags	= va.va_xflags;
		fa.fsx_extsize	= va.va_extsize;
		fa.fsx_nextents = va.va_anextents;

		if (copy_to_user((struct fsxattr *)arg, &fa, sizeof(fa)))
			return -XFS_ERROR(EFAULT);
		return 0;
	}

	case XFS_IOC_GETXFLAGS: {
		flags = xfs_di2lxflags(ip->i_d.di_flags);
		if (copy_to_user((unsigned int *)arg, &flags, sizeof(flags)))
			return -XFS_ERROR(EFAULT);
		return 0;
	}

	case XFS_IOC_SETXFLAGS: {
		if (copy_from_user(&flags, (unsigned int *)arg, sizeof(flags)))
			return -XFS_ERROR(EFAULT);

		if (flags & ~(LINUX_XFLAG_IMMUTABLE | LINUX_XFLAG_APPEND | \
			      LINUX_XFLAG_NOATIME | LINUX_XFLAG_NODUMP | \
			      LINUX_XFLAG_SYNC))
			return -XFS_ERROR(EOPNOTSUPP);

		attr_flags = 0;
		if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
			attr_flags |= ATTR_NONBLOCK;

		va.va_mask = XFS_AT_XFLAGS;
		va.va_xflags = xfs_merge_ioc_xflags(flags,
				xfs_dic2xflags(&ip->i_d, ARCH_NOCONVERT));

		VOP_SETATTR(vp, &va, attr_flags, NULL, error);
		if (!error)
			vn_revalidate(vp);	/* update Linux inode flags */
		return -error;
	}

	case XFS_IOC_GETVERSION: {
		flags = LINVFS_GET_IP(vp)->i_generation;
		if (copy_to_user((unsigned int *)arg, &flags, sizeof(flags)))
			return -XFS_ERROR(EFAULT);
		return 0;
	}

	default:
		return -ENOTTY;
	}
}
Ejemplo n.º 30
0
int
ptmioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
{
	dev_t newdev, error;
	struct pt_softc * pti;
	struct nameidata cnd, snd;
	struct filedesc *fdp = p->p_fd;
	struct file *cfp = NULL, *sfp = NULL;
	int cindx, sindx;
	uid_t uid;
	gid_t gid;
	struct vattr vattr;
	struct ucred *cred;
	struct ptmget *ptm = (struct ptmget *)data;

	error = 0;
	switch (cmd) {
	case PTMGET:
		fdplock(fdp);
		/* Grab two filedescriptors. */
		if ((error = falloc(p, &cfp, &cindx)) != 0) {
			fdpunlock(fdp);
			break;
		}
		if ((error = falloc(p, &sfp, &sindx)) != 0) {
			fdremove(fdp, cindx);
			closef(cfp, p);
			fdpunlock(fdp);
			break;
		}

retry:
		/* Find and open a free master pty. */
		newdev = pty_getfree();
		if ((error = check_pty(minor(newdev))))
			goto bad;
		pti = pt_softc[minor(newdev)];
		NDINIT(&cnd, LOOKUP, NOFOLLOW|LOCKLEAF, UIO_SYSSPACE,
		    pti->pty_pn, p);
		if ((error = ptm_vn_open(&cnd)) != 0) {
			/*
			 * Check if the master open failed because we lost
			 * the race to grab it.
			 */
			if (error == EIO && !pty_isfree(minor(newdev)))
				goto retry;
			goto bad;
		}
		cfp->f_flag = FREAD|FWRITE;
		cfp->f_type = DTYPE_VNODE;
		cfp->f_ops = &vnops;
		cfp->f_data = (caddr_t) cnd.ni_vp;
		VOP_UNLOCK(cnd.ni_vp, 0, p);

		/*
		 * Open the slave.
		 * namei -> setattr -> unlock -> revoke -> vrele ->
		 * namei -> open -> unlock
		 * Three stage rocket:
		 * 1. Change the owner and permissions on the slave.
		 * 2. Revoke all the users of the slave.
		 * 3. open the slave.
		 */
		NDINIT(&snd, LOOKUP, NOFOLLOW|LOCKLEAF, UIO_SYSSPACE,
		    pti->pty_sn, p);
		if ((error = namei(&snd)) != 0)
			goto bad;
		if ((snd.ni_vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
			gid = tty_gid;
			/* get real uid */
			uid = p->p_cred->p_ruid;

			VATTR_NULL(&vattr);
			vattr.va_uid = uid;
			vattr.va_gid = gid;
			vattr.va_mode = (S_IRUSR|S_IWUSR|S_IWGRP) & ALLPERMS;
			/* Get a fake cred to pretend we're root. */
			cred = crget();
			error = VOP_SETATTR(snd.ni_vp, &vattr, cred, p);
			crfree(cred);
			if (error) {
				vput(snd.ni_vp);
				goto bad;
			}
		}
		VOP_UNLOCK(snd.ni_vp, 0, p);
		if (snd.ni_vp->v_usecount > 1 ||
		    (snd.ni_vp->v_flag & (VALIASED)))
			VOP_REVOKE(snd.ni_vp, REVOKEALL);

		/*
		 * The vnode is useless after the revoke, we need to
		 * namei again.
		 */
		vrele(snd.ni_vp);

		NDINIT(&snd, LOOKUP, NOFOLLOW|LOCKLEAF, UIO_SYSSPACE,
		    pti->pty_sn, p);
		/* now open it */
		if ((error = ptm_vn_open(&snd)) != 0)
			goto bad;
		sfp->f_flag = FREAD|FWRITE;
		sfp->f_type = DTYPE_VNODE;
		sfp->f_ops = &vnops;
		sfp->f_data = (caddr_t) snd.ni_vp;
		VOP_UNLOCK(snd.ni_vp, 0, p);

		/* now, put the indexen and names into struct ptmget */
		ptm->cfd = cindx;
		ptm->sfd = sindx;
		memcpy(ptm->cn, pti->pty_pn, sizeof(pti->pty_pn));
		memcpy(ptm->sn, pti->pty_sn, sizeof(pti->pty_sn));

		/* mark the files mature now that we've passed all errors */
		FILE_SET_MATURE(cfp);
		FILE_SET_MATURE(sfp);

		fdpunlock(fdp);
		break;
	default:
		error = EINVAL;
		break;
	}
	return (error);
bad:
	fdremove(fdp, cindx);
	closef(cfp, p);
	fdremove(fdp, sindx);
	closef(sfp, p);
	fdpunlock(fdp);
	return (error);
}