예제 #1
0
int
tmpfs_setattr(struct vop_setattr_args *v)
{
	struct vnode *vp = v->a_vp;
	struct vattr *vap = v->a_vap;
	struct ucred *cred = v->a_cred;
	struct tmpfs_node *node = VP_TO_TMPFS_NODE(vp);
	int error = 0;
	int kflags = 0;

	TMPFS_NODE_LOCK(node);
	if (error == 0 && (vap->va_flags != VNOVAL)) {
		error = tmpfs_chflags(vp, vap->va_flags, cred);
		kflags |= NOTE_ATTRIB;
	}

	if (error == 0 && (vap->va_size != VNOVAL)) {
		if (vap->va_size > node->tn_size)
			kflags |= NOTE_WRITE | NOTE_EXTEND;
		else
			kflags |= NOTE_WRITE;
		error = tmpfs_chsize(vp, vap->va_size, cred);
	}

	if (error == 0 && (vap->va_uid != (uid_t)VNOVAL ||
			   vap->va_gid != (gid_t)VNOVAL)) {
		error = tmpfs_chown(vp, vap->va_uid, vap->va_gid, cred);
		kflags |= NOTE_ATTRIB;
	}

	if (error == 0 && (vap->va_mode != (mode_t)VNOVAL)) {
		error = tmpfs_chmod(vp, vap->va_mode, cred);
		kflags |= NOTE_ATTRIB;
	}

	if (error == 0 && ((vap->va_atime.tv_sec != VNOVAL &&
	    vap->va_atime.tv_nsec != VNOVAL) ||
	    (vap->va_mtime.tv_sec != VNOVAL &&
	    vap->va_mtime.tv_nsec != VNOVAL) )) {
		error = tmpfs_chtimes(vp, &vap->va_atime, &vap->va_mtime,
				      vap->va_vaflags, cred);
		kflags |= NOTE_ATTRIB;
	}

	/*
	 * Update the node times.  We give preference to the error codes
	 * generated by this function rather than the ones that may arise
	 * from tmpfs_update.
	 */
	tmpfs_update(vp);
	TMPFS_NODE_UNLOCK(node);
	tmpfs_knote(vp, kflags);

	return (error);
}
예제 #2
0
/* XXX Should this operation be atomic?  I think it should, but code in
 * XXX other places (e.g., ufs) doesn't seem to be... */
int
tmpfs_setattr(struct vop_setattr_args *v)
{
	struct vnode *vp = v->a_vp;
	struct vattr *vap = v->a_vap;
	struct ucred *cred = v->a_cred;
	struct thread *td = curthread;

	int error;

	MPASS(VOP_ISLOCKED(vp));

	error = 0;

	/* Abort if any unsettable attribute is given. */
	if (vap->va_type != VNON ||
	    vap->va_nlink != VNOVAL ||
	    vap->va_fsid != VNOVAL ||
	    vap->va_fileid != VNOVAL ||
	    vap->va_blocksize != VNOVAL ||
	    vap->va_gen != VNOVAL ||
	    vap->va_rdev != VNOVAL ||
	    vap->va_bytes != VNOVAL)
		error = EINVAL;

	if (error == 0 && (vap->va_flags != VNOVAL))
		error = tmpfs_chflags(vp, vap->va_flags, cred, td);

	if (error == 0 && (vap->va_size != VNOVAL))
		error = tmpfs_chsize(vp, vap->va_size, cred, td);

	if (error == 0 && (vap->va_uid != VNOVAL || vap->va_gid != VNOVAL))
		error = tmpfs_chown(vp, vap->va_uid, vap->va_gid, cred, td);

	if (error == 0 && (vap->va_mode != (mode_t)VNOVAL))
		error = tmpfs_chmod(vp, vap->va_mode, cred, td);

	if (error == 0 && ((vap->va_atime.tv_sec != VNOVAL &&
	    vap->va_atime.tv_nsec != VNOVAL) ||
	    (vap->va_mtime.tv_sec != VNOVAL &&
	    vap->va_mtime.tv_nsec != VNOVAL) ||
	    (vap->va_birthtime.tv_sec != VNOVAL &&
	    vap->va_birthtime.tv_nsec != VNOVAL)))
		error = tmpfs_chtimes(vp, &vap->va_atime, &vap->va_mtime,
			&vap->va_birthtime, vap->va_vaflags, cred, td);

	/* Update the node times.  We give preference to the error codes
	 * generated by this function rather than the ones that may arise
	 * from tmpfs_update. */
	tmpfs_update(vp);

	MPASS(VOP_ISLOCKED(vp));

	return error;
}