Whamcloud - gitweb
LU-228 kernel update [RHEL5 U6 2.6.18-238.9.1.el5]
[fs/lustre-release.git] / ldiskfs / kernel_patches / patches / ext4-osd-iop-common.patch
1 diff -rupN linux-2.6.27.21-0.1_1//fs/ext4/ext4.h linux-2.6.27.21-0.1_2//fs/ext4/ext4.h
2 --- linux-2.6.27.21-0.1_1//fs/ext4/ext4.h       2009-08-24 15:32:00.000000000 +0530
3 +++ linux-2.6.27.21-0.1_2//fs/ext4/ext4.h       2009-08-24 15:32:55.000000000 +0530
4 @@ -1171,6 +1171,19 @@ extern int ext4_fiemap(struct inode *, s
5  /* migrate.c */
6  extern int ext4_ext_migrate(struct inode *);
7  /* namei.c */
8 +extern struct inode *ext4_create_inode(handle_t *handle,
9 +                                         struct inode * dir, int mode);
10 +extern int ext4_add_entry(handle_t *handle, struct dentry *dentry,
11 +                            struct inode *inode);
12 +extern int ext4_delete_entry(handle_t *handle, struct inode * dir,
13 +                               struct ext4_dir_entry_2 * de_del,
14 +                               struct buffer_head * bh);
15 +extern struct buffer_head * ext4_find_entry(struct inode *dir,
16 +                                           const struct qstr *d_name,
17 +                                           struct ext4_dir_entry_2 ** res_dir);
18 +#define ll_ext4_find_entry(inode, dentry, res_dir) ext4_find_entry(dir, &(dentry)->d_name, res_dir)
19 +extern int ext4_add_dot_dotdot(handle_t *handle, struct inode *dir,
20 +                                 struct inode *inode);
21  extern int ext4_orphan_add(handle_t *, struct inode *);
22  extern int ext4_orphan_del(handle_t *, struct inode *);
23  extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
24 diff -rupN linux-2.6.27.21-0.1_1//fs/ext4/namei.c linux-2.6.27.21-0.1_2//fs/ext4/namei.c
25 --- linux-2.6.27.21-0.1_1//fs/ext4/namei.c      2009-08-24 15:32:00.000000000 +0530
26 +++ linux-2.6.27.21-0.1_2//fs/ext4/namei.c      2009-08-24 15:43:56.000000000 +0530
27 @@ -24,6 +24,7 @@
28   *     Theodore Ts'o, 2002
29   */
30  
31 +#include <linux/module.h>
32  #include <linux/fs.h>
33  #include <linux/pagemap.h>
34  #include <linux/jbd2.h>
35 @@ -882,9 +883,9 @@ static inline int search_dirblock(struct
36   * The returned buffer_head has ->b_count elevated.  The caller is expected
37   * to brelse() it when appropriate.
38   */
39 -static struct buffer_head * ext4_find_entry (struct inode *dir,
40 -                                       const struct qstr *d_name,
41 -                                       struct ext4_dir_entry_2 ** res_dir)
42 +struct buffer_head * ext4_find_entry(struct inode *dir,
43 +                                     const struct qstr *d_name,
44 +                                     struct ext4_dir_entry_2 ** res_dir)
45  {
46         struct super_block *sb;
47         struct buffer_head *bh_use[NAMEI_RA_SIZE];
48 @@ -991,6 +992,7 @@ cleanup_and_exit:
49                 brelse(bh_use[ra_ptr]);
50         return ret;
51  }
52 +EXPORT_SYMBOL(ext4_find_entry);
53  
54  static struct buffer_head * ext4_dx_find_entry(struct inode *dir, const struct qstr *d_name,
55                        struct ext4_dir_entry_2 **res_dir, int *err)
56 @@ -1511,8 +1513,8 @@ static int make_indexed_dir(handle_t *ha
57   * may not sleep between calling this and putting something into
58   * the entry, as someone else might have used it while you slept.
59   */
60 -static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
61 -                         struct inode *inode)
62 +int ext4_add_entry(handle_t *handle, struct dentry *dentry,
63 +                  struct inode *inode)
64  {
65         struct inode *dir = dentry->d_parent->d_inode;
66         struct buffer_head *bh;
67 @@ -1557,6 +1559,7 @@ static int ext4_add_entry(handle_t *hand
68         de->rec_len = ext4_rec_len_to_disk(blocksize);
69         return add_dirent_to_buf(handle, dentry, inode, de, bh);
70  }
71 +EXPORT_SYMBOL(ext4_add_entry);
72  
73  /*
74   * Returns 0 for success, or a negative error value
75 @@ -1699,10 +1702,10 @@ cleanup:
76   * ext4_delete_entry deletes a directory entry by merging it with the
77   * previous entry
78   */
79 -static int ext4_delete_entry(handle_t *handle,
80 -                            struct inode *dir,
81 -                            struct ext4_dir_entry_2 *de_del,
82 -                            struct buffer_head *bh)
83 +int ext4_delete_entry(handle_t *handle,
84 +                     struct inode *dir,
85 +                     struct ext4_dir_entry_2 *de_del,
86 +                     struct buffer_head *bh)
87  {
88         struct ext4_dir_entry_2 *de, *pde;
89         int i;
90 @@ -1733,7 +1736,7 @@ static int ext4_delete_entry(handle_t *h
91         }
92         return -ENOENT;
93  }
94 -
95 +EXPORT_SYMBOL(ext4_delete_entry);
96  /*
97   * DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2,
98   * since this indicates that nlinks count was previously 1.
99 @@ -1796,6 +1799,26 @@ static unsigned ext4_dentry_goal(struct
100         return inum;
101  }
102  
103 +struct inode * ext4_create_inode(handle_t *handle, struct inode * dir, int mode)
104 +{
105 +       struct inode *inode;
106 +
107 +       inode = ext4_new_inode(handle, dir, mode, NULL, 0);
108 +       if (!IS_ERR(inode)) {
109 +               if (S_ISCHR(mode) || S_ISBLK(mode) || S_ISFIFO(mode)) {
110 +#ifdef CONFIG_LDISKFS_FS_XATTR
111 +                       inode->i_op = &ext4_special_inode_operations;
112 +#endif
113 +               } else {
114 +                       inode->i_op = &ext4_file_inode_operations;
115 +                       inode->i_fop = &ext4_file_operations;
116 +                       ext4_set_aops(inode);
117 +               }
118 +       }
119 +       return inode;
120 +}
121 +EXPORT_SYMBOL(ext4_create_inode);
122 +
123  /*
124   * By the time this is called, we already have created
125   * the directory cache entry for the new file, but it
126 @@ -1872,40 +1895,32 @@ retry:
127         return err;
128  }
129  
130 -static int ext4_mkdir(struct inode *dir, struct dentry *dentry, int mode)
131 +/* Initialize @inode as a subdirectory of @dir, and add the
132 + * "." and ".." entries into the first directory block. */
133 +int ext4_add_dot_dotdot(handle_t *handle, struct inode * dir,
134 +                       struct inode *inode)
135  {
136 -       handle_t *handle;
137 -       struct inode *inode;
138 -       struct buffer_head *dir_block;
139 -       struct ext4_dir_entry_2 *de;
140         unsigned int blocksize = dir->i_sb->s_blocksize;
141 -       int err, retries = 0;
142 -
143 -       if (EXT4_DIR_LINK_MAX(dir))
144 -               return -EMLINK;
145 +       struct buffer_head * dir_block;
146 +       struct ext4_dir_entry_2 * de;
147 +       int err = 0;
148  
149 -retry:
150 -       handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
151 -                                       EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
152 -                                       EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb));
153         if (IS_ERR(handle))
154                 return PTR_ERR(handle);
155  
156         if (IS_DIRSYNC(dir))
157                 ext4_handle_sync(handle);
158  
159 -       inode = ext4_new_inode(handle, dir, S_IFDIR | mode, &dentry->d_name,
160 -                              ext4_dentry_goal(dir->i_sb, dentry));
161 -       err = PTR_ERR(inode);
162 -       if (IS_ERR(inode))
163 -               goto out_stop;
164 -
165         inode->i_op = &ext4_dir_inode_operations;
166         inode->i_fop = &ext4_dir_operations;
167         inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize;
168         dir_block = ext4_bread(handle, inode, 0, 1, &err);
169 -       if (!dir_block)
170 -               goto out_clear_inode;
171 +       if (!dir_block) {
172 +               clear_nlink(inode);
173 +               ext4_mark_inode_dirty(handle, inode);
174 +               iput (inode);
175 +               goto get_out;
176 +       }
177         BUFFER_TRACE(dir_block, "get_write_access");
178         ext4_journal_get_write_access(handle, dir_block);
179         de = (struct ext4_dir_entry_2 *) dir_block->b_data;
180 @@ -1925,9 +1940,43 @@ retry:
181         ext4_journal_dirty_metadata(handle, dir_block);
182         brelse(dir_block);
183         ext4_mark_inode_dirty(handle, inode);
184 +get_out:
185 +       return err;
186 +}
187 +EXPORT_SYMBOL(ext4_add_dot_dotdot);
188 +
189 +
190 +static int ext4_mkdir(struct inode *dir, struct dentry *dentry, int mode)
191 +{
192 +       handle_t *handle;
193 +       struct inode *inode;
194 +       int err, retries = 0;
195 +
196 +       if (EXT4_DIR_LINK_MAX(dir))
197 +               return -EMLINK;
198 +
199 +retry:
200 +       handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
201 +                                       EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
202 +                                       2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
203 +       if (IS_ERR(handle))
204 +               return PTR_ERR(handle);
205 +
206 +       if (IS_DIRSYNC(dir))
207 +               handle->h_sync = 1;
208 +
209 +       inode = ext4_new_inode(handle, dir, S_IFDIR | mode, &dentry->d_name,
210 +                              ext4_dentry_goal(dir->i_sb, dentry));
211 +       err = PTR_ERR(inode);
212 +       if (IS_ERR(inode))
213 +               goto out_stop;
214 +
215 +       err = ext4_add_dot_dotdot(handle, dir, inode);
216 +       if (err)
217 +               goto out_stop;
218 +
219         err = ext4_add_entry(handle, dentry, inode);
220         if (err) {
221 -out_clear_inode:
222                 clear_nlink(inode);
223                 ext4_mark_inode_dirty(handle, inode);
224                 iput(inode);