Changeset View
Changeset View
Standalone View
Standalone View
sys/ufs/ufs/ufs_vnops.c
Show First 20 Lines • Show All 1,420 Lines • ▼ Show 20 Lines | if (error) { | ||||
tdp->i_effnlink++; | tdp->i_effnlink++; | ||||
if (DOINGSOFTDEP(tdvp)) | if (DOINGSOFTDEP(tdvp)) | ||||
softdep_change_linkcnt(tdp); | softdep_change_linkcnt(tdp); | ||||
} | } | ||||
tip->i_effnlink++; | tip->i_effnlink++; | ||||
if (DOINGSOFTDEP(tvp)) | if (DOINGSOFTDEP(tvp)) | ||||
softdep_change_linkcnt(tip); | softdep_change_linkcnt(tip); | ||||
} | } | ||||
goto bad; | |||||
} | } | ||||
if (doingdirectory && !DOINGSOFTDEP(tvp)) { | if (doingdirectory && !DOINGSOFTDEP(tvp)) { | ||||
/* | /* | ||||
* The only stuff left in the directory is "." | * The only stuff left in the directory is "." | ||||
* and "..". The "." reference is inconsequential | * and "..". The "." reference is inconsequential | ||||
* since we are quashing it. We have removed the "." | * since we are quashing it. We have removed the "." | ||||
* reference and the reference in the parent directory, | * reference and the reference in the parent directory, | ||||
* but there may be other hard links. The soft | * but there may be other hard links. The soft | ||||
▲ Show 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | if (tvp) | ||||
vput(tvp); | vput(tvp); | ||||
/* | /* | ||||
* If compaction or fsync was requested do it now that other locks | * If compaction or fsync was requested do it now that other locks | ||||
* are no longer needed. | * are no longer needed. | ||||
*/ | */ | ||||
if (error == 0 && endoff != 0) { | if (error == 0 && endoff != 0) { | ||||
error = UFS_TRUNCATE(tdvp, endoff, IO_NORMAL | | error = UFS_TRUNCATE(tdvp, endoff, IO_NORMAL | | ||||
(DOINGASYNC(tdvp) ? 0 : IO_SYNC), tcnp->cn_cred); | (DOINGASYNC(tdvp) ? 0 : IO_SYNC), tcnp->cn_cred); | ||||
if (error != 0) | if (error != 0 && !ffs_fsfail_cleanup(VFSTOUFS(mp), error)) | ||||
vn_printf(tdvp, | vn_printf(tdvp, | ||||
"ufs_rename: failed to truncate, error %d\n", | "ufs_rename: failed to truncate, error %d\n", | ||||
error); | error); | ||||
#ifdef UFS_DIRHASH | #ifdef UFS_DIRHASH | ||||
if (error != 0) | |||||
ufsdirhash_free(tdp); | |||||
else if (tdp->i_dirhash != NULL) | else if (tdp->i_dirhash != NULL) | ||||
ufsdirhash_dirtrunc(tdp, endoff); | ufsdirhash_dirtrunc(tdp, endoff); | ||||
#endif | #endif | ||||
/* | /* | ||||
* Even if the directory compaction failed, rename was | * Even if the directory compaction failed, rename was | ||||
* succesful. Do not propagate a UFS_TRUNCATE() error | * succesful. Do not propagate a UFS_TRUNCATE() error | ||||
* to the caller. | * to the caller. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 1,184 Lines • ▼ Show 20 Lines | ufs_ioctl(struct vop_ioctl_args *ap) | ||||
case FIOSEEKHOLE: | case FIOSEEKHOLE: | ||||
return (vn_bmap_seekhole(vp, ap->a_command, (off_t *)ap->a_data, | return (vn_bmap_seekhole(vp, ap->a_command, (off_t *)ap->a_data, | ||||
ap->a_cred)); | ap->a_cred)); | ||||
default: | default: | ||||
return (ENOTTY); | return (ENOTTY); | ||||
} | } | ||||
} | } | ||||
static int | |||||
ufs_putpages(struct vop_putpages_args *ap) | |||||
kib: Is this needed ? stdputpages() does VOP_WRITE(), wouldn't you catch error/convert to ENXIO… | |||||
chsAuthorUnsubmitted Done Inline ActionsOnce we enter this error recovery mode, FFS pretends that all disk writes succeed, so we need to explicitly check if we're in the recovery mode in order to return an error in the paths that should. ffs_write() doesn't have such a check so we wanted one here so that msync() can return an error in this case. It occurs to me that ffs_write() ought to have an explicit check for recovery mode for the benefit of write() with O_SYNC, and then that check there would also do the right thing for msync() without a special vop_putpages. I'll change it that way. chs: Once we enter this error recovery mode, FFS pretends that all disk writes succeed, so we need… | |||||
{ | |||||
int error; | |||||
error = vop_stdputpages(ap); | |||||
if (ffs_fsfail_cleanup(VFSTOUFS(ap->a_vp->v_mount), error)) | |||||
error = ENXIO; | |||||
return (error); | |||||
} | |||||
/* Global vfs data structures for ufs. */ | /* Global vfs data structures for ufs. */ | ||||
struct vop_vector ufs_vnodeops = { | struct vop_vector ufs_vnodeops = { | ||||
.vop_default = &default_vnodeops, | .vop_default = &default_vnodeops, | ||||
.vop_fsync = VOP_PANIC, | .vop_fsync = VOP_PANIC, | ||||
.vop_read = VOP_PANIC, | .vop_read = VOP_PANIC, | ||||
.vop_reallocblks = VOP_PANIC, | .vop_reallocblks = VOP_PANIC, | ||||
.vop_write = VOP_PANIC, | .vop_write = VOP_PANIC, | ||||
.vop_accessx = ufs_accessx, | .vop_accessx = ufs_accessx, | ||||
Show All 9 Lines | struct vop_vector ufs_vnodeops = { | ||||
.vop_mmapped = ufs_mmapped, | .vop_mmapped = ufs_mmapped, | ||||
.vop_mkdir = ufs_mkdir, | .vop_mkdir = ufs_mkdir, | ||||
.vop_mknod = ufs_mknod, | .vop_mknod = ufs_mknod, | ||||
.vop_need_inactive = ufs_need_inactive, | .vop_need_inactive = ufs_need_inactive, | ||||
.vop_open = ufs_open, | .vop_open = ufs_open, | ||||
.vop_pathconf = ufs_pathconf, | .vop_pathconf = ufs_pathconf, | ||||
.vop_poll = vop_stdpoll, | .vop_poll = vop_stdpoll, | ||||
.vop_print = ufs_print, | .vop_print = ufs_print, | ||||
.vop_putpages = ufs_putpages, | |||||
.vop_readdir = ufs_readdir, | .vop_readdir = ufs_readdir, | ||||
.vop_readlink = ufs_readlink, | .vop_readlink = ufs_readlink, | ||||
.vop_reclaim = ufs_reclaim, | .vop_reclaim = ufs_reclaim, | ||||
.vop_remove = ufs_remove, | .vop_remove = ufs_remove, | ||||
.vop_rename = ufs_rename, | .vop_rename = ufs_rename, | ||||
.vop_rmdir = ufs_rmdir, | .vop_rmdir = ufs_rmdir, | ||||
.vop_setattr = ufs_setattr, | .vop_setattr = ufs_setattr, | ||||
#ifdef MAC | #ifdef MAC | ||||
▲ Show 20 Lines • Show All 47 Lines • Show Last 20 Lines |
Is this needed ? stdputpages() does VOP_WRITE(), wouldn't you catch error/convert to ENXIO there already ?