Viewing: ext4-dirdata-lustre-compat.patch
Index: linux-stage/fs/ext4/ext4.h
===================================================================
--- linux-stage.orig/fs/ext4/ext4.h
+++ linux-stage/fs/ext4/ext4.h
@@ -1170,6 +1170,7 @@ struct ext4_inode_info {
__u32 i_csum_seed;
kprojid_t i_projid;
+ void *i_dirdata;
};
/*
@@ -2426,6 +2427,13 @@ struct ext4_dir_entry_tail {
#define EXT4_DIRENT_INO64 0x20
#define EXT4_DIRENT_CFHASH 0x40
+#define EXT4_LUFID_MAGIC 0xAD200907UL
+struct ext4_dentry_param {
+ __u32 edp_magic; /* EXT4_LUFID_MAGIC */
+ char edp_len; /* size of edp_data in bytes */
+ char edp_data[]; /* packed array of data */
+} __packed;
+
struct ext4_dirent_data_header {
/* length of this header + the whole data blob */
__u8 ddh_length;
@@ -2436,6 +2444,17 @@ struct ext4_dirent_hash {
struct ext4_dir_entry_hash dh_hash;
} __packed;
+static inline unsigned char *ext4_dentry_get_data(struct super_block *sb,
+ struct ext4_dentry_param *p)
+{
+ if (!ext4_has_feature_dirdata(sb))
+ return NULL;
+ if (p && p->edp_magic == EXT4_LUFID_MAGIC)
+ return &p->edp_len;
+ else
+ return NULL;
+}
+
#define EXT4_FT_DIR_CSUM 0xDE
/*
Index: linux-stage/fs/ext4/namei.c
===================================================================
--- linux-stage.orig/fs/ext4/namei.c
+++ linux-stage/fs/ext4/namei.c
@@ -2254,6 +2254,8 @@ static int add_dirent_to_buf(handle_t *h
if (ext4_has_metadata_csum(inode->i_sb))
csum_size = sizeof(struct ext4_dir_entry_tail);
+ data = ext4_dentry_get_data(inode->i_sb, (struct ext4_dentry_param *)
+ EXT4_I(inode)->i_dirdata);
if (!de) {
if (data)
dlen = (*data) + 1;
@@ -2626,7 +2628,8 @@ static int ext4_update_dotdot(handle_t *
dotdot_de->inode = cpu_to_le32(inode->i_ino);
- /* Deliver data any appropriate way here. Now it is NULL */
+ data = ext4_dentry_get_data(dir->i_sb,
+ (struct ext4_dentry_param *)dentry->d_fsdata);
if (data != NULL) {
dlen = *data + 1;
if (is_dx(dir)) {
@@ -2686,6 +2689,7 @@ static int ext4_add_entry(handle_t *hand
ext4_lblk_t block, blocks;
int csum_size = 0;
+ EXT4_I(inode)->i_dirdata = dentry->d_fsdata;
if (ext4_has_metadata_csum(inode->i_sb))
csum_size = sizeof(struct ext4_dir_entry_tail);
@@ -3268,20 +3272,50 @@ struct ext4_dir_entry_2 *ext4_init_dot_d
int blocksize, int csum_size,
unsigned int parent_ino, int dotdot_real_len)
{
+ void *data1 = NULL, *data2 = NULL;
+ int dot_reclen = 0;
+
+ if (dotdot_real_len == 10) {
+ struct tmp_block *tmpb = (struct tmp_block *)inode;
+ data1 = tmpb->tmpb_data1;
+ data2 = tmpb->tmpb_data2;
+ inode = tmpb->tmpb_inode;
+ dotdot_real_len = 0;
+ }
+
de->inode = cpu_to_le32(inode->i_ino);
de->name_len = 1;
- de->rec_len = ext4_rec_len_to_disk(ext4_dir_rec_len(de->name_len, NULL),
- blocksize);
strcpy(de->name, ".");
ext4_set_de_type(inode->i_sb, de, S_IFDIR);
+ /* get packed fid data*/
+ data1 = ext4_dentry_get_data(inode->i_sb,
+ (struct ext4_dentry_param *) data1);
+ if (data1) {
+ de->name[1] = 0;
+ memcpy(&de->name[2], data1, *(char *) data1);
+ de->file_type |= EXT4_DIRENT_LUFID;
+ }
+ de->rec_len = cpu_to_le16(ext4_dir_entry_len(de, NULL));
+
+ dot_reclen = cpu_to_le16(de->rec_len);
de = ext4_next_entry(de, blocksize);
de->inode = cpu_to_le32(parent_ino);
de->name_len = 2;
+
+ strcpy(de->name, "..");
+ ext4_set_de_type(inode->i_sb, de, S_IFDIR);
+ data2 = ext4_dentry_get_data(inode->i_sb,
+ (struct ext4_dentry_param *) data2);
+ if (data2) {
+ de->name[2] = 0;
+ memcpy(&de->name[3], data2, *(char *) data2);
+ de->file_type |= EXT4_DIRENT_LUFID;
+ }
+
if (!dotdot_real_len)
de->rec_len = ext4_rec_len_to_disk(blocksize -
- (csum_size + ext4_dir_rec_len(1, NULL)),
- blocksize);
+ (csum_size + dot_reclen), blocksize);
else
de->rec_len = ext4_rec_len_to_disk(
ext4_dir_entry_len(de, NULL),
@@ -3404,6 +3438,29 @@ out_retry:
return err;
}
+/* Initialize @inode as a subdirectory of @dir, and add the
+ * "." and ".." entries into the first directory block. */
+int ext4_add_dot_dotdot(handle_t *handle, struct inode *dir,
+ struct inode *inode,
+ const void *data1, const void *data2)
+{
+ int rc;
+
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+
+ if (IS_DIRSYNC(dir))
+ ext4_handle_sync(handle);
+
+ inode->i_op = &ext4_dir_inode_operations;
+ inode->i_fop = &ext4_dir_operations;
+ rc = ext4_init_new_dir(handle, dir, inode, data1, data2);
+ if (!rc)
+ rc = ext4_mark_inode_dirty(handle, inode);
+ return rc;
+}
+EXPORT_SYMBOL(ext4_add_dot_dotdot);
+
/*
* routine to check that the specified directory is empty (for rmdir)
*/