FreeBSD/sys/ufs/ffs/ffs_vnops.c
/*
 * Vnode operation to remove a named attribute.
 */
Vnode operation to remove a named attribute.
Vnode operation to remove a named attribute .
static int
ffs_deleteextattr(struct vop_deleteextattr_args *ap)
{
	struct inode *ip;
	struct fs *fs;
	uint32_t ealength, ul;
	int ealen, olen, eapad1, eapad2, error, i, easize;
	u_char *eae, *p;
	ip = VTOI(ap->a_vp);
	fs = ip->i_fs;
	if (ap->a_vp->v_type == VCHR || ap->a_vp->v_type == VBLK)
		return (EOPNOTSUPP);
	if (strlen(ap->a_name) == 0)
		return (EINVAL);
	if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY)
		return (EROFS);
	error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace,
	    ap->a_cred, ap->a_td, VWRITE);
	if (error) {
		if (ip->i_ea_area != NULL && ip->i_ea_error == 0)
			ip->i_ea_error = error;
		return (error);
	}
	error = ffs_open_ea(ap->a_vp, ap->a_cred, ap->a_td);
	if (error)
		return (error);
	ealength = eapad1 = ealen = eapad2 = 0;
	eae = malloc(ip->i_ea_len, M_TEMP, M_WAITOK);
	bcopy(ip->i_ea_area, eae, ip->i_ea_len);
	easize = ip->i_ea_len;
	olen = ffs_findextattr(eae, easize, ap->a_attrnamespace, ap->a_name,
	    &p, NULL);
	if (olen == -1) {
		free(eae, M_TEMP);
		ffs_close_ea(ap->a_vp, 0, ap->a_cred, ap->a_td);
		return(ENOATTR);
	}
	bcopy(p, &ul, sizeof ul);
	i = p - eae + ul;
	if (ul != ealength) {
		bcopy(p + ul, p + ealength, easize - i);
		easize += (ealength - ul);
	}
	if (easize > NXADDR * fs->fs_bsize) {
		free(eae, M_TEMP);
		ffs_close_ea(ap->a_vp, 0, ap->a_cred, ap->a_td);
		if (ip->i_ea_area != NULL && ip->i_ea_error == 0)
			ip->i_ea_error = ENOSPC;
		return(ENOSPC);
	}
	p = ip->i_ea_area;
	ip->i_ea_area = eae;
	ip->i_ea_len = easize;
	free(p, M_TEMP);
	error = ffs_close_ea(ap->a_vp, 1, ap->a_cred, ap->a_td);
	return(error);
}
static int ffs_deleteextattr ( struct vop_deleteextattr_args * ap ) { struct inode * ip ; struct fs * fs ; uint32_t ealength , ul ; int ealen , olen , eapad1 , eapad2 , error , i , easize ; u_char * eae , * p ; ip = VTOI ( ap -> a_vp ) ; fs = ip -> i_fs ; if ( ap -> a_vp -> v_type == VCHR || ap -> a_vp -> v_type == VBLK ) return ( EOPNOTSUPP ) ; if ( strlen ( ap -> a_name ) == 0 ) return ( EINVAL ) ; if ( ap -> a_vp -> v_mount -> mnt_flag & MNT_RDONLY ) return ( EROFS ) ; error = extattr_check_cred ( ap -> a_vp , ap -> a_attrnamespace , ap -> a_cred , ap -> a_td , VWRITE ) ; if ( error ) { if ( ip -> i_ea_area != NULL && ip -> i_ea_error == 0 ) ip -> i_ea_error = error ; return ( error ) ; } error = ffs_open_ea ( ap -> a_vp , ap -> a_cred , ap -> a_td ) ; if ( error ) return ( error ) ; ealength = eapad1 = ealen = eapad2 = 0 ; eae = malloc ( ip -> i_ea_len , M_TEMP , M_WAITOK ) ; bcopy ( ip -> i_ea_area , eae , ip -> i_ea_len ) ; easize = ip -> i_ea_len ; olen = ffs_findextattr ( eae , easize , ap -> a_attrnamespace , ap -> a_name , & p , NULL ) ; if ( olen == -1 ) { free ( eae , M_TEMP ) ; ffs_close_ea ( ap -> a_vp , 0 , ap -> a_cred , ap -> a_td ) ; return ( ENOATTR ) ; } bcopy ( p , & ul , sizeof ul ) ; i = p - eae + ul ; if ( ul != ealength ) { bcopy ( p + ul , p + ealength , easize - i ) ; easize += ( ealength - ul ) ; } if ( easize > NXADDR * fs -> fs_bsize ) { free ( eae , M_TEMP ) ; ffs_close_ea ( ap -> a_vp , 0 , ap -> a_cred , ap -> a_td ) ; if ( ip -> i_ea_area != NULL && ip -> i_ea_error == 0 ) ip -> i_ea_error = ENOSPC ; return ( ENOSPC ) ; } p = ip -> i_ea_area ; ip -> i_ea_area = eae ; ip -> i_ea_len = easize ; free ( p , M_TEMP ) ; error = ffs_close_ea ( ap -> a_vp , 1 , ap -> a_cred , ap -> a_td ) ; return ( error ) ; }
Vnode operation to remove a named attribute.
Vnode operation to remove a named attribute .
/*
vop_deleteextattr {
	IN struct vnode *a_vp;
	IN int a_attrnamespace;
	IN const char *a_name;
	IN struct ucred *a_cred;
	IN struct thread *a_td;
};
*/ /*
		 * ffs_lock_ea is not needed there, because the vnode
		 * must be exclusively locked.
		 */ /* delete but nonexistent */