Changeset View
Changeset View
Standalone View
Standalone View
sys/ufs/ffs/ffs_vfsops.c
Show First 20 Lines • Show All 1,024 Lines • ▼ Show 20 Lines | ffs_mountfs(odevvp, mp, td) | ||||
struct fsfail_task *etp; | struct fsfail_task *etp; | ||||
int candelete, canspeedup; | int candelete, canspeedup; | ||||
off_t loc; | off_t loc; | ||||
fs = NULL; | fs = NULL; | ||||
ump = NULL; | ump = NULL; | ||||
cred = td ? td->td_ucred : NOCRED; | cred = td ? td->td_ucred : NOCRED; | ||||
ronly = (mp->mnt_flag & MNT_RDONLY) != 0; | ronly = (mp->mnt_flag & MNT_RDONLY) != 0; | ||||
MNT_ILOCK(mp); | |||||
mp->mnt_kern_flag |= MNTK_USES_BCACHE; | |||||
MNT_IUNLOCK(mp); | |||||
devvp = mntfs_allocvp(mp, odevvp); | devvp = mntfs_allocvp(mp, odevvp); | ||||
VOP_UNLOCK(odevvp); | VOP_UNLOCK(odevvp); | ||||
KASSERT(devvp->v_type == VCHR, ("reclaimed devvp")); | KASSERT(devvp->v_type == VCHR, ("reclaimed devvp")); | ||||
dev = devvp->v_rdev; | dev = devvp->v_rdev; | ||||
KASSERT(dev->si_snapdata == NULL, ("non-NULL snapshot data")); | KASSERT(dev->si_snapdata == NULL, ("non-NULL snapshot data")); | ||||
if (atomic_cmpset_acq_ptr((uintptr_t *)&dev->si_mountpt, 0, | if (atomic_cmpset_acq_ptr((uintptr_t *)&dev->si_mountpt, 0, | ||||
(uintptr_t)mp) == 0) { | (uintptr_t)mp) == 0) { | ||||
mntfs_freevp(devvp); | mntfs_freevp(devvp); | ||||
return (EBUSY); | return (EBUSY); | ||||
} | } | ||||
g_topology_lock(); | g_topology_lock(); | ||||
error = g_vfs_open(devvp, &cp, "ffs", ronly ? 0 : 1); | error = g_vfs_open(devvp, &cp, "ffs", ronly ? 0 : 1); | ||||
g_topology_unlock(); | g_topology_unlock(); | ||||
if (error != 0) { | if (error != 0) { | ||||
atomic_store_rel_ptr((uintptr_t *)&dev->si_mountpt, 0); | atomic_store_rel_ptr((uintptr_t *)&dev->si_mountpt, 0); | ||||
mntfs_freevp(devvp); | mntfs_freevp(devvp); | ||||
return (error); | return (error); | ||||
} | } | ||||
dev_ref(dev); | dev_ref(dev); | ||||
devvp->v_bufobj.bo_ops = &ffs_ops; | vp2bo(devvp)->bo_ops = &ffs_ops; | ||||
BO_LOCK(&odevvp->v_bufobj); | BO_LOCK(vp2bo(odevvp)); | ||||
odevvp->v_bufobj.bo_flag |= BO_NOBUFS; | vp2bo(odevvp)->bo_flag |= BO_NOBUFS; | ||||
BO_UNLOCK(&odevvp->v_bufobj); | BO_UNLOCK(vp2bo(odevvp)); | ||||
if (dev->si_iosize_max != 0) | if (dev->si_iosize_max != 0) | ||||
mp->mnt_iosize_max = dev->si_iosize_max; | mp->mnt_iosize_max = dev->si_iosize_max; | ||||
if (mp->mnt_iosize_max > maxphys) | if (mp->mnt_iosize_max > maxphys) | ||||
mp->mnt_iosize_max = maxphys; | mp->mnt_iosize_max = maxphys; | ||||
if ((SBLOCKSIZE % cp->provider->sectorsize) != 0) { | if ((SBLOCKSIZE % cp->provider->sectorsize) != 0) { | ||||
error = EINVAL; | error = EINVAL; | ||||
vfs_mount_error(mp, | vfs_mount_error(mp, | ||||
"Invalid sectorsize %d for superblock size %d", | "Invalid sectorsize %d for superblock size %d", | ||||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | #else | ||||
printf("WARNING: %s: GJOURNAL flag on fs but no " | printf("WARNING: %s: GJOURNAL flag on fs but no " | ||||
"UFS_GJOURNAL support\n", mp->mnt_stat.f_mntonname); | "UFS_GJOURNAL support\n", mp->mnt_stat.f_mntonname); | ||||
#endif | #endif | ||||
} else { | } else { | ||||
mp->mnt_gjprovider = NULL; | mp->mnt_gjprovider = NULL; | ||||
} | } | ||||
ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK | M_ZERO); | ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK | M_ZERO); | ||||
ump->um_cp = cp; | ump->um_cp = cp; | ||||
ump->um_bo = &devvp->v_bufobj; | ump->um_bo = vp2bo(devvp); | ||||
ump->um_fs = fs; | ump->um_fs = fs; | ||||
if (fs->fs_magic == FS_UFS1_MAGIC) { | if (fs->fs_magic == FS_UFS1_MAGIC) { | ||||
ump->um_fstype = UFS1; | ump->um_fstype = UFS1; | ||||
ump->um_balloc = ffs_balloc_ufs1; | ump->um_balloc = ffs_balloc_ufs1; | ||||
} else { | } else { | ||||
ump->um_fstype = UFS2; | ump->um_fstype = UFS2; | ||||
ump->um_balloc = ffs_balloc_ufs2; | ump->um_balloc = ffs_balloc_ufs2; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | if (ump) { | ||||
mtx_destroy(UFS_MTX(ump)); | mtx_destroy(UFS_MTX(ump)); | ||||
if (mp->mnt_gjprovider != NULL) { | if (mp->mnt_gjprovider != NULL) { | ||||
free(mp->mnt_gjprovider, M_UFSMNT); | free(mp->mnt_gjprovider, M_UFSMNT); | ||||
mp->mnt_gjprovider = NULL; | mp->mnt_gjprovider = NULL; | ||||
} | } | ||||
free(ump, M_UFSMNT); | free(ump, M_UFSMNT); | ||||
mp->mnt_data = NULL; | mp->mnt_data = NULL; | ||||
} | } | ||||
BO_LOCK(&odevvp->v_bufobj); | BO_LOCK(vp2bo(odevvp)); | ||||
odevvp->v_bufobj.bo_flag &= ~BO_NOBUFS; | vp2bo(odevvp)->bo_flag &= ~BO_NOBUFS; | ||||
BO_UNLOCK(&odevvp->v_bufobj); | BO_UNLOCK(vp2bo(odevvp)); | ||||
atomic_store_rel_ptr((uintptr_t *)&dev->si_mountpt, 0); | atomic_store_rel_ptr((uintptr_t *)&dev->si_mountpt, 0); | ||||
mntfs_freevp(devvp); | mntfs_freevp(devvp); | ||||
dev_rel(dev); | dev_rel(dev); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* A read function for use by filesystem-layer routines. | * A read function for use by filesystem-layer routines. | ||||
▲ Show 20 Lines • Show All 189 Lines • ▼ Show 20 Lines | if (ump->um_fsckpid > 0) { | ||||
/* | /* | ||||
* Return to normal read-only mode. | * Return to normal read-only mode. | ||||
*/ | */ | ||||
error = g_access(ump->um_cp, 0, -1, 0); | error = g_access(ump->um_cp, 0, -1, 0); | ||||
ump->um_fsckpid = 0; | ump->um_fsckpid = 0; | ||||
} | } | ||||
g_vfs_close(ump->um_cp); | g_vfs_close(ump->um_cp); | ||||
g_topology_unlock(); | g_topology_unlock(); | ||||
BO_LOCK(&ump->um_odevvp->v_bufobj); | BO_LOCK(vp2bo(ump->um_odevvp)); | ||||
ump->um_odevvp->v_bufobj.bo_flag &= ~BO_NOBUFS; | vp2bo(ump->um_odevvp)->bo_flag &= ~BO_NOBUFS; | ||||
BO_UNLOCK(&ump->um_odevvp->v_bufobj); | BO_UNLOCK(vp2bo(ump->um_odevvp)); | ||||
atomic_store_rel_ptr((uintptr_t *)&ump->um_dev->si_mountpt, 0); | atomic_store_rel_ptr((uintptr_t *)&ump->um_dev->si_mountpt, 0); | ||||
mntfs_freevp(ump->um_devvp); | mntfs_freevp(ump->um_devvp); | ||||
vrele(ump->um_odevvp); | vrele(ump->um_odevvp); | ||||
dev_rel(ump->um_dev); | dev_rel(ump->um_dev); | ||||
mtx_destroy(UFS_MTX(ump)); | mtx_destroy(UFS_MTX(ump)); | ||||
if (mp->mnt_gjprovider != NULL) { | if (mp->mnt_gjprovider != NULL) { | ||||
free(mp->mnt_gjprovider, M_UFSMNT); | free(mp->mnt_gjprovider, M_UFSMNT); | ||||
mp->mnt_gjprovider = NULL; | mp->mnt_gjprovider = NULL; | ||||
▲ Show 20 Lines • Show All 287 Lines • ▼ Show 20 Lines | MNT_VNODE_FOREACH_ALL(vp, mp, mvp) { | ||||
*/ | */ | ||||
if (vp->v_type == VNON) { | if (vp->v_type == VNON) { | ||||
VI_UNLOCK(vp); | VI_UNLOCK(vp); | ||||
continue; | continue; | ||||
} | } | ||||
ip = VTOI(vp); | ip = VTOI(vp); | ||||
if ((ip->i_flag & | if ((ip->i_flag & | ||||
(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 && | (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 && | ||||
vp->v_bufobj.bo_dirty.bv_cnt == 0) { | vp2bo(vp)->bo_dirty.bv_cnt == 0) { | ||||
VI_UNLOCK(vp); | VI_UNLOCK(vp); | ||||
continue; | continue; | ||||
} | } | ||||
if ((error = vget(vp, lockreq)) != 0) { | if ((error = vget(vp, lockreq)) != 0) { | ||||
if (error == ENOENT || error == ENOLCK) { | if (error == ENOENT || error == ENOLCK) { | ||||
MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp); | MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp); | ||||
goto loop; | goto loop; | ||||
} | } | ||||
Show All 21 Lines | if (waitfor == MNT_WAIT || rebooting) { | ||||
if (ffs_fsfail_cleanup(ump, allerror)) | if (ffs_fsfail_cleanup(ump, allerror)) | ||||
allerror = 0; | allerror = 0; | ||||
/* Flushed work items may create new vnodes to clean */ | /* Flushed work items may create new vnodes to clean */ | ||||
if (allerror == 0 && count) | if (allerror == 0 && count) | ||||
goto loop; | goto loop; | ||||
} | } | ||||
devvp = ump->um_devvp; | devvp = ump->um_devvp; | ||||
bo = &devvp->v_bufobj; | bo = vp2bo(devvp); | ||||
BO_LOCK(bo); | BO_LOCK(bo); | ||||
if (bo->bo_numoutput > 0 || bo->bo_dirty.bv_cnt > 0) { | if (bo->bo_numoutput > 0 || bo->bo_dirty.bv_cnt > 0) { | ||||
BO_UNLOCK(bo); | BO_UNLOCK(bo); | ||||
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); | vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); | ||||
error = VOP_FSYNC(devvp, waitfor, td); | error = VOP_FSYNC(devvp, waitfor, td); | ||||
VOP_UNLOCK(devvp); | VOP_UNLOCK(devvp); | ||||
if (MOUNTEDSOFTDEP(mp) && (error == 0 || error == EAGAIN)) | if (MOUNTEDSOFTDEP(mp) && (error == 0 || error == EAGAIN)) | ||||
error = ffs_sbupdate(ump, waitfor, 0); | error = ffs_sbupdate(ump, waitfor, 0); | ||||
▲ Show 20 Lines • Show All 100 Lines • ▼ Show 20 Lines | if (error) { | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* FFS supports recursive locking. | * FFS supports recursive locking. | ||||
*/ | */ | ||||
lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL); | lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL); | ||||
VN_LOCK_AREC(vp); | VN_LOCK_AREC(vp); | ||||
vp->v_data = ip; | vp->v_data = ip; | ||||
vp->v_bufobj.bo_bsize = fs->fs_bsize; | vp2bo(vp)->bo_bsize = fs->fs_bsize; | ||||
ip->i_vnode = vp; | ip->i_vnode = vp; | ||||
ip->i_ump = ump; | ip->i_ump = ump; | ||||
ip->i_number = ino; | ip->i_number = ino; | ||||
ip->i_ea_refs = 0; | ip->i_ea_refs = 0; | ||||
ip->i_nextclustercg = -1; | ip->i_nextclustercg = -1; | ||||
ip->i_flag = fs->fs_magic == FS_UFS1_MAGIC ? 0 : IN_UFS2; | ip->i_flag = fs->fs_magic == FS_UFS1_MAGIC ? 0 : IN_UFS2; | ||||
ip->i_mode = 0; /* ensure error cases below throw away vnode */ | ip->i_mode = 0; /* ensure error cases below throw away vnode */ | ||||
cluster_init_vn(&ip->i_clusterw); | cluster_init_vn(&ip->i_clusterw); | ||||
▲ Show 20 Lines • Show All 711 Lines • Show Last 20 Lines |