Skip to contentSkip to conversation

FEATURE DIRDATA - add user data field in ext4 dirent

PATCH New pravin shelar 1 participant 1 message Aug 28, 2009 ext4 file system

lore
Share & tools
lore
#0 lore raw

PATCH 2/3 FEATURE DIRDATA - add user data field in ext4 dirent

Hi
attached patch adds data field in ext4 dirent. so that user can have data
ext4 dirent.

Thanks,
Pravin.

this patch implements feature which allows ext4 fs uses (e.g. Lustre) store data in ext4 dirent.
data is stored in ext4 dirent after file-name, this space is accounted in de->rec_len. flag EXT4_DIRENT_LUFID added to d_type if extra data is present.

fs/ext4/dir.c +19 -8
Index: b/fs/ext4/dir.c
===================================================================
@@ -53,11 +53,18 @@ const struct file_operations ext4_dir_op
 
 static unsigned char get_dtype(struct super_block *sb, int filetype)
 {
+	int fl_index = filetype & EXT4_FT_MASK;
+
 	if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FILETYPE) ||
-	    (filetype >= EXT4_FT_MAX))
+	    (fl_index >= EXT4_FT_MAX))
 		return DT_UNKNOWN;
 
-	return (ext4_filetype_table[filetype]);
+	if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_DIRDATA))
+		return (ext4_filetype_table[fl_index]);
+
+	return (ext4_filetype_table[fl_index]) |
+		(filetype & EXT4_DIRENT_LUFID);
+
 }
 
 
@@ -69,11 +76,11 @@ int ext4_check_dir_entry (const char * f
 	const char * error_msg = NULL;
 	const int rlen = ext4_rec_len_from_disk(de->rec_len);
 
-	if (rlen < EXT4_DIR_REC_LEN(1))
+	if (rlen < __EXT4_DIR_REC_LEN(1))
 		error_msg = "rec_len is smaller than minimal";
 	else if (rlen % 4 != 0)
 		error_msg = "rec_len % 4 != 0";
-	else if (rlen < EXT4_DIR_REC_LEN(de->name_len))
+	else if (rlen < EXT4_DIR_REC_LEN(de))
 		error_msg = "rec_len is too small for name_len";
 	else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize)
 		error_msg = "directory entry across blocks";
@@ -175,7 +182,7 @@ revalidate:
 				 * failure will be detected in the
 				 * dirent test below. */
 				if (ext4_rec_len_from_disk(de->rec_len)
-						< EXT4_DIR_REC_LEN(1))
+						< __EXT4_DIR_REC_LEN(1))
 					break;
 				i += ext4_rec_len_from_disk(de->rec_len);
 			}
@@ -209,7 +216,6 @@ revalidate:
 				 * during the copy operation.
 				 */
 				u64 version = filp->f_version;
-
 				error = filldir(dirent, de->name,
 						de->name_len,
 						filp->f_pos,
@@ -335,12 +341,17 @@ int ext4_htree_store_dirent(struct file 
 	struct fname * fname, *new_fn;
 	struct dir_private_info *info;
 	int len;
+	int extra_data = 1;
 
 	info = (struct dir_private_info *) dir_file->private_data;
 	p = &info->root.rb_node;
 
 	/* Create and allocate the fname structure */
-	len = sizeof(struct fname) + dirent->name_len + 1;
+	if (dirent->file_type & EXT4_DIRENT_LUFID)
+		extra_data = ext4_get_dirent_data_len(dirent);
+
+	len = sizeof(struct fname) + dirent->name_len + extra_data;
+
 	new_fn = kzalloc(len, GFP_KERNEL);
 	if (!new_fn)
 		return -ENOMEM;
@@ -349,7 +360,7 @@ int ext4_htree_store_dirent(struct file 
 	new_fn->inode = le32_to_cpu(dirent->inode);
 	new_fn->name_len = dirent->name_len;
 	new_fn->file_type = dirent->file_type;
-	memcpy(new_fn->name, dirent->name, dirent->name_len);
+	memcpy(new_fn->name, dirent->name, dirent->name_len + extra_data);
 	new_fn->name[dirent->name_len] = 0;
 
 	while (*p) {
fs/ext4/ext4.h +69 -4

110 lines not on this page · raw message

fs/ext4/namei.c +45 -21

165 lines not on this page · raw message