summaryrefslogtreecommitdiffstats
path: root/sys/ufs/ufs/ufs_vnops.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/ufs/ufs/ufs_vnops.c')
-rw-r--r--sys/ufs/ufs/ufs_vnops.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index 0fac626..0c2da7d 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -331,7 +331,7 @@ ufs_access(ap)
}
/* If immutable bit set, nobody gets to write it. */
- if ((mode & VWRITE) && (ip->i_flags & IMMUTABLE))
+ if ((mode & VWRITE) && (ip->i_flags & (IMMUTABLE | SF_SNAPSHOT)))
return (EPERM);
/* Otherwise, user id 0 always gets access. */
@@ -454,6 +454,12 @@ ufs_setattr(ap)
& (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) &&
securelevel > 0)
return (EPERM);
+ /* Snapshot flag cannot be set or cleared */
+ if (((vap->va_flags & SF_SNAPSHOT) != 0 &&
+ (ip->i_flags & SF_SNAPSHOT) == 0) ||
+ ((vap->va_flags & SF_SNAPSHOT) == 0 &&
+ (ip->i_flags & SF_SNAPSHOT) != 0))
+ return (EPERM);
ip->i_flags = vap->va_flags;
} else {
if (ip->i_flags
@@ -491,6 +497,8 @@ ufs_setattr(ap)
case VREG:
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
+ if ((ip->i_flags & SF_SNAPSHOT) != 0)
+ return (EPERM);
break;
default:
break;
@@ -498,10 +506,11 @@ ufs_setattr(ap)
if ((error = UFS_TRUNCATE(vp, vap->va_size, 0, cred, p)) != 0)
return (error);
}
- ip = VTOI(vp);
if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
+ if ((ip->i_flags & SF_SNAPSHOT) != 0)
+ return (EPERM);
if (cred->cr_uid != ip->i_uid &&
(error = suser_xxx(cred, p, PRISON_ROOT)) &&
((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
@@ -528,6 +537,9 @@ ufs_setattr(ap)
if (vap->va_mode != (mode_t)VNOVAL) {
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
+ if ((ip->i_flags & SF_SNAPSHOT) != 0 && (vap->va_mode &
+ (S_IXUSR | S_IWUSR | S_IXGRP | S_IWGRP | S_IXOTH | S_IWOTH)))
+ return (EPERM);
error = ufs_chmod(vp, (int)vap->va_mode, cred, p);
}
VN_KNOTE(vp, NOTE_ATTRIB);
@@ -702,8 +714,6 @@ ufs_remove(ap)
int error;
ip = VTOI(vp);
- if ((ip->i_flags & SF_SNAPSHOT) != 0)
- ffs_snapremove(vp);
if ((ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND)) ||
(VTOI(dvp)->i_flags & APPEND)) {
error = EPERM;
OpenPOWER on IntegriCloud