Skip to contentSkip to conversation

Fix 64KB blocksize in ext3 directories

PATCH New [email protected] 1 participant 1 message Nov 15, 2007

lore
Share & tools
lore
#0 lore raw

PATCH 76/120 Fix 64KB blocksize in ext3 directories

From: Jan Kara <[email protected]>

With 64KB blocksize, a directory entry can have size 64KB which does not fit into 16 bits we have for entry lenght. So we store 0xffff instead and convert value when read from / written to disk. The patch also converts some places to use ext3_next_entry() when we are changing them anyway.

---

 fs/ext3/dir.c           |   10 ++--
 fs/ext3/namei.c         |   92 ++++++++++++++++++--------------------
 include/linux/ext3_fs.h |   20 ++++++++
 3 files changed, 70 insertions(+), 52 deletions(-)
fs/ext3/dir.c renamed from fs/ext3/dir.c~fix-64kb-blocksize-in-ext3-directories +5 -5
diff -puN fs/ext3/dir.c~fix-64kb-blocksize-in-ext3-directories fs/ext3/dir.c
@@ -67,7 +67,7 @@ int ext3_check_dir_entry (const char * f
 			  unsigned long offset)
 {
 	const char * error_msg = NULL;
-	const int rlen = le16_to_cpu(de->rec_len);
+	const int rlen = ext3_rec_len_from_disk(de->rec_len);
 
 	if (rlen < EXT3_DIR_REC_LEN(1))
 		error_msg = "rec_len is smaller than minimal";
@@ -173,10 +173,10 @@ revalidate:
 				 * least that it is non-zero.  A
 				 * failure will be detected in the
 				 * dirent test below. */
-				if (le16_to_cpu(de->rec_len) <
+				if (ext3_rec_len_from_disk(de->rec_len) <
 						EXT3_DIR_REC_LEN(1))
 					break;
-				i += le16_to_cpu(de->rec_len);
+				i += ext3_rec_len_from_disk(de->rec_len);
 			}
 			offset = i;
 			filp->f_pos = (filp->f_pos & ~(sb->s_blocksize - 1))
@@ -197,7 +197,7 @@ revalidate:
 				ret = stored;
 				goto out;
 			}
-			offset += le16_to_cpu(de->rec_len);
+			offset += ext3_rec_len_from_disk(de->rec_len);
 			if (le32_to_cpu(de->inode)) {
 				/* We might block in the next section
 				 * if the data destination is
@@ -219,7 +219,7 @@ revalidate:
 					goto revalidate;
 				stored ++;
 			}
-			filp->f_pos += le16_to_cpu(de->rec_len);
+			filp->f_pos += ext3_rec_len_from_disk(de->rec_len);
 		}
 		offset = 0;
 		brelse (bh);
fs/ext3/namei.c renamed from fs/ext3/namei.c~fix-64kb-blocksize-in-ext3-directories +45 -47

229 lines not on this page · raw message

include/linux/ext3_fs.h renamed from include/linux/ext3_fs.h~fix-64kb-blocksize-in-ext3-directories +20 -0
diff -puN include/linux/ext3_fs.h~fix-64kb-blocksize-in-ext3-directories include/linux/ext3_fs.h
@@ -656,6 +656,26 @@ struct ext3_dir_entry_2 {
 #define EXT3_DIR_ROUND			(EXT3_DIR_PAD - 1)
 #define EXT3_DIR_REC_LEN(name_len)	(((name_len) + 8 + EXT3_DIR_ROUND) & \
 					 ~EXT3_DIR_ROUND)
+#define EXT3_MAX_REC_LEN		((1<<16)-1)
+
+static inline unsigned ext3_rec_len_from_disk(__le16 dlen)
+{
+	unsigned len = le16_to_cpu(dlen);
+
+	if (len == EXT3_MAX_REC_LEN)
+		return 1 << 16;
+	return len;
+}
+
+static inline __le16 ext3_rec_len_to_disk(unsigned len)
+{
+	if (len == (1 << 16))
+		return cpu_to_le16(EXT3_MAX_REC_LEN);
+	else if (len > (1 << 16))
+		BUG();
+	return cpu_to_le16(len);
+}
+
 /*
  * Hash Tree Directory indexing
  * (c) Daniel Phillips, 2001

_