Add support for with empty directory blocks in 64k blocksize filesystems

The rec_len field in the directory entry is 16 bits, so if the
filesystem is completely empty, rec_len of 0 is used to designate
65536, for the case where the directory entry takes the entire 64k
block.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
diff --git a/lib/ext2fs/link.c b/lib/ext2fs/link.c
index 5e0f4f3..b283488 100644
--- a/lib/ext2fs/link.c
+++ b/lib/ext2fs/link.c
@@ -24,6 +24,7 @@
 	ext2_ino_t	inode;
 	int		flags;
 	int		done;
+	unsigned int	blocksize;
 	struct ext2_super_block *sb;
 };	
 
@@ -35,20 +36,24 @@
 {
 	struct link_struct *ls = (struct link_struct *) priv_data;
 	struct ext2_dir_entry *next;
-	int rec_len, min_rec_len;
+	int rec_len, min_rec_len, curr_rec_len;
 	int ret = 0;
 
 	rec_len = EXT2_DIR_REC_LEN(ls->namelen);
 
+	curr_rec_len = (dirent->rec_len || ls->blocksize < 65536) ?
+		dirent->rec_len : 65536;
+
 	/*
 	 * See if the following directory entry (if any) is unused;
 	 * if so, absorb it into this one.
 	 */
-	next = (struct ext2_dir_entry *) (buf + offset + dirent->rec_len);
-	if ((offset + dirent->rec_len < blocksize - 8) &&
+	next = (struct ext2_dir_entry *) (buf + offset + curr_rec_len);
+	if ((offset + curr_rec_len < blocksize - 8) &&
 	    (next->inode == 0) &&
-	    (offset + dirent->rec_len + next->rec_len <= blocksize)) {
+	    (offset + curr_rec_len + next->rec_len <= blocksize)) {
 		dirent->rec_len += next->rec_len;
+		curr_rec_len = dirent->rec_len;
 		ret = DIRENT_CHANGED;
 	}
 
@@ -59,9 +64,9 @@
 	 */
 	if (dirent->inode) {
 		min_rec_len = EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
-		if (dirent->rec_len < (min_rec_len + rec_len))
+		if (curr_rec_len < (min_rec_len + rec_len))
 			return ret;
-		rec_len = dirent->rec_len - min_rec_len;
+		rec_len = curr_rec_len - min_rec_len;
 		dirent->rec_len = min_rec_len;
 		next = (struct ext2_dir_entry *) (buf + offset +
 						  dirent->rec_len);
@@ -75,7 +80,7 @@
 	 * If we get this far, then the directory entry is not used.
 	 * See if we can fit the request entry in.  If so, do it.
 	 */
-	if (dirent->rec_len < rec_len)
+	if (curr_rec_len < rec_len)
 		return ret;
 	dirent->inode = ls->inode;
 	dirent->name_len = ls->namelen;
@@ -112,6 +117,7 @@
 	ls.flags = flags;
 	ls.done = 0;
 	ls.sb = fs->super;
+	ls.blocksize = fs->blocksize;
 
 	retval = ext2fs_dir_iterate(fs, dir, DIRENT_FLAG_INCLUDE_EMPTY,
 				    0, link_proc, &ls);