CVS commit: src/sys/fs/union
Module Name:src Committed By: thorpej Date: Sat May 18 00:04:46 UTC 2024 Modified Files: src/sys/fs/union: union_vfsops.c Log Message: Remove unnecessary include of . To generate a diff of this commit: cvs rdiff -u -r1.87 -r1.88 src/sys/fs/union/union_vfsops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_vfsops.c diff -u src/sys/fs/union/union_vfsops.c:1.87 src/sys/fs/union/union_vfsops.c:1.88 --- src/sys/fs/union/union_vfsops.c:1.87 Mon Feb 13 08:39:40 2023 +++ src/sys/fs/union/union_vfsops.c Sat May 18 00:04:46 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vfsops.c,v 1.87 2023/02/13 08:39:40 hannken Exp $ */ +/* $NetBSD: union_vfsops.c,v 1.88 2024/05/18 00:04:46 thorpej Exp $ */ /* * Copyright (c) 1994 The Regents of the University of California. @@ -77,7 +77,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: union_vfsops.c,v 1.87 2023/02/13 08:39:40 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: union_vfsops.c,v 1.88 2024/05/18 00:04:46 thorpej Exp $"); #include #include @@ -87,7 +87,6 @@ __KERNEL_RCSID(0, "$NetBSD: union_vfsops #include #include #include -#include #include #include #include
CVS commit: src/sys/fs/union
Module Name:src Committed By: thorpej Date: Sat May 18 00:04:46 UTC 2024 Modified Files: src/sys/fs/union: union_vfsops.c Log Message: Remove unnecessary include of . To generate a diff of this commit: cvs rdiff -u -r1.87 -r1.88 src/sys/fs/union/union_vfsops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Mon Feb 13 08:39:40 UTC 2023 Modified Files: src/sys/fs/union: union_vfsops.c Log Message: When mounting a union file system set its lower mount only on success. Reported-by: syzbot+b81b69971581b4f4d...@syzkaller.appspotmail.com To generate a diff of this commit: cvs rdiff -u -r1.86 -r1.87 src/sys/fs/union/union_vfsops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_vfsops.c diff -u src/sys/fs/union/union_vfsops.c:1.86 src/sys/fs/union/union_vfsops.c:1.87 --- src/sys/fs/union/union_vfsops.c:1.86 Mon Feb 6 10:33:32 2023 +++ src/sys/fs/union/union_vfsops.c Mon Feb 13 08:39:40 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vfsops.c,v 1.86 2023/02/06 10:33:32 hannken Exp $ */ +/* $NetBSD: union_vfsops.c,v 1.87 2023/02/13 08:39:40 hannken Exp $ */ /* * Copyright (c) 1994 The Regents of the University of California. @@ -77,7 +77,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: union_vfsops.c,v 1.86 2023/02/06 10:33:32 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: union_vfsops.c,v 1.87 2023/02/13 08:39:40 hannken Exp $"); #include #include @@ -255,15 +255,16 @@ union_mount(struct mount *mp, const char mp->mnt_data = um; vfs_getnewfsid(mp); - error = vfs_set_lowermount(mp, um->um_uppervp->v_mount); - if (error) - goto bad; error = set_statvfs_info(path, UIO_USERSPACE, NULL, UIO_USERSPACE, mp->mnt_op->vfs_name, mp, l); if (error) goto bad; + error = vfs_set_lowermount(mp, um->um_uppervp->v_mount); + if (error) + goto bad; + switch (um->um_op) { case UNMNT_ABOVE: cp = ":";
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Mon Feb 13 08:39:40 UTC 2023 Modified Files: src/sys/fs/union: union_vfsops.c Log Message: When mounting a union file system set its lower mount only on success. Reported-by: syzbot+b81b69971581b4f4d...@syzkaller.appspotmail.com To generate a diff of this commit: cvs rdiff -u -r1.86 -r1.87 src/sys/fs/union/union_vfsops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Mon Feb 6 10:33:32 UTC 2023 Modified Files: src/sys/fs/union: union_vfsops.c Log Message: Set IMNT_MPSAFE only if all lower layers have it set. To generate a diff of this commit: cvs rdiff -u -r1.85 -r1.86 src/sys/fs/union/union_vfsops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_vfsops.c diff -u src/sys/fs/union/union_vfsops.c:1.85 src/sys/fs/union/union_vfsops.c:1.86 --- src/sys/fs/union/union_vfsops.c:1.85 Mon Nov 21 10:37:14 2022 +++ src/sys/fs/union/union_vfsops.c Mon Feb 6 10:33:32 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vfsops.c,v 1.85 2022/11/21 10:37:14 hannken Exp $ */ +/* $NetBSD: union_vfsops.c,v 1.86 2023/02/06 10:33:32 hannken Exp $ */ /* * Copyright (c) 1994 The Regents of the University of California. @@ -77,7 +77,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: union_vfsops.c,v 1.85 2022/11/21 10:37:14 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: union_vfsops.c,v 1.86 2023/02/06 10:33:32 hannken Exp $"); #include #include @@ -198,7 +198,14 @@ union_mount(struct mount *mp, const char goto bad; } - mp->mnt_iflag |= IMNT_MPSAFE; + /* + * This mount is mp-safe if both lower mounts are mp-safe. + */ + + if (((um->um_lowervp == NULLVP) || + (um->um_lowervp->v_mount->mnt_iflag & IMNT_MPSAFE)) && + (um->um_uppervp->v_mount->mnt_iflag & IMNT_MPSAFE)) + mp->mnt_iflag |= IMNT_MPSAFE; /* * Unless the mount is readonly, ensure that the top layer
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Mon Feb 6 10:33:32 UTC 2023 Modified Files: src/sys/fs/union: union_vfsops.c Log Message: Set IMNT_MPSAFE only if all lower layers have it set. To generate a diff of this commit: cvs rdiff -u -r1.85 -r1.86 src/sys/fs/union/union_vfsops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Mon Nov 21 10:37:14 UTC 2022 Modified Files: src/sys/fs/union: union_vfsops.c Log Message: When testing whiteout support on the underlying file system union_mount() should not use a NULL componentname as not all file systems can handle it. Use static { LOOKUP, NOCRED } componentname instead. Reported-by: syzbot+ecda308a1dd965283...@syzkaller.appspotmail.com Reported-by: syzbot+9b687847ee5f43e94...@syzkaller.appspotmail.com Reported-by: syzbot+9f9d1a841734f9f50...@syzkaller.appspotmail.com To generate a diff of this commit: cvs rdiff -u -r1.84 -r1.85 src/sys/fs/union/union_vfsops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_vfsops.c diff -u src/sys/fs/union/union_vfsops.c:1.84 src/sys/fs/union/union_vfsops.c:1.85 --- src/sys/fs/union/union_vfsops.c:1.84 Fri Nov 4 11:20:39 2022 +++ src/sys/fs/union/union_vfsops.c Mon Nov 21 10:37:14 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vfsops.c,v 1.84 2022/11/04 11:20:39 hannken Exp $ */ +/* $NetBSD: union_vfsops.c,v 1.85 2022/11/21 10:37:14 hannken Exp $ */ /* * Copyright (c) 1994 The Regents of the University of California. @@ -77,7 +77,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: union_vfsops.c,v 1.84 2022/11/04 11:20:39 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: union_vfsops.c,v 1.85 2022/11/21 10:37:14 hannken Exp $"); #include #include @@ -205,9 +205,13 @@ union_mount(struct mount *mp, const char * supports whiteout operations */ if ((mp->mnt_flag & MNT_RDONLY) == 0) { + static struct componentname nullcn = { + .cn_nameiop = LOOKUP, + .cn_cred = NOCRED + }; + vn_lock(um->um_uppervp, LK_EXCLUSIVE | LK_RETRY); - error = VOP_WHITEOUT(um->um_uppervp, - (struct componentname *) 0, LOOKUP); + error = VOP_WHITEOUT(um->um_uppervp, , LOOKUP); VOP_UNLOCK(um->um_uppervp); if (error) goto bad;
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Mon Nov 21 10:37:14 UTC 2022 Modified Files: src/sys/fs/union: union_vfsops.c Log Message: When testing whiteout support on the underlying file system union_mount() should not use a NULL componentname as not all file systems can handle it. Use static { LOOKUP, NOCRED } componentname instead. Reported-by: syzbot+ecda308a1dd965283...@syzkaller.appspotmail.com Reported-by: syzbot+9b687847ee5f43e94...@syzkaller.appspotmail.com Reported-by: syzbot+9f9d1a841734f9f50...@syzkaller.appspotmail.com To generate a diff of this commit: cvs rdiff -u -r1.84 -r1.85 src/sys/fs/union/union_vfsops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Re: CVS commit: src/sys/fs/union
Thanks for quick fix! rin On 2022/09/12 22:10, Christos Zoulas wrote: Yup! christos On Sep 12, 2022, at 5:04 AM, Rin Okuyama wrote: Hi, On 2022/09/12 0:42, Christos Zoulas wrote: @@ -420,11 +423,11 @@ union_statvfs(struct mount *mp, struct s { int error; struct union_mount *um = MOUNTTOUNIONMOUNT(mp); - struct statvfs *sbuf = malloc(sizeof(*sbuf), M_TEMP, M_WAITOK | M_ZERO); + struct statvfs *sbuf = kmem_alloc(sizeof(*sbuf), KM_SLEEP); unsigned long lbsize; #ifdef UNION_DIAGNOSTIC - printf("union_statvfs(mp = %p, lvp = %p, uvp = %p)\n", mp, + printf("%s(mp = %p, lvp = %p, uvp = %p)\n", __func__, mp, um->um_lowervp, um->um_uppervp); #endif kmem_zalloc() here? Thanks, rin
Re: CVS commit: src/sys/fs/union
Yup! christos > On Sep 12, 2022, at 5:04 AM, Rin Okuyama wrote: > > Hi, > > On 2022/09/12 0:42, Christos Zoulas wrote: >> @@ -420,11 +423,11 @@ union_statvfs(struct mount *mp, struct s >> { >> int error; >> struct union_mount *um = MOUNTTOUNIONMOUNT(mp); >> -struct statvfs *sbuf = malloc(sizeof(*sbuf), M_TEMP, M_WAITOK | M_ZERO); >> +struct statvfs *sbuf = kmem_alloc(sizeof(*sbuf), KM_SLEEP); >> unsigned long lbsize; >>#ifdef UNION_DIAGNOSTIC >> -printf("union_statvfs(mp = %p, lvp = %p, uvp = %p)\n", mp, >> +printf("%s(mp = %p, lvp = %p, uvp = %p)\n", __func__, mp, >> um->um_lowervp, um->um_uppervp); >> #endif >> > > kmem_zalloc() here? > > Thanks, > rin signature.asc Description: Message signed with OpenPGP
Re: CVS commit: src/sys/fs/union
Hi, On 2022/09/12 0:42, Christos Zoulas wrote: @@ -420,11 +423,11 @@ union_statvfs(struct mount *mp, struct s { int error; struct union_mount *um = MOUNTTOUNIONMOUNT(mp); - struct statvfs *sbuf = malloc(sizeof(*sbuf), M_TEMP, M_WAITOK | M_ZERO); + struct statvfs *sbuf = kmem_alloc(sizeof(*sbuf), KM_SLEEP); unsigned long lbsize; #ifdef UNION_DIAGNOSTIC - printf("union_statvfs(mp = %p, lvp = %p, uvp = %p)\n", mp, + printf("%s(mp = %p, lvp = %p, uvp = %p)\n", __func__, mp, um->um_lowervp, um->um_uppervp); #endif kmem_zalloc() here? Thanks, rin
CVS commit: src/sys/fs/union
Module Name:src Committed By: christos Date: Sun Sep 11 15:42:29 UTC 2022 Modified Files: src/sys/fs/union: union_vfsops.c Log Message: - avoid another credential leak on error from Chris J-D (chris at accessvector dot net) - KNF - use kmem To generate a diff of this commit: cvs rdiff -u -r1.81 -r1.82 src/sys/fs/union/union_vfsops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_vfsops.c diff -u src/sys/fs/union/union_vfsops.c:1.81 src/sys/fs/union/union_vfsops.c:1.82 --- src/sys/fs/union/union_vfsops.c:1.81 Mon Mar 16 17:20:10 2020 +++ src/sys/fs/union/union_vfsops.c Sun Sep 11 11:42:29 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vfsops.c,v 1.81 2020/03/16 21:20:10 pgoyette Exp $ */ +/* $NetBSD: union_vfsops.c,v 1.82 2022/09/11 15:42:29 christos Exp $ */ /* * Copyright (c) 1994 The Regents of the University of California. @@ -77,7 +77,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: union_vfsops.c,v 1.81 2020/03/16 21:20:10 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: union_vfsops.c,v 1.82 2022/09/11 15:42:29 christos Exp $"); #include #include @@ -122,7 +122,7 @@ union_mount(struct mount *mp, const char return EINVAL; #ifdef UNION_DIAGNOSTIC - printf("union_mount(mp = %p)\n", mp); + printf("%s(mp = %p)\n", __func__, mp); #endif if (mp->mnt_flag & MNT_GETARGS) { @@ -154,7 +154,7 @@ union_mount(struct mount *mp, const char * Find upper node. */ error = namei_simple_user(args->target, -NSM_FOLLOW_NOEMULROOT, ); + NSM_FOLLOW_NOEMULROOT, ); if (error != 0) goto bad; @@ -163,7 +163,7 @@ union_mount(struct mount *mp, const char goto bad; } - um = kmem_zalloc(sizeof(struct union_mount), KM_SLEEP); + um = kmem_zalloc(sizeof(*um), KM_SLEEP); /* * Keep a held reference to the target vnodes. @@ -246,7 +246,7 @@ union_mount(struct mount *mp, const char vfs_getnewfsid(mp); mp->mnt_lower = um->um_uppervp->v_mount; - error = set_statvfs_info( path, UIO_USERSPACE, NULL, UIO_USERSPACE, + error = set_statvfs_info(path, UIO_USERSPACE, NULL, UIO_USERSPACE, mp->mnt_op->vfs_name, mp, l); if (error) goto bad; @@ -264,7 +264,7 @@ union_mount(struct mount *mp, const char default: cp = ":"; #ifdef DIAGNOSTIC - panic("union_mount: bad um_op"); + panic("%s: bad um_op", __func__); #endif break; } @@ -278,7 +278,7 @@ union_mount(struct mount *mp, const char memset(xp + size, 0, len - size); #ifdef UNION_DIAGNOSTIC - printf("union_mount: from %s, on %s\n", + printf("%s: from %s, on %s\n", __func__, mp->mnt_stat.f_mntfromname, mp->mnt_stat.f_mntonname); #endif @@ -286,16 +286,19 @@ union_mount(struct mount *mp, const char if (!vn_union_readdir_hook) vn_union_readdir_hook = union_readdirhook; - return (0); + return 0; bad: - if (um) - kmem_free(um, sizeof(struct union_mount)); + if (um) { + if (um->um_cred) + kauth_cred_free(um->um_cred); + kmem_free(um, sizeof(*um)); + } if (upperrootvp) vrele(upperrootvp); if (lowerrootvp) vrele(lowerrootvp); - return (error); + return error; } /* @@ -308,7 +311,7 @@ int union_start(struct mount *mp, int flags) { - return (0); + return 0; } /* @@ -333,7 +336,7 @@ union_unmount(struct mount *mp, int mntf int error; #ifdef UNION_DIAGNOSTIC - printf("union_unmount(mp = %p)\n", mp); + printf("%s(mp = %p)\n", __func__, mp); #endif /* @@ -383,7 +386,7 @@ union_unmount(struct mount *mp, int mntf /* * Finally, throw away the union_mount structure */ - kmem_free(um, sizeof(struct union_mount)); + kmem_free(um, sizeof(*um)); mp->mnt_data = NULL; return 0; } @@ -401,7 +404,7 @@ union_root(struct mount *mp, int lktype, if (um->um_lowervp) vref(um->um_lowervp); error = union_allocvp(vpp, mp, NULL, NULL, NULL, - um->um_uppervp, um->um_lowervp, 1); + um->um_uppervp, um->um_lowervp, 1); if (error) { vrele(um->um_uppervp); @@ -420,11 +423,11 @@ union_statvfs(struct mount *mp, struct s { int error; struct union_mount *um = MOUNTTOUNIONMOUNT(mp); - struct statvfs *sbuf = malloc(sizeof(*sbuf), M_TEMP, M_WAITOK | M_ZERO); + struct statvfs *sbuf = kmem_alloc(sizeof(*sbuf), KM_SLEEP); unsigned long lbsize; #ifdef UNION_DIAGNOSTIC - printf("union_statvfs(mp = %p, lvp = %p, uvp = %p)\n", mp, + printf("%s(mp = %p, lvp = %p, uvp = %p)\n", __func__, mp, um->um_lowervp, um->um_uppervp); #endif @@ -468,29 +471,27 @@ union_statvfs(struct mount *mp, struct s copy_statvfs_info(sbp, mp); done: - free(sbuf, M_TEMP); + kmem_free(sbuf, sizeof(*sbuf)); return error; } /*ARGSUSED*/ int -union_sync(struct mount *mp, int waitfor, -kauth_cred_t cred) +union_sync(struct mount *mp, int waitfor, kauth_cred_t cred) { /* * XXX - Assumes no data cached at union layer. */ - return (0); + return 0; } /*ARGSUSED*/ int -union_vget(struct mount *mp, ino_t ino, int lktype, -
CVS commit: src/sys/fs/union
Module Name:src Committed By: christos Date: Sun Sep 11 15:42:29 UTC 2022 Modified Files: src/sys/fs/union: union_vfsops.c Log Message: - avoid another credential leak on error from Chris J-D (chris at accessvector dot net) - KNF - use kmem To generate a diff of this commit: cvs rdiff -u -r1.81 -r1.82 src/sys/fs/union/union_vfsops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Sat Mar 19 13:48:04 UTC 2022 Modified Files: src/sys/fs/union: union_subr.c union_vnops.c Log Message: As FSTRANS is part of VOP_*LOCK() since June 4, 2017 the vdead_check() from union_lock() is no longer needed. Adapt union_lock() to the recent addition of upgrade or downgrade. VV_LOCKSWORK now. To generate a diff of this commit: cvs rdiff -u -r1.79 -r1.80 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.82 -r1.83 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Sat Mar 19 13:48:04 UTC 2022 Modified Files: src/sys/fs/union: union_subr.c union_vnops.c Log Message: As FSTRANS is part of VOP_*LOCK() since June 4, 2017 the vdead_check() from union_lock() is no longer needed. Adapt union_lock() to the recent addition of upgrade or downgrade. VV_LOCKSWORK now. To generate a diff of this commit: cvs rdiff -u -r1.79 -r1.80 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.82 -r1.83 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.79 src/sys/fs/union/union_subr.c:1.80 --- src/sys/fs/union/union_subr.c:1.79 Tue Aug 18 09:44:07 2020 +++ src/sys/fs/union/union_subr.c Sat Mar 19 13:48:04 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.79 2020/08/18 09:44:07 hannken Exp $ */ +/* $NetBSD: union_subr.c,v 1.80 2022/03/19 13:48:04 hannken Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: union_subr.c,v 1.79 2020/08/18 09:44:07 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: union_subr.c,v 1.80 2022/03/19 13:48:04 hannken Exp $"); #include #include @@ -567,6 +567,7 @@ union_loadvnode(struct mount *mp, struct vp->v_tag = VT_UNION; vp->v_op = union_vnodeop_p; + vp->v_vflag |= VV_LOCKSWORK; vp->v_data = un; un->un_vnode = vp; Index: src/sys/fs/union/union_vnops.c diff -u src/sys/fs/union/union_vnops.c:1.82 src/sys/fs/union/union_vnops.c:1.83 --- src/sys/fs/union/union_vnops.c:1.82 Fri Dec 10 19:30:05 2021 +++ src/sys/fs/union/union_vnops.c Sat Mar 19 13:48:04 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vnops.c,v 1.82 2021/12/10 19:30:05 andvar Exp $ */ +/* $NetBSD: union_vnops.c,v 1.83 2022/03/19 13:48:04 hannken Exp $ */ /* * Copyright (c) 1992, 1993, 1994, 1995 @@ -72,7 +72,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.82 2021/12/10 19:30:05 andvar Exp $"); +__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.83 2022/03/19 13:48:04 hannken Exp $"); #include #include @@ -1709,15 +1709,6 @@ union_lock(void *v) lockvp = LOCKVP(vp); error = union_lock1(vp, lockvp, flags); mutex_exit(>un_lock); - if (error) - return error; - if (mutex_tryenter(vp->v_interlock)) { - error = vdead_check(vp, VDEAD_NOWAIT); - mutex_exit(vp->v_interlock); - } else - error = EBUSY; - if (error) - union_unlock1(vp, lockvp); return error; } @@ -1726,7 +1717,7 @@ union_lock(void *v) lockvp = LOCKVP(vp); mutex_exit(>un_lock); error = union_lock1(vp, lockvp, flags); - if (error != 0) + if (error != 0 || (flags & (LK_DOWNGRADE | LK_UPGRADE)) != 0) return error; mutex_enter(>un_lock); if (lockvp == LOCKVP(vp)) @@ -1735,14 +1726,6 @@ union_lock(void *v) } mutex_exit(>un_lock); - mutex_enter(vp->v_interlock); - error = vdead_check(vp, VDEAD_NOWAIT); - if (error) { - union_unlock1(vp, lockvp); - error = vdead_check(vp, 0); - KASSERT(error == ENOENT); - } - mutex_exit(vp->v_interlock); return error; }
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Fri Dec 10 09:20:38 UTC 2021 Modified Files: src/sys/fs/union: union_vnops.c Log Message: Fix previous, don't copy up if the underlying node is unreadable. To generate a diff of this commit: cvs rdiff -u -r1.80 -r1.81 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_vnops.c diff -u src/sys/fs/union/union_vnops.c:1.80 src/sys/fs/union/union_vnops.c:1.81 --- src/sys/fs/union/union_vnops.c:1.80 Sun Dec 5 16:16:58 2021 +++ src/sys/fs/union/union_vnops.c Fri Dec 10 09:20:38 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vnops.c,v 1.80 2021/12/05 16:16:58 hannken Exp $ */ +/* $NetBSD: union_vnops.c,v 1.81 2021/12/10 09:20:38 hannken Exp $ */ /* * Copyright (c) 1992, 1993, 1994, 1995 @@ -72,7 +72,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.80 2021/12/05 16:16:58 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.81 2021/12/10 09:20:38 hannken Exp $"); #include #include @@ -771,10 +771,20 @@ union_access(void *v) } } + /* + * Copy up to prevent checking (and failing) against + * underlying file system mounted read only. + * Check for read access first to prevent implicit + * copy of unaccessible underlying vnode. + */ if (un->un_uppervp == NULLVP && (un->un_lowervp->v_type == VREG) && (ap->a_accmode & VWRITE)) { - error = union_copyup(un, 1, ap->a_cred, curlwp); + vn_lock(un->un_lowervp, LK_EXCLUSIVE | LK_RETRY); + error = VOP_ACCESS(un->un_lowervp, VREAD, ap->a_cred); + VOP_UNLOCK(un->un_lowervp); + if (error == 0) + error = union_copyup(un, 1, ap->a_cred, curlwp); if (error) return error; }
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Fri Dec 10 09:20:38 UTC 2021 Modified Files: src/sys/fs/union: union_vnops.c Log Message: Fix previous, don't copy up if the underlying node is unreadable. To generate a diff of this commit: cvs rdiff -u -r1.80 -r1.81 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Sun Dec 5 16:16:58 UTC 2021 Modified Files: src/sys/fs/union: union_vnops.c Log Message: In union_access() copy up regular files before checking permissions. Unionfs is meant to provide a writable layer above a read-only layer and should not fail here just because the lower layer is mounted read-only. To generate a diff of this commit: cvs rdiff -u -r1.79 -r1.80 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Sun Dec 5 16:16:58 UTC 2021 Modified Files: src/sys/fs/union: union_vnops.c Log Message: In union_access() copy up regular files before checking permissions. Unionfs is meant to provide a writable layer above a read-only layer and should not fail here just because the lower layer is mounted read-only. To generate a diff of this commit: cvs rdiff -u -r1.79 -r1.80 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_vnops.c diff -u src/sys/fs/union/union_vnops.c:1.79 src/sys/fs/union/union_vnops.c:1.80 --- src/sys/fs/union/union_vnops.c:1.79 Wed Oct 20 03:08:17 2021 +++ src/sys/fs/union/union_vnops.c Sun Dec 5 16:16:58 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vnops.c,v 1.79 2021/10/20 03:08:17 thorpej Exp $ */ +/* $NetBSD: union_vnops.c,v 1.80 2021/12/05 16:16:58 hannken Exp $ */ /* * Copyright (c) 1992, 1993, 1994, 1995 @@ -72,7 +72,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.79 2021/10/20 03:08:17 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.80 2021/12/05 16:16:58 hannken Exp $"); #include #include @@ -771,6 +771,13 @@ union_access(void *v) } } + if (un->un_uppervp == NULLVP && + (un->un_lowervp->v_type == VREG) && + (ap->a_accmode & VWRITE)) { + error = union_copyup(un, 1, ap->a_cred, curlwp); + if (error) + return error; + } if ((vp = un->un_uppervp) != NULLVP) { ap->a_vp = vp;
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Sun Jul 4 11:24:09 UTC 2021 Modified Files: src/sys/fs/union: union_vnops.c Log Message: Fix union_parsepath(), either the upper or the lower dvp may be NULL. To generate a diff of this commit: cvs rdiff -u -r1.77 -r1.78 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_vnops.c diff -u src/sys/fs/union/union_vnops.c:1.77 src/sys/fs/union/union_vnops.c:1.78 --- src/sys/fs/union/union_vnops.c:1.77 Tue Jun 29 22:39:20 2021 +++ src/sys/fs/union/union_vnops.c Sun Jul 4 11:24:09 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vnops.c,v 1.77 2021/06/29 22:39:20 dholland Exp $ */ +/* $NetBSD: union_vnops.c,v 1.78 2021/07/04 11:24:09 hannken Exp $ */ /* * Copyright (c) 1992, 1993, 1994, 1995 @@ -72,7 +72,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.77 2021/06/29 22:39:20 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.78 2021/07/04 11:24:09 hannken Exp $"); #include #include @@ -213,14 +213,26 @@ union_parsepath(void *v) upperdvp = UPPERVP(ap->a_dvp); lowerdvp = LOWERVP(ap->a_dvp); - error = VOP_PARSEPATH(upperdvp, ap->a_name, ); - if (error) { - return error; + if (upperdvp != NULLVP) { + error = VOP_PARSEPATH(upperdvp, ap->a_name, ); + if (error) { + return error; + } + } else { + upper = 0; } - error = VOP_PARSEPATH(lowerdvp, ap->a_name, ); - if (error) { - return error; + if (lowerdvp != NULLVP) { + error = VOP_PARSEPATH(lowerdvp, ap->a_name, ); + if (error) { + return error; + } + } else { + lower = 0; + } + + if (upper == 0 && lower == 0) { + panic("%s: missing both layers", __func__); } /*
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Sun Jul 4 11:24:09 UTC 2021 Modified Files: src/sys/fs/union: union_vnops.c Log Message: Fix union_parsepath(), either the upper or the lower dvp may be NULL. To generate a diff of this commit: cvs rdiff -u -r1.77 -r1.78 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Tue Aug 18 09:44:07 UTC 2020 Modified Files: src/sys/fs/union: union.h union_subr.c union_vnops.c Log Message: Operation union_readdirhook() stores the lower directory as un_uppervp. This breaks the assumption that un_uppervp->v_mount is the upper mount. Fix by storing the directory as un_lowervp and adapt union_readdir(). Should fix PR kern/2: panic with union mount To generate a diff of this commit: cvs rdiff -u -r1.29 -r1.30 src/sys/fs/union/union.h cvs rdiff -u -r1.78 -r1.79 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.73 -r1.74 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Tue Aug 18 09:44:07 UTC 2020 Modified Files: src/sys/fs/union: union.h union_subr.c union_vnops.c Log Message: Operation union_readdirhook() stores the lower directory as un_uppervp. This breaks the assumption that un_uppervp->v_mount is the upper mount. Fix by storing the directory as un_lowervp and adapt union_readdir(). Should fix PR kern/2: panic with union mount To generate a diff of this commit: cvs rdiff -u -r1.29 -r1.30 src/sys/fs/union/union.h cvs rdiff -u -r1.78 -r1.79 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.73 -r1.74 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union.h diff -u src/sys/fs/union/union.h:1.29 src/sys/fs/union/union.h:1.30 --- src/sys/fs/union/union.h:1.29 Mon Jul 17 09:22:36 2017 +++ src/sys/fs/union/union.h Tue Aug 18 09:44:07 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: union.h,v 1.29 2017/07/17 09:22:36 hannken Exp $ */ +/* $NetBSD: union.h,v 1.30 2020/08/18 09:44:07 hannken Exp $ */ /* * Copyright (c) 1994 The Regents of the University of California. @@ -130,6 +130,7 @@ struct union_node { char *un_path; /* v: saved component name */ int un_openl; /* v: # of opens on lowervp */ unsigned int un_cflags; /* c: cache flags */ + bool un_hooknode; /* :: from union_readdirhook */ struct vnode **un_dircache; /* v: cached union stack */ off_t un_uppersz; /* l: size of upper object */ off_t un_lowersz; /* l: size of lower object */ Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.78 src/sys/fs/union/union_subr.c:1.79 --- src/sys/fs/union/union_subr.c:1.78 Sun Feb 23 15:46:41 2020 +++ src/sys/fs/union/union_subr.c Tue Aug 18 09:44:07 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.78 2020/02/23 15:46:41 ad Exp $ */ +/* $NetBSD: union_subr.c,v 1.79 2020/08/18 09:44:07 hannken Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: union_subr.c,v 1.78 2020/02/23 15:46:41 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: union_subr.c,v 1.79 2020/08/18 09:44:07 hannken Exp $"); #include #include @@ -480,6 +480,7 @@ found: un->un_dircache = 0; un->un_openl = 0; un->un_cflags = 0; + un->un_hooknode = false; un->un_uppersz = VNOVAL; un->un_lowersz = VNOVAL; @@ -1067,7 +1068,7 @@ union_dircache(struct vnode *vp, struct } else { vpp = dircache; do { - if (*vpp++ == VTOUNION(vp)->un_uppervp) + if (*vpp++ == VTOUNION(vp)->un_lowervp) break; } while (*vpp != NULLVP); } @@ -1076,10 +1077,12 @@ union_dircache(struct vnode *vp, struct goto out; vref(*vpp); - error = union_allocvp(, vp->v_mount, NULLVP, NULLVP, 0, *vpp, NULLVP, 0); + error = union_allocvp(, vp->v_mount, NULLVP, NULLVP, 0, + NULLVP, *vpp, 0); if (!error) { vn_lock(nvp, LK_EXCLUSIVE | LK_RETRY); VTOUNION(vp)->un_dircache = 0; + VTOUNION(nvp)->un_hooknode = true; VTOUNION(nvp)->un_dircache = dircache; } Index: src/sys/fs/union/union_vnops.c diff -u src/sys/fs/union/union_vnops.c:1.73 src/sys/fs/union/union_vnops.c:1.74 --- src/sys/fs/union/union_vnops.c:1.73 Sat May 16 18:31:50 2020 +++ src/sys/fs/union/union_vnops.c Tue Aug 18 09:44:07 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vnops.c,v 1.73 2020/05/16 18:31:50 christos Exp $ */ +/* $NetBSD: union_vnops.c,v 1.74 2020/08/18 09:44:07 hannken Exp $ */ /* * Copyright (c) 1992, 1993, 1994, 1995 @@ -72,7 +72,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.73 2020/05/16 18:31:50 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.74 2020/08/18 09:44:07 hannken Exp $"); #include #include @@ -1493,13 +1493,29 @@ union_readdir(void *v) int a_ncookies; } */ *ap = v; struct union_node *un = VTOUNION(ap->a_vp); - struct vnode *uvp = un->un_uppervp; + struct vnode *vp; + int dolock, error; - if (uvp == NULLVP) - return (0); + if (un->un_hooknode) { + KASSERT(un->un_uppervp == NULLVP); + KASSERT(un->un_lowervp != NULLVP); + vp = un->un_lowervp; + dolock = 1; + } else { + vp = un->un_uppervp; + dolock = 0; + } + if (vp == NULLVP) + return 0; - ap->a_vp = uvp; - return (VCALL(uvp, VOFFSET(vop_readdir), ap)); + if (dolock) + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); + ap->a_vp = vp; + error = VCALL(vp, VOFFSET(vop_readdir), ap); + if (dolock) + VOP_UNLOCK(vp); + + return error; } int
CVS commit: src/sys/fs/union
Module Name:src Committed By: christos Date: Sun Jan 28 15:48:44 UTC 2018 Modified Files: src/sys/fs/union: union_subr.c Log Message: CID-1428639: make sure we always initialiaze hash, because if ultimately the file is not found and we end up looping we need them. To generate a diff of this commit: cvs rdiff -u -r1.76 -r1.77 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.76 src/sys/fs/union/union_subr.c:1.77 --- src/sys/fs/union/union_subr.c:1.76 Mon Jul 17 05:22:36 2017 +++ src/sys/fs/union/union_subr.c Sun Jan 28 10:48:44 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.76 2017/07/17 09:22:36 hannken Exp $ */ +/* $NetBSD: union_subr.c,v 1.77 2018/01/28 15:48:44 christos Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: union_subr.c,v 1.76 2017/07/17 09:22:36 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: union_subr.c,v 1.77 2018/01/28 15:48:44 christos Exp $"); #include #include @@ -377,11 +377,6 @@ union_allocvp( lowervp = NULLVP; } - if (!docache) { - un = NULL; - goto found; - } - /* * If both uppervp and lowervp are not NULL we have to * search union nodes with one vnode as NULL too. @@ -394,6 +389,11 @@ union_allocvp( hash[2] = UNION_HASH(NULLVP, lowervp); } + if (!docache) { + un = NULL; + goto found; + } + loop: mutex_enter(_lock);
CVS commit: src/sys/fs/union
Module Name:src Committed By: christos Date: Sun Jan 28 15:48:44 UTC 2018 Modified Files: src/sys/fs/union: union_subr.c Log Message: CID-1428639: make sure we always initialiaze hash, because if ultimately the file is not found and we end up looping we need them. To generate a diff of this commit: cvs rdiff -u -r1.76 -r1.77 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Mon Jul 17 09:22:36 UTC 2017 Modified Files: src/sys/fs/union: union.h union_subr.c Log Message: Make union_newlower() ans union_newupper() local to union_subr.c, expand and remove union_updatevp() and take care to transfer the vnode lock from the union vnode to its new upper vnode without breaking the fstrans state. Add assertions that un_lowervp and un_uppervp never change from non-NULL to non-NULL. To generate a diff of this commit: cvs rdiff -u -r1.28 -r1.29 src/sys/fs/union/union.h cvs rdiff -u -r1.75 -r1.76 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Mon Jul 17 09:22:36 UTC 2017 Modified Files: src/sys/fs/union: union.h union_subr.c Log Message: Make union_newlower() ans union_newupper() local to union_subr.c, expand and remove union_updatevp() and take care to transfer the vnode lock from the union vnode to its new upper vnode without breaking the fstrans state. Add assertions that un_lowervp and un_uppervp never change from non-NULL to non-NULL. To generate a diff of this commit: cvs rdiff -u -r1.28 -r1.29 src/sys/fs/union/union.h cvs rdiff -u -r1.75 -r1.76 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union.h diff -u src/sys/fs/union/union.h:1.28 src/sys/fs/union/union.h:1.29 --- src/sys/fs/union/union.h:1.28 Mon Feb 16 10:22:00 2015 +++ src/sys/fs/union/union.h Mon Jul 17 09:22:36 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: union.h,v 1.28 2015/02/16 10:22:00 hannken Exp $ */ +/* $NetBSD: union.h,v 1.29 2017/07/17 09:22:36 hannken Exp $ */ /* * Copyright (c) 1994 The Regents of the University of California. @@ -158,8 +158,6 @@ extern int union_cn_close(struct vnode * struct lwp *); extern void union_removed_upper(struct union_node *un); extern struct vnode *union_lowervp(struct vnode *); -extern void union_newlower(struct union_node *, struct vnode *); -extern void union_newupper(struct union_node *, struct vnode *); extern void union_newsize(struct vnode *, off_t, off_t); int union_readdirhook(struct vnode **, struct file *, struct lwp *); Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.75 src/sys/fs/union/union_subr.c:1.76 --- src/sys/fs/union/union_subr.c:1.75 Thu Jun 1 02:45:13 2017 +++ src/sys/fs/union/union_subr.c Mon Jul 17 09:22:36 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.75 2017/06/01 02:45:13 chs Exp $ */ +/* $NetBSD: union_subr.c,v 1.76 2017/07/17 09:22:36 hannken Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: union_subr.c,v 1.75 2017/06/01 02:45:13 chs Exp $"); +__KERNEL_RCSID(0, "$NetBSD: union_subr.c,v 1.76 2017/07/17 09:22:36 hannken Exp $"); #include #include @@ -104,7 +104,8 @@ static u_long uhash_mask; /* size of ha static kmutex_t uhash_lock; -void union_updatevp(struct union_node *, struct vnode *, struct vnode *); +static void union_newupper(struct union_node *, struct vnode *); +static void union_newlower(struct union_node *, struct vnode *); static void union_ref(struct union_node *); static void union_rele(struct union_node *); static int union_do_lookup(struct vnode *, struct componentname *, kauth_cred_t,const char *); @@ -160,71 +161,28 @@ union_done(void) } void -union_updatevp(struct union_node *un, struct vnode *uppervp, - struct vnode *lowervp) +union_newlower(struct union_node *un, struct vnode *lowervp) { int ohash = UNION_HASH(un->un_uppervp, un->un_lowervp); - int nhash = UNION_HASH(uppervp, lowervp); - int docache = (lowervp != NULLVP || uppervp != NULLVP); - bool un_unlock; + int nhash = UNION_HASH(un->un_uppervp, lowervp); + + if (un->un_lowervp == lowervp) + return; KASSERT(VOP_ISLOCKED(UNIONTOV(un)) == LK_EXCLUSIVE); + KASSERT(un->un_lowervp == NULL); mutex_enter(_lock); - if (!docache || ohash != nhash) { - if (un->un_cflags & UN_CACHED) { - un->un_cflags &= ~UN_CACHED; - LIST_REMOVE(un, un_cache); - } - } - - if (un->un_lowervp != lowervp) { - if (un->un_lowervp) { - vrele(un->un_lowervp); - if (un->un_path) { -free(un->un_path, M_TEMP); -un->un_path = 0; - } - if (un->un_dirvp) { -vrele(un->un_dirvp); -un->un_dirvp = NULLVP; - } - } - un->un_lowervp = lowervp; - mutex_enter(>un_lock); - un->un_lowersz = VNOVAL; - mutex_exit(>un_lock); - } - - if (un->un_uppervp != uppervp) { - if (un->un_uppervp) { - un_unlock = false; - vrele(un->un_uppervp); - } else - un_unlock = true; - - mutex_enter(>un_lock); - un->un_uppervp = uppervp; - mutex_exit(>un_lock); - if (un_unlock) { - struct vop_unlock_args ap; - - ap.a_vp = UNIONTOV(un); - genfs_unlock(); - } - mutex_enter(>un_lock); - un->un_uppersz = VNOVAL; - mutex_exit(>un_lock); - /* Update union vnode interlock. */ - if (uppervp != NULL) { - mutex_obj_hold(uppervp->v_interlock); - uvm_obj_setlock((un)->v_uobj, - uppervp->v_interlock); - } + if (ohash != nhash && (un->un_cflags & UN_CACHED)) { + un->un_cflags &= ~UN_CACHED; + LIST_REMOVE(un, un_cache); } - - if (docache && (ohash != nhash)) { + mutex_enter(>un_lock); + un->un_lowervp = lowervp; + un->un_lowersz = VNOVAL; + mutex_exit(>un_lock); + if (ohash != nhash) { LIST_INSERT_HEAD([nhash], un, un_cache); un->un_cflags |= UN_CACHED; } @@ -233,17 +191,57 @@ union_updatevp(struct union_node *un, st } void -union_newlower(struct union_node *un, struct vnode *lowervp)
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Wed May 24 09:55:19 UTC 2017 Modified Files: src/sys/fs/union: union_vnops.c Log Message: Use VCALL() to lock or unlock the lower node. To generate a diff of this commit: cvs rdiff -u -r1.68 -r1.69 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Wed May 24 09:55:19 UTC 2017 Modified Files: src/sys/fs/union: union_vnops.c Log Message: Use VCALL() to lock or unlock the lower node. To generate a diff of this commit: cvs rdiff -u -r1.68 -r1.69 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_vnops.c diff -u src/sys/fs/union/union_vnops.c:1.68 src/sys/fs/union/union_vnops.c:1.69 --- src/sys/fs/union/union_vnops.c:1.68 Sun May 7 08:22:40 2017 +++ src/sys/fs/union/union_vnops.c Wed May 24 09:55:18 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vnops.c,v 1.68 2017/05/07 08:22:40 hannken Exp $ */ +/* $NetBSD: union_vnops.c,v 1.69 2017/05/24 09:55:18 hannken Exp $ */ /* * Copyright (c) 1992, 1993, 1994, 1995 @@ -72,7 +72,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.68 2017/05/07 08:22:40 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.69 2017/05/24 09:55:18 hannken Exp $"); #include #include @@ -1600,12 +1600,14 @@ union_lock1(struct vnode *vp, struct vno { struct vop_lock_args ap; - if (lockvp == vp) { - ap.a_vp = vp; - ap.a_flags = flags; + ap.a_desc = VDESC(vop_lock); + ap.a_vp = lockvp; + ap.a_flags = flags; + + if (lockvp == vp) return genfs_lock(); - } else - return VOP_LOCK(lockvp, flags); + else + return VCALL(ap.a_vp, VOFFSET(vop_lock), ); } static int @@ -1613,11 +1615,13 @@ union_unlock1(struct vnode *vp, struct v { struct vop_unlock_args ap; - if (lockvp == vp) { - ap.a_vp = vp; + ap.a_desc = VDESC(vop_unlock); + ap.a_vp = lockvp; + + if (lockvp == vp) return genfs_unlock(); - } else - return VOP_UNLOCK(lockvp); + else + return VCALL(ap.a_vp, VOFFSET(vop_unlock), ); } int
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Sun May 7 08:22:40 UTC 2017 Modified Files: src/sys/fs/union: union_vnops.c Log Message: Move v_writecount adjustment from revoke to reclaim. To generate a diff of this commit: cvs rdiff -u -r1.67 -r1.68 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_vnops.c diff -u src/sys/fs/union/union_vnops.c:1.67 src/sys/fs/union/union_vnops.c:1.68 --- src/sys/fs/union/union_vnops.c:1.67 Wed Apr 26 03:02:48 2017 +++ src/sys/fs/union/union_vnops.c Sun May 7 08:22:40 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vnops.c,v 1.67 2017/04/26 03:02:48 riastradh Exp $ */ +/* $NetBSD: union_vnops.c,v 1.68 2017/05/07 08:22:40 hannken Exp $ */ /* * Copyright (c) 1992, 1993, 1994, 1995 @@ -72,7 +72,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.67 2017/04/26 03:02:48 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.68 2017/05/07 08:22:40 hannken Exp $"); #include #include @@ -1064,13 +1064,8 @@ union_revoke(void *v) } */ *ap = v; struct vnode *vp = ap->a_vp; - if (UPPERVP(vp)) { - mutex_enter(UPPERVP(vp)->v_interlock); - KASSERT(vp->v_interlock == UPPERVP(vp)->v_interlock); - UPPERVP(vp)->v_writecount -= vp->v_writecount; - mutex_exit(UPPERVP(vp)->v_interlock); + if (UPPERVP(vp)) VOP_REVOKE(UPPERVP(vp), ap->a_flags); - } if (LOWERVP(vp)) VOP_REVOKE(LOWERVP(vp), ap->a_flags); vgone(vp); /* XXXAD?? */ @@ -1585,8 +1580,17 @@ union_reclaim(void *v) struct vop_reclaim_args /* { struct vnode *a_vp; } */ *ap = v; + struct vnode *vp = ap->a_vp; + struct vnode *uvp = UPPERVP(vp); + + if (uvp != NULL) { + mutex_enter(uvp->v_interlock); + KASSERT(vp->v_interlock == uvp->v_interlock); + uvp->v_writecount -= vp->v_writecount; + mutex_exit(uvp->v_interlock); + } - union_freevp(ap->a_vp); + union_freevp(vp); return (0); }
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Sun May 7 08:22:40 UTC 2017 Modified Files: src/sys/fs/union: union_vnops.c Log Message: Move v_writecount adjustment from revoke to reclaim. To generate a diff of this commit: cvs rdiff -u -r1.67 -r1.68 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Mon Mar 6 10:08:49 UTC 2017 Modified Files: src/sys/fs/union: union_vnops.c Log Message: Handle v_writecount from union_open(), union_close() and union_revoke() so lower file system vnodes get marked as open for writing. To generate a diff of this commit: cvs rdiff -u -r1.63 -r1.64 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_vnops.c diff -u src/sys/fs/union/union_vnops.c:1.63 src/sys/fs/union/union_vnops.c:1.64 --- src/sys/fs/union/union_vnops.c:1.63 Mon Apr 20 23:03:08 2015 +++ src/sys/fs/union/union_vnops.c Mon Mar 6 10:08:49 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vnops.c,v 1.63 2015/04/20 23:03:08 riastradh Exp $ */ +/* $NetBSD: union_vnops.c,v 1.64 2017/03/06 10:08:49 hannken Exp $ */ /* * Copyright (c) 1992, 1993, 1994, 1995 @@ -72,7 +72,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.63 2015/04/20 23:03:08 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.64 2017/03/06 10:08:49 hannken Exp $"); #include #include @@ -616,6 +616,11 @@ union_open(void *v) error = union_copyup(un, (mode_TRUNC) == 0, cred, l); if (error == 0) error = VOP_OPEN(un->un_uppervp, mode, cred); + if (error == 0) { +mutex_enter(un->un_uppervp->v_interlock); +un->un_uppervp->v_writecount++; +mutex_exit(un->un_uppervp->v_interlock); + } return (error); } @@ -640,6 +645,11 @@ union_open(void *v) return ENXIO; error = VOP_OPEN(tvp, mode, cred); + if (error == 0 && (ap->a_mode & FWRITE)) { + mutex_enter(tvp->v_interlock); + tvp->v_writecount++; + mutex_exit(tvp->v_interlock); + } return (error); } @@ -669,6 +679,12 @@ union_close(void *v) KASSERT(vp != NULLVP); ap->a_vp = vp; + if ((ap->a_fflag & FWRITE)) { + KASSERT(vp == un->un_uppervp); + mutex_enter(vp->v_interlock); + vp->v_writecount--; + mutex_exit(vp->v_interlock); + } if (do_lock) vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); error = VCALL(vp, VOFFSET(vop_close), ap); @@ -1048,8 +1064,13 @@ union_revoke(void *v) } */ *ap = v; struct vnode *vp = ap->a_vp; - if (UPPERVP(vp)) + if (UPPERVP(vp)) { + mutex_enter(UPPERVP(vp)->v_interlock); + KASSERT(vp->v_interlock == UPPERVP(vp)->v_interlock); + UPPERVP(vp)->v_writecount -= vp->v_writecount; + mutex_exit(UPPERVP(vp)->v_interlock); VOP_REVOKE(UPPERVP(vp), ap->a_flags); + } if (LOWERVP(vp)) VOP_REVOKE(LOWERVP(vp), ap->a_flags); vgone(vp); /* XXXAD?? */
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Mon Mar 6 10:08:49 UTC 2017 Modified Files: src/sys/fs/union: union_vnops.c Log Message: Handle v_writecount from union_open(), union_close() and union_revoke() so lower file system vnodes get marked as open for writing. To generate a diff of this commit: cvs rdiff -u -r1.63 -r1.64 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Thu Jul 23 09:45:21 UTC 2015 Modified Files: src/sys/fs/union: union_vfsops.c Log Message: union_unmount: use vfs_vnode_iterator to count attached vnodes. To generate a diff of this commit: cvs rdiff -u -r1.74 -r1.75 src/sys/fs/union/union_vfsops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Thu Jul 23 09:45:21 UTC 2015 Modified Files: src/sys/fs/union: union_vfsops.c Log Message: union_unmount: use vfs_vnode_iterator to count attached vnodes. To generate a diff of this commit: cvs rdiff -u -r1.74 -r1.75 src/sys/fs/union/union_vfsops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_vfsops.c diff -u src/sys/fs/union/union_vfsops.c:1.74 src/sys/fs/union/union_vfsops.c:1.75 --- src/sys/fs/union/union_vfsops.c:1.74 Mon Feb 16 10:22:00 2015 +++ src/sys/fs/union/union_vfsops.c Thu Jul 23 09:45:21 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vfsops.c,v 1.74 2015/02/16 10:22:00 hannken Exp $ */ +/* $NetBSD: union_vfsops.c,v 1.75 2015/07/23 09:45:21 hannken Exp $ */ /* * Copyright (c) 1994 The Regents of the University of California. @@ -77,7 +77,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_vfsops.c,v 1.74 2015/02/16 10:22:00 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_vfsops.c,v 1.75 2015/07/23 09:45:21 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -314,6 +314,15 @@ union_start(struct mount *mp, int flags) /* * Free reference to union layer */ +static bool +union_unmount_selector(void *cl, struct vnode *vp) +{ + int *count = cl; + + *count += 1; + return false; +} + int union_unmount(struct mount *mp, int mntflags) { @@ -335,13 +344,14 @@ union_unmount(struct mount *mp, int mntf * in the filesystem. */ for (freeing = 0; (error = vflush(mp, NULL, 0)) != 0;) { - struct vnode *vp; + struct vnode_iterator *marker; int n; /* count #vnodes held on mount list */ n = 0; - TAILQ_FOREACH(vp, mp-mnt_vnodelist, v_mntvnodes) - n++; + vfs_vnode_iterator_init(mp, marker); + vfs_vnode_iterator_next(marker, union_unmount_selector, n); + vfs_vnode_iterator_destroy(marker); /* if this is unchanged then stop */ if (n == freeing)
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Tue Feb 24 16:08:01 UTC 2015 Modified Files: src/sys/fs/union: union_subr.c Log Message: A union node may be reactivated while it is being reclaimed so change union_freevp() to detach the vnode from the union node by clearing the vnode backpointer and the lower node sizes. To generate a diff of this commit: cvs rdiff -u -r1.70 -r1.71 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Tue Feb 24 16:08:01 UTC 2015 Modified Files: src/sys/fs/union: union_subr.c Log Message: A union node may be reactivated while it is being reclaimed so change union_freevp() to detach the vnode from the union node by clearing the vnode backpointer and the lower node sizes. To generate a diff of this commit: cvs rdiff -u -r1.70 -r1.71 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.70 src/sys/fs/union/union_subr.c:1.71 --- src/sys/fs/union/union_subr.c:1.70 Mon Feb 16 10:22:00 2015 +++ src/sys/fs/union/union_subr.c Tue Feb 24 16:08:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.70 2015/02/16 10:22:00 hannken Exp $ */ +/* $NetBSD: union_subr.c,v 1.71 2015/02/24 16:08:01 hannken Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.70 2015/02/16 10:22:00 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.71 2015/02/24 16:08:01 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -534,8 +534,14 @@ union_freevp(struct vnode *vp) { struct union_node *un = VTOUNION(vp); + /* Detach vnode from union node. */ + un-un_vnode = NULL; + un-un_uppersz = VNOVAL; + un-un_lowersz = VNOVAL; + vcache_remove(vp-v_mount, un, sizeof(un)); + /* Detach union node from vnode. */ mutex_enter(vp-v_interlock); vp-v_data = NULL; mutex_exit(vp-v_interlock);
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Mon Feb 16 10:21:25 UTC 2015 Modified Files: src/sys/fs/union: union.h union_subr.c Log Message: Add reference count to union node. To generate a diff of this commit: cvs rdiff -u -r1.26 -r1.27 src/sys/fs/union/union.h cvs rdiff -u -r1.68 -r1.69 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union.h diff -u src/sys/fs/union/union.h:1.26 src/sys/fs/union/union.h:1.27 --- src/sys/fs/union/union.h:1.26 Fri Feb 14 08:50:27 2014 +++ src/sys/fs/union/union.h Mon Feb 16 10:21:25 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: union.h,v 1.26 2014/02/14 08:50:27 hannken Exp $ */ +/* $NetBSD: union.h,v 1.27 2015/02/16 10:21:25 hannken Exp $ */ /* * Copyright (c) 1994 The Regents of the University of California. @@ -120,6 +120,7 @@ struct union_mount { struct union_node { kmutex_t un_lock; LIST_ENTRY(union_node) un_cache; /* c: Hash chain */ + int un_refs; /* c: Reference counter */ struct vnode *un_vnode; /* :: Back pointer */ struct vnode *un_uppervp; /* m: overlaying object */ struct vnode *un_lowervp; /* v: underlying object */ Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.68 src/sys/fs/union/union_subr.c:1.69 --- src/sys/fs/union/union_subr.c:1.68 Mon Feb 16 10:20:57 2015 +++ src/sys/fs/union/union_subr.c Mon Feb 16 10:21:25 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.68 2015/02/16 10:20:57 hannken Exp $ */ +/* $NetBSD: union_subr.c,v 1.69 2015/02/16 10:21:25 hannken Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.68 2015/02/16 10:20:57 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.69 2015/02/16 10:21:25 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -105,6 +105,8 @@ static u_long uhash_mask; /* size of ha static kmutex_t uhash_lock; void union_updatevp(struct union_node *, struct vnode *, struct vnode *); +static void union_ref(struct union_node *); +static void union_rele(struct union_node *); static int union_do_lookup(struct vnode *, struct componentname *, kauth_cred_t,const char *); int union_vn_close(struct vnode *, int, kauth_cred_t, struct lwp *); static void union_dircache_r(struct vnode *, struct vnode ***, int *); @@ -289,6 +291,45 @@ union_newsize(struct vnode *vp, off_t up } } +static void +union_ref(struct union_node *un) +{ + + KASSERT(mutex_owned(uhash_lock)); + un-un_refs++; +} + +static void +union_rele(struct union_node *un) +{ + + mutex_enter(uhash_lock); + un-un_refs--; + if (un-un_refs 0) { + mutex_exit(uhash_lock); + return; + } + if (un-un_cflags UN_CACHED) { + un-un_cflags = ~UN_CACHED; + LIST_REMOVE(un, un_cache); + } + mutex_exit(uhash_lock); + + if (un-un_pvp != NULLVP) + vrele(un-un_pvp); + if (un-un_uppervp != NULLVP) + vrele(un-un_uppervp); + if (un-un_lowervp != NULLVP) + vrele(un-un_lowervp); + if (un-un_dirvp != NULLVP) + vrele(un-un_dirvp); + if (un-un_path) + free(un-un_path, M_TEMP); + mutex_destroy(un-un_lock); + + free(un, M_TEMP); +} + /* * allocate a union_node/vnode pair. the vnode is * referenced and unlocked. the new vnode is returned @@ -397,9 +438,12 @@ loop: continue; vp = UNIONTOV(un); + union_ref(un); mutex_enter(vp-v_interlock); mutex_exit(uhash_lock); - if (vget(vp, 0)) + error = vget(vp, 0); + union_rele(un); + if (error) goto loop; goto found; } @@ -517,6 +561,7 @@ found: un = VTOUNION(*vpp); mutex_init(un-un_lock, MUTEX_DEFAULT, IPL_NONE); + un-un_refs = 1; un-un_vnode = *vpp; un-un_uppervp = uppervp; un-un_lowervp = lowervp; @@ -562,29 +607,11 @@ union_freevp(struct vnode *vp) { struct union_node *un = VTOUNION(vp); - mutex_enter(uhash_lock); - if (un-un_cflags UN_CACHED) { - un-un_cflags = ~UN_CACHED; - LIST_REMOVE(un, un_cache); - } - mutex_exit(uhash_lock); - - if (un-un_pvp != NULLVP) - vrele(un-un_pvp); - if (un-un_uppervp != NULLVP) - vrele(un-un_uppervp); - if (un-un_lowervp != NULLVP) - vrele(un-un_lowervp); - if (un-un_dirvp != NULLVP) - vrele(un-un_dirvp); - if (un-un_path) - free(un-un_path, M_TEMP); - mutex_destroy(un-un_lock); + union_rele(un); - free(vp-v_data, M_TEMP); vp-v_data = NULL; - return (0); + return 0; } /*
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Mon Feb 16 10:21:25 UTC 2015 Modified Files: src/sys/fs/union: union.h union_subr.c Log Message: Add reference count to union node. To generate a diff of this commit: cvs rdiff -u -r1.26 -r1.27 src/sys/fs/union/union.h cvs rdiff -u -r1.68 -r1.69 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Mon Feb 16 10:22:00 UTC 2015 Modified Files: src/sys/fs/union: union.h union_subr.c union_vfsops.c Log Message: Change union to vcache. Use address of the union node as key. It would be better to use (uppervp, lowervp) as key, but either may be NULL and may change any time. To generate a diff of this commit: cvs rdiff -u -r1.27 -r1.28 src/sys/fs/union/union.h cvs rdiff -u -r1.69 -r1.70 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.73 -r1.74 src/sys/fs/union/union_vfsops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Mon Feb 16 10:20:57 UTC 2015 Modified Files: src/sys/fs/union: union_subr.c Log Message: Remove a superfluous vref(), VOP_CREATE() was changed to keep dvp referenced and locked some time ago. To generate a diff of this commit: cvs rdiff -u -r1.67 -r1.68 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.67 src/sys/fs/union/union_subr.c:1.68 --- src/sys/fs/union/union_subr.c:1.67 Fri Sep 5 09:26:16 2014 +++ src/sys/fs/union/union_subr.c Mon Feb 16 10:20:57 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.67 2014/09/05 09:26:16 matt Exp $ */ +/* $NetBSD: union_subr.c,v 1.68 2015/02/16 10:20:57 hannken Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.67 2014/09/05 09:26:16 matt Exp $); +__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.68 2015/02/16 10:20:57 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -889,7 +889,6 @@ union_vn_create(struct vnode **vpp, stru vattr_null(vap); vap-va_type = VREG; vap-va_mode = cmode; - vref(un-un_dirvp); vp = NULL; error = VOP_CREATE(un-un_dirvp, vp, cn, vap); if (error) {
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Mon Feb 16 10:20:57 UTC 2015 Modified Files: src/sys/fs/union: union_subr.c Log Message: Remove a superfluous vref(), VOP_CREATE() was changed to keep dvp referenced and locked some time ago. To generate a diff of this commit: cvs rdiff -u -r1.67 -r1.68 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Mon Feb 16 10:22:00 UTC 2015 Modified Files: src/sys/fs/union: union.h union_subr.c union_vfsops.c Log Message: Change union to vcache. Use address of the union node as key. It would be better to use (uppervp, lowervp) as key, but either may be NULL and may change any time. To generate a diff of this commit: cvs rdiff -u -r1.27 -r1.28 src/sys/fs/union/union.h cvs rdiff -u -r1.69 -r1.70 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.73 -r1.74 src/sys/fs/union/union_vfsops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union.h diff -u src/sys/fs/union/union.h:1.27 src/sys/fs/union/union.h:1.28 --- src/sys/fs/union/union.h:1.27 Mon Feb 16 10:21:25 2015 +++ src/sys/fs/union/union.h Mon Feb 16 10:22:00 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: union.h,v 1.27 2015/02/16 10:21:25 hannken Exp $ */ +/* $NetBSD: union.h,v 1.28 2015/02/16 10:22:00 hannken Exp $ */ /* * Copyright (c) 1994 The Regents of the University of California. @@ -121,6 +121,7 @@ struct union_node { kmutex_t un_lock; LIST_ENTRY(union_node) un_cache; /* c: Hash chain */ int un_refs; /* c: Reference counter */ + struct mount *un_mount; /* c: union mount */ struct vnode *un_vnode; /* :: Back pointer */ struct vnode *un_uppervp; /* m: overlaying object */ struct vnode *un_lowervp; /* v: underlying object */ @@ -162,6 +163,8 @@ extern void union_newupper(struct union_ extern void union_newsize(struct vnode *, off_t, off_t); int union_readdirhook(struct vnode **, struct file *, struct lwp *); +VFS_PROTOS(union); + #define MOUNTTOUNIONMOUNT(mp) ((struct union_mount *)((mp)-mnt_data)) #define VTOUNION(vp) ((struct union_node *)(vp)-v_data) #define UNIONTOV(un) ((un)-un_vnode) Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.69 src/sys/fs/union/union_subr.c:1.70 --- src/sys/fs/union/union_subr.c:1.69 Mon Feb 16 10:21:25 2015 +++ src/sys/fs/union/union_subr.c Mon Feb 16 10:22:00 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.69 2015/02/16 10:21:25 hannken Exp $ */ +/* $NetBSD: union_subr.c,v 1.70 2015/02/16 10:22:00 hannken Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.69 2015/02/16 10:21:25 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.70 2015/02/16 10:22:00 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -344,22 +344,12 @@ union_rele(struct union_node *un) * the reference is either maintained in the new union_node * object which is allocated, or they are vrele'd. * - * all union_nodes are maintained on a singly-linked + * all union_nodes are maintained on a hash * list. new nodes are only allocated when they cannot * be found on this list. entries on the list are * removed when the vfs reclaim entry is called. * - * a single lock is kept for the entire list. this is - * needed because the getnewvnode() function can block - * waiting for a vnode to become free, in which case there - * may be more than one process trying to get the same - * vnode. this lock is only taken if we are going to - * call getnewvnode, since the kernel itself is single-threaded. - * - * if an entry is found on the list, then call vget() to - * take a reference. this is done because there may be - * zero references to it and so it needs to removed from - * the vnode free list. + * the vnode gets attached or referenced with vcache_get(). */ int union_allocvp( @@ -373,14 +363,9 @@ union_allocvp( int docache) { int error; - struct vattr va; struct union_node *un = NULL, *un1; struct vnode *vp, *xlowervp = NULLVP; - struct union_mount *um = MOUNTTOUNIONMOUNT(mp); - voff_t uppersz, lowersz; - dev_t rdev; u_long hash[3]; - int vflag, iflag; int try; bool is_dotdot; @@ -394,20 +379,6 @@ union_allocvp( lowervp = NULLVP; } - /* detect the root vnode (and aliases) */ - iflag = VI_LAYER; - vflag = 0; - if ((uppervp == um-um_uppervp) - ((lowervp == NULLVP) || lowervp == um-um_lowervp)) { - if (lowervp == NULLVP) { - lowervp = um-um_lowervp; - if (lowervp != NULLVP) -vref(lowervp); - } - iflag = 0; - vflag = VV_ROOT; - } - if (!docache) { un = NULL; goto found; @@ -434,17 +405,18 @@ loop: LIST_FOREACH(un, uhashtbl[hash[try]], un_cache) { if ((un-un_lowervp un-un_lowervp != lowervp) || (un-un_uppervp un-un_uppervp != uppervp) || - UNIONTOV(un)-v_mount != mp) + un-un_mount != mp) continue; - vp = UNIONTOV(un); union_ref(un); - mutex_enter(vp-v_interlock); mutex_exit(uhash_lock); - error = vget(vp, 0); + error = vcache_get(mp, un, sizeof(un), vp); + KASSERT(error != 0 || UNIONTOV(un) == vp); union_rele(un); - if (error) + if (error == ENOENT) goto loop; + else if (error) +goto out; goto
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Tue Jun 17 12:38:12 UTC 2014 Modified Files: src/sys/fs/union: union_subr.c Log Message: Unlock directory vnode after VOP_CREATE. To generate a diff of this commit: cvs rdiff -u -r1.65 -r1.66 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.65 src/sys/fs/union/union_subr.c:1.66 --- src/sys/fs/union/union_subr.c:1.65 Sat May 17 04:07:15 2014 +++ src/sys/fs/union/union_subr.c Tue Jun 17 12:38:12 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.65 2014/05/17 04:07:15 dholland Exp $ */ +/* $NetBSD: union_subr.c,v 1.66 2014/06/17 12:38:12 hannken Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.65 2014/05/17 04:07:15 dholland Exp $); +__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.66 2014/06/17 12:38:12 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -892,10 +892,13 @@ union_vn_create(struct vnode **vpp, stru vref(un-un_dirvp); vp = NULL; error = VOP_CREATE(un-un_dirvp, vp, cn, vap); - if (error) + if (error) { + VOP_UNLOCK(un-un_dirvp); return error; + } vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); + VOP_UNLOCK(un-un_dirvp); error = VOP_OPEN(vp, fmode, cred); if (error) { vput(vp);
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Tue Jun 17 12:38:12 UTC 2014 Modified Files: src/sys/fs/union: union_subr.c Log Message: Unlock directory vnode after VOP_CREATE. To generate a diff of this commit: cvs rdiff -u -r1.65 -r1.66 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: dholland Date: Sat May 17 04:03:49 UTC 2014 Modified Files: src/sys/fs/union: union_subr.c union_vnops.c Log Message: Set *vpp to NULL before calling VOP_CREATE. This always happens when calling using nameidata, and if not something went wrong, so we'd like to be able to assert about it. To generate a diff of this commit: cvs rdiff -u -r1.63 -r1.64 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.59 -r1.60 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.63 src/sys/fs/union/union_subr.c:1.64 --- src/sys/fs/union/union_subr.c:1.63 Sun Feb 16 09:50:25 2014 +++ src/sys/fs/union/union_subr.c Sat May 17 04:03:49 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.63 2014/02/16 09:50:25 hannken Exp $ */ +/* $NetBSD: union_subr.c,v 1.64 2014/05/17 04:03:49 dholland Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.63 2014/02/16 09:50:25 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.64 2014/05/17 04:03:49 dholland Exp $); #include sys/param.h #include sys/systm.h @@ -889,6 +889,7 @@ union_vn_create(struct vnode **vpp, stru vap-va_type = VREG; vap-va_mode = cmode; vref(un-un_dirvp); + vp = NULL; error = VOP_CREATE(un-un_dirvp, vp, cn, vap); if (error) return error; Index: src/sys/fs/union/union_vnops.c diff -u src/sys/fs/union/union_vnops.c:1.59 src/sys/fs/union/union_vnops.c:1.60 --- src/sys/fs/union/union_vnops.c:1.59 Mon Mar 24 13:42:40 2014 +++ src/sys/fs/union/union_vnops.c Sat May 17 04:03:49 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vnops.c,v 1.59 2014/03/24 13:42:40 hannken Exp $ */ +/* $NetBSD: union_vnops.c,v 1.60 2014/05/17 04:03:49 dholland Exp $ */ /* * Copyright (c) 1992, 1993, 1994, 1995 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_vnops.c,v 1.59 2014/03/24 13:42:40 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_vnops.c,v 1.60 2014/05/17 04:03:49 dholland Exp $); #include sys/param.h #include sys/systm.h @@ -517,6 +517,8 @@ union_create(void *v) struct mount *mp; mp = ap-a_dvp-v_mount; + + vp = NULL; error = VOP_CREATE(dvp, vp, cnp, ap-a_vap); if (error) return (error);
CVS commit: src/sys/fs/union
Module Name:src Committed By: dholland Date: Sat May 17 04:07:15 UTC 2014 Modified Files: src/sys/fs/union: union_subr.c union_vnops.c Log Message: Also set or assert that *vpp is null before calling VOP_MKDIR. To generate a diff of this commit: cvs rdiff -u -r1.64 -r1.65 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.60 -r1.61 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.64 src/sys/fs/union/union_subr.c:1.65 --- src/sys/fs/union/union_subr.c:1.64 Sat May 17 04:03:49 2014 +++ src/sys/fs/union/union_subr.c Sat May 17 04:07:15 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.64 2014/05/17 04:03:49 dholland Exp $ */ +/* $NetBSD: union_subr.c,v 1.65 2014/05/17 04:07:15 dholland Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.64 2014/05/17 04:03:49 dholland Exp $); +__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.65 2014/05/17 04:07:15 dholland Exp $); #include sys/param.h #include sys/systm.h @@ -811,6 +811,7 @@ union_mkshadow(struct union_mount *um, s va.va_type = VDIR; va.va_mode = um-um_cmode; + KASSERT(*vpp == NULL); error = VOP_MKDIR(dvp, vpp, cn, va); VOP_UNLOCK(dvp); PNBUF_PUT(pnbuf); Index: src/sys/fs/union/union_vnops.c diff -u src/sys/fs/union/union_vnops.c:1.60 src/sys/fs/union/union_vnops.c:1.61 --- src/sys/fs/union/union_vnops.c:1.60 Sat May 17 04:03:49 2014 +++ src/sys/fs/union/union_vnops.c Sat May 17 04:07:15 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vnops.c,v 1.60 2014/05/17 04:03:49 dholland Exp $ */ +/* $NetBSD: union_vnops.c,v 1.61 2014/05/17 04:07:15 dholland Exp $ */ /* * Copyright (c) 1992, 1993, 1994, 1995 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_vnops.c,v 1.60 2014/05/17 04:03:49 dholland Exp $); +__KERNEL_RCSID(0, $NetBSD: union_vnops.c,v 1.61 2014/05/17 04:07:15 dholland Exp $); #include sys/param.h #include sys/systm.h @@ -1385,6 +1385,7 @@ union_mkdir(void *v) int error; struct vnode *vp; + vp = NULL; error = VOP_MKDIR(dvp, vp, cnp, ap-a_vap); if (error) { vrele(ap-a_dvp);
CVS commit: src/sys/fs/union
Module Name:src Committed By: dholland Date: Sat May 17 04:03:49 UTC 2014 Modified Files: src/sys/fs/union: union_subr.c union_vnops.c Log Message: Set *vpp to NULL before calling VOP_CREATE. This always happens when calling using nameidata, and if not something went wrong, so we'd like to be able to assert about it. To generate a diff of this commit: cvs rdiff -u -r1.63 -r1.64 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.59 -r1.60 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: dholland Date: Sat May 17 04:07:15 UTC 2014 Modified Files: src/sys/fs/union: union_subr.c union_vnops.c Log Message: Also set or assert that *vpp is null before calling VOP_MKDIR. To generate a diff of this commit: cvs rdiff -u -r1.64 -r1.65 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.60 -r1.61 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Wed Mar 12 09:40:05 UTC 2014 Modified Files: src/sys/fs/union: union_vnops.c Log Message: Restructure union_lock() to always lock before testing for dead node. Add two little helpers to lock or unlock a node. Use vp for the union node and lockvp for the node to be locked. Use ISSET() to test flags, add assertions. To generate a diff of this commit: cvs rdiff -u -r1.57 -r1.58 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_vnops.c diff -u src/sys/fs/union/union_vnops.c:1.57 src/sys/fs/union/union_vnops.c:1.58 --- src/sys/fs/union/union_vnops.c:1.57 Thu Feb 27 16:51:38 2014 +++ src/sys/fs/union/union_vnops.c Wed Mar 12 09:40:05 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vnops.c,v 1.57 2014/02/27 16:51:38 hannken Exp $ */ +/* $NetBSD: union_vnops.c,v 1.58 2014/03/12 09:40:05 hannken Exp $ */ /* * Copyright (c) 1992, 1993, 1994, 1995 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_vnops.c,v 1.57 2014/02/27 16:51:38 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_vnops.c,v 1.58 2014/03/12 09:40:05 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -1590,6 +1590,31 @@ union_reclaim(void *v) return (0); } +static int +union_lock1(struct vnode *vp, struct vnode *lockvp, int flags) +{ + struct vop_lock_args ap; + + if (lockvp == vp) { + ap.a_vp = vp; + ap.a_flags = flags; + return genfs_lock(ap); + } else + return VOP_LOCK(lockvp, flags); +} + +static int +union_unlock1(struct vnode *vp, struct vnode *lockvp) +{ + struct vop_unlock_args ap; + + if (lockvp == vp) { + ap.a_vp = vp; + return genfs_unlock(ap); + } else + return VOP_UNLOCK(lockvp); +} + int union_lock(void *v) { @@ -1597,66 +1622,57 @@ union_lock(void *v) struct vnode *a_vp; int a_flags; } */ *ap = v; - struct vnode *vp; - struct union_node *un = VTOUNION(ap-a_vp); + struct vnode *vp = ap-a_vp, *lockvp; + struct union_node *un = VTOUNION(vp); int flags = ap-a_flags; int error; if ((flags LK_NOWAIT) != 0) { if (!mutex_tryenter(un-un_lock)) return EBUSY; - vp = LOCKVP(ap-a_vp); - if (!mutex_tryenter(vp-v_interlock)) { - mutex_exit(un-un_lock); - return EBUSY; - } - if ((vp-v_iflag (VI_XLOCK | VI_CLEAN)) != 0) { - mutex_exit(vp-v_interlock); - mutex_exit(un-un_lock); - return EBUSY; - } - mutex_exit(vp-v_interlock); - if (vp == ap-a_vp) - error = genfs_lock(ap); - else - error = VOP_LOCK(vp, flags); + lockvp = LOCKVP(vp); + error = union_lock1(vp, lockvp, flags); mutex_exit(un-un_lock); + if (error) + return error; + if (mutex_tryenter(vp-v_interlock)) { + if (ISSET(vp-v_iflag, VI_XLOCK)) +error = EBUSY; + else if (ISSET(vp-v_iflag, VI_CLEAN)) +error = ENOENT; + else +error = 0; + mutex_exit(vp-v_interlock); + } else + error = EBUSY; + if (error) + union_unlock1(vp, lockvp); return error; } mutex_enter(un-un_lock); for (;;) { - vp = LOCKVP(ap-a_vp); + lockvp = LOCKVP(vp); mutex_exit(un-un_lock); - if (vp == ap-a_vp) - error = genfs_lock(ap); - else - error = VOP_LOCK(vp, ap-a_flags); + error = union_lock1(vp, lockvp, flags); if (error != 0) return error; mutex_enter(un-un_lock); - if (vp == LOCKVP(ap-a_vp)) + if (lockvp == LOCKVP(vp)) break; - if (vp == ap-a_vp) - genfs_unlock(ap); - else - VOP_UNLOCK(vp); + union_unlock1(vp, lockvp); } + mutex_exit(un-un_lock); + mutex_enter(vp-v_interlock); - if ((vp-v_iflag (VI_XLOCK | VI_CLEAN)) != 0) { - if (vp == ap-a_vp) - genfs_unlock(ap); - else - VOP_UNLOCK(vp); - if ((vp-v_iflag VI_XLOCK)) - vwait(vp, VI_XLOCK); + if (ISSET(vp-v_iflag, VI_XLOCK) || ISSET(vp-v_iflag, VI_CLEAN)) { + union_unlock1(vp, lockvp); + vwait(vp, VI_XLOCK); + KASSERT(ISSET(vp-v_iflag, VI_CLEAN)); mutex_exit(vp-v_interlock); - mutex_exit(un-un_lock); return ENOENT; } mutex_exit(vp-v_interlock); - mutex_exit(un-un_lock); - return 0; } @@ -1667,13 +1683,10 @@ union_unlock(void *v) struct vnode *a_vp; int a_flags; } */ *ap = v; - struct vnode *vp; + struct vnode *vp = ap-a_vp, *lockvp; - vp = LOCKVP(ap-a_vp); - if (vp == ap-a_vp) - genfs_unlock(ap); - else - VOP_UNLOCK(vp); + lockvp = LOCKVP(vp); + union_unlock1(vp, lockvp); return 0; }
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Wed Mar 12 09:40:05 UTC 2014 Modified Files: src/sys/fs/union: union_vnops.c Log Message: Restructure union_lock() to always lock before testing for dead node. Add two little helpers to lock or unlock a node. Use vp for the union node and lockvp for the node to be locked. Use ISSET() to test flags, add assertions. To generate a diff of this commit: cvs rdiff -u -r1.57 -r1.58 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Sun Feb 16 09:50:25 UTC 2014 Modified Files: src/sys/fs/union: union_subr.c union_vfsops.c union_vnops.c Log Message: Change union_allocvp() to take an unlocked uppervp and to return the union node unlocked. Another VI_XLOCK hack is gone. To generate a diff of this commit: cvs rdiff -u -r1.62 -r1.63 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.68 -r1.69 src/sys/fs/union/union_vfsops.c cvs rdiff -u -r1.55 -r1.56 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.62 src/sys/fs/union/union_subr.c:1.63 --- src/sys/fs/union/union_subr.c:1.62 Fri Feb 14 08:50:27 2014 +++ src/sys/fs/union/union_subr.c Sun Feb 16 09:50:25 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.62 2014/02/14 08:50:27 hannken Exp $ */ +/* $NetBSD: union_subr.c,v 1.63 2014/02/16 09:50:25 hannken Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.62 2014/02/14 08:50:27 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.63 2014/02/16 09:50:25 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -291,7 +291,7 @@ union_newsize(struct vnode *vp, off_t up /* * allocate a union_node/vnode pair. the vnode is - * referenced and locked. the new vnode is returned + * referenced and unlocked. the new vnode is returned * via (vpp). (mp) is the mountpoint of the union filesystem, * (dvp) is the parent directory where the upper layer object * should exist (but doesn't) and (cnp) is the componentname @@ -299,7 +299,7 @@ union_newsize(struct vnode *vp, off_t up * layer object to be created at a later time. (uppervp) * and (lowervp) reference the upper and lower layer objects * being mapped. either, but not both, can be nil. - * if supplied, (uppervp) is locked. + * both, if supplied, are unlocked. * the reference is either maintained in the new union_node * object which is allocated, or they are vrele'd. * @@ -339,11 +339,11 @@ union_allocvp( voff_t uppersz, lowersz; dev_t rdev; u_long hash[3]; - int vflag, iflag, lflag; + int vflag, iflag; int try; + bool is_dotdot; - if (uppervp) - KASSERT(VOP_ISLOCKED(uppervp) == LK_EXCLUSIVE); + is_dotdot = (dvp != NULL cnp != NULL (cnp-cn_flags ISDOTDOT)); if (uppervp == NULLVP lowervp == NULLVP) panic(union: unidentifiable allocation); @@ -396,28 +396,10 @@ loop: UNIONTOV(un)-v_mount != mp) continue; - if (uppervp != NULL - (uppervp == dvp || uppervp == un-un_uppervp)) -/* . or already locked. */ -lflag = 0; - else -lflag = LK_EXCLUSIVE; vp = UNIONTOV(un); mutex_enter(vp-v_interlock); - /* - * If this node being cleaned out and our caller - * holds a lock, then ignore it and continue. To - * allow the cleaning to succeed the current thread - * must make progress. For a brief time the cache - * may contain more than one vnode referring to - * a lower node. - */ - if ((vp-v_iflag VI_XLOCK) != 0 lflag == 0) { -mutex_exit(vp-v_interlock); -continue; - } mutex_exit(uhash_lock); - if (vget(vp, lflag)) + if (vget(vp, 0)) goto loop; goto found; } @@ -427,9 +409,13 @@ loop: found: if (un) { - KASSERT(VOP_ISLOCKED(UNIONTOV(un)) == LK_EXCLUSIVE); - KASSERT(uppervp == NULL || - VOP_ISLOCKED(uppervp) == LK_EXCLUSIVE); + if (uppervp != dvp) { + if (is_dotdot) +VOP_UNLOCK(dvp); + vn_lock(UNIONTOV(un), LK_EXCLUSIVE | LK_RETRY); + if (is_dotdot) +vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); + } /* * Save information about the upper layer. */ @@ -460,19 +446,23 @@ found: vrele(lowervp); } *vpp = UNIONTOV(un); + if (uppervp != dvp) + VOP_UNLOCK(*vpp); return (0); } uppersz = lowersz = VNOVAL; - if (uppervp != NULLVP) + if (uppervp != NULLVP) { + vn_lock(uppervp, LK_SHARED | LK_RETRY); if (VOP_GETATTR(uppervp, va, FSCRED) == 0) uppersz = va.va_size; + VOP_UNLOCK(uppervp); + } if (lowervp != NULLVP) { vn_lock(lowervp, LK_SHARED | LK_RETRY); - error = VOP_GETATTR(lowervp, va, FSCRED); - VOP_UNLOCK(lowervp); - if (error == 0) + if (VOP_GETATTR(lowervp, va, FSCRED) == 0) lowersz = va.va_size; + VOP_UNLOCK(lowervp); } /* @@ -483,12 +473,8 @@ found: error = getnewvnode(VT_UNION, mp, union_vnodeop_p, svp-v_interlock, vpp); if (error) { - if (uppervp) { - if (dvp == uppervp) -vrele(uppervp); - else -vput(uppervp); - } + if (uppervp) + vrele(uppervp); if (lowervp) vrele(lowervp); @@ -501,17 +487,6 @@ found: if (un1-un_lowervp == lowervp un1-un_uppervp == uppervp UNIONTOV(un1)-v_mount == mp) { -vp = UNIONTOV(un1); -mutex_enter(vp-v_interlock); -/* - * Ignore nodes being cleaned
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Sun Feb 16 09:50:25 UTC 2014 Modified Files: src/sys/fs/union: union_subr.c union_vfsops.c union_vnops.c Log Message: Change union_allocvp() to take an unlocked uppervp and to return the union node unlocked. Another VI_XLOCK hack is gone. To generate a diff of this commit: cvs rdiff -u -r1.62 -r1.63 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.68 -r1.69 src/sys/fs/union/union_vfsops.c cvs rdiff -u -r1.55 -r1.56 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Fri Feb 14 08:50:27 UTC 2014 Modified Files: src/sys/fs/union: union.h union_subr.c Log Message: Member un_flags is unused now -- remove. To generate a diff of this commit: cvs rdiff -u -r1.25 -r1.26 src/sys/fs/union/union.h cvs rdiff -u -r1.61 -r1.62 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union.h diff -u src/sys/fs/union/union.h:1.25 src/sys/fs/union/union.h:1.26 --- src/sys/fs/union/union.h:1.25 Thu Feb 13 09:55:04 2014 +++ src/sys/fs/union/union.h Fri Feb 14 08:50:27 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: union.h,v 1.25 2014/02/13 09:55:04 hannken Exp $ */ +/* $NetBSD: union.h,v 1.26 2014/02/14 08:50:27 hannken Exp $ */ /* * Copyright (c) 1994 The Regents of the University of California. @@ -127,7 +127,6 @@ struct union_node { struct vnode *un_pvp; /* v: Parent vnode */ char *un_path; /* v: saved component name */ int un_openl; /* v: # of opens on lowervp */ - unsigned int un_flags; /* v: node flags */ unsigned int un_cflags; /* c: cache flags */ struct vnode **un_dircache; /* v: cached union stack */ off_t un_uppersz; /* l: size of upper object */ Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.61 src/sys/fs/union/union_subr.c:1.62 --- src/sys/fs/union/union_subr.c:1.61 Thu Feb 13 09:55:04 2014 +++ src/sys/fs/union/union_subr.c Fri Feb 14 08:50:27 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.61 2014/02/13 09:55:04 hannken Exp $ */ +/* $NetBSD: union_subr.c,v 1.62 2014/02/14 08:50:27 hannken Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.61 2014/02/13 09:55:04 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.62 2014/02/14 08:50:27 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -550,7 +550,6 @@ found: vref(undvp); un-un_dircache = 0; un-un_openl = 0; - un-un_flags = 0; un-un_cflags = 0; if (uppervp == NULL) {
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Fri Feb 14 08:50:27 UTC 2014 Modified Files: src/sys/fs/union: union.h union_subr.c Log Message: Member un_flags is unused now -- remove. To generate a diff of this commit: cvs rdiff -u -r1.25 -r1.26 src/sys/fs/union/union.h cvs rdiff -u -r1.61 -r1.62 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Thu Feb 13 09:50:31 UTC 2014 Modified Files: src/sys/fs/union: union_vnops.c Log Message: Fix the DOT and DOTDOT case for union_lookup1(). To generate a diff of this commit: cvs rdiff -u -r1.52 -r1.53 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_vnops.c diff -u src/sys/fs/union/union_vnops.c:1.52 src/sys/fs/union/union_vnops.c:1.53 --- src/sys/fs/union/union_vnops.c:1.52 Fri Feb 7 15:29:22 2014 +++ src/sys/fs/union/union_vnops.c Thu Feb 13 09:50:31 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vnops.c,v 1.52 2014/02/07 15:29:22 hannken Exp $ */ +/* $NetBSD: union_vnops.c,v 1.53 2014/02/13 09:50:31 hannken Exp $ */ /* * Copyright (c) 1992, 1993, 1994, 1995 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_vnops.c,v 1.52 2014/02/07 15:29:22 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_vnops.c,v 1.53 2014/02/13 09:50:31 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -228,14 +228,19 @@ union_lookup1(struct vnode *udvp, struct error = VOP_LOOKUP(dvp, tdvp, cnp); if (error) return (error); - error = vn_lock(tdvp, LK_EXCLUSIVE); - if (error) { - vrele(tdvp); - return error; + if (dvp != tdvp) { + if (cnp-cn_flags ISDOTDOT) + VOP_UNLOCK(dvp); + error = vn_lock(tdvp, LK_EXCLUSIVE); + if (cnp-cn_flags ISDOTDOT) + vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); + if (error) { + vrele(tdvp); + return error; + } + dvp = tdvp; } - dvp = tdvp; - /* * Lastly check if the current node is a mount point in * which case walk up the mount hierarchy making sure not to
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Thu Feb 13 09:55:04 UTC 2014 Modified Files: src/sys/fs/union: union.h union_subr.c union_vnops.c Log Message: Get rid of UN_KLOCK to keep a lock on vput(). It is not really needed and makes the source difficult to read. Always hold references to the union nodes until the operation is done. To generate a diff of this commit: cvs rdiff -u -r1.24 -r1.25 src/sys/fs/union/union.h cvs rdiff -u -r1.60 -r1.61 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.53 -r1.54 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union.h diff -u src/sys/fs/union/union.h:1.24 src/sys/fs/union/union.h:1.25 --- src/sys/fs/union/union.h:1.24 Mon Nov 5 17:24:11 2012 +++ src/sys/fs/union/union.h Thu Feb 13 09:55:04 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: union.h,v 1.24 2012/11/05 17:24:11 dholland Exp $ */ +/* $NetBSD: union.h,v 1.25 2014/02/13 09:55:04 hannken Exp $ */ /* * Copyright (c) 1994 The Regents of the University of California. @@ -134,7 +134,6 @@ struct union_node { off_t un_lowersz; /* l: size of lower object */ }; -#define UN_KLOCK 0x08 /* Keep upper node locked on vput */ #define UN_CACHED 0x10 /* In union cache */ extern int union_allocvp(struct vnode **, struct mount *, Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.60 src/sys/fs/union/union_subr.c:1.61 --- src/sys/fs/union/union_subr.c:1.60 Fri Feb 7 15:29:22 2014 +++ src/sys/fs/union/union_subr.c Thu Feb 13 09:55:04 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.60 2014/02/07 15:29:22 hannken Exp $ */ +/* $NetBSD: union_subr.c,v 1.61 2014/02/13 09:55:04 hannken Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.60 2014/02/07 15:29:22 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.61 2014/02/13 09:55:04 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -439,9 +439,6 @@ found: vrele(uppervp); } - if (un-un_uppervp) - un-un_flags = ~UN_KLOCK; - /* * Save information about the lower layer. * This needs to keep track of pathname Index: src/sys/fs/union/union_vnops.c diff -u src/sys/fs/union/union_vnops.c:1.53 src/sys/fs/union/union_vnops.c:1.54 --- src/sys/fs/union/union_vnops.c:1.53 Thu Feb 13 09:50:31 2014 +++ src/sys/fs/union/union_vnops.c Thu Feb 13 09:55:04 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vnops.c,v 1.53 2014/02/13 09:50:31 hannken Exp $ */ +/* $NetBSD: union_vnops.c,v 1.54 2014/02/13 09:55:04 hannken Exp $ */ /* * Copyright (c) 1992, 1993, 1994, 1995 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_vnops.c,v 1.53 2014/02/13 09:50:31 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_vnops.c,v 1.54 2014/02/13 09:55:04 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -1156,18 +1156,19 @@ union_remove(void *v) struct vnode *dvp = dun-un_uppervp; struct vnode *vp = un-un_uppervp; + /* + * Account for VOP_REMOVE to vrele dvp and vp. + * Note: VOP_REMOVE will unlock dvp and vp. + */ vref(dvp); - dun-un_flags |= UN_KLOCK; - vput(ap-a_dvp); vref(vp); - un-un_flags |= UN_KLOCK; - vput(ap-a_vp); - if (union_dowhiteout(un, cnp-cn_cred)) cnp-cn_flags |= DOWHITEOUT; error = VOP_REMOVE(dvp, vp, cnp); if (!error) union_removed_upper(un); + vrele(ap-a_dvp); + vrele(ap-a_vp); } else { error = union_mkwhiteout( MOUNTTOUNIONMOUNT(UNIONTOV(dun)-v_mount), @@ -1258,11 +1259,15 @@ union_link(void *v) return (error); } + /* + * Account for VOP_LINK to vrele dvp. + * Note: VOP_LINK will unlock dvp. + */ vref(dvp); - dun-un_flags |= UN_KLOCK; - vput(ap-a_dvp); + error = VOP_LINK(dvp, vp, cnp); + vrele(ap-a_dvp); - return (VOP_LINK(dvp, vp, cnp)); + return error; } int @@ -1283,6 +1288,11 @@ union_rename(void *v) struct vnode *tdvp = ap-a_tdvp; struct vnode *tvp = ap-a_tvp; + /* + * Account for VOP_RENAME to vrele all nodes. + * Note: VOP_RENAME will unlock tdvp. + */ + if (fdvp-v_op == union_vnodeop_p) { /* always true */ struct union_node *un = VTOUNION(fdvp); if (un-un_uppervp == NULLVP) { @@ -1330,8 +1340,6 @@ union_rename(void *v) tdvp = un-un_uppervp; vref(tdvp); - un-un_flags |= UN_KLOCK; - vput(ap-a_tdvp); } if (tvp != NULLVP tvp-v_op == union_vnodeop_p) { @@ -1340,9 +1348,7 @@ union_rename(void *v) tvp = un-un_uppervp; if (tvp != NULLVP) { vref(tvp); - un-un_flags |= UN_KLOCK; } - vput(ap-a_tvp); } error = VOP_RENAME(fdvp, fvp, ap-a_fcnp, tdvp, tvp, ap-a_tcnp); @@ -1362,6 +1368,12 @@ out: if (fvp != ap-a_fvp) { vrele(ap-a_fvp); } + if (tdvp != ap-a_tdvp) { + vrele(ap-a_tdvp); + } + if (tvp != ap-a_tvp) { + vrele(ap-a_tvp); + } return (error); } @@ -1428,18 +1440,19 @@ union_rmdir(void *v) struct vnode
CVS commit: src/sys/fs/union
Module Name:src Committed By: martin Date: Thu Feb 13 21:05:26 UTC 2014 Modified Files: src/sys/fs/union: union_vnops.c Log Message: Remove an unused variable To generate a diff of this commit: cvs rdiff -u -r1.54 -r1.55 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_vnops.c diff -u src/sys/fs/union/union_vnops.c:1.54 src/sys/fs/union/union_vnops.c:1.55 --- src/sys/fs/union/union_vnops.c:1.54 Thu Feb 13 09:55:04 2014 +++ src/sys/fs/union/union_vnops.c Thu Feb 13 21:05:26 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vnops.c,v 1.54 2014/02/13 09:55:04 hannken Exp $ */ +/* $NetBSD: union_vnops.c,v 1.55 2014/02/13 21:05:26 martin Exp $ */ /* * Copyright (c) 1992, 1993, 1994, 1995 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_vnops.c,v 1.54 2014/02/13 09:55:04 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_vnops.c,v 1.55 2014/02/13 21:05:26 martin Exp $); #include sys/param.h #include sys/systm.h @@ -1647,9 +1647,7 @@ union_unlock(void *v) int a_flags; } */ *ap = v; struct vnode *vp; - struct union_node *un; - un = VTOUNION(ap-a_vp); vp = LOCKVP(ap-a_vp); if (vp == ap-a_vp) genfs_unlock(ap);
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Thu Feb 13 09:50:31 UTC 2014 Modified Files: src/sys/fs/union: union_vnops.c Log Message: Fix the DOT and DOTDOT case for union_lookup1(). To generate a diff of this commit: cvs rdiff -u -r1.52 -r1.53 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Thu Feb 13 09:55:04 UTC 2014 Modified Files: src/sys/fs/union: union.h union_subr.c union_vnops.c Log Message: Get rid of UN_KLOCK to keep a lock on vput(). It is not really needed and makes the source difficult to read. Always hold references to the union nodes until the operation is done. To generate a diff of this commit: cvs rdiff -u -r1.24 -r1.25 src/sys/fs/union/union.h cvs rdiff -u -r1.60 -r1.61 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.53 -r1.54 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: martin Date: Thu Feb 13 21:05:26 UTC 2014 Modified Files: src/sys/fs/union: union_vnops.c Log Message: Remove an unused variable To generate a diff of this commit: cvs rdiff -u -r1.54 -r1.55 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: christos Date: Thu Oct 17 21:03:50 UTC 2013 Modified Files: src/sys/fs/union: union_subr.c Log Message: remove unused code To generate a diff of this commit: cvs rdiff -u -r1.56 -r1.57 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.56 src/sys/fs/union/union_subr.c:1.57 --- src/sys/fs/union/union_subr.c:1.56 Mon Nov 5 12:24:11 2012 +++ src/sys/fs/union/union_subr.c Thu Oct 17 17:03:50 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.56 2012/11/05 17:24:11 dholland Exp $ */ +/* $NetBSD: union_subr.c,v 1.57 2013/10/17 21:03:50 christos Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.56 2012/11/05 17:24:11 dholland Exp $); +__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.57 2013/10/17 21:03:50 christos Exp $); #include sys/param.h #include sys/systm.h @@ -598,11 +598,8 @@ found: int union_freevp(struct vnode *vp) { - int hash; struct union_node *un = VTOUNION(vp); - hash = UNION_HASH(un-un_uppervp, un-un_lowervp); - mutex_enter(uhash_lock); if (un-un_cflags UN_CACHED) { un-un_cflags = ~UN_CACHED; @@ -961,7 +958,6 @@ void union_removed_upper(struct union_node *un) { struct vnode *vp = UNIONTOV(un); - int hash; vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); #if 1 @@ -979,7 +975,6 @@ union_removed_upper(struct union_node *u union_newupper(un, NULLVP); #endif - hash = UNION_HASH(un-un_uppervp, un-un_lowervp); VOP_UNLOCK(vp); mutex_enter(uhash_lock);
CVS commit: src/sys/fs/union
Module Name:src Committed By: christos Date: Thu Oct 17 21:03:50 UTC 2013 Modified Files: src/sys/fs/union: union_subr.c Log Message: remove unused code To generate a diff of this commit: cvs rdiff -u -r1.56 -r1.57 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Re: CVS commit: src/sys/fs/union
On Mon, Dec 05, 2011 at 11:12:11AM +, Juergen Hannken-Illjes wrote: Modified Files: src/sys/fs/union: union_vfsops.c Log Message: The union file system is as stable as other layered file systems so no longer print a warning to the console. Erm... I'm not sure I'd say that. Given some of the known outstanding and more or less unfixable bugs, I think the warning should probably stay... although as discussed somewhere or other it should go in the mount program and not in the kernel. -- David A. Holland dholl...@netbsd.org
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Mon Dec 5 11:12:11 UTC 2011 Modified Files: src/sys/fs/union: union_vfsops.c Log Message: The union file system is as stable as other layered file systems so no longer print a warning to the console. Gnats is waiting ... To generate a diff of this commit: cvs rdiff -u -r1.66 -r1.67 src/sys/fs/union/union_vfsops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_vfsops.c diff -u src/sys/fs/union/union_vfsops.c:1.66 src/sys/fs/union/union_vfsops.c:1.67 --- src/sys/fs/union/union_vfsops.c:1.66 Wed Nov 23 19:39:11 2011 +++ src/sys/fs/union/union_vfsops.c Mon Dec 5 11:12:10 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vfsops.c,v 1.66 2011/11/23 19:39:11 hannken Exp $ */ +/* $NetBSD: union_vfsops.c,v 1.67 2011/12/05 11:12:10 hannken Exp $ */ /* * Copyright (c) 1994 The Regents of the University of California. @@ -77,7 +77,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_vfsops.c,v 1.66 2011/11/23 19:39:11 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_vfsops.c,v 1.67 2011/12/05 11:12:10 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -101,9 +101,6 @@ MODULE(MODULE_CLASS_VFS, union, NULL); VFS_PROTOS(union); static struct sysctllog *union_sysctl_log; -static const char *warn_user = -WARNING: the union file system is experimental\n -WARNING: it can cause crashes and file system corruption\n; /* * Mount union filesystem @@ -151,11 +148,6 @@ union_mount(struct mount *mp, const char goto bad; } - if (warn_user != NULL) { - printf(%s, warn_user); - warn_user = NULL; - } - lowerrootvp = mp-mnt_vnodecovered; vref(lowerrootvp);
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Mon Dec 5 11:12:11 UTC 2011 Modified Files: src/sys/fs/union: union_vfsops.c Log Message: The union file system is as stable as other layered file systems so no longer print a warning to the console. Gnats is waiting ... To generate a diff of this commit: cvs rdiff -u -r1.66 -r1.67 src/sys/fs/union/union_vfsops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Fri Nov 25 11:19:10 UTC 2011 Modified Files: src/sys/fs/union: union_subr.c Log Message: When union_allocvp() finds a node being cleaned out and the caller holds a lock, ignore the node and continue. To allow the cleaning to succeed the current threadmust make progress. For a brief time the cache may contain more than one vnode referring to a lower node. Don't unlock the hash mutex if getnewvnode fails -- we don't hold it. To generate a diff of this commit: cvs rdiff -u -r1.54 -r1.55 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.54 src/sys/fs/union/union_subr.c:1.55 --- src/sys/fs/union/union_subr.c:1.54 Wed Nov 23 19:39:11 2011 +++ src/sys/fs/union/union_subr.c Fri Nov 25 11:19:10 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.54 2011/11/23 19:39:11 hannken Exp $ */ +/* $NetBSD: union_subr.c,v 1.55 2011/11/25 11:19:10 hannken Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.54 2011/11/23 19:39:11 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.55 2011/11/25 11:19:10 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -404,6 +404,18 @@ loop: lflag = LK_EXCLUSIVE; vp = UNIONTOV(un); mutex_enter(vp-v_interlock); + /* + * If this node being cleaned out and our caller + * holds a lock, then ignore it and continue. To + * allow the cleaning to succeed the current thread + * must make progress. For a brief time the cache + * may contain more than one vnode referring to + * a lower node. + */ + if ((vp-v_iflag VI_XLOCK) != 0 lflag == 0) { +mutex_exit(vp-v_interlock); +continue; + } mutex_exit(uhash_lock); if (vget(vp, lflag)) goto loop; @@ -484,7 +496,7 @@ found: if (lowervp) vrele(lowervp); - goto out; + return error; } if (docache) { @@ -493,6 +505,17 @@ found: if (un1-un_lowervp == lowervp un1-un_uppervp == uppervp UNIONTOV(un1)-v_mount == mp) { +vp = UNIONTOV(un1); +mutex_enter(vp-v_interlock); +/* + * Ignore nodes being cleaned out. + * See the cache lookup above. + */ +if ((vp-v_iflag VI_XLOCK) != 0) { + mutex_exit(vp-v_interlock); + continue; +} +mutex_exit(vp-v_interlock); /* * Another thread beat us, push back freshly * allocated vnode and retry. @@ -569,7 +592,6 @@ found: if (xlowervp) vrele(xlowervp); -out: if (docache) mutex_exit(uhash_lock);
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Fri Nov 25 11:19:10 UTC 2011 Modified Files: src/sys/fs/union: union_subr.c Log Message: When union_allocvp() finds a node being cleaned out and the caller holds a lock, ignore the node and continue. To allow the cleaning to succeed the current threadmust make progress. For a brief time the cache may contain more than one vnode referring to a lower node. Don't unlock the hash mutex if getnewvnode fails -- we don't hold it. To generate a diff of this commit: cvs rdiff -u -r1.54 -r1.55 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Re: CVS commit: src/sys/fs/union
My vote would be to remove [unionfs]; it doesn't work and the only reason it was ever brought in had to do with alleged locking improvements. Is anyone using it? I used to make heavy use of unionfs, and I had no problems. (That was on a uniprocessor machine several years ago.) I sometimes used five layers: a base set of sources; a unionfs layer for third party changes; a unionfs layer for my own changes; a unionfs layer for the obj directories; and a final unionfs layer for files created or changed at build time. For example, I could easily blow away all the build products but keep the obj directories, by unmounting the top layer unionfs, removing the files in its backing store, and then re-mounting it. Today, I'd use a smarter revision control system instead of the unionfs layers to manage the source files, but I might still want a unionfs layer to isolate changes made at build time. I have not used unionfs in the past few years, but it would be a pity to lose this functionality. --apb (Alan Barrett)
Re: CVS commit: src/sys/fs/union
On Nov 23, 2011, at 11:11 AM, Alan Barrett wrote: My vote would be to remove [unionfs]; it doesn't work and the only reason it was ever brought in had to do with alleged locking improvements. Is anyone using it? I used to make heavy use of unionfs, and I had no problems. (That was on a uniprocessor machine several years ago.) I sometimes used five layers: a base set of sources; a unionfs layer for third party changes; a unionfs layer for my own changes; a unionfs layer for the obj directories; and a final unionfs layer for files created or changed at build time. For example, I could easily blow away all the build products but keep the obj directories, by unmounting the top layer unionfs, removing the files in its backing store, and then re-mounting it. Today, I'd use a smarter revision control system instead of the unionfs layers to manage the source files, but I might still want a unionfs layer to isolate changes made at build time. I have not used unionfs in the past few years, but it would be a pity to lose this functionality. Do you mean `union'? `unionfs' was imported 2008/02/18 and was never enabled in any kernel config. -- Juergen Hannken-Illjes - hann...@eis.cs.tu-bs.de - TU Braunschweig (Germany)
Re: CVS commit: src/sys/fs/union
On Wed, 23 Nov 2011, J. Hannken-Illjes wrote: I used to make heavy use of unionfs, and I had no problems. [...] Do you mean `union'? I mean mount -t union. `unionfs' was imported 2008/02/18 and was never enabled in any kernel config. No, I haven't used that one. I didn't even know about it. --apb (Alan Barrett)
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Wed Nov 23 19:39:11 UTC 2011 Modified Files: src/sys/fs/union: union.h union_subr.c union_vfsops.c Log Message: Use hashinit() / hashdone() to create the union node hash list. Cleanup the hash lookup in union_allocvp(). Needs more work as there is still a possible deadlock between union_allocvp() and vclean(). To generate a diff of this commit: cvs rdiff -u -r1.22 -r1.23 src/sys/fs/union/union.h cvs rdiff -u -r1.53 -r1.54 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.65 -r1.66 src/sys/fs/union/union_vfsops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union.h diff -u src/sys/fs/union/union.h:1.22 src/sys/fs/union/union.h:1.23 --- src/sys/fs/union/union.h:1.22 Mon Nov 21 18:29:22 2011 +++ src/sys/fs/union/union.h Wed Nov 23 19:39:11 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: union.h,v 1.22 2011/11/21 18:29:22 hannken Exp $ */ +/* $NetBSD: union.h,v 1.23 2011/11/23 19:39:11 hannken Exp $ */ /* * Copyright (c) 1994 The Regents of the University of California. @@ -175,6 +175,7 @@ int union_readdirhook(struct vnode **, s extern int (**union_vnodeop_p)(void *); void union_init(void); +void union_reinit(void); void union_done(void); int union_freevp(struct vnode *); Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.53 src/sys/fs/union/union_subr.c:1.54 --- src/sys/fs/union/union_subr.c:1.53 Mon Nov 21 18:29:22 2011 +++ src/sys/fs/union/union_subr.c Wed Nov 23 19:39:11 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.53 2011/11/21 18:29:22 hannken Exp $ */ +/* $NetBSD: union_subr.c,v 1.54 2011/11/23 19:39:11 hannken Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.53 2011/11/21 18:29:22 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.54 2011/11/23 19:39:11 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -96,15 +96,13 @@ __KERNEL_RCSID(0, $NetBSD: union_subr.c #include miscfs/genfs/genfs.h #include miscfs/specfs/specdev.h -/* must be power of two, otherwise change UNION_HASH() */ -#define NHASH 32 - -/* unsigned int ... */ +static LIST_HEAD(uhashhead, union_node) *uhashtbl; +static u_long uhash_mask; /* size of hash table - 1 */ #define UNION_HASH(u, l) \ - (unsigned long) (u)) + ((unsigned long) l)) 8) (NHASH-1)) + u_long) (u) + (u_long) (l)) 8) uhash_mask) +#define NOHASH ((u_long)-1) -static LIST_HEAD(unhead, union_node) unhead[NHASH]; -static kmutex_t unheadlock[NHASH]; +static kmutex_t uhash_lock; void union_updatevp(struct union_node *, struct vnode *, struct vnode *); static int union_do_lookup(struct vnode *, struct componentname *, kauth_cred_t,const char *, u_long); @@ -115,12 +113,34 @@ struct vnode *union_dircache(struct vnod void union_init(void) { + + mutex_init(uhash_lock, MUTEX_DEFAULT, IPL_NONE); + uhashtbl = hashinit(desiredvnodes, HASH_LIST, true, uhash_mask); +} + +void +union_reinit(void) +{ + struct union_node *un; + struct uhashhead *oldhash, *hash; + u_long oldmask, mask, val; int i; - for (i = 0; i NHASH; i++) { - LIST_INIT(unhead[i]); - mutex_init(unheadlock[i], MUTEX_DEFAULT, IPL_NONE); + hash = hashinit(desiredvnodes, HASH_LIST, true, mask); + mutex_enter(uhash_lock); + oldhash = uhashtbl; + oldmask = uhash_mask; + uhashtbl = hash; + uhash_mask = mask; + for (i = 0; i = oldmask; i++) { + while ((un = LIST_FIRST(oldhash[i])) != NULL) { + LIST_REMOVE(un, un_cache); + val = UNION_HASH(un-un_uppervp, un-un_lowervp); + LIST_INSERT_HEAD(hash[val], un, un_cache); + } } + mutex_exit(uhash_lock); + hashdone(oldhash, HASH_LIST, oldmask); } /* @@ -129,10 +149,9 @@ union_init(void) void union_done(void) { - int i; - for (i = 0; i NHASH; i++) - mutex_destroy(unheadlock[i]); + hashdone(uhashtbl, HASH_LIST, uhash_mask); + mutex_destroy(uhash_lock); /* Make sure to unset the readdir hook. */ vn_union_readdir_hook = NULL; @@ -145,37 +164,19 @@ union_updatevp(struct union_node *un, st int ohash = UNION_HASH(un-un_uppervp, un-un_lowervp); int nhash = UNION_HASH(uppervp, lowervp); int docache = (lowervp != NULLVP || uppervp != NULLVP); - int lhash, uhash; bool un_unlock; KASSERT(VOP_ISLOCKED(UNIONTOV(un)) == LK_EXCLUSIVE); - /* - * Ensure locking is ordered from lower to higher - * to avoid deadlocks. - */ - if (nhash ohash) { - lhash = nhash; - uhash = ohash; - } else { - lhash = ohash; - uhash = nhash; - } - - if (lhash != uhash) - mutex_enter(unheadlock[lhash]); - mutex_enter(unheadlock[uhash]); + mutex_enter(uhash_lock); - if (ohash != nhash || !docache) { + if (!docache || ohash != nhash) { if (un-un_cflags UN_CACHED) { un-un_cflags = ~UN_CACHED; LIST_REMOVE(un, un_cache); } } - if (ohash != nhash) - mutex_exit(unheadlock[ohash]); - if (un-un_lowervp != lowervp) {
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Wed Nov 23 19:39:11 UTC 2011 Modified Files: src/sys/fs/union: union.h union_subr.c union_vfsops.c Log Message: Use hashinit() / hashdone() to create the union node hash list. Cleanup the hash lookup in union_allocvp(). Needs more work as there is still a possible deadlock between union_allocvp() and vclean(). To generate a diff of this commit: cvs rdiff -u -r1.22 -r1.23 src/sys/fs/union/union.h cvs rdiff -u -r1.53 -r1.54 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.65 -r1.66 src/sys/fs/union/union_vfsops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Re: CVS commit: src/sys/fs/union
In article 2022035848.ga17...@netbsd.org, David Holland dholland-sourcechan...@netbsd.org wrote: On Tue, Nov 22, 2011 at 01:17:43AM +, YAMAMOTO Takashi wrote: hi, do you have any plan on fs/unionfs? eg. remove it My vote would be to remove it; it doesn't work and the only reason it was ever brought in had to do with alleged locking improvements. Is anyone using it? christos
Re: CVS commit: src/sys/fs/union
hi, do you have any plan on fs/unionfs? eg. remove it YAMAMOTO Takashi Module Name: src Committed By: hannken Date: Mon Nov 21 18:29:23 UTC 2011 Modified Files: src/sys/fs/union: union.h union_subr.c union_vfsops.c union_vnops.c Log Message: Replace flag based union node locking with generic vnode lock, support shared and nowait locks and protect un_uppervp and un_*sz with mutex. Mark file system MPSAFE. To generate a diff of this commit: cvs rdiff -u -r1.21 -r1.22 src/sys/fs/union/union.h cvs rdiff -u -r1.52 -r1.53 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.64 -r1.65 src/sys/fs/union/union_vfsops.c cvs rdiff -u -r1.48 -r1.49 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Re: CVS commit: src/sys/fs/union
On Tue, Nov 22, 2011 at 01:17:43AM +, YAMAMOTO Takashi wrote: hi, do you have any plan on fs/unionfs? eg. remove it My vote would be to remove it; it doesn't work and the only reason it was ever brought in had to do with alleged locking improvements. -- David A. Holland dholl...@netbsd.org
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Mon Nov 21 18:29:23 UTC 2011 Modified Files: src/sys/fs/union: union.h union_subr.c union_vfsops.c union_vnops.c Log Message: Replace flag based union node locking with generic vnode lock, support shared and nowait locks and protect un_uppervp and un_*sz with mutex. Mark file system MPSAFE. To generate a diff of this commit: cvs rdiff -u -r1.21 -r1.22 src/sys/fs/union/union.h cvs rdiff -u -r1.52 -r1.53 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.64 -r1.65 src/sys/fs/union/union_vfsops.c cvs rdiff -u -r1.48 -r1.49 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union.h diff -u src/sys/fs/union/union.h:1.21 src/sys/fs/union/union.h:1.22 --- src/sys/fs/union/union.h:1.21 Tue Aug 23 07:39:37 2011 +++ src/sys/fs/union/union.h Mon Nov 21 18:29:22 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: union.h,v 1.21 2011/08/23 07:39:37 hannken Exp $ */ +/* $NetBSD: union.h,v 1.22 2011/11/21 18:29:22 hannken Exp $ */ /* * Copyright (c) 1994 The Regents of the University of California. @@ -105,28 +105,36 @@ struct union_mount { #define UN_FILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) /* - * A cache of vnode references + * A cache of vnode references. + * Lock requirements are: + * + * : stable + * c unheadlock[hash] + * l un_lock + * m un_lock or vnode lock to read, un_lock and + * exclusive vnode lock to write + * v vnode lock to read, exclusive vnode lock to write + * + * Lock order is vnode then un_lock. */ struct union_node { - LIST_ENTRY(union_node) un_cache; /* Hash chain */ - struct vnode *un_vnode; /* Back pointer */ - struct vnode *un_uppervp; /* overlaying object */ - struct vnode *un_lowervp; /* underlying object */ - struct vnode *un_dirvp; /* Parent dir of uppervp */ - struct vnode *un_pvp; /* Parent vnode */ - char *un_path; /* saved component name */ - int un_hash; /* saved un_path hash value */ - int un_openl; /* # of opens on lowervp */ - unsigned int un_flags; - struct vnode **un_dircache; /* cached union stack */ - off_t un_uppersz; /* size of upper object */ - off_t un_lowersz; /* size of lower object */ - lwp_t *un_lwp; /* DIAGNOSTIC only */ + kmutex_t un_lock; + LIST_ENTRY(union_node) un_cache; /* c: Hash chain */ + struct vnode *un_vnode; /* :: Back pointer */ + struct vnode *un_uppervp; /* m: overlaying object */ + struct vnode *un_lowervp; /* v: underlying object */ + struct vnode *un_dirvp; /* v: Parent dir of uppervp */ + struct vnode *un_pvp; /* v: Parent vnode */ + char *un_path; /* v: saved component name */ + int un_hash; /* v: saved un_path hash */ + int un_openl; /* v: # of opens on lowervp */ + unsigned int un_flags; /* v: node flags */ + unsigned int un_cflags; /* c: cache flags */ + struct vnode **un_dircache; /* v: cached union stack */ + off_t un_uppersz; /* l: size of upper object */ + off_t un_lowersz; /* l: size of lower object */ }; -#define UN_WANTED 0x01 -#define UN_LOCKED 0x02 -#define UN_ULOCK 0x04 /* Upper node is locked */ #define UN_KLOCK 0x08 /* Keep upper node locked on vput */ #define UN_CACHED 0x10 /* In union cache */ @@ -162,6 +170,7 @@ int union_readdirhook(struct vnode **, s #define LOWERVP(vp) (VTOUNION(vp)-un_lowervp) #define UPPERVP(vp) (VTOUNION(vp)-un_uppervp) #define OTHERVP(vp) (UPPERVP(vp) ? UPPERVP(vp) : LOWERVP(vp)) +#define LOCKVP(vp) (UPPERVP(vp) ? UPPERVP(vp) : (vp)) extern int (**union_vnodeop_p)(void *); Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.52 src/sys/fs/union/union_subr.c:1.53 --- src/sys/fs/union/union_subr.c:1.52 Mon Nov 14 18:38:13 2011 +++ src/sys/fs/union/union_subr.c Mon Nov 21 18:29:22 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.52 2011/11/14 18:38:13 hannken Exp $ */ +/* $NetBSD: union_subr.c,v 1.53 2011/11/21 18:29:22 hannken Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.52 2011/11/14 18:38:13 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.53 2011/11/21 18:29:22 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -93,6 +93,7 @@ __KERNEL_RCSID(0, $NetBSD: union_subr.c #include uvm/uvm_extern.h #include fs/union/union.h +#include miscfs/genfs/genfs.h #include miscfs/specfs/specdev.h /* must be power of two, otherwise change UNION_HASH() */ @@ -145,7 +146,9 @@ union_updatevp(struct union_node *un, st int nhash = UNION_HASH(uppervp, lowervp); int docache = (lowervp != NULLVP || uppervp != NULLVP); int lhash, uhash; + bool un_unlock; + KASSERT(VOP_ISLOCKED(UNIONTOV(un)) == LK_EXCLUSIVE); /* * Ensure locking is ordered from lower to higher * to avoid deadlocks. @@ -164,8 +167,8 @@ union_updatevp(struct union_node *un, st mutex_enter(unheadlock[uhash]); if
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Mon Nov 21 18:29:23 UTC 2011 Modified Files: src/sys/fs/union: union.h union_subr.c union_vfsops.c union_vnops.c Log Message: Replace flag based union node locking with generic vnode lock, support shared and nowait locks and protect un_uppervp and un_*sz with mutex. Mark file system MPSAFE. To generate a diff of this commit: cvs rdiff -u -r1.21 -r1.22 src/sys/fs/union/union.h cvs rdiff -u -r1.52 -r1.53 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.64 -r1.65 src/sys/fs/union/union_vfsops.c cvs rdiff -u -r1.48 -r1.49 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Mon Nov 14 18:38:14 UTC 2011 Modified Files: src/sys/fs/union: union_subr.c Log Message: Remove a needless vnode lock/unlock dance. This is a leftover from the removal of VOP_LEASE(). Function union_removed_upper() always works on unlocked upper vnodes so remove the test-and-unlock and add an assertion. To generate a diff of this commit: cvs rdiff -u -r1.51 -r1.52 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.51 src/sys/fs/union/union_subr.c:1.52 --- src/sys/fs/union/union_subr.c:1.51 Tue Oct 18 09:22:53 2011 +++ src/sys/fs/union/union_subr.c Mon Nov 14 18:38:13 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.51 2011/10/18 09:22:53 hannken Exp $ */ +/* $NetBSD: union_subr.c,v 1.52 2011/11/14 18:38:13 hannken Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.51 2011/10/18 09:22:53 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.52 2011/11/14 18:38:13 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -638,11 +638,6 @@ union_copyfile(struct vnode *fvp, struct uio.uio_offset = 0; UIO_SETUP_SYSSPACE(uio); - VOP_UNLOCK(fvp); /* XXX */ - vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY); /* XXX */ - VOP_UNLOCK(tvp); /* XXX */ - vn_lock(tvp, LK_EXCLUSIVE | LK_RETRY); /* XXX */ - tbuf = malloc(MAXBSIZE, M_TEMP, M_WAITOK); /* ugly loop follows... */ @@ -961,6 +956,7 @@ union_removed_upper(struct union_node *u { int hash; + KASSERT((un-un_flags UN_ULOCK) == 0); #if 1 /* * We do not set the uppervp to NULLVP here, because lowervp @@ -984,11 +980,6 @@ union_removed_upper(struct union_node *u LIST_REMOVE(un, un_cache); } mutex_exit(unheadlock[hash]); - - if (un-un_flags UN_ULOCK) { - un-un_flags = ~UN_ULOCK; - VOP_UNLOCK(un-un_uppervp); - } } #if 0
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Mon Nov 14 18:42:57 UTC 2011 Modified Files: src/sys/fs/union: union_vnops.c Log Message: VOP_ABORTOP() has no specific lock requirements so there is no need to force locked vnodes here. It should be impossible to come here with a nil upper node. Relock the directory vnode after copyup. A locked union node with an unlocked upper vnode can no longer exist so make FIXUP() an assertion. To generate a diff of this commit: cvs rdiff -u -r1.47 -r1.48 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_vnops.c diff -u src/sys/fs/union/union_vnops.c:1.47 src/sys/fs/union/union_vnops.c:1.48 --- src/sys/fs/union/union_vnops.c:1.47 Tue Oct 18 09:22:53 2011 +++ src/sys/fs/union/union_vnops.c Mon Nov 14 18:42:57 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vnops.c,v 1.47 2011/10/18 09:22:53 hannken Exp $ */ +/* $NetBSD: union_vnops.c,v 1.48 2011/11/14 18:42:57 hannken Exp $ */ /* * Copyright (c) 1992, 1993, 1994, 1995 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_vnops.c,v 1.47 2011/10/18 09:22:53 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_vnops.c,v 1.48 2011/11/14 18:42:57 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -134,7 +134,6 @@ int union_getpages(void *); int union_putpages(void *); int union_kqfilter(void *); -static void union_fixup(struct union_node *); static int union_lookup1(struct vnode *, struct vnode **, struct vnode **, struct componentname *); @@ -190,23 +189,12 @@ const struct vnodeopv_entry_desc union_v const struct vnodeopv_desc union_vnodeop_opv_desc = { union_vnodeop_p, union_vnodeop_entries }; -#define FIXUP(un) { \ - if (((un)-un_flags UN_ULOCK) == 0) { \ - union_fixup(un); \ - } \ -} +#define FIXUP(un) \ + KASSERT(((un)-un_flags UN_ULOCK) == UN_ULOCK) #define NODE_IS_SPECIAL(vp) \ ((vp)-v_type == VBLK || (vp)-v_type == VCHR || \ (vp)-v_type == VSOCK || (vp)-v_type == VFIFO) -static void -union_fixup(struct union_node *un) -{ - - vn_lock(un-un_uppervp, LK_EXCLUSIVE | LK_RETRY); - un-un_flags |= UN_ULOCK; -} - static int union_lookup1(struct vnode *udvp, struct vnode **dvpp, struct vnode **vpp, struct componentname *cnp) @@ -1248,6 +1236,9 @@ union_link(void *v) } error = union_copyup(un, 1, cnp-cn_cred, curlwp); if (dun-un_uppervp == un-un_dirvp) { +vn_lock(dun-un_uppervp, +LK_EXCLUSIVE | LK_RETRY); +dun-un_flags |= UN_ULOCK; /* * During copyup, we dropped the lock on the * dir and invalidated any saved namei lookup @@ -1583,24 +1574,11 @@ union_abortop(void *v) struct vnode *a_dvp; struct componentname *a_cnp; } */ *ap = v; - int error; - struct vnode *vp = OTHERVP(ap-a_dvp); - struct union_node *un = VTOUNION(ap-a_dvp); - int islocked = un-un_flags UN_LOCKED; - int dolock = (vp == LOWERVP(ap-a_dvp)); - if (islocked) { - if (dolock) - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); - else - FIXUP(VTOUNION(ap-a_dvp)); - } - ap-a_dvp = vp; - error = VCALL(vp, VOFFSET(vop_abortop), ap); - if (islocked dolock) - VOP_UNLOCK(vp); + KASSERT(UPPERVP(ap-a_dvp) != NULL); - return (error); + ap-a_dvp = UPPERVP(ap-a_dvp); + return VCALL(ap-a_dvp, VOFFSET(vop_abortop), ap); } int
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Mon Nov 14 18:38:14 UTC 2011 Modified Files: src/sys/fs/union: union_subr.c Log Message: Remove a needless vnode lock/unlock dance. This is a leftover from the removal of VOP_LEASE(). Function union_removed_upper() always works on unlocked upper vnodes so remove the test-and-unlock and add an assertion. To generate a diff of this commit: cvs rdiff -u -r1.51 -r1.52 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Mon Nov 14 18:42:57 UTC 2011 Modified Files: src/sys/fs/union: union_vnops.c Log Message: VOP_ABORTOP() has no specific lock requirements so there is no need to force locked vnodes here. It should be impossible to come here with a nil upper node. Relock the directory vnode after copyup. A locked union node with an unlocked upper vnode can no longer exist so make FIXUP() an assertion. To generate a diff of this commit: cvs rdiff -u -r1.47 -r1.48 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Tue Oct 18 09:22:53 UTC 2011 Modified Files: src/sys/fs/union: union_subr.c union_vnops.c Log Message: VOP_GETATTR() needs a shared lock at least. To generate a diff of this commit: cvs rdiff -u -r1.50 -r1.51 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.46 -r1.47 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.50 src/sys/fs/union/union_subr.c:1.51 --- src/sys/fs/union/union_subr.c:1.50 Tue Aug 23 07:39:37 2011 +++ src/sys/fs/union/union_subr.c Tue Oct 18 09:22:53 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.50 2011/08/23 07:39:37 hannken Exp $ */ +/* $NetBSD: union_subr.c,v 1.51 2011/10/18 09:22:53 hannken Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.50 2011/08/23 07:39:37 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.51 2011/10/18 09:22:53 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -472,9 +472,13 @@ loop: if (uppervp != NULLVP) if (VOP_GETATTR(uppervp, va, FSCRED) == 0) uppersz = va.va_size; - if (lowervp != NULLVP) - if (VOP_GETATTR(lowervp, va, FSCRED) == 0) + if (lowervp != NULLVP) { + vn_lock(lowervp, LK_SHARED | LK_RETRY); + error = VOP_GETATTR(lowervp, va, FSCRED); + VOP_UNLOCK(lowervp); + if (error == 0) lowersz = va.va_size; + } hash = UNION_HASH(uppervp, lowervp); /* @@ -1213,18 +1217,16 @@ union_readdirhook(struct vnode **vpp, st if (vp-v_op != union_vnodeop_p) return (0); - if ((lvp = union_dircache(vp, l)) == NULLVP) - return (0); - /* * If the directory is opaque, * then don't show lower entries */ error = VOP_GETATTR(vp, va, fp-f_cred); - if (error || (va.va_flags OPAQUE)) { - vput(lvp); - return (error); - } + if (error || (va.va_flags OPAQUE)) + return error; + + if ((lvp = union_dircache(vp, l)) == NULLVP) + return (0); error = VOP_OPEN(lvp, FREAD, fp-f_cred); if (error) { Index: src/sys/fs/union/union_vnops.c diff -u src/sys/fs/union/union_vnops.c:1.46 src/sys/fs/union/union_vnops.c:1.47 --- src/sys/fs/union/union_vnops.c:1.46 Tue Aug 23 07:39:37 2011 +++ src/sys/fs/union/union_vnops.c Tue Oct 18 09:22:53 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vnops.c,v 1.46 2011/08/23 07:39:37 hannken Exp $ */ +/* $NetBSD: union_vnops.c,v 1.47 2011/10/18 09:22:53 hannken Exp $ */ /* * Copyright (c) 1992, 1993, 1994, 1995 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_vnops.c,v 1.46 2011/08/23 07:39:37 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_vnops.c,v 1.47 2011/10/18 09:22:53 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -830,14 +830,6 @@ union_getattr(void *v) vp = un-un_uppervp; if (vp != NULLVP) { - /* - * It's not clear whether VOP_GETATTR is to be - * called with the vnode locked or not. stat() calls - * it with (vp) locked, and fstat calls it with - * (vp) unlocked. - * In the mean time, compensate here by checking - * the union_node's lock flag. - */ if (un-un_flags UN_LOCKED) FIXUP(un); @@ -858,7 +850,11 @@ union_getattr(void *v) } if (vp != NULLVP) { + if (vp == un-un_lowervp) + vn_lock(vp, LK_SHARED | LK_RETRY); error = VOP_GETATTR(vp, vap, ap-a_cred); + if (vp == un-un_lowervp) + VOP_UNLOCK(vp); if (error) return (error); union_newsize(ap-a_vp, VNOVAL, vap-va_size);
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Tue Oct 18 09:22:53 UTC 2011 Modified Files: src/sys/fs/union: union_subr.c union_vnops.c Log Message: VOP_GETATTR() needs a shared lock at least. To generate a diff of this commit: cvs rdiff -u -r1.50 -r1.51 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.46 -r1.47 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Sun Aug 28 08:27:57 UTC 2011 Modified Files: src/sys/fs/union: union_vfsops.c Log Message: Print the warning message on mount once. Should fix PR #42795 (patch to make mounting union filesystems less obnoxious) To generate a diff of this commit: cvs rdiff -u -r1.63 -r1.64 src/sys/fs/union/union_vfsops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_vfsops.c diff -u src/sys/fs/union/union_vfsops.c:1.63 src/sys/fs/union/union_vfsops.c:1.64 --- src/sys/fs/union/union_vfsops.c:1.63 Mon Jul 5 21:27:08 2010 +++ src/sys/fs/union/union_vfsops.c Sun Aug 28 08:27:57 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vfsops.c,v 1.63 2010/07/05 21:27:08 pooka Exp $ */ +/* $NetBSD: union_vfsops.c,v 1.64 2011/08/28 08:27:57 hannken Exp $ */ /* * Copyright (c) 1994 The Regents of the University of California. @@ -77,7 +77,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_vfsops.c,v 1.63 2010/07/05 21:27:08 pooka Exp $); +__KERNEL_RCSID(0, $NetBSD: union_vfsops.c,v 1.64 2011/08/28 08:27:57 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -101,6 +101,9 @@ VFS_PROTOS(union); static struct sysctllog *union_sysctl_log; +static const char *warn_user = +WARNING: the union file system is experimental\n +WARNING: it can cause crashes and file system corruption\n; /* * Mount union filesystem @@ -148,8 +151,10 @@ goto bad; } - printf(WARNING: the union file system is experimental\n - WARNING: it can cause crashes and file system corruption\n); + if (warn_user != NULL) { + printf(%s, warn_user); + warn_user = NULL; + } lowerrootvp = mp-mnt_vnodecovered; vref(lowerrootvp);
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Tue Aug 23 07:39:37 UTC 2011 Modified Files: src/sys/fs/union: union.h union_subr.c union_vnops.c Log Message: Stop abusing relookup() to prepare the creation of new nodes in the upper layer. Replace union_relookup() with union_do_lookup() that prepares a component, calls VOP_LOOKUP() and does the EEXIST test. To generate a diff of this commit: cvs rdiff -u -r1.20 -r1.21 src/sys/fs/union/union.h cvs rdiff -u -r1.49 -r1.50 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.45 -r1.46 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union.h diff -u src/sys/fs/union/union.h:1.20 src/sys/fs/union/union.h:1.21 --- src/sys/fs/union/union.h:1.20 Fri Aug 12 17:41:17 2011 +++ src/sys/fs/union/union.h Tue Aug 23 07:39:37 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: union.h,v 1.20 2011/08/12 17:41:17 hannken Exp $ */ +/* $NetBSD: union.h,v 1.21 2011/08/23 07:39:37 hannken Exp $ */ /* * Copyright (c) 1994 The Regents of the University of California. @@ -144,7 +144,7 @@ extern int union_mkshadow(struct union_mount *, struct vnode *, struct componentname *, struct vnode **); extern int union_mkwhiteout(struct union_mount *, struct vnode *, -struct componentname *, char *); +struct componentname *, struct union_node *); extern int union_vn_create(struct vnode **, struct union_node *, struct lwp *); extern int union_cn_close(struct vnode *, int, kauth_cred_t, Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.49 src/sys/fs/union/union_subr.c:1.50 --- src/sys/fs/union/union_subr.c:1.49 Sat Aug 13 10:48:14 2011 +++ src/sys/fs/union/union_subr.c Tue Aug 23 07:39:37 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.49 2011/08/13 10:48:14 hannken Exp $ */ +/* $NetBSD: union_subr.c,v 1.50 2011/08/23 07:39:37 hannken Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.49 2011/08/13 10:48:14 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.50 2011/08/23 07:39:37 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -106,10 +106,7 @@ static kmutex_t unheadlock[NHASH]; void union_updatevp(struct union_node *, struct vnode *, struct vnode *); -static int union_relookup(struct union_mount *, struct vnode *, - struct vnode **, struct componentname *, - struct componentname *, char **, - const char *, int); +static int union_do_lookup(struct vnode *, struct componentname *, kauth_cred_t,const char *, u_long); int union_vn_close(struct vnode *, int, kauth_cred_t, struct lwp *); static void union_dircache_r(struct vnode *, struct vnode ***, int *); struct vnode *union_dircache(struct vnode *, struct lwp *); @@ -755,54 +752,50 @@ } +/* + * Prepare the creation of a new node in the upper layer. + * + * (dvp) is the directory in which to create the new node. + * it is locked on entry and exit. + * (cnp) is the componentname to be created. + * (cred, path, hash) are credentials, path and its hash to fill (cnp). + */ static int -union_relookup( - struct union_mount *um, - struct vnode *dvp, - struct vnode **vpp, - struct componentname *cnp, - struct componentname *cn, - char **pnbuf_ret, - const char *path, - int pathlen) +union_do_lookup(struct vnode *dvp, struct componentname *cnp, kauth_cred_t cred, +const char *path, u_long hash) { int error; - char *pnbuf; + const char *cp; + struct vnode *vp; - /* - * A new componentname structure must be faked up because - * there is no way to know where the upper level cnp came - * from or what it is being used for. This must duplicate - * some of the work done by NDINIT, some of the work done - * by namei, some of the work done by lookup and some of - * the work done by VOP_LOOKUP when given a CREATE flag. - * Conclusion: Horrible. - */ - cn-cn_namelen = pathlen; - if ((cn-cn_namelen + 1) MAXPATHLEN) - return (ENAMETOOLONG); - pnbuf = PNBUF_GET(); - memcpy(pnbuf, path, cn-cn_namelen); - pnbuf[cn-cn_namelen] = '\0'; - *pnbuf_ret = pnbuf; - - cn-cn_nameiop = CREATE; - cn-cn_flags = (LOCKPARENT|ISLASTCN); - if (um-um_op == UNMNT_ABOVE) - cn-cn_cred = cnp-cn_cred; - else - cn-cn_cred = um-um_cred; - cn-cn_nameptr = pnbuf; - cn-cn_hash = cnp-cn_hash; - cn-cn_consume = cnp-cn_consume; + cnp-cn_nameiop = CREATE; + cnp-cn_flags = LOCKPARENT | ISLASTCN; + cnp-cn_cred = cred; + cnp-cn_nameptr = path; + cnp-cn_namelen = strlen(path); + if (hash == 0) { + cp = NULL; + cnp-cn_hash = namei_hash(cnp-cn_nameptr, cp); + KASSERT(*cp == 0); + } else { + cnp-cn_hash = hash; + } - error = relookup(dvp, vpp, cn, 0); - if (error) { - PNBUF_PUT(pnbuf); - *pnbuf_ret = NULL; + error = VOP_LOOKUP(dvp, vp, cnp); + + if (error == 0) { + KASSERT(vp != NULL); + VOP_ABORTOP(dvp, cnp); + if (dvp != vp) +
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Tue Aug 23 07:39:37 UTC 2011 Modified Files: src/sys/fs/union: union.h union_subr.c union_vnops.c Log Message: Stop abusing relookup() to prepare the creation of new nodes in the upper layer. Replace union_relookup() with union_do_lookup() that prepares a component, calls VOP_LOOKUP() and does the EEXIST test. To generate a diff of this commit: cvs rdiff -u -r1.20 -r1.21 src/sys/fs/union/union.h cvs rdiff -u -r1.49 -r1.50 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.45 -r1.46 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Sat Aug 13 10:48:14 UTC 2011 Modified Files: src/sys/fs/union: union_subr.c Log Message: Use mutexes to protect the hash lists instead of tsleep/wakeup. To generate a diff of this commit: cvs rdiff -u -r1.48 -r1.49 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.48 src/sys/fs/union/union_subr.c:1.49 --- src/sys/fs/union/union_subr.c:1.48 Fri Aug 12 17:41:17 2011 +++ src/sys/fs/union/union_subr.c Sat Aug 13 10:48:14 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.48 2011/08/12 17:41:17 hannken Exp $ */ +/* $NetBSD: union_subr.c,v 1.49 2011/08/13 10:48:14 hannken Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.48 2011/08/12 17:41:17 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.49 2011/08/13 10:48:14 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -103,10 +103,8 @@ (unsigned long) (u)) + ((unsigned long) l)) 8) (NHASH-1)) static LIST_HEAD(unhead, union_node) unhead[NHASH]; -static int unvplock[NHASH]; +static kmutex_t unheadlock[NHASH]; -static int union_list_lock(int); -static void union_list_unlock(int); void union_updatevp(struct union_node *, struct vnode *, struct vnode *); static int union_relookup(struct union_mount *, struct vnode *, struct vnode **, struct componentname *, @@ -121,9 +119,10 @@ { int i; - for (i = 0; i NHASH; i++) + for (i = 0; i NHASH; i++) { LIST_INIT(unhead[i]); - memset(unvplock, 0, sizeof(unvplock)); + mutex_init(unheadlock[i], MUTEX_DEFAULT, IPL_NONE); + } } /* @@ -132,38 +131,15 @@ void union_done(void) { + int i; + + for (i = 0; i NHASH; i++) + mutex_destroy(unheadlock[i]); /* Make sure to unset the readdir hook. */ vn_union_readdir_hook = NULL; } -static int -union_list_lock(int ix) -{ - - if (unvplock[ix] UN_LOCKED) { - unvplock[ix] |= UN_WANTED; - (void) tsleep(unvplock[ix], PINOD, unionlk, 0); - return (1); - } - - unvplock[ix] |= UN_LOCKED; - - return (0); -} - -static void -union_list_unlock(int ix) -{ - - unvplock[ix] = ~UN_LOCKED; - - if (unvplock[ix] UN_WANTED) { - unvplock[ix] = ~UN_WANTED; - wakeup(unvplock[ix]); - } -} - void union_updatevp(struct union_node *un, struct vnode *uppervp, struct vnode *lowervp) @@ -186,11 +162,9 @@ } if (lhash != uhash) - while (union_list_lock(lhash)) - continue; + mutex_enter(unheadlock[lhash]); - while (union_list_lock(uhash)) - continue; + mutex_enter(unheadlock[uhash]); if (ohash != nhash || !docache) { if (un-un_flags UN_CACHED) { @@ -200,7 +174,7 @@ } if (ohash != nhash) - union_list_unlock(ohash); + mutex_exit(unheadlock[ohash]); if (un-un_lowervp != lowervp) { if (un-un_lowervp) { @@ -237,7 +211,7 @@ un-un_flags |= UN_CACHED; } - union_list_unlock(nhash); + mutex_exit(unheadlock[nhash]); } void @@ -394,8 +368,7 @@ break; } - while (union_list_lock(hash)) - continue; + mutex_enter(unheadlock[hash]); for (un = unhead[hash].lh_first; un != 0; un = un-un_cache.le_next) { @@ -407,14 +380,14 @@ vp = UNIONTOV(un); mutex_enter(vp-v_interlock); if (vget(vp, 0)) { - union_list_unlock(hash); + mutex_exit(unheadlock[hash]); goto loop; } break; } } - union_list_unlock(hash); + mutex_exit(unheadlock[hash]); if (un) break; @@ -528,8 +501,7 @@ } if (docache) { - while (union_list_lock(hash)) - continue; + mutex_enter(unheadlock[hash]); LIST_FOREACH(un1, unhead[hash], un_cache) { if (un1-un_lowervp == lowervp un1-un_uppervp == uppervp @@ -538,7 +510,7 @@ * Another thread beat us, push back freshly * allocated vnode and retry. */ -union_list_unlock(hash); +mutex_exit(unheadlock[hash]); ungetnewvnode(*vpp); goto loop; } @@ -603,7 +575,7 @@ out: if (docache) - union_list_unlock(hash); + mutex_exit(unheadlock[hash]); return (error); } @@ -616,13 +588,12 @@ hash = UNION_HASH(un-un_uppervp, un-un_lowervp); - while (union_list_lock(hash)) - continue; + mutex_enter(unheadlock[hash]); if (un-un_flags UN_CACHED) { un-un_flags = ~UN_CACHED; LIST_REMOVE(un, un_cache); } - union_list_unlock(hash); + mutex_exit(unheadlock[hash]); if (un-un_pvp != NULLVP) vrele(un-un_pvp); @@ -1060,13 +1031,12 @@ hash = UNION_HASH(un-un_uppervp, un-un_lowervp); - while (union_list_lock(hash)) - continue; + mutex_enter(unheadlock[hash]); if (un-un_flags UN_CACHED) { un-un_flags = ~UN_CACHED; LIST_REMOVE(un, un_cache); } - union_list_unlock(hash); + mutex_exit(unheadlock[hash]); if (un-un_flags UN_ULOCK) { un-un_flags = ~UN_ULOCK;
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Sat Aug 13 10:48:14 UTC 2011 Modified Files: src/sys/fs/union: union_subr.c Log Message: Use mutexes to protect the hash lists instead of tsleep/wakeup. To generate a diff of this commit: cvs rdiff -u -r1.48 -r1.49 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Fri Aug 12 06:40:10 UTC 2011 Modified Files: src/sys/fs/union: union_subr.c Log Message: When creating a union node representing a device initialize the spec_node to make vrele() happy. To generate a diff of this commit: cvs rdiff -u -r1.46 -r1.47 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.46 src/sys/fs/union/union_subr.c:1.47 --- src/sys/fs/union/union_subr.c:1.46 Wed Aug 10 15:56:01 2011 +++ src/sys/fs/union/union_subr.c Fri Aug 12 06:40:10 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.46 2011/08/10 15:56:01 hannken Exp $ */ +/* $NetBSD: union_subr.c,v 1.47 2011/08/12 06:40:10 hannken Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.46 2011/08/10 15:56:01 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.47 2011/08/12 06:40:10 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -93,6 +93,7 @@ #include uvm/uvm_extern.h #include fs/union/union.h +#include miscfs/specfs/specdev.h /* must be power of two, otherwise change UNION_HASH() */ #define NHASH 32 @@ -342,6 +343,7 @@ struct vnode *vp, *xlowervp = NULLVP; struct union_mount *um = MOUNTTOUNIONMOUNT(mp); voff_t uppersz, lowersz; + dev_t rdev; int hash = 0; int vflag, iflag; int try; @@ -556,10 +558,19 @@ (*vpp)-v_vflag |= vflag; (*vpp)-v_iflag |= iflag; - if (uppervp) + rdev = NODEV; + if (uppervp) { (*vpp)-v_type = uppervp-v_type; - else + if (uppervp-v_type == VCHR || uppervp-v_type == VBLK) + rdev = uppervp-v_rdev; + } else { (*vpp)-v_type = lowervp-v_type; + if (lowervp-v_type == VCHR || lowervp-v_type == VBLK) + rdev = lowervp-v_rdev; + } + if (rdev != NODEV) + spec_node_init(*vpp, rdev); + un = VTOUNION(*vpp); un-un_vnode = *vpp; un-un_uppervp = uppervp;
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Fri Aug 12 14:36:30 UTC 2011 Modified Files: src/sys/fs/union: union_vnops.c Log Message: Add missing parts to mount devices from a union file system: - union_close()has to lock/unlock the lower vnode. - union_fsync()has to call spec_fsync() for the union vnode. - union_strategy() must allow writes to devices on the lower file system. - union_bwrite() was completely missing. To generate a diff of this commit: cvs rdiff -u -r1.43 -r1.44 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_vnops.c diff -u src/sys/fs/union/union_vnops.c:1.43 src/sys/fs/union/union_vnops.c:1.44 --- src/sys/fs/union/union_vnops.c:1.43 Wed Aug 10 06:27:02 2011 +++ src/sys/fs/union/union_vnops.c Fri Aug 12 14:36:29 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vnops.c,v 1.43 2011/08/10 06:27:02 hannken Exp $ */ +/* $NetBSD: union_vnops.c,v 1.44 2011/08/12 14:36:29 hannken Exp $ */ /* * Copyright (c) 1992, 1993, 1994, 1995 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_vnops.c,v 1.43 2011/08/10 06:27:02 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_vnops.c,v 1.44 2011/08/12 14:36:29 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -91,6 +91,7 @@ #include fs/union/union.h #include miscfs/genfs/genfs.h +#include miscfs/specfs/specdev.h int union_lookup(void *); int union_create(void *); @@ -128,6 +129,7 @@ int union_pathconf(void *); int union_advlock(void *); int union_strategy(void *); +int union_bwrite(void *); int union_getpages(void *); int union_putpages(void *); int union_kqfilter(void *); @@ -175,6 +177,7 @@ { vop_unlock_desc, union_unlock }, /* unlock */ { vop_bmap_desc, union_bmap }, /* bmap */ { vop_strategy_desc, union_strategy }, /* strategy */ + { vop_bwrite_desc, union_bwrite }, /* bwrite */ { vop_print_desc, union_print }, /* print */ { vop_islocked_desc, union_islocked }, /* islocked */ { vop_pathconf_desc, union_pathconf }, /* pathconf */ @@ -182,9 +185,6 @@ { vop_getpages_desc, union_getpages }, /* getpages */ { vop_putpages_desc, union_putpages }, /* putpages */ { vop_kqfilter_desc, union_kqfilter }, /* kqfilter */ -#ifdef notdef - { vop_bwrite_desc, union_bwrite }, /* bwrite */ -#endif { NULL, NULL } }; const struct vnodeopv_desc union_vnodeop_opv_desc = @@ -195,6 +195,9 @@ union_fixup(un); \ } \ } +#define NODE_IS_SPECIAL(vp) \ + ((vp)-v_type == VBLK || (vp)-v_type == VCHR || \ + (vp)-v_type == VSOCK || (vp)-v_type == VFIFO) static void union_fixup(struct union_node *un) @@ -695,24 +698,28 @@ } */ *ap = v; struct union_node *un = VTOUNION(ap-a_vp); struct vnode *vp; + int error; + bool do_lock; vp = un-un_uppervp; - if (vp == NULLVP) { -#ifdef UNION_DIAGNOSTIC - if (un-un_openl = 0) - panic(union: un_openl cnt); -#endif + if (vp != NULLVP) { + do_lock = false; + } else { + KASSERT(un-un_openl 0); --un-un_openl; vp = un-un_lowervp; + do_lock = true; } -#ifdef DIAGNOSTIC - if (vp == NULLVP) - panic(union_close empty union vnode); -#endif - + KASSERT(vp != NULLVP); ap-a_vp = vp; - return (VCALL(vp, VOFFSET(vop_close), ap)); + if (do_lock) + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); + error = VCALL(vp, VOFFSET(vop_close), ap); + if (do_lock) + VOP_UNLOCK(vp); + + return error; } /* @@ -944,20 +951,14 @@ union_newsize(ap-a_vp, vap-va_size, VNOVAL); } else { KASSERT(un-un_lowervp != NULLVP); - switch (un-un_lowervp-v_type) { - case VCHR: - case VBLK: - case VSOCK: - case VFIFO: + if (NODE_IS_SPECIAL(un-un_lowervp)) { if (size_only (vap-va_size == 0 || vap-va_size == VNOVAL)) error = 0; else error = EROFS; - break; - default: + } else { error = EROFS; - break; } } @@ -1023,20 +1024,14 @@ vp = UPPERVP(ap-a_vp); if (vp == NULLVP) { vp = LOWERVP(ap-a_vp); - KASSERT(vp != NULL); - switch (vp-v_type) { - case VBLK: - case VCHR: - case VSOCK: - case VFIFO: + if (NODE_IS_SPECIAL(vp)) { vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); error = VOP_WRITE(vp, ap-a_uio, ap-a_ioflag, ap-a_cred); VOP_UNLOCK(vp); return error; - default: - panic(union: missing upper layer in write); } + panic(union: missing upper layer in write); } FIXUP(un); @@ -1137,11 +1132,16 @@ * they're locked; otherwise, pass it through to the * underlying layer. */ + if (ap-a_vp-v_type == VBLK || ap-a_vp-v_type == VCHR) { + error = spec_fsync(v); + if (error) + return error; + } + if (ap-a_flags FSYNC_RECLAIM) return 0; targetvp = OTHERVP(ap-a_vp); - if (targetvp != NULLVP) { int dolock = (targetvp == LOWERVP(ap-a_vp)); @@ -1885,12 +1885,6 @@ return (VCALL(ovp, VOFFSET(vop_advlock), ap)); } - -/* - * XXX - vop_strategy must be hand coded because it has no - * vnode
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Fri Aug 12 17:41:17 UTC 2011 Modified Files: src/sys/fs/union: union.h union_subr.c union_vnops.c Log Message: Change some `#ifdef DIAGNOSTIC' to `KASSERT'. Instead of a `pid_t' use a `lwp_t *' for locking diagnostics. No functional changes intended. To generate a diff of this commit: cvs rdiff -u -r1.19 -r1.20 src/sys/fs/union/union.h cvs rdiff -u -r1.47 -r1.48 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.44 -r1.45 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union.h diff -u src/sys/fs/union/union.h:1.19 src/sys/fs/union/union.h:1.20 --- src/sys/fs/union/union.h:1.19 Sun Aug 7 06:01:51 2011 +++ src/sys/fs/union/union.h Fri Aug 12 17:41:17 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: union.h,v 1.19 2011/08/07 06:01:51 hannken Exp $ */ +/* $NetBSD: union.h,v 1.20 2011/08/12 17:41:17 hannken Exp $ */ /* * Copyright (c) 1994 The Regents of the University of California. @@ -121,7 +121,7 @@ struct vnode **un_dircache; /* cached union stack */ off_t un_uppersz; /* size of upper object */ off_t un_lowersz; /* size of lower object */ - pid_t un_pid; /* DIAGNOSTIC only */ + lwp_t *un_lwp; /* DIAGNOSTIC only */ }; #define UN_WANTED 0x01 Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.47 src/sys/fs/union/union_subr.c:1.48 --- src/sys/fs/union/union_subr.c:1.47 Fri Aug 12 06:40:10 2011 +++ src/sys/fs/union/union_subr.c Fri Aug 12 17:41:17 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.47 2011/08/12 06:40:10 hannken Exp $ */ +/* $NetBSD: union_subr.c,v 1.48 2011/08/12 17:41:17 hannken Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.47 2011/08/12 06:40:10 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.48 2011/08/12 17:41:17 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -437,13 +437,9 @@ * the lock on (uppervp) no other * process can hold the lock on (un). */ -#ifdef DIAGNOSTIC - if ((un-un_flags UN_LOCKED) == 0) -panic(union: . not locked); - else if (curproc un-un_pid != curproc-p_pid -un-un_pid -1 curproc-p_pid -1) -panic(union: allocvp not lock owner); -#endif + KASSERT((un-un_flags UN_LOCKED) != 0); + KASSERT(curlwp == NULL || un-un_lwp == NULL || + un-un_lwp == curlwp); } else { if (un-un_flags UN_LOCKED) { vrele(UNIONTOV(un)); @@ -454,12 +450,7 @@ } un-un_flags |= UN_LOCKED; -#ifdef DIAGNOSTIC - if (curproc) -un-un_pid = curproc-p_pid; - else -un-un_pid = -1; -#endif + un-un_lwp = curlwp; } /* @@ -588,12 +579,7 @@ if (un-un_uppervp) un-un_flags |= UN_ULOCK; -#ifdef DIAGNOSTIC - if (curproc) - un-un_pid = curproc-p_pid; - else - un-un_pid = -1; -#endif + un-un_lwp = curlwp; if (dvp cnp (lowervp != NULLVP)) { un-un_hash = cnp-cn_hash; un-un_path = malloc(cnp-cn_namelen+1, M_TEMP, M_WAITOK); Index: src/sys/fs/union/union_vnops.c diff -u src/sys/fs/union/union_vnops.c:1.44 src/sys/fs/union/union_vnops.c:1.45 --- src/sys/fs/union/union_vnops.c:1.44 Fri Aug 12 14:36:29 2011 +++ src/sys/fs/union/union_vnops.c Fri Aug 12 17:41:17 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vnops.c,v 1.44 2011/08/12 14:36:29 hannken Exp $ */ +/* $NetBSD: union_vnops.c,v 1.45 2011/08/12 17:41:17 hannken Exp $ */ /* * Copyright (c) 1992, 1993, 1994, 1995 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_vnops.c,v 1.44 2011/08/12 14:36:29 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_vnops.c,v 1.45 2011/08/12 17:41:17 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -1235,13 +1235,7 @@ dun = VTOUNION(ap-a_dvp); -#ifdef DIAGNOSTIC - if (!(ap-a_cnp-cn_flags LOCKPARENT)) { - printf(union_link called without LOCKPARENT set!\n); - error = EIO; /* need some error code for caller is a bozo */ - } else -#endif - + KASSERT((ap-a_cnp-cn_flags LOCKPARENT) != 0); if (ap-a_dvp-v_op != ap-a_vp-v_op) { vp = ap-a_vp; @@ -1680,17 +1674,6 @@ flags = (flags ~LK_SHARED) | LK_EXCLUSIVE; } - /* - * Need to do real lockmgr-style locking here. - * in the mean time, draining won't work quite right, - * which could lead to a few race conditions. - * the following test was here, but is not quite right, we - * still need to take the lock: - if ((flags LK_TYPE_MASK) == LK_DRAIN) - return (0); - */ - - un = VTOUNION(vp); start: un = VTOUNION(vp); @@ -1718,22 +1701,14 @@ /* XXX ignores LK_NOWAIT */ if (un-un_flags UN_LOCKED) { -#ifdef DIAGNOSTIC - if (curproc un-un_pid == curproc-p_pid - un-un_pid -1 curproc-p_pid -1) - panic(union: locking against myself); -#endif + KASSERT(curlwp == NULL || un-un_lwp == NULL || + un-un_lwp != curlwp); un-un_flags |= UN_WANTED;
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Wed Aug 10 06:19:54 UTC 2011 Modified Files: src/sys/fs/union: union_subr.c Log Message: Use LK_SHARED, it is sufficient for VOP_GETATTR() and VOP_READDIR(). To generate a diff of this commit: cvs rdiff -u -r1.44 -r1.45 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.44 src/sys/fs/union/union_subr.c:1.45 --- src/sys/fs/union/union_subr.c:1.44 Sun Aug 7 06:01:51 2011 +++ src/sys/fs/union/union_subr.c Wed Aug 10 06:19:54 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.44 2011/08/07 06:01:51 hannken Exp $ */ +/* $NetBSD: union_subr.c,v 1.45 2011/08/10 06:19:54 hannken Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.44 2011/08/07 06:01:51 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.45 2011/08/10 06:19:54 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -1221,7 +1221,7 @@ return 0; /* Check lower for being empty. */ - vn_lock(un-un_lowervp, LK_EXCLUSIVE | LK_RETRY); + vn_lock(un-un_lowervp, LK_SHARED | LK_RETRY); error = VOP_GETATTR(un-un_lowervp, va, cred); if (error) { VOP_UNLOCK(un-un_lowervp);
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Wed Aug 10 15:56:01 UTC 2011 Modified Files: src/sys/fs/union: union_subr.c Log Message: Update the (shared) v_interlock if the upper node changes. To generate a diff of this commit: cvs rdiff -u -r1.45 -r1.46 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.45 src/sys/fs/union/union_subr.c:1.46 --- src/sys/fs/union/union_subr.c:1.45 Wed Aug 10 06:19:54 2011 +++ src/sys/fs/union/union_subr.c Wed Aug 10 15:56:01 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.45 2011/08/10 06:19:54 hannken Exp $ */ +/* $NetBSD: union_subr.c,v 1.46 2011/08/10 15:56:01 hannken Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.45 2011/08/10 06:19:54 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.46 2011/08/10 15:56:01 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -223,6 +223,12 @@ un-un_uppervp = uppervp; un-un_uppersz = VNOVAL; + /* Update union vnode interlock. */ + if (uppervp != NULL) { + mutex_obj_hold(uppervp-v_interlock); + uvm_obj_setlock(UNIONTOV(un)-v_uobj, + uppervp-v_interlock); + } } if (docache (ohash != nhash)) {
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Wed Aug 10 15:56:01 UTC 2011 Modified Files: src/sys/fs/union: union_subr.c Log Message: Update the (shared) v_interlock if the upper node changes. To generate a diff of this commit: cvs rdiff -u -r1.45 -r1.46 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Fri Jul 16 08:23:28 UTC 2010 Modified Files: src/sys/fs/union: union_subr.c Log Message: Always take the hash list lock before removing a node from the hash chain. Release the hash list lock before calling getnewvnode() and check the hash list again like other file systems do. Take v_interlock before calling vget(). To generate a diff of this commit: cvs rdiff -u -r1.37 -r1.38 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_subr.c diff -u src/sys/fs/union/union_subr.c:1.37 src/sys/fs/union/union_subr.c:1.38 --- src/sys/fs/union/union_subr.c:1.37 Thu Jun 24 13:03:11 2010 +++ src/sys/fs/union/union_subr.c Fri Jul 16 08:23:28 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: union_subr.c,v 1.37 2010/06/24 13:03:11 hannken Exp $ */ +/* $NetBSD: union_subr.c,v 1.38 2010/07/16 08:23:28 hannken Exp $ */ /* * Copyright (c) 1994 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.37 2010/06/24 13:03:11 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_subr.c,v 1.38 2010/07/16 08:23:28 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -330,8 +330,8 @@ { int error; struct vattr va; - struct union_node *un = NULL; - struct vnode *xlowervp = NULLVP; + struct union_node *un = NULL, *un1; + struct vnode *vp, *xlowervp = NULLVP; struct union_mount *um = MOUNTTOUNIONMOUNT(mp); voff_t uppersz, lowersz; int hash = 0; @@ -394,7 +394,9 @@ (un-un_uppervp == uppervp || un-un_uppervp == NULLVP) (UNIONTOV(un)-v_mount == mp)) { -if (vget(UNIONTOV(un), 0)) { +vp = UNIONTOV(un); +mutex_enter(vp-v_interlock); +if (vget(vp, LK_INTERLOCK)) { union_list_unlock(hash); goto loop; } @@ -502,17 +504,7 @@ if (lowervp != NULLVP) if (VOP_GETATTR(lowervp, va, FSCRED) == 0) lowersz = va.va_size; - - if (docache) { - /* - * otherwise lock the vp list while we call getnewvnode - * since that can block. - */ - hash = UNION_HASH(uppervp, lowervp); - - if (union_list_lock(hash)) - goto loop; - } + hash = UNION_HASH(uppervp, lowervp); error = getnewvnode(VT_UNION, mp, union_vnodeop_p, vpp); if (error) { @@ -528,6 +520,24 @@ goto out; } + if (docache) { + while (union_list_lock(hash)) + continue; + LIST_FOREACH(un1, unhead[hash], un_cache) { + if (un1-un_lowervp == lowervp + un1-un_uppervp == uppervp + UNIONTOV(un1)-v_mount == mp) { +/* + * Another thread beat us, push back freshly + * allocated vnode and retry. + */ +union_list_unlock(hash); +ungetnewvnode(*vpp); +goto loop; + } + } + } + (*vpp)-v_data = malloc(sizeof(struct union_node), M_TEMP, M_WAITOK); (*vpp)-v_vflag |= vflag; @@ -590,12 +600,18 @@ int union_freevp(struct vnode *vp) { + int hash; struct union_node *un = VTOUNION(vp); + hash = UNION_HASH(un-un_uppervp, un-un_lowervp); + + while (union_list_lock(hash)) + continue; if (un-un_flags UN_CACHED) { un-un_flags = ~UN_CACHED; LIST_REMOVE(un, un_cache); } + union_list_unlock(hash); if (un-un_pvp != NULLVP) vrele(un-un_pvp); @@ -998,6 +1014,8 @@ void union_removed_upper(struct union_node *un) { + int hash; + #if 1 /* * We do not set the uppervp to NULLVP here, because lowervp @@ -1013,10 +1031,15 @@ union_newupper(un, NULLVP); #endif + hash = UNION_HASH(un-un_uppervp, un-un_lowervp); + + while (union_list_lock(hash)) + continue; if (un-un_flags UN_CACHED) { un-un_flags = ~UN_CACHED; LIST_REMOVE(un, un_cache); } + union_list_unlock(hash); if (un-un_flags UN_ULOCK) { un-un_flags = ~UN_ULOCK;
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Fri Jul 16 08:23:28 UTC 2010 Modified Files: src/sys/fs/union: union_subr.c Log Message: Always take the hash list lock before removing a node from the hash chain. Release the hash list lock before calling getnewvnode() and check the hash list again like other file systems do. Take v_interlock before calling vget(). To generate a diff of this commit: cvs rdiff -u -r1.37 -r1.38 src/sys/fs/union/union_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: pooka Date: Mon Jul 5 21:27:08 UTC 2010 Modified Files: src/sys/fs/union: union_vfsops.c Log Message: union doesn't use layerfs (avoids panic in kernel bootstrap when union is compiled in but none of the layer-using file systems are). To generate a diff of this commit: cvs rdiff -u -r1.62 -r1.63 src/sys/fs/union/union_vfsops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_vfsops.c diff -u src/sys/fs/union/union_vfsops.c:1.62 src/sys/fs/union/union_vfsops.c:1.63 --- src/sys/fs/union/union_vfsops.c:1.62 Wed Jun 30 13:10:35 2010 +++ src/sys/fs/union/union_vfsops.c Mon Jul 5 21:27:08 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vfsops.c,v 1.62 2010/06/30 13:10:35 hannken Exp $ */ +/* $NetBSD: union_vfsops.c,v 1.63 2010/07/05 21:27:08 pooka Exp $ */ /* * Copyright (c) 1994 The Regents of the University of California. @@ -77,7 +77,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_vfsops.c,v 1.62 2010/06/30 13:10:35 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_vfsops.c,v 1.63 2010/07/05 21:27:08 pooka Exp $); #include sys/param.h #include sys/systm.h @@ -96,7 +96,7 @@ #include fs/union/union.h -MODULE(MODULE_CLASS_VFS, union, layerfs); +MODULE(MODULE_CLASS_VFS, union, NULL); VFS_PROTOS(union);
CVS commit: src/sys/fs/union
Module Name:src Committed By: pooka Date: Mon Jul 5 21:27:08 UTC 2010 Modified Files: src/sys/fs/union: union_vfsops.c Log Message: union doesn't use layerfs (avoids panic in kernel bootstrap when union is compiled in but none of the layer-using file systems are). To generate a diff of this commit: cvs rdiff -u -r1.62 -r1.63 src/sys/fs/union/union_vfsops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
CVS commit: src/sys/fs/union
Module Name:src Committed By: hannken Date: Fri Jul 2 07:56:46 UTC 2010 Modified Files: src/sys/fs/union: union_vnops.c Log Message: LK_INTERLOCK is no longer a valid flag for VOP_LOCK(). To generate a diff of this commit: cvs rdiff -u -r1.37 -r1.38 src/sys/fs/union/union_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/fs/union/union_vnops.c diff -u src/sys/fs/union/union_vnops.c:1.37 src/sys/fs/union/union_vnops.c:1.38 --- src/sys/fs/union/union_vnops.c:1.37 Thu Jul 1 13:00:56 2010 +++ src/sys/fs/union/union_vnops.c Fri Jul 2 07:56:46 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vnops.c,v 1.37 2010/07/01 13:00:56 hannken Exp $ */ +/* $NetBSD: union_vnops.c,v 1.38 2010/07/02 07:56:46 hannken Exp $ */ /* * Copyright (c) 1992, 1993, 1994, 1995 @@ -72,7 +72,7 @@ */ #include sys/cdefs.h -__KERNEL_RCSID(0, $NetBSD: union_vnops.c,v 1.37 2010/07/01 13:00:56 hannken Exp $); +__KERNEL_RCSID(0, $NetBSD: union_vnops.c,v 1.38 2010/07/02 07:56:46 hannken Exp $); #include sys/param.h #include sys/systm.h @@ -1630,7 +1630,6 @@ flags = (flags ~LK_SHARED) | LK_EXCLUSIVE; } - genfs_nolock(ap); /* * Need to do real lockmgr-style locking here. * in the mean time, draining won't work quite right, @@ -1640,7 +1639,6 @@ if ((flags LK_TYPE_MASK) == LK_DRAIN) return (0); */ - flags = ~LK_INTERLOCK; un = VTOUNION(vp); start: @@ -1734,7 +1732,6 @@ #ifdef DIAGNOSTIC un-un_pid = 0; #endif - genfs_nounlock(ap); return (0); }