Whamcloud - gitweb
b=19686
[fs/lustre-release.git] / ldiskfs / kernel_patches / patches / ext4-wantedi-2.6-sles11.patch
1 Index: linux-2.6.27.21-0.1/fs/ext4/ialloc.c
2 ===================================================================
3 --- linux-2.6.27.21-0.1.orig/fs/ext4/ialloc.c   2009-06-02 18:39:22.000000000 +0530
4 +++ linux-2.6.27.21-0.1/fs/ext4/ialloc.c        2009-06-04 17:01:26.000000000 +0530
5 @@ -675,7 +675,8 @@
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,48 @@
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 +               if (ext4_set_bit_atomic(sb_bgl_lock(sbi, group),
38 +                                       ino, inode_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, inode_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 +               BUFFER_TRACE(group_desc_bh, "get_write_access");
53 +               err = ext4_journal_get_write_access(handle, group_desc_bh);
54 +               if (err)
55 +                       goto fail;
56 +
57 +               goto got;
58 +       }
59 +
60 +continue_allocation:
61         if (sbi->s_log_groups_per_flex) {
62                 ret2 = find_group_flex(sb, dir, &group);
63                 goto got_group;
64 Index: linux-2.6.27.21-0.1/fs/ext4/namei.c
65 ===================================================================
66 --- linux-2.6.27.21-0.1.orig/fs/ext4/namei.c    2009-06-02 18:39:22.000000000 +0530
67 +++ linux-2.6.27.21-0.1/fs/ext4/namei.c 2009-06-04 17:00:38.000000000 +0530
68 @@ -104,6 +104,7 @@
69         __le32 block;
70  };
71  
72 +
73  /*
74   * dx_root_info is laid out so that if it should somehow get overlaid by a
75   * dirent the two low bits of the hash version will be zero.  Therefore, the
76 @@ -149,6 +150,14 @@
77         u16 size;
78  };
79  
80 +#define LVFS_DENTRY_PARAM_MAGIC                20070216UL
81 +struct lvfs_dentry_params
82 +{
83 +       unsigned long   p_inum;
84 +       void        *p_ptr;
85 +       u32          magic;
86 +};
87 +
88  static inline ext4_lblk_t dx_get_block(struct dx_entry *entry);
89  static void dx_set_block(struct dx_entry *entry, ext4_lblk_t value);
90  static inline unsigned dx_get_hash(struct dx_entry *entry);
91 @@ -1716,6 +1725,20 @@
92         return err;
93  }
94  
95 +static struct inode * ext4_new_inode_wantedi(handle_t *handle, struct inode *dir,
96 +                                               int mode, struct dentry *dentry)
97 +{
98 +       unsigned long inum = 0;
99 +
100 +       if (dentry->d_fsdata != NULL) {
101 +               struct lvfs_dentry_params *param = dentry->d_fsdata;
102 +
103 +               if (param->magic == LVFS_DENTRY_PARAM_MAGIC)
104 +                       inum = param->p_inum;
105 +       }
106 +       return ext4_new_inode(handle, dir, mode, inum);
107 +}
108 +
109  /*
110   * By the time this is called, we already have created
111   * the directory cache entry for the new file, but it
112 @@ -1741,7 +1764,7 @@
113         if (IS_DIRSYNC(dir))
114                 handle->h_sync = 1;
115  
116 -       inode = ext4_new_inode (handle, dir, mode);
117 +       inode = ext4_new_inode_wantedi(handle, dir, mode, dentry);
118         err = PTR_ERR(inode);
119         if (!IS_ERR(inode)) {
120                 inode->i_op = &ext4_file_inode_operations;
121 @@ -1775,7 +1798,7 @@
122         if (IS_DIRSYNC(dir))
123                 handle->h_sync = 1;
124  
125 -       inode = ext4_new_inode(handle, dir, mode);
126 +       inode = ext4_new_inode_wantedi(handle, dir, mode, dentry);
127         err = PTR_ERR(inode);
128         if (!IS_ERR(inode)) {
129                 init_special_inode(inode, inode->i_mode, rdev);
130 @@ -1811,7 +1834,7 @@
131         if (IS_DIRSYNC(dir))
132                 handle->h_sync = 1;
133  
134 -       inode = ext4_new_inode(handle, dir, S_IFDIR | mode);
135 +       inode = ext4_new_inode_wantedi(handle, dir, S_IFDIR | mode, dentry);
136         err = PTR_ERR(inode);
137         if (IS_ERR(inode))
138                 goto out_stop;
139 @@ -2211,7 +2234,7 @@
140         if (IS_DIRSYNC(dir))
141                 handle->h_sync = 1;
142  
143 -       inode = ext4_new_inode(handle, dir, S_IFLNK|S_IRWXUGO);
144 +       inode = ext4_new_inode_wantedi(handle, dir, S_IFLNK|S_IRWXUGO, dentry);
145         err = PTR_ERR(inode);
146         if (IS_ERR(inode))
147                 goto out_stop;
148 Index: linux-2.6.27.21-0.1/fs/ext4/ext4.h
149 ===================================================================
150 --- linux-2.6.27.21-0.1.orig/fs/ext4/ext4.h     2009-06-02 18:39:22.000000000 +0530
151 +++ linux-2.6.27.21-0.1/fs/ext4/ext4.h  2009-06-04 17:00:38.000000000 +0530
152 @@ -1032,7 +1032,8 @@
153                           dx_hash_info *hinfo);
154  
155  /* ialloc.c */
156 -extern struct inode * ext4_new_inode(handle_t *, struct inode *, int);
157 +extern struct inode * ext4_new_inode(handle_t *, struct inode *, int,
158 +                                    unsigned long);
159  extern void ext4_free_inode(handle_t *, struct inode *);
160  extern struct inode * ext4_orphan_get(struct super_block *, unsigned long);
161  extern unsigned long ext4_count_free_inodes(struct super_block *);
162 Index: linux-2.6.27.21-0.1/fs/ext4/migrate.c
163 ===================================================================
164 --- linux-2.6.27.21-0.1.orig/fs/ext4/migrate.c  2009-06-02 18:39:22.000000000 +0530
165 +++ linux-2.6.27.21-0.1/fs/ext4/migrate.c       2009-06-04 17:00:38.000000000 +0530
166 @@ -484,7 +484,7 @@
167         }
168         tmp_inode = ext4_new_inode(handle,
169                                 inode->i_sb->s_root->d_inode,
170 -                               S_IFREG);
171 +                               S_IFREG, 0);
172         if (IS_ERR(tmp_inode)) {
173                 retval = -ENOMEM;
174                 ext4_journal_stop(handle);