FreeBSD/sys/ufs/ufs/ufs_extattr.c
/*
 * Enable a named attribute on the specified filesystem; provide an
 * unlocked backing vnode to hold the attribute data.
 */
Enable a named attribute on the specified filesystem; provide an
unlocked backing vnode to hold the attribute data.
Enable a named attribute on the specified filesystem ; provide an unlocked backing vnode to hold the attribute data .
static int
ufs_extattr_enable(struct ufsmount *ump, int attrnamespace,
    const char *attrname, struct vnode *backing_vnode, struct thread *td)
{
	struct ufs_extattr_list_entry *attribute;
	struct iovec aiov;
	struct uio auio;
	int error = 0;
	if (!ufs_extattr_valid_attrname(attrnamespace, attrname))
		return (EINVAL);
	if (backing_vnode->v_type != VREG)
		return (EINVAL);
	attribute = malloc(sizeof(struct ufs_extattr_list_entry),
	    M_UFS_EXTATTR, M_WAITOK);
	if (!(ump->um_extattr.uepm_flags & UFS_EXTATTR_UEPM_STARTED)) {
		error = EOPNOTSUPP;
		goto free_exit;
	}
	if (ufs_extattr_find_attr(ump, attrnamespace, attrname)) {
		error = EEXIST;
		goto free_exit;
	}
	strncpy(attribute->uele_attrname, attrname,
	    UFS_EXTATTR_MAXEXTATTRNAME);
	attribute->uele_attrnamespace = attrnamespace;
	bzero(&attribute->uele_fileheader,
	    sizeof(struct ufs_extattr_fileheader));
	attribute->uele_backing_vnode = backing_vnode;
	auio.uio_iov = &aiov;
	auio.uio_iovcnt = 1;
	aiov.iov_base = (caddr_t) &attribute->uele_fileheader;
	aiov.iov_len = sizeof(struct ufs_extattr_fileheader);
	auio.uio_resid = sizeof(struct ufs_extattr_fileheader);
	auio.uio_offset = (off_t) 0;
	auio.uio_segflg = UIO_SYSSPACE;
	auio.uio_rw = UIO_READ;
	auio.uio_td = td;
	vn_lock(backing_vnode, LK_SHARED | LK_RETRY);
	error = VOP_READ(backing_vnode, &auio, IO_NODELOCKED,
	    ump->um_extattr.uepm_ucred);
	if (error)
		goto unlock_free_exit;
	if (auio.uio_resid != 0) {
		printf("ufs_extattr_enable: malformed attribute header\n");
		error = EINVAL;
		goto unlock_free_exit;
	}
	if (attribute->uele_fileheader.uef_magic != UFS_EXTATTR_MAGIC) {
		printf("ufs_extattr_enable: invalid attribute header magic\n");
		error = EINVAL;
		goto unlock_free_exit;
	}
	if (attribute->uele_fileheader.uef_version != UFS_EXTATTR_VERSION) {
		printf("ufs_extattr_enable: incorrect attribute header "
		    "version\n");
		error = EINVAL;
		goto unlock_free_exit;
	}
	ASSERT_VOP_LOCKED(backing_vnode, "ufs_extattr_enable");
	LIST_INSERT_HEAD(&ump->um_extattr.uepm_list, attribute,
	    uele_entries);
	VOP_UNLOCK(backing_vnode, 0);
	return (0);
unlock_free_exit:
	VOP_UNLOCK(backing_vnode, 0);
free_exit:
	free(attribute, M_UFS_EXTATTR);
	return (error);
}
static int ufs_extattr_enable ( struct ufsmount * ump , int attrnamespace , const char * attrname , struct vnode * backing_vnode , struct thread * td ) { struct ufs_extattr_list_entry * attribute ; struct iovec aiov ; struct uio auio ; int error = 0 ; if ( ! ufs_extattr_valid_attrname ( attrnamespace , attrname ) ) return ( EINVAL ) ; if ( backing_vnode -> v_type != VREG ) return ( EINVAL ) ; attribute = malloc ( sizeof ( struct ufs_extattr_list_entry ) , M_UFS_EXTATTR , M_WAITOK ) ; if ( ! ( ump -> um_extattr . uepm_flags & UFS_EXTATTR_UEPM_STARTED ) ) { error = EOPNOTSUPP ; goto free_exit ; } if ( ufs_extattr_find_attr ( ump , attrnamespace , attrname ) ) { error = EEXIST ; goto free_exit ; } strncpy ( attribute -> uele_attrname , attrname , UFS_EXTATTR_MAXEXTATTRNAME ) ; attribute -> uele_attrnamespace = attrnamespace ; bzero ( & attribute -> uele_fileheader , sizeof ( struct ufs_extattr_fileheader ) ) ; attribute -> uele_backing_vnode = backing_vnode ; auio . uio_iov = & aiov ; auio . uio_iovcnt = 1 ; aiov . iov_base = ( caddr_t ) & attribute -> uele_fileheader ; aiov . iov_len = sizeof ( struct ufs_extattr_fileheader ) ; auio . uio_resid = sizeof ( struct ufs_extattr_fileheader ) ; auio . uio_offset = ( off_t ) 0 ; auio . uio_segflg = UIO_SYSSPACE ; auio . uio_rw = UIO_READ ; auio . uio_td = td ; vn_lock ( backing_vnode , LK_SHARED | LK_RETRY ) ; error = VOP_READ ( backing_vnode , & auio , IO_NODELOCKED , ump -> um_extattr . uepm_ucred ) ; if ( error ) goto unlock_free_exit ; if ( auio . uio_resid != 0 ) { printf ( " \n " ) ; error = EINVAL ; goto unlock_free_exit ; } if ( attribute -> uele_fileheader . uef_magic != UFS_EXTATTR_MAGIC ) { printf ( " \n " ) ; error = EINVAL ; goto unlock_free_exit ; } if ( attribute -> uele_fileheader . uef_version != UFS_EXTATTR_VERSION ) { printf ( " " " \n " ) ; error = EINVAL ; goto unlock_free_exit ; } ASSERT_VOP_LOCKED ( backing_vnode , " " ) ; LIST_INSERT_HEAD ( & ump -> um_extattr . uepm_list , attribute , uele_entries ) ; VOP_UNLOCK ( backing_vnode , 0 ) ; return ( 0 ) ; unlock_free_exit : VOP_UNLOCK ( backing_vnode , 0 ) ; free_exit : free ( attribute , M_UFS_EXTATTR ) ; return ( error ) ; }
Enable a named attribute on the specified filesystem; provide an
 unlocked backing vnode to hold the attribute data.
Enable a named attribute on the specified filesystem ; provide an unlocked backing vnode to hold the attribute data .