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); }
/* 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; }