Moved the filesystem read-only check out of the syscalls and into the
filesystem layer, as was done in lite-2. Merged in some other cosmetic changes while I was at it. Rewrote most of msdosfs_access() to be more like ufs_access() and to include the FS read-only check. Obtained from: partially from 4.4BSD-lite2
This commit is contained in:
parent
bc06de1c3a
commit
ac8daf6b64
@ -38,7 +38,7 @@
|
||||
* from: @(#)ufs_lookup.c 7.33 (Berkeley) 5/19/91
|
||||
*
|
||||
* @(#)cd9660_lookup.c 8.2 (Berkeley) 1/23/94
|
||||
* $Id: cd9660_lookup.c,v 1.6 1995/01/16 17:03:23 joerg Exp $
|
||||
* $Id: cd9660_lookup.c,v 1.7 1995/05/30 08:04:57 rgrimes Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -142,6 +142,9 @@ cd9660_lookup(ap)
|
||||
return (ENOTDIR);
|
||||
if ((error = VOP_ACCESS(vdp, VEXEC, cred, cnp->cn_proc)))
|
||||
return (error);
|
||||
if ((flags & ISLASTCN) && (vdp->v_mount->mnt_flag & MNT_RDONLY) &&
|
||||
(cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
|
||||
return (EROFS);
|
||||
|
||||
/*
|
||||
* We now have a segment name to search for, and a directory to search.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: msdosfs_vnops.c,v 1.23 1995/09/04 00:20:45 dyson Exp $ */
|
||||
/* $Id: msdosfs_vnops.c,v 1.24 1995/10/07 10:14:12 bde Exp $ */
|
||||
/* $NetBSD: msdosfs_vnops.c,v 1.20 1994/08/21 18:44:13 ws Exp $ */
|
||||
|
||||
/*-
|
||||
@ -204,64 +204,6 @@ msdosfs_close(ap)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine will go into sys/kern/vfs_subr.c one day!
|
||||
*
|
||||
* Do the usual access checking.
|
||||
* file_node, uid and gid are from the vnode in question,
|
||||
* while acc_mode and cred are from the VOP_ACCESS parameter list.
|
||||
*/
|
||||
static int
|
||||
vaccess(file_mode, uid, gid, acc_mode, cred)
|
||||
mode_t file_mode;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
mode_t acc_mode;
|
||||
struct ucred *cred;
|
||||
{
|
||||
mode_t mask;
|
||||
int i;
|
||||
register gid_t *gp;
|
||||
|
||||
/* User id 0 always gets access. */
|
||||
if (cred->cr_uid == 0)
|
||||
return 0;
|
||||
|
||||
mask = 0;
|
||||
|
||||
/* Otherwise, check the owner. */
|
||||
if (cred->cr_uid == uid) {
|
||||
if (acc_mode & VEXEC)
|
||||
mask |= S_IXUSR;
|
||||
if (acc_mode & VREAD)
|
||||
mask |= S_IRUSR;
|
||||
if (acc_mode & VWRITE)
|
||||
mask |= S_IWUSR;
|
||||
return (file_mode & mask) == mask ? 0 : EACCES;
|
||||
}
|
||||
|
||||
/* Otherwise, check the groups. */
|
||||
for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++)
|
||||
if (gid == *gp) {
|
||||
if (acc_mode & VEXEC)
|
||||
mask |= S_IXGRP;
|
||||
if (acc_mode & VREAD)
|
||||
mask |= S_IRGRP;
|
||||
if (acc_mode & VWRITE)
|
||||
mask |= S_IWGRP;
|
||||
return (file_mode & mask) == mask ? 0 : EACCES;
|
||||
}
|
||||
|
||||
/* Otherwise, check everyone else. */
|
||||
if (acc_mode & VEXEC)
|
||||
mask |= S_IXOTH;
|
||||
if (acc_mode & VREAD)
|
||||
mask |= S_IROTH;
|
||||
if (acc_mode & VWRITE)
|
||||
mask |= S_IWOTH;
|
||||
return (file_mode & mask) == mask ? 0 : EACCES;
|
||||
}
|
||||
|
||||
int
|
||||
msdosfs_access(ap)
|
||||
struct vop_access_args /* {
|
||||
@ -271,15 +213,71 @@ msdosfs_access(ap)
|
||||
struct proc *a_p;
|
||||
} */ *ap;
|
||||
{
|
||||
mode_t dosmode;
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct denode *dep = VTODE(ap->a_vp);
|
||||
struct msdosfsmount *pmp = dep->de_pmp;
|
||||
struct ucred *cred = ap->a_cred;
|
||||
mode_t mask, file_mode, mode = ap->a_mode;
|
||||
register gid_t *gp;
|
||||
int i;
|
||||
|
||||
dosmode = (S_IXUSR|S_IXGRP|S_IXOTH) | (S_IRUSR|S_IRGRP|S_IROTH) |
|
||||
file_mode = (S_IXUSR|S_IXGRP|S_IXOTH) | (S_IRUSR|S_IRGRP|S_IROTH) |
|
||||
((dep->de_Attributes & ATTR_READONLY) ? 0 : (S_IWUSR|S_IWGRP|S_IWOTH));
|
||||
dosmode &= pmp->pm_mask;
|
||||
file_mode &= pmp->pm_mask;
|
||||
|
||||
return vaccess(dosmode, pmp->pm_uid, pmp->pm_gid, ap->a_mode, ap->a_cred);
|
||||
/*
|
||||
* Disallow write attempts on read-only file systems;
|
||||
* unless the file is a socket, fifo, or a block or
|
||||
* character device resident on the file system.
|
||||
*/
|
||||
if (mode & VWRITE) {
|
||||
switch (vp->v_type) {
|
||||
case VDIR:
|
||||
case VLNK:
|
||||
case VREG:
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
return (EROFS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* User id 0 always gets access. */
|
||||
if (cred->cr_uid == 0)
|
||||
return 0;
|
||||
|
||||
mask = 0;
|
||||
|
||||
/* Otherwise, check the owner. */
|
||||
if (cred->cr_uid == pmp->pm_uid) {
|
||||
if (mode & VEXEC)
|
||||
mask |= S_IXUSR;
|
||||
if (mode & VREAD)
|
||||
mask |= S_IRUSR;
|
||||
if (mode & VWRITE)
|
||||
mask |= S_IWUSR;
|
||||
return (file_mode & mask) == mask ? 0 : EACCES;
|
||||
}
|
||||
|
||||
/* Otherwise, check the groups. */
|
||||
for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++)
|
||||
if (pmp->pm_gid == *gp) {
|
||||
if (mode & VEXEC)
|
||||
mask |= S_IXGRP;
|
||||
if (mode & VREAD)
|
||||
mask |= S_IRGRP;
|
||||
if (mode & VWRITE)
|
||||
mask |= S_IWGRP;
|
||||
return (file_mode & mask) == mask ? 0 : EACCES;
|
||||
}
|
||||
|
||||
/* Otherwise, check everyone else. */
|
||||
if (mode & VEXEC)
|
||||
mask |= S_IXOTH;
|
||||
if (mode & VREAD)
|
||||
mask |= S_IROTH;
|
||||
if (mode & VWRITE)
|
||||
mask |= S_IWOTH;
|
||||
return (file_mode & mask) == mask ? 0 : EACCES;
|
||||
}
|
||||
|
||||
int
|
||||
@ -349,85 +347,27 @@ msdosfs_setattr(ap)
|
||||
struct proc *a_p;
|
||||
} */ *ap;
|
||||
{
|
||||
int error = 0;
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct denode *dep = VTODE(ap->a_vp);
|
||||
struct vattr *vap = ap->a_vap;
|
||||
struct ucred *cred = ap->a_cred;
|
||||
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_setattr(): vp %08x, vap %08x, cred %08x, p %08x\n",
|
||||
ap->a_vp, vap, cred, ap->a_p);
|
||||
#endif
|
||||
if ((vap->va_type != VNON) ||
|
||||
(vap->va_nlink != VNOVAL) ||
|
||||
(vap->va_fsid != VNOVAL) ||
|
||||
(vap->va_fileid != VNOVAL) ||
|
||||
(vap->va_blocksize != VNOVAL) ||
|
||||
(vap->va_rdev != VNOVAL) ||
|
||||
(vap->va_bytes != VNOVAL) ||
|
||||
(vap->va_gen != VNOVAL)) {
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_setattr(): returning EINVAL\n");
|
||||
printf(" va_type %d, va_nlink %x, va_fsid %x, va_fileid %x\n",
|
||||
vap->va_type, vap->va_nlink, vap->va_fsid, vap->va_fileid);
|
||||
printf(" va_blocksize %x, va_rdev %x, va_bytes %x, va_gen %x\n",
|
||||
vap->va_blocksize, vap->va_rdev, vap->va_bytes, vap->va_gen);
|
||||
#endif
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (uid_t)VNOVAL) {
|
||||
if ((cred->cr_uid != dep->de_pmp->pm_uid ||
|
||||
vap->va_uid != dep->de_pmp->pm_uid ||
|
||||
(vap->va_gid != dep->de_pmp->pm_gid &&
|
||||
!groupmember(vap->va_gid, cred))) &&
|
||||
(error = suser(cred, &ap->a_p->p_acflag)))
|
||||
return error;
|
||||
if (vap->va_uid != dep->de_pmp->pm_uid ||
|
||||
vap->va_gid != dep->de_pmp->pm_gid)
|
||||
return EINVAL;
|
||||
}
|
||||
if (vap->va_size != VNOVAL) {
|
||||
if (ap->a_vp->v_type == VDIR)
|
||||
return EISDIR;
|
||||
error = detrunc(dep, vap->va_size, 0, cred, ap->a_p);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
if (vap->va_mtime.ts_sec != VNOVAL) {
|
||||
if (cred->cr_uid != dep->de_pmp->pm_uid &&
|
||||
(error = suser(cred, &ap->a_p->p_acflag)) &&
|
||||
((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
|
||||
(error = VOP_ACCESS(ap->a_vp, VWRITE, cred, ap->a_p))))
|
||||
return error;
|
||||
dep->de_flag |= DE_UPDATE;
|
||||
error = deupdat(dep, &vap->va_mtime, 1);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
int error = 0;
|
||||
|
||||
/*
|
||||
* DOS files only have the ability to have their writability
|
||||
* attribute set, so we use the owner write bit to set the readonly
|
||||
* attribute.
|
||||
* Check for unsettable attributes.
|
||||
*/
|
||||
if (vap->va_mode != (u_short) VNOVAL) {
|
||||
if (cred->cr_uid != dep->de_pmp->pm_uid &&
|
||||
(error = suser(cred, &ap->a_p->p_acflag)))
|
||||
return error;
|
||||
|
||||
/* We ignore the read and execute bits */
|
||||
if (vap->va_mode & VWRITE)
|
||||
dep->de_Attributes &= ~ATTR_READONLY;
|
||||
else
|
||||
dep->de_Attributes |= ATTR_READONLY;
|
||||
dep->de_flag |= DE_MODIFIED;
|
||||
if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
|
||||
(vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
|
||||
(vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
|
||||
(vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if (vap->va_flags != VNOVAL) {
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
return (EROFS);
|
||||
if (cred->cr_uid != dep->de_pmp->pm_uid &&
|
||||
(error = suser(cred, &ap->a_p->p_acflag)))
|
||||
return error;
|
||||
return (error);
|
||||
/*
|
||||
* We are very inconsistent about handling unsupported
|
||||
* attributes. We ignored the the access time and the
|
||||
@ -452,6 +392,73 @@ msdosfs_setattr(ap)
|
||||
dep->de_Attributes |= ATTR_ARCHIVE;
|
||||
dep->de_flag |= DE_MODIFIED;
|
||||
}
|
||||
|
||||
if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (uid_t)VNOVAL) {
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
return (EROFS);
|
||||
if ((cred->cr_uid != dep->de_pmp->pm_uid ||
|
||||
vap->va_uid != dep->de_pmp->pm_uid ||
|
||||
(vap->va_gid != dep->de_pmp->pm_gid &&
|
||||
!groupmember(vap->va_gid, cred))) &&
|
||||
(error = suser(cred, &ap->a_p->p_acflag)))
|
||||
return error;
|
||||
if (vap->va_uid != dep->de_pmp->pm_uid ||
|
||||
vap->va_gid != dep->de_pmp->pm_gid)
|
||||
return EINVAL;
|
||||
}
|
||||
if (vap->va_size != VNOVAL) {
|
||||
/*
|
||||
* Disallow write attempts on read-only file systems;
|
||||
* unless the file is a socket, fifo, or a block or
|
||||
* character device resident on the file system.
|
||||
*/
|
||||
switch (vp->v_type) {
|
||||
case VDIR:
|
||||
return (EISDIR);
|
||||
case VLNK:
|
||||
case VREG:
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
return (EROFS);
|
||||
break;
|
||||
}
|
||||
error = detrunc(dep, vap->va_size, 0, cred, ap->a_p);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
if (vap->va_mtime.ts_sec != VNOVAL) {
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
return (EROFS);
|
||||
if (cred->cr_uid != dep->de_pmp->pm_uid &&
|
||||
(error = suser(cred, &ap->a_p->p_acflag)) &&
|
||||
((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
|
||||
(error = VOP_ACCESS(vp, VWRITE, cred, ap->a_p))))
|
||||
return error;
|
||||
dep->de_flag |= DE_UPDATE;
|
||||
error = deupdat(dep, &vap->va_mtime, 1);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* DOS files only have the ability to have their writability
|
||||
* attribute set, so we use the owner write bit to set the readonly
|
||||
* attribute.
|
||||
*/
|
||||
error = 0;
|
||||
if (vap->va_mode != (u_short) VNOVAL) {
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
return (EROFS);
|
||||
if (cred->cr_uid != dep->de_pmp->pm_uid &&
|
||||
(error = suser(cred, &ap->a_p->p_acflag)))
|
||||
return error;
|
||||
|
||||
/* We ignore the read and execute bits */
|
||||
if (vap->va_mode & VWRITE)
|
||||
dep->de_Attributes &= ~ATTR_READONLY;
|
||||
else
|
||||
dep->de_Attributes |= ATTR_READONLY;
|
||||
dep->de_flag |= DE_MODIFIED;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
||||
* from: @(#)ufs_lookup.c 7.33 (Berkeley) 5/19/91
|
||||
*
|
||||
* @(#)cd9660_lookup.c 8.2 (Berkeley) 1/23/94
|
||||
* $Id: cd9660_lookup.c,v 1.6 1995/01/16 17:03:23 joerg Exp $
|
||||
* $Id: cd9660_lookup.c,v 1.7 1995/05/30 08:04:57 rgrimes Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -142,6 +142,9 @@ cd9660_lookup(ap)
|
||||
return (ENOTDIR);
|
||||
if ((error = VOP_ACCESS(vdp, VEXEC, cred, cnp->cn_proc)))
|
||||
return (error);
|
||||
if ((flags & ISLASTCN) && (vdp->v_mount->mnt_flag & MNT_RDONLY) &&
|
||||
(cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
|
||||
return (EROFS);
|
||||
|
||||
/*
|
||||
* We now have a segment name to search for, and a directory to search.
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
|
||||
* $Id: vfs_syscalls.c,v 1.33 1995/08/28 09:18:56 julian Exp $
|
||||
* $Id: vfs_syscalls.c,v 1.34 1995/10/08 00:06:10 swallace Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -1395,13 +1395,9 @@ chflags(p, uap, retval)
|
||||
vp = nd.ni_vp;
|
||||
LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
|
||||
VOP_LOCK(vp);
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
error = EROFS;
|
||||
else {
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_flags = uap->flags;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
}
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_flags = uap->flags;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
vput(vp);
|
||||
return (error);
|
||||
}
|
||||
@ -1431,13 +1427,9 @@ fchflags(p, uap, retval)
|
||||
vp = (struct vnode *)fp->f_data;
|
||||
LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
|
||||
VOP_LOCK(vp);
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
error = EROFS;
|
||||
else {
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_flags = uap->flags;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
}
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_flags = uap->flags;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
VOP_UNLOCK(vp);
|
||||
return (error);
|
||||
}
|
||||
@ -1468,13 +1460,9 @@ chmod(p, uap, retval)
|
||||
vp = nd.ni_vp;
|
||||
LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
|
||||
VOP_LOCK(vp);
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
error = EROFS;
|
||||
else {
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_mode = uap->mode & ALLPERMS;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
}
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_mode = uap->mode & ALLPERMS;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
vput(vp);
|
||||
return (error);
|
||||
}
|
||||
@ -1504,13 +1492,9 @@ fchmod(p, uap, retval)
|
||||
vp = (struct vnode *)fp->f_data;
|
||||
LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
|
||||
VOP_LOCK(vp);
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
error = EROFS;
|
||||
else {
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_mode = uap->mode & ALLPERMS;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
}
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_mode = uap->mode & ALLPERMS;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
VOP_UNLOCK(vp);
|
||||
return (error);
|
||||
}
|
||||
@ -1542,14 +1526,10 @@ chown(p, uap, retval)
|
||||
vp = nd.ni_vp;
|
||||
LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
|
||||
VOP_LOCK(vp);
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
error = EROFS;
|
||||
else {
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_uid = uap->uid;
|
||||
vattr.va_gid = uap->gid;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
}
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_uid = uap->uid;
|
||||
vattr.va_gid = uap->gid;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
vput(vp);
|
||||
return (error);
|
||||
}
|
||||
@ -1580,14 +1560,10 @@ fchown(p, uap, retval)
|
||||
vp = (struct vnode *)fp->f_data;
|
||||
LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
|
||||
VOP_LOCK(vp);
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
error = EROFS;
|
||||
else {
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_uid = uap->uid;
|
||||
vattr.va_gid = uap->gid;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
}
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_uid = uap->uid;
|
||||
vattr.va_gid = uap->gid;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
VOP_UNLOCK(vp);
|
||||
return (error);
|
||||
}
|
||||
@ -1629,15 +1605,11 @@ utimes(p, uap, retval)
|
||||
vp = nd.ni_vp;
|
||||
LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
|
||||
VOP_LOCK(vp);
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
error = EROFS;
|
||||
else {
|
||||
vattr.va_atime.ts_sec = tv[0].tv_sec;
|
||||
vattr.va_atime.ts_nsec = tv[0].tv_usec * 1000;
|
||||
vattr.va_mtime.ts_sec = tv[1].tv_sec;
|
||||
vattr.va_mtime.ts_nsec = tv[1].tv_usec * 1000;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
}
|
||||
vattr.va_atime.ts_sec = tv[0].tv_sec;
|
||||
vattr.va_atime.ts_nsec = tv[0].tv_usec * 1000;
|
||||
vattr.va_mtime.ts_sec = tv[1].tv_sec;
|
||||
vattr.va_mtime.ts_nsec = tv[1].tv_usec * 1000;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
vput(vp);
|
||||
return (error);
|
||||
}
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)vfs_lookup.c 8.4 (Berkeley) 2/16/94
|
||||
* $Id: vfs_lookup.c,v 1.8 1995/07/31 00:35:46 bde Exp $
|
||||
* $Id: vfs_lookup.c,v 1.9 1995/08/24 10:16:59 dfr Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -422,7 +422,7 @@ lookup(ndp)
|
||||
* If creating and at end of pathname, then can consider
|
||||
* allowing file to be created.
|
||||
*/
|
||||
if (rdonly || (ndp->ni_dvp->v_mount->mnt_flag & MNT_RDONLY)) {
|
||||
if (rdonly) {
|
||||
error = EROFS;
|
||||
goto bad;
|
||||
}
|
||||
@ -510,19 +510,12 @@ lookup(ndp)
|
||||
goto dirloop;
|
||||
}
|
||||
/*
|
||||
* Check for read-only file systems.
|
||||
* Disallow directory write attempts on 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 &&
|
||||
(ndp->ni_dvp->v_mount->mnt_flag & MNT_RDONLY))) {
|
||||
error = EROFS;
|
||||
goto bad2;
|
||||
}
|
||||
if (rdonly &&
|
||||
(cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) {
|
||||
error = EROFS;
|
||||
goto bad2;
|
||||
}
|
||||
if (cnp->cn_flags & SAVESTART) {
|
||||
ndp->ni_startdir = ndp->ni_dvp;
|
||||
@ -638,7 +631,7 @@ relookup(dvp, vpp, cnp)
|
||||
* If creating and at end of pathname, then can consider
|
||||
* allowing file to be created.
|
||||
*/
|
||||
if (rdonly || (dvp->v_mount->mnt_flag & MNT_RDONLY)) {
|
||||
if (rdonly) {
|
||||
error = EROFS;
|
||||
goto bad;
|
||||
}
|
||||
@ -663,19 +656,12 @@ relookup(dvp, vpp, cnp)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check for read-only file systems.
|
||||
* Disallow directory write attempts on 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;
|
||||
}
|
||||
if (rdonly &&
|
||||
(cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) {
|
||||
error = EROFS;
|
||||
goto bad2;
|
||||
}
|
||||
/* ASSERT(dvp == ndp->ni_startdir) */
|
||||
if (cnp->cn_flags & SAVESTART)
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
|
||||
* $Id: vfs_syscalls.c,v 1.33 1995/08/28 09:18:56 julian Exp $
|
||||
* $Id: vfs_syscalls.c,v 1.34 1995/10/08 00:06:10 swallace Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -1395,13 +1395,9 @@ chflags(p, uap, retval)
|
||||
vp = nd.ni_vp;
|
||||
LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
|
||||
VOP_LOCK(vp);
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
error = EROFS;
|
||||
else {
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_flags = uap->flags;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
}
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_flags = uap->flags;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
vput(vp);
|
||||
return (error);
|
||||
}
|
||||
@ -1431,13 +1427,9 @@ fchflags(p, uap, retval)
|
||||
vp = (struct vnode *)fp->f_data;
|
||||
LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
|
||||
VOP_LOCK(vp);
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
error = EROFS;
|
||||
else {
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_flags = uap->flags;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
}
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_flags = uap->flags;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
VOP_UNLOCK(vp);
|
||||
return (error);
|
||||
}
|
||||
@ -1468,13 +1460,9 @@ chmod(p, uap, retval)
|
||||
vp = nd.ni_vp;
|
||||
LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
|
||||
VOP_LOCK(vp);
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
error = EROFS;
|
||||
else {
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_mode = uap->mode & ALLPERMS;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
}
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_mode = uap->mode & ALLPERMS;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
vput(vp);
|
||||
return (error);
|
||||
}
|
||||
@ -1504,13 +1492,9 @@ fchmod(p, uap, retval)
|
||||
vp = (struct vnode *)fp->f_data;
|
||||
LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
|
||||
VOP_LOCK(vp);
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
error = EROFS;
|
||||
else {
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_mode = uap->mode & ALLPERMS;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
}
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_mode = uap->mode & ALLPERMS;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
VOP_UNLOCK(vp);
|
||||
return (error);
|
||||
}
|
||||
@ -1542,14 +1526,10 @@ chown(p, uap, retval)
|
||||
vp = nd.ni_vp;
|
||||
LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
|
||||
VOP_LOCK(vp);
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
error = EROFS;
|
||||
else {
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_uid = uap->uid;
|
||||
vattr.va_gid = uap->gid;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
}
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_uid = uap->uid;
|
||||
vattr.va_gid = uap->gid;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
vput(vp);
|
||||
return (error);
|
||||
}
|
||||
@ -1580,14 +1560,10 @@ fchown(p, uap, retval)
|
||||
vp = (struct vnode *)fp->f_data;
|
||||
LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
|
||||
VOP_LOCK(vp);
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
error = EROFS;
|
||||
else {
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_uid = uap->uid;
|
||||
vattr.va_gid = uap->gid;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
}
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_uid = uap->uid;
|
||||
vattr.va_gid = uap->gid;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
VOP_UNLOCK(vp);
|
||||
return (error);
|
||||
}
|
||||
@ -1629,15 +1605,11 @@ utimes(p, uap, retval)
|
||||
vp = nd.ni_vp;
|
||||
LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
|
||||
VOP_LOCK(vp);
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
error = EROFS;
|
||||
else {
|
||||
vattr.va_atime.ts_sec = tv[0].tv_sec;
|
||||
vattr.va_atime.ts_nsec = tv[0].tv_usec * 1000;
|
||||
vattr.va_mtime.ts_sec = tv[1].tv_sec;
|
||||
vattr.va_mtime.ts_nsec = tv[1].tv_usec * 1000;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
}
|
||||
vattr.va_atime.ts_sec = tv[0].tv_sec;
|
||||
vattr.va_atime.ts_nsec = tv[0].tv_usec * 1000;
|
||||
vattr.va_mtime.ts_sec = tv[1].tv_sec;
|
||||
vattr.va_mtime.ts_nsec = tv[1].tv_usec * 1000;
|
||||
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
|
||||
vput(vp);
|
||||
return (error);
|
||||
}
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)vfs_vnops.c 8.2 (Berkeley) 1/21/94
|
||||
* $Id: vfs_vnops.c,v 1.17 1995/07/20 09:43:04 davidg Exp $
|
||||
* $Id: vfs_vnops.c,v 1.18 1995/10/06 09:43:32 phk Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -193,19 +193,6 @@ vn_writechk(vp)
|
||||
register struct vnode *vp;
|
||||
{
|
||||
|
||||
/*
|
||||
* Disallow write attempts on read-only file systems;
|
||||
* unless the file is a socket or a block or character
|
||||
* device resident on the file system.
|
||||
*/
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY) {
|
||||
switch (vp->v_type) {
|
||||
case VREG: case VDIR: case VLNK:
|
||||
return (EROFS);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If there's shared text associated with
|
||||
* the vnode, try to free it up once. If
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: msdosfs_vnops.c,v 1.23 1995/09/04 00:20:45 dyson Exp $ */
|
||||
/* $Id: msdosfs_vnops.c,v 1.24 1995/10/07 10:14:12 bde Exp $ */
|
||||
/* $NetBSD: msdosfs_vnops.c,v 1.20 1994/08/21 18:44:13 ws Exp $ */
|
||||
|
||||
/*-
|
||||
@ -204,64 +204,6 @@ msdosfs_close(ap)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine will go into sys/kern/vfs_subr.c one day!
|
||||
*
|
||||
* Do the usual access checking.
|
||||
* file_node, uid and gid are from the vnode in question,
|
||||
* while acc_mode and cred are from the VOP_ACCESS parameter list.
|
||||
*/
|
||||
static int
|
||||
vaccess(file_mode, uid, gid, acc_mode, cred)
|
||||
mode_t file_mode;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
mode_t acc_mode;
|
||||
struct ucred *cred;
|
||||
{
|
||||
mode_t mask;
|
||||
int i;
|
||||
register gid_t *gp;
|
||||
|
||||
/* User id 0 always gets access. */
|
||||
if (cred->cr_uid == 0)
|
||||
return 0;
|
||||
|
||||
mask = 0;
|
||||
|
||||
/* Otherwise, check the owner. */
|
||||
if (cred->cr_uid == uid) {
|
||||
if (acc_mode & VEXEC)
|
||||
mask |= S_IXUSR;
|
||||
if (acc_mode & VREAD)
|
||||
mask |= S_IRUSR;
|
||||
if (acc_mode & VWRITE)
|
||||
mask |= S_IWUSR;
|
||||
return (file_mode & mask) == mask ? 0 : EACCES;
|
||||
}
|
||||
|
||||
/* Otherwise, check the groups. */
|
||||
for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++)
|
||||
if (gid == *gp) {
|
||||
if (acc_mode & VEXEC)
|
||||
mask |= S_IXGRP;
|
||||
if (acc_mode & VREAD)
|
||||
mask |= S_IRGRP;
|
||||
if (acc_mode & VWRITE)
|
||||
mask |= S_IWGRP;
|
||||
return (file_mode & mask) == mask ? 0 : EACCES;
|
||||
}
|
||||
|
||||
/* Otherwise, check everyone else. */
|
||||
if (acc_mode & VEXEC)
|
||||
mask |= S_IXOTH;
|
||||
if (acc_mode & VREAD)
|
||||
mask |= S_IROTH;
|
||||
if (acc_mode & VWRITE)
|
||||
mask |= S_IWOTH;
|
||||
return (file_mode & mask) == mask ? 0 : EACCES;
|
||||
}
|
||||
|
||||
int
|
||||
msdosfs_access(ap)
|
||||
struct vop_access_args /* {
|
||||
@ -271,15 +213,71 @@ msdosfs_access(ap)
|
||||
struct proc *a_p;
|
||||
} */ *ap;
|
||||
{
|
||||
mode_t dosmode;
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct denode *dep = VTODE(ap->a_vp);
|
||||
struct msdosfsmount *pmp = dep->de_pmp;
|
||||
struct ucred *cred = ap->a_cred;
|
||||
mode_t mask, file_mode, mode = ap->a_mode;
|
||||
register gid_t *gp;
|
||||
int i;
|
||||
|
||||
dosmode = (S_IXUSR|S_IXGRP|S_IXOTH) | (S_IRUSR|S_IRGRP|S_IROTH) |
|
||||
file_mode = (S_IXUSR|S_IXGRP|S_IXOTH) | (S_IRUSR|S_IRGRP|S_IROTH) |
|
||||
((dep->de_Attributes & ATTR_READONLY) ? 0 : (S_IWUSR|S_IWGRP|S_IWOTH));
|
||||
dosmode &= pmp->pm_mask;
|
||||
file_mode &= pmp->pm_mask;
|
||||
|
||||
return vaccess(dosmode, pmp->pm_uid, pmp->pm_gid, ap->a_mode, ap->a_cred);
|
||||
/*
|
||||
* Disallow write attempts on read-only file systems;
|
||||
* unless the file is a socket, fifo, or a block or
|
||||
* character device resident on the file system.
|
||||
*/
|
||||
if (mode & VWRITE) {
|
||||
switch (vp->v_type) {
|
||||
case VDIR:
|
||||
case VLNK:
|
||||
case VREG:
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
return (EROFS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* User id 0 always gets access. */
|
||||
if (cred->cr_uid == 0)
|
||||
return 0;
|
||||
|
||||
mask = 0;
|
||||
|
||||
/* Otherwise, check the owner. */
|
||||
if (cred->cr_uid == pmp->pm_uid) {
|
||||
if (mode & VEXEC)
|
||||
mask |= S_IXUSR;
|
||||
if (mode & VREAD)
|
||||
mask |= S_IRUSR;
|
||||
if (mode & VWRITE)
|
||||
mask |= S_IWUSR;
|
||||
return (file_mode & mask) == mask ? 0 : EACCES;
|
||||
}
|
||||
|
||||
/* Otherwise, check the groups. */
|
||||
for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++)
|
||||
if (pmp->pm_gid == *gp) {
|
||||
if (mode & VEXEC)
|
||||
mask |= S_IXGRP;
|
||||
if (mode & VREAD)
|
||||
mask |= S_IRGRP;
|
||||
if (mode & VWRITE)
|
||||
mask |= S_IWGRP;
|
||||
return (file_mode & mask) == mask ? 0 : EACCES;
|
||||
}
|
||||
|
||||
/* Otherwise, check everyone else. */
|
||||
if (mode & VEXEC)
|
||||
mask |= S_IXOTH;
|
||||
if (mode & VREAD)
|
||||
mask |= S_IROTH;
|
||||
if (mode & VWRITE)
|
||||
mask |= S_IWOTH;
|
||||
return (file_mode & mask) == mask ? 0 : EACCES;
|
||||
}
|
||||
|
||||
int
|
||||
@ -349,85 +347,27 @@ msdosfs_setattr(ap)
|
||||
struct proc *a_p;
|
||||
} */ *ap;
|
||||
{
|
||||
int error = 0;
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct denode *dep = VTODE(ap->a_vp);
|
||||
struct vattr *vap = ap->a_vap;
|
||||
struct ucred *cred = ap->a_cred;
|
||||
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_setattr(): vp %08x, vap %08x, cred %08x, p %08x\n",
|
||||
ap->a_vp, vap, cred, ap->a_p);
|
||||
#endif
|
||||
if ((vap->va_type != VNON) ||
|
||||
(vap->va_nlink != VNOVAL) ||
|
||||
(vap->va_fsid != VNOVAL) ||
|
||||
(vap->va_fileid != VNOVAL) ||
|
||||
(vap->va_blocksize != VNOVAL) ||
|
||||
(vap->va_rdev != VNOVAL) ||
|
||||
(vap->va_bytes != VNOVAL) ||
|
||||
(vap->va_gen != VNOVAL)) {
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_setattr(): returning EINVAL\n");
|
||||
printf(" va_type %d, va_nlink %x, va_fsid %x, va_fileid %x\n",
|
||||
vap->va_type, vap->va_nlink, vap->va_fsid, vap->va_fileid);
|
||||
printf(" va_blocksize %x, va_rdev %x, va_bytes %x, va_gen %x\n",
|
||||
vap->va_blocksize, vap->va_rdev, vap->va_bytes, vap->va_gen);
|
||||
#endif
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (uid_t)VNOVAL) {
|
||||
if ((cred->cr_uid != dep->de_pmp->pm_uid ||
|
||||
vap->va_uid != dep->de_pmp->pm_uid ||
|
||||
(vap->va_gid != dep->de_pmp->pm_gid &&
|
||||
!groupmember(vap->va_gid, cred))) &&
|
||||
(error = suser(cred, &ap->a_p->p_acflag)))
|
||||
return error;
|
||||
if (vap->va_uid != dep->de_pmp->pm_uid ||
|
||||
vap->va_gid != dep->de_pmp->pm_gid)
|
||||
return EINVAL;
|
||||
}
|
||||
if (vap->va_size != VNOVAL) {
|
||||
if (ap->a_vp->v_type == VDIR)
|
||||
return EISDIR;
|
||||
error = detrunc(dep, vap->va_size, 0, cred, ap->a_p);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
if (vap->va_mtime.ts_sec != VNOVAL) {
|
||||
if (cred->cr_uid != dep->de_pmp->pm_uid &&
|
||||
(error = suser(cred, &ap->a_p->p_acflag)) &&
|
||||
((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
|
||||
(error = VOP_ACCESS(ap->a_vp, VWRITE, cred, ap->a_p))))
|
||||
return error;
|
||||
dep->de_flag |= DE_UPDATE;
|
||||
error = deupdat(dep, &vap->va_mtime, 1);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
int error = 0;
|
||||
|
||||
/*
|
||||
* DOS files only have the ability to have their writability
|
||||
* attribute set, so we use the owner write bit to set the readonly
|
||||
* attribute.
|
||||
* Check for unsettable attributes.
|
||||
*/
|
||||
if (vap->va_mode != (u_short) VNOVAL) {
|
||||
if (cred->cr_uid != dep->de_pmp->pm_uid &&
|
||||
(error = suser(cred, &ap->a_p->p_acflag)))
|
||||
return error;
|
||||
|
||||
/* We ignore the read and execute bits */
|
||||
if (vap->va_mode & VWRITE)
|
||||
dep->de_Attributes &= ~ATTR_READONLY;
|
||||
else
|
||||
dep->de_Attributes |= ATTR_READONLY;
|
||||
dep->de_flag |= DE_MODIFIED;
|
||||
if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
|
||||
(vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
|
||||
(vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
|
||||
(vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if (vap->va_flags != VNOVAL) {
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
return (EROFS);
|
||||
if (cred->cr_uid != dep->de_pmp->pm_uid &&
|
||||
(error = suser(cred, &ap->a_p->p_acflag)))
|
||||
return error;
|
||||
return (error);
|
||||
/*
|
||||
* We are very inconsistent about handling unsupported
|
||||
* attributes. We ignored the the access time and the
|
||||
@ -452,6 +392,73 @@ msdosfs_setattr(ap)
|
||||
dep->de_Attributes |= ATTR_ARCHIVE;
|
||||
dep->de_flag |= DE_MODIFIED;
|
||||
}
|
||||
|
||||
if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (uid_t)VNOVAL) {
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
return (EROFS);
|
||||
if ((cred->cr_uid != dep->de_pmp->pm_uid ||
|
||||
vap->va_uid != dep->de_pmp->pm_uid ||
|
||||
(vap->va_gid != dep->de_pmp->pm_gid &&
|
||||
!groupmember(vap->va_gid, cred))) &&
|
||||
(error = suser(cred, &ap->a_p->p_acflag)))
|
||||
return error;
|
||||
if (vap->va_uid != dep->de_pmp->pm_uid ||
|
||||
vap->va_gid != dep->de_pmp->pm_gid)
|
||||
return EINVAL;
|
||||
}
|
||||
if (vap->va_size != VNOVAL) {
|
||||
/*
|
||||
* Disallow write attempts on read-only file systems;
|
||||
* unless the file is a socket, fifo, or a block or
|
||||
* character device resident on the file system.
|
||||
*/
|
||||
switch (vp->v_type) {
|
||||
case VDIR:
|
||||
return (EISDIR);
|
||||
case VLNK:
|
||||
case VREG:
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
return (EROFS);
|
||||
break;
|
||||
}
|
||||
error = detrunc(dep, vap->va_size, 0, cred, ap->a_p);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
if (vap->va_mtime.ts_sec != VNOVAL) {
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
return (EROFS);
|
||||
if (cred->cr_uid != dep->de_pmp->pm_uid &&
|
||||
(error = suser(cred, &ap->a_p->p_acflag)) &&
|
||||
((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
|
||||
(error = VOP_ACCESS(vp, VWRITE, cred, ap->a_p))))
|
||||
return error;
|
||||
dep->de_flag |= DE_UPDATE;
|
||||
error = deupdat(dep, &vap->va_mtime, 1);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* DOS files only have the ability to have their writability
|
||||
* attribute set, so we use the owner write bit to set the readonly
|
||||
* attribute.
|
||||
*/
|
||||
error = 0;
|
||||
if (vap->va_mode != (u_short) VNOVAL) {
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
return (EROFS);
|
||||
if (cred->cr_uid != dep->de_pmp->pm_uid &&
|
||||
(error = suser(cred, &ap->a_p->p_acflag)))
|
||||
return error;
|
||||
|
||||
/* We ignore the read and execute bits */
|
||||
if (vap->va_mode & VWRITE)
|
||||
dep->de_Attributes &= ~ATTR_READONLY;
|
||||
else
|
||||
dep->de_Attributes |= ATTR_READONLY;
|
||||
dep->de_flag |= DE_MODIFIED;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nfs_vnops.c 8.5 (Berkeley) 2/13/94
|
||||
* $Id: nfs_vnops.c,v 1.23 1995/08/01 18:50:59 davidg Exp $
|
||||
* $Id: nfs_vnops.c,v 1.24 1995/09/04 00:20:50 dyson Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -329,6 +329,17 @@ nfs_access(ap)
|
||||
u_long mode, rmode;
|
||||
int v3 = NFS_ISV3(vp);
|
||||
|
||||
/*
|
||||
* Disallow write attempts on filesystems mounted read-only;
|
||||
* unless the file is a socket, fifo, or a block or character
|
||||
* device resident on the filesystem.
|
||||
*/
|
||||
if ((ap->a_mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) {
|
||||
switch (vp->v_type) {
|
||||
case VREG: case VDIR: case VLNK:
|
||||
return (EROFS);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* For nfs v3, do an access rpc, otherwise you are stuck emulating
|
||||
* ufs_access() locally using the vattr. This may not be correct,
|
||||
@ -430,7 +441,6 @@ nfs_open(ap)
|
||||
if ((error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred,
|
||||
ap->a_p, 1)) == EINTR)
|
||||
return (error);
|
||||
/* (void) vnode_pager_uncache(vp); */
|
||||
np->n_attrstamp = 0;
|
||||
if (vp->v_type == VDIR)
|
||||
np->n_direofoffset = 0;
|
||||
@ -448,7 +458,6 @@ nfs_open(ap)
|
||||
if ((error = nfs_vinvalbuf(vp, V_SAVE,
|
||||
ap->a_cred, ap->a_p, 1)) == EINTR)
|
||||
return (error);
|
||||
/* (void) vnode_pager_uncache(vp); */
|
||||
np->n_mtime = vattr.va_mtime.ts_sec;
|
||||
}
|
||||
}
|
||||
@ -585,6 +594,14 @@ nfs_setattr(ap)
|
||||
#ifndef nolint
|
||||
tsize = (u_quad_t)0;
|
||||
#endif
|
||||
/*
|
||||
* Disallow write attempts if the filesystem is mounted read-only.
|
||||
*/
|
||||
if ((vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL ||
|
||||
vap->va_gid != (gid_t)VNOVAL || vap->va_atime.ts_sec != VNOVAL ||
|
||||
vap->va_mtime.ts_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) &&
|
||||
(vp->v_mount->mnt_flag & MNT_RDONLY))
|
||||
return (EROFS);
|
||||
if (vap->va_size != VNOVAL) {
|
||||
switch (vp->v_type) {
|
||||
case VDIR:
|
||||
@ -600,6 +617,12 @@ nfs_setattr(ap)
|
||||
vap->va_size = VNOVAL;
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* Disallow write attempts if the filesystem is
|
||||
* mounted read-only.
|
||||
*/
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
return (EROFS);
|
||||
if (vap->va_size == 0)
|
||||
error = nfs_vinvalbuf(vp, 0,
|
||||
ap->a_cred, ap->a_p, 1);
|
||||
@ -768,6 +791,9 @@ nfs_lookup(ap)
|
||||
int lockparent, wantparent, error = 0, attrflag, fhsize;
|
||||
int v3 = NFS_ISV3(dvp);
|
||||
|
||||
if ((flags & ISLASTCN) && (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
|
||||
(cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
|
||||
return (EROFS);
|
||||
*vpp = NULLVP;
|
||||
if (dvp->v_type != VDIR)
|
||||
return (ENOTDIR);
|
||||
@ -908,7 +934,10 @@ nfs_lookup(ap)
|
||||
(flags & ISLASTCN) && error == ENOENT) {
|
||||
if (!lockparent)
|
||||
VOP_UNLOCK(dvp);
|
||||
error = EJUSTRETURN;
|
||||
if (dvp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
error = EROFS;
|
||||
else
|
||||
error = EJUSTRETURN;
|
||||
}
|
||||
if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
|
||||
cnp->cn_flags |= SAVENAME;
|
||||
@ -3131,11 +3160,23 @@ nfsspec_access(ap)
|
||||
register struct vattr *vap;
|
||||
register gid_t *gp;
|
||||
register struct ucred *cred = ap->a_cred;
|
||||
struct vnode *vp = ap->a_vp;
|
||||
mode_t mode = ap->a_mode;
|
||||
struct vattr vattr;
|
||||
register int i;
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Disallow write attempts on filesystems mounted read-only;
|
||||
* unless the file is a socket, fifo, or a block or character
|
||||
* device resident on the filesystem.
|
||||
*/
|
||||
if ((mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) {
|
||||
switch (vp->v_type) {
|
||||
case VREG: case VDIR: case VLNK:
|
||||
return (EROFS);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If you're the super-user,
|
||||
* you always get access.
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nfs_vnops.c 8.5 (Berkeley) 2/13/94
|
||||
* $Id: nfs_vnops.c,v 1.23 1995/08/01 18:50:59 davidg Exp $
|
||||
* $Id: nfs_vnops.c,v 1.24 1995/09/04 00:20:50 dyson Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -329,6 +329,17 @@ nfs_access(ap)
|
||||
u_long mode, rmode;
|
||||
int v3 = NFS_ISV3(vp);
|
||||
|
||||
/*
|
||||
* Disallow write attempts on filesystems mounted read-only;
|
||||
* unless the file is a socket, fifo, or a block or character
|
||||
* device resident on the filesystem.
|
||||
*/
|
||||
if ((ap->a_mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) {
|
||||
switch (vp->v_type) {
|
||||
case VREG: case VDIR: case VLNK:
|
||||
return (EROFS);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* For nfs v3, do an access rpc, otherwise you are stuck emulating
|
||||
* ufs_access() locally using the vattr. This may not be correct,
|
||||
@ -430,7 +441,6 @@ nfs_open(ap)
|
||||
if ((error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred,
|
||||
ap->a_p, 1)) == EINTR)
|
||||
return (error);
|
||||
/* (void) vnode_pager_uncache(vp); */
|
||||
np->n_attrstamp = 0;
|
||||
if (vp->v_type == VDIR)
|
||||
np->n_direofoffset = 0;
|
||||
@ -448,7 +458,6 @@ nfs_open(ap)
|
||||
if ((error = nfs_vinvalbuf(vp, V_SAVE,
|
||||
ap->a_cred, ap->a_p, 1)) == EINTR)
|
||||
return (error);
|
||||
/* (void) vnode_pager_uncache(vp); */
|
||||
np->n_mtime = vattr.va_mtime.ts_sec;
|
||||
}
|
||||
}
|
||||
@ -585,6 +594,14 @@ nfs_setattr(ap)
|
||||
#ifndef nolint
|
||||
tsize = (u_quad_t)0;
|
||||
#endif
|
||||
/*
|
||||
* Disallow write attempts if the filesystem is mounted read-only.
|
||||
*/
|
||||
if ((vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL ||
|
||||
vap->va_gid != (gid_t)VNOVAL || vap->va_atime.ts_sec != VNOVAL ||
|
||||
vap->va_mtime.ts_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) &&
|
||||
(vp->v_mount->mnt_flag & MNT_RDONLY))
|
||||
return (EROFS);
|
||||
if (vap->va_size != VNOVAL) {
|
||||
switch (vp->v_type) {
|
||||
case VDIR:
|
||||
@ -600,6 +617,12 @@ nfs_setattr(ap)
|
||||
vap->va_size = VNOVAL;
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* Disallow write attempts if the filesystem is
|
||||
* mounted read-only.
|
||||
*/
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
return (EROFS);
|
||||
if (vap->va_size == 0)
|
||||
error = nfs_vinvalbuf(vp, 0,
|
||||
ap->a_cred, ap->a_p, 1);
|
||||
@ -768,6 +791,9 @@ nfs_lookup(ap)
|
||||
int lockparent, wantparent, error = 0, attrflag, fhsize;
|
||||
int v3 = NFS_ISV3(dvp);
|
||||
|
||||
if ((flags & ISLASTCN) && (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
|
||||
(cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
|
||||
return (EROFS);
|
||||
*vpp = NULLVP;
|
||||
if (dvp->v_type != VDIR)
|
||||
return (ENOTDIR);
|
||||
@ -908,7 +934,10 @@ nfs_lookup(ap)
|
||||
(flags & ISLASTCN) && error == ENOENT) {
|
||||
if (!lockparent)
|
||||
VOP_UNLOCK(dvp);
|
||||
error = EJUSTRETURN;
|
||||
if (dvp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
error = EROFS;
|
||||
else
|
||||
error = EJUSTRETURN;
|
||||
}
|
||||
if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
|
||||
cnp->cn_flags |= SAVENAME;
|
||||
@ -3131,11 +3160,23 @@ nfsspec_access(ap)
|
||||
register struct vattr *vap;
|
||||
register gid_t *gp;
|
||||
register struct ucred *cred = ap->a_cred;
|
||||
struct vnode *vp = ap->a_vp;
|
||||
mode_t mode = ap->a_mode;
|
||||
struct vattr vattr;
|
||||
register int i;
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Disallow write attempts on filesystems mounted read-only;
|
||||
* unless the file is a socket, fifo, or a block or character
|
||||
* device resident on the filesystem.
|
||||
*/
|
||||
if ((mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) {
|
||||
switch (vp->v_type) {
|
||||
case VREG: case VDIR: case VLNK:
|
||||
return (EROFS);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If you're the super-user,
|
||||
* you always get access.
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ufs_lookup.c 8.6 (Berkeley) 4/1/94
|
||||
* $Id: ufs_lookup.c,v 1.5 1995/08/28 09:19:16 julian Exp $
|
||||
* $Id: ufs_lookup.c,v 1.6 1995/10/06 09:56:51 phk Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -145,6 +145,9 @@ ufs_lookup(ap)
|
||||
error = VOP_ACCESS(vdp, VEXEC, cred, cnp->cn_proc);
|
||||
if (error)
|
||||
return (error);
|
||||
if ((flags & ISLASTCN) && (vdp->v_mount->mnt_flag & MNT_RDONLY) &&
|
||||
(cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
|
||||
return (EROFS);
|
||||
|
||||
/*
|
||||
* We now have a segment name to search for, and a directory to search.
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ufs_vnops.c 8.10 (Berkeley) 4/1/94
|
||||
* $Id: ufs_vnops.c,v 1.29 1995/09/09 01:43:49 julian Exp $
|
||||
* $Id: ufs_vnops.c,v 1.30 1995/10/07 10:13:41 bde Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -122,9 +122,9 @@ ufs_mknod(ap)
|
||||
struct vattr *a_vap;
|
||||
} */ *ap;
|
||||
{
|
||||
register struct vattr *vap = ap->a_vap;
|
||||
register struct vnode **vpp = ap->a_vpp;
|
||||
register struct inode *ip;
|
||||
struct vattr *vap = ap->a_vap;
|
||||
struct vnode **vpp = ap->a_vpp;
|
||||
struct inode *ip;
|
||||
int error;
|
||||
|
||||
error = ufs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode),
|
||||
@ -209,33 +209,32 @@ ufs_access(ap)
|
||||
struct proc *a_p;
|
||||
} */ *ap;
|
||||
{
|
||||
register struct vnode *vp = ap->a_vp;
|
||||
register struct inode *ip = VTOI(vp);
|
||||
register struct ucred *cred = ap->a_cred;
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct inode *ip = VTOI(vp);
|
||||
struct ucred *cred = ap->a_cred;
|
||||
mode_t mask, mode = ap->a_mode;
|
||||
register gid_t *gp;
|
||||
int i;
|
||||
#ifdef QUOTA
|
||||
int error;
|
||||
#endif
|
||||
int i, error;
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if (!VOP_ISLOCKED(vp)) {
|
||||
vprint("ufs_access: not locked", vp);
|
||||
panic("ufs_access: not locked");
|
||||
}
|
||||
#endif
|
||||
#ifdef QUOTA
|
||||
if (mode & VWRITE)
|
||||
/*
|
||||
* Disallow write attempts on read-only file systems;
|
||||
* unless the file is a socket, fifo, or a block or
|
||||
* character device resident on the file system.
|
||||
*/
|
||||
if (mode & VWRITE) {
|
||||
switch (vp->v_type) {
|
||||
case VDIR:
|
||||
case VLNK:
|
||||
case VREG:
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
return (EROFS);
|
||||
#ifdef QUOTA
|
||||
if (error = getinoquota(ip))
|
||||
return (error);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* If immutable bit set, nobody gets to write it. */
|
||||
if ((mode & VWRITE) && (ip->i_flags & IMMUTABLE))
|
||||
@ -336,11 +335,11 @@ ufs_setattr(ap)
|
||||
struct proc *a_p;
|
||||
} */ *ap;
|
||||
{
|
||||
register struct vattr *vap = ap->a_vap;
|
||||
register struct vnode *vp = ap->a_vp;
|
||||
register struct inode *ip = VTOI(vp);
|
||||
register struct ucred *cred = ap->a_cred;
|
||||
register struct proc *p = ap->a_p;
|
||||
struct vattr *vap = ap->a_vap;
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct inode *ip = VTOI(vp);
|
||||
struct ucred *cred = ap->a_cred;
|
||||
struct proc *p = ap->a_p;
|
||||
struct timeval atimeval, mtimeval;
|
||||
int error;
|
||||
|
||||
@ -354,6 +353,8 @@ ufs_setattr(ap)
|
||||
return (EINVAL);
|
||||
}
|
||||
if (vap->va_flags != VNOVAL) {
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
return (EROFS);
|
||||
if (cred->cr_uid != ip->i_uid &&
|
||||
(error = suser(cred, &p->p_acflag)))
|
||||
return (error);
|
||||
@ -378,19 +379,35 @@ ufs_setattr(ap)
|
||||
* Go through the fields and update iff not VNOVAL.
|
||||
*/
|
||||
if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) {
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
return (EROFS);
|
||||
error = ufs_chown(vp, vap->va_uid, vap->va_gid, cred, p);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
if (vap->va_size != VNOVAL) {
|
||||
if (vp->v_type == VDIR)
|
||||
/*
|
||||
* Disallow write attempts on read-only file systems;
|
||||
* unless the file is a socket, fifo, or a block or
|
||||
* character device resident on the file system.
|
||||
*/
|
||||
switch (vp->v_type) {
|
||||
case VDIR:
|
||||
return (EISDIR);
|
||||
case VLNK:
|
||||
case VREG:
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
return (EROFS);
|
||||
break;
|
||||
}
|
||||
error = VOP_TRUNCATE(vp, vap->va_size, 0, cred, p);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
ip = VTOI(vp);
|
||||
if (vap->va_atime.ts_sec != VNOVAL || vap->va_mtime.ts_sec != VNOVAL) {
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
return (EROFS);
|
||||
if (cred->cr_uid != ip->i_uid &&
|
||||
(error = suser(cred, &p->p_acflag)) &&
|
||||
((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
|
||||
@ -409,8 +426,11 @@ ufs_setattr(ap)
|
||||
return (error);
|
||||
}
|
||||
error = 0;
|
||||
if (vap->va_mode != (mode_t)VNOVAL)
|
||||
if (vap->va_mode != (mode_t)VNOVAL) {
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
return (EROFS);
|
||||
error = ufs_chmod(vp, (int)vap->va_mode, cred, p);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -636,9 +656,9 @@ ufs_remove(ap)
|
||||
struct componentname *a_cnp;
|
||||
} */ *ap;
|
||||
{
|
||||
register struct inode *ip;
|
||||
register struct vnode *vp = ap->a_vp;
|
||||
register struct vnode *dvp = ap->a_dvp;
|
||||
struct inode *ip;
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct vnode *dvp = ap->a_dvp;
|
||||
int error;
|
||||
|
||||
ip = VTOI(vp);
|
||||
@ -671,10 +691,10 @@ ufs_link(ap)
|
||||
struct componentname *a_cnp;
|
||||
} */ *ap;
|
||||
{
|
||||
register struct vnode *vp = ap->a_vp;
|
||||
register struct vnode *tdvp = ap->a_tdvp;
|
||||
register struct componentname *cnp = ap->a_cnp;
|
||||
register struct inode *ip;
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct vnode *tdvp = ap->a_tdvp;
|
||||
struct componentname *cnp = ap->a_cnp;
|
||||
struct inode *ip;
|
||||
struct timeval tv;
|
||||
int error;
|
||||
|
||||
@ -760,10 +780,10 @@ ufs_rename(ap)
|
||||
struct vnode *tvp = ap->a_tvp;
|
||||
register struct vnode *tdvp = ap->a_tdvp;
|
||||
struct vnode *fvp = ap->a_fvp;
|
||||
register struct vnode *fdvp = ap->a_fdvp;
|
||||
register struct componentname *tcnp = ap->a_tcnp;
|
||||
register struct componentname *fcnp = ap->a_fcnp;
|
||||
register struct inode *ip, *xp, *dp;
|
||||
struct vnode *fdvp = ap->a_fdvp;
|
||||
struct componentname *tcnp = ap->a_tcnp;
|
||||
struct componentname *fcnp = ap->a_fcnp;
|
||||
struct inode *ip, *xp, *dp;
|
||||
struct dirtemplate dirbuf;
|
||||
struct timeval tv;
|
||||
int doingdirectory = 0, oldparent = 0, newparent = 0;
|
||||
@ -1264,10 +1284,10 @@ ufs_rmdir(ap)
|
||||
struct componentname *a_cnp;
|
||||
} */ *ap;
|
||||
{
|
||||
register struct vnode *vp = ap->a_vp;
|
||||
register struct vnode *dvp = ap->a_dvp;
|
||||
register struct componentname *cnp = ap->a_cnp;
|
||||
register struct inode *ip, *dp;
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct vnode *dvp = ap->a_dvp;
|
||||
struct componentname *cnp = ap->a_cnp;
|
||||
struct inode *ip, *dp;
|
||||
int error;
|
||||
|
||||
ip = VTOI(vp);
|
||||
|
Loading…
Reference in New Issue
Block a user