Index: ufs_extattr.c
===================================================================
RCS file: /home/ncvs/src/sys/ufs/ufs/ufs_extattr.c,v
retrieving revision 1.17
diff -u -r1.17 ufs_extattr.c
--- ufs_extattr.c	2001/01/07 21:38:26	1.17
+++ ufs_extattr.c	2001/01/07 23:05:36
@@ -90,9 +90,9 @@
  * attribute.
  *
  * Invalid currently consists of:
- *         NULL pointer for attrname
- *         zero-length attrname (used to retrieve application attr list)
- *         attrname consisting of "$" (used to treive system attr list)
+ *	 NULL pointer for attrname
+ *	 zero-length attrname (used to retrieve application attr list)
+ *	 attrname consisting of "$" (used to treive system attr list)
  */
 static int
 ufs_extattr_valid_attrname(const char *attrname)
@@ -114,18 +114,18 @@
 static struct ufs_extattr_list_entry *
 ufs_extattr_find_attr(struct ufsmount *ump, const char *attrname)
 {
-        struct ufs_extattr_list_entry   *search_attribute;
+	struct ufs_extattr_list_entry   *search_attribute;
 
-        for (search_attribute = ump->um_extattr.uepm_list.lh_first;
+	for (search_attribute = ump->um_extattr.uepm_list.lh_first;
 	    search_attribute;
 	    search_attribute = search_attribute->uele_entries.le_next) {
-                if (!(strncmp(attrname, search_attribute->uele_attrname,
-                    UFS_EXTATTR_MAXEXTATTRNAME))) {
-                        return (search_attribute);
-                }
-        }
+		if (!(strncmp(attrname, search_attribute->uele_attrname,
+		    UFS_EXTATTR_MAXEXTATTRNAME))) {
+			return (search_attribute);
+		}
+	}
 
-        return (0);
+	return (0);
 }
 
 /*
@@ -217,10 +217,10 @@
 		goto unlock;
 	}
 
-        while (ump->um_extattr.uepm_list.lh_first != NULL) {
-                uele = ump->um_extattr.uepm_list.lh_first;
+	while (ump->um_extattr.uepm_list.lh_first != NULL) {
+		uele = ump->um_extattr.uepm_list.lh_first;
 		ufs_extattr_disable(ump, uele->uele_attrname, p);
-        }
+	}
 
 	ump->um_extattr.uepm_flags &= ~UFS_EXTATTR_UEPM_STARTED;
 
@@ -340,7 +340,7 @@
 	LIST_REMOVE(uele, uele_entries);
 
 	uele->uele_backing_vnode->v_flag &= ~VSYSTEM;
-        error = vn_close(uele->uele_backing_vnode, FREAD|FWRITE, p->p_ucred, p);
+	error = vn_close(uele->uele_backing_vnode, FREAD|FWRITE, p->p_ucred, p);
 
 	FREE(uele, M_UFS_EXTATTR);
 
@@ -455,11 +455,11 @@
 ufs_vop_getextattr(struct vop_getextattr_args *ap)
 /*
 vop_getextattr {
-        IN struct vnode *a_vp;
-        IN const char *a_name;
-        INOUT struct uio *a_uio;
-        IN struct ucred *a_cred;
-        IN struct proc *a_p;
+	IN struct vnode *a_vp;
+	IN const char *a_name;
+	INOUT struct uio *a_uio;
+	IN struct ucred *a_cred;
+	IN struct proc *a_p;
 };
 */
 {
@@ -574,7 +574,7 @@
 		 * is to coerce this to undefined, and let it get cleaned
 		 * up by the next write or extattrctl clean.
 		 */
-		printf("ufs_extattr: inode number inconsistency (%d, %d)\n",
+		printf("ufs_extattr_get: inode number inconsistency (%d, %d)\n",
 		    ueh.ueh_i_gen, ip->i_gen);
 		error = ENOENT;
 		goto vopunlock_exit;
@@ -621,11 +621,11 @@
 ufs_vop_setextattr(struct vop_setextattr_args *ap)
 /*
 vop_setextattr {
-        IN struct vnode *a_vp;
-        IN const char *a_name;
-        INOUT struct uio *a_uio;
-        IN struct ucred *a_cred;
-        IN struct proc *a_p;
+	IN struct vnode *a_vp;
+	IN const char *a_name;
+	INOUT struct uio *a_uio;
+	IN struct ucred *a_cred;
+	IN struct proc *a_p;
 };
 */
 {
@@ -683,7 +683,7 @@
 	/*
 	 * Early rejection of invalid offsets/lengths	
 	 * Reject: any offset but 0 (replace)
-	 *         Any size greater than attribute size limit
+	 *	 Any size greater than attribute size limit
  	 */
 	if (uio->uio_offset != 0 ||
 	    uio->uio_resid > attribute->uele_fileheader.uef_size)
@@ -829,12 +829,33 @@
 		goto vopunlock_exit;
 	}
 
+	/* valid for the current inode generation? */
+	if (ueh.ueh_i_gen != ip->i_gen) {
+		/*
+		 * The inode itself has a different generation number
+		 * than the attribute data.  For now, the best solution
+		 * is to coerce this to undefined, and let it get cleaned
+		 * up by the next write or extattrctl clean.
+		 */
+		printf("ufs_extattr_rm: inode number inconsistency (%d, %d)\n",
+		    ueh.ueh_i_gen, ip->i_gen);
+		error = ENOENT;
+		goto vopunlock_exit;
+	}
+
 	/* flag it as not in use */
 	ueh.ueh_flags = 0;
+	ueh.ueh_len = 0;
 
+	local_aiov.iov_base = (caddr_t) &ueh;
+	local_aiov.iov_len = sizeof(struct ufs_extattr_header);
+	local_aio.uio_iov = &local_aiov;
+	local_aio.uio_iovcnt = 1;
+	local_aio.uio_rw = UIO_WRITE;
+	local_aio.uio_segflg = UIO_SYSSPACE;
+	local_aio.uio_procp = p;
 	local_aio.uio_offset = base_offset;
 	local_aio.uio_resid = sizeof(struct ufs_extattr_header);
-	local_aio.uio_rw = UIO_WRITE;
 
 	error = VOP_WRITE(attribute->uele_backing_vnode, &local_aio,
 	    IO_NODELOCKED | IO_SYNC, ump->um_extattr.uepm_ucred);
@@ -862,7 +883,7 @@
 	struct ufsmount	*ump = VFSTOUFS(mp);
 
 	ufs_extattr_uepm_lock(ump, p);
-        
+	
 	if (!(ump->um_extattr.uepm_flags & UFS_EXTATTR_UEPM_STARTED)) {
 		ufs_extattr_uepm_unlock(ump, p);
 		return;

