FreeBSD/sys/ufs/ffs/ffs_vnops.c
/*
 * Vnode extattr transaction commit/abort
 */
Vnode extattr transaction commit/abort
Vnode extattr transaction commit / abort
static int
ffs_close_ea(struct vnode *vp, int commit, struct ucred *cred, struct thread *td)
{
	struct inode *ip;
	struct uio luio;
	struct iovec liovec;
	int error;
	struct ufs2_dinode *dp;
	ip = VTOI(vp);
	ffs_lock_ea(vp);
	if (ip->i_ea_area == NULL) {
		ffs_unlock_ea(vp);
		return (EINVAL);
	}
	dp = ip->i_din2;
	error = ip->i_ea_error;
	if (commit && error == 0) {
		ASSERT_VOP_ELOCKED(vp, "ffs_close_ea commit");
		if (cred == NOCRED)
			cred =  vp->v_mount->mnt_cred;
		liovec.iov_base = ip->i_ea_area;
		liovec.iov_len = ip->i_ea_len;
		luio.uio_iov = &liovec;
		luio.uio_iovcnt = 1;
		luio.uio_offset = 0;
		luio.uio_resid = ip->i_ea_len;
		luio.uio_segflg = UIO_SYSSPACE;
		luio.uio_rw = UIO_WRITE;
		luio.uio_td = td;
		if (ip->i_ea_len < dp->di_extsize)
			error = ffs_truncate(vp, 0, IO_EXT, cred);
		error = ffs_extwrite(vp, &luio, IO_EXT | IO_SYNC, cred);
	}
	if (--ip->i_ea_refs == 0) {
		free(ip->i_ea_area, M_TEMP);
		ip->i_ea_area = NULL;
		ip->i_ea_len = 0;
		ip->i_ea_error = 0;
	}
	ffs_unlock_ea(vp);
	return (error);
}
static int ffs_close_ea ( struct vnode * vp , int commit , struct ucred * cred , struct thread * td ) { struct inode * ip ; struct uio luio ; struct iovec liovec ; int error ; struct ufs2_dinode * dp ; ip = VTOI ( vp ) ; ffs_lock_ea ( vp ) ; if ( ip -> i_ea_area == NULL ) { ffs_unlock_ea ( vp ) ; return ( EINVAL ) ; } dp = ip -> i_din2 ; error = ip -> i_ea_error ; if ( commit && error == 0 ) { ASSERT_VOP_ELOCKED ( vp , " " ) ; if ( cred == NOCRED ) cred = vp -> v_mount -> mnt_cred ; liovec . iov_base = ip -> i_ea_area ; liovec . iov_len = ip -> i_ea_len ; luio . uio_iov = & liovec ; luio . uio_iovcnt = 1 ; luio . uio_offset = 0 ; luio . uio_resid = ip -> i_ea_len ; luio . uio_segflg = UIO_SYSSPACE ; luio . uio_rw = UIO_WRITE ; luio . uio_td = td ; if ( ip -> i_ea_len < dp -> di_extsize ) error = ffs_truncate ( vp , 0 , IO_EXT , cred ) ; error = ffs_extwrite ( vp , & luio , IO_EXT | IO_SYNC , cred ) ; } if ( -- ip -> i_ea_refs == 0 ) { free ( ip -> i_ea_area , M_TEMP ) ; ip -> i_ea_area = NULL ; ip -> i_ea_len = 0 ; ip -> i_ea_error = 0 ; } ffs_unlock_ea ( vp ) ; return ( error ) ; }
Vnode extattr transaction commit/abort
Vnode extattr transaction commit / abort
/* XXX: I'm not happy about truncating to zero size */