Module Name: src Committed By: tls Date: Sun Aug 10 06:55:54 UTC 2014
Modified Files: src/sys/fs [tls-earlyentropy]: unicode.h src/sys/fs/adosfs [tls-earlyentropy]: adosfs.h adutil.c advfsops.c advnops.c src/sys/fs/cd9660 [tls-earlyentropy]: cd9660_bmap.c cd9660_lookup.c cd9660_node.c cd9660_node.h cd9660_util.c cd9660_vfsops.c cd9660_vnops.c src/sys/fs/efs [tls-earlyentropy]: efs_vfsops.c efs_vnops.c files.efs src/sys/fs/filecorefs [tls-earlyentropy]: filecore_lookup.c filecore_vfsops.c filecore_vnops.c src/sys/fs/hfs [tls-earlyentropy]: hfs_vfsops.c hfs_vnops.c src/sys/fs/msdosfs [tls-earlyentropy]: denode.h msdosfs_denode.c msdosfs_lookup.c msdosfs_vfsops.c msdosfs_vnops.c msdosfsmount.h src/sys/fs/nilfs [tls-earlyentropy]: nilfs_vfsops.c nilfs_vnops.c src/sys/fs/ntfs [tls-earlyentropy]: ntfs_vfsops.c ntfs_vnops.c src/sys/fs/ptyfs [tls-earlyentropy]: ptyfs_vfsops.c ptyfs_vnops.c src/sys/fs/puffs [tls-earlyentropy]: puffs_vfsops.c puffs_vnops.c src/sys/fs/smbfs [tls-earlyentropy]: smbfs_vfsops.c smbfs_vnops.c src/sys/fs/sysvbfs [tls-earlyentropy]: sysvbfs.c sysvbfs_vfsops.c sysvbfs_vnops.c src/sys/fs/tmpfs [tls-earlyentropy]: tmpfs.h tmpfs_fifoops.c tmpfs_mem.c tmpfs_specops.c tmpfs_vfsops.c tmpfs_vnops.c src/sys/fs/udf [tls-earlyentropy]: udf_subr.c udf_vfsops.c udf_vnops.c src/sys/fs/union [tls-earlyentropy]: union_subr.c union_vfsops.c union_vnops.c src/sys/fs/unionfs [tls-earlyentropy]: unionfs_vfsops.c unionfs_vnops.c src/sys/fs/v7fs [tls-earlyentropy]: v7fs_extern.c v7fs_vfsops.c v7fs_vnops.c Removed Files: src/sys/fs/efs [tls-earlyentropy]: efs_ihash.c efs_ihash.h Log Message: Rebase. To generate a diff of this commit: cvs rdiff -u -r1.6 -r1.6.60.1 src/sys/fs/unicode.h cvs rdiff -u -r1.12 -r1.12.10.1 src/sys/fs/adosfs/adosfs.h cvs rdiff -u -r1.16 -r1.16.2.1 src/sys/fs/adosfs/adutil.c cvs rdiff -u -r1.69 -r1.69.2.1 src/sys/fs/adosfs/advfsops.c cvs rdiff -u -r1.43 -r1.43.2.1 src/sys/fs/adosfs/advnops.c cvs rdiff -u -r1.4 -r1.4.64.1 src/sys/fs/cd9660/cd9660_bmap.c cvs rdiff -u -r1.26 -r1.26.2.1 src/sys/fs/cd9660/cd9660_lookup.c cvs rdiff -u -r1.30 -r1.30.2.1 src/sys/fs/cd9660/cd9660_node.c cvs rdiff -u -r1.14 -r1.14.64.1 src/sys/fs/cd9660/cd9660_node.h cvs rdiff -u -r1.10 -r1.10.26.1 src/sys/fs/cd9660/cd9660_util.c cvs rdiff -u -r1.83 -r1.83.2.1 src/sys/fs/cd9660/cd9660_vfsops.c cvs rdiff -u -r1.47 -r1.47.2.1 src/sys/fs/cd9660/cd9660_vnops.c cvs rdiff -u -r1.10 -r0 src/sys/fs/efs/efs_ihash.c cvs rdiff -u -r1.1 -r0 src/sys/fs/efs/efs_ihash.h cvs rdiff -u -r1.24 -r1.24.10.1 src/sys/fs/efs/efs_vfsops.c cvs rdiff -u -r1.31 -r1.31.2.1 src/sys/fs/efs/efs_vnops.c cvs rdiff -u -r1.1 -r1.1.98.1 src/sys/fs/efs/files.efs cvs rdiff -u -r1.19 -r1.19.2.1 src/sys/fs/filecorefs/filecore_lookup.c cvs rdiff -u -r1.75 -r1.75.2.1 src/sys/fs/filecorefs/filecore_vfsops.c cvs rdiff -u -r1.41 -r1.41.2.1 src/sys/fs/filecorefs/filecore_vnops.c cvs rdiff -u -r1.30 -r1.30.2.1 src/sys/fs/hfs/hfs_vfsops.c cvs rdiff -u -r1.29 -r1.29.2.1 src/sys/fs/hfs/hfs_vnops.c cvs rdiff -u -r1.23 -r1.23.10.1 src/sys/fs/msdosfs/denode.h cvs rdiff -u -r1.48 -r1.48.10.1 src/sys/fs/msdosfs/msdosfs_denode.c cvs rdiff -u -r1.32 -r1.32.2.1 src/sys/fs/msdosfs/msdosfs_lookup.c cvs rdiff -u -r1.106 -r1.106.2.1 src/sys/fs/msdosfs/msdosfs_vfsops.c cvs rdiff -u -r1.89 -r1.89.2.1 src/sys/fs/msdosfs/msdosfs_vnops.c cvs rdiff -u -r1.19 -r1.19.10.1 src/sys/fs/msdosfs/msdosfsmount.h cvs rdiff -u -r1.15 -r1.15.2.1 src/sys/fs/nilfs/nilfs_vfsops.c cvs rdiff -u -r1.27 -r1.27.2.1 src/sys/fs/nilfs/nilfs_vnops.c cvs rdiff -u -r1.93 -r1.93.2.1 src/sys/fs/ntfs/ntfs_vfsops.c cvs rdiff -u -r1.56 -r1.56.2.1 src/sys/fs/ntfs/ntfs_vnops.c cvs rdiff -u -r1.49 -r1.49.2.1 src/sys/fs/ptyfs/ptyfs_vfsops.c cvs rdiff -u -r1.46 -r1.46.2.1 src/sys/fs/ptyfs/ptyfs_vnops.c cvs rdiff -u -r1.109 -r1.109.2.1 src/sys/fs/puffs/puffs_vfsops.c cvs rdiff -u -r1.181 -r1.181.2.1 src/sys/fs/puffs/puffs_vnops.c cvs rdiff -u -r1.99 -r1.99.2.1 src/sys/fs/smbfs/smbfs_vfsops.c cvs rdiff -u -r1.89 -r1.89.2.1 src/sys/fs/smbfs/smbfs_vnops.c cvs rdiff -u -r1.13 -r1.13.2.1 src/sys/fs/sysvbfs/sysvbfs.c cvs rdiff -u -r1.42 -r1.42.2.1 src/sys/fs/sysvbfs/sysvbfs_vfsops.c cvs rdiff -u -r1.53 -r1.53.2.1 src/sys/fs/sysvbfs/sysvbfs_vnops.c cvs rdiff -u -r1.48 -r1.48.2.1 src/sys/fs/tmpfs/tmpfs.h cvs rdiff -u -r1.10 -r1.10.2.1 src/sys/fs/tmpfs/tmpfs_fifoops.c cvs rdiff -u -r1.4 -r1.4.28.1 src/sys/fs/tmpfs/tmpfs_mem.c cvs rdiff -u -r1.11 -r1.11.2.1 src/sys/fs/tmpfs/tmpfs_specops.c cvs rdiff -u -r1.58 -r1.58.2.1 src/sys/fs/tmpfs/tmpfs_vfsops.c cvs rdiff -u -r1.118 -r1.118.2.1 src/sys/fs/tmpfs/tmpfs_vnops.c cvs rdiff -u -r1.124 -r1.124.2.1 src/sys/fs/udf/udf_subr.c cvs rdiff -u -r1.66 -r1.66.2.1 src/sys/fs/udf/udf_vfsops.c cvs rdiff -u -r1.91 -r1.91.2.1 src/sys/fs/udf/udf_vnops.c cvs rdiff -u -r1.63 -r1.63.2.1 src/sys/fs/union/union_subr.c cvs rdiff -u -r1.71 -r1.71.2.1 src/sys/fs/union/union_vfsops.c cvs rdiff -u -r1.59 -r1.59.2.1 src/sys/fs/union/union_vnops.c cvs rdiff -u -r1.12 -r1.12.2.1 src/sys/fs/unionfs/unionfs_vfsops.c cvs rdiff -u -r1.7 -r1.7.10.1 src/sys/fs/unionfs/unionfs_vnops.c cvs rdiff -u -r1.2 -r1.2.2.1 src/sys/fs/v7fs/v7fs_extern.c cvs rdiff -u -r1.9 -r1.9.2.1 src/sys/fs/v7fs/v7fs_vfsops.c cvs rdiff -u -r1.16 -r1.16.2.1 src/sys/fs/v7fs/v7fs_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/unicode.h diff -u src/sys/fs/unicode.h:1.6 src/sys/fs/unicode.h:1.6.60.1 --- src/sys/fs/unicode.h:1.6 Mon Apr 28 20:24:02 2008 +++ src/sys/fs/unicode.h Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: unicode.h,v 1.6 2008/04/28 20:24:02 martin Exp $ */ +/* $NetBSD: unicode.h,v 1.6.60.1 2014/08/10 06:55:53 tls Exp $ */ /*- * Copyright (c) 2001, 2004 The NetBSD Foundation, Inc. @@ -76,7 +76,7 @@ static int wput_utf8(char *, size_t, u_i static u_int16_t wget_utf8(const char **str, size_t *sz) { - int c; + size_t c; u_int16_t rune = 0; const char *s = *str; static const int _utf_count[16] = { Index: src/sys/fs/adosfs/adosfs.h diff -u src/sys/fs/adosfs/adosfs.h:1.12 src/sys/fs/adosfs/adosfs.h:1.12.10.1 --- src/sys/fs/adosfs/adosfs.h:1.12 Wed Oct 3 07:20:50 2012 +++ src/sys/fs/adosfs/adosfs.h Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: adosfs.h,v 1.12 2012/10/03 07:20:50 mlelstv Exp $ */ +/* $NetBSD: adosfs.h,v 1.12.10.1 2014/08/10 06:55:53 tls Exp $ */ /* * Copyright (c) 1994 Christian E. Hopps @@ -73,7 +73,6 @@ enum anode_type { AROOT, ADIR, AFILE, AL */ struct anode { struct genfs_node gnode; - LIST_ENTRY(anode) link; enum anode_type type; char name[ADMAXNAMELEN+1]; /* (r/d/f) name for object */ struct datestamp mtimev; /* (r) volume modified */ @@ -112,7 +111,6 @@ struct anode { #define ANODEHASHSZ (512) struct adosfsmount { - LIST_HEAD(anodechain, anode) anodetab[ANODEHASHSZ]; struct mount *mp; /* owner mount */ u_int32_t dostype; /* type of volume */ u_long rootb; /* root block number */ @@ -169,10 +167,6 @@ int adoshash(const u_char *, int, int, i int adunixprot(int); int adosfs_getblktype(struct adosfsmount *, struct buf *); -struct vnode *adosfs_ahashget(struct mount *, ino_t); -void adosfs_ainshash(struct adosfsmount *, struct anode *); -void adosfs_aremhash(struct anode *); - int adosfs_lookup(void *); extern int (**adosfs_vnodeop_p)(void *); Index: src/sys/fs/adosfs/adutil.c diff -u src/sys/fs/adosfs/adutil.c:1.16 src/sys/fs/adosfs/adutil.c:1.16.2.1 --- src/sys/fs/adosfs/adutil.c:1.16 Thu Feb 27 16:51:37 2014 +++ src/sys/fs/adosfs/adutil.c Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: adutil.c,v 1.16 2014/02/27 16:51:37 hannken Exp $ */ +/* $NetBSD: adutil.c,v 1.16.2.1 2014/08/10 06:55:53 tls Exp $ */ /* * Copyright (c) 1994 Christian E. Hopps @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: adutil.c,v 1.16 2014/02/27 16:51:37 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: adutil.c,v 1.16.2.1 2014/08/10 06:55:53 tls Exp $"); #include <sys/param.h> #include <sys/vnode.h> @@ -47,62 +47,8 @@ __KERNEL_RCSID(0, "$NetBSD: adutil.c,v 1 /* * look for anode in the mount's hash table, return locked. */ -#define AHASH(an) ((an) & (ANODEHASHSZ - 1)) static int CapitalChar(int, int); -extern kmutex_t adosfs_hashlock; - -struct vnode * -adosfs_ahashget(struct mount *mp, ino_t an) -{ - struct anodechain *hp; - struct anode *ap; - struct vnode *vp; - - hp = &VFSTOADOSFS(mp)->anodetab[AHASH(an)]; - -start_over: - mutex_enter(&adosfs_hashlock); - for (ap = hp->lh_first; ap != NULL; ap = ap->link.le_next) { - if (ap->block == an) { - vp = ATOV(ap); - mutex_enter(vp->v_interlock); - mutex_exit(&adosfs_hashlock); - if (vget(vp, LK_EXCLUSIVE)) - goto start_over; - return (ATOV(ap)); - } - } - mutex_exit(&adosfs_hashlock); - return (NULL); -} - -/* - * insert in hash table and lock - * - * ap->vp must have been initialized before this call. - */ -void -adosfs_ainshash(struct adosfsmount *amp, struct anode *ap) -{ - int error __diagused; - - error = VOP_LOCK(ATOV(ap), LK_EXCLUSIVE); - KASSERT(error == 0); - - mutex_enter(&adosfs_hashlock); - LIST_INSERT_HEAD(&->anodetab[AHASH(ap->block)], ap, link); - mutex_exit(&adosfs_hashlock); -} - -void -adosfs_aremhash(struct anode *ap) -{ - mutex_enter(&adosfs_hashlock); - LIST_REMOVE(ap, link); - mutex_exit(&adosfs_hashlock); -} - int adosfs_getblktype(struct adosfsmount *amp, struct buf *bp) { Index: src/sys/fs/adosfs/advfsops.c diff -u src/sys/fs/adosfs/advfsops.c:1.69 src/sys/fs/adosfs/advfsops.c:1.69.2.1 --- src/sys/fs/adosfs/advfsops.c:1.69 Sun Mar 23 15:21:15 2014 +++ src/sys/fs/adosfs/advfsops.c Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: advfsops.c,v 1.69 2014/03/23 15:21:15 hannken Exp $ */ +/* $NetBSD: advfsops.c,v 1.69.2.1 2014/08/10 06:55:53 tls Exp $ */ /* * Copyright (c) 1994 Christian E. Hopps @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: advfsops.c,v 1.69 2014/03/23 15:21:15 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: advfsops.c,v 1.69.2.1 2014/08/10 06:55:53 tls Exp $"); #if defined(_KERNEL_OPT) #include "opt_compat_netbsd.h" @@ -70,8 +70,6 @@ static struct sysctllog *adosfs_sysctl_l int adosfs_mountfs(struct vnode *, struct mount *, struct lwp *); int adosfs_loadbitmap(struct adosfsmount *); -kmutex_t adosfs_hashlock; - struct pool adosfs_node_pool; MALLOC_JUSTDEFINE(M_ANODE, "adosfs anode","adosfs anode structures and tables"); @@ -92,6 +90,8 @@ adosfs_mount(struct mount *mp, const cha int error; mode_t accessmode; + if (args == NULL) + return EINVAL; if (*data_len < sizeof *args) return EINVAL; @@ -167,7 +167,7 @@ adosfs_mountfs(struct vnode *devvp, stru struct buf *bp; struct vnode *rvp; size_t bitmap_sz = 0; - int error, i; + int error; uint64_t numsecs; unsigned secsize; unsigned long secsperblk, blksperdisk, resvblks; @@ -262,12 +262,6 @@ adosfs_mountfs(struct vnode *devvp, stru mp->mnt_flag |= MNT_LOCAL; /* - * init anode table. - */ - for (i = 0; i < ANODEHASHSZ; i++) - LIST_INIT(&->anodetab[i]); - - /* * get the root anode, if not a valid fs this will fail. */ if ((error = VFS_ROOT(mp, &rvp)) != 0) @@ -369,50 +363,55 @@ adosfs_statvfs(struct mount *mp, struct } /* - * lookup an anode, check mount's hash table if not found, create - * return locked and referenced al la vget(vp, 1); + * lookup an anode, if not found, create + * return locked and referenced al la vget(vp, LK_EXCLUSIVE); */ int adosfs_vget(struct mount *mp, ino_t an, struct vnode **vpp) { + int error; + + error = vcache_get(mp, &an, sizeof(an), vpp); + if (error) + return error; + error = vn_lock(*vpp, LK_EXCLUSIVE); + if (error) { + vrele(*vpp); + *vpp = NULL; + return error; + } + return 0; +} + +/* + * Initialize this vnode / anode pair. + * Caller assures no other thread will try to load this inode. + */ +int +adosfs_loadvnode(struct mount *mp, struct vnode *vp, + const void *key, size_t key_len, const void **new_key) +{ struct adosfsmount *amp; - struct vnode *vp; struct anode *ap; struct buf *bp; + ino_t an; char *nam, *tmp; int namlen, error; - error = 0; + KASSERT(key_len == sizeof(an)); + memcpy(&an, key, key_len); amp = VFSTOADOSFS(mp); - bp = NULL; - /* - * check hash table. we are done if found - */ - if ((*vpp = adosfs_ahashget(mp, an)) != NULL) - return (0); - - error = getnewvnode(VT_ADOSFS, mp, adosfs_vnodeop_p, NULL, &vp); - if (error) - return (error); + if ((error = bread(amp->devvp, an * amp->bsize / DEV_BSIZE, + amp->bsize, NOCRED, 0, &bp)) != 0) + return error; - /* - * setup, insert in hash, and lock before io. - */ - vp->v_data = ap = pool_get(&adosfs_node_pool, PR_WAITOK); + ap = pool_get(&adosfs_node_pool, PR_WAITOK); memset(ap, 0, sizeof(struct anode)); ap->vp = vp; ap->amp = amp; ap->block = an; ap->nwords = amp->nwords; - genfs_node_init(vp, &adosfs_genfsops); - adosfs_ainshash(amp, ap); - - if ((error = bread(amp->devvp, an * amp->bsize / DEV_BSIZE, - amp->bsize, NOCRED, 0, &bp)) != 0) { - vput(vp); - return (error); - } /* * get type and fill rest in based on that. @@ -466,9 +465,8 @@ adosfs_vget(struct mount *mp, ino_t an, ap->fsize = namlen; break; default: - brelse(bp, 0); - vput(vp); - return (EINVAL); + error = EINVAL; + goto bad; } /* @@ -486,9 +484,8 @@ adosfs_vget(struct mount *mp, ino_t an, printf("adosfs: aget: name length too long blk %llu\n", (unsigned long long)an); #endif - brelse(bp, 0); - vput(vp); - return (EINVAL); + error = EINVAL; + goto bad; } memcpy(ap->name, nam, namlen); ap->name[namlen] = 0; @@ -529,15 +526,9 @@ adosfs_vget(struct mount *mp, ino_t an, bp = NULL; error = bread(amp->devvp, ap->linkto * amp->bsize / DEV_BSIZE, amp->bsize, NOCRED, 0, &bp); - if (error) { - vput(vp); - return (error); - } + if (error) + goto bad; ap->fsize = adoswordn(bp, ap->nwords - 47); - /* - * Should ap->block be set to the real file header block? - */ - ap->block = ap->linkto; } if (ap->type == AROOT) { @@ -584,10 +575,20 @@ adosfs_vget(struct mount *mp, ino_t an, ap->mtime.mins = adoswordn(bp, ap->nwords - 22); ap->mtime.ticks = adoswordn(bp, ap->nwords - 21); - *vpp = vp; brelse(bp, 0); + vp->v_tag = VT_ADOSFS; + vp->v_op = adosfs_vnodeop_p; + vp->v_data = ap; + genfs_node_init(vp, &adosfs_genfsops); uvm_vnp_setsize(vp, ap->fsize); - return (0); + *new_key = &ap->block; + return 0; + +bad: + if (bp) + brelse(bp, 0); + pool_put(&adosfs_node_pool, ap); + return error; } /* @@ -759,7 +760,6 @@ adosfs_init(void) { malloc_type_attach(M_ANODE); - mutex_init(&adosfs_hashlock, MUTEX_DEFAULT, IPL_NONE); pool_init(&adosfs_node_pool, sizeof(struct anode), 0, 0, 0, "adosndpl", &pool_allocator_nointr, IPL_NONE); } @@ -769,7 +769,6 @@ adosfs_done(void) { pool_destroy(&adosfs_node_pool); - mutex_destroy(&adosfs_hashlock); malloc_type_detach(M_ANODE); } @@ -795,6 +794,7 @@ struct vfsops adosfs_vfsops = { .vfs_statvfs = adosfs_statvfs, .vfs_sync = adosfs_sync, .vfs_vget = adosfs_vget, + .vfs_loadvnode = adosfs_loadvnode, .vfs_fhtovp = adosfs_fhtovp, .vfs_vptofh = adosfs_vptofh, .vfs_init = adosfs_init, Index: src/sys/fs/adosfs/advnops.c diff -u src/sys/fs/adosfs/advnops.c:1.43 src/sys/fs/adosfs/advnops.c:1.43.2.1 --- src/sys/fs/adosfs/advnops.c:1.43 Thu Jan 23 10:13:56 2014 +++ src/sys/fs/adosfs/advnops.c Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: advnops.c,v 1.43 2014/01/23 10:13:56 hannken Exp $ */ +/* $NetBSD: advnops.c,v 1.43.2.1 2014/08/10 06:55:53 tls Exp $ */ /* * Copyright (c) 1994 Christian E. Hopps @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: advnops.c,v 1.43 2014/01/23 10:13:56 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: advnops.c,v 1.43.2.1 2014/08/10 06:55:53 tls Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -105,6 +105,8 @@ const struct vnodeopv_entry_desc adosfs_ { &vop_setattr_desc, adosfs_setattr }, /* setattr */ { &vop_read_desc, adosfs_read }, /* read */ { &vop_write_desc, adosfs_write }, /* write */ + { &vop_fallocate_desc, genfs_eopnotsupp }, /* fallocate */ + { &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */ { &vop_fcntl_desc, adosfs_fcntl }, /* fcntl */ { &vop_ioctl_desc, adosfs_ioctl }, /* ioctl */ { &vop_poll_desc, adosfs_poll }, /* poll */ @@ -878,7 +880,7 @@ adosfs_reclaim(void *v) #endif vp = sp->a_vp; ap = VTOA(vp); - LIST_REMOVE(ap, link); + vcache_remove(vp->v_mount, &ap->block, sizeof(ap->block)); if (vp->v_type == VDIR && ap->tab) free(ap->tab, M_ANODE); else if (vp->v_type == VLNK && ap->slinkto) Index: src/sys/fs/cd9660/cd9660_bmap.c diff -u src/sys/fs/cd9660/cd9660_bmap.c:1.4 src/sys/fs/cd9660/cd9660_bmap.c:1.4.64.1 --- src/sys/fs/cd9660/cd9660_bmap.c:1.4 Wed Feb 27 19:43:36 2008 +++ src/sys/fs/cd9660/cd9660_bmap.c Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: cd9660_bmap.c,v 1.4 2008/02/27 19:43:36 matt Exp $ */ +/* $NetBSD: cd9660_bmap.c,v 1.4.64.1 2014/08/10 06:55:53 tls Exp $ */ /*- * Copyright (c) 1994 @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cd9660_bmap.c,v 1.4 2008/02/27 19:43:36 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cd9660_bmap.c,v 1.4.64.1 2014/08/10 06:55:53 tls Exp $"); #include <sys/param.h> #include <sys/namei.h> @@ -74,7 +74,7 @@ cd9660_bmap(void *v) * to physical mapping is requested. */ if (ap->a_vpp != NULL) - *ap->a_vpp = ip->i_devvp; + *ap->a_vpp = ip->i_mnt->im_devvp; if (ap->a_bnp == NULL) return (0); Index: src/sys/fs/cd9660/cd9660_lookup.c diff -u src/sys/fs/cd9660/cd9660_lookup.c:1.26 src/sys/fs/cd9660/cd9660_lookup.c:1.26.2.1 --- src/sys/fs/cd9660/cd9660_lookup.c:1.26 Fri Feb 7 15:29:21 2014 +++ src/sys/fs/cd9660/cd9660_lookup.c Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: cd9660_lookup.c,v 1.26 2014/02/07 15:29:21 hannken Exp $ */ +/* $NetBSD: cd9660_lookup.c,v 1.26.2.1 2014/08/10 06:55:53 tls Exp $ */ /*- * Copyright (c) 1989, 1993, 1994 @@ -39,7 +39,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cd9660_lookup.c,v 1.26 2014/02/07 15:29:21 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cd9660_lookup.c,v 1.26.2.1 2014/08/10 06:55:53 tls Exp $"); #include <sys/param.h> #include <sys/namei.h> @@ -57,8 +57,6 @@ __KERNEL_RCSID(0, "$NetBSD: cd9660_looku #include <fs/cd9660/cd9660_rrip.h> #include <fs/cd9660/cd9660_mount.h> -struct nchstats iso_nchstats; - /* * Convert a component of a pathname into a pointer to a locked inode. * This is a very central and rather complicated routine. @@ -109,8 +107,7 @@ cd9660_lookup(void *v) int saveoffset = -1; /* offset of last directory entry in dir */ int numdirpasses; /* strategy for directory search */ doff_t endsearch; /* offset to end directory search */ - struct vnode *pdp; /* saved dp during symlink work */ - struct vnode *tdp; /* returned by cd9660_vget_internal */ + struct vnode *tdp; /* returned by vcache_get */ u_long bmask; /* block offset mask */ int error; ino_t ino = 0; @@ -191,7 +188,7 @@ cd9660_lookup(void *v) &bp))) return (error); numdirpasses = 2; - iso_nchstats.ncs_2passes++; + namecache_count_2passes(); } endsearch = dp->i_size; @@ -343,7 +340,8 @@ notfound: found: if (numdirpasses == 2) - iso_nchstats.ncs_pass2++; + namecache_count_pass2(); + brelse(bp, 0); /* * Found component in pathname. @@ -353,46 +351,12 @@ found: if ((flags & ISLASTCN) && nameiop == LOOKUP) dp->i_diroff = dp->i_offset; - /* - * Step through the translation in the name. We do not `iput' the - * directory because we may need it again if a symbolic link - * is relative to the current directory. Instead we save it - * unlocked as "pdp". We must get the target inode before unlocking - * the directory to insure that the inode will not be removed - * before we get it. We prevent deadlock by always fetching - * inodes from the root, moving down the directory tree. Thus - * when following backward pointers ".." we must unlock the - * parent directory before getting the requested directory. - * There is a potential race condition here if both the current - * and parent directories are removed before the `iget' for the - * inode associated with ".." returns. We hope that this occurs - * infrequently since we cannot avoid this race condition without - * implementing a sophisticated deadlock detection algorithm. - * Note also that this simple deadlock detection scheme will not - * work if the file system has any hard links other than ".." - * that point backwards in the directory structure. - */ - pdp = vdp; - - /* - * If ino is different from dp->i_ino, - * it's a relocated directory. - */ - brelse(bp, 0); - if (flags & ISDOTDOT) { - VOP_UNLOCK(pdp); /* race to get the inode */ - error = cd9660_vget_internal(vdp->v_mount, dp->i_ino, &tdp, - dp->i_ino != ino, ep); - vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY); - if (error) - return error; - *vpp = tdp; - } else if (dp->i_number == dp->i_ino) { + if (dp->i_number == dp->i_ino) { vref(vdp); /* we want ourself, ie "." */ *vpp = vdp; } else { - error = cd9660_vget_internal(vdp->v_mount, dp->i_ino, &tdp, - dp->i_ino != ino, ep); + error = vcache_get(vdp->v_mount, + &dp->i_ino, sizeof(dp->i_ino), &tdp); if (error) return (error); *vpp = tdp; @@ -403,8 +367,6 @@ found: */ cache_enter(vdp, *vpp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_flags); - if (*vpp != vdp) - VOP_UNLOCK(*vpp); return 0; } @@ -418,6 +380,7 @@ cd9660_blkatoff(struct vnode *vp, off_t { struct iso_node *ip; struct iso_mnt *imp; + struct vnode *devvp; struct buf *bp; daddr_t lbn; int bsize, error; @@ -427,7 +390,11 @@ cd9660_blkatoff(struct vnode *vp, off_t lbn = cd9660_lblkno(imp, offset); bsize = cd9660_blksize(imp, ip, lbn); - if ((error = bread(vp, lbn, bsize, NOCRED, 0, &bp)) != 0) { + if ((error = VOP_BMAP(vp, lbn, &devvp, &lbn, NULL)) != 0) { + *bpp = NULL; + return error; + } + if ((error = bread(devvp, lbn, bsize, NOCRED, 0, &bp)) != 0) { *bpp = NULL; return (error); } Index: src/sys/fs/cd9660/cd9660_node.c diff -u src/sys/fs/cd9660/cd9660_node.c:1.30 src/sys/fs/cd9660/cd9660_node.c:1.30.2.1 --- src/sys/fs/cd9660/cd9660_node.c:1.30 Thu Feb 27 16:51:38 2014 +++ src/sys/fs/cd9660/cd9660_node.c Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: cd9660_node.c,v 1.30 2014/02/27 16:51:38 hannken Exp $ */ +/* $NetBSD: cd9660_node.c,v 1.30.2.1 2014/08/10 06:55:53 tls Exp $ */ /*- * Copyright (c) 1982, 1986, 1989, 1994 @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cd9660_node.c,v 1.30 2014/02/27 16:51:38 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cd9660_node.c,v 1.30.2.1 2014/08/10 06:55:53 tls Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -58,15 +58,6 @@ __KERNEL_RCSID(0, "$NetBSD: cd9660_node. #include <fs/cd9660/cd9660_mount.h> #include <fs/cd9660/iso_rrip.h> -/* - * Structures associated with iso_node caching. - */ -LIST_HEAD(ihashhead, iso_node) *isohashtbl; -u_long isohash; -#define INOHASH(device, inum) (((device) + ((inum)>>12)) & isohash) -kmutex_t cd9660_ihash_lock; -kmutex_t cd9660_hashlock; - extern int prtactive; /* 1 => print out reclaim of active vnodes */ struct pool cd9660_node_pool; @@ -74,7 +65,7 @@ struct pool cd9660_node_pool; static u_int cd9660_chars2ui(const u_char *, int); /* - * Initialize hash links for inodes and dnodes. + * Initialize pool for nodes. */ void cd9660_init(void) @@ -83,118 +74,29 @@ cd9660_init(void) malloc_type_attach(M_ISOFSMNT); pool_init(&cd9660_node_pool, sizeof(struct iso_node), 0, 0, 0, "cd9660nopl", &pool_allocator_nointr, IPL_NONE); - isohashtbl = hashinit(desiredvnodes, HASH_LIST, true, &isohash); - mutex_init(&cd9660_ihash_lock, MUTEX_DEFAULT, IPL_NONE); - mutex_init(&cd9660_hashlock, MUTEX_DEFAULT, IPL_NONE); } /* - * Reinitialize inode hash table. + * Reinitialize. */ void cd9660_reinit(void) { - struct iso_node *ip; - struct ihashhead *oldhash1, *hash1; - u_long oldmask1, mask1, val; - u_int i; - - hash1 = hashinit(desiredvnodes, HASH_LIST, true, &mask1); - - mutex_enter(&cd9660_ihash_lock); - oldhash1 = isohashtbl; - oldmask1 = isohash; - isohashtbl = hash1; - isohash = mask1; - for (i = 0; i <= oldmask1; i++) { - while ((ip = LIST_FIRST(&oldhash1[i])) != NULL) { - LIST_REMOVE(ip, i_hash); - val = INOHASH(ip->i_dev, ip->i_number); - LIST_INSERT_HEAD(&hash1[val], ip, i_hash); - } - } - mutex_exit(&cd9660_ihash_lock); - hashdone(oldhash1, HASH_LIST, oldmask1); + } /* - * Destroy node pool and hash table. + * Destroy node pool. */ void cd9660_done(void) { - hashdone(isohashtbl, HASH_LIST, isohash); pool_destroy(&cd9660_node_pool); - mutex_destroy(&cd9660_ihash_lock); - mutex_destroy(&cd9660_hashlock); malloc_type_detach(M_ISOFSMNT); } /* - * Use the device/inum pair to find the incore inode, and return a pointer - * to it. If it is in core, but locked, wait for it. - */ -struct vnode * -cd9660_ihashget(dev_t dev, ino_t inum, int flags) -{ - struct iso_node *ip; - struct vnode *vp; - -loop: - mutex_enter(&cd9660_ihash_lock); - LIST_FOREACH(ip, &isohashtbl[INOHASH(dev, inum)], i_hash) { - if (inum == ip->i_number && dev == ip->i_dev) { - vp = ITOV(ip); - if (flags == 0) { - mutex_exit(&cd9660_ihash_lock); - } else { - mutex_enter(vp->v_interlock); - mutex_exit(&cd9660_ihash_lock); - if (vget(vp, flags)) - goto loop; - } - return (vp); - } - } - mutex_exit(&cd9660_ihash_lock); - return (NULL); -} - -/* - * Insert the inode into the hash table, and return it locked. - * - * ip->i_vnode must be initialized first. - */ -void -cd9660_ihashins(struct iso_node *ip) -{ - struct ihashhead *ipp; - int error __diagused; - - KASSERT(mutex_owned(&cd9660_hashlock)); - - mutex_enter(&cd9660_ihash_lock); - ipp = &isohashtbl[INOHASH(ip->i_dev, ip->i_number)]; - LIST_INSERT_HEAD(ipp, ip, i_hash); - mutex_exit(&cd9660_ihash_lock); - - error = VOP_LOCK(ITOV(ip), LK_EXCLUSIVE); - KASSERT(error == 0); -} - -/* - * Remove the inode from the hash table. - */ -void -cd9660_ihashrem(struct iso_node *ip) -{ - mutex_enter(&cd9660_ihash_lock); - LIST_REMOVE(ip, i_hash); - mutex_exit(&cd9660_ihash_lock); -} - -/* * Last reference to an inode, write the inode out and if necessary, * truncate and deallocate the file. */ @@ -235,16 +137,12 @@ cd9660_reclaim(void *v) if (prtactive && vp->v_usecount > 1) vprint("cd9660_reclaim: pushing active", vp); /* - * Remove the inode from its hash chain. + * Remove the inode from the vnode cache. */ - cd9660_ihashrem(ip); + vcache_remove(vp->v_mount, &ip->i_number, sizeof(ip->i_number)); /* * Purge old data structures associated with the inode. */ - if (ip->i_devvp) { - vrele(ip->i_devvp); - ip->i_devvp = 0; - } genfs_node_destroy(vp); pool_put(&cd9660_node_pool, vp->v_data); vp->v_data = NULL; @@ -440,7 +338,14 @@ isodirino(struct iso_directory_record *i { ino_t ino; - ino = (isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length)) - << imp->im_bshift; - return (ino); + /* + * Note there is an inverse calculation in + * cd9660_vfsops.c:cd9660_loadvnode(): + * ip->iso_start = ino >> imp->im_bshift; + * and also a calculation of the isodir pointer + * from an inode in cd9660_vnops.c:cd9660_readlink() + */ + ino = ((ino_t)isonum_733(isodir->extent) + + isonum_711(isodir->ext_attr_length)) << imp->im_bshift; + return ino; } Index: src/sys/fs/cd9660/cd9660_node.h diff -u src/sys/fs/cd9660/cd9660_node.h:1.14 src/sys/fs/cd9660/cd9660_node.h:1.14.64.1 --- src/sys/fs/cd9660/cd9660_node.h:1.14 Wed Feb 27 19:43:36 2008 +++ src/sys/fs/cd9660/cd9660_node.h Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: cd9660_node.h,v 1.14 2008/02/27 19:43:36 matt Exp $ */ +/* $NetBSD: cd9660_node.h,v 1.14.64.1 2014/08/10 06:55:53 tls Exp $ */ /*- * Copyright (c) 1994 @@ -63,7 +63,6 @@ typedef struct { struct iso_node { struct genfs_node i_gnode; - LIST_ENTRY(iso_node) i_hash; struct vnode *i_vnode; /* vnode associated with this inode */ struct vnode *i_devvp; /* vnode for block I/O */ u_long i_flag; /* see below */ @@ -128,15 +127,8 @@ void cd9660_defattr(struct iso_directory struct iso_node *, struct buf *); void cd9660_deftstamp(struct iso_directory_record *, struct iso_node *, struct buf *); -struct vnode *cd9660_ihashget(dev_t, ino_t, int); -void cd9660_ihashins(struct iso_node *); -void cd9660_ihashrem(struct iso_node *); int cd9660_tstamp_conv7(const u_char *, struct timespec *); int cd9660_tstamp_conv17(const u_char *, struct timespec *); -int cd9660_vget_internal(struct mount *, ino_t, struct vnode **, int, - struct iso_directory_record *); - -extern kmutex_t cd9660_hashlock; #endif /* _KERNEL */ #endif /* _ISOFS_CD9660_CD9660_NODE_H_ */ Index: src/sys/fs/cd9660/cd9660_util.c diff -u src/sys/fs/cd9660/cd9660_util.c:1.10 src/sys/fs/cd9660/cd9660_util.c:1.10.26.1 --- src/sys/fs/cd9660/cd9660_util.c:1.10 Tue Sep 27 01:01:43 2011 +++ src/sys/fs/cd9660/cd9660_util.c Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: cd9660_util.c,v 1.10 2011/09/27 01:01:43 christos Exp $ */ +/* $NetBSD: cd9660_util.c,v 1.10.26.1 2014/08/10 06:55:53 tls Exp $ */ /*- * Copyright (c) 1994 @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cd9660_util.c,v 1.10 2011/09/27 01:01:43 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cd9660_util.c,v 1.10.26.1 2014/08/10 06:55:53 tls Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -117,7 +117,6 @@ isofncmp(const u_char *fn, size_t fnlen, case ';': break; } - fn++; for (i = 0; fnlen-- != 0; i = i * 10 + *fn++ - '0') { if (*fn < '0' || *fn > '9') { return -1; Index: src/sys/fs/cd9660/cd9660_vfsops.c diff -u src/sys/fs/cd9660/cd9660_vfsops.c:1.83 src/sys/fs/cd9660/cd9660_vfsops.c:1.83.2.1 --- src/sys/fs/cd9660/cd9660_vfsops.c:1.83 Mon Mar 24 04:03:25 2014 +++ src/sys/fs/cd9660/cd9660_vfsops.c Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: cd9660_vfsops.c,v 1.83 2014/03/24 04:03:25 dholland Exp $ */ +/* $NetBSD: cd9660_vfsops.c,v 1.83.2.1 2014/08/10 06:55:53 tls Exp $ */ /*- * Copyright (c) 1994 @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cd9660_vfsops.c,v 1.83 2014/03/24 04:03:25 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cd9660_vfsops.c,v 1.83.2.1 2014/08/10 06:55:53 tls Exp $"); #if defined(_KERNEL_OPT) #include "opt_compat_netbsd.h" @@ -102,6 +102,7 @@ struct vfsops cd9660_vfsops = { .vfs_statvfs = cd9660_statvfs, .vfs_sync = cd9660_sync, .vfs_vget = cd9660_vget, + .vfs_loadvnode = cd9660_loadvnode, .vfs_fhtovp = cd9660_fhtovp, .vfs_vptofh = cd9660_vptofh, .vfs_init = cd9660_init, @@ -126,8 +127,6 @@ static const struct genfs_ops cd9660_gen * * Name is updated by mount(8) after booting. */ -#define ROOTNAME "root_device" - static int iso_makemp(struct iso_mnt *isomp, struct buf *bp, int *ea_len); static int iso_mountfs(struct vnode *devvp, struct mount *mp, struct lwp *l, struct iso_args *argp); @@ -216,6 +215,8 @@ cd9660_mount(struct mount *mp, const cha int error; struct iso_mnt *imp = VFSTOISOFS(mp); + if (args == NULL) + return EINVAL; if (*data_len < sizeof *args) return EINVAL; @@ -584,12 +585,7 @@ cd9660_root(struct mount *mp, struct vno (struct iso_directory_record *)imp->root; ino_t ino = isodirino(dp, imp); - /* - * With RRIP we must use the `.' entry of the root directory. - * Simply tell vget, that it's a relocated directory. - */ - return (cd9660_vget_internal(mp, ino, vpp, - imp->iso_ftype == ISO_FTYPE_RRIP, dp)); + return cd9660_vget(mp, ino, vpp); } /* @@ -639,8 +635,10 @@ cd9660_sync(struct mount *mp, int waitfo struct ifid { ushort ifid_len; ushort ifid_pad; - int ifid_ino; - long ifid_start; + ino_t ifid_ino; +#ifdef ISOFS_DBG + u_long ifid_start; +#endif }; /* ARGSUSED */ @@ -657,7 +655,7 @@ cd9660_fhtovp(struct mount *mp, struct f memcpy(&ifh, fhp, sizeof(ifh)); #ifdef ISOFS_DBG - printf("fhtovp: ino %d, start %ld\n", + printf("fhtovp: ino %"PRIu64", start %lu\n", ifh.ifid_ino, ifh.ifid_start); #endif @@ -678,161 +676,110 @@ cd9660_fhtovp(struct mount *mp, struct f int cd9660_vget(struct mount *mp, ino_t ino, struct vnode **vpp) { + int error; - /* - * XXXX - * It would be nice if we didn't always set the `relocated' flag - * and force the extra read, but I don't want to think about fixing - * that right now. - */ - return (cd9660_vget_internal(mp, ino, vpp, -#if 0 - VFSTOISOFS(mp)->iso_ftype == ISO_FTYPE_RRIP, -#else - 0, -#endif - NULL)); + error = vcache_get(mp, &ino, sizeof(ino), vpp); + if (error) + return error; + error = vn_lock(*vpp, LK_EXCLUSIVE); + if (error) { + vrele(*vpp); + *vpp = NULL; + return error; + } + return 0; } int -cd9660_vget_internal(struct mount *mp, ino_t ino, struct vnode **vpp, - int relocated, struct iso_directory_record *isodir) +cd9660_loadvnode(struct mount *mp, struct vnode *vp, + const void *key, size_t key_len, const void **new_key) { struct iso_mnt *imp; struct iso_node *ip; + struct iso_directory_record *isodir; struct buf *bp; - struct vnode *vp; dev_t dev; + ino_t ino; + int lbn, off; int error; + KASSERT(key_len == sizeof(ino)); + memcpy(&ino, key, key_len); imp = VFSTOISOFS(mp); dev = imp->im_dev; - retry: - if ((*vpp = cd9660_ihashget(dev, ino, LK_EXCLUSIVE)) != NULLVP) - return (0); - - /* Allocate a new vnode/iso_node. */ - error = getnewvnode(VT_ISOFS, mp, cd9660_vnodeop_p, NULL, &vp); - if (error) { - *vpp = NULLVP; - return (error); - } ip = pool_get(&cd9660_node_pool, PR_WAITOK); - /* - * If someone beat us to it, put back the freshly allocated - * vnode/inode pair and retry. - */ - mutex_enter(&cd9660_hashlock); - if (cd9660_ihashget(dev, ino, 0) != NULL) { - mutex_exit(&cd9660_hashlock); - ungetnewvnode(vp); - pool_put(&cd9660_node_pool, ip); - goto retry; - } - memset(ip, 0, sizeof(struct iso_node)); - vp->v_data = ip; ip->i_vnode = vp; ip->i_dev = dev; ip->i_number = ino; ip->i_mnt = imp; ip->i_devvp = imp->im_devvp; - genfs_node_init(vp, &cd9660_genfsops); - /* - * Put it onto its hash chain and lock it so that other requests for - * this inode will block if they arrive while we are sleeping waiting - * for old data structures to be purged or for the contents of the - * disk portion of this inode to be read. - */ - cd9660_ihashins(ip); - mutex_exit(&cd9660_hashlock); - - if (isodir == 0) { - int lbn, off; - - lbn = cd9660_lblkno(imp, ino); - if (lbn >= imp->volume_space_size) { - vput(vp); - printf("fhtovp: lbn exceed volume space %d\n", lbn); - return (ESTALE); - } + lbn = cd9660_lblkno(imp, ino); + if (lbn >= imp->volume_space_size) { + pool_put(&cd9660_node_pool, ip); + printf("fhtovp: lbn exceed volume space %d\n", lbn); + return (ESTALE); + } - off = cd9660_blkoff(imp, ino); - if (off + ISO_DIRECTORY_RECORD_SIZE > imp->logical_block_size) { - vput(vp); - printf("fhtovp: crosses block boundary %d\n", - off + ISO_DIRECTORY_RECORD_SIZE); - return (ESTALE); - } + off = cd9660_blkoff(imp, ino); + if (off + ISO_DIRECTORY_RECORD_SIZE > imp->logical_block_size) { + pool_put(&cd9660_node_pool, ip); + printf("fhtovp: crosses block boundary %d\n", + off + ISO_DIRECTORY_RECORD_SIZE); + return (ESTALE); + } - error = bread(imp->im_devvp, - lbn << (imp->im_bshift - DEV_BSHIFT), - imp->logical_block_size, NOCRED, 0, &bp); - if (error) { - vput(vp); - printf("fhtovp: bread error %d\n",error); - return (error); - } - isodir = (struct iso_directory_record *)((char *)bp->b_data + off); + error = bread(imp->im_devvp, + lbn << (imp->im_bshift - DEV_BSHIFT), + imp->logical_block_size, NOCRED, 0, &bp); + if (error) { + pool_put(&cd9660_node_pool, ip); + printf("fhtovp: bread error %d\n",error); + return (error); + } + isodir = (struct iso_directory_record *)((char *)bp->b_data + off); - if (off + isonum_711(isodir->length) > - imp->logical_block_size) { - vput(vp); - if (bp != 0) - brelse(bp, 0); - printf("fhtovp: directory crosses block boundary %d[off=%d/len=%d]\n", - off +isonum_711(isodir->length), off, - isonum_711(isodir->length)); - return (ESTALE); - } + if (off + isonum_711(isodir->length) > imp->logical_block_size) { + pool_put(&cd9660_node_pool, ip); + brelse(bp, 0); + printf("fhtovp: directory crosses block boundary %d[off=%d/len=%d]\n", + off +isonum_711(isodir->length), off, + isonum_711(isodir->length)); + return (ESTALE); + } #if 0 - if (isonum_733(isodir->extent) + - isonum_711(isodir->ext_attr_length) != ifhp->ifid_start) { - if (bp != 0) - brelse(bp, 0); - printf("fhtovp: file start miss %d vs %d\n", - isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length), - ifhp->ifid_start); - return (ESTALE); - } -#endif - } else - bp = 0; - - vref(ip->i_devvp); - - if (relocated) { - /* - * On relocated directories we must - * read the `.' entry out of a dir. - */ - ip->iso_start = ino >> imp->im_bshift; + if (isonum_733(isodir->extent) + + isonum_711(isodir->ext_attr_length) != ifhp->ifid_start) { + pool_put(&cd9660_node_pool, ip); if (bp != 0) brelse(bp, 0); - if ((error = cd9660_blkatoff(vp, (off_t)0, NULL, &bp)) != 0) { - vput(vp); - return (error); - } - isodir = (struct iso_directory_record *)bp->b_data; + printf("fhtovp: file start miss %d vs %d\n", + isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length), + ifhp->ifid_start); + return (ESTALE); } +#endif ip->iso_extent = isonum_733(isodir->extent); ip->i_size = isonum_733(isodir->size); ip->iso_start = isonum_711(isodir->ext_attr_length) + ip->iso_extent; + vp->v_tag = VT_ISOFS; + vp->v_op = cd9660_vnodeop_p; + vp->v_data = ip; + genfs_node_init(vp, &cd9660_genfsops); + /* * Setup time stamp, attribute */ - vp->v_type = VNON; switch (imp->iso_ftype) { default: /* ISO_FTYPE_9660 */ { struct buf *bp2; - int off; if ((imp->im_flags & ISOFSMNT_EXTATT) && (off = isonum_711(isodir->ext_attr_length))) cd9660_blkatoff(vp, (off_t)-(off << imp->im_bshift), @@ -850,8 +797,7 @@ cd9660_vget_internal(struct mount *mp, i break; } - if (bp != 0) - brelse(bp, 0); + brelse(bp, 0); /* * Initialize the associated vnode @@ -889,8 +835,8 @@ cd9660_vget_internal(struct mount *mp, i * XXX need generation number? */ - *vpp = vp; - return (0); + *new_key = &ip->i_number; + return 0; } /* @@ -912,11 +858,13 @@ cd9660_vptofh(struct vnode *vp, struct f memset(&ifh, 0, sizeof(ifh)); ifh.ifid_len = sizeof(struct ifid); ifh.ifid_ino = ip->i_number; +#ifdef ISOFS_DBG ifh.ifid_start = ip->iso_start; +#endif memcpy(fhp, &ifh, sizeof(ifh)); #ifdef ISOFS_DBG - printf("vptofh: ino %d, start %ld\n", + printf("vptofh: ino %"PRIu64", start %lu\n", ifh.ifid_ino,ifh.ifid_start); #endif return 0; Index: src/sys/fs/cd9660/cd9660_vnops.c diff -u src/sys/fs/cd9660/cd9660_vnops.c:1.47 src/sys/fs/cd9660/cd9660_vnops.c:1.47.2.1 --- src/sys/fs/cd9660/cd9660_vnops.c:1.47 Thu Jan 23 10:13:56 2014 +++ src/sys/fs/cd9660/cd9660_vnops.c Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: cd9660_vnops.c,v 1.47 2014/01/23 10:13:56 hannken Exp $ */ +/* $NetBSD: cd9660_vnops.c,v 1.47.2.1 2014/08/10 06:55:53 tls Exp $ */ /*- * Copyright (c) 1994 @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cd9660_vnops.c,v 1.47 2014/01/23 10:13:56 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cd9660_vnops.c,v 1.47.2.1 2014/08/10 06:55:53 tls Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -723,7 +723,7 @@ cd9660_strategy(void *v) biodone(bp); return (0); } - vp = ip->i_devvp; + vp = ip->i_mnt->im_devvp; return (VOP_STRATEGY(vp, bp)); } @@ -859,6 +859,8 @@ const struct vnodeopv_entry_desc cd9660_ { &vop_setattr_desc, cd9660_setattr }, /* setattr */ { &vop_read_desc, cd9660_read }, /* read */ { &vop_write_desc, cd9660_write }, /* write */ + { &vop_fallocate_desc, genfs_eopnotsupp }, /* fallocate */ + { &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */ { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ { &vop_ioctl_desc, cd9660_ioctl }, /* ioctl */ { &vop_poll_desc, cd9660_poll }, /* poll */ @@ -909,6 +911,8 @@ const struct vnodeopv_entry_desc cd9660_ { &vop_setattr_desc, cd9660_setattr }, /* setattr */ { &vop_read_desc, spec_read }, /* read */ { &vop_write_desc, spec_write }, /* write */ + { &vop_fallocate_desc, spec_fallocate }, /* fallocate */ + { &vop_fdiscard_desc, spec_fdiscard }, /* fdiscard */ { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ { &vop_ioctl_desc, spec_ioctl }, /* ioctl */ { &vop_poll_desc, spec_poll }, /* poll */ @@ -957,6 +961,8 @@ const struct vnodeopv_entry_desc cd9660_ { &vop_setattr_desc, cd9660_setattr }, /* setattr */ { &vop_read_desc, vn_fifo_bypass }, /* read */ { &vop_write_desc, vn_fifo_bypass }, /* write */ + { &vop_fallocate_desc, vn_fifo_bypass }, /* fallocate */ + { &vop_fdiscard_desc, vn_fifo_bypass }, /* fdiscard */ { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ { &vop_ioctl_desc, vn_fifo_bypass }, /* ioctl */ { &vop_poll_desc, vn_fifo_bypass }, /* poll */ Index: src/sys/fs/efs/efs_vfsops.c diff -u src/sys/fs/efs/efs_vfsops.c:1.24 src/sys/fs/efs/efs_vfsops.c:1.24.10.1 --- src/sys/fs/efs/efs_vfsops.c:1.24 Thu Dec 20 08:03:42 2012 +++ src/sys/fs/efs/efs_vfsops.c Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: efs_vfsops.c,v 1.24 2012/12/20 08:03:42 hannken Exp $ */ +/* $NetBSD: efs_vfsops.c,v 1.24.10.1 2014/08/10 06:55:53 tls Exp $ */ /* * Copyright (c) 2006 Stephen M. Rumble <rum...@ephemeral.org> @@ -17,7 +17,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: efs_vfsops.c,v 1.24 2012/12/20 08:03:42 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: efs_vfsops.c,v 1.24.10.1 2014/08/10 06:55:53 tls Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -47,7 +47,6 @@ __KERNEL_RCSID(0, "$NetBSD: efs_vfsops.c #include <fs/efs/efs_dinode.h> #include <fs/efs/efs_inode.h> #include <fs/efs/efs_subr.h> -#include <fs/efs/efs_ihash.h> MODULE(MODULE_CLASS_VFS, efs, NULL); @@ -180,6 +179,8 @@ efs_mount(struct mount *mp, const char * struct vnode *devvp; int err, mode; + if (args == NULL) + return EINVAL; if (*data_len < sizeof *args) return EINVAL; @@ -339,74 +340,53 @@ efs_statvfs(struct mount *mp, struct sta /* * Obtain a locked vnode for the given on-disk inode number. * - * We currently allocate a new vnode from getnewnode(), tack it with - * our in-core inode structure (efs_inode), and read in the inode from - * disk. The returned inode must be locked. - * * Returns 0 on success. */ static int efs_vget(struct mount *mp, ino_t ino, struct vnode **vpp) { - int err; - struct vnode *vp; + int error; + + error = vcache_get(mp, &ino, sizeof(ino), vpp); + if (error) + return error; + error = vn_lock(*vpp, LK_EXCLUSIVE); + if (error) { + vrele(*vpp); + *vpp = NULL; + return error; + } + return 0; +} + +/* + * Initialize this vnode / inode pair. + * Caller assures no other thread will try to load this inode. + */ +static int +efs_loadvnode(struct mount *mp, struct vnode *vp, + const void *key, size_t key_len, const void **new_key) +{ + int error; + ino_t ino; struct efs_inode *eip; struct efs_mount *emp; + KASSERT(key_len == sizeof(ino)); + memcpy(&ino, key, key_len); emp = VFSTOEFS(mp); - while (true) { - *vpp = efs_ihashget(emp->em_dev, ino, LK_EXCLUSIVE); - if (*vpp != NULL) - return (0); - - err = getnewvnode(VT_EFS, mp, efs_vnodeop_p, NULL, &vp); - if (err) - return (err); - - eip = pool_get(&efs_inode_pool, PR_WAITOK); - - /* - * See if anybody has raced us here. If not, continue - * setting up the new inode, otherwise start over. - */ - efs_ihashlock(); - - if (efs_ihashget(emp->em_dev, ino, 0) == NULL) - break; - - efs_ihashunlock(); - ungetnewvnode(vp); - pool_put(&efs_inode_pool, eip); - } - - vp->v_vflag |= VV_LOCKSWORK; + eip = pool_get(&efs_inode_pool, PR_WAITOK); eip->ei_mode = 0; eip->ei_lockf = NULL; eip->ei_number = ino; eip->ei_dev = emp->em_dev; eip->ei_vp = vp; - vp->v_data = eip; - - /* - * Place the vnode on the hash chain. Doing so will lock the - * vnode, so it's okay to drop the global lock and read in - * the inode from disk. - */ - efs_ihashins(eip); - efs_ihashunlock(); - - /* - * Init genfs early, otherwise we'll trip up on genfs_node_destroy - * in efs_reclaim when vput()ing in an error branch here. - */ - genfs_node_init(vp, &efs_genfsops); - err = efs_read_inode(emp, ino, NULL, &eip->ei_di); - if (err) { - vput(vp); - *vpp = NULL; - return (err); + error = efs_read_inode(emp, ino, NULL, &eip->ei_di); + if (error) { + pool_put(&efs_inode_pool, eip); + return error; } efs_sync_dinode_to_inode(eip); @@ -414,9 +394,8 @@ efs_vget(struct mount *mp, ino_t ino, st if (ino == EFS_ROOTINO && !S_ISDIR(eip->ei_mode)) { printf("efs: root inode (%lu) is not a directory!\n", (ulong)EFS_ROOTINO); - vput(vp); - *vpp = NULL; - return (EIO); + pool_put(&efs_inode_pool, eip); + return EIO; } switch (eip->ei_mode & S_IFMT) { @@ -431,6 +410,7 @@ efs_vget(struct mount *mp, ino_t ino, st break; case S_IFDIR: vp->v_type = VDIR; + vp->v_op = efs_vnodeop_p; if (ino == EFS_ROOTINO) vp->v_vflag |= VV_ROOT; break; @@ -441,27 +421,30 @@ efs_vget(struct mount *mp, ino_t ino, st break; case S_IFREG: vp->v_type = VREG; + vp->v_op = efs_vnodeop_p; break; case S_IFLNK: vp->v_type = VLNK; + vp->v_op = efs_vnodeop_p; break; case S_IFSOCK: vp->v_type = VSOCK; + vp->v_op = efs_vnodeop_p; break; default: printf("efs: invalid mode 0x%x in inode %lu on mount %s\n", eip->ei_mode, (ulong)ino, mp->mnt_stat.f_mntonname); - vput(vp); - *vpp = NULL; - return (EIO); + pool_put(&efs_inode_pool, eip); + return EIO; } + vp->v_tag = VT_EFS; + vp->v_vflag |= VV_LOCKSWORK; + vp->v_data = eip; + genfs_node_init(vp, &efs_genfsops); uvm_vnp_setsize(vp, eip->ei_size); - *vpp = vp; - - KASSERT(VOP_ISLOCKED(vp)); - - return (0); + *new_key = &eip->ei_number; + return 0; } /* @@ -535,7 +518,6 @@ efs_init(void) malloc_type_attach(M_EFSMNT); malloc_type_attach(M_EFSINO); malloc_type_attach(M_EFSTMP); - efs_ihashinit(); pool_init(&efs_inode_pool, sizeof(struct efs_inode), 0, 0, 0, "efsinopl", &pool_allocator_nointr, IPL_NONE); } @@ -547,7 +529,6 @@ static void efs_reinit(void) { - efs_ihashreinit(); } /* @@ -558,7 +539,6 @@ efs_done(void) { pool_destroy(&efs_inode_pool); - efs_ihashdone(); malloc_type_detach(M_EFSMNT); malloc_type_detach(M_EFSINO); malloc_type_detach(M_EFSTMP); @@ -586,6 +566,7 @@ struct vfsops efs_vfsops = { .vfs_statvfs = efs_statvfs, .vfs_sync = (void *)nullop, .vfs_vget = efs_vget, + .vfs_loadvnode = efs_loadvnode, .vfs_fhtovp = efs_fhtovp, .vfs_vptofh = efs_vptofh, .vfs_init = efs_init, Index: src/sys/fs/efs/efs_vnops.c diff -u src/sys/fs/efs/efs_vnops.c:1.31 src/sys/fs/efs/efs_vnops.c:1.31.2.1 --- src/sys/fs/efs/efs_vnops.c:1.31 Fri Feb 7 15:29:21 2014 +++ src/sys/fs/efs/efs_vnops.c Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: efs_vnops.c,v 1.31 2014/02/07 15:29:21 hannken Exp $ */ +/* $NetBSD: efs_vnops.c,v 1.31.2.1 2014/08/10 06:55:53 tls Exp $ */ /* * Copyright (c) 2006 Stephen M. Rumble <rum...@ephemeral.org> @@ -17,7 +17,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: efs_vnops.c,v 1.31 2014/02/07 15:29:21 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: efs_vnops.c,v 1.31.2.1 2014/08/10 06:55:53 tls Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -46,7 +46,6 @@ __KERNEL_RCSID(0, "$NetBSD: efs_vnops.c, #include <fs/efs/efs_dinode.h> #include <fs/efs/efs_inode.h> #include <fs/efs/efs_subr.h> -#include <fs/efs/efs_ihash.h> MALLOC_DECLARE(M_EFSTMP); @@ -79,30 +78,17 @@ efs_lookup(void *v) } /* - * Handle the three lookup types: '.', '..', and everything else. + * Handle the lookup types: '.' or everything else. */ if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') { vref(ap->a_dvp); *ap->a_vpp = ap->a_dvp; - } else if (cnp->cn_flags & ISDOTDOT) { - err = efs_inode_lookup(VFSTOEFS(ap->a_dvp->v_mount), - EFS_VTOI(ap->a_dvp), ap->a_cnp, &ino); - if (err) - return (err); - - VOP_UNLOCK(ap->a_dvp); /* preserve lock order */ - - err = VFS_VGET(ap->a_dvp->v_mount, ino, &vp); - if (err) { - vn_lock(ap->a_dvp, LK_EXCLUSIVE | LK_RETRY); - return (err); - } - vn_lock(ap->a_dvp, LK_EXCLUSIVE | LK_RETRY); - *ap->a_vpp = vp; } else { err = efs_inode_lookup(VFSTOEFS(ap->a_dvp->v_mount), EFS_VTOI(ap->a_dvp), ap->a_cnp, &ino); if (err) { + if (cnp->cn_flags & ISDOTDOT) + return (err); if (err == ENOENT && nameiop != CREATE) cache_enter(ap->a_dvp, NULL, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_flags); @@ -116,7 +102,7 @@ efs_lookup(void *v) } return (err); } - err = VFS_VGET(ap->a_dvp->v_mount, ino, &vp); + err = vcache_get(ap->a_dvp->v_mount, &ino, sizeof(ino), &vp); if (err) return (err); *ap->a_vpp = vp; @@ -125,9 +111,6 @@ efs_lookup(void *v) cache_enter(ap->a_dvp, *ap->a_vpp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_flags); - if (*ap->a_vpp != ap->a_dvp) - VOP_UNLOCK(*ap->a_vpp); - return 0; } @@ -598,10 +581,11 @@ efs_reclaim(void *v) struct vnode *a_vp; } */ *ap = v; struct vnode *vp = ap->a_vp; + struct efs_inode *eip = EFS_VTOI(vp); - efs_ihashrem(EFS_VTOI(vp)); + vcache_remove(vp->v_mount, &eip->ei_number, sizeof(eip->ei_number)); genfs_node_destroy(vp); - pool_put(&efs_inode_pool, vp->v_data); + pool_put(&efs_inode_pool, eip); vp->v_data = NULL; return (0); @@ -809,6 +793,8 @@ const struct vnodeopv_entry_desc efs_vno { &vop_setattr_desc, genfs_eopnotsupp}, /* setattr */ { &vop_read_desc, efs_read }, /* read */ { &vop_write_desc, genfs_eopnotsupp}, /* write */ + { &vop_fallocate_desc, genfs_eopnotsupp}, /* fallocate */ + { &vop_fdiscard_desc, genfs_eopnotsupp}, /* fdiscard */ { &vop_ioctl_desc, genfs_enoioctl }, /* ioctl */ { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ { &vop_poll_desc, genfs_poll }, /* poll */ @@ -865,6 +851,8 @@ const struct vnodeopv_entry_desc efs_spe { &vop_setattr_desc, genfs_eopnotsupp}, /* setattr */ { &vop_read_desc, spec_read }, /* read */ { &vop_write_desc, spec_write }, /* write */ + { &vop_fallocate_desc, spec_fallocate }, /* fallocate */ + { &vop_fdiscard_desc, spec_fdiscard }, /* fdiscard */ { &vop_ioctl_desc, spec_ioctl }, /* ioctl */ { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ { &vop_poll_desc, spec_poll }, /* poll */ @@ -921,6 +909,8 @@ const struct vnodeopv_entry_desc efs_fif { &vop_setattr_desc, genfs_eopnotsupp}, /* setattr */ { &vop_read_desc, vn_fifo_bypass }, /* read */ { &vop_write_desc, vn_fifo_bypass }, /* write */ + { &vop_fallocate_desc, vn_fifo_bypass }, /* fallocate */ + { &vop_fdiscard_desc, vn_fifo_bypass }, /* fdiscard */ { &vop_ioctl_desc, vn_fifo_bypass }, /* ioctl */ { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ { &vop_poll_desc, vn_fifo_bypass }, /* poll */ Index: src/sys/fs/efs/files.efs diff -u src/sys/fs/efs/files.efs:1.1 src/sys/fs/efs/files.efs:1.1.98.1 --- src/sys/fs/efs/files.efs:1.1 Fri Jun 29 23:30:30 2007 +++ src/sys/fs/efs/files.efs Sun Aug 10 06:55:53 2014 @@ -1,9 +1,8 @@ -# $NetBSD: files.efs,v 1.1 2007/06/29 23:30:30 rumble Exp $ +# $NetBSD: files.efs,v 1.1.98.1 2014/08/10 06:55:53 tls Exp $ deffs EFS file fs/efs/efs_genfs.c efs -file fs/efs/efs_ihash.c efs file fs/efs/efs_subr.c efs file fs/efs/efs_vnops.c efs file fs/efs/efs_vfsops.c efs Index: src/sys/fs/filecorefs/filecore_lookup.c diff -u src/sys/fs/filecorefs/filecore_lookup.c:1.19 src/sys/fs/filecorefs/filecore_lookup.c:1.19.2.1 --- src/sys/fs/filecorefs/filecore_lookup.c:1.19 Fri Feb 7 15:29:21 2014 +++ src/sys/fs/filecorefs/filecore_lookup.c Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: filecore_lookup.c,v 1.19 2014/02/07 15:29:21 hannken Exp $ */ +/* $NetBSD: filecore_lookup.c,v 1.19.2.1 2014/08/10 06:55:53 tls Exp $ */ /*- * Copyright (c) 1989, 1993, 1994 The Regents of the University of California. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: filecore_lookup.c,v 1.19 2014/02/07 15:29:21 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: filecore_lookup.c,v 1.19.2.1 2014/08/10 06:55:53 tls Exp $"); #include <sys/param.h> #include <sys/namei.h> @@ -80,8 +80,6 @@ __KERNEL_RCSID(0, "$NetBSD: filecore_loo #include <fs/filecorefs/filecore_extern.h> #include <fs/filecorefs/filecore_node.h> -struct nchstats filecore_nchstats; - /* * Convert a component of a pathname into a pointer to a locked inode. * This is a very central and rather complicated routine. @@ -193,7 +191,7 @@ filecore_lookup(void *v) } else { i = dp->i_diroff; numdirpasses = 2; - filecore_nchstats.ncs_2passes++; + namecache_count_2passes(); } endsearch = FILECORE_MAXDIRENTS; @@ -251,7 +249,7 @@ notfound: found: if (numdirpasses == 2) - filecore_nchstats.ncs_pass2++; + namecache_count_pass2(); /* * Found component in pathname. Index: src/sys/fs/filecorefs/filecore_vfsops.c diff -u src/sys/fs/filecorefs/filecore_vfsops.c:1.75 src/sys/fs/filecorefs/filecore_vfsops.c:1.75.2.1 --- src/sys/fs/filecorefs/filecore_vfsops.c:1.75 Sun Mar 23 15:21:15 2014 +++ src/sys/fs/filecorefs/filecore_vfsops.c Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: filecore_vfsops.c,v 1.75 2014/03/23 15:21:15 hannken Exp $ */ +/* $NetBSD: filecore_vfsops.c,v 1.75.2.1 2014/08/10 06:55:53 tls Exp $ */ /*- * Copyright (c) 1994 The Regents of the University of California. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: filecore_vfsops.c,v 1.75 2014/03/23 15:21:15 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: filecore_vfsops.c,v 1.75.2.1 2014/08/10 06:55:53 tls Exp $"); #if defined(_KERNEL_OPT) #include "opt_compat_netbsd.h" @@ -229,6 +229,8 @@ filecore_mount(struct mount *mp, const c int error; struct filecore_mnt *fcmp = NULL; + if (args == NULL) + return EINVAL; if (*data_len < sizeof *args) return EINVAL; Index: src/sys/fs/filecorefs/filecore_vnops.c diff -u src/sys/fs/filecorefs/filecore_vnops.c:1.41 src/sys/fs/filecorefs/filecore_vnops.c:1.41.2.1 --- src/sys/fs/filecorefs/filecore_vnops.c:1.41 Thu Jan 23 10:13:56 2014 +++ src/sys/fs/filecorefs/filecore_vnops.c Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: filecore_vnops.c,v 1.41 2014/01/23 10:13:56 hannken Exp $ */ +/* $NetBSD: filecore_vnops.c,v 1.41.2.1 2014/08/10 06:55:53 tls Exp $ */ /*- * Copyright (c) 1994 The Regents of the University of California. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: filecore_vnops.c,v 1.41 2014/01/23 10:13:56 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: filecore_vnops.c,v 1.41.2.1 2014/08/10 06:55:53 tls Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -565,6 +565,8 @@ const struct vnodeopv_entry_desc filecor { &vop_setattr_desc, filecore_setattr }, /* setattr */ { &vop_read_desc, filecore_read }, /* read */ { &vop_write_desc, filecore_write }, /* write */ + { &vop_fallocate_desc, genfs_eopnotsupp }, /* fallocate */ + { &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */ { &vop_fcntl_desc, filecore_fcntl }, /* fcntl */ { &vop_ioctl_desc, filecore_ioctl }, /* ioctl */ { &vop_poll_desc, filecore_poll }, /* poll */ Index: src/sys/fs/hfs/hfs_vfsops.c diff -u src/sys/fs/hfs/hfs_vfsops.c:1.30 src/sys/fs/hfs/hfs_vfsops.c:1.30.2.1 --- src/sys/fs/hfs/hfs_vfsops.c:1.30 Sun Mar 23 15:21:15 2014 +++ src/sys/fs/hfs/hfs_vfsops.c Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: hfs_vfsops.c,v 1.30 2014/03/23 15:21:15 hannken Exp $ */ +/* $NetBSD: hfs_vfsops.c,v 1.30.2.1 2014/08/10 06:55:53 tls Exp $ */ /*- * Copyright (c) 2005, 2007 The NetBSD Foundation, Inc. @@ -99,7 +99,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: hfs_vfsops.c,v 1.30 2014/03/23 15:21:15 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: hfs_vfsops.c,v 1.30.2.1 2014/08/10 06:55:53 tls Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -201,6 +201,8 @@ hfs_mount(struct mount *mp, const char * int update; mode_t accessmode; + if (args == NULL) + return EINVAL; if (*data_len < sizeof *args) return EINVAL; Index: src/sys/fs/hfs/hfs_vnops.c diff -u src/sys/fs/hfs/hfs_vnops.c:1.29 src/sys/fs/hfs/hfs_vnops.c:1.29.2.1 --- src/sys/fs/hfs/hfs_vnops.c:1.29 Fri Feb 7 15:29:21 2014 +++ src/sys/fs/hfs/hfs_vnops.c Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: hfs_vnops.c,v 1.29 2014/02/07 15:29:21 hannken Exp $ */ +/* $NetBSD: hfs_vnops.c,v 1.29.2.1 2014/08/10 06:55:53 tls Exp $ */ /*- * Copyright (c) 2005, 2007 The NetBSD Foundation, Inc. @@ -101,7 +101,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: hfs_vnops.c,v 1.29 2014/02/07 15:29:21 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: hfs_vnops.c,v 1.29.2.1 2014/08/10 06:55:53 tls Exp $"); #ifdef _KERNEL_OPT #include "opt_ipsec.h" @@ -165,6 +165,8 @@ const struct vnodeopv_entry_desc hfs_vno { &vop_setattr_desc, hfs_vop_setattr }, /* setattr */ { &vop_read_desc, hfs_vop_read }, /* read */ { &vop_write_desc, genfs_eopnotsupp }, /* write */ + { &vop_fallocate_desc, genfs_eopnotsupp }, /* fallocate */ + { &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */ { &vop_ioctl_desc, genfs_eopnotsupp }, /* ioctl */ { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ { &vop_poll_desc, genfs_eopnotsupp }, /* poll */ @@ -219,6 +221,8 @@ const struct vnodeopv_entry_desc hfs_spe { &vop_setattr_desc, hfs_vop_setattr }, /* setattr */ { &vop_read_desc, spec_read }, /* read */ { &vop_write_desc, spec_write }, /* write */ + { &vop_fallocate_desc, spec_fallocate }, /* fallocate */ + { &vop_fdiscard_desc, spec_fdiscard }, /* fdiscard */ { &vop_ioctl_desc, spec_ioctl }, /* ioctl */ { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ { &vop_poll_desc, spec_poll }, /* poll */ @@ -275,6 +279,8 @@ const struct vnodeopv_entry_desc hfs_fif { &vop_setattr_desc, hfs_vop_setattr }, /* setattr */ { &vop_read_desc, vn_fifo_bypass }, /* read */ { &vop_write_desc, vn_fifo_bypass }, /* write */ + { &vop_fallocate_desc, vn_fifo_bypass }, /* fallocate */ + { &vop_fdiscard_desc, vn_fifo_bypass }, /* fdiscard */ { &vop_ioctl_desc, vn_fifo_bypass }, /* ioctl */ { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ { &vop_poll_desc, vn_fifo_bypass }, /* poll */ Index: src/sys/fs/msdosfs/denode.h diff -u src/sys/fs/msdosfs/denode.h:1.23 src/sys/fs/msdosfs/denode.h:1.23.10.1 --- src/sys/fs/msdosfs/denode.h:1.23 Sat Jan 26 19:45:02 2013 +++ src/sys/fs/msdosfs/denode.h Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: denode.h,v 1.23 2013/01/26 19:45:02 christos Exp $ */ +/* $NetBSD: denode.h,v 1.23.10.1 2014/08/10 06:55:53 tls Exp $ */ /*- * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank. @@ -153,15 +153,21 @@ struct fatcache { * This is the in memory variant of a dos directory entry. It is usually * contained within a vnode. */ +struct denode_key { + u_long dk_dirclust; /* cluster of the directory file containing this entry */ + u_long dk_diroffset; /* offset of this entry in the directory cluster */ + void *dk_dirgen; /* non zero and unique for unlinked nodes */ +}; struct denode { struct genfs_node de_gnode; - LIST_ENTRY(denode) de_hash; struct vnode *de_vnode; /* addr of vnode we are part of */ struct vnode *de_devvp; /* vnode of blk dev we live on */ u_long de_flag; /* flag bits */ dev_t de_dev; /* device where direntry lives */ - u_long de_dirclust; /* cluster of the directory file containing this entry */ - u_long de_diroffset; /* offset of this entry in the directory cluster */ + struct denode_key de_key; +#define de_dirclust de_key.dk_dirclust +#define de_diroffset de_key.dk_diroffset +#define de_dirgen de_key.dk_dirgen u_long de_fndoffset; /* offset of found dir entry */ int de_fndcnt; /* number of slots before de_fndoffset */ long de_refcnt; /* reference count */ @@ -303,7 +309,11 @@ int msdosfs_update(struct vnode *, const int createde(struct denode *, struct denode *, struct denode **, struct componentname *); int deextend(struct denode *, u_long, struct kauth_cred *); +#ifdef MAKEFS int deget(struct msdosfsmount *, u_long, u_long, struct denode **); +#else +int deget(struct msdosfsmount *, u_long, u_long, struct vnode **); +#endif int detrunc(struct denode *, u_long, int, struct kauth_cred *); int deupdat(struct denode *, int); int doscheckpath(struct denode *, struct denode *); @@ -311,7 +321,6 @@ int dosdirempty(struct denode *); int readde(struct denode *, struct buf **, struct direntry **); int readep(struct msdosfsmount *, u_long, u_long, struct buf **, struct direntry **); -void reinsert(struct denode *); int removede(struct denode *, struct denode *); int uniqdosname(struct denode *, struct componentname *, u_char *); int findwin95(struct denode *); Index: src/sys/fs/msdosfs/msdosfs_denode.c diff -u src/sys/fs/msdosfs/msdosfs_denode.c:1.48 src/sys/fs/msdosfs/msdosfs_denode.c:1.48.10.1 --- src/sys/fs/msdosfs/msdosfs_denode.c:1.48 Thu Dec 20 08:03:42 2012 +++ src/sys/fs/msdosfs/msdosfs_denode.c Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: msdosfs_denode.c,v 1.48 2012/12/20 08:03:42 hannken Exp $ */ +/* $NetBSD: msdosfs_denode.c,v 1.48.10.1 2014/08/10 06:55:53 tls Exp $ */ /*- * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank. @@ -48,7 +48,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: msdosfs_denode.c,v 1.48 2012/12/20 08:03:42 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: msdosfs_denode.c,v 1.48.10.1 2014/08/10 06:55:53 tls Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -72,14 +72,6 @@ __KERNEL_RCSID(0, "$NetBSD: msdosfs_deno #include <fs/msdosfs/denode.h> #include <fs/msdosfs/fat.h> -LIST_HEAD(ihashhead, denode) *dehashtbl; -u_long dehash; /* size of hash table - 1 */ -#define DEHASH(dev, dcl, doff) \ - (((dev) + (dcl) + (doff) / sizeof(struct direntry)) & dehash) - -kmutex_t msdosfs_ihash_lock; -kmutex_t msdosfs_hashlock; - struct pool msdosfs_denode_pool; extern int prtactive; @@ -138,10 +130,6 @@ static const struct genfs_ops msdosfs_ge .gop_markupdate = msdosfs_gop_markupdate, }; -static struct denode *msdosfs_hashget(dev_t, u_long, u_long, int); -static void msdosfs_hashins(struct denode *); -static void msdosfs_hashrem(struct denode *); - MALLOC_DECLARE(M_MSDOSFSFAT); void @@ -155,112 +143,33 @@ msdosfs_init(void) "msdosnopl", &pool_allocator_nointr, IPL_NONE); pool_init(&fh_pool, sizeof(struct fh_node), 0, 0, 0, "msdosfhpl", &pool_allocator_nointr, IPL_NONE); - dehashtbl = hashinit(desiredvnodes / 2, HASH_LIST, true, &dehash); rb_tree_init(&fh_rbtree, &fh_rbtree_ops); - mutex_init(&msdosfs_ihash_lock, MUTEX_DEFAULT, IPL_NONE); mutex_init(&fh_lock, MUTEX_DEFAULT, IPL_NONE); - mutex_init(&msdosfs_hashlock, MUTEX_DEFAULT, IPL_NONE); } /* - * Reinitialize inode hash table. + * Reinitialize. */ void msdosfs_reinit(void) { - struct denode *dep; - struct ihashhead *oldhash, *hash; - u_long oldmask, mask, val; - int i; - - hash = hashinit(desiredvnodes / 2, HASH_LIST, true, &mask); - - mutex_enter(&msdosfs_ihash_lock); - oldhash = dehashtbl; - oldmask = dehash; - dehashtbl = hash; - dehash = mask; - for (i = 0; i <= oldmask; i++) { - while ((dep = LIST_FIRST(&oldhash[i])) != NULL) { - LIST_REMOVE(dep, de_hash); - val = DEHASH(dep->de_dev, dep->de_dirclust, - dep->de_diroffset); - LIST_INSERT_HEAD(&hash[val], dep, de_hash); - } - } - mutex_exit(&msdosfs_ihash_lock); - hashdone(oldhash, HASH_LIST, oldmask); + } void msdosfs_done(void) { - hashdone(dehashtbl, HASH_LIST, dehash); pool_destroy(&msdosfs_denode_pool); pool_destroy(&fh_pool); - mutex_destroy(&msdosfs_ihash_lock); mutex_destroy(&fh_lock); - mutex_destroy(&msdosfs_hashlock); malloc_type_detach(M_MSDOSFSTMP); malloc_type_detach(M_MSDOSFSFAT); malloc_type_detach(M_MSDOSFSMNT); } -static struct denode * -msdosfs_hashget(dev_t dev, u_long dirclust, u_long diroff, int flags) -{ - struct denode *dep; - struct vnode *vp; - -loop: - mutex_enter(&msdosfs_ihash_lock); - LIST_FOREACH(dep, &dehashtbl[DEHASH(dev, dirclust, diroff)], de_hash) { - if (dirclust == dep->de_dirclust && - diroff == dep->de_diroffset && - dev == dep->de_dev && - dep->de_refcnt != 0) { - vp = DETOV(dep); - if (flags == 0) { - mutex_exit(&msdosfs_ihash_lock); - } else { - mutex_enter(vp->v_interlock); - mutex_exit(&msdosfs_ihash_lock); - if (vget(vp, flags)) - goto loop; - } - return (dep); - } - } - mutex_exit(&msdosfs_ihash_lock); - return (NULL); -} - -static void -msdosfs_hashins(struct denode *dep) -{ - struct ihashhead *depp; - int val; - - KASSERT(mutex_owned(&msdosfs_hashlock)); - - mutex_enter(&msdosfs_ihash_lock); - val = DEHASH(dep->de_dev, dep->de_dirclust, dep->de_diroffset); - depp = &dehashtbl[val]; - LIST_INSERT_HEAD(depp, dep, de_hash); - mutex_exit(&msdosfs_ihash_lock); -} - -static void -msdosfs_hashrem(struct denode *dep) -{ - mutex_enter(&msdosfs_ihash_lock); - LIST_REMOVE(dep, de_hash); - mutex_exit(&msdosfs_ihash_lock); -} - /* - * If deget() succeeds it returns with the gotten denode locked(). + * If deget() succeeds it returns with the gotten denode unlocked. * * pmp - address of msdosfsmount structure of the filesystem containing * the denode of interest. The pm_dev field and the address of @@ -269,26 +178,18 @@ msdosfs_hashrem(struct denode *dep) * diroffset is relative to the beginning of the root directory, * otherwise it is cluster relative. * diroffset - offset past begin of cluster of denode we want - * depp - returns the address of the gotten denode. + * vpp - returns the address of the gotten vnode. */ int -deget(struct msdosfsmount *pmp, u_long dirclust, u_long diroffset, struct denode **depp) +deget(struct msdosfsmount *pmp, u_long dirclust, u_long diroffset, + struct vnode **vpp) /* pmp: so we know the maj/min number */ /* dirclust: cluster this dir entry came from */ /* diroffset: index of entry within the cluster */ - /* depp: returns the addr of the gotten denode */ + /* vpp: returns the addr of the gotten vnode */ { int error; - extern int (**msdosfs_vnodeop_p)(void *); - struct direntry *direntptr; - struct denode *ldep; - struct vnode *nvp; - struct buf *bp; - -#ifdef MSDOSFS_DEBUG - printf("deget(pmp %p, dirclust %lu, diroffset %lx, depp %p)\n", - pmp, dirclust, diroffset, depp); -#endif + struct denode_key key; /* * On FAT32 filesystems, root is a (more or less) normal @@ -297,78 +198,59 @@ deget(struct msdosfsmount *pmp, u_long d if (FAT32(pmp) && dirclust == MSDOSFSROOT) dirclust = pmp->pm_rootdirblk; - /* - * See if the denode is in the denode cache. Use the location of - * the directory entry to compute the hash value. For subdir use - * address of "." entry. For root dir (if not FAT32) use cluster - * MSDOSFSROOT, offset MSDOSFSROOT_OFS - * - * NOTE: The check for de_refcnt > 0 below insures the denode being - * examined does not represent an unlinked but still open file. - * These files are not to be accessible even when the directory - * entry that represented the file happens to be reused while the - * deleted file is still open. - */ - retry: - ldep = msdosfs_hashget(pmp->pm_dev, dirclust, diroffset, LK_EXCLUSIVE); - if (ldep) { - *depp = ldep; - return (0); - } + memset(&key, 0, sizeof(key)); + key.dk_dirclust = dirclust; + key.dk_diroffset = diroffset; + /* key.dk_dirgen = NULL; */ - /* - * Directory entry was not in cache, have to create a vnode and - * copy it from the passed disk buffer. - */ - error = getnewvnode(VT_MSDOSFS, pmp->pm_mountp, msdosfs_vnodeop_p, - NULL, &nvp); - if (error) { - *depp = 0; - return (error); - } - ldep = pool_get(&msdosfs_denode_pool, PR_WAITOK); + error = vcache_get(pmp->pm_mountp, &key, sizeof(key), vpp); + return error; +} - /* - * If someone beat us to it, put back the freshly allocated - * vnode/inode pair and retry. - */ - mutex_enter(&msdosfs_hashlock); - if (msdosfs_hashget(pmp->pm_dev, dirclust, diroffset, 0)) { - mutex_exit(&msdosfs_hashlock); - ungetnewvnode(nvp); - pool_put(&msdosfs_denode_pool, ldep); - goto retry; - } - memset(ldep, 0, sizeof *ldep); - nvp->v_data = ldep; - ldep->de_vnode = nvp; - ldep->de_flag = 0; - ldep->de_devvp = 0; - ldep->de_lockf = 0; - ldep->de_dev = pmp->pm_dev; - ldep->de_dirclust = dirclust; - ldep->de_diroffset = diroffset; - fc_purge(ldep, 0); /* init the FAT cache for this denode */ +int +msdosfs_loadvnode(struct mount *mp, struct vnode *vp, + const void *key, size_t key_len, const void **new_key) +{ + bool is_root; + int error; + extern int (**msdosfs_vnodeop_p)(void *); + struct msdosfsmount *pmp; + struct direntry *direntptr; + struct denode *ldep; + struct buf *bp; + struct denode_key dkey; - /* - * Insert the denode into the hash queue and lock the denode so it - * can't be accessed until we've read it in and have done what we - * need to it. - */ - vn_lock(nvp, LK_EXCLUSIVE | LK_RETRY); - genfs_node_init(nvp, &msdosfs_genfsops); - msdosfs_hashins(ldep); - mutex_exit(&msdosfs_hashlock); + KASSERT(key_len == sizeof(dkey)); + memcpy(&dkey, key, key_len); + KASSERT(dkey.dk_dirgen == NULL); + + pmp = VFSTOMSDOSFS(mp); + is_root = ((dkey.dk_dirclust == MSDOSFSROOT || + (FAT32(pmp) && dkey.dk_dirclust == pmp->pm_rootdirblk)) && + dkey.dk_diroffset == MSDOSFSROOT_OFS); +#ifdef MSDOSFS_DEBUG + printf("loadvnode(pmp %p, dirclust %lu, diroffset %lx, vp %p)\n", + pmp, dkey.dk_dirclust, dkey.dk_diroffset, vp); +#endif + + ldep = pool_get(&msdosfs_denode_pool, PR_WAITOK); + memset(ldep, 0, sizeof *ldep); + /* ldep->de_flag = 0; */ + /* ldep->de_devvp = 0; */ + /* ldep->de_lockf = 0; */ + ldep->de_dev = pmp->pm_dev; + ldep->de_dirclust = dkey.dk_dirclust; + ldep->de_diroffset = dkey.dk_diroffset; ldep->de_pmp = pmp; ldep->de_devvp = pmp->pm_devvp; ldep->de_refcnt = 1; + fc_purge(ldep, 0); /* init the FAT cache for this denode */ + /* * Copy the directory entry into the denode area of the vnode. */ - if ((dirclust == MSDOSFSROOT - || (FAT32(pmp) && dirclust == pmp->pm_rootdirblk)) - && diroffset == MSDOSFSROOT_OFS) { + if (is_root) { /* * Directory entry for the root directory. There isn't one, * so we manufacture one. We should probably rummage @@ -376,15 +258,14 @@ deget(struct msdosfsmount *pmp, u_long d * exists), and then use the time and date from that entry * as the time and date for the root denode. */ - nvp->v_vflag |= VV_ROOT; /* should be further down XXX */ - ldep->de_Attributes = ATTR_DIRECTORY; if (FAT32(pmp)) ldep->de_StartCluster = pmp->pm_rootdirblk; /* de_FileSize will be filled in further down */ else { ldep->de_StartCluster = MSDOSFSROOT; - ldep->de_FileSize = pmp->pm_rootdirsize * pmp->pm_BytesPerSec; + ldep->de_FileSize = pmp->pm_rootdirsize * + pmp->pm_BytesPerSec; } /* * fill in time and date so that dos2unixtime() doesn't @@ -401,12 +282,11 @@ deget(struct msdosfsmount *pmp, u_long d ldep->de_MDate = ldep->de_CDate; /* leave the other fields as garbage */ } else { - error = readep(pmp, dirclust, diroffset, &bp, &direntptr); + error = readep(pmp, ldep->de_dirclust, ldep->de_diroffset, + &bp, &direntptr); if (error) { - ldep->de_devvp = NULL; - ldep->de_Name[0] = SLOT_DELETED; - vput(nvp); - return (error); + pool_put(&msdosfs_denode_pool, ldep); + return error; } DE_INTERNALIZE(ldep, direntptr); brelse(bp, 0); @@ -414,7 +294,7 @@ deget(struct msdosfsmount *pmp, u_long d /* * Fill in a few fields of the vnode and finish filling in the - * denode. Then return the address of the found denode. + * denode. */ if (ldep->de_Attributes & ATTR_DIRECTORY) { /* @@ -425,21 +305,30 @@ deget(struct msdosfsmount *pmp, u_long d */ u_long size; - nvp->v_type = VDIR; + vp->v_type = VDIR; if (ldep->de_StartCluster != MSDOSFSROOT) { error = pcbmap(ldep, CLUST_END, 0, &size, 0); if (error == E2BIG) { ldep->de_FileSize = de_cn2off(pmp, size); error = 0; } else - printf("deget(): pcbmap returned %d\n", error); + printf("loadvnode(): pcbmap returned %d\n", + error); } } else - nvp->v_type = VREG; + vp->v_type = VREG; vref(ldep->de_devvp); - *depp = ldep; - uvm_vnp_setsize(nvp, ldep->de_FileSize); - return (0); + if (is_root) + vp->v_vflag |= VV_ROOT; + vp->v_tag = VT_MSDOSFS; + vp->v_op = msdosfs_vnodeop_p; + vp->v_data = ldep; + ldep->de_vnode = vp; + genfs_node_init(vp, &msdosfs_genfsops); + uvm_vnp_setsize(vp, ldep->de_FileSize); + *new_key = &ldep->de_key; + + return 0; } int @@ -641,29 +530,6 @@ deextend(struct denode *dep, u_long leng return (deupdat(dep, 1)); } -/* - * Move a denode to its correct hash queue after the file it represents has - * been moved to a new directory. - */ -void -reinsert(struct denode *dep) -{ - /* - * Fix up the denode cache. If the denode is for a directory, - * there is nothing to do since the hash is based on the starting - * cluster of the directory file and that hasn't changed. If for a - * file the hash is based on the location of the directory entry, - * so we must remove it from the cache and re-enter it with the - * hash based on the new location of the directory entry. - */ - if (dep->de_Attributes & ATTR_DIRECTORY) - return; - mutex_enter(&msdosfs_hashlock); - msdosfs_hashrem(dep); - msdosfs_hashins(dep); - mutex_exit(&msdosfs_hashlock); -} - int msdosfs_reclaim(void *v) { @@ -671,8 +537,10 @@ msdosfs_reclaim(void *v) struct vnode *a_vp; } */ *ap = v; struct vnode *vp = ap->a_vp; + struct mount *mp = vp->v_mount; struct denode *dep = VTODE(vp); + fstrans_start(mp, FSTRANS_LAZY); #ifdef MSDOSFS_DEBUG printf("msdosfs_reclaim(): dep %p, file %s, refcnt %ld\n", dep, dep->de_Name, dep->de_refcnt); @@ -681,9 +549,9 @@ msdosfs_reclaim(void *v) if (prtactive && vp->v_usecount > 1) vprint("msdosfs_reclaim(): pushing active", vp); /* - * Remove the denode from its hash chain. + * Remove the denode from the vnode cache. */ - msdosfs_hashrem(dep); + vcache_remove(vp->v_mount, &dep->de_key, sizeof(dep->de_key)); /* * Purge old data structures associated with the denode. */ @@ -694,9 +562,15 @@ msdosfs_reclaim(void *v) #if 0 /* XXX */ dep->de_flag = 0; #endif + /* + * To interlock with msdosfs_sync(). + */ genfs_node_destroy(vp); - pool_put(&msdosfs_denode_pool, dep); + mutex_enter(vp->v_interlock); vp->v_data = NULL; + mutex_exit(vp->v_interlock); + pool_put(&msdosfs_denode_pool, dep); + fstrans_done(mp); return (0); } Index: src/sys/fs/msdosfs/msdosfs_lookup.c diff -u src/sys/fs/msdosfs/msdosfs_lookup.c:1.32 src/sys/fs/msdosfs/msdosfs_lookup.c:1.32.2.1 --- src/sys/fs/msdosfs/msdosfs_lookup.c:1.32 Fri Feb 7 15:29:21 2014 +++ src/sys/fs/msdosfs/msdosfs_lookup.c Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: msdosfs_lookup.c,v 1.32 2014/02/07 15:29:21 hannken Exp $ */ +/* $NetBSD: msdosfs_lookup.c,v 1.32.2.1 2014/08/10 06:55:53 tls Exp $ */ /*- * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank. @@ -52,7 +52,7 @@ #endif #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: msdosfs_lookup.c,v 1.32 2014/02/07 15:29:21 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: msdosfs_lookup.c,v 1.32.2.1 2014/08/10 06:55:53 tls Exp $"); #include <sys/param.h> @@ -64,6 +64,7 @@ __KERNEL_RCSID(0, "$NetBSD: msdosfs_look #include <sys/dirent.h> #include <sys/buf.h> #include <sys/vnode.h> +#include <sys/atomic.h> #else #include <ffs/buf.h> #endif /* _KERNEL */ @@ -113,9 +114,7 @@ msdosfs_lookup(void *v) int blsize; int isadir; /* ~0 if found direntry is a directory */ u_long scn; /* starting cluster number */ - struct vnode *pdp; struct denode *dp; - struct denode *tdp; struct msdosfsmount *pmp; struct buf *bp = 0; struct direntry *dep; @@ -217,7 +216,7 @@ msdosfs_lookup(void *v) * Search the directory pointed at by vdp for the name pointed at * by cnp->cn_nameptr. */ - tdp = NULL; + /* * The outer loop ranges over the clusters that make up the * directory. Note that the root directory is different from all @@ -491,11 +490,8 @@ foundroot: *vpp = vdp; return (0); } - if ((error = deget(pmp, cluster, blkoff, &tdp)) != 0) - return (error); - *vpp = DETOV(tdp); - VOP_UNLOCK(*vpp); - return (0); + error = deget(pmp, cluster, blkoff, vpp); + return error; } /* @@ -523,48 +519,15 @@ foundroot: if (dp->de_StartCluster == scn && isadir) return (EISDIR); - if ((error = deget(pmp, cluster, blkoff, &tdp)) != 0) - return (error); - *vpp = DETOV(tdp); - VOP_UNLOCK(*vpp); - return (0); + error = deget(pmp, cluster, blkoff, vpp); + return error; } - /* - * Step through the translation in the name. We do not `vput' the - * directory because we may need it again if a symbolic link - * is relative to the current directory. Instead we save it - * unlocked as "pdp". We must get the target inode before unlocking - * the directory to insure that the inode will not be removed - * before we get it. We prevent deadlock by always fetching - * inodes from the root, moving down the directory tree. Thus - * when following backward pointers ".." we must unlock the - * parent directory before getting the requested directory. - * There is a potential race condition here if both the current - * and parent directories are removed before the VFS_VGET for the - * inode associated with ".." returns. We hope that this occurs - * infrequently since we cannot avoid this race condition without - * implementing a sophisticated deadlock detection algorithm. - * Note also that this simple deadlock detection scheme will not - * work if the file system has any hard links other than ".." - * that point backwards in the directory structure. - */ - pdp = vdp; - if (flags & ISDOTDOT) { - VOP_UNLOCK(pdp); /* race to get the inode */ - error = deget(pmp, cluster, blkoff, &tdp); - vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY); - if (error) { - return error; - } - *vpp = DETOV(tdp); - } else if (dp->de_StartCluster == scn && isadir) { + if (dp->de_StartCluster == scn && isadir) { vref(vdp); /* we want ourself, ie "." */ *vpp = vdp; - } else { - if ((error = deget(pmp, cluster, blkoff, &tdp)) != 0) - return (error); - *vpp = DETOV(tdp); + } else if ((error = deget(pmp, cluster, blkoff, vpp)) != 0) { + return error; } /* @@ -572,9 +535,6 @@ foundroot: */ cache_enter(vdp, *vpp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_flags); - if (*vpp != vdp) - VOP_UNLOCK(*vpp); - return 0; } #endif /* _KERNEL */ @@ -707,6 +667,7 @@ createde(struct denode *dep, struct deno */ if (depp) { u_long diroffset = clusoffset; + if (dep->de_Attributes & ATTR_DIRECTORY) { dirclust = dep->de_StartCluster; if (FAT32(pmp) && dirclust == pmp->pm_rootdirblk) @@ -716,10 +677,16 @@ createde(struct denode *dep, struct deno else diroffset = 0; } +#ifdef MAKEFS error = deget(pmp, dirclust, diroffset, depp); -#ifndef MAKEFS +#else + struct vnode *vp; + + error = deget(pmp, dirclust, diroffset, &vp); if (error == 0) - VOP_UNLOCK(DETOV(*depp)); + *depp = VTODE(vp); + else + *depp = NULL; #endif return error; } @@ -935,9 +902,24 @@ doscheckpath(struct denode *source, stru vput(DETOV(dep)); brelse(bp, 0); bp = NULL; +#ifdef MAKEFS /* NOTE: deget() clears dep on error */ if ((error = deget(pmp, scn, 0, &dep)) != 0) break; +#else + struct vnode *vp; + + dep = NULL; + error = deget(pmp, scn, 0, &vp); + if (error) + break; + error = vn_lock(vp, LK_EXCLUSIVE); + if (error) { + vrele(vp); + break; + } + dep = VTODE(vp); +#endif } out: if (bp) @@ -1019,7 +1001,20 @@ removede(struct denode *pdep, struct den dep->de_Name, dep, offset); #endif - dep->de_refcnt--; + if (--dep->de_refcnt == 0) { +#ifndef MAKEFS + struct denode_key old_key = dep->de_key; + struct denode_key new_key = dep->de_key; + + KASSERT(new_key.dk_dirgen == NULL); + new_key.dk_dirgen = dep; + vcache_rekey_enter(pmp->pm_mountp, DETOV(dep), &old_key, + sizeof(old_key), &new_key, sizeof(new_key)); + dep->de_key = new_key; + vcache_rekey_exit(pmp->pm_mountp, DETOV(dep), &old_key, + sizeof(old_key), &dep->de_key, sizeof(dep->de_key)); +#endif + } offset += sizeof(struct direntry); do { offset -= sizeof(struct direntry); Index: src/sys/fs/msdosfs/msdosfs_vfsops.c diff -u src/sys/fs/msdosfs/msdosfs_vfsops.c:1.106 src/sys/fs/msdosfs/msdosfs_vfsops.c:1.106.2.1 --- src/sys/fs/msdosfs/msdosfs_vfsops.c:1.106 Sun Mar 23 15:21:15 2014 +++ src/sys/fs/msdosfs/msdosfs_vfsops.c Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: msdosfs_vfsops.c,v 1.106 2014/03/23 15:21:15 hannken Exp $ */ +/* $NetBSD: msdosfs_vfsops.c,v 1.106.2.1 2014/08/10 06:55:53 tls Exp $ */ /*- * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank. @@ -48,7 +48,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: msdosfs_vfsops.c,v 1.106 2014/03/23 15:21:15 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: msdosfs_vfsops.c,v 1.106.2.1 2014/08/10 06:55:53 tls Exp $"); #if defined(_KERNEL_OPT) #include "opt_compat_netbsd.h" @@ -88,16 +88,16 @@ __KERNEL_RCSID(0, "$NetBSD: msdosfs_vfso MODULE(MODULE_CLASS_VFS, msdos, NULL); #ifdef MSDOSFS_DEBUG -#define DPRINTF(a) uprintf a +#define DPRINTF(fmt, ...) uprintf("%s(): " fmt "\n", __func__, ##__VA_ARGS__) #else -#define DPRINTF(a) +#define DPRINTF(fmt, ...) #endif +#define GEMDOSFS_BSIZE 512 + #define MSDOSFS_NAMEMAX(pmp) \ (pmp)->pm_flags & MSDOSFSMNT_LONGNAME ? WIN_MAXLEN : 12 -VFS_PROTOS(msdosfs); - int msdosfs_mountfs(struct vnode *, struct mount *, struct lwp *, struct msdosfs_args *); @@ -107,8 +107,6 @@ MALLOC_JUSTDEFINE(M_MSDOSFSMNT, "MSDOSFS MALLOC_JUSTDEFINE(M_MSDOSFSFAT, "MSDOSFS FAT", "MSDOS FS FAT table"); MALLOC_JUSTDEFINE(M_MSDOSFSTMP, "MSDOSFS temp", "MSDOS FS temp. structures"); -#define ROOTNAME "root_device" - static struct sysctllog *msdosfs_sysctl_log; extern const struct vnodeopv_desc msdosfs_vnodeop_opv_desc; @@ -129,6 +127,7 @@ struct vfsops msdosfs_vfsops = { .vfs_statvfs = msdosfs_statvfs, .vfs_sync = msdosfs_sync, .vfs_vget = msdosfs_vget, + .vfs_loadvnode = msdosfs_loadvnode, .vfs_fhtovp = msdosfs_fhtovp, .vfs_vptofh = msdosfs_vptofh, .vfs_init = msdosfs_init, @@ -284,6 +283,8 @@ msdosfs_mount(struct mount *mp, const ch int error, flags; mode_t accessmode; + if (args == NULL) + return EINVAL; if (*data_len < sizeof *args) return EINVAL; @@ -336,7 +337,7 @@ msdosfs_mount(struct mount *mp, const ch /* not yet implemented */ error = EOPNOTSUPP; if (error) { - DPRINTF(("vflush %d\n", error)); + DPRINTF("vflush %d", error); return (error); } if ((pmp->pm_flags & MSDOSFSMNT_RONLY) && @@ -356,14 +357,14 @@ msdosfs_mount(struct mount *mp, const ch KAUTH_SYSTEM_MOUNT, KAUTH_REQ_SYSTEM_MOUNT_DEVICE, mp, devvp, KAUTH_ARG(VREAD | VWRITE)); VOP_UNLOCK(devvp); - DPRINTF(("KAUTH_REQ_SYSTEM_MOUNT_DEVICE %d\n", error)); + DPRINTF("KAUTH_REQ_SYSTEM_MOUNT_DEVICE %d", error); if (error) return (error); pmp->pm_flags &= ~MSDOSFSMNT_RONLY; } if (args->fspec == NULL) { - DPRINTF(("missing fspec\n")); + DPRINTF("missing fspec"); return EINVAL; } } @@ -374,17 +375,17 @@ msdosfs_mount(struct mount *mp, const ch error = namei_simple_user(args->fspec, NSM_FOLLOW_NOEMULROOT, &devvp); if (error != 0) { - DPRINTF(("namei %d\n", error)); + DPRINTF("namei %d", error); return (error); } if (devvp->v_type != VBLK) { - DPRINTF(("not block\n")); + DPRINTF("not block"); vrele(devvp); return (ENOTBLK); } if (bdevsw_lookup(devvp->v_rdev) == NULL) { - DPRINTF(("no block switch\n")); + DPRINTF("no block switch"); vrele(devvp); return (ENXIO); } @@ -400,7 +401,7 @@ msdosfs_mount(struct mount *mp, const ch KAUTH_REQ_SYSTEM_MOUNT_DEVICE, mp, devvp, KAUTH_ARG(accessmode)); VOP_UNLOCK(devvp); if (error) { - DPRINTF(("KAUTH_REQ_SYSTEM_MOUNT_DEVICE %d\n", error)); + DPRINTF("KAUTH_REQ_SYSTEM_MOUNT_DEVICE %d", error); vrele(devvp); return (error); } @@ -415,12 +416,12 @@ msdosfs_mount(struct mount *mp, const ch error = VOP_OPEN(devvp, xflags, FSCRED); VOP_UNLOCK(devvp); if (error) { - DPRINTF(("VOP_OPEN %d\n", error)); + DPRINTF("VOP_OPEN %d", error); goto fail; } error = msdosfs_mountfs(devvp, mp, l, args); if (error) { - DPRINTF(("msdosfs_mountfs %d\n", error)); + DPRINTF("msdosfs_mountfs %d", error); vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); (void) VOP_CLOSE(devvp, xflags, NOCRED); VOP_UNLOCK(devvp); @@ -432,14 +433,13 @@ msdosfs_mount(struct mount *mp, const ch } else { vrele(devvp); if (devvp != pmp->pm_devvp) { - DPRINTF(("devvp %p pmp %p\n", - devvp, pmp->pm_devvp)); + DPRINTF("devvp %p pmp %p", devvp, pmp->pm_devvp); return (EINVAL); /* needs translation */ } } if ((error = update_mp(mp, args)) != 0) { msdosfs_unmount(mp, MNT_FORCE); - DPRINTF(("update_mp %d\n", error)); + DPRINTF("update_mp %d", error); return error; } @@ -465,8 +465,7 @@ msdosfs_mountfs(struct vnode *devvp, str struct byte_bpb50 *b50; struct byte_bpb710 *b710; uint8_t SecPerClust; - int ronly, error, tmp; - int bsize; + int ronly, error, BlkPerSec; uint64_t psize; unsigned secsize; @@ -493,16 +492,19 @@ msdosfs_mountfs(struct vnode *devvp, str psize = 0; error = 0; } + if (secsize < DEV_BSIZE) { + DPRINTF("Invalid block secsize (%d < DEV_BSIZE)", secsize); + error = EINVAL; + goto error_exit; + } if (argp->flags & MSDOSFSMNT_GEMDOSFS) { - bsize = secsize; - if (bsize != 512) { - DPRINTF(("Invalid block bsize %d for GEMDOS\n", bsize)); + if (secsize != GEMDOSFS_BSIZE) { + DPRINTF("Invalid block secsize %d for GEMDOS", secsize); error = EINVAL; goto error_exit; } - } else - bsize = 0; + } /* * Read the boot sector of the filesystem, and then check the @@ -518,16 +520,15 @@ msdosfs_mountfs(struct vnode *devvp, str if (!(argp->flags & MSDOSFSMNT_GEMDOSFS)) { if (bsp->bs50.bsBootSectSig0 != BOOTSIG0 || bsp->bs50.bsBootSectSig1 != BOOTSIG1) { - DPRINTF(("bootsig0 %d bootsig1 %d\n", + DPRINTF("bootsig0 %d bootsig1 %d", bsp->bs50.bsBootSectSig0, - bsp->bs50.bsBootSectSig1)); + bsp->bs50.bsBootSectSig1); error = EINVAL; goto error_exit; } } - pmp = malloc(sizeof *pmp, M_MSDOSFSMNT, M_WAITOK); - memset(pmp, 0, sizeof *pmp); + pmp = malloc(sizeof(*pmp), M_MSDOSFSMNT, M_WAITOK|M_ZERO); pmp->pm_mountp = mp; /* @@ -546,19 +547,6 @@ msdosfs_mountfs(struct vnode *devvp, str pmp->pm_Heads = getushort(b50->bpbHeads); pmp->pm_Media = b50->bpbMedia; - if (!(argp->flags & MSDOSFSMNT_GEMDOSFS)) { - /* XXX - We should probably check more values here */ - if (!pmp->pm_BytesPerSec || !SecPerClust - || pmp->pm_SecPerTrack > 63) { - DPRINTF(("bytespersec %d secperclust %d " - "secpertrack %d\n", - pmp->pm_BytesPerSec, SecPerClust, - pmp->pm_SecPerTrack)); - error = EINVAL; - goto error_exit; - } - } - if (pmp->pm_Sectors == 0) { pmp->pm_HiddenSects = getulong(b50->bpbHiddenSecs); pmp->pm_HugeSectors = getulong(b50->bpbHugeSectors); @@ -567,16 +555,40 @@ msdosfs_mountfs(struct vnode *devvp, str pmp->pm_HugeSectors = pmp->pm_Sectors; } + /* + * Sanity checks, from the FAT specification: + * - sectors per cluster: >= 1, power of 2 + * - logical sector size: >= 1, power of 2 + * - cluster size: <= max FS block size + * - number of sectors: >= 1 + */ + if ((SecPerClust == 0) || !powerof2(SecPerClust) || + (pmp->pm_BytesPerSec == 0) || !powerof2(pmp->pm_BytesPerSec) || + (SecPerClust * pmp->pm_BytesPerSec > MAXBSIZE) || + (pmp->pm_HugeSectors == 0)) { + DPRINTF("consistency checks"); + error = EINVAL; + goto error_exit; + } + + if (!(argp->flags & MSDOSFSMNT_GEMDOSFS) && + (pmp->pm_SecPerTrack > 63)) { + DPRINTF("SecPerTrack %d", pmp->pm_SecPerTrack); + error = EINVAL; + goto error_exit; + } + if (pmp->pm_RootDirEnts == 0) { - unsigned short vers = getushort(b710->bpbFSVers); + unsigned short FSVers = getushort(b710->bpbFSVers); + unsigned short ExtFlags = getushort(b710->bpbExtFlags); /* * Some say that bsBootSectSig[23] must be zero, but * Windows does not require this and some digital cameras * do not set these to zero. Therefore, do not insist. */ - if (pmp->pm_Sectors || pmp->pm_FATsecs || vers) { - DPRINTF(("sectors %d fatsecs %lu vers %d\n", - pmp->pm_Sectors, pmp->pm_FATsecs, vers)); + if (pmp->pm_Sectors || pmp->pm_FATsecs || FSVers) { + DPRINTF("Sectors %d FATsecs %lu FSVers %d", + pmp->pm_Sectors, pmp->pm_FATsecs, FSVers); error = EINVAL; goto error_exit; } @@ -585,38 +597,31 @@ msdosfs_mountfs(struct vnode *devvp, str pmp->pm_fatdiv = 1; pmp->pm_FATsecs = getulong(b710->bpbBigFATsecs); - /* mirrorring is enabled if the FATMIRROR bit is not set */ - if ((getushort(b710->bpbExtFlags) & FATMIRROR) == 0) + /* Mirroring is enabled if the FATMIRROR bit is not set. */ + if ((ExtFlags & FATMIRROR) == 0) pmp->pm_flags |= MSDOSFS_FATMIRROR; else - pmp->pm_curfat = getushort(b710->bpbExtFlags) & FATNUM; + pmp->pm_curfat = ExtFlags & FATNUM; } else pmp->pm_flags |= MSDOSFS_FATMIRROR; if (argp->flags & MSDOSFSMNT_GEMDOSFS) { if (FAT32(pmp)) { - DPRINTF(("FAT32 for GEMDOS\n")); - /* - * GEMDOS doesn't know FAT32. - */ + /* GEMDOS doesn't know FAT32. */ + DPRINTF("FAT32 for GEMDOS"); error = EINVAL; goto error_exit; } /* * Check a few values (could do some more): - * - logical sector size: power of 2, >= block size - * - sectors per cluster: power of 2, >= 1 - * - number of sectors: >= 1, <= size of partition + * - logical sector size: >= block size + * - number of sectors: <= size of partition */ - if ( (SecPerClust == 0) - || (SecPerClust & (SecPerClust - 1)) - || (pmp->pm_BytesPerSec < bsize) - || (pmp->pm_BytesPerSec & (pmp->pm_BytesPerSec - 1)) - || (pmp->pm_HugeSectors == 0) - || (pmp->pm_HugeSectors * (pmp->pm_BytesPerSec / bsize) - > psize)) { - DPRINTF(("consistency checks for GEMDOS\n")); + if ((pmp->pm_BytesPerSec < GEMDOSFS_BSIZE) || + (pmp->pm_HugeSectors * + (pmp->pm_BytesPerSec / GEMDOSFS_BSIZE) > psize)) { + DPRINTF("consistency checks for GEMDOS"); error = EINVAL; goto error_exit; } @@ -626,19 +631,19 @@ msdosfs_mountfs(struct vnode *devvp, str * always be the same as the number of bytes per disk block * Let's pretend it is. */ - tmp = pmp->pm_BytesPerSec / bsize; - pmp->pm_BytesPerSec = bsize; - pmp->pm_HugeSectors *= tmp; - pmp->pm_HiddenSects *= tmp; - pmp->pm_ResSectors *= tmp; - pmp->pm_Sectors *= tmp; - pmp->pm_FATsecs *= tmp; - SecPerClust *= tmp; + BlkPerSec = pmp->pm_BytesPerSec / GEMDOSFS_BSIZE; + pmp->pm_BytesPerSec = GEMDOSFS_BSIZE; + pmp->pm_HugeSectors *= BlkPerSec; + pmp->pm_HiddenSects *= BlkPerSec; + pmp->pm_ResSectors *= BlkPerSec; + pmp->pm_Sectors *= BlkPerSec; + pmp->pm_FATsecs *= BlkPerSec; + SecPerClust *= BlkPerSec; } /* Check that fs has nonzero FAT size */ if (pmp->pm_FATsecs == 0) { - DPRINTF(("FATsecs is 0\n")); + DPRINTF("FATsecs is 0"); error = EINVAL; goto error_exit; } @@ -711,8 +716,8 @@ msdosfs_mountfs(struct vnode *devvp, str * must be a power of 2 */ if (pmp->pm_bpcluster ^ (1 << pmp->pm_cnshift)) { - DPRINTF(("bpcluster %lu cnshift %lu\n", - pmp->pm_bpcluster, pmp->pm_cnshift)); + DPRINTF("bpcluster %lu cnshift %lu", pmp->pm_bpcluster, + pmp->pm_cnshift); error = EINVAL; goto error_exit; } @@ -723,8 +728,8 @@ msdosfs_mountfs(struct vnode *devvp, str * 32KiB due to limits in Windows versions before Vista. */ if (pmp->pm_bpcluster > MAXBSIZE) { - DPRINTF(("bpcluster %lu > MAXBSIZE %d\n", - pmp->pm_bpcluster, MAXBSIZE)); + DPRINTF("bpcluster %lu > MAXBSIZE %d", + pmp->pm_bpcluster, MAXBSIZE); error = EINVAL; goto error_exit; } @@ -740,6 +745,7 @@ msdosfs_mountfs(struct vnode *devvp, str */ if (pmp->pm_fsinfo) { struct fsinfo *fp; + const int rdsz = roundup(sizeof(*fp), pmp->pm_BytesPerSec); /* * XXX If the fsinfo block is stored on media with @@ -747,7 +753,7 @@ msdosfs_mountfs(struct vnode *devvp, str * padded at the end or in the middle? */ if ((error = bread(devvp, de_bn2kb(pmp, pmp->pm_fsinfo), - pmp->pm_BytesPerSec, NOCRED, 0, &bp)) != 0) + rdsz, NOCRED, 0, &bp)) != 0) goto error_exit; fp = (struct fsinfo *)bp->b_data; if (!memcmp(fp->fsisig1, "RRaA", 4) @@ -790,7 +796,7 @@ msdosfs_mountfs(struct vnode *devvp, str * Have the inuse map filled in. */ if ((error = fillinusemap(pmp)) != 0) { - DPRINTF(("fillinusemap %d\n", error)); + DPRINTF("fillinusemap %d", error); goto error_exit; } @@ -908,16 +914,20 @@ int msdosfs_root(struct mount *mp, struct vnode **vpp) { struct msdosfsmount *pmp = VFSTOMSDOSFS(mp); - struct denode *ndep; int error; #ifdef MSDOSFS_DEBUG printf("msdosfs_root(); mp %p, pmp %p\n", mp, pmp); #endif - if ((error = deget(pmp, MSDOSFSROOT, MSDOSFSROOT_OFS, &ndep)) != 0) - return (error); - *vpp = DETOV(ndep); - return (0); + if ((error = deget(pmp, MSDOSFSROOT, MSDOSFSROOT_OFS, vpp)) != 0) + return error; + error = vn_lock(*vpp, LK_EXCLUSIVE); + if (error) { + vrele(*vpp); + *vpp = NULL; + return error; + } + return 0; } int @@ -941,14 +951,34 @@ msdosfs_statvfs(struct mount *mp, struct return (0); } +struct msdosfs_sync_ctx { + int waitfor; +}; + +static bool +msdosfs_sync_selector(void *cl, struct vnode *vp) +{ + struct msdosfs_sync_ctx *c = cl; + struct denode *dep; + + dep = VTODE(vp); + if (c->waitfor == MNT_LAZY || vp->v_type == VNON || + dep == NULL || (((dep->de_flag & + (DE_ACCESS | DE_CREATE | DE_UPDATE | DE_MODIFIED)) == 0) && + (LIST_EMPTY(&vp->v_dirtyblkhd) && + UVM_OBJ_IS_CLEAN(&vp->v_uobj)))) + return false; + return true; +} + int msdosfs_sync(struct mount *mp, int waitfor, kauth_cred_t cred) { struct vnode *vp; struct vnode_iterator *marker; - struct denode *dep; struct msdosfsmount *pmp = VFSTOMSDOSFS(mp); int error, allerror = 0; + struct msdosfs_sync_ctx ctx; /* * If we ever switch to not updating all of the FATs all the time, @@ -966,21 +996,15 @@ msdosfs_sync(struct mount *mp, int waitf * Write back each (modified) denode. */ vfs_vnode_iterator_init(mp, &marker); - while (vfs_vnode_iterator_next(marker, &vp)) { + ctx.waitfor = waitfor; + while ((vp = vfs_vnode_iterator_next(marker, msdosfs_sync_selector, + &ctx))) + { error = vn_lock(vp, LK_EXCLUSIVE); if (error) { vrele(vp); continue; } - dep = VTODE(vp); - if (waitfor == MNT_LAZY || vp->v_type == VNON || - dep == NULL || (((dep->de_flag & - (DE_ACCESS | DE_CREATE | DE_UPDATE | DE_MODIFIED)) == 0) && - (LIST_EMPTY(&vp->v_dirtyblkhd) && - UVM_OBJ_IS_CLEAN(&vp->v_uobj)))) { - vput(vp); - continue; - } if ((error = VOP_FSYNC(vp, cred, waitfor == MNT_WAIT ? FSYNC_WAIT : 0, 0, 0)) != 0) allerror = error; @@ -1003,13 +1027,11 @@ msdosfs_fhtovp(struct mount *mp, struct { struct msdosfsmount *pmp = VFSTOMSDOSFS(mp); struct defid defh; - struct denode *dep; uint32_t gen; int error; if (fhp->fid_len != sizeof(struct defid)) { - DPRINTF(("fid_len %d %zd\n", fhp->fid_len, - sizeof(struct defid))); + DPRINTF("fid_len %d %zd", fhp->fid_len, sizeof(struct defid)); return EINVAL; } memcpy(&defh, fhp, sizeof(defh)); @@ -1021,14 +1043,19 @@ msdosfs_fhtovp(struct mount *mp, struct *vpp = NULLVP; return error; } - error = deget(pmp, defh.defid_dirclust, defh.defid_dirofs, &dep); + error = deget(pmp, defh.defid_dirclust, defh.defid_dirofs, vpp); if (error) { - DPRINTF(("deget %d\n", error)); + DPRINTF("deget %d", error); *vpp = NULLVP; - return (error); + return error; } - *vpp = DETOV(dep); - return (0); + error = vn_lock(*vpp, LK_EXCLUSIVE); + if (error) { + vrele(*vpp); + *vpp = NULLVP; + return error; + } + return 0; } int Index: src/sys/fs/msdosfs/msdosfs_vnops.c diff -u src/sys/fs/msdosfs/msdosfs_vnops.c:1.89 src/sys/fs/msdosfs/msdosfs_vnops.c:1.89.2.1 --- src/sys/fs/msdosfs/msdosfs_vnops.c:1.89 Thu Jan 23 10:13:56 2014 +++ src/sys/fs/msdosfs/msdosfs_vnops.c Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: msdosfs_vnops.c,v 1.89 2014/01/23 10:13:56 hannken Exp $ */ +/* $NetBSD: msdosfs_vnops.c,v 1.89.2.1 2014/08/10 06:55:53 tls Exp $ */ /*- * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank. @@ -48,7 +48,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: msdosfs_vnops.c,v 1.89 2014/01/23 10:13:56 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: msdosfs_vnops.c,v 1.89.2.1 2014/08/10 06:55:53 tls Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -1072,18 +1072,25 @@ abortit: } cache_purge(fvp); if (!doingdirectory) { + struct denode_key old_key = ip->de_key; + struct denode_key new_key = ip->de_key; + error = pcbmap(dp, de_cluster(pmp, to_diroffset), 0, - &ip->de_dirclust, 0); + &new_key.dk_dirclust, 0); if (error) { /* XXX should really panic here, fs is corrupt */ VOP_UNLOCK(fvp); goto bad; } - ip->de_diroffset = to_diroffset; - if (ip->de_dirclust != MSDOSFSROOT) - ip->de_diroffset &= pmp->pm_crbomask; + new_key.dk_diroffset = to_diroffset; + if (new_key.dk_dirclust != MSDOSFSROOT) + new_key.dk_diroffset &= pmp->pm_crbomask; + vcache_rekey_enter(pmp->pm_mountp, fvp, &old_key, + sizeof(old_key), &new_key, sizeof(new_key)); + ip->de_key = new_key; + vcache_rekey_exit(pmp->pm_mountp, fvp, &old_key, + sizeof(old_key), &ip->de_key, sizeof(ip->de_key)); } - reinsert(ip); } /* @@ -1871,6 +1878,8 @@ const struct vnodeopv_entry_desc msdosfs { &vop_setattr_desc, msdosfs_setattr }, /* setattr */ { &vop_read_desc, msdosfs_read }, /* read */ { &vop_write_desc, msdosfs_write }, /* write */ + { &vop_fallocate_desc, genfs_eopnotsupp }, /* fallocate */ + { &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */ { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ { &vop_ioctl_desc, msdosfs_ioctl }, /* ioctl */ { &vop_poll_desc, msdosfs_poll }, /* poll */ Index: src/sys/fs/msdosfs/msdosfsmount.h diff -u src/sys/fs/msdosfs/msdosfsmount.h:1.19 src/sys/fs/msdosfs/msdosfsmount.h:1.19.10.1 --- src/sys/fs/msdosfs/msdosfsmount.h:1.19 Sat Jan 26 16:51:51 2013 +++ src/sys/fs/msdosfs/msdosfsmount.h Sun Aug 10 06:55:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: msdosfsmount.h,v 1.19 2013/01/26 16:51:51 christos Exp $ */ +/* $NetBSD: msdosfsmount.h,v 1.19.10.1 2014/08/10 06:55:53 tls Exp $ */ /*- * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank. @@ -251,5 +251,9 @@ void msdosfs_init(void); void msdosfs_reinit(void); void msdosfs_done(void); +#ifndef MAKEFS +VFS_PROTOS(msdosfs); +#endif + #endif /* _KERNEL || MAKEFS */ #endif /* _MSDOSFS_MSDOSFSMOUNT_H_ */ Index: src/sys/fs/nilfs/nilfs_vfsops.c diff -u src/sys/fs/nilfs/nilfs_vfsops.c:1.15 src/sys/fs/nilfs/nilfs_vfsops.c:1.15.2.1 --- src/sys/fs/nilfs/nilfs_vfsops.c:1.15 Sun Mar 23 15:21:15 2014 +++ src/sys/fs/nilfs/nilfs_vfsops.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: nilfs_vfsops.c,v 1.15 2014/03/23 15:21:15 hannken Exp $ */ +/* $NetBSD: nilfs_vfsops.c,v 1.15.2.1 2014/08/10 06:55:54 tls Exp $ */ /* * Copyright (c) 2008, 2009 Reinoud Zandijk @@ -28,7 +28,7 @@ #include <sys/cdefs.h> #ifndef lint -__KERNEL_RCSID(0, "$NetBSD: nilfs_vfsops.c,v 1.15 2014/03/23 15:21:15 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nilfs_vfsops.c,v 1.15.2.1 2014/08/10 06:55:54 tls Exp $"); #endif /* not lint */ @@ -800,6 +800,8 @@ nilfs_mount(struct mount *mp, const char DPRINTF(VFSCALL, ("nilfs_mount called\n")); + if (args == NULL) + return EINVAL; if (*data_len < sizeof *args) return EINVAL; Index: src/sys/fs/nilfs/nilfs_vnops.c diff -u src/sys/fs/nilfs/nilfs_vnops.c:1.27 src/sys/fs/nilfs/nilfs_vnops.c:1.27.2.1 --- src/sys/fs/nilfs/nilfs_vnops.c:1.27 Fri Feb 7 15:29:21 2014 +++ src/sys/fs/nilfs/nilfs_vnops.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: nilfs_vnops.c,v 1.27 2014/02/07 15:29:21 hannken Exp $ */ +/* $NetBSD: nilfs_vnops.c,v 1.27.2.1 2014/08/10 06:55:54 tls Exp $ */ /* * Copyright (c) 2008, 2009 Reinoud Zandijk @@ -28,7 +28,7 @@ #include <sys/cdefs.h> #ifndef lint -__KERNEL_RCSID(0, "$NetBSD: nilfs_vnops.c,v 1.27 2014/02/07 15:29:21 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nilfs_vnops.c,v 1.27.2.1 2014/08/10 06:55:54 tls Exp $"); #endif /* not lint */ @@ -1572,6 +1572,8 @@ const struct vnodeopv_entry_desc nilfs_v { &vop_setattr_desc, nilfs_setattr }, /* setattr */ /* TODO chflags */ { &vop_read_desc, nilfs_read }, /* read */ { &vop_write_desc, nilfs_write }, /* write */ /* WRITE */ + { &vop_fallocate_desc, genfs_eopnotsupp }, /* fallocate */ + { &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */ { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ /* TODO? */ { &vop_ioctl_desc, genfs_enoioctl }, /* ioctl */ /* TODO? */ { &vop_poll_desc, genfs_poll }, /* poll */ /* TODO/OK? */ Index: src/sys/fs/ntfs/ntfs_vfsops.c diff -u src/sys/fs/ntfs/ntfs_vfsops.c:1.93 src/sys/fs/ntfs/ntfs_vfsops.c:1.93.2.1 --- src/sys/fs/ntfs/ntfs_vfsops.c:1.93 Sun Mar 23 15:21:15 2014 +++ src/sys/fs/ntfs/ntfs_vfsops.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ntfs_vfsops.c,v 1.93 2014/03/23 15:21:15 hannken Exp $ */ +/* $NetBSD: ntfs_vfsops.c,v 1.93.2.1 2014/08/10 06:55:54 tls Exp $ */ /*- * Copyright (c) 1998, 1999 Semen Ustimenko @@ -29,7 +29,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ntfs_vfsops.c,v 1.93 2014/03/23 15:21:15 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ntfs_vfsops.c,v 1.93.2.1 2014/08/10 06:55:54 tls Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -172,6 +172,8 @@ ntfs_mount ( struct vnode *devvp; struct ntfs_args *args = data; + if (args == NULL) + return EINVAL; if (*data_len < sizeof *args) return EINVAL; Index: src/sys/fs/ntfs/ntfs_vnops.c diff -u src/sys/fs/ntfs/ntfs_vnops.c:1.56 src/sys/fs/ntfs/ntfs_vnops.c:1.56.2.1 --- src/sys/fs/ntfs/ntfs_vnops.c:1.56 Fri Feb 7 15:29:21 2014 +++ src/sys/fs/ntfs/ntfs_vnops.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ntfs_vnops.c,v 1.56 2014/02/07 15:29:21 hannken Exp $ */ +/* $NetBSD: ntfs_vnops.c,v 1.56.2.1 2014/08/10 06:55:54 tls Exp $ */ /* * Copyright (c) 1992, 1993 @@ -36,7 +36,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ntfs_vnops.c,v 1.56 2014/02/07 15:29:21 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ntfs_vnops.c,v 1.56.2.1 2014/08/10 06:55:54 tls Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -818,6 +818,8 @@ const struct vnodeopv_entry_desc ntfs_vn { &vop_setattr_desc, genfs_eopnotsupp }, /* setattr */ { &vop_read_desc, (vop_t *) ntfs_read }, /* read */ { &vop_write_desc, (vop_t *) ntfs_write }, /* write */ + { &vop_fallocate_desc, genfs_eopnotsupp }, /* fallocate */ + { &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */ { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ { &vop_ioctl_desc, genfs_enoioctl }, /* ioctl */ { &vop_poll_desc, genfs_poll }, /* poll */ Index: src/sys/fs/ptyfs/ptyfs_vfsops.c diff -u src/sys/fs/ptyfs/ptyfs_vfsops.c:1.49 src/sys/fs/ptyfs/ptyfs_vfsops.c:1.49.2.1 --- src/sys/fs/ptyfs/ptyfs_vfsops.c:1.49 Fri Apr 4 18:10:29 2014 +++ src/sys/fs/ptyfs/ptyfs_vfsops.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ptyfs_vfsops.c,v 1.49 2014/04/04 18:10:29 christos Exp $ */ +/* $NetBSD: ptyfs_vfsops.c,v 1.49.2.1 2014/08/10 06:55:54 tls Exp $ */ /* * Copyright (c) 1992, 1993, 1995 @@ -38,7 +38,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ptyfs_vfsops.c,v 1.49 2014/04/04 18:10:29 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ptyfs_vfsops.c,v 1.49.2.1 2014/08/10 06:55:54 tls Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -259,6 +259,8 @@ ptyfs_mount(struct mount *mp, const char struct ptyfsmount *pmnt; struct ptyfs_args *args = data; + if (args == NULL) + return EINVAL; if (*data_len != sizeof *args && *data_len != OSIZE) return EINVAL; Index: src/sys/fs/ptyfs/ptyfs_vnops.c diff -u src/sys/fs/ptyfs/ptyfs_vnops.c:1.46 src/sys/fs/ptyfs/ptyfs_vnops.c:1.46.2.1 --- src/sys/fs/ptyfs/ptyfs_vnops.c:1.46 Fri Apr 4 18:10:29 2014 +++ src/sys/fs/ptyfs/ptyfs_vnops.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ptyfs_vnops.c,v 1.46 2014/04/04 18:10:29 christos Exp $ */ +/* $NetBSD: ptyfs_vnops.c,v 1.46.2.1 2014/08/10 06:55:54 tls Exp $ */ /* * Copyright (c) 1993, 1995 @@ -76,7 +76,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ptyfs_vnops.c,v 1.46 2014/04/04 18:10:29 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ptyfs_vnops.c,v 1.46.2.1 2014/08/10 06:55:54 tls Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -176,6 +176,8 @@ const struct vnodeopv_entry_desc ptyfs_v { &vop_setattr_desc, ptyfs_setattr }, /* setattr */ { &vop_read_desc, ptyfs_read }, /* read */ { &vop_write_desc, ptyfs_write }, /* write */ + { &vop_fallocate_desc, genfs_eopnotsupp }, /* fallocate */ + { &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */ { &vop_ioctl_desc, ptyfs_ioctl }, /* ioctl */ { &vop_fcntl_desc, ptyfs_fcntl }, /* fcntl */ { &vop_poll_desc, ptyfs_poll }, /* poll */ Index: src/sys/fs/puffs/puffs_vfsops.c diff -u src/sys/fs/puffs/puffs_vfsops.c:1.109 src/sys/fs/puffs/puffs_vfsops.c:1.109.2.1 --- src/sys/fs/puffs/puffs_vfsops.c:1.109 Sun Mar 23 15:21:15 2014 +++ src/sys/fs/puffs/puffs_vfsops.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: puffs_vfsops.c,v 1.109 2014/03/23 15:21:15 hannken Exp $ */ +/* $NetBSD: puffs_vfsops.c,v 1.109.2.1 2014/08/10 06:55:54 tls Exp $ */ /* * Copyright (c) 2005, 2006 Antti Kantee. All Rights Reserved. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: puffs_vfsops.c,v 1.109 2014/03/23 15:21:15 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: puffs_vfsops.c,v 1.109.2.1 2014/08/10 06:55:54 tls Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -102,6 +102,8 @@ puffs_vfsop_mount(struct mount *mp, cons int error = 0, i; pid_t mntpid = curlwp->l_proc->p_pid; + if (data == NULL) + return EINVAL; if (*data_len < sizeof *args) return EINVAL; @@ -116,12 +118,6 @@ puffs_vfsop_mount(struct mount *mp, cons if (mp->mnt_flag & MNT_UPDATE) return EOPNOTSUPP; - /* - * We need the file system name - */ - if (!data) - return EINVAL; - args = (struct puffs_kargs *)data; if (args->pa_vers != PUFFSVERSION) { @@ -514,6 +510,13 @@ puffs_vfsop_statvfs(struct mount *mp, st return error; } +static bool +pageflush_selector(void *cl, struct vnode *vp) +{ + return vp->v_type == VREG && + !(LIST_EMPTY(&vp->v_dirtyblkhd) && UVM_OBJ_IS_CLEAN(&vp->v_uobj)); +} + static int pageflush(struct mount *mp, kauth_cred_t cred, int waitfor) { @@ -532,7 +535,9 @@ pageflush(struct mount *mp, kauth_cred_t * all the nodes it knows to exist. */ vfs_vnode_iterator_init(mp, &marker); - while (vfs_vnode_iterator_next(marker, &vp)) { + while ((vp = vfs_vnode_iterator_next(marker, pageflush_selector, + NULL))) + { /* * Here we try to get a reference to the vnode and to * lock it. This is mostly cargo-culted, but I will @@ -554,11 +559,6 @@ pageflush(struct mount *mp, kauth_cred_t continue; } pn = VPTOPP(vp); - if (vp->v_type != VREG || UVM_OBJ_IS_CLEAN(&vp->v_uobj)) { - vput(vp); - continue; - } - /* hmm.. is the FAF thing entirely sensible? */ if (waitfor == MNT_LAZY) { mutex_enter(vp->v_interlock); Index: src/sys/fs/puffs/puffs_vnops.c diff -u src/sys/fs/puffs/puffs_vnops.c:1.181 src/sys/fs/puffs/puffs_vnops.c:1.181.2.1 --- src/sys/fs/puffs/puffs_vnops.c:1.181 Mon Mar 24 13:42:40 2014 +++ src/sys/fs/puffs/puffs_vnops.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: puffs_vnops.c,v 1.181 2014/03/24 13:42:40 hannken Exp $ */ +/* $NetBSD: puffs_vnops.c,v 1.181.2.1 2014/08/10 06:55:54 tls Exp $ */ /* * Copyright (c) 2005, 2006, 2007 Antti Kantee. All Rights Reserved. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.181 2014/03/24 13:42:40 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.181.2.1 2014/08/10 06:55:54 tls Exp $"); #include <sys/param.h> #include <sys/buf.h> @@ -113,6 +113,8 @@ const struct vnodeopv_entry_desc puffs_v { &vop_setattr_desc, puffs_vnop_checkop }, /* setattr */ { &vop_read_desc, puffs_vnop_checkop }, /* read */ { &vop_write_desc, puffs_vnop_checkop }, /* write */ + { &vop_fallocate_desc, genfs_eopnotsupp }, /* fallocate */ + { &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */ { &vop_fsync_desc, puffs_vnop_fsync }, /* REAL fsync */ { &vop_seek_desc, puffs_vnop_checkop }, /* seek */ { &vop_remove_desc, puffs_vnop_checkop }, /* remove */ @@ -168,6 +170,8 @@ const struct vnodeopv_entry_desc puffs_s { &vop_setattr_desc, puffs_vnop_checkop }, /* setattr */ { &vop_read_desc, puffs_vnop_spec_read }, /* update, read */ { &vop_write_desc, puffs_vnop_spec_write }, /* update, write */ + { &vop_fallocate_desc, spec_fallocate }, /* fallocate */ + { &vop_fdiscard_desc, spec_fdiscard }, /* fdiscard */ { &vop_ioctl_desc, spec_ioctl }, /* spec_ioctl */ { &vop_fcntl_desc, genfs_fcntl }, /* dummy */ { &vop_poll_desc, spec_poll }, /* spec_poll */ @@ -225,6 +229,8 @@ const struct vnodeopv_entry_desc puffs_f { &vop_setattr_desc, puffs_vnop_checkop }, /* setattr */ { &vop_read_desc, puffs_vnop_fifo_read }, /* read, update */ { &vop_write_desc, puffs_vnop_fifo_write }, /* write, update */ + { &vop_fallocate_desc, vn_fifo_bypass }, /* fallocate */ + { &vop_fdiscard_desc, vn_fifo_bypass }, /* fdiscard */ { &vop_ioctl_desc, vn_fifo_bypass }, /* ioctl */ { &vop_fcntl_desc, genfs_fcntl }, /* dummy */ { &vop_poll_desc, vn_fifo_bypass }, /* poll */ Index: src/sys/fs/smbfs/smbfs_vfsops.c diff -u src/sys/fs/smbfs/smbfs_vfsops.c:1.99 src/sys/fs/smbfs/smbfs_vfsops.c:1.99.2.1 --- src/sys/fs/smbfs/smbfs_vfsops.c:1.99 Sun Mar 23 15:21:15 2014 +++ src/sys/fs/smbfs/smbfs_vfsops.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: smbfs_vfsops.c,v 1.99 2014/03/23 15:21:15 hannken Exp $ */ +/* $NetBSD: smbfs_vfsops.c,v 1.99.2.1 2014/08/10 06:55:54 tls Exp $ */ /* * Copyright (c) 2000-2001, Boris Popov @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: smbfs_vfsops.c,v 1.99 2014/03/23 15:21:15 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: smbfs_vfsops.c,v 1.99.2.1 2014/08/10 06:55:54 tls Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -62,7 +62,7 @@ __KERNEL_RCSID(0, "$NetBSD: smbfs_vfsops #include <fs/smbfs/smbfs_node.h> #include <fs/smbfs/smbfs_subr.h> -MODULE(MODULE_CLASS_VFS, smbfs, NULL); +MODULE(MODULE_CLASS_VFS, smbfs, "nsmb"); VFS_PROTOS(smbfs); @@ -156,6 +156,8 @@ smbfs_mount(struct mount *mp, const char char *fromname; int error; + if (args == NULL) + return EINVAL; if (*data_len < sizeof *args) return EINVAL; @@ -398,6 +400,23 @@ smbfs_statvfs(struct mount *mp, struct s return 0; } +static bool +smbfs_sync_selector(void *cl, struct vnode *vp) +{ + struct smbnode *np; + + np = VTOSMB(vp); + if (np == NULL) + return false; + + if ((vp->v_type == VNON || (np->n_flag & NMODIFIED) == 0) && + LIST_EMPTY(&vp->v_dirtyblkhd) && + UVM_OBJ_IS_CLEAN(&vp->v_uobj)) + return false; + + return true; +} + /* * Flush out the buffer cache */ @@ -406,27 +425,17 @@ smbfs_sync(struct mount *mp, int waitfor { struct vnode *vp; struct vnode_iterator *marker; - struct smbnode *np; int error, allerror = 0; vfs_vnode_iterator_init(mp, &marker); - while (vfs_vnode_iterator_next(marker, &vp)) { + while ((vp = vfs_vnode_iterator_next(marker, smbfs_sync_selector, + NULL))) + { error = vn_lock(vp, LK_EXCLUSIVE); if (error) { vrele(vp); continue; } - np = VTOSMB(vp); - if (np == NULL) { - vput(vp); - continue; - } - if ((vp->v_type == VNON || (np->n_flag & NMODIFIED) == 0) && - LIST_EMPTY(&vp->v_dirtyblkhd) && - vp->v_uobj.uo_npages == 0) { - vput(vp); - continue; - } error = VOP_FSYNC(vp, cred, waitfor == MNT_WAIT ? FSYNC_WAIT : 0, 0, 0); if (error) Index: src/sys/fs/smbfs/smbfs_vnops.c diff -u src/sys/fs/smbfs/smbfs_vnops.c:1.89 src/sys/fs/smbfs/smbfs_vnops.c:1.89.2.1 --- src/sys/fs/smbfs/smbfs_vnops.c:1.89 Fri Feb 7 15:29:21 2014 +++ src/sys/fs/smbfs/smbfs_vnops.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: smbfs_vnops.c,v 1.89 2014/02/07 15:29:21 hannken Exp $ */ +/* $NetBSD: smbfs_vnops.c,v 1.89.2.1 2014/08/10 06:55:54 tls Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -64,7 +64,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: smbfs_vnops.c,v 1.89 2014/02/07 15:29:21 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: smbfs_vnops.c,v 1.89.2.1 2014/08/10 06:55:54 tls Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -127,6 +127,8 @@ static struct vnodeopv_entry_desc smbfs_ { &vop_advlock_desc, smbfs_advlock }, { &vop_close_desc, smbfs_close }, { &vop_create_desc, smbfs_create }, + { &vop_fallocate_desc, genfs_eopnotsupp }, + { &vop_fdiscard_desc, genfs_eopnotsupp }, { &vop_fsync_desc, smbfs_fsync }, { &vop_getattr_desc, smbfs_getattr }, { &vop_getpages_desc, genfs_compat_getpages }, @@ -1244,9 +1246,11 @@ smbfs_lookup(void *v) } newvp = *vpp; - vn_lock(newvp, LK_SHARED | LK_RETRY); + if (newvp != dvp) + vn_lock(newvp, LK_SHARED | LK_RETRY); error = VOP_GETATTR(newvp, &vattr, cnp->cn_cred); - VOP_UNLOCK(newvp); + if (newvp != dvp) + VOP_UNLOCK(newvp); /* * If the file type on the server is inconsistent * with what it was when we created the vnode, Index: src/sys/fs/sysvbfs/sysvbfs.c diff -u src/sys/fs/sysvbfs/sysvbfs.c:1.13 src/sys/fs/sysvbfs/sysvbfs.c:1.13.2.1 --- src/sys/fs/sysvbfs/sysvbfs.c:1.13 Sun Mar 23 15:21:15 2014 +++ src/sys/fs/sysvbfs/sysvbfs.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: sysvbfs.c,v 1.13 2014/03/23 15:21:15 hannken Exp $ */ +/* $NetBSD: sysvbfs.c,v 1.13.2.1 2014/08/10 06:55:54 tls Exp $ */ /*- * Copyright (c) 2004 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sysvbfs.c,v 1.13 2014/03/23 15:21:15 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sysvbfs.c,v 1.13.2.1 2014/08/10 06:55:54 tls Exp $"); #include <sys/resource.h> #include <sys/param.h> @@ -59,6 +59,8 @@ const struct vnodeopv_entry_desc sysvbfs { &vop_setattr_desc, sysvbfs_setattr }, /* setattr */ { &vop_read_desc, sysvbfs_read }, /* read */ { &vop_write_desc, sysvbfs_write }, /* write */ + { &vop_fallocate_desc, genfs_eopnotsupp }, /* fallocate */ + { &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */ { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ { &vop_ioctl_desc, genfs_enoioctl }, /* ioctl */ { &vop_poll_desc, genfs_poll }, /* poll */ Index: src/sys/fs/sysvbfs/sysvbfs_vfsops.c diff -u src/sys/fs/sysvbfs/sysvbfs_vfsops.c:1.42 src/sys/fs/sysvbfs/sysvbfs_vfsops.c:1.42.2.1 --- src/sys/fs/sysvbfs/sysvbfs_vfsops.c:1.42 Wed Dec 25 11:15:49 2013 +++ src/sys/fs/sysvbfs/sysvbfs_vfsops.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: sysvbfs_vfsops.c,v 1.42 2013/12/25 11:15:49 mlelstv Exp $ */ +/* $NetBSD: sysvbfs_vfsops.c,v 1.42.2.1 2014/08/10 06:55:54 tls Exp $ */ /*- * Copyright (c) 2004 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sysvbfs_vfsops.c,v 1.42 2013/12/25 11:15:49 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sysvbfs_vfsops.c,v 1.42.2.1 2014/08/10 06:55:54 tls Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -77,6 +77,8 @@ sysvbfs_mount(struct mount *mp, const ch DPRINTF("%s: mnt_flag=%x\n", __func__, mp->mnt_flag); + if (args == NULL) + return EINVAL; if (*data_len < sizeof *args) return EINVAL; Index: src/sys/fs/sysvbfs/sysvbfs_vnops.c diff -u src/sys/fs/sysvbfs/sysvbfs_vnops.c:1.53 src/sys/fs/sysvbfs/sysvbfs_vnops.c:1.53.2.1 --- src/sys/fs/sysvbfs/sysvbfs_vnops.c:1.53 Fri Feb 7 15:29:21 2014 +++ src/sys/fs/sysvbfs/sysvbfs_vnops.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: sysvbfs_vnops.c,v 1.53 2014/02/07 15:29:21 hannken Exp $ */ +/* $NetBSD: sysvbfs_vnops.c,v 1.53.2.1 2014/08/10 06:55:54 tls Exp $ */ /*- * Copyright (c) 2004 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sysvbfs_vnops.c,v 1.53 2014/02/07 15:29:21 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sysvbfs_vnops.c,v 1.53.2.1 2014/08/10 06:55:54 tls Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -450,7 +450,7 @@ sysvbfs_read(void *arg) DPRINTF("%s: read %ldbyte\n", __func__, sz); } - return sysvbfs_update(v, NULL, NULL, UPDATE_WAIT); + return sysvbfs_update(v, NULL, NULL, UPDATE_WAIT); } int Index: src/sys/fs/tmpfs/tmpfs.h diff -u src/sys/fs/tmpfs/tmpfs.h:1.48 src/sys/fs/tmpfs/tmpfs.h:1.48.2.1 --- src/sys/fs/tmpfs/tmpfs.h:1.48 Sat Nov 23 16:35:32 2013 +++ src/sys/fs/tmpfs/tmpfs.h Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: tmpfs.h,v 1.48 2013/11/23 16:35:32 rmind Exp $ */ +/* $NetBSD: tmpfs.h,v 1.48.2.1 2014/08/10 06:55:54 tls Exp $ */ /* * Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc. @@ -279,6 +279,7 @@ void tmpfs_update(vnode_t *, unsigned); void tmpfs_mntmem_init(tmpfs_mount_t *, uint64_t); void tmpfs_mntmem_destroy(tmpfs_mount_t *); +int tmpfs_mntmem_set(tmpfs_mount_t *, uint64_t); size_t tmpfs_mem_info(bool); uint64_t tmpfs_bytes_max(tmpfs_mount_t *); @@ -306,13 +307,6 @@ bool tmpfs_strname_neqlen(struct compon KASSERT((node)->tn_size % sizeof(tmpfs_dirent_t) == 0); /* - * Memory management stuff. - */ - -/* Amount of memory pages to reserve for the system. */ -#define TMPFS_PAGES_RESERVED (4 * 1024 * 1024 / PAGE_SIZE) - -/* * Routines to convert VFS structures to tmpfs internal ones. */ Index: src/sys/fs/tmpfs/tmpfs_fifoops.c diff -u src/sys/fs/tmpfs/tmpfs_fifoops.c:1.10 src/sys/fs/tmpfs/tmpfs_fifoops.c:1.10.2.1 --- src/sys/fs/tmpfs/tmpfs_fifoops.c:1.10 Sat Nov 23 16:35:32 2013 +++ src/sys/fs/tmpfs/tmpfs_fifoops.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: tmpfs_fifoops.c,v 1.10 2013/11/23 16:35:32 rmind Exp $ */ +/* $NetBSD: tmpfs_fifoops.c,v 1.10.2.1 2014/08/10 06:55:54 tls Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tmpfs_fifoops.c,v 1.10 2013/11/23 16:35:32 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tmpfs_fifoops.c,v 1.10.2.1 2014/08/10 06:55:54 tls Exp $"); #include <sys/param.h> #include <sys/vnode.h> @@ -59,6 +59,8 @@ const struct vnodeopv_entry_desc tmpfs_f { &vop_setattr_desc, tmpfs_fifo_setattr }, { &vop_read_desc, tmpfs_fifo_read }, { &vop_write_desc, tmpfs_fifo_write }, + { &vop_fallocate_desc, vn_fifo_bypass }, + { &vop_fdiscard_desc, vn_fifo_bypass }, { &vop_ioctl_desc, tmpfs_fifo_ioctl }, { &vop_fcntl_desc, tmpfs_fifo_fcntl }, { &vop_poll_desc, tmpfs_fifo_poll }, Index: src/sys/fs/tmpfs/tmpfs_mem.c diff -u src/sys/fs/tmpfs/tmpfs_mem.c:1.4 src/sys/fs/tmpfs/tmpfs_mem.c:1.4.28.1 --- src/sys/fs/tmpfs/tmpfs_mem.c:1.4 Tue May 24 01:09:47 2011 +++ src/sys/fs/tmpfs/tmpfs_mem.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: tmpfs_mem.c,v 1.4 2011/05/24 01:09:47 rmind Exp $ */ +/* $NetBSD: tmpfs_mem.c,v 1.4.28.1 2014/08/10 06:55:54 tls Exp $ */ /* * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tmpfs_mem.c,v 1.4 2011/05/24 01:09:47 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tmpfs_mem.c,v 1.4.28.1 2014/08/10 06:55:54 tls Exp $"); #include <sys/param.h> #include <sys/atomic.h> @@ -65,13 +65,31 @@ tmpfs_mntmem_destroy(struct tmpfs_mount mutex_destroy(&mp->tm_acc_lock); } +int +tmpfs_mntmem_set(struct tmpfs_mount *mp, uint64_t memlimit) +{ + int error; + + mutex_enter(&mp->tm_acc_lock); + if (round_page(mp->tm_bytes_used) >= memlimit) + error = EBUSY; + else { + error = 0; + mp->tm_mem_limit = memlimit; + } + mutex_exit(&mp->tm_acc_lock); + return error; +} + + + /* * tmpfs_mem_info: return the number of available memory pages. * * => If 'total' is true, then return _total_ amount of pages. * => If false, then return the amount of _free_ memory pages. * - * Remember to remove TMPFS_PAGES_RESERVED from the returned value to avoid + * Remember to remove uvmexp.freetarg from the returned value to avoid * excessive memory usage. */ size_t @@ -97,13 +115,13 @@ tmpfs_mem_info(bool total) uint64_t tmpfs_bytes_max(struct tmpfs_mount *mp) { - size_t freepages = tmpfs_mem_info(false); + psize_t freepages = tmpfs_mem_info(false); uint64_t avail_mem; - if (freepages < TMPFS_PAGES_RESERVED) { + if (freepages < uvmexp.freetarg) { freepages = 0; } else { - freepages -= TMPFS_PAGES_RESERVED; + freepages -= uvmexp.freetarg; } avail_mem = round_page(mp->tm_bytes_used) + (freepages << PAGE_SHIFT); return MIN(mp->tm_mem_limit, avail_mem); Index: src/sys/fs/tmpfs/tmpfs_specops.c diff -u src/sys/fs/tmpfs/tmpfs_specops.c:1.11 src/sys/fs/tmpfs/tmpfs_specops.c:1.11.2.1 --- src/sys/fs/tmpfs/tmpfs_specops.c:1.11 Sat Nov 23 16:35:32 2013 +++ src/sys/fs/tmpfs/tmpfs_specops.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: tmpfs_specops.c,v 1.11 2013/11/23 16:35:32 rmind Exp $ */ +/* $NetBSD: tmpfs_specops.c,v 1.11.2.1 2014/08/10 06:55:54 tls Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tmpfs_specops.c,v 1.11 2013/11/23 16:35:32 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tmpfs_specops.c,v 1.11.2.1 2014/08/10 06:55:54 tls Exp $"); #include <sys/param.h> #include <sys/vnode.h> @@ -62,6 +62,8 @@ const struct vnodeopv_entry_desc tmpfs_s { &vop_setattr_desc, tmpfs_spec_setattr }, { &vop_read_desc, tmpfs_spec_read }, { &vop_write_desc, tmpfs_spec_write }, + { &vop_fallocate_desc, spec_fallocate }, + { &vop_fdiscard_desc, spec_fdiscard }, { &vop_ioctl_desc, tmpfs_spec_ioctl }, { &vop_fcntl_desc, tmpfs_spec_fcntl }, { &vop_poll_desc, tmpfs_spec_poll }, Index: src/sys/fs/tmpfs/tmpfs_vfsops.c diff -u src/sys/fs/tmpfs/tmpfs_vfsops.c:1.58 src/sys/fs/tmpfs/tmpfs_vfsops.c:1.58.2.1 --- src/sys/fs/tmpfs/tmpfs_vfsops.c:1.58 Sun Mar 23 15:21:16 2014 +++ src/sys/fs/tmpfs/tmpfs_vfsops.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: tmpfs_vfsops.c,v 1.58 2014/03/23 15:21:16 hannken Exp $ */ +/* $NetBSD: tmpfs_vfsops.c,v 1.58.2.1 2014/08/10 06:55:54 tls Exp $ */ /* * Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc. @@ -42,7 +42,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tmpfs_vfsops.c,v 1.58 2014/03/23 15:21:16 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tmpfs_vfsops.c,v 1.58.2.1 2014/08/10 06:55:54 tls Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -103,6 +103,9 @@ tmpfs_mount(struct mount *mp, const char ino_t nodes; int error; + if (args == NULL) + return EINVAL; + /* Validate the version. */ if (*data_len < sizeof(*args) || args->ta_version != TMPFS_ARGS_VERSION) @@ -127,13 +130,17 @@ tmpfs_mount(struct mount *mp, const char return 0; } - if (mp->mnt_flag & MNT_UPDATE) { - /* TODO */ - return EOPNOTSUPP; - } /* Prohibit mounts if there is not enough memory. */ - if (tmpfs_mem_info(true) < TMPFS_PAGES_RESERVED) + if (tmpfs_mem_info(true) < uvmexp.freetarg) + return EINVAL; + + /* Check for invalid uid and gid arguments */ + if (args->ta_root_uid == VNOVAL || args->ta_root_gid == VNOVAL) + return EINVAL; + + /* This can never happen? */ + if ((args->ta_root_mode & ALLPERMS) == VNOVAL) return EINVAL; /* Get the memory usage limit for this file-system. */ @@ -152,6 +159,20 @@ tmpfs_mount(struct mount *mp, const char nodes = MIN(nodes, INT_MAX); KASSERT(nodes >= 3); + if (mp->mnt_flag & MNT_UPDATE) { + tmp = VFS_TO_TMPFS(mp); + if (nodes < tmp->tm_nodes_cnt) + return EBUSY; + if ((error = tmpfs_mntmem_set(tmp, memlimit)) != 0) + return error; + tmp->tm_nodes_max = nodes; + root = tmp->tm_root; + root->tn_uid = args->ta_root_uid; + root->tn_gid = args->ta_root_gid; + root->tn_mode = args->ta_root_mode; + return 0; + } + /* Allocate the tmpfs mount structure and fill it. */ tmp = kmem_zalloc(sizeof(tmpfs_mount_t), KM_SLEEP); if (tmp == NULL) Index: src/sys/fs/tmpfs/tmpfs_vnops.c diff -u src/sys/fs/tmpfs/tmpfs_vnops.c:1.118 src/sys/fs/tmpfs/tmpfs_vnops.c:1.118.2.1 --- src/sys/fs/tmpfs/tmpfs_vnops.c:1.118 Thu Feb 27 16:51:38 2014 +++ src/sys/fs/tmpfs/tmpfs_vnops.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: tmpfs_vnops.c,v 1.118 2014/02/27 16:51:38 hannken Exp $ */ +/* $NetBSD: tmpfs_vnops.c,v 1.118.2.1 2014/08/10 06:55:54 tls Exp $ */ /* * Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.118 2014/02/27 16:51:38 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.118.2.1 2014/08/10 06:55:54 tls Exp $"); #include <sys/param.h> #include <sys/dirent.h> @@ -74,6 +74,8 @@ const struct vnodeopv_entry_desc tmpfs_v { &vop_setattr_desc, tmpfs_setattr }, { &vop_read_desc, tmpfs_read }, { &vop_write_desc, tmpfs_write }, + { &vop_fallocate_desc, genfs_eopnotsupp }, + { &vop_fdiscard_desc, genfs_eopnotsupp }, { &vop_ioctl_desc, tmpfs_ioctl }, { &vop_fcntl_desc, tmpfs_fcntl }, { &vop_poll_desc, tmpfs_poll }, @@ -343,7 +345,7 @@ tmpfs_mknod(void *v) enum vtype vt = vap->va_type; if (vt != VBLK && vt != VCHR && vt != VFIFO) { - vput(dvp); + *vpp = NULL; return EINVAL; } return tmpfs_construct_node(dvp, vpp, vap, cnp, NULL); Index: src/sys/fs/udf/udf_subr.c diff -u src/sys/fs/udf/udf_subr.c:1.124 src/sys/fs/udf/udf_subr.c:1.124.2.1 --- src/sys/fs/udf/udf_subr.c:1.124 Sun Mar 23 09:34:42 2014 +++ src/sys/fs/udf/udf_subr.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: udf_subr.c,v 1.124 2014/03/23 09:34:42 christos Exp $ */ +/* $NetBSD: udf_subr.c,v 1.124.2.1 2014/08/10 06:55:54 tls Exp $ */ /* * Copyright (c) 2006, 2008 Reinoud Zandijk @@ -29,7 +29,7 @@ #include <sys/cdefs.h> #ifndef lint -__KERNEL_RCSID(0, "$NetBSD: udf_subr.c,v 1.124 2014/03/23 09:34:42 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: udf_subr.c,v 1.124.2.1 2014/08/10 06:55:54 tls Exp $"); #endif /* not lint */ @@ -1808,8 +1808,8 @@ udf_write_metadata_partition_spacetable( dscr = (union dscrptr *) ump->metadata_unalloc_dscr; new_inflen = udf_tagsize(dscr, 1); - DPRINTF(VOLUMES, ("Resize and write out metadata space bitmap from " - "%"PRIu64" to %"PRIu64" bytes\n", inflen, new_inflen)); + DPRINTF(VOLUMES, ("Resize and write out metadata space bitmap " + " for %"PRIu64" bytes\n", new_inflen)); error = udf_resize_node(bitmap_node, new_inflen, &dummy); if (error) Index: src/sys/fs/udf/udf_vfsops.c diff -u src/sys/fs/udf/udf_vfsops.c:1.66 src/sys/fs/udf/udf_vfsops.c:1.66.2.1 --- src/sys/fs/udf/udf_vfsops.c:1.66 Sun Mar 23 15:21:16 2014 +++ src/sys/fs/udf/udf_vfsops.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: udf_vfsops.c,v 1.66 2014/03/23 15:21:16 hannken Exp $ */ +/* $NetBSD: udf_vfsops.c,v 1.66.2.1 2014/08/10 06:55:54 tls Exp $ */ /* * Copyright (c) 2006, 2008 Reinoud Zandijk @@ -28,7 +28,7 @@ #include <sys/cdefs.h> #ifndef lint -__KERNEL_RCSID(0, "$NetBSD: udf_vfsops.c,v 1.66 2014/03/23 15:21:16 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: udf_vfsops.c,v 1.66.2.1 2014/08/10 06:55:54 tls Exp $"); #endif /* not lint */ @@ -316,6 +316,8 @@ udf_mount(struct mount *mp, const char * DPRINTF(CALL, ("udf_mount called\n")); + if (args == NULL) + return EINVAL; if (*data_len < sizeof *args) return EINVAL; Index: src/sys/fs/udf/udf_vnops.c diff -u src/sys/fs/udf/udf_vnops.c:1.91 src/sys/fs/udf/udf_vnops.c:1.91.2.1 --- src/sys/fs/udf/udf_vnops.c:1.91 Sun Mar 23 09:34:42 2014 +++ src/sys/fs/udf/udf_vnops.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: udf_vnops.c,v 1.91 2014/03/23 09:34:42 christos Exp $ */ +/* $NetBSD: udf_vnops.c,v 1.91.2.1 2014/08/10 06:55:54 tls Exp $ */ /* * Copyright (c) 2006, 2008 Reinoud Zandijk @@ -32,7 +32,7 @@ #include <sys/cdefs.h> #ifndef lint -__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.91 2014/03/23 09:34:42 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.91.2.1 2014/08/10 06:55:54 tls Exp $"); #endif /* not lint */ @@ -67,6 +67,9 @@ __KERNEL_RCSID(0, "$NetBSD: udf_vnops.c, #define VTOI(vnode) ((struct udf_node *) (vnode)->v_data) +/* forward declarations */ +static int udf_do_readlink(struct udf_node *udf_node, uint64_t filesize, + uint8_t *targetbuf, int *length); /* externs */ extern int prtactive; @@ -865,10 +868,10 @@ udf_getattr(void *v) uint64_t filesize, blkssize; uint32_t nlink; uint32_t offset, a_l; - uint8_t *filedata; + uint8_t *filedata, *targetbuf; uid_t uid; gid_t gid; - int error; + int length, error; DPRINTF(CALL, ("udf_getattr called\n")); @@ -939,6 +942,22 @@ udf_getattr(void *v) if (vap->va_type == VDIR) vap->va_nlink++; + /* + * BUG-ALERT: Posix requires the va_size to be pathlength for symbolic + * links. + */ + if (vap->va_type == VLNK) { + /* claim temporary buffers for translation */ + targetbuf = malloc(PATH_MAX+1, M_UDFTEMP, M_WAITOK); + error = udf_do_readlink(udf_node, filesize, targetbuf, &length); + if (!error) { + vap->va_size = length; + KASSERT(length == strlen(targetbuf)); + } + free(targetbuf, M_UDFTEMP); + /* XXX return error? */ + } + /* access times */ udf_timestamp_to_timespec(ump, atime, &vap->va_atime); udf_timestamp_to_timespec(ump, mtime, &vap->va_mtime); @@ -1020,8 +1039,6 @@ udf_chown(struct vnode *vp, uid_t new_ui /* mark node changed */ udf_node->i_flags |= IN_CHANGE; - if (vp->v_mount->mnt_flag & MNT_RELATIME) - udf_node->i_flags |= IN_ACCESS; return 0; } @@ -1059,8 +1076,6 @@ udf_chmod(struct vnode *vp, mode_t mode, /* mark node changed */ udf_node->i_flags |= IN_CHANGE; - if (vp->v_mount->mnt_flag & MNT_RELATIME) - udf_node->i_flags |= IN_ACCESS; return 0; } @@ -1734,49 +1749,30 @@ udf_symlink(void *v) /* --------------------------------------------------------------------- */ -int -udf_readlink(void *v) +static int +udf_do_readlink(struct udf_node *udf_node, uint64_t filesize, + uint8_t *targetbuf, int *length) { - struct vop_readlink_args /* { - struct vnode *a_vp; - struct uio *a_uio; - kauth_cred_t a_cred; - } */ *ap = v; - struct vnode *vp = ap->a_vp; - struct uio *uio = ap->a_uio; - kauth_cred_t cred = ap->a_cred; - struct udf_node *udf_node; struct pathcomp pathcomp; - struct vattr vattr; - uint8_t *pathbuf, *targetbuf, *tmpname; + uint8_t *pathbuf, *tmpname; uint8_t *pathpos, *targetpos; char *mntonname; int pathlen, targetlen, namelen, mntonnamelen, len, l_ci; int first, error; - DPRINTF(CALL, ("udf_readlink called\n")); - - udf_node = VTOI(vp); - error = VOP_GETATTR(vp, &vattr, cred); - if (error) - return error; - - /* claim temporary buffers for translation */ pathbuf = malloc(UDF_SYMLINKBUFLEN, M_UDFTEMP, M_WAITOK); - targetbuf = malloc(PATH_MAX+1, M_UDFTEMP, M_WAITOK); tmpname = malloc(PATH_MAX+1, M_UDFTEMP, M_WAITOK); memset(pathbuf, 0, UDF_SYMLINKBUFLEN); memset(targetbuf, 0, PATH_MAX); /* read contents of file in our temporary buffer */ error = vn_rdwr(UIO_READ, udf_node->vnode, - pathbuf, vattr.va_size, 0, + pathbuf, filesize, 0, UIO_SYSSPACE, IO_NODELOCKED | IO_ALTSEMANTICS, FSCRED, NULL, NULL); if (error) { /* failed to read in symlink contents */ free(pathbuf, M_UDFTEMP); - free(targetbuf, M_UDFTEMP); free(tmpname, M_UDFTEMP); return error; } @@ -1791,7 +1787,7 @@ udf_readlink(void *v) error = 0; first = 1; - while (vattr.va_size - pathlen >= UDF_PATH_COMP_SIZE) { + while (filesize - pathlen >= UDF_PATH_COMP_SIZE) { len = UDF_PATH_COMP_SIZE; memcpy(&pathcomp, pathpos, len); l_ci = pathcomp.l_ci; @@ -1812,7 +1808,7 @@ udf_readlink(void *v) } memcpy(targetpos, mntonname, mntonnamelen); targetpos += mntonnamelen; targetlen -= mntonnamelen; - if (vattr.va_size-pathlen > UDF_PATH_COMP_SIZE+l_ci) { + if (filesize-pathlen > UDF_PATH_COMP_SIZE+l_ci) { /* more follows, so must be directory */ *targetpos++ = '/'; targetlen--; } @@ -1853,7 +1849,7 @@ udf_readlink(void *v) } memcpy(targetpos, tmpname, namelen); targetpos += namelen; targetlen -= namelen; - if (vattr.va_size-pathlen > UDF_PATH_COMP_SIZE+l_ci) { + if (filesize-pathlen > UDF_PATH_COMP_SIZE+l_ci) { /* more follows, so must be directory */ *targetpos++ = '/'; targetlen--; } @@ -1870,17 +1866,54 @@ udf_readlink(void *v) } /* all processed? */ - if (vattr.va_size - pathlen > 0) + if (filesize - pathlen > 0) error = EINVAL; + free(pathbuf, M_UDFTEMP); + free(tmpname, M_UDFTEMP); + + *length = PATH_MAX - targetlen; + return error; +} + + +int +udf_readlink(void *v) +{ + struct vop_readlink_args /* { + struct vnode *a_vp; + struct uio *a_uio; + kauth_cred_t a_cred; + } */ *ap = v; + struct vnode *vp = ap->a_vp; + struct udf_node *udf_node = VTOI(vp); + struct file_entry *fe = udf_node->fe; + struct extfile_entry *efe = udf_node->efe; + struct uio *uio = ap->a_uio; + uint64_t filesize; + uint8_t *targetbuf; + int length; + int error; + + DPRINTF(CALL, ("udf_readlink called\n")); + + if (fe) { + filesize = udf_rw64(fe->inf_len); + } else { + assert(udf_node->efe); + filesize = udf_rw64(efe->inf_len); + } + + /* claim temporary buffers for translation */ + targetbuf = malloc(PATH_MAX+1, M_UDFTEMP, M_WAITOK); + + error = udf_do_readlink(udf_node, filesize, targetbuf, &length); + /* uiomove() to destination */ if (!error) - uiomove(targetbuf, PATH_MAX - targetlen, uio); + uiomove(targetbuf, length, uio); - free(pathbuf, M_UDFTEMP); free(targetbuf, M_UDFTEMP); - free(tmpname, M_UDFTEMP); - return error; } @@ -2143,6 +2176,8 @@ const struct vnodeopv_entry_desc udf_vno { &vop_setattr_desc, udf_setattr }, /* setattr */ /* TODO chflags */ { &vop_read_desc, udf_read }, /* read */ { &vop_write_desc, udf_write }, /* write */ /* WRITE */ + { &vop_fallocate_desc, genfs_eopnotsupp }, /* fallocate */ + { &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */ { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ /* TODO? */ { &vop_ioctl_desc, genfs_enoioctl }, /* ioctl */ /* TODO? */ { &vop_poll_desc, genfs_poll }, /* poll */ /* TODO/OK? */ 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.63.2.1 --- src/sys/fs/union/union_subr.c:1.63 Sun Feb 16 09:50:25 2014 +++ src/sys/fs/union/union_subr.c Sun Aug 10 06:55:54 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.63.2.1 2014/08/10 06:55:54 tls 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.63.2.1 2014/08/10 06:55:54 tls 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); @@ -889,11 +890,15 @@ 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) + 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); Index: src/sys/fs/union/union_vfsops.c diff -u src/sys/fs/union/union_vfsops.c:1.71 src/sys/fs/union/union_vfsops.c:1.71.2.1 --- src/sys/fs/union/union_vfsops.c:1.71 Sun Mar 23 15:21:16 2014 +++ src/sys/fs/union/union_vfsops.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vfsops.c,v 1.71 2014/03/23 15:21:16 hannken Exp $ */ +/* $NetBSD: union_vfsops.c,v 1.71.2.1 2014/08/10 06:55:54 tls 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.71 2014/03/23 15:21:16 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: union_vfsops.c,v 1.71.2.1 2014/08/10 06:55:54 tls Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -119,6 +119,8 @@ union_mount(struct mount *mp, const char int len; size_t size; + if (args == NULL) + return EINVAL; if (*data_len < sizeof *args) return EINVAL; 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.59.2.1 --- src/sys/fs/union/union_vnops.c:1.59 Mon Mar 24 13:42:40 2014 +++ src/sys/fs/union/union_vnops.c Sun Aug 10 06:55:54 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.59.2.1 2014/08/10 06:55:54 tls 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.59.2.1 2014/08/10 06:55:54 tls Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -155,6 +155,8 @@ const struct vnodeopv_entry_desc union_v { &vop_setattr_desc, union_setattr }, /* setattr */ { &vop_read_desc, union_read }, /* read */ { &vop_write_desc, union_write }, /* write */ + { &vop_fallocate_desc, genfs_eopnotsupp }, /* fallocate */ + { &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */ { &vop_ioctl_desc, union_ioctl }, /* ioctl */ { &vop_poll_desc, union_poll }, /* select */ { &vop_revoke_desc, union_revoke }, /* revoke */ @@ -517,6 +519,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); @@ -1383,6 +1387,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); Index: src/sys/fs/unionfs/unionfs_vfsops.c diff -u src/sys/fs/unionfs/unionfs_vfsops.c:1.12 src/sys/fs/unionfs/unionfs_vfsops.c:1.12.2.1 --- src/sys/fs/unionfs/unionfs_vfsops.c:1.12 Sun Mar 23 15:21:16 2014 +++ src/sys/fs/unionfs/unionfs_vfsops.c Sun Aug 10 06:55:54 2014 @@ -89,6 +89,8 @@ unionfs_mount(struct mount *mp, const ch const char *cp; char *xp; + if (args == NULL) + return EINVAL; if (*data_len < sizeof *args) return EINVAL; Index: src/sys/fs/unionfs/unionfs_vnops.c diff -u src/sys/fs/unionfs/unionfs_vnops.c:1.7 src/sys/fs/unionfs/unionfs_vnops.c:1.7.10.1 --- src/sys/fs/unionfs/unionfs_vnops.c:1.7 Mon Nov 5 17:27:39 2012 +++ src/sys/fs/unionfs/unionfs_vnops.c Sun Aug 10 06:55:54 2014 @@ -1820,6 +1820,8 @@ const struct vnodeopv_entry_desc unionfs { &vop_setattr_desc, unionfs_setattr }, /* setattr */ { &vop_read_desc, unionfs_read }, /* read */ { &vop_write_desc, unionfs_write }, /* write */ + { &vop_fallocate_desc, genfs_eopnotsupp }, /* fallocate */ + { &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */ { &vop_ioctl_desc, unionfs_ioctl }, /* ioctl */ { &vop_poll_desc, unionfs_poll }, /* select */ { &vop_revoke_desc, unionfs_revoke }, /* revoke */ Index: src/sys/fs/v7fs/v7fs_extern.c diff -u src/sys/fs/v7fs/v7fs_extern.c:1.2 src/sys/fs/v7fs/v7fs_extern.c:1.2.2.1 --- src/sys/fs/v7fs/v7fs_extern.c:1.2 Sun Mar 23 15:21:16 2014 +++ src/sys/fs/v7fs/v7fs_extern.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: v7fs_extern.c,v 1.2 2014/03/23 15:21:16 hannken Exp $ */ +/* $NetBSD: v7fs_extern.c,v 1.2.2.1 2014/08/10 06:55:54 tls Exp $ */ /*- * Copyright (c) 2004, 2011 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: v7fs_extern.c,v 1.2 2014/03/23 15:21:16 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: v7fs_extern.c,v 1.2.2.1 2014/08/10 06:55:54 tls Exp $"); #if defined _KERNEL_OPT #include "opt_v7fs.h" @@ -65,6 +65,8 @@ const struct vnodeopv_entry_desc v7fs_vn { &vop_setattr_desc, v7fs_setattr }, /* setattr */ { &vop_read_desc, v7fs_read }, /* read */ { &vop_write_desc, v7fs_write }, /* write */ + { &vop_fallocate_desc, genfs_eopnotsupp }, /* fallocate */ + { &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */ { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ { &vop_ioctl_desc, genfs_enoioctl }, /* ioctl */ { &vop_poll_desc, genfs_poll }, /* poll */ @@ -112,6 +114,8 @@ const struct vnodeopv_entry_desc v7fs_sp { &vop_setattr_desc, v7fs_setattr }, /* setattr */ { &vop_read_desc, spec_read }, /* read */ { &vop_write_desc, spec_write }, /* write */ + { &vop_fallocate_desc, spec_fallocate }, /* fallocate */ + { &vop_fdiscard_desc, spec_fdiscard }, /* fdiscard */ { &vop_ioctl_desc, spec_ioctl }, /* ioctl */ { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ { &vop_poll_desc, spec_poll }, /* poll */ @@ -158,6 +162,8 @@ const struct vnodeopv_entry_desc v7fs_fi { &vop_setattr_desc, v7fs_setattr }, /* setattr */ { &vop_read_desc, vn_fifo_bypass }, /* read */ { &vop_write_desc, vn_fifo_bypass }, /* write */ + { &vop_fallocate_desc, vn_fifo_bypass }, /* fallocate */ + { &vop_fdiscard_desc, vn_fifo_bypass }, /* fdiscard */ { &vop_ioctl_desc, vn_fifo_bypass }, /* ioctl */ { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ { &vop_poll_desc, vn_fifo_bypass }, /* poll */ Index: src/sys/fs/v7fs/v7fs_vfsops.c diff -u src/sys/fs/v7fs/v7fs_vfsops.c:1.9 src/sys/fs/v7fs/v7fs_vfsops.c:1.9.2.1 --- src/sys/fs/v7fs/v7fs_vfsops.c:1.9 Sat Nov 23 13:35:36 2013 +++ src/sys/fs/v7fs/v7fs_vfsops.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: v7fs_vfsops.c,v 1.9 2013/11/23 13:35:36 christos Exp $ */ +/* $NetBSD: v7fs_vfsops.c,v 1.9.2.1 2014/08/10 06:55:54 tls Exp $ */ /*- * Copyright (c) 2004, 2011 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: v7fs_vfsops.c,v 1.9 2013/11/23 13:35:36 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: v7fs_vfsops.c,v 1.9.2.1 2014/08/10 06:55:54 tls Exp $"); #if defined _KERNEL_OPT #include "opt_v7fs.h" #endif @@ -88,6 +88,8 @@ v7fs_mount(struct mount *mp, const char DPRINTF("mnt_flag=%x %s\n", mp->mnt_flag, update ? "update" : ""); + if (args == NULL) + return EINVAL; if (*data_len < sizeof(*args)) return EINVAL; Index: src/sys/fs/v7fs/v7fs_vnops.c diff -u src/sys/fs/v7fs/v7fs_vnops.c:1.16 src/sys/fs/v7fs/v7fs_vnops.c:1.16.2.1 --- src/sys/fs/v7fs/v7fs_vnops.c:1.16 Fri Feb 7 15:29:22 2014 +++ src/sys/fs/v7fs/v7fs_vnops.c Sun Aug 10 06:55:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: v7fs_vnops.c,v 1.16 2014/02/07 15:29:22 hannken Exp $ */ +/* $NetBSD: v7fs_vnops.c,v 1.16.2.1 2014/08/10 06:55:54 tls Exp $ */ /*- * Copyright (c) 2004, 2011 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: v7fs_vnops.c,v 1.16 2014/02/07 15:29:22 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: v7fs_vnops.c,v 1.16.2.1 2014/08/10 06:55:54 tls Exp $"); #if defined _KERNEL_OPT #include "opt_v7fs.h" #endif @@ -587,7 +587,7 @@ v7fs_read(void *v) } v7node->update_atime = true; - return error; + return error; } int