From owner-svn-src-head@freebsd.org Wed Aug 8 12:07:47 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 09E7E105A565; Wed, 8 Aug 2018 12:07:47 +0000 (UTC) (envelope-from fsu@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id B3FB57B11A; Wed, 8 Aug 2018 12:07:46 +0000 (UTC) (envelope-from fsu@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 964DB225E; Wed, 8 Aug 2018 12:07:46 +0000 (UTC) (envelope-from fsu@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w78C7k7q031174; Wed, 8 Aug 2018 12:07:46 GMT (envelope-from fsu@FreeBSD.org) Received: (from fsu@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w78C7kK2031172; Wed, 8 Aug 2018 12:07:46 GMT (envelope-from fsu@FreeBSD.org) Message-Id: <201808081207.w78C7kK2031172@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: fsu set sender to fsu@FreeBSD.org using -f From: Fedor Uporov Date: Wed, 8 Aug 2018 12:07:46 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r337453 - head/sys/fs/ext2fs X-SVN-Group: head X-SVN-Commit-Author: fsu X-SVN-Commit-Paths: head/sys/fs/ext2fs X-SVN-Commit-Revision: 337453 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 08 Aug 2018 12:07:47 -0000 Author: fsu Date: Wed Aug 8 12:07:45 2018 New Revision: 337453 URL: https://svnweb.freebsd.org/changeset/base/337453 Log: Fix directory blocks checksum updating logic. The checksum updating functions were not called in case of dir index inode splitting and in case of dir entry removing, when the entry was first in the block. Fix and move the dir entry adding logic when i_count == 0 to new function. MFC after: 3 months Modified: head/sys/fs/ext2fs/ext2_htree.c head/sys/fs/ext2fs/ext2_lookup.c Modified: head/sys/fs/ext2fs/ext2_htree.c ============================================================================== --- head/sys/fs/ext2fs/ext2_htree.c Wed Aug 8 07:58:29 2018 (r337452) +++ head/sys/fs/ext2fs/ext2_htree.c Wed Aug 8 12:07:45 2018 (r337453) @@ -800,7 +800,7 @@ ext2_htree_add_entry(struct vnode *dvp, struct ext2fs_ cursize = roundup(ip->i_size, blksize); dirsize = cursize + blksize; blknum = dirsize / blksize - 1; - + ext2_dx_csum_set(ip, (struct ext2fs_direct_2 *)newidxblock); error = ext2_htree_append_block(dvp, newidxblock, cnp, blksize); if (error) Modified: head/sys/fs/ext2fs/ext2_lookup.c ============================================================================== --- head/sys/fs/ext2fs/ext2_lookup.c Wed Aug 8 07:58:29 2018 (r337452) +++ head/sys/fs/ext2fs/ext2_lookup.c Wed Aug 8 12:07:45 2018 (r337453) @@ -859,6 +859,68 @@ ext2_dirbadentry(struct vnode *dp, struct ext2fs_direc } /* + * Insert an entry into the fresh directory block. + * Initialize entry tail if the metadata_csum feature is turned on. + */ +static int +ext2_add_first_entry(struct vnode *dvp, struct ext2fs_direct_2 *entry, + struct componentname *cnp) +{ + struct inode *dp; + struct iovec aiov; + struct uio auio; + char* buf = NULL; + int dirblksize, error; + + dp = VTOI(dvp); + dirblksize = dp->i_e2fs->e2fs_bsize; + + if (dp->i_offset & (dirblksize - 1)) + panic("ext2_add_first_entry: bad directory offset"); + + if (EXT2_HAS_RO_COMPAT_FEATURE(dp->i_e2fs, + EXT2F_ROCOMPAT_METADATA_CKSUM)) { + entry->e2d_reclen = dirblksize - sizeof(struct ext2fs_direct_tail); + buf = malloc(dirblksize, M_TEMP, M_WAITOK); + if (!buf) { + error = ENOMEM; + goto out; + } + memcpy(buf, entry, EXT2_DIR_REC_LEN(entry->e2d_namlen)); + ext2_init_dirent_tail(EXT2_DIRENT_TAIL(buf, dirblksize)); + ext2_dirent_csum_set(dp, (struct ext2fs_direct_2 *)buf); + + auio.uio_offset = dp->i_offset; + auio.uio_resid = dirblksize; + aiov.iov_len = auio.uio_resid; + aiov.iov_base = (caddr_t)buf; + } else { + entry->e2d_reclen = dirblksize; + auio.uio_offset = dp->i_offset; + auio.uio_resid = EXT2_DIR_REC_LEN(entry->e2d_namlen); + aiov.iov_len = auio.uio_resid; + aiov.iov_base = (caddr_t)entry; + } + + auio.uio_iov = &aiov; + auio.uio_iovcnt = 1; + auio.uio_rw = UIO_WRITE; + auio.uio_segflg = UIO_SYSSPACE; + auio.uio_td = (struct thread *)0; + error = VOP_WRITE(dvp, &auio, IO_SYNC, cnp->cn_cred); + if (error) + goto out; + + dp->i_size = roundup2(dp->i_size, dirblksize); + dp->i_flag |= IN_CHANGE; + +out: + free(buf, M_TEMP); + return (error); + +} + +/* * Write a directory entry after a call to namei, using the parameters * that it left in nameidata. The argument ip is the inode which the new * directory entry will refer to. Dvp is a pointer to the directory to @@ -871,7 +933,6 @@ ext2_direnter(struct inode *ip, struct vnode *dvp, str { struct inode *dp; struct ext2fs_direct_2 newdir; - struct buf *bp; int DIRBLKSIZ = ip->i_e2fs->e2fs_bsize; int error; @@ -911,36 +972,15 @@ ext2_direnter(struct inode *ip, struct vnode *dvp, str } } - if (dp->i_count == 0) { - /* - * If dp->i_count is 0, then namei could find no - * space in the directory. Here, dp->i_offset will - * be on a directory block boundary and we will write the - * new entry into a fresh block. - */ - if (dp->i_offset & (DIRBLKSIZ - 1)) - panic("ext2_direnter: newblk"); + /* + * If dp->i_count is 0, then namei could find no + * space in the directory. Here, dp->i_offset will + * be on a directory block boundary and we will write the + * new entry into a fresh block. + */ + if (dp->i_count == 0) + return ext2_add_first_entry(dvp, &newdir, cnp); - newdir.e2d_reclen = DIRBLKSIZ; - - bp = getblk(ip->i_devvp, lblkno(dp->i_e2fs, dp->i_offset), - DIRBLKSIZ, 0, 0, 0); - if (!bp) - return (EIO); - - memcpy(bp->b_data, &newdir, sizeof(struct ext2fs_direct_2)); - - ext2_dirent_csum_set(dp, (struct ext2fs_direct_2 *)bp->b_data); - error = bwrite(bp); - if (error) - return (error); - - dp->i_size = roundup2(dp->i_size, DIRBLKSIZ); - dp->i_flag |= IN_CHANGE; - - return (0); - } - error = ext2_add_entry(dvp, &newdir); if (!error && dp->i_endoff && dp->i_endoff < dp->i_size) error = ext2_truncate(dvp, (off_t)dp->i_endoff, IO_SYNC, @@ -1071,6 +1111,7 @@ ext2_dirremove(struct vnode *dvp, struct componentname &bp)) != 0) return (error); ep->e2d_ino = 0; + ext2_dirent_csum_set(dp, (struct ext2fs_direct_2 *)bp->b_data); error = bwrite(bp); dp->i_flag |= IN_CHANGE | IN_UPDATE; return (error);