Fix encoding for rec_len in directories for >= 64k blocksize file systems

Previously e2fsprogs interpreted 0 for a rec_len of 65536 (which could
occur if the directory block is completely empty in 64k blocksize
filesystems), while the kernel interpreted 65535 to mean 65536.  The
kernel will accept both to mean 65536, and encodes 65535 to be 65536.
This commit changes e2fsprogs to match.

We add the encoding agreed upon for 128k and 256k filesystems, but we
don't enable support for these larger block sizes, since they haven't
been fully tested.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
diff --git a/debugfs/htree.c b/debugfs/htree.c
index afb7605..01e4ca5 100644
--- a/debugfs/htree.c
+++ b/debugfs/htree.c
@@ -39,7 +39,8 @@
 	char		tmp[EXT2_NAME_LEN + 16];
 	blk_t		pblk;
 	ext2_dirhash_t 	hash, minor_hash;
-	int		rec_len, hash_alg;
+	unsigned int	rec_len;
+	int		hash_alg;
 
 	errcode = ext2fs_bmap(fs, ino, inode, buf, 0, blk, &pblk);
 	if (errcode) {
@@ -64,8 +65,13 @@
 
 	while (offset < fs->blocksize) {
 		dirent = (struct ext2_dir_entry *) (buf + offset);
-		rec_len = (dirent->rec_len || fs->blocksize < 65536) ?
-			dirent->rec_len : 65536;
+		errcode = ext2fs_get_rec_len(fs, dirent, &rec_len);
+		if (errcode) {
+			com_err("htree_dump_leaf_inode", errcode,
+				"while getting rec_len for block %lu",
+				(unsigned long) blk);
+			return;
+		}
 		if (((offset + rec_len) > fs->blocksize) ||
 		    (rec_len < 8) ||
 		    ((rec_len % 4) != 0) ||
@@ -386,7 +392,7 @@
 	struct ext2_dir_entry *dirent;
 	errcode_t	       	errcode;
 	unsigned int		offset = 0;
-	int			rec_len;
+	unsigned int		rec_len;
 
 	if (blockcnt < 0)
 		return 0;
@@ -402,8 +408,13 @@
 
 	while (offset < fs->blocksize) {
 		dirent = (struct ext2_dir_entry *) (p->buf + offset);
-		rec_len = (dirent->rec_len || fs->blocksize < 65536) ?
-			dirent->rec_len : 65536;
+		errcode = ext2fs_get_rec_len(fs, dirent, &rec_len);
+		if (errcode) {
+			com_err("htree_dump_leaf_inode", errcode,
+				"while getting rec_len for block %lu",
+				(unsigned long) *blocknr);
+			return;
+		}
 		if (dirent->inode &&
 		    p->len == (dirent->name_len & 0xFF) &&
 		    strncmp(p->search_name, dirent->name,