diff options
author | kato <kato@FreeBSD.org> | 1997-09-04 03:14:49 +0000 |
---|---|---|
committer | kato <kato@FreeBSD.org> | 1997-09-04 03:14:49 +0000 |
commit | 6f2d2e6e949b7ca633a53be9630b0425ecae41a6 (patch) | |
tree | 9e9f04cf42fb39c6cef34eb31a55b6575493235f /sys/miscfs | |
parent | 01052674bd9cd2de028c4c476a70fa10439f5e6a (diff) | |
download | FreeBSD-src-6f2d2e6e949b7ca633a53be9630b0425ecae41a6.zip FreeBSD-src-6f2d2e6e949b7ca633a53be9630b0425ecae41a6.tar.gz |
Support read-only mount.
Diffstat (limited to 'sys/miscfs')
-rw-r--r-- | sys/miscfs/union/union_vnops.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/sys/miscfs/union/union_vnops.c b/sys/miscfs/union/union_vnops.c index f153f46..adaaa4f 100644 --- a/sys/miscfs/union/union_vnops.c +++ b/sys/miscfs/union/union_vnops.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * @(#)union_vnops.c 8.32 (Berkeley) 6/23/95 - * $Id: union_vnops.c,v 1.38 1997/08/15 02:36:28 kato Exp $ + * $Id: union_vnops.c,v 1.39 1997/09/02 20:06:13 bde Exp $ */ #include <sys/param.h> @@ -213,6 +213,14 @@ union_lookup(ap) int iswhiteout; struct vattr va; + + /* + * Disallow write attemps to the filesystem mounted read-only. + */ + if ((cnp->cn_flags & ISLASTCN) && (dvp->v_mount->mnt_flag & MNT_RDONLY) && + (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) + return (EROFS); + #ifdef notyet if (cnp->cn_namelen == 3 && cnp->cn_nameptr[2] == '.' && @@ -261,6 +269,17 @@ union_lookup(ap) } uerror = union_lookup1(um->um_uppervp, &upperdvp, &uppervp, cnp); + /* + * Disallow write attemps to the filesystem mounted read-only. + */ + if (uerror == EJUSTRETURN && (cnp->cn_flags & ISLASTCN) && + (dvp->v_mount->mnt_flag & MNT_RDONLY) && + (cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME)) { + if (!lockparent) + cnp->cn_flags &= ~LOCKPARENT; + return (EROFS); + } + if (cnp->cn_flags & ISDOTDOT) { if (dun->un_uppervp == upperdvp) { /* @@ -653,6 +672,15 @@ union_access(ap) struct vnode *vp; struct vnode *savedvp; + /* + * Disallow write attempts on filesystems mounted read-only. + */ + if (ap->a_mode & VWRITE && (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY)) { + switch (ap->a_vp->v_type) { + case VREG: case VDIR: case VLNK: + return (EROFS); + } + } if ((vp = un->un_uppervp) != NULLVP) { FIXUP(un, p); ap->a_vp = vp; @@ -765,9 +793,19 @@ union_setattr(ap) { struct union_node *un = VTOUNION(ap->a_vp); struct proc *p = ap->a_p; + struct vattr *vap = ap->a_vap; 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. |