Strange behaviour with sappend flag set on ZFS
Markus Gebert
markus.gebert at hostpoint.ch
Thu Sep 23 23:27:00 UTC 2010
On 23.09.2010, at 19:38, Michael Naef wrote:
> If I open (2) a file with O_APPEND the fd position pointer is set
> to the start of the file. When I then write to an fd on a ufs FS in
> FB6.4, it is automatically moved to the end and the bytes are
> appended. No problems appear with write to the sappend-flages file.
>
> However if I do the same on FB8.1/ZFS, the write fails as "not
> permitted".
To me, it seems that the zfs_write() VOP incorrectly uses FAPPEND instead of IO_APPEND when checking the ioflag argument to see if the current write is an appending one, here:
----
/*
* If immutable or not appending then return EPERM
*/
pflags = zp->z_phys->zp_flags;
if ((pflags & (ZFS_IMMUTABLE | ZFS_READONLY)) ||
((pflags & ZFS_APPENDONLY) && !(ioflag & FAPPEND) &&
(uio->uio_loffset < zp->z_phys->zp_size))) {
ZFS_EXIT(zfsvfs);
return (EPERM);
}
----
The function comment only mentions IO_APPEND and even later on in zfs_write() IO_APPEND is used to check wether the offset should be changed to EOF, so FAPPEND really seems to wrong in the above permission check.
CURRENT and STABLE-8 seem to be affected to. The following patch seems to fix it (at least Michi's test case works fine with it):
----
diff -ru ../src/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c ./sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
--- ../src/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c 2010-05-19 08:49:52.000000000 +0200
+++ ./sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c 2010-09-23 23:24:43.549846948 +0200
@@ -709,7 +709,7 @@
*/
pflags = zp->z_phys->zp_flags;
if ((pflags & (ZFS_IMMUTABLE | ZFS_READONLY)) ||
- ((pflags & ZFS_APPENDONLY) && !(ioflag & FAPPEND) &&
+ ((pflags & ZFS_APPENDONLY) && !(ioflag & IO_APPEND) &&
(uio->uio_loffset < zp->z_phys->zp_size))) {
ZFS_EXIT(zfsvfs);
return (EPERM);
----
Can someone commit this if the patch is ok? Or should I (or Michi) open a PR?
Markus
More information about the freebsd-fs
mailing list