From owner-svn-src-head@freebsd.org Thu Sep 8 12:01:30 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 393B3BD1B0D; Thu, 8 Sep 2016 12:01:30 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 10BA7ADF; Thu, 8 Sep 2016 12:01:29 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u88C1Tj2013853; Thu, 8 Sep 2016 12:01:29 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u88C1S2p013850; Thu, 8 Sep 2016 12:01:28 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201609081201.u88C1S2p013850@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Thu, 8 Sep 2016 12:01:28 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r305592 - head/sys/ufs/ffs X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 08 Sep 2016 12:01:30 -0000 Author: kib Date: Thu Sep 8 12:01:28 2016 New Revision: 305592 URL: https://svnweb.freebsd.org/changeset/base/305592 Log: Partially lift suspension when ffs_reload() finished with cgs and going to re-read inodes. Secondary write initiators, e.g. ufs_inactive(), might need to start a write while owning the vnode lock. Since the suspended state established by /dev/ufssuspend prevents them from entering vn_start_secondary_write(), we get deadlock otherwise. Note that it is arguably not very useful to re-read inodes after /dev/ufssuspend suspension, because the suspension does not block readers, and other threads might read existing files in parallel with suspension owner (for now, only growfs(8)) operations. This effectively means that suspension owner cannot safely modify existing inodes, and then there is no sense in re-reading. But keep the code enabled for now. Reported and tested by: pho Reviewed by: mckusick Sponsored by: The FreeBSD Foundation MFC after: 2 weeks Modified: head/sys/ufs/ffs/ffs_extern.h head/sys/ufs/ffs/ffs_suspend.c head/sys/ufs/ffs/ffs_vfsops.c Modified: head/sys/ufs/ffs/ffs_extern.h ============================================================================== --- head/sys/ufs/ffs/ffs_extern.h Thu Sep 8 12:00:02 2016 (r305591) +++ head/sys/ufs/ffs/ffs_extern.h Thu Sep 8 12:01:28 2016 (r305592) @@ -106,6 +106,9 @@ void ffs_susp_uninitialize(void); #define FFSV_FORCEINSMQ 0x0001 +#define FFSR_FORCE 0x0001 +#define FFSR_UNSUSPEND 0x0002 + extern struct vop_vector ffs_vnodeops1; extern struct vop_vector ffs_fifoops1; extern struct vop_vector ffs_vnodeops2; Modified: head/sys/ufs/ffs/ffs_suspend.c ============================================================================== --- head/sys/ufs/ffs/ffs_suspend.c Thu Sep 8 12:00:02 2016 (r305591) +++ head/sys/ufs/ffs/ffs_suspend.c Thu Sep 8 12:01:28 2016 (r305592) @@ -235,7 +235,7 @@ ffs_susp_dtor(void *data) KASSERT((mp->mnt_kern_flag & MNTK_SUSPEND) != 0, ("MNTK_SUSPEND not set")); - error = ffs_reload(mp, curthread, 1); + error = ffs_reload(mp, curthread, FFSR_FORCE | FFSR_UNSUSPEND); if (error != 0) panic("failed to unsuspend writes on %s", fs->fs_fsmnt); Modified: head/sys/ufs/ffs/ffs_vfsops.c ============================================================================== --- head/sys/ufs/ffs/ffs_vfsops.c Thu Sep 8 12:00:02 2016 (r305591) +++ head/sys/ufs/ffs/ffs_vfsops.c Thu Sep 8 12:01:28 2016 (r305592) @@ -573,11 +573,13 @@ ffs_cmount(struct mntarg *ma, void *data * 2) re-read superblock from disk. * 3) re-read summary information from disk. * 4) invalidate all inactive vnodes. - * 5) invalidate all cached file data. - * 6) re-read inode data for all active vnodes. + * 5) clear MNTK_SUSPEND2 and MNTK_SUSPENDED flags, allowing secondary + * writers, if requested. + * 6) invalidate all cached file data. + * 7) re-read inode data for all active vnodes. */ int -ffs_reload(struct mount *mp, struct thread *td, int force) +ffs_reload(struct mount *mp, struct thread *td, int flags) { struct vnode *vp, *mvp, *devvp; struct inode *ip; @@ -592,7 +594,7 @@ ffs_reload(struct mount *mp, struct thre ump = VFSTOUFS(mp); MNT_ILOCK(mp); - if ((mp->mnt_flag & MNT_RDONLY) == 0 && force == 0) { + if ((mp->mnt_flag & MNT_RDONLY) == 0 && (flags & FFSR_FORCE) == 0) { MNT_IUNLOCK(mp); return (EINVAL); } @@ -682,6 +684,12 @@ ffs_reload(struct mount *mp, struct thre size = fs->fs_ncg * sizeof(u_int8_t); fs->fs_contigdirs = (u_int8_t *)space; bzero(fs->fs_contigdirs, size); + if ((flags & FFSR_UNSUSPEND) != 0) { + MNT_ILOCK(mp); + mp->mnt_kern_flag &= ~(MNTK_SUSPENDED | MNTK_SUSPEND2); + wakeup(&mp->mnt_flag); + MNT_IUNLOCK(mp); + } loop: MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {