2 Index: linux-2.6.5-7.311/fs/ext3/ialloc.c
3 ===================================================================
4 --- linux-2.6.5-7.311.orig/fs/ext3/ialloc.c
5 +++ linux-2.6.5-7.311/fs/ext3/ialloc.c
6 @@ -633,6 +633,9 @@ got:
7 spin_unlock(&sbi->s_next_gen_lock);
9 ei->i_state = EXT3_STATE_NEW;
11 + (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) ?
12 + sizeof(struct ext3_inode) - EXT3_GOOD_OLD_INODE_SIZE : 0;
15 if(DQUOT_ALLOC_INODE(inode)) {
16 Index: linux-2.6.5-7.311/fs/ext3/inode.c
17 ===================================================================
18 --- linux-2.6.5-7.311.orig/fs/ext3/inode.c
19 +++ linux-2.6.5-7.311/fs/ext3/inode.c
20 @@ -2284,7 +2284,7 @@ static unsigned long ext3_get_inode_bloc
21 * trying to determine the inode's location on-disk and no read need be
24 -static int ext3_get_inode_loc(struct inode *inode,
25 +int ext3_get_inode_loc(struct inode *inode,
26 struct ext3_iloc *iloc, int in_mem)
29 @@ -2495,6 +2495,11 @@ void ext3_read_inode(struct inode * inod
30 ei->i_data[block] = raw_inode->i_block[block];
31 INIT_LIST_HEAD(&ei->i_orphan);
33 + if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE)
34 + ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize);
36 + ei->i_extra_isize = 0;
38 if (S_ISREG(inode->i_mode)) {
39 inode->i_op = &ext3_file_inode_operations;
40 inode->i_fop = &ext3_file_operations;
41 @@ -2630,6 +2635,9 @@ static int ext3_do_update_inode(handle_t
42 } else for (block = 0; block < EXT3_N_BLOCKS; block++)
43 raw_inode->i_block[block] = ei->i_data[block];
45 + if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE)
46 + raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize);
48 BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
49 rc = ext3_journal_dirty_metadata(handle, bh);
51 @@ -2839,7 +2847,8 @@ ext3_reserve_inode_write(handle_t *handl
55 - err = ext3_get_inode_loc(inode, iloc, 1);
56 + err = ext3_get_inode_loc(inode, iloc, EXT3_I(inode)->i_state &
59 BUFFER_TRACE(iloc->bh, "get_write_access");
60 err = ext3_journal_get_write_access(handle, iloc->bh);
61 Index: linux-2.6.5-7.311/fs/ext3/xattr.c
62 ===================================================================
63 --- linux-2.6.5-7.311.orig/fs/ext3/xattr.c
64 +++ linux-2.6.5-7.311/fs/ext3/xattr.c
65 @@ -245,17 +245,12 @@ ext3_removexattr(struct dentry *dentry,
71 - * Copy an extended attribute into the buffer
72 - * provided, or compute the buffer size required.
73 - * Buffer is NULL to compute the size of the buffer required.
74 + * ext3_xattr_block_get()
76 - * Returns a negative error number on failure, or the number of bytes
77 - * used / required on success.
78 + * routine looks for attribute in EA block and returns it's value and size
81 -ext3_xattr_get(struct inode *inode, int name_index, const char *name,
82 +ext3_xattr_block_get(struct inode *inode, int name_index, const char *name,
83 void *buffer, size_t buffer_size)
85 struct buffer_head *bh = NULL;
86 @@ -269,7 +264,6 @@ ext3_xattr_get(struct inode *inode, int
90 - down_read(&EXT3_I(inode)->xattr_sem);
92 if (!EXT3_I(inode)->i_file_acl)
94 @@ -342,15 +336,87 @@ found:
98 - up_read(&EXT3_I(inode)->xattr_sem);
104 - * ext3_xattr_list()
105 + * ext3_xattr_ibody_get()
107 - * Copy a list of attribute names into the buffer
108 + * routine looks for attribute in inode body and returns it's value and size
111 +ext3_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
112 + void *buffer, size_t buffer_size)
114 + int size, name_len = strlen(name), storage_size;
115 + struct ext3_xattr_entry *last;
116 + struct ext3_inode *raw_inode;
117 + struct ext3_iloc iloc;
121 + if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
124 + ret = ext3_get_inode_loc(inode, &iloc, 0);
127 + raw_inode = ext3_raw_inode(&iloc);
129 + storage_size = EXT3_SB(inode->i_sb)->s_inode_size -
130 + EXT3_GOOD_OLD_INODE_SIZE -
131 + EXT3_I(inode)->i_extra_isize -
133 + start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
134 + EXT3_I(inode)->i_extra_isize;
135 + if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) {
139 + start += sizeof(__u32);
140 + end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
142 + last = (struct ext3_xattr_entry *) start;
143 + while (!IS_LAST_ENTRY(last)) {
144 + struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
145 + if (le32_to_cpu(last->e_value_size) > storage_size ||
146 + (char *) next >= end) {
147 + ext3_error(inode->i_sb, "ext3_xattr_ibody_get",
148 + "inode %ld", inode->i_ino);
152 + if (name_index == last->e_name_index &&
153 + name_len == last->e_name_len &&
154 + !memcmp(name, last->e_name, name_len))
159 + /* can't find EA */
164 + size = le32_to_cpu(last->e_value_size);
167 + if (buffer_size >= size) {
168 + memcpy(buffer, start + le16_to_cpu(last->e_value_offs),
181 + * Copy an extended attribute into the buffer
182 * provided, or compute the buffer size required.
183 * Buffer is NULL to compute the size of the buffer required.
185 @@ -358,7 +424,31 @@ cleanup:
186 * used / required on success.
189 -ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
190 +ext3_xattr_get(struct inode *inode, int name_index, const char *name,
191 + void *buffer, size_t buffer_size)
195 + down_read(&EXT3_I(inode)->xattr_sem);
197 + /* try to find attribute in inode body */
198 + err = ext3_xattr_ibody_get(inode, name_index, name,
199 + buffer, buffer_size);
201 + /* search was unsuccessful, try to find EA in dedicated block */
202 + err = ext3_xattr_block_get(inode, name_index, name,
203 + buffer, buffer_size);
204 + up_read(&EXT3_I(inode)->xattr_sem);
209 +/* ext3_xattr_ibody_list()
211 + * generate list of attributes stored in EA block
214 +ext3_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size)
216 struct buffer_head *bh = NULL;
217 struct ext3_xattr_entry *entry;
218 @@ -369,7 +459,6 @@ ext3_xattr_list(struct inode *inode, cha
219 ea_idebug(inode, "buffer=%p, buffer_size=%ld",
220 buffer, (long)buffer_size);
222 - down_read(&EXT3_I(inode)->xattr_sem);
224 if (!EXT3_I(inode)->i_file_acl)
226 @@ -430,11 +519,138 @@ bad_block: ext3_error(inode->i_sb, "ext3
230 - up_read(&EXT3_I(inode)->xattr_sem);
235 +/* ext3_xattr_ibody_list()
237 + * generate list of attributes stored in inode body
240 +ext3_xattr_ibody_list(struct inode *inode, char *buffer, size_t buffer_size)
242 + struct ext3_xattr_entry *last;
243 + struct ext3_inode *raw_inode;
244 + char *start, *end, *buf;
245 + struct ext3_iloc iloc;
250 + if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
253 + ret = ext3_get_inode_loc(inode, &iloc, 0);
256 + raw_inode = ext3_raw_inode(&iloc);
258 + storage_size = EXT3_SB(inode->i_sb)->s_inode_size -
259 + EXT3_GOOD_OLD_INODE_SIZE -
260 + EXT3_I(inode)->i_extra_isize -
262 + start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
263 + EXT3_I(inode)->i_extra_isize;
264 + if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) {
268 + start += sizeof(__u32);
269 + end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
271 + last = (struct ext3_xattr_entry *) start;
272 + while (!IS_LAST_ENTRY(last)) {
273 + struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
274 + struct ext3_xattr_handler *handler;
275 + if (le32_to_cpu(last->e_value_size) > storage_size ||
276 + (char *) next >= end) {
277 + ext3_error(inode->i_sb, "ext3_xattr_ibody_list",
278 + "inode %ld", inode->i_ino);
282 + handler = ext3_xattr_handler(last->e_name_index);
284 + size += handler->list(NULL, inode, last->e_name,
294 + if (size > buffer_size)
298 + last = (struct ext3_xattr_entry *) start;
300 + while (!IS_LAST_ENTRY(last)) {
301 + struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
302 + struct ext3_xattr_handler *handler;
303 + handler = ext3_xattr_handler(last->e_name_index);
305 + buf += handler->list(buf, inode, last->e_name,
316 + * ext3_xattr_list()
318 + * Copy a list of attribute names into the buffer
319 + * provided, or compute the buffer size required.
320 + * Buffer is NULL to compute the size of the buffer required.
322 + * Returns a negative error number on failure, or the number of bytes
323 + * used / required on success.
326 +ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
329 + int size = buffer_size;
331 + down_read(&EXT3_I(inode)->xattr_sem);
333 + /* get list of attributes stored in inode body */
334 + error = ext3_xattr_ibody_list(inode, buffer, buffer_size);
336 + /* some error occured while collecting
337 + * attributes in inode body */
343 + /* get list of attributes stored in dedicated block */
345 + buffer_size -= error;
346 + if (buffer_size <= 0) {
353 + error = ext3_xattr_block_list(inode, buffer, buffer_size);
355 + /* listing was successful, so we return len */
359 + up_read(&EXT3_I(inode)->xattr_sem);
360 + return error + size;
364 * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is
366 @@ -456,6 +672,279 @@ static void ext3_xattr_update_super_bloc
370 + * ext3_xattr_ibody_find()
372 + * search attribute and calculate free space in inode body
373 + * NOTE: free space includes space our attribute hold
376 +ext3_xattr_ibody_find(struct inode *inode, int name_index,
377 + const char *name, struct ext3_xattr_entry *rentry, int *free)
379 + struct ext3_xattr_entry *last;
380 + struct ext3_inode *raw_inode;
381 + int name_len = strlen(name);
382 + int err, storage_size;
383 + struct ext3_iloc iloc;
387 + if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
390 + err = ext3_get_inode_loc(inode, &iloc, 0);
393 + raw_inode = ext3_raw_inode(&iloc);
395 + storage_size = EXT3_SB(inode->i_sb)->s_inode_size -
396 + EXT3_GOOD_OLD_INODE_SIZE -
397 + EXT3_I(inode)->i_extra_isize -
399 + *free = storage_size - sizeof(__u32);
400 + start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
401 + EXT3_I(inode)->i_extra_isize;
402 + if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) {
406 + start += sizeof(__u32);
407 + end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
409 + last = (struct ext3_xattr_entry *) start;
410 + while (!IS_LAST_ENTRY(last)) {
411 + struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
412 + if (le32_to_cpu(last->e_value_size) > storage_size ||
413 + (char *) next >= end) {
414 + ext3_error(inode->i_sb, "ext3_xattr_ibody_find",
415 + "inode %ld", inode->i_ino);
420 + if (name_index == last->e_name_index &&
421 + name_len == last->e_name_len &&
422 + !memcmp(name, last->e_name, name_len)) {
423 + memcpy(rentry, last, sizeof(struct ext3_xattr_entry));
426 + *free -= EXT3_XATTR_LEN(last->e_name_len);
427 + *free -= le32_to_cpu(last->e_value_size);
437 + * ext3_xattr_block_find()
439 + * search attribute and calculate free space in EA block (if it allocated)
440 + * NOTE: free space includes space our attribute hold
443 +ext3_xattr_block_find(struct inode *inode, int name_index, const char *name,
444 + struct ext3_xattr_entry *rentry, int *free)
446 + struct buffer_head *bh = NULL;
447 + struct ext3_xattr_entry *entry;
449 + int name_len, error = -ENOENT;
451 + if (!EXT3_I(inode)->i_file_acl) {
452 + *free = inode->i_sb->s_blocksize -
453 + sizeof(struct ext3_xattr_header) -
457 + ea_idebug(inode, "reading block %d", EXT3_I(inode)->i_file_acl);
458 + bh = sb_bread(inode->i_sb, EXT3_I(inode)->i_file_acl);
461 + ea_bdebug(bh, "b_count=%d, refcount=%d",
462 + atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
463 + end = bh->b_data + bh->b_size;
464 + if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
465 + HDR(bh)->h_blocks != cpu_to_le32(1)) {
466 +bad_block: ext3_error(inode->i_sb, "ext3_xattr_get",
467 + "inode %ld: bad block %d", inode->i_ino,
468 + EXT3_I(inode)->i_file_acl);
472 + /* find named attribute */
473 + name_len = strlen(name);
474 + *free = bh->b_size - sizeof(__u32);
476 + entry = FIRST_ENTRY(bh);
477 + while (!IS_LAST_ENTRY(entry)) {
478 + struct ext3_xattr_entry *next =
479 + EXT3_XATTR_NEXT(entry);
480 + if ((char *)next >= end)
482 + if (name_index == entry->e_name_index &&
483 + name_len == entry->e_name_len &&
484 + memcmp(name, entry->e_name, name_len) == 0) {
485 + memcpy(rentry, entry, sizeof(struct ext3_xattr_entry));
488 + *free -= EXT3_XATTR_LEN(entry->e_name_len);
489 + *free -= le32_to_cpu(entry->e_value_size);
499 + * ext3_xattr_inode_set()
501 + * this routine add/remove/replace attribute in inode body
504 +ext3_xattr_ibody_set(handle_t *handle, struct inode *inode, int name_index,
505 + const char *name, const void *value, size_t value_len,
508 + struct ext3_xattr_entry *last, *next, *here = NULL;
509 + struct ext3_inode *raw_inode;
510 + int name_len = strlen(name);
511 + int esize = EXT3_XATTR_LEN(name_len);
512 + struct buffer_head *bh;
513 + int err, storage_size;
514 + struct ext3_iloc iloc;
515 + int free, min_offs;
518 + if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
521 + err = ext3_get_inode_loc(inode, &iloc, 0);
524 + raw_inode = ext3_raw_inode(&iloc);
527 + storage_size = EXT3_SB(inode->i_sb)->s_inode_size -
528 + EXT3_GOOD_OLD_INODE_SIZE -
529 + EXT3_I(inode)->i_extra_isize -
531 + start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
532 + EXT3_I(inode)->i_extra_isize;
533 + if ((*(__u32*) start) != EXT3_XATTR_MAGIC) {
534 + /* inode had no attributes before */
535 + *((__u32*) start) = cpu_to_le32(EXT3_XATTR_MAGIC);
537 + start += sizeof(__u32);
538 + end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
539 + min_offs = storage_size;
540 + free = storage_size - sizeof(__u32);
542 + last = (struct ext3_xattr_entry *) start;
543 + while (!IS_LAST_ENTRY(last)) {
544 + next = EXT3_XATTR_NEXT(last);
545 + if (le32_to_cpu(last->e_value_size) > storage_size ||
546 + (char *) next >= end) {
547 + ext3_error(inode->i_sb, "ext3_xattr_ibody_set",
548 + "inode %ld", inode->i_ino);
553 + if (last->e_value_size) {
554 + int offs = le16_to_cpu(last->e_value_offs);
555 + if (offs < min_offs)
558 + if (name_index == last->e_name_index &&
559 + name_len == last->e_name_len &&
560 + !memcmp(name, last->e_name, name_len))
563 + /* we calculate all but our attribute
564 + * because it will be removed before changing */
565 + free -= EXT3_XATTR_LEN(last->e_name_len);
566 + free -= le32_to_cpu(last->e_value_size);
571 + if (value && (esize + value_len > free)) {
576 + err = ext3_reserve_inode_write(handle, inode, &iloc);
583 + /* time to remove old value */
584 + struct ext3_xattr_entry *e;
585 + int size = le32_to_cpu(here->e_value_size);
586 + int border = le16_to_cpu(here->e_value_offs);
590 + memmove(start + min_offs + size, start + min_offs,
591 + border - min_offs);
593 + /* recalculate offsets */
594 + e = (struct ext3_xattr_entry *) start;
595 + while (!IS_LAST_ENTRY(e)) {
596 + struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(e);
597 + int offs = le16_to_cpu(e->e_value_offs);
600 + cpu_to_le16(offs + size);
606 + border = EXT3_XATTR_LEN(here->e_name_len);
607 + src = (char *) here + EXT3_XATTR_LEN(here->e_name_len);
608 + size = (char *) last - src;
609 + if ((char *) here + size > end)
610 + printk("ALERT at %s:%d: 0x%p + %d > 0x%p\n",
611 + __FILE__, __LINE__, here, size, end);
612 + memmove(here, src, size);
613 + last = (struct ext3_xattr_entry *) ((char *) last - border);
614 + *((__u32 *) last) = 0;
618 + int offs = min_offs - value_len;
619 + /* use last to create new entry */
620 + memset(last, 0, esize);
621 + last->e_name_len = strlen(name);
622 + last->e_name_index = name_index;
623 + last->e_value_offs = cpu_to_le16(offs);
624 + last->e_value_size = cpu_to_le32(value_len);
625 + last->e_hash = last->e_value_block = 0;
626 + memcpy(last->e_name, name, last->e_name_len);
627 + if (start + offs + value_len > end)
628 + printk("ALERT at %s:%d: 0x%p + %d + %zd > 0x%p\n",
629 + __FILE__, __LINE__, start, offs,
631 + memcpy(start + offs, value, value_len);
632 + last = EXT3_XATTR_NEXT(last);
633 + *((__u32 *) last) = 0;
636 + ext3_mark_iloc_dirty(handle, inode, &iloc);
643 * ext3_xattr_set_handle()
645 * Create, replace or remove an extended attribute for this inode. Buffer
646 @@ -469,6 +958,110 @@ static void ext3_xattr_update_super_bloc
649 ext3_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
650 + const char *name, const void *value, size_t value_len,
653 + struct ext3_xattr_entry entry;
654 + int err, where = 0, found = 0, total;
655 + int free1 = -1, free2 = -1;
658 + ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
659 + name_index, name, value, (long)value_len);
661 + if (IS_RDONLY(inode))
663 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
669 + name_len = strlen(name);
670 + if (name_len > 255 || value_len > inode->i_sb->s_blocksize)
672 + down_write(&EXT3_I(inode)->xattr_sem);
674 + /* try to find attribute in inode body */
675 + err = ext3_xattr_ibody_find(inode, name_index, name, &entry, &free1);
677 + /* found EA in inode */
680 + } else if (err == -ENOENT) {
681 + /* there is no such attribute in inode body */
682 + /* try to find attribute in dedicated block */
683 + err = ext3_xattr_block_find(inode, name_index, name,
685 + if (err != 0 && err != -ENOENT) {
686 + /* not found EA in block */
688 + } else if (err == 0) {
689 + /* found EA in block */
696 + /* check flags: may replace? may create ? */
697 + if (found && (flags & XATTR_CREATE)) {
700 + } else if (!found && (flags & XATTR_REPLACE)) {
703 + } else if (!found && !value) {
708 + /* check if we have enough space to store attribute */
709 + total = EXT3_XATTR_LEN(strlen(name)) + value_len;
710 + if (free1 >= 0 && total > free1 && free2 >= 0 && total > free2) {
711 + /* have no enough space */
716 + /* time to remove attribute */
719 + /* EA is stored in inode body */
720 + ext3_xattr_ibody_set(handle, inode, name_index, name,
723 + /* EA is stored in separated block */
724 + ext3_xattr_block_set(handle, inode, name_index, name,
729 + /* Add entry if value is provided */
730 + if (value != NULL) {
731 + /* try to store EA in inode body */
732 + err = ext3_xattr_ibody_set(handle, inode, name_index, name,
733 + value, value_len, flags);
735 + /* can't store EA in inode body */
736 + /* try to store in block */
737 + err = ext3_xattr_block_set(handle, inode, name_index,
738 + name, value, value_len, flags);
743 + up_write(&EXT3_I(inode)->xattr_sem);
748 + * ext3_xattr_block_set()
750 + * this routine add/remove/replace attribute in EA block
753 +ext3_xattr_block_set(handle_t *handle, struct inode *inode, int name_index,
754 const char *name, const void *value, size_t value_len,
757 @@ -491,22 +1084,7 @@ ext3_xattr_set_handle(handle_t *handle,
758 * towards the end of the block).
759 * end -- Points right after the block pointed to by header.
762 - ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
763 - name_index, name, value, (long)value_len);
765 - if (IS_RDONLY(inode))
767 - if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
773 name_len = strlen(name);
774 - if (name_len > 255 || value_len > sb->s_blocksize)
776 - down_write(&EXT3_I(inode)->xattr_sem);
777 if (EXT3_I(inode)->i_file_acl) {
778 /* The inode already has an extended attribute block. */
779 bh = sb_bread(sb, EXT3_I(inode)->i_file_acl);
780 @@ -730,7 +1308,6 @@ cleanup:
782 if (!(bh && header == HDR(bh)))
784 - up_write(&EXT3_I(inode)->xattr_sem);
788 Index: linux-2.6.5-7.311/fs/ext3/xattr.h
789 ===================================================================
790 --- linux-2.6.5-7.311.orig/fs/ext3/xattr.h
791 +++ linux-2.6.5-7.311/fs/ext3/xattr.h
792 @@ -77,7 +77,8 @@ extern int ext3_removexattr(struct dentr
793 extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t);
794 extern int ext3_xattr_list(struct inode *, char *, size_t);
795 extern int ext3_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
796 -extern int ext3_xattr_set_handle(handle_t *, struct inode *, int, const char *, const void *, size_t, int);
797 +extern int ext3_xattr_set_handle(handle_t *, struct inode *, int, const char *,const void *,size_t,int);
798 +extern int ext3_xattr_block_set(handle_t *, struct inode *, int, const char *,const void *,size_t,int);
800 extern void ext3_xattr_delete_inode(handle_t *, struct inode *);
801 extern void ext3_xattr_put_super(struct super_block *);
802 Index: linux-2.6.5-7.311/include/linux/ext3_fs.h
803 ===================================================================
804 --- linux-2.6.5-7.311.orig/include/linux/ext3_fs.h
805 +++ linux-2.6.5-7.311/include/linux/ext3_fs.h
806 @@ -267,6 +267,8 @@ struct ext3_inode {
807 __u32 m_i_reserved2[2];
809 } osd2; /* OS dependent 2 */
810 + __u16 i_extra_isize;
814 #define i_size_high i_dir_acl
815 @@ -729,6 +731,7 @@ extern unsigned long ext3_count_free (st
816 extern int ext3_forget(handle_t *, int, struct inode *, struct buffer_head *, int);
817 extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
818 extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
819 +int ext3_get_inode_loc(struct inode *inode, struct ext3_iloc *iloc, int in_mem);
821 extern void ext3_read_inode (struct inode *);
822 extern void ext3_write_inode (struct inode *, int);
823 Index: linux-2.6.5-7.311/include/linux/ext3_fs_i.h
824 ===================================================================
825 --- linux-2.6.5-7.311.orig/include/linux/ext3_fs_i.h
826 +++ linux-2.6.5-7.311/include/linux/ext3_fs_i.h
827 @@ -113,6 +113,9 @@ struct ext3_inode_info {
831 + /* on-disk additional length */
832 + __u16 i_extra_isize;
835 * truncate_sem is for serialising ext3_truncate() against
836 * ext3_getblock(). In the 2.4 ext2 design, great chunks of inode's