svn commit: r338150 - head/sys/fs/ext2fs

Fedor Uporov fsu at FreeBSD.org
Tue Aug 21 18:39:04 UTC 2018


Author: fsu
Date: Tue Aug 21 18:39:02 2018
New Revision: 338150
URL: https://svnweb.freebsd.org/changeset/base/338150

Log:
  Fix directory blocks checksum updating logic.
  
  Count dirent tail in the searchslot logic in case of directory block search.
  Add htree root csum update function call in case of rename.

Modified:
  head/sys/fs/ext2fs/ext2_csum.c
  head/sys/fs/ext2fs/ext2_extern.h
  head/sys/fs/ext2fs/ext2_lookup.c
  head/sys/fs/ext2fs/ext2_vnops.c

Modified: head/sys/fs/ext2fs/ext2_csum.c
==============================================================================
--- head/sys/fs/ext2fs/ext2_csum.c	Tue Aug 21 18:22:12 2018	(r338149)
+++ head/sys/fs/ext2fs/ext2_csum.c	Tue Aug 21 18:39:02 2018	(r338150)
@@ -162,12 +162,32 @@ ext2_init_dirent_tail(struct ext2fs_direct_tail *tp)
 	tp->e2dt_reserved_ft = EXT2_FT_DIR_CSUM;
 }
 
+int
+ext2_is_dirent_tail(struct inode *ip, struct ext2fs_direct_2 *ep)
+{
+	struct m_ext2fs *fs;
+	struct ext2fs_direct_tail *tp;
+
+	fs = ip->i_e2fs;
+
+	if (!EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_METADATA_CKSUM))
+		return (0);
+
+	tp = (struct ext2fs_direct_tail *)ep;
+	if (tp->e2dt_reserved_zero1 == 0 &&
+	    tp->e2dt_rec_len == sizeof(struct ext2fs_direct_tail) &&
+	    tp->e2dt_reserved_zero2 == 0 &&
+	    tp->e2dt_reserved_ft == EXT2_FT_DIR_CSUM)
+		return (1);
+
+	return (0);
+}
+
 struct ext2fs_direct_tail *
 ext2_dirent_get_tail(struct inode *ip, struct ext2fs_direct_2 *ep)
 {
 	struct ext2fs_direct_2 *dep;
 	void *top;
-	struct ext2fs_direct_tail *tp;
 	unsigned int rec_len;
 
 	dep = ep;
@@ -184,14 +204,10 @@ ext2_dirent_get_tail(struct inode *ip, struct ext2fs_d
 	if (dep != top)
 		return (NULL);
 
-	tp = (struct ext2fs_direct_tail *)dep;
-	if (tp->e2dt_reserved_zero1 ||
-	    tp->e2dt_rec_len != sizeof(struct ext2fs_direct_tail) ||
-	    tp->e2dt_reserved_zero2 ||
-	    tp->e2dt_reserved_ft != EXT2_FT_DIR_CSUM)
-		return (NULL);
+	if (ext2_is_dirent_tail(ip, dep))
+		return ((struct ext2fs_direct_tail *)dep);
 
-	return (tp);
+	return (NULL);
 }
 
 static uint32_t

Modified: head/sys/fs/ext2fs/ext2_extern.h
==============================================================================
--- head/sys/fs/ext2fs/ext2_extern.h	Tue Aug 21 18:22:12 2018	(r338149)
+++ head/sys/fs/ext2fs/ext2_extern.h	Tue Aug 21 18:39:02 2018	(r338150)
@@ -120,6 +120,7 @@ int	ext2_dx_csum_verify(struct inode *ip, struct ext2f
 int	ext2_extent_blk_csum_verify(struct inode *, void *);
 void	ext2_extent_blk_csum_set(struct inode *, void *);
 void	ext2_init_dirent_tail(struct ext2fs_direct_tail *);
+int	ext2_is_dirent_tail(struct inode *, struct ext2fs_direct_2 *);
 int	ext2_gd_i_bitmap_csum_verify(struct m_ext2fs *, int, struct buf *);
 void	ext2_gd_i_bitmap_csum_set(struct m_ext2fs *, int, struct buf *);
 int	ext2_gd_b_bitmap_csum_verify(struct m_ext2fs *, int, struct buf *);

Modified: head/sys/fs/ext2fs/ext2_lookup.c
==============================================================================
--- head/sys/fs/ext2fs/ext2_lookup.c	Tue Aug 21 18:22:12 2018	(r338149)
+++ head/sys/fs/ext2fs/ext2_lookup.c	Tue Aug 21 18:39:02 2018	(r338150)
@@ -429,16 +429,13 @@ searchloop:
 		error = ext2_blkatoff(vdp, (off_t)i_offset, NULL, &bp);
 		if (error != 0)
 			return (error);
+
 		entryoffsetinblock = 0;
-		/*
-		 * If still looking for a slot, and at a DIRBLKSIZE
-		 * boundary, have to start looking for free space again.
-		 */
-		if (ss.slotstatus == NONE &&
-		    (entryoffsetinblock & (DIRBLKSIZ - 1)) == 0) {
+		if (ss.slotstatus == NONE) {
 			ss.slotoffset = -1;
 			ss.slotfreespace = 0;
 		}
+
 		error = ext2_search_dirblock(dp, bp->b_data, &entry_found,
 		    cnp->cn_nameptr, cnp->cn_namelen,
 		    &entryoffsetinblock, &i_offset, &prevoff,
@@ -719,9 +716,7 @@ ext2_search_dirblock(struct inode *ip, void *data, int
 	vdp = ITOV(ip);
 
 	ep = (struct ext2fs_direct_2 *)((char *)data + offset);
-	top = (struct ext2fs_direct_2 *)((char *)data +
-	    bsize - EXT2_DIR_REC_LEN(0));
-
+	top = (struct ext2fs_direct_2 *)((char *)data + bsize);
 	while (ep < top) {
 		/*
 		 * Full validation checks are slow, so we only check
@@ -751,6 +746,8 @@ ext2_search_dirblock(struct inode *ip, void *data, int
 
 			if (ep->e2d_ino != 0)
 				size -= EXT2_DIR_REC_LEN(ep->e2d_namlen);
+			else if (ext2_is_dirent_tail(ip, ep))
+				size -= sizeof(struct ext2fs_direct_tail);
 			if (size > 0) {
 				if (size >= ssp->slotneeded) {
 					ssp->slotstatus = FOUND;

Modified: head/sys/fs/ext2fs/ext2_vnops.c
==============================================================================
--- head/sys/fs/ext2fs/ext2_vnops.c	Tue Aug 21 18:22:12 2018	(r338149)
+++ head/sys/fs/ext2fs/ext2_vnops.c	Tue Aug 21 18:39:02 2018	(r338150)
@@ -1081,7 +1081,13 @@ abortit:
 					    "rename: mangled dir");
 				} else {
 					dirbuf->dotdot_ino = newparent;
+					/*
+					 * dirblock 0 could be htree root,
+					 * try both csum update functions.
+					 */
 					ext2_dirent_csum_set(ip,
+					    (struct ext2fs_direct_2 *)dirbuf);
+					ext2_dx_csum_set(ip,
 					    (struct ext2fs_direct_2 *)dirbuf);
 					(void)vn_rdwr(UIO_WRITE, fvp,
 					    (caddr_t)dirbuf,


More information about the svn-src-head mailing list