Whamcloud - gitweb
e0c6f8d8cac5b07d1f3fc16d775e57d06a815f46
[fs/lustre-release.git] / ldiskfs / kernel_patches / patches / ext4-wantedi-2.6-rhel5.patch
1 Index: linux-2.6.18.i386/fs/ext4/ialloc.c
2 ===================================================================
3 --- linux-2.6.18.i386.orig/fs/ext4/ialloc.c
4 +++ linux-2.6.18.i386/fs/ext4/ialloc.c
5 @@ -576,7 +576,8 @@ static int find_group_other(struct super
6   * For other inodes, search forward from the parent directory's block
7   * group to find a free inode.
8   */
9 -struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode)
10 +struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode,
11 +                            unsigned long goal)
12  {
13         struct super_block *sb;
14         struct buffer_head *bitmap_bh = NULL;
15 @@ -607,6 +608,43 @@ struct inode *ext4_new_inode(handle_t *h
16         sbi = EXT4_SB(sb);
17         es = sbi->s_es;
18  
19 +       if (goal) {
20 +               group = (goal - 1) / EXT4_INODES_PER_GROUP(sb);
21 +               ino = (goal - 1) % EXT4_INODES_PER_GROUP(sb);
22 +               err = -EIO;
23 +
24 +               gdp = ext4_get_group_desc(sb, group, &bh2);
25 +               if (!gdp)
26 +                       goto fail;
27 +
28 +               bitmap_bh = ext4_read_inode_bitmap(sb, group);
29 +               if (!bitmap_bh)
30 +                       goto fail;
31 +
32 +               BUFFER_TRACE(bh, "get_write_access");
33 +               err = ext4_journal_get_write_access(handle, bitmap_bh);
34 +               if (err)
35 +                       goto fail;
36 +
37 +               if (ext4_set_bit_atomic(sb_bgl_lock(sbi, group),
38 +                                       ino, bitmap_bh->b_data)) {
39 +                       printk(KERN_ERR "goal inode %lu unavailable\n", goal);
40 +                       /* Oh well, we tried. */
41 +                       goto continue_allocation;
42 +               }
43 +
44 +               BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata");
45 +               err = ext4_journal_dirty_metadata(handle, bitmap_bh);
46 +               if (err)
47 +                       goto fail;
48 +
49 +               /* We've shortcircuited the allocation system successfully,
50 +                * now finish filling in the inode.
51 +                */
52 +               goto got;
53 +       }
54 +
55 +continue_allocation:
56         if (sbi->s_log_groups_per_flex) {
57                 ret2 = find_group_flex(sb, dir, &group);
58                 goto got_group;
59 Index: linux-2.6.18.i386/fs/ext4/namei.c
60 ===================================================================
61 --- linux-2.6.18.i386.orig/fs/ext4/namei.c
62 +++ linux-2.6.18.i386/fs/ext4/namei.c
63 @@ -104,6 +104,7 @@ struct dx_entry
64         __le32 block;
65  };
66  
67 +
68  /*
69   * dx_root_info is laid out so that if it should somehow get overlaid by a
70   * dirent the two low bits of the hash version will be zero.  Therefore, the
71 @@ -149,6 +150,14 @@ struct dx_map_entry
72         u16 size;
73  };
74  
75 +#define LVFS_DENTRY_PARAM_MAGIC                20070216UL
76 +struct lvfs_dentry_params
77 +{
78 +       unsigned long   p_inum;
79 +       void        *p_ptr;
80 +       u32          magic;
81 +};
82 +
83  static inline ext4_lblk_t dx_get_block(struct dx_entry *entry);
84  static void dx_set_block(struct dx_entry *entry, ext4_lblk_t value);
85  static inline unsigned dx_get_hash (struct dx_entry *entry);
86 @@ -1708,6 +1717,20 @@ static int ext4_add_nondir(handle_t *han
87         return err;
88  }
89  
90 +static struct inode * ext4_new_inode_wantedi(handle_t *handle, struct inode *dir,
91 +                                               int mode, struct dentry *dentry)
92 +{
93 +       unsigned long inum = 0;
94 +
95 +       if (dentry->d_fsdata != NULL) {
96 +               struct lvfs_dentry_params *param = dentry->d_fsdata;
97 +
98 +               if (param->magic == LVFS_DENTRY_PARAM_MAGIC)
99 +                       inum = param->p_inum;
100 +       }
101 +       return ext4_new_inode(handle, dir, mode, inum);
102 +}
103 +
104  /*
105   * By the time this is called, we already have created
106   * the directory cache entry for the new file, but it
107 @@ -1733,7 +1756,7 @@ retry:
108         if (IS_DIRSYNC(dir))
109                 handle->h_sync = 1;
110  
111 -       inode = ext4_new_inode (handle, dir, mode);
112 +       inode = ext4_new_inode_wantedi (handle, dir, mode, dentry);
113         err = PTR_ERR(inode);
114         if (!IS_ERR(inode)) {
115                 inode->i_op = &ext4_file_inode_operations;
116 @@ -1767,7 +1790,7 @@ retry:
117         if (IS_DIRSYNC(dir))
118                 handle->h_sync = 1;
119  
120 -       inode = ext4_new_inode (handle, dir, mode);
121 +       inode = ext4_new_inode_wantedi (handle, dir, mode, dentry);
122         err = PTR_ERR(inode);
123         if (!IS_ERR(inode)) {
124                 init_special_inode(inode, inode->i_mode, rdev);
125 @@ -1803,7 +1826,7 @@ retry:
126         if (IS_DIRSYNC(dir))
127                 handle->h_sync = 1;
128  
129 -       inode = ext4_new_inode (handle, dir, S_IFDIR | mode);
130 +       inode = ext4_new_inode_wantedi (handle, dir, S_IFDIR | mode, dentry);
131         err = PTR_ERR(inode);
132         if (IS_ERR(inode))
133                 goto out_stop;
134 @@ -2203,7 +2226,7 @@ retry:
135         if (IS_DIRSYNC(dir))
136                 handle->h_sync = 1;
137  
138 -       inode = ext4_new_inode (handle, dir, S_IFLNK|S_IRWXUGO);
139 +       inode = ext4_new_inode_wantedi (handle, dir, S_IFLNK|S_IRWXUGO, dentry);
140         err = PTR_ERR(inode);
141         if (IS_ERR(inode))
142                 goto out_stop;
143 Index: linux-2.6.18.i386/fs/ext4/ext4.h
144 ===================================================================
145 --- linux-2.6.18.i386.orig/fs/ext4/ext4.h
146 +++ linux-2.6.18.i386/fs/ext4/ext4.h
147 @@ -1013,7 +1013,8 @@ extern int ext4fs_dirhash(const char *na
148                           dx_hash_info *hinfo);
149  
150  /* ialloc.c */
151 -extern struct inode * ext4_new_inode (handle_t *, struct inode *, int);
152 +extern struct inode * ext4_new_inode (handle_t *, struct inode *, int,
153 +                                     unsigned long);
154  extern void ext4_free_inode (handle_t *, struct inode *);
155  extern struct inode * ext4_orphan_get (struct super_block *, unsigned long);
156  extern unsigned long ext4_count_free_inodes (struct super_block *);
157 Index: linux-2.6.18.i386/fs/ext4/migrate.c
158 ===================================================================
159 --- linux-2.6.18.i386.orig/fs/ext4/migrate.c
160 +++ linux-2.6.18.i386/fs/ext4/migrate.c
161 @@ -485,7 +485,7 @@ int ext4_ext_migrate(struct inode *inode
162         }
163         tmp_inode = ext4_new_inode(handle,
164                                 inode->i_sb->s_root->d_inode,
165 -                               S_IFREG);
166 +                               S_IFREG, 0);
167         if (IS_ERR(tmp_inode)) {
168                 retval = -ENOMEM;
169                 ext4_journal_stop(handle);