1 Index: linux-2.4.24/fs/ext3/extents-in-ea.c
2 ===================================================================
3 --- linux-2.4.24.orig/fs/ext3/extents-in-ea.c 2003-01-30 18:24:37.000000000 +0800
4 +++ linux-2.4.24/fs/ext3/extents-in-ea.c 2004-06-24 21:53:00.000000000 +0800
7 + * Copyright (C) 2003 Alex Tomas <alex@clusterfs.com>
9 + * This program is free software; you can redistribute it and/or modify
10 + * it under the terms of the GNU General Public License version 2 as
11 + * published by the Free Software Foundation.
13 + * This program is distributed in the hope that it will be useful,
14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 + * GNU General Public License for more details.
18 + * You should have received a copy of the GNU General Public Licens
19 + * along with this program; if not, write to the Free Software
20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-
23 +#include <linux/module.h>
24 +#include <linux/fs.h>
25 +#include <linux/time.h>
26 +#include <linux/ext3_jbd.h>
27 +#include <linux/jbd.h>
28 +#include <linux/smp_lock.h>
29 +#include <linux/highuid.h>
30 +#include <linux/pagemap.h>
31 +#include <linux/quotaops.h>
32 +#include <linux/string.h>
33 +#include <linux/ext3_extents.h>
34 +#include <linux/ext3_xattr.h>
35 +#include <linux/slab.h>
36 +#include <asm/uaccess.h>
38 +static int ext3_get_ea_write_access(handle_t *handle, void *buffer)
40 + struct buffer_head *bh = (struct buffer_head *) buffer;
41 + return ext3_journal_get_write_access(handle, bh);
44 +static int ext3_mark_ea_buffer_dirty(handle_t *handle, void *buffer)
46 + struct buffer_head *bh = (struct buffer_head *) buffer;
47 + ext3_journal_dirty_metadata(handle, bh);
51 +int ext3_init_tree_in_ea_desc(struct ext3_extents_tree *tree,
52 + struct inode *inode, int name_index,
55 + struct buffer_head *bh;
56 + int offset, err, size;
58 + err = ext3_xattr_get_ea_loc(inode, name_index, eaname,
59 + &bh, &offset, &size);
64 + EXT_ASSERT(size >= sizeof(struct ext3_extent_header)
65 + + sizeof(struct ext3_extent));
66 + tree->inode = inode;
67 + tree->root = (void *) bh->b_data + offset;
68 + tree->buffer_len = size;
69 + tree->buffer = (void *) bh;
70 + tree->get_write_access = ext3_get_ea_write_access;
71 + tree->mark_buffer_dirty = ext3_mark_ea_buffer_dirty;
72 + tree->mergable = NULL;
73 + tree->remove_extent = NULL;
74 + tree->remove_extent_credits = NULL;
75 + tree->new_block = NULL;
76 + tree->cex = NULL; /* FIXME: add cache store later */
80 +void ext3_release_tree_in_ea_desc(struct ext3_extents_tree *tree)
82 + struct buffer_head *bh;
84 + bh = (struct buffer_head *) tree->buffer;
89 +int ext3_init_tree_in_ea(struct inode *inode, int name_index,
90 + const char *eaname, int size)
92 + struct ext3_extents_tree tree;
97 + root = kmalloc(size, GFP_USER);
100 + memset(root, 0, size);
102 + /* first, create ea to store root of the tree */
103 + handle = ext3_journal_start(inode, EXT3_ALLOC_NEEDED + 3);
104 + if (IS_ERR(handle))
105 + return PTR_ERR(handle);
106 + if ((err = ext3_xattr_set(handle, inode, name_index,
107 + eaname, root, size, 0)))
109 + if ((err = ext3_init_tree_in_ea_desc(&tree, inode, name_index, eaname)))
111 + err = ext3_extent_tree_init(handle, &tree);
112 + ext3_release_tree_in_ea_desc(&tree);
114 + ext3_journal_stop(handle, inode);
120 +ext3_ext_in_ea_new_extent(struct ext3_extents_tree *tree,
121 + struct ext3_ext_path *path,
122 + struct ext3_extent *newex, int exist)
124 + struct inode *inode = tree->inode;
127 + unsigned long tgen;
130 + return EXT_CONTINUE;
132 + tgen = EXT_GENERATION(tree);
133 + needed = ext3_ext_calc_credits_for_insert(tree, path);
134 + up_write(&EXT3_I(inode)->truncate_sem);
135 + handle = ext3_journal_start(tree->inode, needed + 10);
136 + if (IS_ERR(handle)) {
137 + down_write(&EXT3_I(inode)->truncate_sem);
138 + return PTR_ERR(handle);
141 + if (tgen != EXT_GENERATION(tree)) {
142 + /* the tree has changed. so path can be invalid at moment */
143 + ext3_journal_stop(handle, inode);
144 + down_write(&EXT3_I(inode)->truncate_sem);
148 + down_write(&EXT3_I(inode)->truncate_sem);
150 + /* insert new extent */
151 + newex->e_start = 0;
152 + err = ext3_ext_insert_extent(handle, tree, path, newex);
154 + ext3_journal_stop(handle, tree->inode);
159 +int ext3_ext_in_ea_alloc_space(struct inode *inode, int name_index,
160 + const char *eaname, unsigned long from,
163 + struct ext3_extents_tree tree;
166 + err = ext3_init_tree_in_ea_desc(&tree, inode, name_index, eaname);
168 + down_write(&EXT3_I(inode)->truncate_sem);
169 + err = ext3_ext_walk_space(&tree, from, num,
170 + ext3_ext_in_ea_new_extent);
171 + ext3_release_tree_in_ea_desc(&tree);
172 + up_write(&EXT3_I(inode)->truncate_sem);
177 +int ext3_ext_in_ea_remove_space(struct inode *inode, int name_index,
178 + const char *eaname, unsigned long from,
181 + struct ext3_extents_tree tree;
184 + err = ext3_init_tree_in_ea_desc(&tree, inode, name_index, eaname);
186 + err = ext3_ext_remove_space(&tree, from, num);
187 + ext3_release_tree_in_ea_desc(&tree);
192 +int ext3_ext_in_ea_presence(struct inode *inode, int name_index,
193 + const char *eaname, unsigned long block)
195 + struct ext3_extents_tree tree;
196 + struct ext3_ext_path *path;
197 + struct ext3_extent *ex;
200 + err = ext3_init_tree_in_ea_desc(&tree, inode, name_index, eaname);
204 + /* find extent for this block */
205 + path = ext3_ext_find_extent(&tree, block, NULL);
206 + if (IS_ERR(path)) {
207 + err = PTR_ERR(path);
211 + depth = EXT_DEPTH(&tree);
212 + ex = path[depth].p_ext;
214 + /* there is no extent yet */
218 + if (block >= ex->e_block && block < ex->e_block + ex->e_num)
221 + ext3_release_tree_in_ea_desc(&tree);
225 Index: linux-2.4.24/fs/ext3/Makefile
226 ===================================================================
227 --- linux-2.4.24.orig/fs/ext3/Makefile 2004-06-09 11:31:06.000000000 +0800
228 +++ linux-2.4.24/fs/ext3/Makefile 2004-06-24 21:36:29.000000000 +0800
232 export-objs += xattr.o
233 -obj-$(CONFIG_EXT3_FS_XATTR) += xattr.o
234 +obj-$(CONFIG_EXT3_FS_XATTR) += xattr.o extents-in-ea.o
235 obj-$(CONFIG_EXT3_FS_XATTR_USER) += xattr_user.o
237 include $(TOPDIR)/Rules.make
238 Index: linux-2.4.24/fs/ext3/xattr.c
239 ===================================================================
240 --- linux-2.4.24.orig/fs/ext3/xattr.c 2004-06-09 11:31:06.000000000 +0800
241 +++ linux-2.4.24/fs/ext3/xattr.c 2004-06-24 21:36:29.000000000 +0800
245 ext3_xattr_ibody_find(struct inode *inode, int name_index,
246 - const char *name, struct ext3_xattr_entry *rentry, int *free)
247 + const char *name, struct ext3_xattr_entry *rentry, int *free,
248 + struct buffer_head **bh, int *offset)
250 struct ext3_xattr_entry *last;
251 struct ext3_inode *raw_inode;
253 name_len == last->e_name_len &&
254 !memcmp(name, last->e_name, name_len)) {
255 memcpy(rentry, last, sizeof(struct ext3_xattr_entry));
258 + voff = start + le16_to_cpu(last->e_value_offs);
259 + *offset = voff - (void *) iloc.bh->b_data;
267 *free -= EXT3_XATTR_LEN(last->e_name_len);
271 ext3_xattr_block_find(struct inode *inode, int name_index, const char *name,
272 - struct ext3_xattr_entry *rentry, int *free)
273 + struct ext3_xattr_entry *rentry, int *free,
274 + struct buffer_head **tbh, int *offset)
276 struct buffer_head *bh = NULL;
277 struct ext3_xattr_entry *entry;
279 memcmp(name, entry->e_name, name_len) == 0) {
280 memcpy(rentry, entry, sizeof(struct ext3_xattr_entry));
283 + *offset = le16_to_cpu(entry->e_value_offs);
289 *free -= EXT3_XATTR_LEN(entry->e_name_len);
290 *free -= le32_to_cpu(entry->e_value_size);
291 @@ -1073,7 +1090,8 @@
294 /* try to find attribute in inode body */
295 - err = ext3_xattr_ibody_find(inode, name_index, name, &entry, &free1);
296 + err = ext3_xattr_ibody_find(inode, name_index, name,
297 + &entry, &free1, NULL, NULL);
299 /* found EA in inode */
301 @@ -1082,7 +1100,7 @@
302 /* there is no such attribute in inode body */
303 /* try to find attribute in dedicated block */
304 err = ext3_xattr_block_find(inode, name_index, name,
306 + &entry, &free2, NULL, NULL);
307 if (err != 0 && err != -ENOENT) {
308 /* not found EA in block */
310 @@ -1138,6 +1156,38 @@
314 +int ext3_xattr_get_ea_loc(struct inode *inode, int name_index,
315 + const char *name, struct buffer_head **bh,
316 + int *offset, int *size)
318 + int free1 = -1, free2 = -1, err, name_len;
319 + struct ext3_xattr_entry entry;
321 + ea_idebug(inode, "name=%d.%s", name_index, name);
325 + name_len = strlen(name);
326 + if (name_len > 255)
329 + down(&ext3_xattr_sem);
331 + /* try to find attribute in inode body */
332 + err = ext3_xattr_ibody_find(inode, name_index, name,
333 + &entry, &free1, bh, offset);
334 + if (err == -ENOENT) {
335 + /* there is no such attribute in inode body */
336 + /* try to find attribute in dedicated block */
337 + err = ext3_xattr_block_find(inode, name_index, name,
338 + &entry, &free2, bh, offset);
340 + if (err == 0 && size)
341 + *size = le32_to_cpu(entry.e_value_size);
342 + up(&ext3_xattr_sem);
347 * ext3_xattr_block_set()
349 Index: linux-2.4.24/include/linux/ext3_xattr.h
350 ===================================================================
351 --- linux-2.4.24.orig/include/linux/ext3_xattr.h 2004-06-09 11:31:06.000000000 +0800
352 +++ linux-2.4.24/include/linux/ext3_xattr.h 2004-06-24 21:36:29.000000000 +0800
354 extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t);
355 extern int ext3_xattr_list(struct inode *, char *, size_t);
356 extern int ext3_xattr_set(handle_t *handle, struct inode *, int, const char *, const void *, size_t, int);
357 +extern int ext3_xattr_get_ea_loc(struct inode *, int, const char *, struct buffer_head **, int *, int *);
359 extern void ext3_xattr_delete_inode(handle_t *, struct inode *);
360 extern void ext3_xattr_put_super(struct super_block *);