From owner-svn-src-stable-7@FreeBSD.ORG Sat Feb 14 20:59:50 2009 Return-Path: Delivered-To: svn-src-stable-7@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E4B9E10656CC; Sat, 14 Feb 2009 20:59:50 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id CFEDB8FC0C; Sat, 14 Feb 2009 20:59:50 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n1EKxovr030149; Sat, 14 Feb 2009 20:59:50 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n1EKxo5F030146; Sat, 14 Feb 2009 20:59:50 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <200902142059.n1EKxo5F030146@svn.freebsd.org> From: Konstantin Belousov Date: Sat, 14 Feb 2009 20:59:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r188611 - in stable/7/sys: . contrib/pf dev/ath/ath_hal dev/cxgb ufs/ffs X-BeenThere: svn-src-stable-7@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for only the 7-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 14 Feb 2009 20:59:52 -0000 Author: kib Date: Sat Feb 14 20:59:50 2009 New Revision: 188611 URL: http://svn.freebsd.org/changeset/base/188611 Log: MFC r182365: Softdep code may need to instantiate vnode when processing dependencies. In particular, it may need this while syncing filesystem being unmounted. Since during unmount MNTK_NOINSMNTQUE flag is set, that could sometimes disallow insertion of the vnode into the vnode mount list, softdep code needs to overwrite the MNTK_NOINSMNTQUE flag. Create the ffs_vgetf() function that sets the VV_FORCEINSMQ flag for new vnode and use it consistently from the softdep code instead of ffs_vget(). Add the retry logic to the softdep_flushfiles() to flush the vnodes that could be instantiated while flushing softdep dependencies. Modified: stable/7/sys/ (props changed) stable/7/sys/contrib/pf/ (props changed) stable/7/sys/dev/ath/ath_hal/ (props changed) stable/7/sys/dev/cxgb/ (props changed) stable/7/sys/ufs/ffs/ffs_extern.h stable/7/sys/ufs/ffs/ffs_softdep.c stable/7/sys/ufs/ffs/ffs_vfsops.c Modified: stable/7/sys/ufs/ffs/ffs_extern.h ============================================================================== --- stable/7/sys/ufs/ffs/ffs_extern.h Sat Feb 14 20:42:54 2009 (r188610) +++ stable/7/sys/ufs/ffs/ffs_extern.h Sat Feb 14 20:59:50 2009 (r188611) @@ -87,6 +87,9 @@ int ffs_valloc(struct vnode *, int, stru int ffs_vfree(struct vnode *, ino_t, int); vfs_vget_t ffs_vget; +int ffs_vgetf(struct mount *, ino_t, int, struct vnode **, int); + +#define FFSV_FORCEINSMQ 0x0001 extern struct vop_vector ffs_vnodeops1; extern struct vop_vector ffs_fifoops1; Modified: stable/7/sys/ufs/ffs/ffs_softdep.c ============================================================================== --- stable/7/sys/ufs/ffs/ffs_softdep.c Sat Feb 14 20:42:54 2009 (r188610) +++ stable/7/sys/ufs/ffs/ffs_softdep.c Sat Feb 14 20:59:50 2009 (r188611) @@ -921,8 +921,8 @@ process_worklist_item(mp, flags) wk->wk_state |= INPROGRESS; ump->softdep_on_worklist_inprogress++; FREE_LOCK(&lk); - ffs_vget(mp, WK_DIRREM(wk)->dm_oldinum, - LK_NOWAIT | LK_EXCLUSIVE, &vp); + ffs_vgetf(mp, WK_DIRREM(wk)->dm_oldinum, + LK_NOWAIT | LK_EXCLUSIVE, &vp, FFSV_FORCEINSMQ); ACQUIRE_LOCK(&lk); wk->wk_state &= ~INPROGRESS; ump->softdep_on_worklist_inprogress--; @@ -1076,8 +1076,11 @@ softdep_flushfiles(oldmnt, flags, td) int flags; struct thread *td; { - int error, count, loopcnt; + int error, depcount, loopcnt, retry_flush_count, retry; + loopcnt = 10; + retry_flush_count = 3; +retry_flush: error = 0; /* @@ -1086,15 +1089,15 @@ softdep_flushfiles(oldmnt, flags, td) * creates. In theory, this loop can happen at most twice, * but we give it a few extra just to be sure. */ - for (loopcnt = 10; loopcnt > 0; loopcnt--) { + for (; loopcnt > 0; loopcnt--) { /* * Do another flush in case any vnodes were brought in * as part of the cleanup operations. */ if ((error = ffs_flushfiles(oldmnt, flags, td)) != 0) break; - if ((error = softdep_flushworklist(oldmnt, &count, td)) != 0 || - count == 0) + if ((error = softdep_flushworklist(oldmnt, &depcount, td)) != 0 || + depcount == 0) break; } /* @@ -1109,6 +1112,24 @@ softdep_flushfiles(oldmnt, flags, td) } if (!error) error = softdep_waitidle(oldmnt); + if (!error) { + if (oldmnt->mnt_kern_flag & MNTK_UNMOUNT) { + retry = 0; + MNT_ILOCK(oldmnt); + KASSERT((oldmnt->mnt_kern_flag & MNTK_NOINSMNTQ) != 0, + ("softdep_flushfiles: !MNTK_NOINSMNTQ")); + if (oldmnt->mnt_nvnodelistsize > 0) { + if (--retry_flush_count > 0) { + retry = 1; + loopcnt = 3; + } else + error = EBUSY; + } + MNT_IUNLOCK(oldmnt); + if (retry) + goto retry_flush; + } + } return (error); } @@ -2777,8 +2798,9 @@ handle_workitem_freeblocks(freeblks, fla */ if (freeblks->fb_chkcnt != blocksreleased && (fs->fs_flags & FS_UNCLEAN) != 0 && - ffs_vget(freeblks->fb_list.wk_mp, freeblks->fb_previousinum, - (flags & LK_NOWAIT) | LK_EXCLUSIVE, &vp) == 0) { + ffs_vgetf(freeblks->fb_list.wk_mp, freeblks->fb_previousinum, + (flags & LK_NOWAIT) | LK_EXCLUSIVE, &vp, FFSV_FORCEINSMQ) + == 0) { ip = VTOI(vp); DIP_SET(ip, i_blocks, DIP(ip, i_blocks) + \ freeblks->fb_chkcnt - blocksreleased); @@ -3565,8 +3587,8 @@ handle_workitem_remove(dirrem, xp) int error; if ((vp = xp) == NULL && - (error = ffs_vget(dirrem->dm_list.wk_mp, - dirrem->dm_oldinum, LK_EXCLUSIVE, &vp)) != 0) { + (error = ffs_vgetf(dirrem->dm_list.wk_mp, + dirrem->dm_oldinum, LK_EXCLUSIVE, &vp, FFSV_FORCEINSMQ)) != 0) { softdep_error("handle_workitem_remove: vget", error); return; } @@ -5081,9 +5103,11 @@ softdep_fsync(vp) * for details on possible races. */ FREE_LOCK(&lk); - if (ffs_vget(mp, parentino, LK_NOWAIT | LK_EXCLUSIVE, &pvp)) { + if (ffs_vgetf(mp, parentino, LK_NOWAIT | LK_EXCLUSIVE, &pvp, + FFSV_FORCEINSMQ)) { VOP_UNLOCK(vp, 0, td); - error = ffs_vget(mp, parentino, LK_EXCLUSIVE, &pvp); + error = ffs_vgetf(mp, parentino, LK_EXCLUSIVE, + &pvp, FFSV_FORCEINSMQ); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); if (error != 0) return (error); @@ -5583,7 +5607,8 @@ flush_pagedep_deps(pvp, mp, diraddhdp) inum = dap->da_newinum; if (dap->da_state & MKDIR_BODY) { FREE_LOCK(&lk); - if ((error = ffs_vget(mp, inum, LK_EXCLUSIVE, &vp))) + if ((error = ffs_vgetf(mp, inum, LK_EXCLUSIVE, &vp, + FFSV_FORCEINSMQ))) break; if ((error=ffs_syncvnode(vp, MNT_NOWAIT)) || (error=ffs_syncvnode(vp, MNT_NOWAIT))) { @@ -5921,7 +5946,8 @@ clear_remove(td) if (vn_start_write(NULL, &mp, V_NOWAIT) != 0) continue; FREE_LOCK(&lk); - if ((error = ffs_vget(mp, ino, LK_EXCLUSIVE, &vp))) { + if ((error = ffs_vgetf(mp, ino, LK_EXCLUSIVE, &vp, + FFSV_FORCEINSMQ))) { softdep_error("clear_remove: vget", error); vn_finished_write(mp); ACQUIRE_LOCK(&lk); @@ -5992,7 +6018,8 @@ clear_inodedeps(td) if (vn_start_write(NULL, &mp, V_NOWAIT) != 0) continue; FREE_LOCK(&lk); - if ((error = ffs_vget(mp, ino, LK_EXCLUSIVE, &vp)) != 0) { + if ((error = ffs_vgetf(mp, ino, LK_EXCLUSIVE, &vp, + FFSV_FORCEINSMQ)) != 0) { softdep_error("clear_inodedeps: vget", error); vn_finished_write(mp); ACQUIRE_LOCK(&lk); Modified: stable/7/sys/ufs/ffs/ffs_vfsops.c ============================================================================== --- stable/7/sys/ufs/ffs/ffs_vfsops.c Sat Feb 14 20:42:54 2009 (r188610) +++ stable/7/sys/ufs/ffs/ffs_vfsops.c Sat Feb 14 20:59:50 2009 (r188611) @@ -1295,6 +1295,17 @@ ffs_vget(mp, ino, flags, vpp) int flags; struct vnode **vpp; { + return (ffs_vgetf(mp, ino, flags, vpp, 0)); +} + +int +ffs_vgetf(mp, ino, flags, vpp, ffs_flags) + struct mount *mp; + ino_t ino; + int flags; + struct vnode **vpp; + int ffs_flags; +{ struct fs *fs; struct inode *ip; struct ufsmount *ump; @@ -1369,13 +1380,16 @@ ffs_vget(mp, ino, flags, vpp) td = curthread; lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL, td); + if (ffs_flags & FFSV_FORCEINSMQ) + vp->v_vflag |= VV_FORCEINSMQ; error = insmntque(vp, mp); if (error != 0) { uma_zfree(uma_inode, ip); *vpp = NULL; return (error); } - error = vfs_hash_insert(vp, ino, flags, td, vpp, NULL, NULL); + vp->v_vflag &= ~VV_FORCEINSMQ; + error = vfs_hash_insert(vp, ino, flags, curthread, vpp, NULL, NULL); if (error || *vpp != NULL) return (error);