summaryrefslogtreecommitdiffstats
path: root/sys/ufs/ufs
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2000-04-19 07:38:20 +0000
committerrwatson <rwatson@FreeBSD.org>2000-04-19 07:38:20 +0000
commit5b36470f2033fd9b5d9ae54ce79ef9909a5dba1b (patch)
tree6f17b83fa35f5dc6ebc20226718cadf028b0c3ae /sys/ufs/ufs
parent4d657494f01bde4f682e703a40361d3f4282999d (diff)
downloadFreeBSD-src-5b36470f2033fd9b5d9ae54ce79ef9909a5dba1b.zip
FreeBSD-src-5b36470f2033fd9b5d9ae54ce79ef9909a5dba1b.tar.gz
o Cause attribute data writes to use IO_SYNC since this improves the
chances of consistency with other file/directory meta-data in a write. In the current set of extended attribute applications, this does not hurt much. This should be discussed again later when it comes time to optimize performance of attributes. o Include an inode generation number in the per-attribute header information. This allows consistency verification to catch when a crash occurs, or an inode is recycled while attributes are not properly configured. For now, an irritating error message is displayed when an inconsistency occurs. At some point, may introduce an ``extattrctl check ...'' which catches these before attributes are enabled. Not today. If you get this message, it means you somehow managed to get your attribute backing file out of synch with the file system. When this occurs, attribute not found is returned (== undefined). Writes will overwrite the value there correcting the problem. Might want to think about introducing a new errno or two to handle this kind of situation. Discussed with: kris
Diffstat (limited to 'sys/ufs/ufs')
-rw-r--r--sys/ufs/ufs/extattr.h1
-rw-r--r--sys/ufs/ufs/ufs_extattr.c17
2 files changed, 17 insertions, 1 deletions
diff --git a/sys/ufs/ufs/extattr.h b/sys/ufs/ufs/extattr.h
index 4d3626d..6f3132b 100644
--- a/sys/ufs/ufs/extattr.h
+++ b/sys/ufs/ufs/extattr.h
@@ -59,6 +59,7 @@ struct ufs_extattr_fileheader {
struct ufs_extattr_header {
u_int ueh_flags; /* flags for attribute */
u_int ueh_len; /* local defined length; <= uef_size */
+ u_int32_t ueh_i_gen; /* generation number for sanity */
/* data follows the header */
};
diff --git a/sys/ufs/ufs/ufs_extattr.c b/sys/ufs/ufs/ufs_extattr.c
index 05b2b58..b12f062 100644
--- a/sys/ufs/ufs/ufs_extattr.c
+++ b/sys/ufs/ufs/ufs_extattr.c
@@ -490,6 +490,20 @@ ufs_extattr_get(struct vnode *vp, char *name, struct uio *uio,
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: inode number inconsistency (%d, %d)\n",
+ ueh.ueh_i_gen, ip->i_gen);
+ error = ENOENT;
+ goto vopunlock_exit;
+ }
+
/* local size consistency check */
if (ueh.ueh_len > attribute->uele_fileheader.uef_size) {
error = ENXIO;
@@ -621,6 +635,7 @@ ufs_extattr_set(struct vnode *vp, char *name, struct uio *uio,
*/
ueh.ueh_len = uio->uio_resid;
ueh.ueh_flags = UFS_EXTATTR_ATTR_FLAG_INUSE;
+ ueh.ueh_i_gen = ip->i_gen;
local_aiov.iov_base = (caddr_t) &ueh;
local_aiov.iov_len = sizeof(struct ufs_extattr_header);
local_aio.uio_iov = &local_aiov;
@@ -659,7 +674,7 @@ ufs_extattr_set(struct vnode *vp, char *name, struct uio *uio,
*/
uio->uio_offset = base_offset + sizeof(struct ufs_extattr_header);
- error = VOP_WRITE(attribute->uele_backing_vnode, uio, 0,
+ error = VOP_WRITE(attribute->uele_backing_vnode, uio, IO_SYNC,
ump->um_extattr.uepm_ucred);
vopunlock_exit:
OpenPOWER on IntegriCloud