mirror of
https://git.openafs.org/openafs.git
synced 2025-01-31 05:27:44 +00:00
viced: Check vnode length on dir ops
The commit aadf69eabb1962496fa93745ab560a5b48cacd61 added checks on vnode length whenever we read or write from a vnode. Add the same check on directory vnodes when we modify the directory (whenever entries are added or deleted). Change-Id: I8aa438941f840019bc541d5a978610c4f78330c8 Reviewed-on: http://gerrit.openafs.org/4233 Tested-by: BuildBot <buildbot@rampaginggeek.com> Reviewed-by: Derrick Brashear <shadow@dementia.org>
This commit is contained in:
parent
0f1c921fa1
commit
2578555d7e
@ -277,11 +277,52 @@ SetVolumeSync(struct AFSVolSync *async, Volume * avol)
|
||||
FS_UNLOCK;
|
||||
} /*SetVolumeSync */
|
||||
|
||||
/**
|
||||
* Verify that the on-disk size for a vnode matches the length in the vnode
|
||||
* index.
|
||||
*
|
||||
* @param[in] vp Volume pointer
|
||||
* @param[in] vnp Vnode pointer
|
||||
* @param[in] alen Size of the vnode on disk, if known. If unknown, give -1,
|
||||
* and CheckLength itself will determine the on-disk size.
|
||||
*
|
||||
* @return operation status
|
||||
* @retval 0 lengths match
|
||||
* @retval nonzero Error; either the lengths do not match or there was an
|
||||
* error determining the on-disk size. The volume should be
|
||||
* taken offline and salvaged.
|
||||
*/
|
||||
static int
|
||||
CheckLength(struct Volume *vp, struct Vnode *vnp, afs_sfsize_t alen)
|
||||
{
|
||||
afs_sfsize_t vlen;
|
||||
VN_GET_LEN(vlen, vnp);
|
||||
|
||||
if (alen < 0) {
|
||||
FdHandle_t *fdP;
|
||||
|
||||
fdP = IH_OPEN(vnp->handle);
|
||||
if (fdP == NULL) {
|
||||
ViceLog(0, ("CheckLength: cannot open inode for fid %lu.%lu.%lu\n",
|
||||
afs_printable_uint32_lu(vp->hashid),
|
||||
afs_printable_uint32_lu(Vn_id(vnp)),
|
||||
afs_printable_uint32_lu(vnp->disk.uniquifier)));
|
||||
return -1;
|
||||
}
|
||||
alen = FDH_SIZE(fdP);
|
||||
FDH_CLOSE(fdP);
|
||||
if (alen < 0) {
|
||||
afs_int64 alen64 = alen;
|
||||
ViceLog(0, ("CheckLength: cannot get size for inode for fid "
|
||||
"%lu.%lu.%lu; FDH_SIZE returned %" AFS_INT64_FMT "\n",
|
||||
afs_printable_uint32_lu(vp->hashid),
|
||||
afs_printable_uint32_lu(Vn_id(vnp)),
|
||||
afs_printable_uint32_lu(vnp->disk.uniquifier),
|
||||
alen64));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (alen != vlen) {
|
||||
afs_int64 alen64 = alen, vlen64 = vlen;
|
||||
ViceLog(0, ("Fid %lu.%lu.%lu has inconsistent length (index "
|
||||
@ -1368,6 +1409,12 @@ DeleteTarget(Vnode * parentptr, Volume * volptr, Vnode ** targetptr,
|
||||
/* watch for invalid names */
|
||||
if (!strcmp(Name, ".") || !strcmp(Name, ".."))
|
||||
return (EINVAL);
|
||||
|
||||
if (CheckLength(volptr, parentptr, -1)) {
|
||||
VTakeOffline_r(volptr);
|
||||
return VSALVAGE;
|
||||
}
|
||||
|
||||
if (parentptr->disk.cloned) {
|
||||
ViceLog(25, ("DeleteTarget : CopyOnWrite called\n"));
|
||||
if ((errorCode = CopyOnWrite(parentptr, volptr, 0, MAXFSIZE))) {
|
||||
@ -1779,6 +1826,12 @@ Alloc_NewVnode(Vnode * parentptr, DirHandle * dir, Volume * volptr,
|
||||
return (errorCode);
|
||||
}
|
||||
|
||||
if (CheckLength(volptr, parentptr, -1)) {
|
||||
VAdjustDiskUsage(&temp, volptr, -BlocksPreallocatedForVnode, 0);
|
||||
VTakeOffline_r(volptr);
|
||||
return VSALVAGE;
|
||||
}
|
||||
|
||||
*targetptr = VAllocVnode(&errorCode, volptr, FileType);
|
||||
if (errorCode != 0) {
|
||||
VAdjustDiskUsage(&temp, volptr, -BlocksPreallocatedForVnode, 0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user