Whamcloud - gitweb
- need couple routines to be accessible from modules for size-on-mds feature
[fs/lustre-release.git] / lustre / kernel_patches / patches / ext3-extents-in-ea-2.6.10-fc3.patch
1 Index: linux-2.6.10/fs/ext3/xattr.h
2 ===================================================================
3 --- linux-2.6.10.orig/fs/ext3/xattr.h   2005-04-05 12:26:19.376141960 +0800
4 +++ linux-2.6.10/fs/ext3/xattr.h        2005-04-05 12:27:55.527524728 +0800
5 @@ -70,6 +70,7 @@
6  extern int ext3_xattr_set_handle(handle_t *, struct inode *, int, const char *,const void *,size_t,int);
7  extern int ext3_xattr_block_set(handle_t *, struct inode *, int, const char *,const void *,size_t,int);
8  
9 +extern int ext3_xattr_get_ea_loc(struct inode *, int, const char *, struct buffer_head **, int *, int *);
10  extern void ext3_xattr_delete_inode(handle_t *, struct inode *);
11  extern void ext3_xattr_put_super(struct super_block *);
12  
13 Index: linux-2.6.10/fs/ext3/extents-in-ea.c
14 ===================================================================
15 --- linux-2.6.10.orig/fs/ext3/extents-in-ea.c   2005-04-05 19:01:49.158500672 +0800
16 +++ linux-2.6.10/fs/ext3/extents-in-ea.c        2005-04-05 12:27:55.524525184 +0800
17 @@ -0,0 +1,224 @@
18 +/*
19 + * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com
20 + * Written by Alex Tomas <alex@clusterfs.com>
21 + *
22 + * This program is free software; you can redistribute it and/or modify
23 + * it under the terms of the GNU General Public License version 2 as
24 + * published by the Free Software Foundation.
25 + *
26 + * This program is distributed in the hope that it will be useful,
27 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29 + * GNU General Public License for more details.
30 + *
31 + * You should have received a copy of the GNU General Public Licens
32 + * along with this program; if not, write to the Free Software
33 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-
34 + */
35 +
36 +#include <linux/module.h>
37 +#include <linux/fs.h>
38 +#include <linux/time.h>
39 +#include <linux/ext3_jbd.h>
40 +#include <linux/jbd.h>
41 +#include <linux/smp_lock.h>
42 +#include <linux/highuid.h>
43 +#include <linux/pagemap.h>
44 +#include <linux/quotaops.h>
45 +#include <linux/string.h>
46 +#include <linux/ext3_extents.h>
47 +#include <linux/ext3_xattr.h>
48 +#include <linux/slab.h>
49 +#include <asm/uaccess.h>
50 +
51 +static int ext3_get_ea_write_access(handle_t *handle, void *buffer)
52 +{
53 +       struct buffer_head *bh = (struct buffer_head *) buffer;
54 +       return ext3_journal_get_write_access(handle, bh);
55 +}
56 +
57 +static int ext3_mark_ea_buffer_dirty(handle_t *handle, void *buffer)
58 +{
59 +       struct buffer_head *bh = (struct buffer_head *) buffer;
60 +       ext3_journal_dirty_metadata(handle, bh);
61 +       return 0;
62 +}
63 +
64 +static struct ext3_extents_helpers ext3_ea_helpers = {
65 +       .get_write_access       = ext3_get_ea_write_access,
66 +       .mark_buffer_dirty      = ext3_mark_ea_buffer_dirty,
67 +       .mergable               = NULL,
68 +       .new_block              = NULL,
69 +       .remove_extent          = NULL,
70 +       .remove_extent_credits  = NULL,
71 +};
72 +
73 +int ext3_init_tree_in_ea_desc(struct ext3_extents_tree *tree,
74 +                               struct inode *inode, int name_index,
75 +                               const char *eaname)
76 +{
77 +       struct buffer_head *bh;
78 +       int offset, err, size;
79 +
80 +       err = ext3_xattr_get_ea_loc(inode, name_index, eaname,
81 +                                       &bh, &offset, &size);
82 +       if (err)
83 +               return err;
84 +
85 +       EXT_ASSERT(bh);
86 +       EXT_ASSERT(size >= sizeof(struct ext3_extent_header)
87 +                               + sizeof(struct ext3_extent));
88 +       tree->inode = inode;
89 +       tree->root = (void *) bh->b_data + offset;
90 +       tree->buffer_len = size;
91 +       tree->buffer = (void *) bh;
92 +       tree->ops = &ext3_ea_helpers;
93 +       tree->cex = NULL;       /* FIXME: add cache store later */
94 +       return 0;
95 +}
96 +
97 +void ext3_release_tree_in_ea_desc(struct ext3_extents_tree *tree)
98 +{
99 +       struct buffer_head *bh;
100 +
101 +       bh = (struct buffer_head *) tree->buffer;
102 +       EXT_ASSERT(bh);
103 +       brelse(bh);
104 +}
105 +
106 +int ext3_init_tree_in_ea(struct inode *inode, int name_index,
107 +                               const char *eaname, int size)
108 +{
109 +       struct ext3_extents_tree tree;
110 +       handle_t *handle;
111 +       char *root;
112 +       int err;
113 +
114 +       root = kmalloc(size, GFP_USER);
115 +       if (!root)
116 +               return -ENOMEM;
117 +       memset(root, 0, size);
118 +
119 +       /* first, create ea to store root of the tree */
120 +       handle = ext3_journal_start(inode, EXT3_ALLOC_NEEDED + 3);
121 +       if (IS_ERR(handle))
122 +               return PTR_ERR(handle);
123 +       if ((err = ext3_xattr_set(inode, name_index,
124 +                                 eaname, root, size, 0)))
125 +               goto out;
126 +       if ((err = ext3_init_tree_in_ea_desc(&tree, inode, name_index, eaname)))
127 +               goto out;
128 +       err = ext3_extent_tree_init(handle, &tree);
129 +       ext3_release_tree_in_ea_desc(&tree);
130 +out:
131 +       ext3_journal_stop(handle, inode);
132 +       kfree(root);
133 +       return err;
134 +}
135 +
136 +static int
137 +ext3_ext_in_ea_new_extent(struct ext3_extents_tree *tree,
138 +                       struct ext3_ext_path *path,
139 +                       struct ext3_extent *newex, int exist)
140 +{
141 +       struct inode *inode = tree->inode;
142 +       handle_t *handle;
143 +       int needed, err;
144 +       unsigned long tgen;
145 +
146 +       if (exist)
147 +               return EXT_CONTINUE;
148 +
149 +       tgen = EXT_GENERATION(tree);
150 +       needed = ext3_ext_calc_credits_for_insert(tree, path);
151 +       up(&EXT3_I(inode)->truncate_sem);
152 +       handle = ext3_journal_start(tree->inode, needed + 10);
153 +       if (IS_ERR(handle)) {
154 +               down_write(&EXT3_I(inode)->truncate_sem);
155 +               return PTR_ERR(handle);
156 +       }
157 +
158 +       if (tgen != EXT_GENERATION(tree)) {
159 +               /* the tree has changed. so path can be invalid at moment */
160 +               ext3_journal_stop(handle, inode);
161 +               down_write(&EXT3_I(inode)->truncate_sem);
162 +               return EXT_REPEAT;
163 +       }
164 +
165 +       down_write(&EXT3_I(inode)->truncate_sem);
166 +
167 +       /* insert new extent */
168 +       newex->ee_start = 0;
169 +       err = ext3_ext_insert_extent(handle, tree, path, newex);
170 +       if (!err)
171 +               ext3_journal_stop(handle, tree->inode);
172 +
173 +       return err;
174 +}
175 +
176 +int ext3_ext_in_ea_alloc_space(struct inode *inode, int name_index,
177 +                               const char *eaname, unsigned long from,
178 +                               unsigned long num)
179 +{
180 +       struct ext3_extents_tree tree;
181 +       int err;
182 +
183 +       err = ext3_init_tree_in_ea_desc(&tree, inode, name_index, eaname);
184 +       if (err == 0) {
185 +               down_write(&EXT3_I(inode)->truncate_sem);       
186 +               err = ext3_ext_walk_space(&tree, from, num,
187 +                                               ext3_ext_in_ea_new_extent);
188 +               ext3_release_tree_in_ea_desc(&tree);
189 +               up_write(&EXT3_I(inode)->truncate_sem);
190 +       }
191 +       return err;
192 +}
193 +
194 +int ext3_ext_in_ea_remove_space(struct inode *inode, int name_index,
195 +                               const char *eaname, unsigned long from,
196 +                               unsigned long num)
197 +{
198 +       struct ext3_extents_tree tree;
199 +       int err;
200 +
201 +       err = ext3_init_tree_in_ea_desc(&tree, inode, name_index, eaname);
202 +       if (err == 0) {
203 +               err = ext3_ext_remove_space(&tree, from, num);
204 +               ext3_release_tree_in_ea_desc(&tree);
205 +       }
206 +       return err;
207 +}
208 +
209 +int ext3_ext_in_ea_presence(struct inode *inode, int name_index,
210 +                               const char *eaname, unsigned long block)
211 +{
212 +       struct ext3_extents_tree tree;
213 +       struct ext3_ext_path *path;
214 +       struct ext3_extent *ex;
215 +       int err, depth;
216 +
217 +       err = ext3_init_tree_in_ea_desc(&tree, inode, name_index, eaname);
218 +       if (err)
219 +               return err;
220 +
221 +       /* find extent for this block */
222 +       path = ext3_ext_find_extent(&tree, block, NULL);
223 +       if (IS_ERR(path)) {
224 +               err = PTR_ERR(path);
225 +               goto out;
226 +       }
227 +
228 +       depth = EXT_DEPTH(&tree);
229 +       ex = path[depth].p_ext;
230 +       if (!ex) {
231 +               /* there is no extent yet */
232 +               goto out;
233 +       }
234 +
235 +       if (block >= ex->ee_block && block < ex->ee_block + ex->ee_len)
236 +               err = 1;
237 +out:
238 +       ext3_release_tree_in_ea_desc(&tree);
239 +       return err;
240 +}
241 +
242 Index: linux-2.6.10/fs/ext3/xattr.c
243 ===================================================================
244 --- linux-2.6.10.orig/fs/ext3/xattr.c   2005-04-05 12:26:19.370142872 +0800
245 +++ linux-2.6.10/fs/ext3/xattr.c        2005-04-05 12:27:55.527524728 +0800
246 @@ -590,7 +590,8 @@
247   */
248  int
249  ext3_xattr_ibody_find(struct inode *inode, int name_index,
250 -               const char *name, struct ext3_xattr_entry *rentry, int *free)
251 +               const char *name, struct ext3_xattr_entry *rentry, int *free,
252 +               struct buffer_head **bh, int *offset)
253  {
254         struct ext3_xattr_entry *last;
255         struct ext3_inode *raw_inode;
256 @@ -637,6 +638,15 @@
257                     name_len == last->e_name_len &&
258                     !memcmp(name, last->e_name, name_len)) {
259                         memcpy(rentry, last, sizeof(struct ext3_xattr_entry));
260 +                       if (offset) {
261 +                               void *voff;
262 +                               voff = start + le16_to_cpu(last->e_value_offs);
263 +                               *offset = voff - (void *) iloc.bh->b_data;
264 +                       }
265 +                       if (bh) {
266 +                               get_bh(iloc.bh);        
267 +                               *bh = iloc.bh;
268 +                       }
269                         ret = 0;
270                 } else {
271                         *free -= EXT3_XATTR_LEN(last->e_name_len);
272 @@ -657,7 +667,8 @@
273   */
274  int
275  ext3_xattr_block_find(struct inode *inode, int name_index, const char *name,
276 -              struct ext3_xattr_entry *rentry, int *free)
277 +              struct ext3_xattr_entry *rentry, int *free,
278 +              struct buffer_head **tbh, int *offset)
279  {
280         struct buffer_head *bh = NULL;
281         struct ext3_xattr_entry *entry;
282 @@ -700,6 +711,12 @@
283                     memcmp(name, entry->e_name, name_len) == 0) {
284                         memcpy(rentry, entry, sizeof(struct ext3_xattr_entry));
285                         error = 0;
286 +                       if (offset)
287 +                               *offset = le16_to_cpu(entry->e_value_offs);
288 +                       if (tbh) {
289 +                               get_bh(bh);     
290 +                               *tbh = bh;
291 +                       }
292                 } else {
293                         *free -= EXT3_XATTR_LEN(entry->e_name_len);
294                         *free -= le32_to_cpu(entry->e_value_size);
295 @@ -894,7 +911,8 @@
296         down_write(&EXT3_I(inode)->xattr_sem);
297  
298         /* try to find attribute in inode body */
299 -       err = ext3_xattr_ibody_find(inode, name_index, name, &entry, &free1);
300 +       err = ext3_xattr_ibody_find(inode, name_index, name,
301 +                                       &entry, &free1, NULL, NULL);
302         if (err == 0) {
303                 /* found EA in inode */
304                 found = 1;
305 @@ -903,7 +921,7 @@
306                 /* there is no such attribute in inode body */
307                 /* try to find attribute in dedicated block */
308                 err = ext3_xattr_block_find(inode, name_index, name,
309 -                                               &entry, &free2);
310 +                                               &entry, &free2, NULL, NULL);
311                 if (err != 0 && err != -ENOENT) {
312                         /* not found EA in block */
313                         goto finish;    
314 @@ -960,6 +978,35 @@
315         return err;
316  }
317  
318 +int ext3_xattr_get_ea_loc(struct inode *inode, int name_index,
319 +                               const char *name, struct buffer_head **bh,
320 +                               int *offset, int *size)
321 +{
322 +       int free1 = -1, free2 = -1, err, name_len;
323 +       struct ext3_xattr_entry entry;
324 +       
325 +       ea_idebug(inode, "name=%d.%s", name_index, name);
326 +
327 +       if (name == NULL)
328 +               return -EINVAL;
329 +       name_len = strlen(name);
330 +       if (name_len > 255)
331 +               return -ERANGE;
332 +
333 +       /* try to find attribute in inode body */
334 +       err = ext3_xattr_ibody_find(inode, name_index, name,
335 +                                       &entry, &free1, bh, offset);
336 +       if (err == -ENOENT) {
337 +               /* there is no such attribute in inode body */
338 +               /* try to find attribute in dedicated block */
339 +               err = ext3_xattr_block_find(inode, name_index, name,
340 +                                               &entry, &free2, bh, offset);
341 +       }
342 +       if (err == 0 && size)
343 +               *size = le32_to_cpu(entry.e_value_size);
344 +       return err;
345 +}
346 +
347  /*
348   * ext3_xattr_block_set()
349   *
350 Index: linux-2.6.10/fs/ext3/Makefile
351 ===================================================================
352 --- linux-2.6.10.orig/fs/ext3/Makefile  2005-04-05 12:27:00.597875304 +0800
353 +++ linux-2.6.10/fs/ext3/Makefile       2005-04-05 12:28:26.989741744 +0800
354 @@ -7,6 +7,6 @@
355  ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
356            ioctl.o namei.o super.o symlink.o hash.o resize.o iopen.o \
357            extents.o
358 -ext3-$(CONFIG_EXT3_FS_XATTR)    += xattr.o xattr_user.o xattr_trusted.o
359 +ext3-$(CONFIG_EXT3_FS_XATTR)   += xattr.o xattr_user.o xattr_trusted.o extents-in-ea.o
360  ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o
361  ext3-$(CONFIG_EXT3_FS_SECURITY)         += xattr_security.o