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