make use of dentry->d_fsdata to pass fid to ext4. so no
changes in ext4_add_entry() interface required.
-Index: linux-2.6.32.i386/fs/ext4/dir.c
+Index: linux-stage/fs/ext4/dir.c
===================================================================
---- linux-2.6.32.i386.orig/fs/ext4/dir.c 2009-12-03 09:21:21.000000000 +0530
-+++ linux-2.6.32.i386/fs/ext4/dir.c 2010-04-16 06:25:43.000000000 +0530
-@@ -53,11 +53,18 @@
+--- linux-stage.orig/fs/ext4/dir.c
++++ linux-stage/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)
{
}
-@@ -70,11 +77,11 @@
+@@ -70,11 +77,11 @@ int ext4_check_dir_entry(const char *fun
const int rlen = ext4_rec_len_from_disk(de->rec_len,
dir->i_sb->s_blocksize);
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";
-@@ -179,7 +186,7 @@
+@@ -181,7 +188,7 @@ revalidate:
* failure will be detected in the
* dirent test below. */
if (ext4_rec_len_from_disk(de->rec_len,
break;
i += ext4_rec_len_from_disk(de->rec_len,
sb->s_blocksize);
-@@ -342,12 +349,17 @@
+@@ -344,12 +351,17 @@ int ext4_htree_store_dirent(struct file
struct fname *fname, *new_fn;
struct dir_private_info *info;
int len;
new_fn = kzalloc(len, GFP_KERNEL);
if (!new_fn)
return -ENOMEM;
-@@ -356,7 +368,7 @@
+@@ -358,7 +370,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;
new_fn->name[dirent->name_len] = 0;
while (*p) {
-Index: linux-2.6.32.i386/fs/ext4/ext4.h
+Index: linux-stage/fs/ext4/ext4.h
===================================================================
---- linux-2.6.32.i386.orig/fs/ext4/ext4.h 2010-04-16 06:10:06.000000000 +0530
-+++ linux-2.6.32.i386/fs/ext4/ext4.h 2010-04-16 06:27:40.000000000 +0530
-@@ -1135,6 +1135,7 @@
+--- linux-stage.orig/fs/ext4/ext4.h
++++ linux-stage/fs/ext4/ext4.h
+@@ -1187,6 +1187,7 @@ static inline void ext4_clear_inode_stat
#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080
#define EXT4_FEATURE_INCOMPAT_MMP 0x0100
#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200
#define EXT4_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR
#define EXT4_FEATURE_INCOMPAT_SUPP (EXT4_FEATURE_INCOMPAT_FILETYPE| \
-@@ -1143,7 +1144,9 @@
+@@ -1195,7 +1196,9 @@ static inline void ext4_clear_inode_stat
EXT4_FEATURE_INCOMPAT_EXTENTS| \
EXT4_FEATURE_INCOMPAT_64BIT| \
EXT4_FEATURE_INCOMPAT_FLEX_BG| \
#define EXT4_FEATURE_RO_COMPAT_SUPP (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \
EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \
EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \
-@@ -1225,6 +1228,43 @@
+@@ -1277,6 +1280,43 @@ struct ext4_dir_entry_2 {
#define EXT4_FT_SYMLINK 7
#define EXT4_FT_MAX 8
/*
* EXT4_DIR_PAD defines the directory entries boundaries
-@@ -1233,8 +1273,11 @@
+@@ -1285,8 +1325,11 @@ struct ext4_dir_entry_2 {
*/
#define EXT4_DIR_PAD 4
#define EXT4_DIR_ROUND (EXT4_DIR_PAD - 1)
+
#define EXT4_MAX_REC_LEN ((1<<16)-1)
- /*
-@@ -1524,7 +1567,7 @@
+ static inline unsigned int
+@@ -1613,7 +1656,7 @@ extern struct buffer_head * ext4_find_en
struct ext4_dir_entry_2 ** res_dir);
#define ll_ext4_find_entry(inode, dentry, res_dir) ext4_find_entry(inode, &(dentry)->d_name, res_dir)
extern int ext4_add_dot_dotdot(handle_t *handle, struct inode *dir,
extern struct buffer_head *ext4_append(handle_t *handle,
struct inode *inode,
ext4_lblk_t *block, int *err);
-@@ -1851,6 +1894,28 @@
- set_bit(BH_BITMAP_UPTODATE, &(bh)->b_state);
- }
+@@ -1944,6 +1987,28 @@ static inline void set_bitmap_uptodate(s
+
+ #define in_range(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1)
+/*
+ * Compute the total directory entry data length.
#endif /* __KERNEL__ */
#endif /* _EXT4_H */
-Index: linux-2.6.32.i386/fs/ext4/namei.c
+Index: linux-stage/fs/ext4/namei.c
===================================================================
---- linux-2.6.32.i386.orig/fs/ext4/namei.c 2010-04-16 05:47:41.000000000 +0530
-+++ linux-2.6.32.i386/fs/ext4/namei.c 2010-04-16 06:40:38.000000000 +0530
-@@ -170,7 +170,8 @@
+--- linux-stage.orig/fs/ext4/namei.c
++++ linux-stage/fs/ext4/namei.c
+@@ -169,7 +169,8 @@ static unsigned dx_get_count(struct dx_e
static unsigned dx_get_limit(struct dx_entry *entries);
static void dx_set_count(struct dx_entry *entries, unsigned value);
static void dx_set_limit(struct dx_entry *entries, unsigned value);
static unsigned dx_node_limit(struct inode *dir);
static struct dx_frame *dx_probe(const struct qstr *d_name,
struct inode *dir,
-@@ -237,11 +238,12 @@
+@@ -212,11 +213,12 @@ ext4_next_entry(struct ext4_dir_entry_2
*/
struct dx_root_info * dx_get_dx_info(struct ext4_dir_entry_2 *de)
{
return (struct dx_root_info *) de;
}
-@@ -286,16 +288,23 @@
+@@ -261,16 +263,23 @@ static inline void dx_set_limit(struct d
((struct dx_countlimit *) entries)->limit = cpu_to_le16(value);
}
return entry_space / sizeof(struct dx_entry);
}
-@@ -342,7 +351,7 @@
+@@ -317,7 +326,7 @@ static struct stats dx_show_leaf(struct
printk(":%x.%u ", h.hash,
((char *) de - base));
}
names++;
}
de = ext4_next_entry(de, size);
-@@ -447,7 +456,8 @@
+@@ -419,7 +428,8 @@ dx_probe(const struct qstr *d_name, stru
entries = (struct dx_entry *) (((char *)info) + info->info_length);
+ if (dx_get_limit(entries) != dx_root_limit(dir->i_sb->s_blocksize,
+ (struct ext4_dir_entry_2*)bh->b_data,
info->info_length)) {
- ext4_warning(dir->i_sb, __func__,
- "dx entry: limit != root limit");
-@@ -637,7 +647,7 @@
+ ext4_warning(dir->i_sb, "dx entry: limit != root limit");
+ brelse(bh);
+@@ -608,7 +618,7 @@ static int htree_dirblock_to_tree(struct
de = (struct ext4_dir_entry_2 *) bh->b_data;
top = (struct ext4_dir_entry_2 *) ((char *) de +
dir->i_sb->s_blocksize -
for (; de < top; de = ext4_next_entry(de, dir->i_sb->s_blocksize)) {
if (!ext4_check_dir_entry("htree_dirblock_to_tree", dir, de, bh,
(block<<EXT4_BLOCK_SIZE_BITS(dir->i_sb))
-@@ -1050,7 +1060,7 @@
+@@ -1020,7 +1030,7 @@ static struct buffer_head * ext4_dx_find
goto errout;
de = (struct ext4_dir_entry_2 *) bh->b_data;
top = (struct ext4_dir_entry_2 *) ((char *) de + sb->s_blocksize -
for (; de < top; de = ext4_next_entry(de, sb->s_blocksize)) {
int off = (block << EXT4_BLOCK_SIZE_BITS(sb))
+ ((char *) de - bh->b_data);
-@@ -1216,7 +1226,7 @@
+@@ -1181,7 +1191,7 @@ dx_move_dirents(char *from, char *to, st
while (count--) {
struct ext4_dir_entry_2 *de = (struct ext4_dir_entry_2 *)
(from + (map->offs<<2));
memcpy (to, de, rec_len);
((struct ext4_dir_entry_2 *) to)->rec_len =
ext4_rec_len_to_disk(rec_len, blocksize);
-@@ -1240,7 +1250,7 @@
+@@ -1205,7 +1215,7 @@ static struct ext4_dir_entry_2* dx_pack_
while ((char*)de < base + blocksize) {
next = ext4_next_entry(de, blocksize);
if (de->inode && de->name_len) {
if (de > to)
memmove(to, de, rec_len);
to->rec_len = ext4_rec_len_to_disk(rec_len, blocksize);
-@@ -1370,10 +1380,16 @@
+@@ -1335,10 +1345,16 @@ static int add_dirent_to_buf(handle_t *h
unsigned int offset = 0;
unsigned int blocksize = dir->i_sb->s_blocksize;
unsigned short reclen;
if (!de) {
de = (struct ext4_dir_entry_2 *)bh->b_data;
top = bh->b_data + blocksize - reclen;
-@@ -1383,7 +1399,7 @@
+@@ -1348,7 +1364,7 @@ static int add_dirent_to_buf(handle_t *h
return -EIO;
if (ext4_match(namelen, name, de))
return -EEXIST;
rlen = ext4_rec_len_from_disk(de->rec_len, blocksize);
if ((de->inode? rlen - nlen: rlen) >= reclen)
break;
-@@ -1401,7 +1417,7 @@
+@@ -1366,7 +1382,7 @@ static int add_dirent_to_buf(handle_t *h
}
/* By now the buffer is marked for journaling */
rlen = ext4_rec_len_from_disk(de->rec_len, blocksize);
if (de->inode) {
struct ext4_dir_entry_2 *de1 = (struct ext4_dir_entry_2 *)((char *)de + nlen);
-@@ -1417,6 +1433,12 @@
+@@ -1382,6 +1398,12 @@ static int add_dirent_to_buf(handle_t *h
de->inode = 0;
de->name_len = namelen;
memcpy(de->name, name, namelen);
/*
* XXX shouldn't update any times until successful
* completion of syscall, but too many callers depend
-@@ -1515,7 +1537,8 @@
+@@ -1480,7 +1502,8 @@ static int make_indexed_dir(handle_t *ha
dx_set_block(entries, 1);
dx_set_count(entries, 1);
/* Initialize as for dx_probe */
hinfo.hash_version = dx_info->hash_version;
-@@ -1546,6 +1569,8 @@
+@@ -1511,6 +1534,8 @@ static int ext4_update_dotdot(handle_t *
struct buffer_head * dir_block;
struct ext4_dir_entry_2 * de;
int len, journal = 0, err = 0;
if (IS_ERR(handle))
return PTR_ERR(handle);
-@@ -1561,19 +1586,24 @@
+@@ -1526,19 +1551,24 @@ static int ext4_update_dotdot(handle_t *
/* the first item must be "." */
assert(de->name_len == 1 && de->name[0] == '.');
len = le16_to_cpu(de->rec_len);
de = (struct ext4_dir_entry_2 *)
((char *) de + le16_to_cpu(de->rec_len));
if (!journal) {
-@@ -1587,10 +1617,15 @@
+@@ -1552,10 +1582,15 @@ static int ext4_update_dotdot(handle_t *
if (len > 0)
de->rec_len = cpu_to_le16(len);
else
out_journal:
if (journal) {
-@@ -2011,12 +2046,13 @@
+@@ -1978,12 +2013,13 @@ retry:
/* 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,
if (IS_ERR(handle))
return PTR_ERR(handle);
-@@ -2040,17 +2076,32 @@
+@@ -2007,17 +2043,32 @@ int ext4_add_dot_dotdot(handle_t *handle
de = (struct ext4_dir_entry_2 *) dir_block->b_data;
de->inode = cpu_to_le32(inode->i_ino);
de->name_len = 1;
inode->i_nlink = 2;
BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata");
ext4_handle_dirty_metadata(handle, dir, dir_block);
-@@ -2087,7 +2138,7 @@
+@@ -2054,7 +2105,7 @@ retry:
if (IS_ERR(inode))
goto out_stop;
- err = ext4_add_dot_dotdot(handle, dir, inode);
+ err = ext4_add_dot_dotdot(handle, dir, inode, NULL, NULL);
- if (err)
+ if (err) {
+ unlock_new_inode(inode);
goto out_stop;
-
-@@ -2123,7 +2174,7 @@
+@@ -2092,7 +2143,7 @@ static int empty_dir(struct inode *inode
int err = 0;
sb = inode->i_sb;
+ if (inode->i_size < __EXT4_DIR_REC_LEN(1) + __EXT4_DIR_REC_LEN(2) ||
!(bh = ext4_bread(NULL, inode, 0, 0, &err))) {
if (err)
- ext4_error(inode->i_sb, __func__,
+ ext4_error(inode->i_sb,