svn commit: r366453 - head/sys/ufs/ufs
Author: chs Date: Mon Oct 5 18:17:50 2020 New Revision: 366453 URL: https://svnweb.freebsd.org/changeset/base/366453 Log: ufs: restore uniqueness of st_dev as returned by ufs_stat() switch ufs_stat() to use the same value for st_dev as was used by the previous ufs_getattr() stat path. Submitted by: gallatin Reviewed by: mjg, imp, kib, mckusick Sponsored by: Netflix Differential Revision:https://reviews.freebsd.org/D26596 Modified: head/sys/ufs/ufs/ufs_vnops.c Modified: head/sys/ufs/ufs/ufs_vnops.c == --- head/sys/ufs/ufs/ufs_vnops.cMon Oct 5 18:08:52 2020 (r366452) +++ head/sys/ufs/ufs/ufs_vnops.cMon Oct 5 18:17:50 2020 (r366453) @@ -498,7 +498,7 @@ ufs_stat(struct vop_stat_args *ap) } VI_UNLOCK(vp); - sb->st_dev = vp->v_mount->mnt_stat.f_fsid.val[0]; + sb->st_dev = dev2udev(ITOUMP(ip)->um_dev); sb->st_ino = ip->i_number; sb->st_mode = (ip->i_mode & ~IFMT) | VTTOIF(vp->v_type); sb->st_nlink = ip->i_effnlink; ___ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"
svn commit: r365351 - head/sys/kern
Author: chs Date: Sat Sep 5 00:26:03 2020 New Revision: 365351 URL: https://svnweb.freebsd.org/changeset/base/365351 Log: vfs: avoid exposing partially constructed vnodes If multiple threads race calling vfs_hash_insert() while creating vnodes with the same identity, all of the vnodes which lose the race must be destroyed before any other thread can see them. Previously this was accomplished by the vput() in vfs_hash_insert() resulting in the vnode's VOP_INACTIVE() method calling vgone() before the vnode lock was unlocked, but at some point changes to the the vnode refcount/inactive logic have caused that to no longer work, leading to crashes, so instead vfs_hash_insert() must call vgone() itself before calling vput() on vnodes which lose the race. Reviewed by: mjg, kib Sponsored by: Netflix Differential Revision:https://reviews.freebsd.org/D26291 Modified: head/sys/kern/vfs_hash.c Modified: head/sys/kern/vfs_hash.c == --- head/sys/kern/vfs_hash.cSat Sep 5 00:20:32 2020(r365350) +++ head/sys/kern/vfs_hash.cSat Sep 5 00:26:03 2020(r365351) @@ -172,6 +172,7 @@ vfs_hash_insert(struct vnode *vp, u_int hash, int flag rw_wlock(_hash_lock); LIST_INSERT_HEAD(_hash_side, vp, v_hashlist); rw_wunlock(_hash_lock); + vgone(vp); vput(vp); if (!error) *vpp = vp2; ___ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"
svn commit: r365056 - head/sbin/fsck_ffs
Author: chs Date: Tue Sep 1 18:50:26 2020 New Revision: 365056 URL: https://svnweb.freebsd.org/changeset/base/365056 Log: Move all of the error prints in readsb() from stderr to stdout. The only output from fsck that should go to stderr is the usage message. if setup() fails then exit with EEXIT rather than 0. Reviewed by: mckusick Sponsored by: Netflix Modified: head/sbin/fsck_ffs/main.c head/sbin/fsck_ffs/setup.c Modified: head/sbin/fsck_ffs/main.c == --- head/sbin/fsck_ffs/main.c Tue Sep 1 16:20:42 2020(r365055) +++ head/sbin/fsck_ffs/main.c Tue Sep 1 18:50:26 2020(r365056) @@ -408,7 +408,7 @@ checkfilesys(char *filesys) case 0: if (preen) pfatal("CAN'T CHECK FILE SYSTEM."); - return (0); + return (EEXIT); case -1: clean: pwarn("clean, %ld free ", (long)(sblock.fs_cstotal.cs_nffree + Modified: head/sbin/fsck_ffs/setup.c == --- head/sbin/fsck_ffs/setup.c Tue Sep 1 16:20:42 2020(r365055) +++ head/sbin/fsck_ffs/setup.c Tue Sep 1 18:50:26 2020(r365056) @@ -339,15 +339,15 @@ readsb(int listerr) return (0); case ENOENT: if (bflag) - fprintf(stderr, "%jd is not a file system " + printf("%jd is not a file system " "superblock\n", super / dev_bsize); else - fprintf(stderr, "Cannot find file system " + printf("Cannot find file system " "superblock\n"); return (0); case EIO: default: - fprintf(stderr, "I/O error reading %jd\n", + printf("I/O error reading %jd\n", super / dev_bsize); return (0); } ___ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"
svn commit: r363377 - head/tests/sys/kern
Author: chs Date: Mon Jul 20 20:36:32 2020 New Revision: 363377 URL: https://svnweb.freebsd.org/changeset/base/363377 Log: add a few tests for sendfile. Reviewed by: markj Sponsored by: Netflix Differential Revision:https://reviews.freebsd.org/D25431 Added: head/tests/sys/kern/sendfile_helper.c (contents, props changed) head/tests/sys/kern/sendfile_test.sh (contents, props changed) Modified: head/tests/sys/kern/Makefile Modified: head/tests/sys/kern/Makefile == --- head/tests/sys/kern/MakefileMon Jul 20 20:19:56 2020 (r363376) +++ head/tests/sys/kern/MakefileMon Jul 20 20:36:32 2020 (r363377) @@ -29,6 +29,7 @@ ATF_TESTS_SH+=coredump_phnum_test ATF_TESTS_SH+= sonewconn_overflow TEST_METADATA.sonewconn_overflow+= required_programs="python" TEST_METADATA.sonewconn_overflow+= required_user="root" +ATF_TESTS_SH+= sendfile_test ${PACKAGE}FILES+= sonewconn_overflow.py ${PACKAGE}FILESMODE_sonewconn_overflow.py=0555 @@ -36,6 +37,7 @@ ${PACKAGE}FILESMODE_sonewconn_overflow.py=0555 BINDIR=${TESTSDIR} PROGS+=coredump_phnum_helper PROGS+=pdeathsig_helper +PROGS+=sendfile_helper CFLAGS.sys_getrandom+= -I${SRCTOP}/sys/contrib/zstd/lib LIBADD.sys_getrandom+= zstd @@ -44,6 +46,7 @@ LIBADD.sys_getrandom+=pthread LIBADD.ptrace_test+= pthread LIBADD.unix_seqpacket_test+= pthread LIBADD.kcov+= pthread +LIBADD.sendfile_helper+= pthread NETBSD_ATF_TESTS_C+= lockf_test NETBSD_ATF_TESTS_C+= mqueue_test Added: head/tests/sys/kern/sendfile_helper.c == --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/tests/sys/kern/sendfile_helper.c Mon Jul 20 20:36:32 2020 (r363377) @@ -0,0 +1,147 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2020 Netflix, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *notice, this list of conditions and the following disclaimer in the + *documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int ls; +static char buf[1024*1024]; +static volatile bool accept_done = false; +static volatile bool read_done = false; + +static void * +server(void *arg) +{ + struct sockaddr_in sin; + ssize_t rv; + socklen_t slen; + int ss; + ssize_t readlen = (uintptr_t)arg; + + slen = sizeof(sin); + ss = accept(ls, (void *), ); + if (ss < 0) + err(1, "accept ls"); + + accept_done = true; + + do { + rv = read(ss, buf, sizeof(buf)); + if (rv == -1) + err(2, "read receiver"); + if (rv == 0) + break; + readlen -= rv; + } while (readlen != 0); + + read_done = true; + + return NULL; +} + +int +main(int argc, char **argv) +{ + pthread_t pt; + struct sockaddr_in sin; + off_t start, len; + socklen_t slen; + int fd, cs, on, flags, error; + + if (argc != 5) + errx(1, "usage: %s", + getprogname()); + + start = strtoull(argv[2], NULL, 0); + len = strtoull(argv[3], NULL, 0); + flags = strtoul(argv[4], NULL, 0); + + fd = open(argv[1], O_RDONLY); + if (fd < 0) + err(1, "open"); + + ls = socket(PF_INET, SOCK_STREAM, 0);
svn commit: r363296 - head/sys/vm
Author: chs Date: Fri Jul 17 23:10:35 2020 New Revision: 363296 URL: https://svnweb.freebsd.org/changeset/base/363296 Log: Fix vnode_pager handling of read ahead/behind pages when a disk read fails. Rather than marking the read ahead/behind pages valid even though they were not initialized, free them using the new function vm_page_free_invalid(). Reviewed by: markj, kib Sponsored by: Netflix Differential Revision:https://reviews.freebsd.org/D25430 Modified: head/sys/vm/vnode_pager.c Modified: head/sys/vm/vnode_pager.c == --- head/sys/vm/vnode_pager.c Fri Jul 17 23:09:36 2020(r363295) +++ head/sys/vm/vnode_pager.c Fri Jul 17 23:10:35 2020(r363296) @@ -1139,6 +1139,21 @@ vnode_pager_generic_getpages_done(struct buf *bp) bp->b_data = unmapped_buf; } + /* +* If the read failed, we must free any read ahead/behind pages here. +* The requested pages are freed by the caller (for sync requests) +* or by the bp->b_pgiodone callback (for async requests). +*/ + if (error != 0) { + VM_OBJECT_WLOCK(object); + for (i = 0; i < bp->b_pgbefore; i++) + vm_page_free_invalid(bp->b_pages[i]); + for (i = bp->b_npages - bp->b_pgafter; i < bp->b_npages; i++) + vm_page_free_invalid(bp->b_pages[i]); + VM_OBJECT_WUNLOCK(object); + return (error); + } + /* Read lock to protect size. */ VM_OBJECT_RLOCK(object); for (i = 0, tfoff = IDX_TO_OFF(bp->b_pages[0]->pindex); ___ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"
svn commit: r363295 - head/sys/vm
Author: chs Date: Fri Jul 17 23:09:36 2020 New Revision: 363295 URL: https://svnweb.freebsd.org/changeset/base/363295 Log: Add a new function vm_page_free_invalid() for freeing invalid pages that might be wired. If the page is wired then it cannot be freed now, but the thread that eventually unwires it will free it at that point. Reviewed by: markj, kib Sponsored by: Netflix Differential Revision:https://reviews.freebsd.org/D25430 Modified: head/sys/vm/vm_page.c head/sys/vm/vm_page.h Modified: head/sys/vm/vm_page.c == --- head/sys/vm/vm_page.c Fri Jul 17 23:08:01 2020(r363294) +++ head/sys/vm/vm_page.c Fri Jul 17 23:09:36 2020(r363295) @@ -1362,6 +1362,31 @@ vm_page_readahead_finish(vm_page_t m) } /* + * Destroy the identity of an invalid page and free it if possible. + * This is intended to be used when reading a page from backing store fails. + */ +void +vm_page_free_invalid(vm_page_t m) +{ + + KASSERT(vm_page_none_valid(m), ("page %p is valid", m)); + KASSERT(!pmap_page_is_mapped(m), ("page %p is mapped", m)); + vm_page_assert_xbusied(m); + KASSERT(m->object != NULL, ("page %p has no object", m)); + VM_OBJECT_ASSERT_WLOCKED(m->object); + + /* +* If someone has wired this page while the object lock +* was not held, then the thread that unwires is responsible +* for freeing the page. Otherwise just free the page now. +* The wire count of this unmapped page cannot change while +* we have the page xbusy and the page's object wlocked. +*/ + if (vm_page_remove(m)) + vm_page_free(m); +} + +/* * vm_page_sleep_if_busy: * * Sleep and release the object lock if the page is busied. Modified: head/sys/vm/vm_page.h == --- head/sys/vm/vm_page.h Fri Jul 17 23:08:01 2020(r363294) +++ head/sys/vm/vm_page.h Fri Jul 17 23:09:36 2020(r363295) @@ -629,6 +629,7 @@ void vm_page_deactivate_noreuse(vm_page_t); void vm_page_dequeue(vm_page_t m); void vm_page_dequeue_deferred(vm_page_t m); vm_page_t vm_page_find_least(vm_object_t, vm_pindex_t); +void vm_page_free_invalid(vm_page_t); vm_page_t vm_page_getfake(vm_paddr_t paddr, vm_memattr_t memattr); void vm_page_initfake(vm_page_t m, vm_paddr_t paddr, vm_memattr_t memattr); int vm_page_insert (vm_page_t, vm_object_t, vm_pindex_t); ___ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"
svn commit: r363294 - head/sys/vm
Author: chs Date: Fri Jul 17 23:08:01 2020 New Revision: 363294 URL: https://svnweb.freebsd.org/changeset/base/363294 Log: Revert my change from r361855 in favor of a better fix. Reviewed by: markj, kib Sponsored by: Netflix Differential Revision:https://reviews.freebsd.org/D25430 Modified: head/sys/vm/vnode_pager.c Modified: head/sys/vm/vnode_pager.c == --- head/sys/vm/vnode_pager.c Fri Jul 17 22:54:39 2020(r363293) +++ head/sys/vm/vnode_pager.c Fri Jul 17 23:08:01 2020(r363294) @@ -1150,30 +1150,28 @@ vnode_pager_generic_getpages_done(struct buf *bp) if (mt == bogus_page) continue; - if (error == 0) { - if (nextoff <= object->un_pager.vnp.vnp_size) { - /* -* Read filled up entire page. -*/ - vm_page_valid(mt); - KASSERT(mt->dirty == 0, - ("%s: page %p is dirty", __func__, mt)); - KASSERT(!pmap_page_is_mapped(mt), - ("%s: page %p is mapped", __func__, mt)); - } else { - /* -* Read did not fill up entire page. -* -* Currently we do not set the entire page -* valid, we just try to clear the piece that -* we couldn't read. -*/ - vm_page_set_valid_range(mt, 0, - object->un_pager.vnp.vnp_size - tfoff); - KASSERT((mt->dirty & vm_page_bits(0, - object->un_pager.vnp.vnp_size - tfoff)) == - 0, ("%s: page %p is dirty", __func__, mt)); - } + if (nextoff <= object->un_pager.vnp.vnp_size) { + /* +* Read filled up entire page. +*/ + vm_page_valid(mt); + KASSERT(mt->dirty == 0, + ("%s: page %p is dirty", __func__, mt)); + KASSERT(!pmap_page_is_mapped(mt), + ("%s: page %p is mapped", __func__, mt)); + } else { + /* +* Read did not fill up entire page. +* +* Currently we do not set the entire page valid, +* we just try to clear the piece that we couldn't +* read. +*/ + vm_page_set_valid_range(mt, 0, + object->un_pager.vnp.vnp_size - tfoff); + KASSERT((mt->dirty & vm_page_bits(0, + object->un_pager.vnp.vnp_size - tfoff)) == 0, + ("%s: page %p is dirty", __func__, mt)); } if (i < bp->b_pgbefore || i >= bp->b_npages - bp->b_pgafter) ___ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"
svn commit: r362292 - in head/sys/ufs: ffs ufs
Author: chs Date: Wed Jun 17 23:39:52 2020 New Revision: 362292 URL: https://svnweb.freebsd.org/changeset/base/362292 Log: Move all of the functions in ffs_subr.c that are only used by the ufs kernel module from that file into ffs_vfsops.c. This fixes the build for kernel configs that don't include FFS. PR: 247256 Submitted by: glebius Reviewed by: mckusick (earlier version) Sponsored by: Netflix Differential Revision:https://reviews.freebsd.org/D25285 Modified: head/sys/ufs/ffs/ffs_extern.h head/sys/ufs/ffs/ffs_subr.c head/sys/ufs/ffs/ffs_vfsops.c head/sys/ufs/ufs/ufs_vnops.c Modified: head/sys/ufs/ffs/ffs_extern.h == --- head/sys/ufs/ffs/ffs_extern.h Wed Jun 17 21:51:32 2020 (r362291) +++ head/sys/ufs/ffs/ffs_extern.h Wed Jun 17 23:39:52 2020 (r362292) @@ -61,7 +61,6 @@ int ffs_balloc_ufs1(struct vnode *a_vp, off_t a_starto struct ucred *a_cred, int a_flags, struct buf **a_bpp); intffs_balloc_ufs2(struct vnode *a_vp, off_t a_startoffset, int a_size, struct ucred *a_cred, int a_flags, struct buf **a_bpp); -intffs_blkatoff(struct vnode *, off_t, char **, struct buf **); void ffs_blkfree(struct ufsmount *, struct fs *, struct vnode *, ufs2_daddr_t, long, ino_t, enum vtype, struct workhead *, u_long); ufs2_daddr_t ffs_blkpref_ufs1(struct inode *, ufs_lbn_t, int, ufs1_daddr_t *); @@ -69,7 +68,6 @@ ufs2_daddr_t ffs_blkpref_ufs2(struct inode *, ufs_lbn_ void ffs_blkrelease_finish(struct ufsmount *, u_long); u_long ffs_blkrelease_start(struct ufsmount *, struct vnode *, ino_t); uint32_t ffs_calc_sbhash(struct fs *); -intffs_check_blkno(struct mount *, ino_t, ufs2_daddr_t, int); intffs_checkfreefile(struct fs *, struct vnode *, ino_t); void ffs_clrblock(struct fs *, u_char *, ufs1_daddr_t); void ffs_clusteracct(struct fs *, struct cg *, ufs1_daddr_t, int); @@ -84,7 +82,6 @@ int ffs_getcg(struct fs *, struct vnode *, u_int, int, struct cg **); intffs_isblock(struct fs *, u_char *, ufs1_daddr_t); intffs_isfreeblock(struct fs *, u_char *, ufs1_daddr_t); -intffs_load_inode(struct buf *, struct inode *, struct fs *, ino_t); void ffs_oldfscompat_write(struct fs *, struct ufsmount *); intffs_own_mount(const struct mount *mp); intffs_reallocblks(struct vop_reallocblks_args *); Modified: head/sys/ufs/ffs/ffs_subr.c == --- head/sys/ufs/ffs/ffs_subr.c Wed Jun 17 21:51:32 2020(r362291) +++ head/sys/ufs/ffs/ffs_subr.c Wed Jun 17 23:39:52 2020(r362292) @@ -67,7 +67,6 @@ struct malloc_type; #include #include #include -#include #include #include @@ -81,216 +80,6 @@ struct malloc_type; #define UFS_FREE(ptr, type) free(ptr, type) #define UFS_TIME time_second -/* - * Return buffer with the contents of block "offset" from the beginning of - * directory "ip". If "res" is non-zero, fill it in with a pointer to the - * remaining space in the directory. - */ -int -ffs_blkatoff(struct vnode *vp, off_t offset, char **res, struct buf **bpp) -{ - struct inode *ip; - struct fs *fs; - struct buf *bp; - ufs_lbn_t lbn; - int bsize, error; - - ip = VTOI(vp); - fs = ITOFS(ip); - lbn = lblkno(fs, offset); - bsize = blksize(fs, ip, lbn); - - *bpp = NULL; - error = bread(vp, lbn, bsize, NOCRED, ); - if (error) { - return (error); - } - if (res) - *res = (char *)bp->b_data + blkoff(fs, offset); - *bpp = bp; - return (0); -} - -/* - * Load up the contents of an inode and copy the appropriate pieces - * to the incore copy. - */ -int -ffs_load_inode(struct buf *bp, struct inode *ip, struct fs *fs, ino_t ino) -{ - struct ufs1_dinode *dip1; - struct ufs2_dinode *dip2; - int error; - - if (I_IS_UFS1(ip)) { - dip1 = ip->i_din1; - *dip1 = - *((struct ufs1_dinode *)bp->b_data + ino_to_fsbo(fs, ino)); - ip->i_mode = dip1->di_mode; - ip->i_nlink = dip1->di_nlink; - ip->i_effnlink = dip1->di_nlink; - ip->i_size = dip1->di_size; - ip->i_flags = dip1->di_flags; - ip->i_gen = dip1->di_gen; - ip->i_uid = dip1->di_uid; - ip->i_gid = dip1->di_gid; - return (0); - } - dip2 = ((struct ufs2_dinode *)bp->b_data + ino_to_fsbo(fs, ino)); - if ((error = ffs_verify_dinode_ckhash(fs, dip2)) != 0 && - !ffs_fsfail_cleanup(ITOUMP(ip), error)) { - printf("%s: inode %jd: check-hash failed\n", fs->fs_fsmnt, - (intmax_t)ino); - return (error); - } - *ip->i_din2 = *dip2; - dip2 = ip->i_din2; -
svn commit: r361855 - head/sys/vm
Author: chs Date: Sat Jun 6 00:47:59 2020 New Revision: 361855 URL: https://svnweb.freebsd.org/changeset/base/361855 Log: Don't mark pages as valid if reading the contents from disk fails. Instead, just skip marking pages valid if the read fails. Future attempts to access such pages will notice that they are not marked valid and try to read them from disk again. Reviewed by: kib, markj Sponsored by: Netflix Differential Revision:https://reviews.freebsd.org/D25138 Modified: head/sys/vm/vnode_pager.c Modified: head/sys/vm/vnode_pager.c == --- head/sys/vm/vnode_pager.c Sat Jun 6 00:40:02 2020(r361854) +++ head/sys/vm/vnode_pager.c Sat Jun 6 00:47:59 2020(r361855) @@ -1150,28 +1150,30 @@ vnode_pager_generic_getpages_done(struct buf *bp) if (mt == bogus_page) continue; - if (nextoff <= object->un_pager.vnp.vnp_size) { - /* -* Read filled up entire page. -*/ - vm_page_valid(mt); - KASSERT(mt->dirty == 0, - ("%s: page %p is dirty", __func__, mt)); - KASSERT(!pmap_page_is_mapped(mt), - ("%s: page %p is mapped", __func__, mt)); - } else { - /* -* Read did not fill up entire page. -* -* Currently we do not set the entire page valid, -* we just try to clear the piece that we couldn't -* read. -*/ - vm_page_set_valid_range(mt, 0, - object->un_pager.vnp.vnp_size - tfoff); - KASSERT((mt->dirty & vm_page_bits(0, - object->un_pager.vnp.vnp_size - tfoff)) == 0, - ("%s: page %p is dirty", __func__, mt)); + if (error == 0) { + if (nextoff <= object->un_pager.vnp.vnp_size) { + /* +* Read filled up entire page. +*/ + vm_page_valid(mt); + KASSERT(mt->dirty == 0, + ("%s: page %p is dirty", __func__, mt)); + KASSERT(!pmap_page_is_mapped(mt), + ("%s: page %p is mapped", __func__, mt)); + } else { + /* +* Read did not fill up entire page. +* +* Currently we do not set the entire page +* valid, we just try to clear the piece that +* we couldn't read. +*/ + vm_page_set_valid_range(mt, 0, + object->un_pager.vnp.vnp_size - tfoff); + KASSERT((mt->dirty & vm_page_bits(0, + object->un_pager.vnp.vnp_size - tfoff)) == + 0, ("%s: page %p is dirty", __func__, mt)); + } } if (i < bp->b_pgbefore || i >= bp->b_npages - bp->b_pgafter) ___ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"
svn commit: r361852 - head/sys/kern
Author: chs Date: Sat Jun 6 00:02:50 2020 New Revision: 361852 URL: https://svnweb.freebsd.org/changeset/base/361852 Log: Fix hang due to missing unbusy in sendfile when an async data I/O fails. r359473 removed the page unbusy logic from sendfile_iodone() because when vm_pager_get_pages_async() would return an error after failing to start the async I/O (eg. because VOP_BMAP failed), sendfile_swapin() would also unbusy the pages, and it was wrong to unbusy twice. However this breaks the case where vm_pager_get_pages_async() succeeds in starting an async I/O and the async I/O is what fails. In this case, sendfile_iodone() must unbusy the pages, and because sendfile_iodone() doesn't know which case it is in, sendfile_iodone() must always unbusy pages and relookup pages which have been substituted with bogus_page, which in turn means that sendfile_swapin() must never do unbusy or relookup for pages which have been given to vm_pager_get_pages_async(), even if there is an error. Reviewed by: kib, markj Sponsored by: Netflix Differential Revision:https://reviews.freebsd.org/D25136 Modified: head/sys/kern/kern_sendfile.c Modified: head/sys/kern/kern_sendfile.c == --- head/sys/kern/kern_sendfile.c Fri Jun 5 22:07:10 2020 (r361851) +++ head/sys/kern/kern_sendfile.c Sat Jun 6 00:02:50 2020 (r361852) @@ -292,36 +292,30 @@ sendfile_iodone(void *arg, vm_page_t *pa, int count, i struct socket *so; int i; - if (error != 0) { + if (error != 0) sfio->error = error; - /* -* Restore of the pg[] elements is done by -* sendfile_swapin(). -*/ - } else { - /* -* Restore the valid page pointers. They are already -* unbusied, but still wired. For error != 0 case, -* sendfile_swapin() handles unbusy. -* -* XXXKIB since pages are only wired, and we do not -* own the object lock, other users might have -* invalidated them in meantime. Similarly, after we -* unbusied the swapped-in pages, they can become -* invalid under us. -*/ - MPASS(count == 0 || pa[0] != bogus_page); - for (i = 0; i < count; i++) { - if (pa[i] == bogus_page) { - sfio->pa[(pa[0]->pindex - sfio->pindex0) + i] = - pa[i] = vm_page_relookup(sfio->obj, - pa[0]->pindex + i); - KASSERT(pa[i] != NULL, - ("%s: page %p[%d] disappeared", - __func__, pa, i)); - } else { - vm_page_xunbusy_unchecked(pa[i]); - } + + /* +* Restore the valid page pointers. They are already +* unbusied, but still wired. +* +* XXXKIB since pages are only wired, and we do not +* own the object lock, other users might have +* invalidated them in meantime. Similarly, after we +* unbusied the swapped-in pages, they can become +* invalid under us. +*/ + MPASS(count == 0 || pa[0] != bogus_page); + for (i = 0; i < count; i++) { + if (pa[i] == bogus_page) { + sfio->pa[(pa[0]->pindex - sfio->pindex0) + i] = + pa[i] = vm_page_relookup(sfio->obj, + pa[0]->pindex + i); + KASSERT(pa[i] != NULL, + ("%s: page %p[%d] disappeared", + __func__, pa, i)); + } else { + vm_page_xunbusy_unchecked(pa[i]); } } @@ -534,22 +528,12 @@ sendfile_swapin(vm_object_t obj, struct sf_io *sfio, i sendfile_iowait(sfio, "sferrio"); /* -* Perform full pages recovery before returning EIO. +* Do remaining pages recovery before returning EIO. * Pages from 0 to npages are wired. -* Pages from (i + 1) to (i + count - 1) may be -* substituted to bogus page, and not busied. -* Pages from (i + count) to (i + count1 - 1) are -* not busied. -* Rest of the pages from i to npages are busied. +* Pages from (i + count1) to npages are busied. */ for (j = 0; j < npages; j++) { - if (j >= i + count && j < i + count1) -
svn commit: r361491 - in head/sys: geom kern sys ufs/ffs ufs/ufs
Author: chs Date: Mon May 25 23:47:31 2020 New Revision: 361491 URL: https://svnweb.freebsd.org/changeset/base/361491 Log: This commit enables a UFS filesystem to do a forcible unmount when the underlying media fails or becomes inaccessible. For example when a USB flash memory card hosting a UFS filesystem is unplugged. The strategy for handling disk I/O errors when soft updates are enabled is to stop writing to the disk of the affected file system but continue to accept I/O requests and report that all future writes by the file system to that disk actually succeed. Then initiate an asynchronous forced unmount of the affected file system. There are two cases for disk I/O errors: - ENXIO, which means that this disk is gone and the lower layers of the storage stack already guarantee that no future I/O to this disk will succeed. - EIO (or most other errors), which means that this particular I/O request has failed but subsequent I/O requests to this disk might still succeed. For ENXIO, we can just clear the error and continue, because we know that the file system cannot affect the on-disk state after we see this error. For EIO or other errors, we arrange for the geom_vfs layer to reject all future I/O requests with ENXIO just like is done when the geom_vfs is orphaned. In both cases, the file system code can just clear the error and proceed with the forcible unmount. This new treatment of I/O errors is needed for writes of any buffer that is involved in a dependency. Most dependencies are described by a structure attached to the buffer's b_dep field. But some are created and processed as a result of the completion of the dependencies attached to the buffer. Clearing of some dependencies require a read. For example if there is a dependency that requires an inode to be written, the disk block containing that inode must be read, the updated inode copied into place in that buffer, and the buffer then written back to disk. Often the needed buffer is already in memory and can be used. But if it needs to be read from the disk, the read will fail, so we fabricate a buffer full of zeroes and pretend that the read succeeded. This zero'ed buffer can be updated and written back to disk. The only case where a buffer full of zeros causes the code to do the wrong thing is when reading an inode buffer containing an inode that still has an inode dependency in memory that will reinitialize the effective link count (i_effnlink) based on the actual link count (i_nlink) that we read. To handle this case we now store the i_nlink value that we wrote in the inode dependency so that it can be restored into the zero'ed buffer thus keeping the tracking of the inode link count consistent. Because applications depend on knowing when an attempt to write their data to stable storage has failed, the fsync(2) and msync(2) system calls need to return errors if data fails to be written to stable storage. So these operations return ENXIO for every call made on files in a file system where we have otherwise been ignoring I/O errors. Coauthered by: mckusick Reviewed by: kib Tested by: Peter Holm Approved by: mckusick (mentor) Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D24088 Modified: head/sys/geom/geom_vfs.c head/sys/kern/vfs_bio.c head/sys/sys/buf.h head/sys/ufs/ffs/ffs_alloc.c head/sys/ufs/ffs/ffs_balloc.c head/sys/ufs/ffs/ffs_extern.h head/sys/ufs/ffs/ffs_inode.c head/sys/ufs/ffs/ffs_softdep.c head/sys/ufs/ffs/ffs_subr.c head/sys/ufs/ffs/ffs_vfsops.c head/sys/ufs/ffs/ffs_vnops.c head/sys/ufs/ffs/softdep.h head/sys/ufs/ufs/ufs_vnops.c head/sys/ufs/ufs/ufsmount.h Modified: head/sys/geom/geom_vfs.c == --- head/sys/geom/geom_vfs.cMon May 25 23:20:33 2020(r361490) +++ head/sys/geom/geom_vfs.cMon May 25 23:47:31 2020(r361491) @@ -55,6 +55,7 @@ struct g_vfs_softc { struct bufobj *sc_bo; int sc_active; int sc_orphaned; + int sc_enxio_active; }; static struct buf_ops __g_vfs_bufops = { @@ -139,9 +140,14 @@ g_vfs_done(struct bio *bip) cp = bip->bio_from; sc = cp->geom->softc; - if (bip->bio_error && bip->bio_error != EOPNOTSUPP) + if (bip->bio_error != 0 && bip->bio_error != EOPNOTSUPP) { + if ((bp->b_xflags & BX_CVTENXIO) != 0) + sc->sc_enxio_active = 1; + if (sc->sc_enxio_active) + bip->bio_error = ENXIO; g_print_bio("g_vfs_done():", bip, "error = %d", bip->bio_error); + } bp->b_error = bip->bio_error; bp->b_ioflags = bip->bio_flags; if (bip->bio_error) @@ -172,7 +178,7 @@
svn commit: r360559 - head/sbin/dumpfs
Author: chs Date: Sat May 2 00:10:25 2020 New Revision: 360559 URL: https://svnweb.freebsd.org/changeset/base/360559 Log: Print the fs last-mounted time too. Reviewed by: mckusick Approved by: mckusick (mentor) Sponsored by: Netflix Modified: head/sbin/dumpfs/dumpfs.c Modified: head/sbin/dumpfs/dumpfs.c == --- head/sbin/dumpfs/dumpfs.c Sat May 2 00:08:44 2020(r360558) +++ head/sbin/dumpfs/dumpfs.c Sat May 2 00:10:25 2020(r360559) @@ -156,7 +156,7 @@ dumpfsid(void) static int dumpfs(const char *name) { - time_t fstime; + time_t fstime, fsmtime; int64_t fssize; int32_t fsflags; int i; @@ -165,8 +165,10 @@ dumpfs(const char *name) case 2: fssize = afs.fs_size; fstime = afs.fs_time; - printf("magic\t%x (UFS2)\ttime\t%s", - afs.fs_magic, ctime()); + fsmtime = afs.fs_mtime; + printf("magic\t%x (UFS2)\n", afs.fs_magic); + printf("last mounted time\t%s", ctime()); + printf("last modified time\t%s", ctime()); printf("superblock location\t%jd\tid\t[ %08x %08x ]\n", (intmax_t)afs.fs_sblockloc, afs.fs_id[0], afs.fs_id[1]); printf("ncg\t%d\tsize\t%jd\tblocks\t%jd\n", ___ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"
Re: svn commit: r358597 - head/sys/kern
On Fri, Mar 13, 2020 at 07:48:17PM -0400, Mark Johnston wrote: > On Wed, Mar 04, 2020 at 12:22:51AM +0000, Chuck Silvers wrote: > > Author: chs > > Date: Wed Mar 4 00:22:50 2020 > > New Revision: 358597 > > URL: https://svnweb.freebsd.org/changeset/base/358597 > > > > Log: > > if vm_pager_get_pages_async() returns an error, release the sfio->nios > > refcount that we took earlier that represents the I/O that ended up > > not being started. > > I think a larger bug is that getpages_async is not consistent about > whether it invokes the completion callback in synchronous error cases. > For instance, vop_stdgetpages_async() always calls it, as does > ffs_getpages_async() when the filesystem fragment size is larger than > the page size. But vnode_pager_generic_getpages() does not. So if one > is using sendfile on a filesystem that does not implement > getpages_async, an error will cause sendfile_swapin() to unbusy the > input pages multiple times, and release the sfio refcount twice when it > should be done just once. ah yes, you're right. I was only looking at the path we actually hit. I think the simplest way to resolve this would be to change vnode_pager_generic_getpages() in the async case to always call the iodone callback and always return 0. (in the sync case vnode_pager_generic_getpages() would continue to return an error code if an error is encountered.) vm_pager_get_pages_async() could then be changed to return void since after the avoid changes it would always return 0. swap_pager_getpages_async() already always calls the iodone callback but it would return void too after the above changes. If that is agreeable to you and Gleb then I'll make the changes. -Chuck ___ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"
svn commit: r358812 - head/sys/ufs/ffs
Author: chs Date: Mon Mar 9 15:55:13 2020 New Revision: 358812 URL: https://svnweb.freebsd.org/changeset/base/358812 Log: Use the devfs vnode rather than the mntfs vnode for permissions checks. I missed this one in r358714. Reported by: pho Reviewed by: mckusick Approved by: imp (mentor) Sponsored by: Netflix Modified: head/sys/ufs/ffs/ffs_suspend.c Modified: head/sys/ufs/ffs/ffs_suspend.c == --- head/sys/ufs/ffs/ffs_suspend.c Mon Mar 9 15:48:53 2020 (r358811) +++ head/sys/ufs/ffs/ffs_suspend.c Mon Mar 9 15:55:13 2020 (r358812) @@ -196,10 +196,10 @@ ffs_susp_suspend(struct mount *mp) * device. The permissions can change after we unlock the vnode; * it's harmless. */ - vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY); - error = VOP_ACCESS(ump->um_devvp, VREAD | VWRITE, + vn_lock(ump->um_odevvp, LK_EXCLUSIVE | LK_RETRY); + error = VOP_ACCESS(ump->um_odevvp, VREAD | VWRITE, curthread->td_ucred, curthread); - VOP_UNLOCK(ump->um_devvp); + VOP_UNLOCK(ump->um_odevvp); if (error != 0) return (error); #ifdef MAC ___ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"
svn commit: r358714 - in head/sys: conf fs/mntfs kern sys ufs/ffs ufs/ufs
Author: chs Date: Fri Mar 6 18:41:37 2020 New Revision: 358714 URL: https://svnweb.freebsd.org/changeset/base/358714 Log: Add a new "mntfs" pseudo file system which provides private device vnodes for file systems to safely access their disk devices, and adapt FFS to use it. Also add a new BO_NOBUFS flag to allow enforcing that file systems using mntfs vnodes do not accidentally use the original devfs vnode to create buffers. Reviewed by: kib, mckusick Approved by: imp (mentor) Sponsored by: Netflix Differential Revision:https://reviews.freebsd.org/D23787 Added: head/sys/fs/mntfs/ head/sys/fs/mntfs/mntfs_vnops.c (contents, props changed) Modified: head/sys/conf/files head/sys/kern/vfs_subr.c head/sys/sys/bufobj.h head/sys/sys/mount.h head/sys/ufs/ffs/ffs_alloc.c head/sys/ufs/ffs/ffs_vfsops.c head/sys/ufs/ufs/ufsmount.h Modified: head/sys/conf/files == --- head/sys/conf/files Fri Mar 6 17:24:51 2020(r358713) +++ head/sys/conf/files Fri Mar 6 18:41:37 2020(r358714) @@ -3479,6 +3479,7 @@ fs/fuse/fuse_main.c optional fusefs fs/fuse/fuse_node.coptional fusefs fs/fuse/fuse_vfsops.c optional fusefs fs/fuse/fuse_vnops.c optional fusefs +fs/mntfs/mntfs_vnops.c standard fs/msdosfs/msdosfs_conv.c optional msdosfs fs/msdosfs/msdosfs_denode.coptional msdosfs fs/msdosfs/msdosfs_fat.c optional msdosfs Added: head/sys/fs/mntfs/mntfs_vnops.c == --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/fs/mntfs/mntfs_vnops.c Fri Mar 6 18:41:37 2020 (r358714) @@ -0,0 +1,95 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2020 Netflix, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *notice, this list of conditions and the following disclaimer in the + *documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include + +/* + * The "mntfs" VCHR vnodes implemented here provide a safe way for file systems + * to access their disk devices. Using the normal devfs vnode has the problem + * that if the device disappears, the devfs vnode is vgone'd as part of + * removing it from the application-visible namespace, and some file systems + * (notably FFS with softdep) get very unhappy if their dirty buffers are + * invalidated out from under them. By using a separate, private vnode, + * file systems are able to clean up their buffer state in a controlled fashion + * when the underlying device disappears. + */ + +static int +mntfs_reclaim(struct vop_reclaim_args *ap) +{ + struct vnode *vp = ap->a_vp; + + dev_rel(vp->v_rdev); + return (0); +} + +struct vop_vector mntfs_vnodeops = { + .vop_default = _vnodeops, + + .vop_fsync =vop_stdfsync, + .vop_strategy = VOP_PANIC, + .vop_reclaim = mntfs_reclaim, +}; +VFS_VOP_VECTOR_REGISTER(mntfs_vnodeops); + +/* + * Allocate a private VCHR vnode for use by a mounted fs. + * The underlying device will be the same as for the given vnode. + * This mntfs vnode must be freed with mntfs_freevp() rather than just + * releasing the reference. + */ +struct vnode * +mntfs_allocvp(struct mount *mp, struct vnode *ovp) +{ + struct vnode *vp; + struct cdev *dev; + + ASSERT_VOP_ELOCKED(ovp, __func__); + + dev = ovp->v_rdev; + + getnewvnode("mntfs", mp, _vnodeops, ); + vp->v_type = VCHR; + vp->v_data = NULL; + dev_ref(dev); + vp->v_rdev = dev; + + return (vp); +} + +void +mntfs_freevp(struct vnode *vp) +{ + + vgone(vp); + vrele(vp); +} Modified:
svn commit: r358597 - head/sys/kern
Author: chs Date: Wed Mar 4 00:22:50 2020 New Revision: 358597 URL: https://svnweb.freebsd.org/changeset/base/358597 Log: if vm_pager_get_pages_async() returns an error, release the sfio->nios refcount that we took earlier that represents the I/O that ended up not being started. Reviewed by: glebius Approved by: imp (mentor) Sponsored by: Netflix Modified: head/sys/kern/kern_sendfile.c Modified: head/sys/kern/kern_sendfile.c == --- head/sys/kern/kern_sendfile.c Tue Mar 3 23:15:30 2020 (r358596) +++ head/sys/kern/kern_sendfile.c Wed Mar 4 00:22:50 2020 (r358597) @@ -454,6 +454,7 @@ sendfile_swapin(vm_object_t obj, struct sf_io *sfio, i __func__, pa, j)); vm_page_unwire(pa[j], PQ_INACTIVE); } + refcount_release(>nios); return (EIO); } ___ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"
svn commit: r358058 - head/sys/amd64/amd64
Author: chs Date: Tue Feb 18 00:02:20 2020 New Revision: 358058 URL: https://svnweb.freebsd.org/changeset/base/358058 Log: amd64: keep PTE bitmasks in sync with target pmap during pv reclaim in reclaim_pv_chunk_domain(), when we switch to a new target pmap from which we are trying to reclaim a pv chunk, always update the current PTE bitmasks to match. Reviewed by: kib, markj Approved by: imp (mentor) Sponsored by: Netflix Modified: head/sys/amd64/amd64/pmap.c Modified: head/sys/amd64/amd64/pmap.c == --- head/sys/amd64/amd64/pmap.c Tue Feb 18 00:01:18 2020(r358057) +++ head/sys/amd64/amd64/pmap.c Tue Feb 18 00:02:20 2020(r358058) @@ -4298,7 +4298,7 @@ reclaim_pv_chunk_domain(pmap_t locked_pmap, struct rwl struct spglist free; uint64_t inuse; int bit, field, freed; - bool start_di; + bool start_di, restart; PMAP_LOCK_ASSERT(locked_pmap, MA_OWNED); KASSERT(lockp != NULL, ("reclaim_pv_chunk: lockp is NULL")); @@ -4343,6 +4343,7 @@ reclaim_pv_chunk_domain(pmap_t locked_pmap, struct rwl * corresponding pmap is locked. */ if (pmap != next_pmap) { + restart = false; reclaim_pv_chunk_leave_pmap(pmap, locked_pmap, start_di); pmap = next_pmap; @@ -4353,13 +4354,13 @@ reclaim_pv_chunk_domain(pmap_t locked_pmap, struct rwl if (start_di) pmap_delayed_invl_start(); mtx_lock(>pvc_lock); - continue; + restart = true; } else if (pmap != locked_pmap) { if (PMAP_TRYLOCK(pmap)) { if (start_di) pmap_delayed_invl_start(); mtx_lock(>pvc_lock); - continue; + restart = true; } else { pmap = NULL; /* pmap is not locked */ mtx_lock(>pvc_lock); @@ -4375,6 +4376,8 @@ reclaim_pv_chunk_domain(pmap_t locked_pmap, struct rwl PG_A = pmap_accessed_bit(pmap); PG_M = pmap_modified_bit(pmap); PG_RW = pmap_rw_bit(pmap); + if (restart) + continue; } /* ___ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"
svn commit: r357456 - head/sys/ufs/ffs
Author: chs Date: Mon Feb 3 17:47:14 2020 New Revision: 357456 URL: https://svnweb.freebsd.org/changeset/base/357456 Log: With INVARIANTS, track all softdep dependency structures centrally so that we can find them in dumps. Approved by: mckusick (mentor) Sponsored by: Netflix Modified: head/sys/ufs/ffs/ffs_softdep.c head/sys/ufs/ffs/softdep.h Modified: head/sys/ufs/ffs/ffs_softdep.c == --- head/sys/ufs/ffs/ffs_softdep.c Mon Feb 3 17:35:11 2020 (r357455) +++ head/sys/ufs/ffs/ffs_softdep.c Mon Feb 3 17:47:14 2020 (r357456) @@ -1208,6 +1208,9 @@ workitem_free(item, type) ump->um_fs->fs_fsmnt, TYPENAME(item->wk_type))); atomic_subtract_long(_current[item->wk_type], 1); ump->softdep_curdeps[item->wk_type] -= 1; +#ifdef INVARIANTS + LIST_REMOVE(item, wk_all); +#endif free(item, DtoM(type)); } @@ -1234,6 +1237,9 @@ workitem_alloc(item, type, mp) ump->softdep_curdeps[type] += 1; ump->softdep_deps++; ump->softdep_accdeps++; +#ifdef INVARIANTS + LIST_INSERT_HEAD(>softdep_alldeps[type], item, wk_all); +#endif FREE_LOCK(ump); } @@ -2532,6 +2538,10 @@ softdep_mount(devvp, mp, fs, cred) ump->indir_hash_size = i - 1; for (i = 0; i <= ump->indir_hash_size; i++) TAILQ_INIT(>indir_hashtbl[i]); +#ifdef INVARIANTS + for (i = 0; i <= D_LAST; i++) + LIST_INIT(>softdep_alldeps[i]); +#endif ACQUIRE_GBLLOCK(); TAILQ_INSERT_TAIL(, sdp, sd_next); FREE_GBLLOCK(); @@ -2638,10 +2648,14 @@ softdep_unmount(mp) ump->bmsafemap_hash_size); free(ump->indir_hashtbl, M_FREEWORK); #ifdef INVARIANTS - for (i = 0; i <= D_LAST; i++) + for (i = 0; i <= D_LAST; i++) { KASSERT(ump->softdep_curdeps[i] == 0, ("Unmount %s: Dep type %s != 0 (%ld)", ump->um_fs->fs_fsmnt, TYPENAME(i), ump->softdep_curdeps[i])); + KASSERT(LIST_EMPTY(>softdep_alldeps[i]), + ("Unmount %s: Dep type %s not empty (%p)", ump->um_fs->fs_fsmnt, + TYPENAME(i), LIST_FIRST(>softdep_alldeps[i]))); + } #endif free(ump->um_softdep, M_MOUNTDATA); } Modified: head/sys/ufs/ffs/softdep.h == --- head/sys/ufs/ffs/softdep.h Mon Feb 3 17:35:11 2020(r357455) +++ head/sys/ufs/ffs/softdep.h Mon Feb 3 17:47:14 2020(r357456) @@ -216,6 +216,7 @@ struct worklist { #ifdef INVARIANTS const char *wk_func; /* func where added / removed */ int wk_line;/* line where added / removed */ + LIST_ENTRY(worklist)wk_all; /* list of deps of this type */ #endif }; #defineWK_DATA(wk) ((void *)(wk)) @@ -1073,6 +1074,9 @@ struct mount_softdeps { TAILQ_ENTRY(mount_softdeps) sd_next;/* List of softdep filesystem */ struct ufsmount *sd_ump; /* our ufsmount structure */ u_long sd_curdeps[D_LAST + 1]; /* count of current deps */ +#ifdef INVARIANTS + struct workhead sd_alldeps[D_LAST + 1];/* Lists of all deps */ +#endif }; /* * Flags for communicating with the syncer thread. @@ -1113,3 +1117,4 @@ struct mount_softdeps { #definesoftdep_flags um_softdep->sd_flags #definesoftdep_flushtd um_softdep->sd_flushtd #definesoftdep_curdeps um_softdep->sd_curdeps +#definesoftdep_alldeps um_softdep->sd_alldeps ___ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"
svn commit: r355150 - head/sys/ufs/ffs
Author: chs Date: Thu Nov 28 00:37:43 2019 New Revision: 355150 URL: https://svnweb.freebsd.org/changeset/base/355150 Log: As part of creating a snapshot, set fs->fs_fmod to 0 in the snapshot image because nothing ever changes this field for read-only mounts and we want to verify that it is still 0 when we unmount. Reviewed by: mckusick Approved by: mckusick (mentor) Sponsored by: Netflix Modified: head/sys/ufs/ffs/ffs_snapshot.c Modified: head/sys/ufs/ffs/ffs_snapshot.c == --- head/sys/ufs/ffs/ffs_snapshot.c Thu Nov 28 00:19:09 2019 (r355149) +++ head/sys/ufs/ffs/ffs_snapshot.c Thu Nov 28 00:37:43 2019 (r355150) @@ -803,6 +803,7 @@ out1: brelse(nbp); } else { loc = blkoff(fs, fs->fs_sblockloc); + copy_fs->fs_fmod = 0; copy_fs->fs_ckhash = ffs_calc_sbhash(copy_fs); bcopy((char *)copy_fs, >b_data[loc], (u_int)fs->fs_sbsize); bawrite(nbp); ___ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"
svn commit: r355098 - head/sys/ufs/ffs
Author: chs Date: Mon Nov 25 19:31:38 2019 New Revision: 355098 URL: https://svnweb.freebsd.org/changeset/base/355098 Log: In ffs_freefile(), use a separate variable to hold the inode number within the cg rather than reusuing "ino" for this purpose. This reduces the diff for an upcoming change that improves handling of I/O errors. No functional change. Reviewed by: mckusick Approved by: mckusick (mentor) Sponsored by: Netflix Modified: head/sys/ufs/ffs/ffs_alloc.c Modified: head/sys/ufs/ffs/ffs_alloc.c == --- head/sys/ufs/ffs/ffs_alloc.cMon Nov 25 18:33:21 2019 (r355097) +++ head/sys/ufs/ffs/ffs_alloc.cMon Nov 25 19:31:38 2019 (r355098) @@ -2786,6 +2786,7 @@ ffs_freefile(ump, fs, devvp, ino, mode, wkhd) u_int cg; u_int8_t *inosused; struct cdev *dev; + ino_t cgino; cg = ino_to_cg(fs, ino); if (devvp->v_type == VREG) { @@ -2805,16 +2806,16 @@ ffs_freefile(ump, fs, devvp, ino, mode, wkhd) if ((error = ffs_getcg(fs, devvp, cg, 0, , )) != 0) return (error); inosused = cg_inosused(cgp); - ino %= fs->fs_ipg; - if (isclr(inosused, ino)) { + cgino = ino % fs->fs_ipg; + if (isclr(inosused, cgino)) { printf("dev = %s, ino = %ju, fs = %s\n", devtoname(dev), - (uintmax_t)(ino + cg * fs->fs_ipg), fs->fs_fsmnt); + (uintmax_t)ino, fs->fs_fsmnt); if (fs->fs_ronly == 0) panic("ffs_freefile: freeing free inode"); } - clrbit(inosused, ino); - if (ino < cgp->cg_irotor) - cgp->cg_irotor = ino; + clrbit(inosused, cgino); + if (cgino < cgp->cg_irotor) + cgp->cg_irotor = cgino; cgp->cg_cs.cs_nifree++; UFS_LOCK(ump); fs->fs_cstotal.cs_nifree++; @@ -2828,8 +2829,7 @@ ffs_freefile(ump, fs, devvp, ino, mode, wkhd) ACTIVECLEAR(fs, cg); UFS_UNLOCK(ump); if (MOUNTEDSOFTDEP(UFSTOVFS(ump)) && devvp->v_type == VCHR) - softdep_setup_inofree(UFSTOVFS(ump), bp, - ino + cg * fs->fs_ipg, wkhd); + softdep_setup_inofree(UFSTOVFS(ump), bp, ino, wkhd); bdwrite(bp); return (0); } ___ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"
svn commit: r354632 - head/sys/ufs/ufs
Author: chs Date: Tue Nov 12 00:32:33 2019 New Revision: 354632 URL: https://svnweb.freebsd.org/changeset/base/354632 Log: In ufs_dir_dd_ino(), always initialize *dd_vp since the caller expects it. Reviewed by: kib, mckusick Approved by: imp (mentor) Sponsored by: Netflix Modified: head/sys/ufs/ufs/ufs_lookup.c Modified: head/sys/ufs/ufs/ufs_lookup.c == --- head/sys/ufs/ufs/ufs_lookup.c Mon Nov 11 22:18:05 2019 (r354631) +++ head/sys/ufs/ufs/ufs_lookup.c Tue Nov 12 00:32:33 2019 (r354632) @@ -1408,6 +1408,7 @@ ufs_dir_dd_ino(struct vnode *vp, struct ucred *cred, i int error, namlen; ASSERT_VOP_LOCKED(vp, "ufs_dir_dd_ino"); + *dd_vp = NULL; if (vp->v_type != VDIR) return (ENOTDIR); /* @@ -1440,7 +1441,6 @@ ufs_dir_dd_ino(struct vnode *vp, struct ucred *cred, i dirbuf.dotdot_name[1] != '.') return (ENOTDIR); *dd_ino = dirbuf.dotdot_ino; - *dd_vp = NULL; return (0); } ___ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"
svn commit: r353667 - head/sys/geom
Author: chs Date: Wed Oct 16 21:49:39 2019 New Revision: 353667 URL: https://svnweb.freebsd.org/changeset/base/353667 Log: Add a new gctl_get_paraml_opt() interface to extract optional parameters from the request. It is the same as gctl_get_paraml() except that the request is not marked with an error if the parameter is not present. Approved by: imp (mentor) Reviewed by: cem Sponsored by: Netflix Differential Revision:https://reviews.freebsd.org/D21972 Modified: head/sys/geom/geom.h head/sys/geom/geom_ctl.c Modified: head/sys/geom/geom.h == --- head/sys/geom/geom.hWed Oct 16 21:47:58 2019(r353666) +++ head/sys/geom/geom.hWed Oct 16 21:49:39 2019(r353667) @@ -428,6 +428,7 @@ void gctl_set_param_err(struct gctl_req *req, const ch void *gctl_get_param(struct gctl_req *req, const char *param, int *len); char const *gctl_get_asciiparam(struct gctl_req *req, const char *param); void *gctl_get_paraml(struct gctl_req *req, const char *param, int len); +void *gctl_get_paraml_opt(struct gctl_req *req, const char *param, int len); int gctl_error(struct gctl_req *req, const char *fmt, ...) __printflike(2, 3); struct g_class *gctl_get_class(struct gctl_req *req, char const *arg); struct g_geom *gctl_get_geom(struct gctl_req *req, struct g_class *mpr, char const *arg); Modified: head/sys/geom/geom_ctl.c == --- head/sys/geom/geom_ctl.cWed Oct 16 21:47:58 2019(r353666) +++ head/sys/geom/geom_ctl.cWed Oct 16 21:49:39 2019(r353667) @@ -365,18 +365,27 @@ gctl_get_asciiparam(struct gctl_req *req, const char * } void * -gctl_get_paraml(struct gctl_req *req, const char *param, int len) +gctl_get_paraml_opt(struct gctl_req *req, const char *param, int len) { int i; void *p; p = gctl_get_param(req, param, ); - if (p == NULL) - gctl_error(req, "Missing %s argument", param); - else if (i != len) { + if (i != len) { p = NULL; gctl_error(req, "Wrong length %s argument", param); } + return (p); +} + +void * +gctl_get_paraml(struct gctl_req *req, const char *param, int len) +{ + void *p; + + p = gctl_get_paraml_opt(req, param, len); + if (p == NULL) + gctl_error(req, "Missing %s argument", param); return (p); } ___ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"
svn commit: r353668 - head/sys/geom/nop
Author: chs Date: Wed Oct 16 21:49:44 2019 New Revision: 353668 URL: https://svnweb.freebsd.org/changeset/base/353668 Log: Make all the gnop parameters optional in the request from userland, filling in the same defaults that the current userland module uses. This allows an old geom_nop.so userland module to work with a new kernel. Approved by: imp (mentor) Reviewed by: cem Sponsored by: Netflix Differential Revision:https://reviews.freebsd.org/D21972 Modified: head/sys/geom/nop/g_nop.c Modified: head/sys/geom/nop/g_nop.c == --- head/sys/geom/nop/g_nop.c Wed Oct 16 21:49:39 2019(r353667) +++ head/sys/geom/nop/g_nop.c Wed Oct 16 21:49:44 2019(r353668) @@ -497,15 +497,28 @@ static void g_nop_ctl_create(struct gctl_req *req, struct g_class *mp) { struct g_provider *pp; - intmax_t *error, *rfailprob, *wfailprob, *count_until_fail, *offset, - *secsize, *size, *stripesize, *stripeoffset, *delaymsec, - *rdelayprob, *wdelayprob; + intmax_t *val, error, rfailprob, wfailprob, count_until_fail, offset, + secsize, size, stripesize, stripeoffset, delaymsec, + rdelayprob, wdelayprob; const char *name, *physpath; char param[16]; int i, *nargs; g_topology_assert(); + error = -1; + rfailprob = -1; + wfailprob = -1; + count_until_fail = -1; + offset = 0; + secsize = 0; + size = 0; + stripesize = 0; + stripeoffset = 0; + delaymsec = -1; + rdelayprob = -1; + wdelayprob = -1; + nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); if (nargs == NULL) { gctl_error(req, "No '%s' argument", "nargs"); @@ -515,111 +528,100 @@ g_nop_ctl_create(struct gctl_req *req, struct g_class gctl_error(req, "Missing device(s)."); return; } - error = gctl_get_paraml(req, "error", sizeof(*error)); - if (error == NULL) { - gctl_error(req, "No '%s' argument", "error"); - return; + val = gctl_get_paraml_opt(req, "error", sizeof(*val)); + if (val != NULL) { + error = *val; } - rfailprob = gctl_get_paraml(req, "rfailprob", sizeof(*rfailprob)); - if (rfailprob == NULL) { - gctl_error(req, "No '%s' argument", "rfailprob"); - return; + val = gctl_get_paraml_opt(req, "rfailprob", sizeof(*val)); + if (val != NULL) { + rfailprob = *val; + if (rfailprob < -1 || rfailprob > 100) { + gctl_error(req, "Invalid '%s' argument", "rfailprob"); + return; + } } - if (*rfailprob < -1 || *rfailprob > 100) { - gctl_error(req, "Invalid '%s' argument", "rfailprob"); - return; + val = gctl_get_paraml_opt(req, "wfailprob", sizeof(*val)); + if (val != NULL) { + wfailprob = *val; + if (wfailprob < -1 || wfailprob > 100) { + gctl_error(req, "Invalid '%s' argument", "wfailprob"); + return; + } } - wfailprob = gctl_get_paraml(req, "wfailprob", sizeof(*wfailprob)); - if (wfailprob == NULL) { - gctl_error(req, "No '%s' argument", "wfailprob"); - return; + val = gctl_get_paraml_opt(req, "delaymsec", sizeof(*val)); + if (val != NULL) { + delaymsec = *val; + if (delaymsec < 1 && delaymsec != -1) { + gctl_error(req, "Invalid '%s' argument", "delaymsec"); + return; + } } - if (*wfailprob < -1 || *wfailprob > 100) { - gctl_error(req, "Invalid '%s' argument", "wfailprob"); - return; + val = gctl_get_paraml_opt(req, "rdelayprob", sizeof(*val)); + if (val != NULL) { + rdelayprob = *val; + if (rdelayprob < -1 || rdelayprob > 100) { + gctl_error(req, "Invalid '%s' argument", "rdelayprob"); + return; + } } - delaymsec = gctl_get_paraml(req, "delaymsec", sizeof(*delaymsec)); - if (delaymsec == NULL) { - gctl_error(req, "No '%s' argument", "delaymsec"); - return; + val = gctl_get_paraml_opt(req, "wdelayprob", sizeof(*val)); + if (val != NULL) { + wdelayprob = *val; + if (wdelayprob < -1 || wdelayprob > 100) { + gctl_error(req, "Invalid '%s' argument", "wdelayprob"); + return; + } } - if (*delaymsec < 1 && *delaymsec != -1) { - gctl_error(req, "Invalid '%s' argument", "delaymsec"); - return; + val =
Re: svn commit: r352312 - in head: lib/geom/nop sys/geom/nop
On Wed, Oct 02, 2019 at 08:11:57AM -0600, Alan Somers wrote: > On Fri, Sep 13, 2019 at 5:04 PM Chuck Silvers wrote: > > > Author: chs > > Date: Fri Sep 13 23:03:56 2019 > > New Revision: 352312 > > URL: https://svnweb.freebsd.org/changeset/base/352312 > > > > Log: > > Add a "count_until_fail" option to gnop, which says to start failing > > I/O requests after the given number have been allowed though. > > > > Approved by:imp (mentor) > > Reviewed by:rpokala kib 0mp mckusick > > Sponsored by: Netflix > > Differential Revision: https://reviews.freebsd.org/D21593 > > > > Modified: > > head/lib/geom/nop/geom_nop.c > > head/lib/geom/nop/gnop.8 > > head/sys/geom/nop/g_nop.c > > head/sys/geom/nop/g_nop.h > > > > This patch introduces a backwards-compatibility bug. On a system with a > post-352312 kernel but a pre-352312 userland, the gnop command will always > fail with the error "gnop: Missing count_until_fail argument". > -Alan Thanks for pointing this out, I'll see about fixing it right away. -Chuck ___ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"
svn commit: r352312 - in head: lib/geom/nop sys/geom/nop
Author: chs Date: Fri Sep 13 23:03:56 2019 New Revision: 352312 URL: https://svnweb.freebsd.org/changeset/base/352312 Log: Add a "count_until_fail" option to gnop, which says to start failing I/O requests after the given number have been allowed though. Approved by:imp (mentor) Reviewed by:rpokala kib 0mp mckusick Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D21593 Modified: head/lib/geom/nop/geom_nop.c head/lib/geom/nop/gnop.8 head/sys/geom/nop/g_nop.c head/sys/geom/nop/g_nop.h Modified: head/lib/geom/nop/geom_nop.c == --- head/lib/geom/nop/geom_nop.cFri Sep 13 22:36:04 2019 (r352311) +++ head/lib/geom/nop/geom_nop.cFri Sep 13 23:03:56 2019 (r352312) @@ -43,6 +43,7 @@ uint32_t version = G_NOP_VERSION; struct g_command class_commands[] = { { "create", G_FLAG_VERBOSE | G_FLAG_LOADKLD, NULL, { + { 'c', "count_until_fail", "-1", G_TYPE_NUMBER }, { 'd', "delaymsec", "-1", G_TYPE_NUMBER }, { 'e', "error", "-1", G_TYPE_NUMBER }, { 'o', "offset", "0", G_TYPE_NUMBER }, @@ -57,12 +58,14 @@ struct g_command class_commands[] = { { 'z', "physpath", G_NOP_PHYSPATH_PASSTHROUGH, G_TYPE_STRING }, G_OPT_SENTINEL }, - "[-v] [-d delaymsec] [-e error] [-o offset] [-p stripesize] " - "[-P stripeoffset] [-q rdelayprob] [-r rfailprob] [-s size] " - "[-S secsize] [-w wfailprob] [-x wdelayprob] [-z physpath] dev ..." + "[-v] [-c count_until_fail] [-d delaymsec] [-e error] [-o offset] " + "[-p stripesize] [-P stripeoffset] [-q rdelayprob] [-r rfailprob] " + "[-s size] [-S secsize] [-w wfailprob] [-x wdelayprob] " + "[-z physpath] dev ..." }, { "configure", G_FLAG_VERBOSE, NULL, { + { 'c', "count_until_fail", "-1", G_TYPE_NUMBER }, { 'd', "delaymsec", "-1", G_TYPE_NUMBER }, { 'e', "error", "-1", G_TYPE_NUMBER }, { 'q', "rdelayprob", "-1", G_TYPE_NUMBER }, @@ -71,8 +74,9 @@ struct g_command class_commands[] = { { 'x', "wdelayprob", "-1", G_TYPE_NUMBER }, G_OPT_SENTINEL }, - "[-v] [-d delaymsec] [-e error] [-q rdelayprob] [-r rfailprob] " - "[-w wfailprob] [-x wdelayprob] prov ..." + "[-v] [-c count_until_fail] [-d delaymsec] [-e error] " + "[-q rdelayprob] [-r rfailprob] [-w wfailprob] [-x wdelayprob] " + "prov ..." }, { "destroy", G_FLAG_VERBOSE, NULL, { Modified: head/lib/geom/nop/gnop.8 == --- head/lib/geom/nop/gnop.8Fri Sep 13 22:36:04 2019(r352311) +++ head/lib/geom/nop/gnop.8Fri Sep 13 23:03:56 2019(r352312) @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 31, 2019 +.Dd September 13, 2019 .Dt GNOP 8 .Os .Sh NAME @@ -34,6 +34,7 @@ .Nm .Cm create .Op Fl v +.Op Fl c Ar count_until_fail .Op Fl d Ar delaymsec .Op Fl e Ar error .Op Fl o Ar offset @@ -50,6 +51,7 @@ .Nm .Cm configure .Op Fl v +.Op Fl c Ar count_until_fail .Op Fl d Ar delaymsec .Op Fl e Ar error .Op Fl q Ar rdelayprob @@ -118,7 +120,10 @@ See .El .Pp Additional options: -.Bl -tag -width ".Fl r Ar rfailprob" +.Bl -tag -width "-c count_until_fail" +.It Fl c Ar count_until_fail +Specifies the number of I/O requests to allow before setting the read and write +failure probabilities to 100%. .It Fl d Ar delaymsec Specifies the delay of the requests in milliseconds. Note that requests will be delayed before they are sent to the backing device. Modified: head/sys/geom/nop/g_nop.c == --- head/sys/geom/nop/g_nop.c Fri Sep 13 22:36:04 2019(r352311) +++ head/sys/geom/nop/g_nop.c Fri Sep 13 23:03:56 2019(r352312) @@ -195,6 +195,10 @@ g_nop_start(struct bio *bp) G_NOP_LOGREQ(bp, "Request received."); mtx_lock(>sc_lock); + if (sc->sc_count_until_fail != 0 && --sc->sc_count_until_fail == 0) { + sc->sc_rfailprob = 100; + sc->sc_wfailprob = 100; + } switch (bp->bio_cmd) { case BIO_READ: sc->sc_reads++; @@ -308,9 +312,10 @@ g_nop_access(struct g_provider *pp, int dr, int dw, in static int g_nop_create(struct gctl_req *req, struct g_class *mp, struct g_provider *pp, -int ioerror, u_int rfailprob, u_int wfailprob, u_int delaymsec, u_int rdelayprob, -u_int wdelayprob, off_t offset, off_t size, u_int secsize, off_t stripesize, -off_t stripeoffset, const char *physpath) +int ioerror, u_int count_until_fail, u_int rfailprob, u_int wfailprob, +u_int delaymsec, u_int rdelayprob, u_int