1 Index: linux-stage/fs/ext4/ext4.h
2 ===================================================================
3 --- linux-stage.orig/fs/ext4/ext4.h
4 +++ linux-stage/fs/ext4/ext4.h
5 @@ -1329,6 +1329,7 @@ EXT4_INODE_BIT_FNS(state, state_flags)
6 #define EXT4_FEATURE_INCOMPAT_64BIT 0x0080
7 #define EXT4_FEATURE_INCOMPAT_MMP 0x0100
8 #define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200
9 +#define EXT4_FEATURE_INCOMPAT_EA_INODE 0x0400
10 #define EXT4_FEATURE_INCOMPAT_DIRDATA 0x1000
12 #define EXT4_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR
13 @@ -1338,6 +1339,7 @@ EXT4_INODE_BIT_FNS(state, state_flags)
14 EXT4_FEATURE_INCOMPAT_EXTENTS| \
15 EXT4_FEATURE_INCOMPAT_64BIT| \
16 EXT4_FEATURE_INCOMPAT_FLEX_BG| \
17 + EXT4_FEATURE_INCOMPAT_EA_INODE| \
18 EXT4_FEATURE_INCOMPAT_MMP| \
19 EXT4_FEATURE_INCOMPAT_DIRDATA)
21 @@ -1706,6 +1714,10 @@ struct mmpd_data {
22 # define ATTRIB_NORET __attribute__((noreturn))
23 # define NORET_AND noreturn,
25 +struct ext4_xattr_ino_array {
26 + unsigned int xia_count; /* # of used item in the array */
27 + unsigned int xia_inodes[0];
30 extern unsigned int ext4_count_free(struct buffer_head *, unsigned);
32 Index: linux-stage/fs/ext4/xattr.c
33 ===================================================================
34 --- linux-stage.orig/fs/ext4/xattr.c
35 +++ linux-stage/fs/ext4/xattr.c
36 @@ -168,19 +168,26 @@ ext4_xattr_check_block(struct buffer_hea
40 -ext4_xattr_check_entry(struct ext4_xattr_entry *entry, size_t size)
41 +ext4_xattr_check_entry(struct ext4_xattr_entry *entry, size_t size,
42 + struct inode *inode)
44 size_t value_size = le32_to_cpu(entry->e_value_size);
46 - if (entry->e_value_block != 0 || value_size > size ||
47 + if (!entry->e_value_inum &&
48 le16_to_cpu(entry->e_value_offs) + value_size > size)
50 + if (entry->e_value_inum &&
51 + (le32_to_cpu(entry->e_value_inum) < EXT4_FIRST_INO(inode->i_sb) ||
52 + le32_to_cpu(entry->e_value_inum) >
53 + le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_inodes_count)))
59 ext4_xattr_find_entry(struct ext4_xattr_entry **pentry, int name_index,
60 - const char *name, size_t size, int sorted)
61 + const char *name, size_t size, int sorted,
62 + struct inode *inode)
64 struct ext4_xattr_entry *entry;
66 @@ -200,11 +207,104 @@ ext4_xattr_find_entry(struct ext4_xattr_
70 - if (!cmp && ext4_xattr_check_entry(entry, size))
71 + if (!cmp && ext4_xattr_check_entry(entry, size, inode))
73 return cmp ? -ENODATA : 0;
77 + * Read the EA value from an inode.
80 +ext4_xattr_inode_read(struct inode *ea_inode, void *buf, size_t *size)
82 + unsigned long block = 0;
83 + struct buffer_head *bh = NULL;
85 + size_t csize, ret_size = 0;
90 + blocksize = ea_inode->i_sb->s_blocksize;
92 + while (ret_size < *size) {
93 + csize = (*size - ret_size) > blocksize ? blocksize :
95 + bh = ext4_bread(NULL, ea_inode, block, 0, &err);
100 + memcpy(buf, bh->b_data, csize);
113 +struct inode *ext4_xattr_inode_iget(struct inode *parent, unsigned long ea_ino, int *err)
115 + struct inode *ea_inode = NULL;
117 + ea_inode = ext4_iget(parent->i_sb, ea_ino);
118 + if (IS_ERR(ea_inode) || is_bad_inode(ea_inode)) {
119 + int rc = IS_ERR(ea_inode) ? PTR_ERR(ea_inode) : 0;
120 + ext4_error(parent->i_sb, "error while reading EA inode %lu "
121 + "/ %d %d", ea_ino, rc, is_bad_inode(ea_inode));
122 + *err = rc != 0 ? rc : -EIO;
126 + if (EXT4_XATTR_INODE_GET_PARENT(ea_inode) != parent->i_ino ||
127 + ea_inode->i_generation != parent->i_generation) {
128 + ext4_error(parent->i_sb, "Backpointer from EA inode %lu "
129 + "to parent invalid.", ea_ino);
134 + if (!(EXT4_I(ea_inode)->i_flags & EXT4_EA_INODE_FL)) {
135 + ext4_error(parent->i_sb, "EA inode %lu does not have "
136 + "EXT4_EA_INODE_FL flag set.\n", ea_ino);
150 + * Read the value from the EA inode.
153 +ext4_xattr_inode_get(struct inode *inode, unsigned long ea_ino, void *buffer,
156 + struct inode *ea_inode = NULL;
159 + ea_inode = ext4_xattr_inode_iget(inode, ea_ino, &err);
163 + err = ext4_xattr_inode_read(ea_inode, buffer, size);
170 ext4_xattr_block_get(struct inode *inode, int name_index, const char *name,
171 void *buffer, size_t buffer_size)
172 @@ -236,7 +335,8 @@ bad_block:
174 ext4_xattr_cache_insert(bh);
176 - error = ext4_xattr_find_entry(&entry, name_index, name, bh->b_size, 1);
177 + error = ext4_xattr_find_entry(&entry, name_index, name, bh->b_size, 1,
182 @@ -246,8 +346,16 @@ bad_block:
184 if (size > buffer_size)
186 - memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
188 + if (entry->e_value_inum) {
189 + error = ext4_xattr_inode_get(inode,
190 + le32_to_cpu(entry->e_value_inum),
195 + memcpy(buffer, bh->b_data +
196 + le16_to_cpu(entry->e_value_offs), size);
201 @@ -281,7 +389,7 @@ ext4_xattr_ibody_get(struct inode *inode
204 error = ext4_xattr_find_entry(&entry, name_index, name,
205 - end - (void *)entry, 0);
206 + end - (void *)entry, 0, inode);
209 size = le32_to_cpu(entry->e_value_size);
210 @@ -289,8 +397,16 @@ ext4_xattr_ibody_get(struct inode *inode
212 if (size > buffer_size)
214 - memcpy(buffer, (void *)IFIRST(header) +
215 - le16_to_cpu(entry->e_value_offs), size);
216 + if (entry->e_value_inum) {
217 + error = ext4_xattr_inode_get(inode,
218 + le32_to_cpu(entry->e_value_inum),
223 + memcpy(buffer, (void *)IFIRST(header) +
224 + le16_to_cpu(entry->e_value_offs), size);
229 @@ -513,7 +629,7 @@ static size_t ext4_xattr_free_space(stru
231 for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {
232 *total += EXT4_XATTR_LEN(last->e_name_len);
233 - if (!last->e_value_block && last->e_value_size) {
234 + if (!last->e_value_inum && last->e_value_size) {
235 size_t offs = le16_to_cpu(last->e_value_offs);
236 if (offs < *min_offs)
238 @@ -522,11 +638,159 @@ static size_t ext4_xattr_free_space(stru
239 return (*min_offs - ((void *)last - base) - sizeof(__u32));
243 + * Write the value of the EA in an inode.
246 +ext4_xattr_inode_write(handle_t *handle, struct inode *ea_inode,
247 + const void *buf, int bufsize)
249 + struct buffer_head *bh = NULL, dummy;
250 + unsigned long block = 0;
251 + unsigned blocksize = ea_inode->i_sb->s_blocksize;
252 + unsigned max_blocks = (bufsize + blocksize - 1) >> ea_inode->i_blkbits;
253 + int csize, wsize = 0;
258 + while (ret >= 0 && ret < max_blocks) {
262 + ret = ext4_get_blocks(handle, ea_inode, block, max_blocks,
263 + &dummy, EXT4_GET_BLOCKS_CREATE);
265 + ext4_mark_inode_dirty(handle, ea_inode);
266 + if (ret == -ENOSPC &&
267 + ext4_should_retry_alloc(ea_inode->i_sb, &retries)) {
279 + while (wsize < bufsize) {
282 + csize = (bufsize - wsize) > blocksize ? blocksize :
284 + bh = ext4_getblk(handle, ea_inode, block, 0, &ret);
287 + ret = ext4_journal_get_write_access(handle, bh);
291 + memcpy(bh->b_data, buf, csize);
292 + set_buffer_uptodate(bh);
293 + ext4_handle_dirty_metadata(handle, ea_inode, bh);
300 + i_size_write(ea_inode, wsize);
301 + ext4_update_i_disksize(ea_inode, wsize);
303 + ext4_mark_inode_dirty(handle, ea_inode);
312 + * Create an inode to store the value of a large EA.
314 +static struct inode *
315 +ext4_xattr_inode_create(handle_t *handle, struct inode *inode)
317 + struct inode *ea_inode = NULL;
320 + * Let the next inode be the goal, so we try and allocate the EA inode
321 + * in the same group, or nearby one.
323 + ea_inode = ext4_new_inode(handle, inode->i_sb->s_root->d_inode,
324 + S_IFREG|0600, NULL, inode->i_ino + 1);
326 + if (!IS_ERR(ea_inode)) {
327 + ea_inode->i_op = &ext4_file_inode_operations;
328 + ea_inode->i_fop = &ext4_file_operations;
329 + ext4_set_aops(ea_inode);
330 + ea_inode->i_generation = inode->i_generation;
331 + EXT4_I(ea_inode)->i_flags |= EXT4_EA_INODE_FL;
334 + * A back-pointer from EA inode to parent inode will be useful
337 + EXT4_XATTR_INODE_SET_PARENT(ea_inode, inode->i_ino);
338 + unlock_new_inode(ea_inode);
345 + * Unlink the inode storing the value of the EA.
348 +ext4_xattr_inode_unlink(struct inode *inode, unsigned long ea_ino)
350 + struct inode *ea_inode = NULL;
353 + ea_inode = ext4_xattr_inode_iget(inode, ea_ino, &err);
357 + ea_inode->i_nlink = 0;
364 + * Add value of the EA in an inode.
367 +ext4_xattr_inode_set(handle_t *handle, struct inode *inode, unsigned long *ea_ino,
368 + const void *value, size_t value_len)
370 + struct inode *ea_inode = NULL;
373 + /* Create an inode for the EA value */
374 + ea_inode = ext4_xattr_inode_create(handle, inode);
375 + if (IS_ERR(ea_inode))
378 + err = ext4_xattr_inode_write(handle, ea_inode, value, value_len);
380 + ea_inode->i_nlink = 0;
382 + *ea_ino = ea_inode->i_ino;
389 struct ext4_xattr_info {
398 struct ext4_xattr_search {
399 @@ -538,15 +802,23 @@ struct ext4_xattr_search {
403 -ext4_xattr_set_entry(struct ext4_xattr_info *i, struct ext4_xattr_search *s)
404 +ext4_xattr_set_entry(struct ext4_xattr_info *i, struct ext4_xattr_search *s,
405 + handle_t *handle, struct inode *inode)
407 struct ext4_xattr_entry *last;
408 size_t free, min_offs = s->end - s->base, name_len = strlen(i->name);
409 + int in_inode = i->in_inode;
411 + if (EXT4_HAS_INCOMPAT_FEATURE(inode->i_sb,
412 + EXT4_FEATURE_INCOMPAT_EA_INODE) &&
413 + (EXT4_XATTR_SIZE(i->value_len) >
414 + EXT4_XATTR_MIN_LARGE_EA_SIZE(inode->i_sb->s_blocksize)))
417 /* Compute min_offs and last. */
419 for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {
420 - if (!last->e_value_block && last->e_value_size) {
421 + if (!last->e_value_inum && last->e_value_size) {
422 size_t offs = le16_to_cpu(last->e_value_offs);
425 @@ -554,16 +826,21 @@ ext4_xattr_set_entry(struct ext4_xattr_i
427 free = min_offs - ((void *)last - s->base) - sizeof(__u32);
429 - if (!s->here->e_value_block && s->here->e_value_size) {
431 + !s->here->e_value_inum && s->here->e_value_size) {
432 size_t size = le32_to_cpu(s->here->e_value_size);
433 free += EXT4_XATTR_SIZE(size);
435 free += EXT4_XATTR_LEN(name_len);
438 - if (free < EXT4_XATTR_SIZE(i->value_len) ||
439 - free < EXT4_XATTR_LEN(name_len) +
440 - EXT4_XATTR_SIZE(i->value_len))
441 + size_t value_len = EXT4_XATTR_SIZE(i->value_len);
446 + if (free < value_len ||
447 + free < EXT4_XATTR_LEN(name_len) + value_len)
451 @@ -577,7 +854,8 @@ ext4_xattr_set_entry(struct ext4_xattr_i
452 s->here->e_name_len = name_len;
453 memcpy(s->here->e_name, i->name, name_len);
455 - if (!s->here->e_value_block && s->here->e_value_size) {
456 + if (!s->here->e_value_inum && s->here->e_value_size &&
457 + s->here->e_value_offs > 0) {
458 void *first_val = s->base + min_offs;
459 size_t offs = le16_to_cpu(s->here->e_value_offs);
460 void *val = s->base + offs;
461 @@ -606,13 +884,18 @@ ext4_xattr_set_entry(struct ext4_xattr_i
463 while (!IS_LAST_ENTRY(last)) {
464 size_t o = le16_to_cpu(last->e_value_offs);
465 - if (!last->e_value_block &&
466 + if (!last->e_value_inum &&
467 last->e_value_size && o < offs)
469 cpu_to_le16(o + size);
470 last = EXT4_XATTR_NEXT(last);
473 + if (s->here->e_value_inum) {
474 + ext4_xattr_inode_unlink(inode,
475 + le32_to_cpu(s->here->e_value_inum));
476 + s->here->e_value_inum = 0;
479 /* Remove the old name. */
480 size_t size = EXT4_XATTR_LEN(name_len);
481 @@ -626,10 +908,17 @@ ext4_xattr_set_entry(struct ext4_xattr_i
483 /* Insert the new value. */
484 s->here->e_value_size = cpu_to_le32(i->value_len);
485 - if (i->value_len) {
487 + unsigned long ea_ino = le32_to_cpu(s->here->e_value_inum);
488 + ext4_xattr_inode_set(handle, inode, &ea_ino, i->value,
490 + s->here->e_value_inum = cpu_to_le32(ea_ino);
491 + s->here->e_value_offs = 0;
492 + } else if (i->value_len) {
493 size_t size = EXT4_XATTR_SIZE(i->value_len);
494 void *val = s->base + min_offs - size;
495 s->here->e_value_offs = cpu_to_le16(min_offs - size);
496 + s->here->e_value_inum = 0;
497 memset(val + size - EXT4_XATTR_PAD, 0,
498 EXT4_XATTR_PAD); /* Clear the pad bytes. */
499 memcpy(val, i->value, i->value_len);
500 @@ -674,7 +963,7 @@ ext4_xattr_block_find(struct inode *inod
501 bs->s.end = bs->bh->b_data + bs->bh->b_size;
502 bs->s.here = bs->s.first;
503 error = ext4_xattr_find_entry(&bs->s.here, i->name_index,
504 - i->name, bs->bh->b_size, 1);
505 + i->name, bs->bh->b_size, 1, inode);
506 if (error && error != -ENODATA)
508 bs->s.not_found = error;
509 @@ -698,8 +987,6 @@ ext4_xattr_block_set(handle_t *handle, s
511 #define header(x) ((struct ext4_xattr_header *)(x))
513 - if (i->value && i->value_len > sb->s_blocksize)
516 ce = mb_cache_entry_get(ext4_xattr_cache, bs->bh->b_bdev,
518 @@ -714,7 +1001,7 @@ ext4_xattr_block_set(handle_t *handle, s
521 ea_bdebug(bs->bh, "modifying in-place");
522 - error = ext4_xattr_set_entry(i, s);
523 + error = ext4_xattr_set_entry(i, s, handle, inode);
525 if (!IS_LAST_ENTRY(s->first))
526 ext4_xattr_rehash(header(s->base),
527 @@ -766,7 +1053,7 @@ ext4_xattr_block_set(handle_t *handle, s
528 s->end = s->base + sb->s_blocksize;
531 - error = ext4_xattr_set_entry(i, s);
532 + error = ext4_xattr_set_entry(i, s, handle, inode);
536 @@ -917,7 +1204,7 @@ ext4_xattr_ibody_find(struct inode *inod
537 /* Find the named attribute. */
538 error = ext4_xattr_find_entry(&is->s.here, i->name_index,
540 - (void *)is->s.base, 0);
541 + (void *)is->s.base, 0, inode);
542 if (error && error != -ENODATA)
544 is->s.not_found = error;
545 @@ -936,7 +1223,7 @@ ext4_xattr_ibody_set(handle_t *handle, s
547 if (EXT4_I(inode)->i_extra_isize == 0)
549 - error = ext4_xattr_set_entry(i, s);
550 + error = ext4_xattr_set_entry(i, s, handle, inode);
553 header = IHDR(inode, ext4_raw_inode(&is->iloc));
554 @@ -972,7 +1259,7 @@ ext4_xattr_set_handle(handle_t *handle,
557 .value_len = value_len,
561 struct ext4_xattr_ibody_find is = {
562 .s = { .not_found = -ENODATA, },
563 @@ -1041,6 +1328,15 @@ ext4_xattr_set_handle(handle_t *handle,
566 error = ext4_xattr_block_set(handle, inode, &i, &bs);
567 + if (EXT4_HAS_INCOMPAT_FEATURE(inode->i_sb,
568 + EXT4_FEATURE_INCOMPAT_EA_INODE) &&
569 + error == -ENOSPC) {
570 + /* xattr not fit to block, store at external
573 + error = ext4_xattr_ibody_set(handle, inode,
578 if (!is.s.not_found) {
579 @@ -1087,10 +1383,25 @@ ext4_xattr_set(struct inode *inode, int
580 const void *value, size_t value_len, int flags)
583 + struct super_block *sb = inode->i_sb;
584 + int buffer_credits;
585 int error, retries = 0;
587 + buffer_credits = EXT4_DATA_TRANS_BLOCKS(sb);
588 + if ((value_len >= EXT4_XATTR_MIN_LARGE_EA_SIZE(sb->s_blocksize)) &&
589 + EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EA_INODE)) {
590 + int nrblocks = (value_len + sb->s_blocksize - 1) >>
591 + sb->s_blocksize_bits;
593 + /* For new inode */
594 + buffer_credits += EXT4_SINGLEDATA_TRANS_BLOCKS(sb) + 3;
596 + /* For data blocks of EA inode */
597 + buffer_credits += ext4_meta_trans_blocks(inode, nrblocks, 0);
601 - handle = ext4_journal_start(inode, EXT4_DATA_TRANS_BLOCKS(inode->i_sb));
602 + handle = ext4_journal_start(inode, buffer_credits);
603 if (IS_ERR(handle)) {
604 error = PTR_ERR(handle);
606 @@ -1100,7 +1411,7 @@ retry:
607 value, value_len, flags);
608 error2 = ext4_journal_stop(handle);
609 if (error == -ENOSPC &&
610 - ext4_should_retry_alloc(inode->i_sb, &retries))
611 + ext4_should_retry_alloc(sb, &retries))
615 @@ -1122,7 +1433,7 @@ static void ext4_xattr_shift_entries(str
617 /* Adjust the value offsets of the entries */
618 for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {
619 - if (!last->e_value_block && last->e_value_size) {
620 + if (!last->e_value_inum && last->e_value_size) {
621 new_offs = le16_to_cpu(last->e_value_offs) +
623 BUG_ON(new_offs + le32_to_cpu(last->e_value_size)
624 @@ -1355,22 +1666,135 @@ cleanup:
628 +#define EIA_INCR 16 /* must be 2^n */
629 +#define EIA_MASK (EIA_INCR - 1)
630 +/* Add the large xattr @ino into @lea_ino_array for later deletion.
631 + * If @lea_ino_array is new or full it will be grown and the old
632 + * contents copied over.
635 +ext4_expand_ino_array(struct ext4_xattr_ino_array **lea_ino_array, __u32 ino)
637 + if (*lea_ino_array == NULL) {
639 + * Start with 15 inodes, so it fits into a power-of-two size.
640 + * If *lea_ino_array is NULL, this is essentially offsetof()
643 + kmalloc(offsetof(struct ext4_xattr_ino_array,
644 + xia_inodes[EIA_MASK]),
646 + if (*lea_ino_array == NULL)
648 + (*lea_ino_array)->xia_count = 0;
649 + } else if (((*lea_ino_array)->xia_count & EIA_MASK) == EIA_MASK) {
650 + /* expand the array once all 15 + n * 16 slots are full */
651 + struct ext4_xattr_ino_array *new_array = NULL;
652 + int count = (*lea_ino_array)->xia_count;
654 + /* if new_array is NULL, this is essentially offsetof() */
655 + new_array = kmalloc(
656 + offsetof(struct ext4_xattr_ino_array,
657 + xia_inodes[count + EIA_INCR]),
659 + if (new_array == NULL)
661 + memcpy(new_array, *lea_ino_array,
662 + offsetof(struct ext4_xattr_ino_array,
663 + xia_inodes[count]));
664 + kfree(*lea_ino_array);
665 + *lea_ino_array = new_array;
667 + (*lea_ino_array)->xia_inodes[(*lea_ino_array)->xia_count++] = ino;
672 + * Add xattr inode to orphan list
675 +ext4_xattr_inode_orphan_add(handle_t *handle, struct inode *inode,
676 + int credits, struct ext4_xattr_ino_array *lea_ino_array)
678 + struct inode *ea_inode = NULL;
679 + int idx = 0, error = 0;
681 + if (lea_ino_array == NULL)
684 + for (; idx < lea_ino_array->xia_count; ++idx) {
685 + if (!ext4_handle_has_enough_credits(handle, credits)) {
686 + error = ext4_journal_extend(handle, credits);
688 + error = ext4_journal_restart(handle, credits);
691 + ext4_warning(inode->i_sb,
692 + "couldn't extend journal "
693 + "(err %d)", error);
697 + ea_inode = ext4_xattr_inode_iget(inode,
698 + lea_ino_array->xia_inodes[idx], &error);
701 + ext4_orphan_add(handle, ea_inode);
702 + /* the inode's i_count will be released by caller */
709 * ext4_xattr_delete_inode()
711 - * Free extended attribute resources associated with this inode. This
712 + * Free extended attribute resources associated with this inode. Traverse
713 + * all entries and unlink any xattr inodes associated with this inode. This
714 * is called immediately before an inode is freed. We have exclusive
715 - * access to the inode.
716 + * access to the inode. If an orphan inode is deleted it will also delete any
717 + * xattr block and all xattr inodes. They are checked by ext4_xattr_inode_iget()
718 + * to ensure they belong to the parent inode and were not deleted already.
721 -ext4_xattr_delete_inode(handle_t *handle, struct inode *inode)
723 +ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
724 + struct ext4_xattr_ino_array **lea_ino_array)
726 struct buffer_head *bh = NULL;
727 + struct ext4_xattr_ibody_header *header;
728 + struct ext4_inode *raw_inode;
729 + struct ext4_iloc iloc;
730 + struct ext4_xattr_entry *entry;
731 + int credits = 3, error = 0;
733 - if (!EXT4_I(inode)->i_file_acl)
734 + if (!ext4_test_inode_state(inode, EXT4_STATE_XATTR))
735 + goto delete_external_ea;
737 + error = ext4_get_inode_loc(inode, &iloc);
740 + raw_inode = ext4_raw_inode(&iloc);
741 + header = IHDR(inode, raw_inode);
742 + for (entry = IFIRST(header); !IS_LAST_ENTRY(entry);
743 + entry = EXT4_XATTR_NEXT(entry)) {
744 + if (!entry->e_value_inum)
746 + if (ext4_expand_ino_array(lea_ino_array,
747 + entry->e_value_inum) != 0) {
751 + entry->e_value_inum = 0;
756 + if (!EXT4_I(inode)->i_file_acl) {
757 + /* add xattr inode to orphan list */
758 + ext4_xattr_inode_orphan_add(handle, inode, credits,
762 bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
764 ext4_error(inode->i_sb, "inode %lu: block %llu read error",
765 @@ -1383,11 +1807,71 @@ ext4_xattr_delete_inode(handle_t *handle
766 inode->i_ino, EXT4_I(inode)->i_file_acl);
770 + for (entry = BFIRST(bh); !IS_LAST_ENTRY(entry);
771 + entry = EXT4_XATTR_NEXT(entry)) {
772 + if (!entry->e_value_inum)
774 + if (ext4_expand_ino_array(lea_ino_array,
775 + entry->e_value_inum) != 0)
777 + entry->e_value_inum = 0;
780 + /* add xattr inode to orphan list */
781 + error = ext4_xattr_inode_orphan_add(handle, inode, credits,
786 + if (!IS_NOQUOTA(inode))
787 + credits += 2 * EXT4_QUOTA_DEL_BLOCKS(inode->i_sb);
789 + if (!ext4_handle_has_enough_credits(handle, credits)) {
790 + error = ext4_journal_extend(handle, credits);
792 + error = ext4_journal_restart(handle, credits);
794 + ext4_warning(inode->i_sb,
795 + "couldn't extend journal (err %d)", error);
800 ext4_xattr_release_block(handle, inode, bh);
801 EXT4_I(inode)->i_file_acl = 0;
810 +ext4_xattr_inode_array_free(struct inode *inode,
811 + struct ext4_xattr_ino_array *lea_ino_array)
813 + struct inode *ea_inode = NULL;
817 + if (lea_ino_array == NULL)
820 + for (; idx < lea_ino_array->xia_count; ++idx) {
821 + ea_inode = ext4_xattr_inode_iget(inode,
822 + lea_ino_array->xia_inodes[idx], &err);
826 + /* for inode's i_count get from ext4_xattr_delete_inode */
827 + if (!list_empty(&EXT4_I(ea_inode)->i_orphan))
830 + ea_inode->i_nlink = 0;
833 + kfree(lea_ino_array);
837 @@ -1457,10 +1941,9 @@ ext4_xattr_cmp(struct ext4_xattr_header
838 entry1->e_name_index != entry2->e_name_index ||
839 entry1->e_name_len != entry2->e_name_len ||
840 entry1->e_value_size != entry2->e_value_size ||
841 + entry1->e_value_inum != entry2->e_value_inum ||
842 memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
844 - if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
846 if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
847 (char *)header2 + le16_to_cpu(entry2->e_value_offs),
848 le32_to_cpu(entry1->e_value_size)))
849 @@ -1545,7 +2028,7 @@ static inline void ext4_xattr_hash_entry
853 - if (entry->e_value_block == 0 && entry->e_value_size != 0) {
854 + if (!entry->e_value_inum && entry->e_value_size) {
855 __le32 *value = (__le32 *)((char *)header +
856 le16_to_cpu(entry->e_value_offs));
857 for (n = (le32_to_cpu(entry->e_value_size) +
858 Index: linux-stage/fs/ext4/xattr.h
859 ===================================================================
860 --- linux-stage.orig/fs/ext4/xattr.h
861 +++ linux-stage/fs/ext4/xattr.h
862 @@ -38,7 +38,7 @@ struct ext4_xattr_entry {
863 __u8 e_name_len; /* length of name */
864 __u8 e_name_index; /* attribute name index */
865 __le16 e_value_offs; /* offset in disk block of value */
866 - __le32 e_value_block; /* disk block attribute is stored on (n/i) */
867 + __le32 e_value_inum; /* inode in which the value is stored */
868 __le32 e_value_size; /* size of attribute value */
869 __le32 e_hash; /* hash value of name and value */
870 char e_name[0]; /* attribute name */
871 @@ -63,6 +63,26 @@ struct ext4_xattr_entry {
872 EXT4_I(inode)->i_extra_isize))
873 #define IFIRST(hdr) ((struct ext4_xattr_entry *)((hdr)+1))
876 + * Link EA inode back to parent one using i_mtime field.
877 + * Extra integer type conversion added to ignore higher
878 + * bits in i_mtime.tv_sec which might be set by ext4_get()
880 +#define EXT4_XATTR_INODE_SET_PARENT(inode, inum) \
882 + (inode)->i_mtime.tv_sec = inum; \
885 +#define EXT4_XATTR_INODE_GET_PARENT(inode) \
886 +((__u32)(inode)->i_mtime.tv_sec)
889 + * The minimum size of EA value when you start storing it in an external inode
890 + * size of block - size of header - size of 1 entry - 4 null bytes
892 +#define EXT4_XATTR_MIN_LARGE_EA_SIZE(b) \
893 + ((b) - EXT4_XATTR_LEN(3) - sizeof(struct ext4_xattr_header) - 4)
895 # ifdef CONFIG_EXT4_FS_XATTR
897 extern struct xattr_handler ext4_xattr_user_handler;
898 @@ -77,7 +86,13 @@ extern int ext4_xattr_get(struct inode *
899 extern int ext4_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
900 extern int ext4_xattr_set_handle(handle_t *, struct inode *, int, const char *, const void *, size_t, int);
902 -extern void ext4_xattr_delete_inode(handle_t *, struct inode *);
903 +extern struct inode *ext4_xattr_inode_iget(struct inode *parent, unsigned long ea_ino,
905 +extern int ext4_xattr_inode_unlink(struct inode *inode, unsigned long ea_ino);
906 +extern int ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
907 + struct ext4_xattr_ino_array **array);
908 +extern void ext4_xattr_inode_array_free(struct inode *inode,
909 + struct ext4_xattr_ino_array *array);
910 extern void ext4_xattr_put_super(struct super_block *);
912 extern int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
913 @@ -111,9 +126,11 @@ ext4_xattr_set_handle(handle_t *handle,
918 -ext4_xattr_delete_inode(handle_t *handle, struct inode *inode)
920 +ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
921 + struct ext4_xattr_ino_array **array)
923 + return -EOPNOTSUPP;
927 Index: linux-stage/fs/ext4/inode.c
928 ===================================================================
929 --- linux-stage.orig/fs/ext4/inode.c
930 +++ linux-stage/fs/ext4/inode.c
931 @@ -222,6 +222,8 @@ void ext4_delete_inode(struct inode *ino
935 + int extra_credits = 3;
936 + struct ext4_xattr_ino_array *lea_ino_array = NULL;
938 if (ext4_should_order_data(inode))
939 ext4_begin_ordered_truncate(inode, 0);
940 @@ -235,7 +237,8 @@ void ext4_delete_inode(struct inode *ino
941 * protection against it
943 sb_start_intwrite(inode->i_sb);
944 - handle = ext4_journal_start(inode, blocks_for_truncate(inode)+3);
946 + handle = ext4_journal_start(inode, extra_credits);
947 if (IS_ERR(handle)) {
948 ext4_std_error(inode->i_sb, PTR_ERR(handle));
950 @@ -247,9 +250,36 @@ void ext4_delete_inode(struct inode *ino
951 sb_end_intwrite(inode->i_sb);
956 ext4_handle_sync(handle);
959 + * Delete xattr inode before deleting the main inode.
961 + err = ext4_xattr_delete_inode(handle, inode, &lea_ino_array);
963 + ext4_warning(inode->i_sb,
964 + "couldn't delete inode's xattr (err %d)", err);
968 + if (!IS_NOQUOTA(inode))
969 + extra_credits += 2 * EXT4_QUOTA_DEL_BLOCKS(inode->i_sb);
971 + if (!ext4_handle_has_enough_credits(handle,
972 + blocks_for_truncate(inode) + extra_credits)) {
973 + err = ext4_journal_extend(handle,
974 + blocks_for_truncate(inode) + extra_credits);
976 + err = ext4_journal_restart(handle,
977 + blocks_for_truncate(inode) + extra_credits);
979 + ext4_warning(inode->i_sb,
980 + "couldn't extend journal (err %d)", err);
986 err = ext4_mark_inode_dirty(handle, inode);
988 @@ -266,10 +296,10 @@ void ext4_delete_inode(struct inode *ino
989 * enough credits left in the handle to remove the inode from
990 * the orphan list and set the dtime field.
992 - if (!ext4_handle_has_enough_credits(handle, 3)) {
993 - err = ext4_journal_extend(handle, 3);
994 + if (!ext4_handle_has_enough_credits(handle, extra_credits)) {
995 + err = ext4_journal_extend(handle, extra_credits);
997 - err = ext4_journal_restart(handle, 3);
998 + err = ext4_journal_restart(handle, extra_credits);
1000 ext4_warning(inode->i_sb,
1001 "couldn't extend journal (err %d)", err);
1002 @@ -303,8 +333,12 @@ void ext4_delete_inode(struct inode *ino
1005 ext4_free_inode(handle, inode);
1007 ext4_journal_stop(handle);
1008 sb_end_intwrite(inode->i_sb);
1010 + if (lea_ino_array != NULL)
1011 + ext4_xattr_inode_array_free(inode, lea_ino_array);
1014 clear_inode(inode); /* We must guarantee clearing of inode... */
1015 Index: linux-stage/fs/ext4/extents.c
1016 ===================================================================
1017 --- linux-stage.orig/fs/ext4/extents.c
1018 +++ linux-stage/fs/ext4/extents.c
1019 @@ -2163,7 +2163,8 @@ int ext4_remove_blocks(handle_t *handle
1020 unsigned short ee_len = ext4_ext_get_actual_len(ex);
1021 int i, metadata = 0;
1023 - if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
1024 + if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode) ||
1025 + (EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL))
1027 #ifdef EXTENTS_STATS
1029 Index: linux-stage/fs/ext4/ialloc.c
1030 ===================================================================
1031 --- linux-stage.orig/fs/ext4/ialloc.c
1032 +++ linux-stage/fs/ext4/ialloc.c
1033 @@ -219,7 +219,6 @@ void ext4_free_inode(handle_t *handle, s
1034 * as writing the quota to disk may need the lock as well.
1037 - ext4_xattr_delete_inode(handle, inode);
1038 vfs_dq_free_inode(inode);
1041 Index: linux-stage/fs/ext4/inode.c
1042 ===================================================================
1043 --- linux-stage.orig/fs/ext4/inode.c
1044 +++ linux-stage/fs/ext4/inode.c
1045 @@ -4385,7 +4385,8 @@ static void ext4_clear_blocks(handle_t *h
1049 - int is_metadata = S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode);
1050 + int is_metadata = S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode) ||
1051 + (EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL);
1053 if (try_to_extend_transaction(handle, inode)) {