viced: Check vnode length on read and write

When reading or writing a file vnode, check that the length of the
vnode in the vnode index matches the size of the on-disk file
containing the data for the file. If it does not match, take the
volume offline (and for DAFS, demand-salvage it).

Change-Id: I20e02cd84c8425cf0835c104a8e695a0cb6665d9
Reviewed-on: http://gerrit.openafs.org/4121
Tested-by: Andrew Deason <adeason@sinenomine.net>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>
This commit is contained in:
Andrew Deason 2011-03-03 16:02:47 -06:00 committed by Derrick Brashear
parent b2c979a9de
commit aadf69eabb

View File

@ -288,6 +288,25 @@ SetVolumeSync(struct AFSVolSync *async, Volume * avol)
FS_UNLOCK;
} /*SetVolumeSync */
static int
CheckLength(struct Volume *vp, struct Vnode *vnp, afs_sfsize_t alen)
{
afs_sfsize_t vlen;
VN_GET_LEN(vlen, vnp);
if (alen != vlen) {
afs_int64 alen64 = alen, vlen64 = vlen;
ViceLog(0, ("Fid %lu.%lu.%lu has inconsistent length (index "
"%" AFS_INT64_FMT ", inode %" AFS_INT64_FMT "); volume "
"must be salvaged\n",
afs_printable_uint32_lu(vp->hashid),
afs_printable_uint32_lu(Vn_id(vnp)),
afs_printable_uint32_lu(vnp->disk.uniquifier),
vlen64, alen64));
return -1;
}
return 0;
}
/*
* Note that this function always returns a held host, so
* that CallPostamble can block without the host's disappearing.
@ -7109,6 +7128,11 @@ FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
volptr->hashid));
return EIO;
}
if (CheckLength(volptr, targetptr, tlen)) {
FDH_CLOSE(fdP);
VTakeOffline(volptr);
return VSALVAGE;
}
if (Pos > tlen) {
Len = 0;
}
@ -7345,6 +7369,11 @@ StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
volptr->hashid));
return EIO;
}
if (CheckLength(volptr, targetptr, DataLength)) {
FDH_CLOSE(fdP);
VTakeOffline(volptr);
return VSALVAGE;
}
if (linkCount != 1) {
afs_fsize_t size;