Whamcloud - gitweb
Branch b1_8
[fs/lustre-release.git] / ldiskfs / kernel_patches / patches / ext4-wantedi-2.6-sles11.patch
1 Index: linux-stage/fs/ext4/ialloc.c
2 ===================================================================
3 --- linux-stage.orig/fs/ext4/ialloc.c
4 +++ linux-stage/fs/ext4/ialloc.c
5 @@ -675,7 +675,8 @@ err_ret:
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 *inode_bitmap_bh = NULL;
15 @@ -706,6 +707,51 @@ 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, &group_desc_bh);
25 +               if (!gdp)
26 +                       goto fail;
27 +
28 +               inode_bitmap_bh = ext4_read_inode_bitmap(sb, group);
29 +               if (!inode_bitmap_bh)
30 +                       goto fail;
31 +
32 +               BUFFER_TRACE(bh, "get_write_access");
33 +               err = ext4_journal_get_write_access(handle, inode_bitmap_bh);
34 +               if (err)
35 +                       goto fail;
36 +
37 +               BUFFER_TRACE(group_desc_bh, "get_write_access");
38 +               err = ext4_journal_get_write_access(handle, group_desc_bh);
39 +               if (err)
40 +                       goto fail;
41 +
42 +               err = ext4_claim_inode(sb, inode_bitmap_bh, ino, group, mode);
43 +               if (err) {
44 +                       printk(KERN_ERR "goal inode %lu unavailable\n", goal);
45 +                       /* Oh well, we tried. */
46 +                       jbd2_journal_release_buffer(handle, inode_bitmap_bh);
47 +                       jbd2_journal_release_buffer(handle, group_desc_bh);
48 +                       goto continue_allocation;
49 +               }
50 +
51 +               /* we won it */
52 +               BUFFER_TRACE(inode_bitmap_bh,
53 +                            "call ext4_journal_dirty_metadata");
54 +               err = ext4_journal_dirty_metadata(handle, inode_bitmap_bh);
55 +               if (err)
56 +                       goto fail;
57 +
58 +               /* zero bit is inode number 1*/
59 +               ino++;
60 +               goto got;
61 +       }
62 +
63 +continue_allocation:
64         if (sbi->s_log_groups_per_flex) {
65                 ret2 = find_group_flex(sb, dir, &group);
66                 goto got_group;
67 Index: linux-stage/fs/ext4/namei.c
68 ===================================================================
69 --- linux-stage.orig/fs/ext4/namei.c
70 +++ linux-stage/fs/ext4/namei.c
71 @@ -104,6 +104,7 @@ struct dx_entry
72         __le32 block;
73  };
74  
75 +
76  /*
77   * dx_root_info is laid out so that if it should somehow get overlaid by a
78   * dirent the two low bits of the hash version will be zero.  Therefore, the
79 @@ -149,6 +150,14 @@ struct dx_map_entry
80         u16 size;
81  };
82  
83 +#define LVFS_DENTRY_PARAM_MAGIC                20070216UL
84 +struct lvfs_dentry_params
85 +{
86 +       unsigned long   p_inum;
87 +       void        *p_ptr;
88 +       u32          magic;
89 +};
90 +
91  static inline ext4_lblk_t dx_get_block(struct dx_entry *entry);
92  static void dx_set_block(struct dx_entry *entry, ext4_lblk_t value);
93  static inline unsigned dx_get_hash(struct dx_entry *entry);
94 @@ -1716,6 +1725,20 @@ static int ext4_add_nondir(handle_t *han
95         return err;
96  }
97  
98 +static struct inode * ext4_new_inode_wantedi(handle_t *handle, struct inode *dir,
99 +                                               int mode, struct dentry *dentry)
100 +{
101 +       unsigned long inum = 0;
102 +
103 +       if (dentry->d_fsdata != NULL) {
104 +               struct lvfs_dentry_params *param = dentry->d_fsdata;
105 +
106 +               if (param->magic == LVFS_DENTRY_PARAM_MAGIC)
107 +                       inum = param->p_inum;
108 +       }
109 +       return ext4_new_inode(handle, dir, mode, inum);
110 +}
111 +
112  /*
113   * By the time this is called, we already have created
114   * the directory cache entry for the new file, but it
115 @@ -1741,7 +1764,7 @@ retry:
116         if (IS_DIRSYNC(dir))
117                 handle->h_sync = 1;
118  
119 -       inode = ext4_new_inode (handle, dir, mode);
120 +       inode = ext4_new_inode_wantedi(handle, dir, mode, dentry);
121         err = PTR_ERR(inode);
122         if (!IS_ERR(inode)) {
123                 inode->i_op = &ext4_file_inode_operations;
124 @@ -1775,7 +1798,7 @@ retry:
125         if (IS_DIRSYNC(dir))
126                 handle->h_sync = 1;
127  
128 -       inode = ext4_new_inode(handle, dir, mode);
129 +       inode = ext4_new_inode_wantedi(handle, dir, mode, dentry);
130         err = PTR_ERR(inode);
131         if (!IS_ERR(inode)) {
132                 init_special_inode(inode, inode->i_mode, rdev);
133 @@ -1811,7 +1834,7 @@ retry:
134         if (IS_DIRSYNC(dir))
135                 handle->h_sync = 1;
136  
137 -       inode = ext4_new_inode(handle, dir, S_IFDIR | mode);
138 +       inode = ext4_new_inode_wantedi(handle, dir, S_IFDIR | mode, dentry);
139         err = PTR_ERR(inode);
140         if (IS_ERR(inode))
141                 goto out_stop;
142 @@ -2211,7 +2234,7 @@ retry:
143         if (IS_DIRSYNC(dir))
144                 handle->h_sync = 1;
145  
146 -       inode = ext4_new_inode(handle, dir, S_IFLNK|S_IRWXUGO);
147 +       inode = ext4_new_inode_wantedi(handle, dir, S_IFLNK|S_IRWXUGO, dentry);
148         err = PTR_ERR(inode);
149         if (IS_ERR(inode))
150                 goto out_stop;
151 Index: linux-stage/fs/ext4/ext4.h
152 ===================================================================
153 --- linux-stage.orig/fs/ext4/ext4.h
154 +++ linux-stage/fs/ext4/ext4.h
155 @@ -1032,7 +1032,8 @@ extern int ext4fs_dirhash(const char *na
156                           dx_hash_info *hinfo);
157  
158  /* ialloc.c */
159 -extern struct inode * ext4_new_inode(handle_t *, struct inode *, int);
160 +extern struct inode * ext4_new_inode(handle_t *, struct inode *, int,
161 +                                    unsigned long);
162  extern void ext4_free_inode(handle_t *, struct inode *);
163  extern struct inode * ext4_orphan_get(struct super_block *, unsigned long);
164  extern unsigned long ext4_count_free_inodes(struct super_block *);
165 Index: linux-stage/fs/ext4/migrate.c
166 ===================================================================
167 --- linux-stage.orig/fs/ext4/migrate.c
168 +++ linux-stage/fs/ext4/migrate.c
169 @@ -484,7 +484,7 @@ int ext4_ext_migrate(struct inode *inode
170         }
171         tmp_inode = ext4_new_inode(handle,
172                                 inode->i_sb->s_root->d_inode,
173 -                               S_IFREG);
174 +                               S_IFREG, 0);
175         if (IS_ERR(tmp_inode)) {
176                 retval = -ENOMEM;
177                 ext4_journal_stop(handle);