Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F111607984
D26136.id76043.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D26136.id76043.diff
View Options
Index: sys/ufs/ffs/ffs_snapshot.c
===================================================================
--- sys/ufs/ffs/ffs_snapshot.c
+++ sys/ufs/ffs/ffs_snapshot.c
@@ -368,8 +368,12 @@
if (error)
goto out;
bawrite(nbp);
- if (cg % 10 == 0)
- ffs_syncvnode(vp, MNT_WAIT, 0);
+ if (cg % 10 == 0) {
+ error = ffs_syncvnode(vp, MNT_WAIT, 0);
+ /* vp possibly reclaimed if unlocked */
+ if (error != 0)
+ goto out;
+ }
}
/*
* Copy all the cylinder group maps. Although the
@@ -391,8 +395,8 @@
goto out;
error = cgaccount(cg, vp, nbp, 1);
bawrite(nbp);
- if (cg % 10 == 0)
- ffs_syncvnode(vp, MNT_WAIT, 0);
+ if (cg % 10 == 0 && error == 0)
+ error = ffs_syncvnode(vp, MNT_WAIT, 0);
if (error)
goto out;
}
Index: sys/ufs/ffs/ffs_softdep.c
===================================================================
--- sys/ufs/ffs/ffs_softdep.c
+++ sys/ufs/ffs/ffs_softdep.c
@@ -748,7 +748,7 @@
static void clear_unlinked_inodedep(struct inodedep *);
static struct inodedep *first_unlinked_inodedep(struct ufsmount *);
static int flush_pagedep_deps(struct vnode *, struct mount *,
- struct diraddhd *);
+ struct diraddhd *, struct buf *);
static int free_pagedep(struct pagedep *);
static int flush_newblk_dep(struct vnode *, struct mount *, ufs_lbn_t);
static int flush_inodedep_deps(struct vnode *, struct mount *, ino_t);
@@ -1389,6 +1389,60 @@
/* List of all filesystems mounted with soft updates */
static TAILQ_HEAD(, mount_softdeps) softdepmounts;
+static int
+get_parent_vp(struct vnode *vp, struct mount *mp, ino_t inum, struct buf *bp,
+ struct vnode **rvp)
+{
+ struct vnode *pvp;
+ int error;
+
+ ASSERT_VOP_ELOCKED(vp, "child vnode must be locked");
+ for (;;) {
+ error = ffs_vgetf(mp, inum, LK_EXCLUSIVE | LK_NOWAIT, &pvp,
+ FFSV_FORCEINSMQ);
+ if (error == 0) {
+ KASSERT(VTOI(pvp)->i_mode != 0,
+ ("vnode %p/ino %jx is not fully constructed",
+ vp, (uintmax_t)inum));
+ *rvp = pvp;
+ return (0);
+ }
+ VOP_UNLOCK(vp);
+ if (bp != NULL) {
+ BUF_NOREC(bp);
+ BUF_UNLOCK(bp);
+ }
+ error = ffs_vgetf(mp, inum, LK_EXCLUSIVE, &pvp, FFSV_FORCEINSMQ);
+ if (error != 0) {
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ return (error);
+ }
+ KASSERT(VTOI(pvp)->i_mode != 0,
+ ("vnode %p/ino %jx is not fully constructed",
+ vp, (uintmax_t)inum));
+ error = vn_lock(vp, LK_EXCLUSIVE | LK_NOWAIT);
+ if (error == 0)
+ break;
+ vput(pvp);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ if (VN_IS_DOOMED(vp))
+ return (ENOENT);
+ }
+ if (VN_IS_DOOMED(vp)) {
+ if (error == 0)
+ vput(pvp);
+ error = ENOENT;
+ }
+ if (bp != NULL) {
+ if (error == 0)
+ vput(pvp);
+ error = ERESTART;
+ }
+ if (error == 0)
+ *rvp = pvp;
+ return (error);
+}
+
/*
* This function cleans the worklist for a filesystem.
* Each filesystem running with soft dependencies gets its own
@@ -12629,25 +12683,9 @@
* for details on possible races.
*/
FREE_LOCK(ump);
- if (ffs_vgetf(mp, parentino, LK_NOWAIT | LK_EXCLUSIVE, &pvp,
- FFSV_FORCEINSMQ)) {
- /*
- * Unmount cannot proceed after unlock because
- * caller must have called vn_start_write().
- */
- VOP_UNLOCK(vp);
- error = ffs_vgetf(mp, parentino, LK_EXCLUSIVE,
- &pvp, FFSV_FORCEINSMQ);
- MPASS(VTOI(pvp)->i_mode != 0);
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
- if (VN_IS_DOOMED(vp)) {
- if (error == 0)
- vput(pvp);
- error = ENOENT;
- }
- if (error != 0)
- return (error);
- }
+ error = get_parent_vp(vp, mp, parentino, NULL, &pvp);
+ if (error != 0)
+ return (error);
/*
* All MKDIR_PARENT dependencies and all the NEWBLOCK pagedeps
* that are contained in direct blocks will be resolved by
@@ -12972,9 +13010,11 @@
for (i = 0; i < DAHASHSZ; i++) {
if (LIST_FIRST(&pagedep->pd_diraddhd[i]) == 0)
continue;
- if ((error = flush_pagedep_deps(vp, wk->wk_mp,
- &pagedep->pd_diraddhd[i]))) {
- BUF_NOREC(bp);
+ error = flush_pagedep_deps(vp, wk->wk_mp,
+ &pagedep->pd_diraddhd[i], bp);
+ if (error != 0) {
+ if (error != ERESTART)
+ BUF_NOREC(bp);
goto out_unlock;
}
}
@@ -13208,10 +13248,11 @@
* Eliminate a pagedep dependency by flushing out all its diradd dependencies.
*/
static int
-flush_pagedep_deps(pvp, mp, diraddhdp)
+flush_pagedep_deps(pvp, mp, diraddhdp, locked_bp)
struct vnode *pvp;
struct mount *mp;
struct diraddhd *diraddhdp;
+ struct buf *locked_bp;
{
struct inodedep *inodedep;
struct inoref *inoref;
@@ -13278,10 +13319,9 @@
}
if (dap->da_state & MKDIR_BODY) {
FREE_LOCK(ump);
- if ((error = ffs_vgetf(mp, inum, LK_EXCLUSIVE, &vp,
- FFSV_FORCEINSMQ)))
+ error = get_parent_vp(pvp, mp, inum, locked_bp, &vp);
+ if (error != 0)
break;
- MPASS(VTOI(vp)->i_mode != 0);
error = flush_newblk_dep(vp, mp, 0);
/*
* If we still have the dependency we might need to
@@ -13343,10 +13383,9 @@
*/
if (dap == LIST_FIRST(diraddhdp)) {
FREE_LOCK(ump);
- if ((error = ffs_vgetf(mp, inum, LK_EXCLUSIVE, &vp,
- FFSV_FORCEINSMQ)))
+ error = get_parent_vp(pvp, mp, inum, locked_bp, &vp);
+ if (error != 0)
break;
- MPASS(VTOI(vp)->i_mode != 0);
error = ffs_update(vp, 1);
vput(vp);
if (error)
Index: sys/ufs/ffs/ffs_vnops.c
===================================================================
--- sys/ufs/ffs/ffs_vnops.c
+++ sys/ufs/ffs/ffs_vnops.c
@@ -325,6 +325,9 @@
if (!LIST_EMPTY(&bp->b_dep) &&
(error = softdep_sync_buf(vp, bp,
wait ? MNT_WAIT : MNT_NOWAIT)) != 0) {
+ /* Lock order conflict, buffer was already unlocked. */
+ if (error == ERESTART)
+ goto next;
/* I/O error. */
if (error != EBUSY) {
BUF_UNLOCK(bp);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Mar 6, 11:03 PM (14 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17021181
Default Alt Text
D26136.id76043.diff (5 KB)
Attached To
Mode
D26136: Handle LoR in flush_pagedep_deps().
Attached
Detach File
Event Timeline
Log In to Comment