Lines Matching +full:fs +full:- +full:extra
2 * ext_attr.c --- extended attribute blocks
8 * %Begin-Header%
11 * %End-Header%
28 static errcode_t read_ea_inode_hash(ext2_filsys fs, ext2_ino_t ino, __u32 *hash) in read_ea_inode_hash() argument
33 retval = ext2fs_read_inode(fs, ino, &inode); in read_ea_inode_hash()
55 for (n = 0; n < entry->e_name_len; n++) { in ext2fs_ext_attr_hash_entry()
57 (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^ in ext2fs_ext_attr_hash_entry()
61 /* The hash needs to be calculated on the data in little-endian. */ in ext2fs_ext_attr_hash_entry()
62 if (entry->e_value_inum == 0 && entry->e_value_size != 0) { in ext2fs_ext_attr_hash_entry()
64 for (n = (entry->e_value_size + EXT2_EXT_ATTR_ROUND) >> in ext2fs_ext_attr_hash_entry()
65 EXT2_EXT_ATTR_PAD_BITS; n; n--) { in ext2fs_ext_attr_hash_entry()
67 (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^ in ext2fs_ext_attr_hash_entry()
83 for (n = 0; n < entry->e_name_len; n++) { in ext2fs_ext_attr_hash_entry_signed()
85 (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^ in ext2fs_ext_attr_hash_entry_signed()
89 /* The hash needs to be calculated on the data in little-endian. */ in ext2fs_ext_attr_hash_entry_signed()
90 if (entry->e_value_inum == 0 && entry->e_value_size != 0) { in ext2fs_ext_attr_hash_entry_signed()
92 for (n = (entry->e_value_size + EXT2_EXT_ATTR_ROUND) >> in ext2fs_ext_attr_hash_entry_signed()
93 EXT2_EXT_ATTR_PAD_BITS; n; n--) { in ext2fs_ext_attr_hash_entry_signed()
95 (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^ in ext2fs_ext_attr_hash_entry_signed()
112 errcode_t ext2fs_ext_attr_hash_entry3(ext2_filsys fs, in ext2fs_ext_attr_hash_entry3() argument
121 if (entry->e_value_inum) { in ext2fs_ext_attr_hash_entry3()
125 retval = read_ea_inode_hash(fs, entry->e_value_inum, in ext2fs_ext_attr_hash_entry3()
131 (*hash >> (8*sizeof(*hash) - VALUE_HASH_SHIFT)) ^ in ext2fs_ext_attr_hash_entry3()
135 (*signed_hash >> (8*sizeof(*hash) - in ext2fs_ext_attr_hash_entry3()
149 errcode_t ext2fs_ext_attr_hash_entry2(ext2_filsys fs, in ext2fs_ext_attr_hash_entry2() argument
153 return ext2fs_ext_attr_hash_entry3(fs, entry, data, hash, NULL); in ext2fs_ext_attr_hash_entry2()
170 if (!here->e_hash) { in ext2fs_ext_attr_block_rehash()
176 (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^ in ext2fs_ext_attr_block_rehash()
177 here->e_hash; in ext2fs_ext_attr_block_rehash()
180 header->h_hash = hash; in ext2fs_ext_attr_block_rehash()
187 return inode->i_atime; in ext2fs_get_ea_inode_hash()
192 inode->i_atime = hash; in ext2fs_set_ea_inode_hash()
197 return ((__u64)inode->i_ctime << 32) | inode->osd1.linux1.l_i_version; in ext2fs_get_ea_inode_ref()
202 inode->i_ctime = (__u32)(ref_count >> 32); in ext2fs_set_ea_inode_ref()
203 inode->osd1.linux1.l_i_version = (__u32)ref_count; in ext2fs_set_ea_inode_ref()
208 if ((header->h_magic != EXT2_EXT_ATTR_MAGIC_v1 && in check_ext_attr_header()
209 header->h_magic != EXT2_EXT_ATTR_MAGIC) || in check_ext_attr_header()
210 header->h_blocks != 1) in check_ext_attr_header()
216 errcode_t ext2fs_read_ext_attr3(ext2_filsys fs, blk64_t block, void *buf, in ext2fs_read_ext_attr3() argument
222 retval = io_channel_read_blk64(fs->io, block, 1, buf); in ext2fs_read_ext_attr3()
226 if (!(fs->flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) && in ext2fs_read_ext_attr3()
227 !ext2fs_ext_attr_block_csum_verify(fs, inum, block, buf)) in ext2fs_read_ext_attr3()
231 ext2fs_swap_ext_attr(buf, buf, fs->blocksize, 1); in ext2fs_read_ext_attr3()
241 errcode_t ext2fs_read_ext_attr2(ext2_filsys fs, blk64_t block, void *buf) in ext2fs_read_ext_attr2() argument
243 return ext2fs_read_ext_attr3(fs, block, buf, 0); in ext2fs_read_ext_attr2()
246 errcode_t ext2fs_read_ext_attr(ext2_filsys fs, blk_t block, void *buf) in ext2fs_read_ext_attr() argument
248 return ext2fs_read_ext_attr2(fs, block, buf); in ext2fs_read_ext_attr()
251 errcode_t ext2fs_write_ext_attr3(ext2_filsys fs, blk64_t block, void *inbuf, in ext2fs_write_ext_attr3() argument
258 retval = ext2fs_get_mem(fs->blocksize, &write_buf); in ext2fs_write_ext_attr3()
261 ext2fs_swap_ext_attr(write_buf, inbuf, fs->blocksize, 1); in ext2fs_write_ext_attr3()
266 retval = ext2fs_ext_attr_block_csum_set(fs, inum, block, in ext2fs_write_ext_attr3()
271 retval = io_channel_write_blk64(fs->io, block, 1, write_buf); in ext2fs_write_ext_attr3()
276 ext2fs_mark_changed(fs); in ext2fs_write_ext_attr3()
280 errcode_t ext2fs_write_ext_attr2(ext2_filsys fs, blk64_t block, void *inbuf) in ext2fs_write_ext_attr2() argument
282 return ext2fs_write_ext_attr3(fs, block, inbuf, 0); in ext2fs_write_ext_attr2()
285 errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block, void *inbuf) in ext2fs_write_ext_attr() argument
287 return ext2fs_write_ext_attr2(fs, block, inbuf); in ext2fs_write_ext_attr()
293 errcode_t ext2fs_adjust_ea_refcount3(ext2_filsys fs, blk64_t blk, in ext2fs_adjust_ea_refcount3() argument
301 if ((blk >= ext2fs_blocks_count(fs->super)) || in ext2fs_adjust_ea_refcount3()
302 (blk < fs->super->s_first_data_block)) in ext2fs_adjust_ea_refcount3()
306 retval = ext2fs_get_mem(fs->blocksize, &buf); in ext2fs_adjust_ea_refcount3()
312 retval = ext2fs_read_ext_attr3(fs, blk, block_buf, inum); in ext2fs_adjust_ea_refcount3()
317 header->h_refcount += adjust; in ext2fs_adjust_ea_refcount3()
319 *newcount = header->h_refcount; in ext2fs_adjust_ea_refcount3()
321 retval = ext2fs_write_ext_attr3(fs, blk, block_buf, inum); in ext2fs_adjust_ea_refcount3()
331 errcode_t ext2fs_adjust_ea_refcount2(ext2_filsys fs, blk64_t blk, in ext2fs_adjust_ea_refcount2() argument
335 return ext2fs_adjust_ea_refcount3(fs, blk, block_buf, adjust, in ext2fs_adjust_ea_refcount2()
339 errcode_t ext2fs_adjust_ea_refcount(ext2_filsys fs, blk_t blk, in ext2fs_adjust_ea_refcount() argument
343 return ext2fs_adjust_ea_refcount2(fs, blk, block_buf, adjust, in ext2fs_adjust_ea_refcount()
359 ext2_filsys fs; member
374 err = ext2fs_get_arrayzero(h->capacity + expandby, in ext2fs_xattrs_expand()
379 memcpy(new_attrs, h->attrs, h->capacity * sizeof(struct ext2_xattr)); in ext2fs_xattrs_expand()
380 ext2fs_free_mem(&h->attrs); in ext2fs_xattrs_expand()
381 h->capacity += expandby; in ext2fs_xattrs_expand()
382 h->attrs = new_attrs; in ext2fs_xattrs_expand()
409 for (e = ea_names; e->name; e++) in find_ea_prefix()
410 if (e->index == index) in find_ea_prefix()
411 return e->name; in find_ea_prefix()
420 for (e = ea_names; e->name; e++) { in find_ea_index()
421 if (strncmp(fullname, e->name, strlen(e->name)) == 0) { in find_ea_index()
422 *name = fullname + strlen(e->name); in find_ea_index()
423 *index = e->index; in find_ea_index()
430 errcode_t ext2fs_free_ext_attr(ext2_filsys fs, ext2_ino_t ino, in ext2fs_free_ext_attr() argument
441 err = ext2fs_read_inode_full(fs, ino, (struct ext2_inode *)&i, in ext2fs_free_ext_attr()
449 blk = ext2fs_file_acl_block(fs, (struct ext2_inode *)inode); in ext2fs_free_ext_attr()
454 if ((blk < fs->super->s_first_data_block) || in ext2fs_free_ext_attr()
455 (blk >= ext2fs_blocks_count(fs->super))) { in ext2fs_free_ext_attr()
460 err = ext2fs_get_mem(fs->blocksize, &block_buf); in ext2fs_free_ext_attr()
464 err = ext2fs_read_ext_attr3(fs, blk, block_buf, ino); in ext2fs_free_ext_attr()
470 if (header->h_magic != EXT2_EXT_ATTR_MAGIC) { in ext2fs_free_ext_attr()
475 header->h_refcount--; in ext2fs_free_ext_attr()
476 err = ext2fs_write_ext_attr3(fs, blk, block_buf, ino); in ext2fs_free_ext_attr()
481 ext2fs_file_acl_block_set(fs, (struct ext2_inode *)inode, 0); in ext2fs_free_ext_attr()
482 if (header->h_refcount == 0) in ext2fs_free_ext_attr()
483 ext2fs_block_alloc_stats2(fs, blk, -1); in ext2fs_free_ext_attr()
484 err = ext2fs_iblk_sub_blocks(fs, (struct ext2_inode *)inode, 1); in ext2fs_free_ext_attr()
490 err = ext2fs_write_inode_full(fs, ino, (struct ext2_inode *)&i, in ext2fs_free_ext_attr()
502 static errcode_t prep_ea_block_for_write(ext2_filsys fs, ext2_ino_t ino, in prep_ea_block_for_write() argument
511 blk = ext2fs_file_acl_block(fs, (struct ext2_inode *)inode); in prep_ea_block_for_write()
513 if ((blk < fs->super->s_first_data_block) || in prep_ea_block_for_write()
514 (blk >= ext2fs_blocks_count(fs->super))) { in prep_ea_block_for_write()
519 err = ext2fs_get_mem(fs->blocksize, &block_buf); in prep_ea_block_for_write()
523 err = ext2fs_read_ext_attr3(fs, blk, block_buf, ino); in prep_ea_block_for_write()
529 if (header->h_magic != EXT2_EXT_ATTR_MAGIC) { in prep_ea_block_for_write()
534 /* Single-user block. We're done here. */ in prep_ea_block_for_write()
535 if (header->h_refcount == 1) in prep_ea_block_for_write()
539 header->h_refcount--; in prep_ea_block_for_write()
540 err = ext2fs_write_ext_attr3(fs, blk, block_buf, ino); in prep_ea_block_for_write()
545 err = ext2fs_iblk_add_blocks(fs, (struct ext2_inode *)inode, in prep_ea_block_for_write()
552 goal = ext2fs_find_inode_goal(fs, ino, (struct ext2_inode *)inode, 0); in prep_ea_block_for_write()
553 err = ext2fs_alloc_block2(fs, goal, NULL, &blk); in prep_ea_block_for_write()
556 ext2fs_file_acl_block_set(fs, (struct ext2_inode *)inode, blk); in prep_ea_block_for_write()
569 return -1; in posix_acl_xattr_count()
570 size -= sizeof(posix_acl_xattr_header); in posix_acl_xattr_count()
572 return -1; in posix_acl_xattr_count()
578 * attribute format. The on-disk format uses a more compact encoding.
579 * See the ext4_acl_to_disk in fs/ext4/acl.c.
598 if (header->a_version != ext2fs_cpu_to_le32(POSIX_ACL_XATTR_VERSION)) in convert_posix_acl_to_disk_buffer()
603 ext_acl->a_version = ext2fs_cpu_to_le32(EXT4_ACL_VERSION); in convert_posix_acl_to_disk_buffer()
612 disk_entry->e_tag = entry->e_tag; in convert_posix_acl_to_disk_buffer()
613 disk_entry->e_perm = entry->e_perm; in convert_posix_acl_to_disk_buffer()
615 switch(ext2fs_le16_to_cpu(entry->e_tag)) { in convert_posix_acl_to_disk_buffer()
625 disk_entry->e_id = entry->e_id; in convert_posix_acl_to_disk_buffer()
649 (ext_acl->a_version != ext2fs_cpu_to_le32(EXT4_ACL_VERSION))) in convert_disk_buffer_to_posix_acl()
657 header->a_version = ext2fs_cpu_to_le32(POSIX_ACL_XATTR_VERSION); in convert_disk_buffer_to_posix_acl()
661 size -= sizeof(ext4_acl_header); in convert_disk_buffer_to_posix_acl()
666 entry->e_tag = disk_entry->e_tag; in convert_disk_buffer_to_posix_acl()
667 entry->e_perm = disk_entry->e_perm; in convert_disk_buffer_to_posix_acl()
669 switch(ext2fs_le16_to_cpu(entry->e_tag)) { in convert_disk_buffer_to_posix_acl()
674 entry->e_id = 0; in convert_disk_buffer_to_posix_acl()
676 size -= sizeof(ext4_acl_entry_short); in convert_disk_buffer_to_posix_acl()
680 entry->e_id = disk_entry->e_id; in convert_disk_buffer_to_posix_acl()
682 size -= sizeof(ext4_acl_entry); in convert_disk_buffer_to_posix_acl()
691 *size_out = ((char *) entry - out); in convert_disk_buffer_to_posix_acl()
696 write_xattrs_to_buffer(ext2_filsys fs, struct ext2_xattr *attrs, int count, in write_xattrs_to_buffer() argument
708 value_size = ((x->value_len + EXT2_EXT_ATTR_PAD - 1) / in write_xattrs_to_buffer()
712 e->e_name_len = strlen(x->short_name); in write_xattrs_to_buffer()
713 e->e_name_index = x->name_index; in write_xattrs_to_buffer()
715 e->e_value_size = x->value_len; in write_xattrs_to_buffer()
716 e->e_value_inum = x->ea_ino; in write_xattrs_to_buffer()
719 memcpy((char *)e + sizeof(*e), x->short_name, e->e_name_len); in write_xattrs_to_buffer()
720 if (x->ea_ino) { in write_xattrs_to_buffer()
721 e->e_value_offs = 0; in write_xattrs_to_buffer()
723 end -= value_size; in write_xattrs_to_buffer()
724 e->e_value_offs = end - (char *) entries_start + in write_xattrs_to_buffer()
726 memcpy(end, x->value, e->e_value_size); in write_xattrs_to_buffer()
729 if (write_hash || x->ea_ino) { in write_xattrs_to_buffer()
730 err = ext2fs_ext_attr_hash_entry2(fs, e, in write_xattrs_to_buffer()
731 x->ea_ino ? 0 : end, in write_xattrs_to_buffer()
732 &e->e_hash); in write_xattrs_to_buffer()
736 e->e_hash = 0; in write_xattrs_to_buffer()
746 ext2_filsys fs = handle->fs; in ext2fs_xattrs_write() local
747 const unsigned int inode_size = EXT2_INODE_SIZE(fs->super); in ext2fs_xattrs_write()
765 err = ext2fs_read_inode_full(fs, handle->ino, EXT2_INODE(inode), in ext2fs_xattrs_write()
771 if (inode->i_extra_isize == 0 && in ext2fs_xattrs_write()
774 size_t extra = fs->super->s_want_extra_isize; in ext2fs_xattrs_write() local
776 if (extra == 0) in ext2fs_xattrs_write()
777 extra = sizeof(__u32); in ext2fs_xattrs_write()
778 memset(p + EXT2_GOOD_OLD_INODE_SIZE, 0, extra); in ext2fs_xattrs_write()
779 inode->i_extra_isize = extra; in ext2fs_xattrs_write()
781 if (inode->i_extra_isize & 3) { in ext2fs_xattrs_write()
787 if (inode->i_extra_isize < sizeof(inode->i_extra_isize) || in ext2fs_xattrs_write()
788 inode_size <= EXT2_GOOD_OLD_INODE_SIZE + inode->i_extra_isize + in ext2fs_xattrs_write()
795 inode->i_extra_isize, &ea_inode_magic, sizeof(__u32)); in ext2fs_xattrs_write()
796 storage_size = inode_size - EXT2_GOOD_OLD_INODE_SIZE - in ext2fs_xattrs_write()
797 inode->i_extra_isize - sizeof(__u32); in ext2fs_xattrs_write()
799 inode->i_extra_isize + sizeof(__u32); in ext2fs_xattrs_write()
801 err = write_xattrs_to_buffer(fs, handle->attrs, handle->ibody_count, in ext2fs_xattrs_write()
807 if (handle->ibody_count == handle->count && in ext2fs_xattrs_write()
808 !ext2fs_file_acl_block(fs, EXT2_INODE(inode))) in ext2fs_xattrs_write()
812 err = ext2fs_get_memzero(fs->blocksize, &block_buf); in ext2fs_xattrs_write()
816 storage_size = fs->blocksize - sizeof(struct ext2_ext_attr_header); in ext2fs_xattrs_write()
819 err = write_xattrs_to_buffer(fs, handle->attrs + handle->ibody_count, in ext2fs_xattrs_write()
820 handle->count - handle->ibody_count, start, in ext2fs_xattrs_write()
821 storage_size, start - block_buf, 1); in ext2fs_xattrs_write()
827 header->h_magic = EXT2_EXT_ATTR_MAGIC; in ext2fs_xattrs_write()
828 header->h_refcount = 1; in ext2fs_xattrs_write()
829 header->h_blocks = 1; in ext2fs_xattrs_write()
832 err = prep_ea_block_for_write(fs, handle->ino, inode); in ext2fs_xattrs_write()
837 blk = ext2fs_file_acl_block(fs, EXT2_INODE(inode)); in ext2fs_xattrs_write()
838 err = ext2fs_write_ext_attr3(fs, blk, block_buf, handle->ino); in ext2fs_xattrs_write()
843 blk = ext2fs_file_acl_block(fs, (struct ext2_inode *)inode); in ext2fs_xattrs_write()
846 err = ext2fs_free_ext_attr(fs, handle->ino, inode); in ext2fs_xattrs_write()
852 err = ext2fs_write_inode_full(fs, handle->ino, EXT2_INODE(inode), in ext2fs_xattrs_write()
876 ((char *)entries - value_start); in read_xattrs_from_buffer()
885 remain -= sizeof(struct ext2_ext_attr_entry); in read_xattrs_from_buffer()
888 if (EXT2_EXT_ATTR_SIZE(end->e_name_len) > remain) in read_xattrs_from_buffer()
892 remain -= EXT2_EXT_ATTR_SIZE(end->e_name_len); in read_xattrs_from_buffer()
902 if (handle->count == handle->capacity) { in read_xattrs_from_buffer()
908 x = handle->attrs + handle->count; in read_xattrs_from_buffer()
911 remain -= sizeof(struct ext2_ext_attr_entry); in read_xattrs_from_buffer()
914 remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len); in read_xattrs_from_buffer()
917 prefix = find_ea_prefix(entry->e_name_index); in read_xattrs_from_buffer()
919 err = ext2fs_get_memzero(entry->e_name_len + prefix_len + 1, in read_xattrs_from_buffer()
920 &x->name); in read_xattrs_from_buffer()
924 memcpy(x->name, prefix, prefix_len); in read_xattrs_from_buffer()
925 if (entry->e_name_len) in read_xattrs_from_buffer()
926 memcpy(x->name + prefix_len, in read_xattrs_from_buffer()
928 entry->e_name_len); in read_xattrs_from_buffer()
929 x->short_name = x->name + prefix_len; in read_xattrs_from_buffer()
930 x->name_index = entry->e_name_index; in read_xattrs_from_buffer()
933 if (!ext2fs_has_feature_ea_inode(handle->fs->super) && in read_xattrs_from_buffer()
934 entry->e_value_inum != 0) in read_xattrs_from_buffer()
937 if (entry->e_value_inum == 0) { in read_xattrs_from_buffer()
938 if (entry->e_value_size > remain) in read_xattrs_from_buffer()
941 if (entry->e_value_offs + entry->e_value_size > values_size) in read_xattrs_from_buffer()
944 if (entry->e_value_size > 0 && in read_xattrs_from_buffer()
945 value_start + entry->e_value_offs < in read_xattrs_from_buffer()
949 remain -= entry->e_value_size; in read_xattrs_from_buffer()
951 err = ext2fs_get_mem(entry->e_value_size, &x->value); in read_xattrs_from_buffer()
954 memcpy(x->value, value_start + entry->e_value_offs, in read_xattrs_from_buffer()
955 entry->e_value_size); in read_xattrs_from_buffer()
960 if (entry->e_value_offs != 0) in read_xattrs_from_buffer()
963 if (entry->e_value_size > (64 * 1024)) in read_xattrs_from_buffer()
966 err = ext2fs_get_mem(entry->e_value_size, &x->value); in read_xattrs_from_buffer()
970 err = ext2fs_file_open(handle->fs, entry->e_value_inum, in read_xattrs_from_buffer()
976 if ((ea_inode->i_flags & EXT4_INLINE_DATA_FL) || in read_xattrs_from_buffer()
977 !(ea_inode->i_flags & EXT4_EA_INODE_FL) || in read_xattrs_from_buffer()
978 ea_inode->i_links_count == 0) in read_xattrs_from_buffer()
981 entry->e_value_size) in read_xattrs_from_buffer()
984 err = ext2fs_file_read(ea_file, x->value, in read_xattrs_from_buffer()
985 entry->e_value_size, 0); in read_xattrs_from_buffer()
991 x->ea_ino = entry->e_value_inum; in read_xattrs_from_buffer()
992 x->value_len = entry->e_value_size; in read_xattrs_from_buffer()
995 if (entry->e_hash != 0) { in read_xattrs_from_buffer()
998 void *data = (entry->e_value_inum != 0) ? in read_xattrs_from_buffer()
999 0 : value_start + entry->e_value_offs; in read_xattrs_from_buffer()
1001 err = ext2fs_ext_attr_hash_entry3(handle->fs, entry, in read_xattrs_from_buffer()
1006 if ((entry->e_hash != hash) && in read_xattrs_from_buffer()
1007 (entry->e_hash != signed_hash)) { in read_xattrs_from_buffer()
1010 /* Check whether this is an old Lustre-style in read_xattrs_from_buffer()
1013 err = ext2fs_read_inode(handle->fs, in read_xattrs_from_buffer()
1014 entry->e_value_inum, in read_xattrs_from_buffer()
1018 if (child.i_mtime != handle->ino || in read_xattrs_from_buffer()
1019 child.i_generation != inode->i_generation) in read_xattrs_from_buffer()
1024 handle->count++; in read_xattrs_from_buffer()
1033 struct ext2_xattr *a = h->attrs; in xattrs_free_keys()
1036 for (i = 0; i < h->capacity; i++) { in xattrs_free_keys()
1042 h->count = 0; in xattrs_free_keys()
1043 h->ibody_count = 0; in xattrs_free_keys()
1058 i = EXT2_INODE_SIZE(handle->fs->super); in ext2fs_xattrs_read()
1065 err = ext2fs_read_inode_full(handle->fs, handle->ino, in ext2fs_xattrs_read()
1067 EXT2_INODE_SIZE(handle->fs->super)); in ext2fs_xattrs_read()
1074 if (inode->i_extra_isize < sizeof(inode->i_extra_isize) || in ext2fs_xattrs_read()
1075 EXT2_INODE_SIZE(handle->fs->super) <= EXT2_GOOD_OLD_INODE_SIZE + in ext2fs_xattrs_read()
1076 inode->i_extra_isize + in ext2fs_xattrs_read()
1079 if (inode->i_extra_isize & 3) { in ext2fs_xattrs_read()
1086 inode->i_extra_isize, sizeof(__u32)); in ext2fs_xattrs_read()
1088 storage_size = EXT2_INODE_SIZE(handle->fs->super) - in ext2fs_xattrs_read()
1089 EXT2_GOOD_OLD_INODE_SIZE - inode->i_extra_isize - in ext2fs_xattrs_read()
1092 inode->i_extra_isize + sizeof(__u32); in ext2fs_xattrs_read()
1100 handle->ibody_count = handle->count; in ext2fs_xattrs_read()
1105 blk = ext2fs_file_acl_block(handle->fs, (struct ext2_inode *)inode); in ext2fs_xattrs_read()
1107 if ((blk < handle->fs->super->s_first_data_block) || in ext2fs_xattrs_read()
1108 (blk >= ext2fs_blocks_count(handle->fs->super))) { in ext2fs_xattrs_read()
1113 err = ext2fs_get_mem(handle->fs->blocksize, &block_buf); in ext2fs_xattrs_read()
1117 err = ext2fs_read_ext_attr3(handle->fs, blk, block_buf, in ext2fs_xattrs_read()
1118 handle->ino); in ext2fs_xattrs_read()
1124 if (header->h_magic != EXT2_EXT_ATTR_MAGIC) { in ext2fs_xattrs_read()
1130 storage_size = handle->fs->blocksize - in ext2fs_xattrs_read()
1163 for (x = h->attrs; x < h->attrs + h->count; x++) { in ext2fs_xattrs_iterate()
1164 ret = func(x->name, x->value, x->value_len, data); in ext2fs_xattrs_iterate()
1184 for (x = h->attrs; x < h->attrs + h->count; x++) { in ext2fs_xattr_get()
1185 if (strcmp(x->name, key)) in ext2fs_xattr_get()
1188 if (!(h->flags & XATTR_HANDLE_FLAG_RAW) && in ext2fs_xattr_get()
1191 err = convert_disk_buffer_to_posix_acl(x->value, x->value_len, in ext2fs_xattr_get()
1195 err = ext2fs_get_mem(x->value_len, &val); in ext2fs_xattr_get()
1198 memcpy(val, x->value, x->value_len); in ext2fs_xattr_get()
1200 *value_len = x->value_len; in ext2fs_xattr_get()
1208 errcode_t ext2fs_xattr_inode_max_size(ext2_filsys fs, ext2_ino_t ino, in ext2fs_xattr_inode_max_size() argument
1219 i = EXT2_INODE_SIZE(fs->super); in ext2fs_xattr_inode_max_size()
1226 err = ext2fs_read_inode_full(fs, ino, (struct ext2_inode *)inode, in ext2fs_xattr_inode_max_size()
1227 EXT2_INODE_SIZE(fs->super)); in ext2fs_xattr_inode_max_size()
1232 if (EXT2_INODE_SIZE(fs->super) <= EXT2_GOOD_OLD_INODE_SIZE + in ext2fs_xattr_inode_max_size()
1233 inode->i_extra_isize + in ext2fs_xattr_inode_max_size()
1239 minoff = EXT2_INODE_SIZE(fs->super) - sizeof(*inode) - sizeof(__u32); in ext2fs_xattr_inode_max_size()
1241 inode->i_extra_isize, sizeof(__u32)); in ext2fs_xattr_inode_max_size()
1245 inode->i_extra_isize + sizeof(__u32); in ext2fs_xattr_inode_max_size()
1248 if (!entry->e_value_inum && entry->e_value_size) { in ext2fs_xattr_inode_max_size()
1249 unsigned int offs = entry->e_value_offs; in ext2fs_xattr_inode_max_size()
1255 *size = minoff - ((char *)entry - (char *)start) - sizeof(__u32); in ext2fs_xattr_inode_max_size()
1258 *size = EXT2_EXT_ATTR_SIZE(minoff - in ext2fs_xattr_inode_max_size()
1259 EXT2_EXT_ATTR_LEN(strlen("data")) - in ext2fs_xattr_inode_max_size()
1260 EXT2_EXT_ATTR_ROUND - sizeof(__u32)); in ext2fs_xattr_inode_max_size()
1268 static errcode_t xattr_create_ea_inode(ext2_filsys fs, const void *value, in xattr_create_ea_inode() argument
1277 ret = ext2fs_new_inode(fs, 0, 0, 0, &ino); in xattr_create_ea_inode()
1283 if (ext2fs_has_feature_extents(fs->super)) in xattr_create_ea_inode()
1288 ret = ext2fs_write_new_inode(fs, ino, &inode); in xattr_create_ea_inode()
1298 hash = ext2fs_crc32c_le(fs->csum_seed, value, value_len); in xattr_create_ea_inode()
1301 ret = ext2fs_write_inode(fs, ino, &inode); in xattr_create_ea_inode()
1305 ret = ext2fs_file_open(fs, ino, EXT2_FILE_WRITE, &file); in xattr_create_ea_inode()
1313 ext2fs_inode_alloc_stats2(fs, ino, 1 /* inuse */, 0 /* isdir */); in xattr_create_ea_inode()
1319 static errcode_t xattr_inode_dec_ref(ext2_filsys fs, ext2_ino_t ino) in xattr_inode_dec_ref() argument
1325 ret = ext2fs_read_inode_full(fs, ino, (struct ext2_inode *)&inode, in xattr_inode_dec_ref()
1331 ref_count--; in xattr_inode_dec_ref()
1338 inode.i_dtime = fs->now ? fs->now : time(0); in xattr_inode_dec_ref()
1340 ret = ext2fs_free_ext_attr(fs, ino, &inode); in xattr_inode_dec_ref()
1344 if (ext2fs_inode_has_valid_blocks2(fs, (struct ext2_inode *)&inode)) { in xattr_inode_dec_ref()
1345 ret = ext2fs_punch(fs, ino, (struct ext2_inode *)&inode, NULL, in xattr_inode_dec_ref()
1351 ext2fs_inode_alloc_stats2(fs, ino, -1 /* inuse */, 0 /* is_dir */); in xattr_inode_dec_ref()
1354 ret = ext2fs_write_inode_full(fs, ino, (struct ext2_inode *)&inode, in xattr_inode_dec_ref()
1360 static errcode_t xattr_update_entry(ext2_filsys fs, struct ext2_xattr *x, in xattr_update_entry() argument
1371 if (!x->name) { in xattr_update_entry()
1385 ret = xattr_create_ea_inode(fs, value, value_len, &ea_ino); in xattr_update_entry()
1390 if (x->ea_ino) { in xattr_update_entry()
1391 ret = xattr_inode_dec_ref(fs, x->ea_ino); in xattr_update_entry()
1396 if (!x->name) { in xattr_update_entry()
1397 x->name = new_name; in xattr_update_entry()
1398 x->short_name = new_name + (short_name - name); in xattr_update_entry()
1400 x->name_index = index; in xattr_update_entry()
1402 if (x->value) in xattr_update_entry()
1403 ext2fs_free_mem(&x->value); in xattr_update_entry()
1404 x->value = new_value; in xattr_update_entry()
1405 x->value_len = value_len; in xattr_update_entry()
1406 x->ea_ino = ea_ino; in xattr_update_entry()
1414 xattr_inode_dec_ref(fs, ea_ino); in xattr_update_entry()
1428 if (name_idx < x->name_index) in xattr_find_position()
1430 if (name_idx > x->name_index) in xattr_find_position()
1433 x_shortname_len = strlen(x->short_name); in xattr_find_position()
1439 if (memcmp(shortname, x->short_name, shortname_len) <= 0) in xattr_find_position()
1466 if (old_idx >= 0 && old_idx < h->ibody_count) { in xattr_array_update()
1468 if (!h->attrs[old_idx].ea_ino) in xattr_array_update()
1470 h->attrs[old_idx].value_len); in xattr_array_update()
1475 new_idx = h->ibody_count; in xattr_array_update()
1481 ret = xattr_update_entry(h->fs, &h->attrs[old_idx], name, in xattr_array_update()
1486 if (h->ibody_count <= old_idx) { in xattr_array_update()
1488 tmp = h->attrs[old_idx]; in xattr_array_update()
1489 memmove(h->attrs + h->ibody_count + 1, in xattr_array_update()
1490 h->attrs + h->ibody_count, in xattr_array_update()
1491 (old_idx - h->ibody_count) * sizeof(*h->attrs)); in xattr_array_update()
1492 h->attrs[h->ibody_count] = tmp; in xattr_array_update()
1493 h->ibody_count++; in xattr_array_update()
1498 if (h->ibody_count <= old_idx) { in xattr_array_update()
1500 if (!h->attrs[old_idx].ea_ino) in xattr_array_update()
1502 EXT2_EXT_ATTR_SIZE(h->attrs[old_idx].value_len); in xattr_array_update()
1510 ret = xattr_update_entry(h->fs, &h->attrs[old_idx], name, in xattr_array_update()
1515 if (old_idx < h->ibody_count) { in xattr_array_update()
1520 new_idx = xattr_find_position(h->attrs + h->ibody_count, in xattr_array_update()
1521 h->count - h->ibody_count, in xattr_array_update()
1523 new_idx += h->ibody_count - 1; in xattr_array_update()
1524 tmp = h->attrs[old_idx]; in xattr_array_update()
1525 memmove(h->attrs + old_idx, h->attrs + old_idx + 1, in xattr_array_update()
1526 (new_idx - old_idx) * sizeof(*h->attrs)); in xattr_array_update()
1527 h->attrs[new_idx] = tmp; in xattr_array_update()
1528 h->ibody_count--; in xattr_array_update()
1533 new_idx = xattr_find_position(h->attrs + h->ibody_count, in xattr_array_update()
1534 h->count - h->ibody_count, in xattr_array_update()
1536 new_idx += h->ibody_count; in xattr_array_update()
1540 if (h->count == h->capacity) { in xattr_array_update()
1546 ret = xattr_update_entry(h->fs, &h->attrs[h->count], name, shortname, in xattr_array_update()
1551 tmp = h->attrs[h->count]; in xattr_array_update()
1552 memmove(h->attrs + new_idx + 1, h->attrs + new_idx, in xattr_array_update()
1553 (h->count - new_idx)*sizeof(*h->attrs)); in xattr_array_update()
1554 h->attrs[new_idx] = tmp; in xattr_array_update()
1556 h->ibody_count++; in xattr_array_update()
1557 h->count++; in xattr_array_update()
1568 len = strlen(x->short_name); in space_used()
1570 if (!x->ea_ino) in space_used()
1571 total += EXT2_EXT_ATTR_SIZE(x->value_len); in space_used()
1578 * size of block - size of header - size of 1 entry - 4 null bytes
1581 ((b) - EXT2_EXT_ATTR_LEN(3) - sizeof(struct ext2_ext_attr_header) - 4)
1588 ext2_filsys fs = h->fs; in ext2fs_xattr_set() local
1589 const int inode_size = EXT2_INODE_SIZE(fs->super); in ext2fs_xattr_set()
1595 int old_idx = -1; in ext2fs_xattr_set()
1604 if (!(h->flags & XATTR_HANDLE_FLAG_RAW) && in ext2fs_xattr_set()
1615 for (x = h->attrs; x < h->attrs + h->count; x++) { in ext2fs_xattr_set()
1616 if (!strcmp(x->name, name)) { in ext2fs_xattr_set()
1617 if (!x->ea_ino && x->value_len == value_len && in ext2fs_xattr_set()
1619 !memcmp(x->value, new_value, value_len))) { in ext2fs_xattr_set()
1623 old_idx = x - h->attrs; in ext2fs_xattr_set()
1631 ret = ext2fs_read_inode_full(fs, h->ino, in ext2fs_xattr_set()
1637 extra_isize = inode->i_extra_isize; in ext2fs_xattr_set()
1639 extra_isize = fs->super->s_want_extra_isize; in ext2fs_xattr_set()
1643 ibody_free = inode_size - EXT2_GOOD_OLD_INODE_SIZE; in ext2fs_xattr_set()
1644 ibody_free -= extra_isize; in ext2fs_xattr_set()
1646 ibody_free -= sizeof(__u32) * 2; in ext2fs_xattr_set()
1647 ibody_free -= space_used(h->attrs, h->ibody_count); in ext2fs_xattr_set()
1653 if (h->ibody_count <= old_idx) { in ext2fs_xattr_set()
1666 block_free = fs->blocksize; in ext2fs_xattr_set()
1667 block_free -= sizeof(struct ext2_ext_attr_header); in ext2fs_xattr_set()
1669 block_free -= sizeof(__u32); in ext2fs_xattr_set()
1670 block_free -= space_used(h->attrs + h->ibody_count, in ext2fs_xattr_set()
1671 h->count - h->ibody_count); in ext2fs_xattr_set()
1673 if (ext2fs_has_feature_ea_inode(fs->super) && in ext2fs_xattr_set()
1674 value_len > EXT4_XATTR_MIN_LARGE_EA_SIZE(fs->blocksize)) in ext2fs_xattr_set()
1680 ext2fs_has_feature_ea_inode(fs->super)) in ext2fs_xattr_set()
1699 struct ext2_xattr *end = handle->attrs + handle->count; in ext2fs_xattr_remove()
1702 for (x = handle->attrs; x < end; x++) { in ext2fs_xattr_remove()
1703 if (strcmp(x->name, key) == 0) { in ext2fs_xattr_remove()
1704 ext2fs_free_mem(&x->name); in ext2fs_xattr_remove()
1705 ext2fs_free_mem(&x->value); in ext2fs_xattr_remove()
1706 if (x->ea_ino) in ext2fs_xattr_remove()
1707 xattr_inode_dec_ref(handle->fs, x->ea_ino); in ext2fs_xattr_remove()
1708 memmove(x, x + 1, (end - x - 1)*sizeof(*x)); in ext2fs_xattr_remove()
1709 memset(end - 1, 0, sizeof(*end)); in ext2fs_xattr_remove()
1710 if (x < handle->attrs + handle->ibody_count) in ext2fs_xattr_remove()
1711 handle->ibody_count--; in ext2fs_xattr_remove()
1712 handle->count--; in ext2fs_xattr_remove()
1721 errcode_t ext2fs_xattrs_open(ext2_filsys fs, ext2_ino_t ino, in ext2fs_xattrs_open() argument
1727 if (!ext2fs_has_feature_xattr(fs->super) && in ext2fs_xattrs_open()
1728 !ext2fs_has_feature_inline_data(fs->super)) in ext2fs_xattrs_open()
1735 h->magic = EXT2_ET_MAGIC_EA_HANDLE; in ext2fs_xattrs_open()
1736 h->capacity = 4; in ext2fs_xattrs_open()
1737 err = ext2fs_get_arrayzero(h->capacity, sizeof(struct ext2_xattr), in ext2fs_xattrs_open()
1738 &h->attrs); in ext2fs_xattrs_open()
1743 h->count = 0; in ext2fs_xattrs_open()
1744 h->ino = ino; in ext2fs_xattrs_open()
1745 h->fs = fs; in ext2fs_xattrs_open()
1756 ext2fs_free_mem(&h->attrs); in ext2fs_xattrs_close()
1764 *count = handle->count; in ext2fs_xattrs_count()
1773 *old_flags = handle->flags; in ext2fs_xattrs_flags()
1775 handle->flags = *new_flags; in ext2fs_xattrs_flags()