ocfs2-tools: Add extended attribute support in mkfs.ocfs2
PATCH 1/2 ocfs2-tools: Add extended attribute support in mkfs.ocfs2
This patch add support for new feature xattr in mkfs.ocfs2.
--- include/ocfs2-kernel/ocfs2_fs.h | 89 ++++++++++++++++++++++++++++++++++---- include/ocfs2/ocfs2.h | 2 + libocfs2/Makefile | 3 +- libocfs2/feature_string.c | 9 ++++- libocfs2/inode.c | 7 +++ libocfs2/xattr.c | 37 ++++++++++++++++ mkfs.ocfs2/mkfs.c | 6 +++ mkfs.ocfs2/mkfs.ocfs2.8.in | 5 ++ sizetest/sizetest.c | 12 +++++- 9 files changed, 157 insertions(+), 13 deletions(-) create mode 100644 libocfs2/xattr.c
include/ocfs2-kernel/ocfs2_fs.h +79 -10
@@ -64,6 +64,7 @@#define OCFS2_INODE_SIGNATURE "INODE01"#define OCFS2_EXTENT_BLOCK_SIGNATURE "EXBLK01"#define OCFS2_GROUP_DESC_SIGNATURE "GROUP01" +#define OCFS2_XATTR_BLOCK_SIGNATURE "XATTR01"/* Compatibility flags */ #define OCFS2_HAS_COMPAT_FEATURE (sb,mask) \
@@ -89,7 +90,8 @@#define OCFS2_FEATURE_INCOMPAT_SUPP (OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT \ | OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC \ | OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP \ - | OCFS2_FEATURE_INCOMPAT_USERSPACE_STACK) + | OCFS2_FEATURE_INCOMPAT_USERSPACE_STACK \ + | OCFS2_FEATURE_INCOMPAT_XATTR)#define OCFS2_FEATURE_RO_COMPAT_SUPP OCFS2_FEATURE_RO_COMPAT_UNWRITTEN/*
@@ -126,10 +128,6 @@/* Support for data packed into inode blocks */ #define OCFS2_FEATURE_INCOMPAT_INLINE_DATA 0x0040 -/* Support for the extended slot map */ -#define OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP 0x100 - -/* * Support for alternate, userspace cluster stacks. If set, the superblock * field s_cluster_info contains a tag for the alternate stack in use as
@@ -141,6 +139,12 @@*/ #define OCFS2_FEATURE_INCOMPAT_USERSPACE_STACK 0x0080 +/* Support for the extended slot map */ +#define OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP 0x100 + +/* Support for extended attributes */ +#define OCFS2_FEATURE_INCOMPAT_XATTR 0x0200 +/* * backup superblock flag is used to indicate that this volume * has backup superblocks.
@@ -554,7 +558,7 @@ struct ocfs2_super_block {/*40*/ __le16 s_max_slots;/* Max number of simultaneous mounts before tunefs required */ __le16 s_tunefs_flag; -__le32 s_reserved1; +__le32 s_uuid_hash;__le64 s_first_cluster_group;/* Block offset of 1st cluster * group header */ /*50*/ __u8 s_label[OCFS2_MAX_VOL_LABEL_LEN ];/* Label for mounting, etc. */
@@ -562,7 +566,11 @@ struct ocfs2_super_block {/*A0*/ struct ocfs2_cluster_info s_cluster_info;/* Selected userspace stack. Only valid with INCOMPAT flag. */ -/*B8*/ __le64 s_reserved2[17 ];/* Fill out superblock */ +/*B8*/ __le16 s_xattr_inline_size;/* extended attribute inline size +for this fs*/ +__le16 s_reserved0; +__le32 s_reserved1; +/*C0*/ __le64 s_reserved2[16 ];/* Fill out superblock */ /*140*/ /*
@@ -612,7 +620,8 @@ struct ocfs2_dinode {belongs to */ __le16 i_suballoc_bit;/* Bit offset in suballocator block group */ -/*10*/ __le32 i_reserved0; +/*10*/ __le16 i_reserved0; +__le16 i_xattr_inline_size;__le32 i_clusters;/* Cluster count */ __le32 i_uid;/* Owner UID */ __le32 i_gid;/* Owning GID */
@@ -631,11 +640,12 @@ struct ocfs2_dinode {__le32 i_atime_nsec;__le32 i_ctime_nsec;__le32 i_mtime_nsec; -__le32 i_attr; +/*70*/ __le32 i_attr;__le16 i_orphaned_slot;/* Only valid when OCFS2_ORPHANED_FL was set in i_flags */ __le16 i_dyn_features; -/*70*/ __le64 i_reserved2[8 ]; +__le64 i_xattr_loc; +/*80*/ __le64 i_reserved2[7 ];/*B8*/ union {__le64 i_pad1;/* Generic way to refer to this 64bit union */
@@ -706,6 +716,65 @@ struct ocfs2_group_desc/*40*/ __u8 bg_bitmap[0 ]; }; +/* +* On disk extended attribute structure for OCFS2 +* Include ocfs2_xattr_entry, ocfs2_xattr_header, ocfs2_xattr_value_root +* ocfs2_xattr_tree_root and ocfs2_xattr_block. +*/ +#define OCFS2_XATTR_INDEXED 0x1 + +#define OCFS2_HASH_SHIFT 5 + +/* Inline extended attribute size (in bytes) */ +#define OCFS2_MIN_XATTR_INLINE_SIZE 256 + +struct ocfs2_xattr_entry { +__le32 xe_name_hash; +__le16 xe_name_offset; +__u8 xe_name_len; +__u8 xe_type :7 ; +__u8 xe_local :1 ; +__le64 xe_value_size; +}; + +struct ocfs2_xattr_header { +__le16 xh_count; +__le16 xh_reserved1; +__le32 xh_csum; +__le64 xh_reserved2; +struct ocfs2_xattr_entry xh_entries[0 ]; +}; + +struct ocfs2_xattr_value_root { +/*00*/ __le32 xr_clusters; +__le32 xr_reserved0; +__le64 xr_last_eb_blk; +/*10*/ struct ocfs2_extent_list xr_list; +}; + +struct ocfs2_xattr_tree_root { +/*00*/ __le32 xt_clusters; +__le32 xt_reserved0; +__le64 xt_last_eb_blk; +/*10*/ struct ocfs2_extent_list xt_list; +}; + +struct ocfs2_xattr_block { +/*00*/ __u8 xb_signature[8 ]; +__le16 xb_suballoc_slot; +__le16 xb_suballoc_bit; +__le32 xb_fs_generation; +/*10*/ __le32 xb_csum; +__le16 xb_flags; +__le16 xb_reserved0; +__le64 xb_blkno; +/*20*/ __le64 xb_reserved1[2 ]; +/*30*/ union { +struct ocfs2_xattr_header xb_header; +struct ocfs2_xattr_tree_root xb_root; + } xb_attrs; +}; +#ifdef __KERNEL__static inline int ocfs2_fast_symlink_chars (struct super_block *sb) {
include/ocfs2/ocfs2.h +2 -0
@@ -941,4 +941,6 @@ errcode_t ocfs2_block_iterate_inode(ocfs2_filesys *fs, void *priv_data), void *priv_data); +uint32_t xattr_uuid_hash (unsigned char *uuid); +#endif /* _FILESYS_H */
libocfs2/Makefile +2 -1
@@ -73,7 +73,8 @@ CFILES = \ lockid.c \ backup_super.c \ feature_string.c\ - image.c + image.c \ + xattr.c HFILES = \ bitmap.h \
libocfs2/feature_string.c +8 -1
@@ -59,7 +59,8 @@ static ocfs2_fs_options feature_level_defaults[] = { {OCFS2_FEATURE_COMPAT_BACKUP_SB ,OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC | -OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP , +OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP | +OCFS2_FEATURE_INCOMPAT_XATTR , OCFS2_FEATURE_RO_COMPAT_UNWRITTEN}, /* OCFS2_FEATURE_LEVEL_MAX_FEATURES */ };
@@ -91,6 +92,12 @@ static struct fs_feature_flags ocfs2_supported_features[] = { {0, OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP, 0}, }, { +"xattr" , + {0, OCFS2_FEATURE_INCOMPAT_XATTR, 0}, + {0, OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC | + OCFS2_FEATURE_INCOMPAT_XATTR, 0}, + }, + {NULL , {0, 0, 0}, {0, 0, 0}
libocfs2/inode.c +7 -0
@@ -127,7 +127,10 @@ static void ocfs2_swap_inode_second(struct ocfs2_dinode *di) sb->s_blocksize_bits =bswap_32 (sb->s_blocksize_bits); sb->s_clustersize_bits =bswap_32 (sb->s_clustersize_bits); sb->s_max_slots =bswap_16 (sb->s_max_slots); + sb->s_tunefs_flag =bswap_16 (sb->s_tunefs_flag); + sb->s_uuid_hash =bswap_32 (sb->s_uuid_hash); sb->s_first_cluster_group =bswap_64 (sb->s_first_cluster_group); + sb->s_xattr_inline_size =bswap_16 (sb->s_xattr_inline_size); }else if (di->i_flags &OCFS2_LOCAL_ALLOC_FL ) {struct ocfs2_local_alloc *la = &di->id2.i_lab;
@@ -156,6 +159,7 @@ static void ocfs2_swap_inode_first(struct ocfs2_dinode *di) di->i_generation =bswap_32 (di->i_generation); di->i_suballoc_slot =bswap_16 (di->i_suballoc_slot); di->i_suballoc_bit =bswap_16 (di->i_suballoc_bit); + di->i_xattr_inline_size =bswap_16 (di->i_xattr_inline_size); di->i_clusters =bswap_32 (di->i_clusters); di->i_uid =bswap_32 (di->i_uid); di->i_gid =bswap_32 (di->i_gid);
@@ -174,6 +178,9 @@ static void ocfs2_swap_inode_first(struct ocfs2_dinode *di) di->i_ctime_nsec =bswap_32 (di->i_ctime_nsec); di->i_mtime_nsec =bswap_32 (di->i_mtime_nsec); di->i_attr =bswap_32 (di->i_attr); + di->i_orphaned_slot =bswap_16 (di->i_orphaned_slot); + di->i_dyn_features =bswap_16 (di->i_dyn_features); + di->i_xattr_loc =bswap_64 (di->i_xattr_loc); }static int has_extents (struct ocfs2_dinode *di)
libocfs2/xattr.c new file +37 -0
@@ -0,0 +1,37 @@ +/* -*- mode: c; c-basic-offset: 8; -*- +* vim: noexpandtab sw=8 ts=8 sts=0: +* +* Copyright (C) 2004 Oracle. All rights reserved. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public +* License, version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public +* License along with this program; if not, write to the +* Free Software Foundation, Inc., 59 Temple Place - Suite 330, +* Boston, MA 021110-1307, USA. +*/ +#include <string.h> +#include <inttypes.h> + +#include "ocfs2/byteorder.h" +#include "ocfs2/ocfs2.h" + +uint32_t xattr_uuid_hash (unsigned char *uuid) +{ +uint32_t i, hash =0 ; + +for (i =0 ; i <OCFS2_VOL_UUID_LEN ; i++) { + hash = (hash <<OCFS2_HASH_SHIFT ) ^ + (hash >> (8 *sizeof (hash) -OCFS2_HASH_SHIFT )) ^ + *uuid++; + } +return hash; +} +
mkfs.ocfs2/mkfs.c +6 -0
@@ -1876,6 +1876,12 @@ format_superblock(State *s, SystemFileDiskRecord *rec,*/ s->feature_flags.opt_compat &= !OCFS2_FEATURE_COMPAT_BACKUP_SB ; +if (s->feature_flags.opt_incompat &OCFS2_FEATURE_INCOMPAT_XATTR ) { + di->id2.i_super.s_xattr_inline_size = +OCFS2_MIN_XATTR_INLINE_SIZE ; + di->id2.i_super.s_uuid_hash =xattr_uuid_hash (s->uuid); + } + di->id2.i_super.s_feature_incompat = s->feature_flags.opt_incompat; di->id2.i_super.s_feature_compat = s->feature_flags.opt_compat; di->id2.i_super.s_feature_ro_compat = s->feature_flags.opt_ro_compat;
mkfs.ocfs2/mkfs.ocfs2.8.in +5 -0
@@ -108,6 +108,11 @@ Enable support for sparse files. With this, \fIOCFS2\fR can avoid allocating (an \fBunwritten\fR Enable unwritten extents support. With this turned on, an application can request that a range of clusters be pre-allocated within a file. \fIOCFS2\fR will mark those extents with a special flag so that expensive data zeroing doesn't have to be performed. Reads and writes to a pre-allocated region act as reads and writes to a hole, except a write will not fail due to lack of data allocation. This feature requires \fBsparse\fR file support to be turned on. Available with the file system bundled with Linux kernels 2.6.23 and later. .RE +.RS 1.2i +.TP +\fBxattr\fR +Enable support for extended attribute. +.RE .TP \fB\-\-fs\-feature\-level=\fR\fR\fIfeature\-level\fR
sizetest/sizetest.c +11 -1
@@ -137,10 +137,15 @@ static void print_ocfs2_super_block(void) SHOW_OFFSET(struct ocfs2_super_block, s_clustersize_bits); SHOW_OFFSET(struct ocfs2_super_block, s_max_slots); SHOW_OFFSET(struct ocfs2_super_block, s_tunefs_flag); - SHOW_OFFSET(struct ocfs2_super_block, s_reserved1); + SHOW_OFFSET(struct ocfs2_super_block, s_uuid_hash); SHOW_OFFSET(struct ocfs2_super_block, s_first_cluster_group); SHOW_OFFSET(struct ocfs2_super_block, s_label); SHOW_OFFSET(struct ocfs2_super_block, s_uuid); + SHOW_OFFSET(struct ocfs2_super_block, s_cluster_info); + SHOW_OFFSET(struct ocfs2_super_block, s_xattr_inline_size); + SHOW_OFFSET(struct ocfs2_super_block, s_reserved0); + SHOW_OFFSET(struct ocfs2_super_block, s_reserved1); + SHOW_OFFSET(struct ocfs2_super_block, s_reserved2);END_TYPE (struct ocfs2_super_block );printf ("\n" );
@@ -169,6 +174,7 @@ static void print_ocfs2_dinode(void) SHOW_OFFSET(struct ocfs2_dinode, i_suballoc_slot); SHOW_OFFSET(struct ocfs2_dinode, i_suballoc_bit); SHOW_OFFSET(struct ocfs2_dinode, i_reserved0); + SHOW_OFFSET(struct ocfs2_dinode, i_xattr_inline_size); SHOW_OFFSET(struct ocfs2_dinode, i_clusters); SHOW_OFFSET(struct ocfs2_dinode, i_uid); SHOW_OFFSET(struct ocfs2_dinode, i_gid);
@@ -187,7 +193,9 @@ static void print_ocfs2_dinode(void) SHOW_OFFSET(struct ocfs2_dinode, i_ctime_nsec); SHOW_OFFSET(struct ocfs2_dinode, i_mtime_nsec); SHOW_OFFSET(struct ocfs2_dinode, i_attr); + SHOW_OFFSET(struct ocfs2_dinode, i_orphaned_slot); SHOW_OFFSET(struct ocfs2_dinode, i_dyn_features); + SHOW_OFFSET(struct ocfs2_dinode, i_xattr_loc); SHOW_OFFSET(struct ocfs2_dinode, i_reserved2); SHOW_OFFSET(struct ocfs2_dinode, id1.i_pad1);
@@ -201,6 +209,8 @@ static void print_ocfs2_dinode(void) SHOW_OFFSET(struct ocfs2_dinode, id2.i_lab); SHOW_OFFSET(struct ocfs2_dinode, id2.i_chain); SHOW_OFFSET(struct ocfs2_dinode, id2.i_list); + SHOW_OFFSET(struct ocfs2_dinode, id2.i_dealloc); + SHOW_OFFSET(struct ocfs2_dinode, id2.i_data); SHOW_OFFSET(struct ocfs2_dinode, id2.i_symlink);END_TYPE (struct ocfs2_dinode );
Signature · 1 line
1.5.4.4
PATCH 2/2 ocfs2-tools: Add extended attribute support in fsck.ocfs2
This patch will check all extended attribute associated with each inode, mark all xattr block as used.
--- fsck.ocfs2/Makefile | 3 +- fsck.ocfs2/extent.c | 17 +-- fsck.ocfs2/include/extent.h | 13 ++ fsck.ocfs2/include/xattr.h | 29 +++ fsck.ocfs2/pass1.c | 18 ++- fsck.ocfs2/xattr.c | 420 +++++++++++++++++++++++++++++++++++++++ include/ocfs2-kernel/ocfs2_fs.h | 7 + include/ocfs2/ocfs2.h | 6 + libocfs2/extend_file.c | 4 +- libocfs2/extent_map.c | 2 +- libocfs2/ocfs2_err.et | 3 + libocfs2/xattr.c | 110 ++++++++++ 12 files changed, 609 insertions(+), 23 deletions(-) create mode 100644 fsck.ocfs2/include/xattr.h create mode 100644 fsck.ocfs2/xattr.c
fsck.ocfs2/Makefile +2 -1
@@ -30,7 +30,8 @@ CFILES = fsck.c \ pass4.c \ problem.c \ strings.c \ - util.c + util.c \ + xattr.c HFILES = include/fsck.h \ include/dirblocks.h \
fsck.ocfs2/extent.c +2 -15
@@ -46,19 +46,6 @@static const char *whoami ="extent.c" ; -struct extent_info { -uint64_t ei_max_size; -uint64_t ei_clusters; -uint64_t ei_last_eb_blk; -uint16_t ei_expected_depth; -unsigned ei_expect_depth:1 ; -}; - -static errcode_t check_el (o2fsck_state *ost,struct extent_info *ei, -struct ocfs2_dinode *di, -struct ocfs2_extent_list *el, -uint16_t max_recs,int *changed); -static errcode_t check_eb (o2fsck_state *ost,struct extent_info *ei,struct ocfs2_dinode *di,uint64_t blkno,int *is_valid)
@@ -233,7 +220,7 @@ out:return ret; } -static errcode_t check_el (o2fsck_state *ost,struct extent_info *ei, +errcode_t check_el (o2fsck_state *ost,struct extent_info *ei,struct ocfs2_dinode *di,struct ocfs2_extent_list *el,uint16_t max_recs,int *changed)
@@ -373,4 +360,4 @@ errcode_t o2fsck_check_extents(o2fsck_state *ost,o2fsck_write_inode (ost, di->i_blkno, di);return ret; -} +}
fsck.ocfs2/include/extent.h +13 -0
@@ -22,8 +22,21 @@#include "fsck.h" +struct extent_info { +uint64_t ei_max_size; +uint64_t ei_clusters; +uint64_t ei_last_eb_blk; +uint16_t ei_expected_depth; +unsigned ei_expect_depth:1 ; +}; +errcode_t o2fsck_check_extents (o2fsck_state *ost,struct ocfs2_dinode *di); +errcode_t check_el (o2fsck_state *ost,struct extent_info *ei, +struct ocfs2_dinode *di, +struct ocfs2_extent_list *el, +uint16_t max_recs,int *changed); +#endif /* __O2FSCK_EXTENT_H__ */
fsck.ocfs2/include/xattr.h new file +29 -0
@@ -0,0 +1,29 @@ +/* +* Copyright (C) 2002 Oracle Corporation. All rights reserved. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public +* License along with this program; if not, write to the +* Free Software Foundation, Inc., 59 Temple Place - Suite 330, +* Boston, MA 021110-1307, USA. +*/ + +#ifndef __O2FSCK_XATTR_H__ +#define __O2FSCK_XATTR_H__ + +#include "fsck.h" + +errcode_t o2fsck_check_xattr (o2fsck_state *ost, +struct ocfs2_dinode *di); + +#endif /* __O2FSCK_XATTR_H__ */ +
fsck.ocfs2/pass1.c +14 -4
@@ -59,6 +59,7 @@#include "dirblocks.h" #include "dirparents.h" +#include "xattr.h" #include "extent.h" #include "icount.h" #include "fsck.h"
@@ -758,13 +759,22 @@ static errcode_t o2fsck_check_blocks(ocfs2_filesys *fs, o2fsck_state *ost, .vb_di = di, }; +if (di->i_flags & (OCFS2_SUPER_BLOCK_FL |OCFS2_LOCAL_ALLOC_FL | +OCFS2_BITMAP_FL |OCFS2_CHAIN_FL | +OCFS2_DEALLOC_FL )) +return 0 ; + + ret =o2fsck_check_xattr (ost, di); +if (ret) { +com_err (whoami, ret,"while iterating over the xattr blocks " +"for inode %" PRIu64, di->i_blkno); + goto out; + } +/* don't bother to verify for inodes that don't have i_list, * we have to trust i_mode/i_clusters to tell us that a symlink * has put target data in the union instead of i_list */ -if ((di->i_flags & (OCFS2_SUPER_BLOCK_FL |OCFS2_LOCAL_ALLOC_FL | -OCFS2_BITMAP_FL |OCFS2_CHAIN_FL | -OCFS2_DEALLOC_FL )) || - (S_ISLNK (di->i_mode) && di->i_clusters ==0 )) +if (S_ISLNK (di->i_mode) && di->i_clusters ==0 )return 0 ; ret =o2fsck_check_extents (ost, di);
fsck.ocfs2/xattr.c new file +420 -0
420 lines not on this page · raw message
include/ocfs2-kernel/ocfs2_fs.h +7 -0
@@ -728,6 +728,13 @@ struct ocfs2_group_desc/* Inline extended attribute size (in bytes) */ #define OCFS2_MIN_XATTR_INLINE_SIZE 256 +#define OCFS2_XATTR_BUCKET_SIZE 4096 + +#define OCFS2_XATTR_ROUND 3 + +#define OCFS2_XATTR_SIZE (size) (((size) + OCFS2_XATTR_ROUND) & \ + ~(OCFS2_XATTR_ROUND)) +struct ocfs2_xattr_entry {__le32 xe_name_hash;__le16 xe_name_offset;
include/ocfs2/ocfs2.h +6 -0
@@ -291,6 +291,7 @@ errcode_t ocfs2_get_clusters(ocfs2_cached_inode *cinode,uint32_t *num_clusters, uint16_t *extent_flags);int ocfs2_find_leaf (ocfs2_filesys *fs,struct ocfs2_dinode *di, +struct ocfs2_extent_list *el,uint32_t cpos,char **leaf_buf);int ocfs2_search_extent_list (struct ocfs2_extent_list *el,uint32_t v_cluster);void ocfs2_swap_journal_superblock (journal_superblock_t *jsb);
@@ -942,5 +943,10 @@ errcode_t ocfs2_block_iterate_inode(ocfs2_filesys *fs, void *priv_data);uint32_t xattr_uuid_hash (unsigned char *uuid); +void ocfs2_swap_xattr_entries_to_cpu (struct ocfs2_xattr_header *xh); +void ocfs2_swap_xattr_entries_from_cpu (struct ocfs2_xattr_header *xh); +void ocfs2_swap_xattr_header (struct ocfs2_xattr_header *xh); +void ocfs2_swap_xattr_block_from_cpu (struct ocfs2_xattr_block *xb); +void ocfs2_swap_xattr_block_to_cpu (struct ocfs2_xattr_block *xb);#endif /* _FILESYS_H */
libocfs2/extend_file.c +2 -2
@@ -997,16 +997,16 @@ static int ocfs2_find_path(ocfs2_filesys *fs, struct ocfs2_path *path,* This function doesn't handle non btree extent lists. */ int ocfs2_find_leaf (ocfs2_filesys *fs,struct ocfs2_dinode *di, +struct ocfs2_extent_list *el,uint32_t cpos,char **leaf_buf) {int ret;char *buf =NULL ;struct ocfs2_path *path =NULL ; -struct ocfs2_extent_list *el = &di->id2.i_list;assert (el->l_tree_depth >0 ); - path =ocfs2_new_inode_path (fs, di); + path =ocfs2_new_path (fs, (char *)di, el);if (!path) { ret =OCFS2_ET_NO_MEMORY ; goto out;
libocfs2/extent_map.c +1 -1
@@ -147,7 +147,7 @@ errcode_t ocfs2_get_clusters(ocfs2_cached_inode *cinode, el = &di->id2.i_list;if (el->l_tree_depth) { - ret =ocfs2_find_leaf (fs, di, v_cluster, &eb_buf); + ret =ocfs2_find_leaf (fs, di, el, v_cluster, &eb_buf);if (ret) goto out;
libocfs2/ocfs2_err.et +3 -0
@@ -171,4 +171,7 @@ ec OCFS2_ET_NO_BACKUP_SUPER, ec OCFS2_ET_TOO_MANY_SLOTS, "Too many slots for slot map" +ec OCFS2_ET_BAD_XATTR_BLOCK_MAGIC, + "Bad magic number in xattr block" + end
libocfs2/xattr.c +110 -0
113 lines not on this page · raw message
Signature · 1 line
1.5.4.4
PATCH 2/2 ocfs2-tools: Add extended attribute support in fsck.ocfs2
Quoted 13 lines · Tiger Yang
fsck.ocfs2/xattr.c new file +13
-0+#include <string.h> +#include <inttypes.h> + +#include "ocfs2/byteorder.h" +#include "ocfs2/ocfs2.h" + +#include "xattr.h" +#include "extent.h" +#include "fsck.h" +#include "problem.h" +#include "util.h" + +static const char *whoami ="xattr.c" ;
fsck.ocfs2/xattr.c line 42
Quoted 10 lines
fsck.ocfs2/xattr.c new file +10
-0+ +static inline int ocfs2_xattr_extent_recs_per_inode (int blocksize) +{ +int size; + + size = blocksize - offsetof(struct ocfs2_xattr_block , + xb_attrs.xb_root.xt_list.l_recs); + +return (size /sizeof (struct ocfs2_extent_rec )); +}
I remember with 512, there is no xattr in inode.
Quoted 66 lines
fsck.ocfs2/xattr.c new file +66
-0+ +static inline uint16_t ocfs2_xattr_buckets_per_cluster (ocfs2_filesys *fs) +{ +return (fs->fs_clustersize /OCFS2_XATTR_BUCKET_SIZE ); +} + +static inline uint16_t ocfs2_blocks_per_xattr_bucket (ocfs2_filesys *fs) +{ +return (OCFS2_XATTR_BUCKET_SIZE / fs->fs_blocksize); +} + +static errcode_t check_xattr (o2fsck_state *ost, +struct ocfs2_dinode *di, +struct ocfs2_xattr_header *xh, +int *changed) +{ +struct extent_info ei = {0 , }; +int i; +errcode_t ret =0 ; + +for (i =0 ; i < xh->xh_count; i++) { +int change =0 ; +struct ocfs2_xattr_entry *xe = &xh->xh_entries[i]; + +if (!xe->xe_local) { +struct ocfs2_xattr_value_root *xv = + (struct ocfs2_xattr_value_root *) + ((void *)xh + xe->xe_name_offset + +OCFS2_XATTR_SIZE (xe->xe_name_len)); +struct ocfs2_extent_list *el = &xv->xr_list; + ret =check_el (ost, &ei, di, el,1 , &change); +if (ret) +break ; +if (change) { + *changed =1 ; +ocfs2_swap_extent_list_from_cpu (el); + } + } + } + +return ret; +} + +static errcode_t ocfs2_xattr_get_rec (o2fsck_state *ost, +struct ocfs2_dinode *di, +uint32_t name_hash, +uint64_t *p_blkno, +uint32_t *e_cpos, +uint32_t *num_clusters, +struct ocfs2_extent_list *el) +{ +int i; +errcode_t ret =0 ; +char *eb_buf =NULL ; +struct ocfs2_extent_block *eb; +struct ocfs2_extent_rec *rec =NULL ; +uint64_t e_blkno =0 ; + +if (el->l_tree_depth) { + ret =ocfs2_find_leaf (ost->ost_fs, di, el, name_hash, &eb_buf); +if (ret) { +com_err (whoami, ret,"while finding leaf of xattr " +"tree" ); + goto out; + } +
fsck.ocfs2/xattr.c line 195
Quoted 10 lines
fsck.ocfs2/xattr.c new file +10
-0+ eb = (struct ocfs2_extent_block *) eb_buf; + el = &eb->h_list; + +if (el->l_tree_depth) { + ret =-1 ; + goto out; + } + } + +for (i =le16_to_cpu (el->l_next_free_rec) -1 ; i >=0 ; i--) {
no le16_to_cpu in tools. there are also some below, please remove them.
Quoted 39 lines
fsck.ocfs2/xattr.c new file +39
-0+ rec = &el->l_recs[i]; + +if (le32_to_cpu (rec->e_cpos) <= name_hash) { + e_blkno =le64_to_cpu (rec->e_blkno); +break ; + } + } + +if (!e_blkno) { + ret =-1 ; + goto out; + } + + *p_blkno =le64_to_cpu (rec->e_blkno); + *num_clusters =le16_to_cpu (rec->e_leaf_clusters); +if (e_cpos) + *e_cpos =le32_to_cpu (rec->e_cpos); +out: +if (eb_buf) +ocfs2_free (&eb_buf); +return ret; +} + +static errcode_t ocfs2_iterate_xattr_buckets (o2fsck_state *ost, +struct ocfs2_dinode *di, +uint64_t blkno, +uint32_t clusters) +{ +int i; +errcode_t ret =0 ; +char *bucket =NULL ; +struct ocfs2_xattr_header *xh; +int block_num =ocfs2_blocks_per_xattr_bucket (ost->ost_fs); +uint32_t bpc =ocfs2_xattr_buckets_per_cluster (ost->ost_fs); +uint32_t bucket_num = clusters * bpc; +char *bhs =NULL ; + + + ret =ocfs2_malloc_blocks (ost->ost_fs->fs_io, block_num, &bhs);
fsck.ocfs2/xattr.c line 244
Quoted 10 lines
fsck.ocfs2/xattr.c new file +10
-0+if (ret) { +com_err (whoami, ret,"while allocating room to read bucket " +"of xattr data" ); + goto out; + } + +for (i =0 ; i < bucket_num; i++, blkno += block_num) { +int changed =0 ; + + ret =io_read_block (ost->ost_fs->fs_io, blkno, block_num, bhs);
bucket size isn't block size. So you can't just read and handle the first block for a bucket. the same for the write.
Quoted 157 lines
fsck.ocfs2/xattr.c new file +157
-0+if (ret) { +com_err (whoami, ret,"while reading blocks of xattr " +"bucket" ); + goto out; + } + + bucket = bhs; + + xh = (struct ocfs2_xattr_header *)bucket; +ocfs2_swap_xattr_header (xh); +ocfs2_swap_xattr_entries_to_cpu (xh); +/* +* The real bucket num in this series of blocks is stored +* in the 1st bucket. +*/ +if (i ==0 ) + bucket_num =le16_to_cpu (xh->xh_reserved1); + + ret =check_xattr (ost, di, xh, &changed); +if (ret) +break ; +if (changed) { +ocfs2_swap_xattr_entries_from_cpu (xh); +ocfs2_swap_xattr_header (xh); +io_write_block (ost->ost_fs->fs_io, blkno, block_num, + bhs); + } + } +out: +ocfs2_free (&bhs); + +return ret; +} + +static errcode_t o2fsck_check_xattr_index_block ( +o2fsck_state *ost, +struct ocfs2_dinode *di, +struct ocfs2_xattr_tree_root *xt, +int *changed) +{ +struct ocfs2_extent_list *el = &xt->xt_list; +errcode_t ret =0 ; +uint32_t name_hash =UINT_MAX , e_cpos =0 , num_clusters =0 ; +uint64_t p_blkno =0 ; +struct extent_info ei = {0 , }; + +if (el->l_next_free_rec ==0 ) +return 0 ; + + ret =check_el (ost, &ei, di, el, +ocfs2_xattr_extent_recs_per_inode (ost->ost_fs->fs_blocksize), + changed); +if (ret) +return ret; + +while (name_hash >0 ) { + ret =ocfs2_xattr_get_rec (ost, di, name_hash, &p_blkno, + &e_cpos, &num_clusters, el); +if (ret) { +com_err (whoami, ret,"while getting bucket record " +"of xattr data." ); + goto out; + } + + ret =ocfs2_iterate_xattr_buckets (ost, di, p_blkno, + num_clusters); +if (ret) { +com_err (whoami, ret,"while iterating buckets " +"of xattr data." ); + goto out; + } + +if (e_cpos ==0 ) +break ; + + name_hash = e_cpos -1 ; + } +if (*changed) +ocfs2_swap_extent_list_from_cpu (el); + +out: +return ret; +} + +static errcode_t o2fsck_check_xattr_ibody (o2fsck_state *ost, +struct ocfs2_dinode *di) +{ +errcode_t ret; +struct ocfs2_xattr_header *xh =NULL ; +int changed =0 ; + + xh = (struct ocfs2_xattr_header *) + ((void *)di + ost->ost_fs->fs_blocksize - + di->i_xattr_inline_size); + +ocfs2_swap_xattr_header (xh); +ocfs2_swap_xattr_entries_to_cpu (xh); + + ret =check_xattr (ost, di, xh, &changed); + +if (changed) { +ocfs2_swap_xattr_entries_from_cpu (xh); +ocfs2_swap_xattr_header (xh); +o2fsck_write_inode (ost, di->i_blkno, di); + } +return ret; +} + +static errcode_t o2fsck_check_xattr_block (o2fsck_state *ost, +struct ocfs2_dinode *di) +{ +errcode_t ret; +char *blk =NULL ; +struct ocfs2_xattr_block *xb =NULL ; +int changed =0 ; + +o2fsck_mark_cluster_allocated (ost, +ocfs2_blocks_to_clusters (ost->ost_fs, di->i_xattr_loc)); + + ret =ocfs2_malloc_block (ost->ost_fs->fs_io, &blk); +if (ret) { +com_err (whoami, ret,"while allocating room to read block " +"of xattr." ); +return ret; + } + + ret =ocfs2_read_xattr_block (ost->ost_fs, di->i_xattr_loc, blk); +if (ret) { +com_err (whoami, ret,"while reading externel block of xattr." ); +return ret; + } + + xb = (struct ocfs2_xattr_block *)blk; + +if (!(xb->xb_flags &OCFS2_XATTR_INDEXED )) { +struct ocfs2_xattr_header *xh = &xb->xb_attrs.xb_header; + + ret =check_xattr (ost, di, xh, &changed); + }else { +struct ocfs2_xattr_tree_root *xt = &xb->xb_attrs.xb_root; + + ret =o2fsck_check_xattr_index_block (ost, di, xt, &changed); + } + +if (changed) +ocfs2_write_xattr_block (ost->ost_fs, di->i_xattr_loc, blk); + +if (blk) +ocfs2_free (&blk); + +return ret; +} + +/* +* o2fsck_check_xattr +* +* Check extended attribute in inode block or external block.
fsck.ocfs2/xattr.c line 411
Quoted 10 lines
fsck.ocfs2/xattr.c new file +10
-0+*/ +errcode_t o2fsck_check_xattr (o2fsck_state *ost, +struct ocfs2_dinode *di) +{ +errcode_t ret =0 ; + +if (!(di->i_dyn_features &OCFS2_HAS_XATTR_FL )) +return 0 ; + +if (di->i_dyn_features &OCFS2_HAS_XATTR_FL ) {
you mean inline_xattr here?
Quoted 182 lines
fsck.ocfs2/xattr.c new file +9
-0+ ret =o2fsck_check_xattr_ibody (ost, di); +if (ret) +return ret; + } +if (di->i_xattr_loc) + ret =o2fsck_check_xattr_block (ost, di); + +return ret; +}include/ocfs2-kernel/ocfs2_fs.h +7
-0@@ -728,6 +728,13 @@ struct ocfs2_group_desc/* Inline extended attribute size (in bytes) */ #define OCFS2_MIN_XATTR_INLINE_SIZE 256 +#define OCFS2_XATTR_BUCKET_SIZE 4096 + +#define OCFS2_XATTR_ROUND 3 + +#define OCFS2_XATTR_SIZE (size) (((size) + OCFS2_XATTR_ROUND) & \ + ~(OCFS2_XATTR_ROUND)) +struct ocfs2_xattr_entry {__le32 xe_name_hash;__le16 xe_name_offset;include/ocfs2/ocfs2.h +6
-0@@ -291,6 +291,7 @@ errcode_t ocfs2_get_clusters(ocfs2_cached_inode *cinode,uint32_t *num_clusters, uint16_t *extent_flags);int ocfs2_find_leaf (ocfs2_filesys *fs,struct ocfs2_dinode *di, +struct ocfs2_extent_list *el,uint32_t cpos,char **leaf_buf);int ocfs2_search_extent_list (struct ocfs2_extent_list *el,uint32_t v_cluster);void ocfs2_swap_journal_superblock (journal_superblock_t *jsb);@@ -942,5 +943,10 @@ errcode_t ocfs2_block_iterate_inode(ocfs2_filesys *fs, void *priv_data);uint32_t xattr_uuid_hash (unsigned char *uuid); +void ocfs2_swap_xattr_entries_to_cpu (struct ocfs2_xattr_header *xh); +void ocfs2_swap_xattr_entries_from_cpu (struct ocfs2_xattr_header *xh); +void ocfs2_swap_xattr_header (struct ocfs2_xattr_header *xh); +void ocfs2_swap_xattr_block_from_cpu (struct ocfs2_xattr_block *xb); +void ocfs2_swap_xattr_block_to_cpu (struct ocfs2_xattr_block *xb);#endif /* _FILESYS_H */ libocfs2/extend_file.c +2
-2@@ -997,16 +997,16 @@ static int ocfs2_find_path(ocfs2_filesys *fs, struct ocfs2_path *path,* This function doesn't handle non btree extent lists. */ int ocfs2_find_leaf (ocfs2_filesys *fs,struct ocfs2_dinode *di, +struct ocfs2_extent_list *el,uint32_t cpos,char **leaf_buf) {int ret;char *buf =NULL ;struct ocfs2_path *path =NULL ; -struct ocfs2_extent_list *el = &di->id2.i_list;assert (el->l_tree_depth >0 ); - path =ocfs2_new_inode_path (fs, di); + path =ocfs2_new_path (fs, (char *)di, el);if (!path) { ret =OCFS2_ET_NO_MEMORY ; goto out;libocfs2/extent_map.c +1
-1@@ -147,7 +147,7 @@ errcode_t ocfs2_get_clusters(ocfs2_cached_inode *cinode, el = &di->id2.i_list;if (el->l_tree_depth) { - ret =ocfs2_find_leaf (fs, di, v_cluster, &eb_buf); + ret =ocfs2_find_leaf (fs, di, el, v_cluster, &eb_buf);if (ret) goto out;libocfs2/ocfs2_err.et +3
-0@@ -171,4 +171,7 @@ ec OCFS2_ET_NO_BACKUP_SUPER, ec OCFS2_ET_TOO_MANY_SLOTS, "Too many slots for slot map" +ec OCFS2_ET_BAD_XATTR_BLOCK_MAGIC, + "Bad magic number in xattr block" + endlibocfs2/xattr.c +76
-0@@ -35,3 +35,113 @@ uint32_t xattr_uuid_hash(unsigned char *uuid)return hash; } +static void ocfs2_swap_xattr_tree_root (struct ocfs2_xattr_tree_root *xt) +{ + xt->xt_clusters =bswap_16 (xt->xt_clusters); + xt->xt_last_eb_blk =bswap_16 (xt->xt_last_eb_blk); +} + +static void ocfs2_swap_xattr_value_root (struct ocfs2_xattr_value_root *xr) +{ + xr->xr_clusters =bswap_16 (xr->xr_clusters); + xr->xr_last_eb_blk =bswap_16 (xr->xr_last_eb_blk); +} + +static void ocfs2_swap_xattr_block_header (struct ocfs2_xattr_block *xb) +{ + xb->xb_suballoc_slot =bswap_16 (xb->xb_suballoc_slot); + xb->xb_suballoc_bit =bswap_16 (xb->xb_suballoc_bit); + xb->xb_fs_generation =bswap_32 (xb->xb_fs_generation); + xb->xb_csum =bswap_32 (xb->xb_csum); + xb->xb_flags =bswap_16 (xb->xb_flags); + xb->xb_blkno =bswap_64 (xb->xb_blkno); +} + +void ocfs2_swap_xattr_entries_to_cpu (struct ocfs2_xattr_header *xh) +{ +uint16_t i; + +if (cpu_is_little_endian) +return ; + +for (i =0 ; i < xh->xh_count; i++) { +struct ocfs2_xattr_entry *xe = &xh->xh_entries[i]; + + xe->xe_name_offset =bswap_16 (xe->xe_name_offset); + xe->xe_value_size =bswap_64 (xe->xe_value_size); + +if (!xe->xe_local) { +struct ocfs2_xattr_value_root *xr = + (struct ocfs2_xattr_value_root *) + ((char *)xh + xe->xe_name_offset + +OCFS2_XATTR_SIZE (xe->xe_name_len)); + +ocfs2_swap_xattr_value_root (xr); +ocfs2_swap_extent_list_to_cpu (&xr->xr_list); + } + } +} + +void ocfs2_swap_xattr_entries_from_cpu (struct ocfs2_xattr_header *xh) +{ +uint16_t i; + +if (cpu_is_little_endian) +return ; + +for (i =0 ; i < xh->xh_count; i++) { +struct ocfs2_xattr_entry *xe = &xh->xh_entries[i]; + +if (!xe->xe_local) { +struct ocfs2_xattr_value_root *xr = + (struct ocfs2_xattr_value_root *) + ((char *)xh + xe->xe_name_offset + +OCFS2_XATTR_SIZE (xe->xe_name_len)); + +ocfs2_swap_xattr_value_root (xr); + } + xe->xe_name_offset =bswap_16 (xe->xe_name_offset); + xe->xe_value_size =bswap_64 (xe->xe_value_size); + } +} + +void ocfs2_swap_xattr_header (struct ocfs2_xattr_header *xh) +{ +if (cpu_is_little_endian) +return ; + + xh->xh_count =bswap_16 (xh->xh_count);
libocfs2/xattr.c uint32_t xattr_uuid_hash(unsigned char *uuid) · line 123
Quoted 10 lines
libocfs2/xattr.c +10
-0+ xh->xh_reserved1 =bswap_16 (xh->xh_reserved1); + xh->xh_csum =bswap_32 (xh->xh_csum); +} + +void ocfs2_swap_xattr_block_from_cpu (struct ocfs2_xattr_block *xb) +{ +if (cpu_is_little_endian) +return ; + +if (!(xb->xb_flags &OCFS2_XATTR_INDEXED )) {
you should handle xb_flags swap first.
Quoted 24 lines
libocfs2/xattr.c +24
-0+ocfs2_swap_xattr_entries_from_cpu (&xb->xb_attrs.xb_header); +ocfs2_swap_xattr_header (&xb->xb_attrs.xb_header); + }else { +ocfs2_swap_xattr_tree_root (&xb->xb_attrs.xb_root); + } + +ocfs2_swap_xattr_block_header (xb); +} + +void ocfs2_swap_xattr_block_to_cpu (struct ocfs2_xattr_block *xb) +{ +if (cpu_is_little_endian) +return ; + +ocfs2_swap_xattr_block_header (xb); +if (!(xb->xb_flags &OCFS2_XATTR_INDEXED )) { +ocfs2_swap_xattr_header (&xb->xb_attrs.xb_header); +ocfs2_swap_xattr_entries_to_cpu (&xb->xb_attrs.xb_header); + }else { +ocfs2_swap_xattr_tree_root (&xb->xb_attrs.xb_root); +ocfs2_swap_extent_list_to_cpu (&xb->xb_attrs.xb_root.xt_list); + } +} +
PATCH 2/2 ocfs2-tools: Add extended attribute support in fsck.ocfs2
Quoted 10 lines · Tao Ma
fsck.ocfs2/xattr.c line 42
Quoted 9 lines
fsck.ocfs2/xattr.c new file +9
-0+static inline int ocfs2_xattr_extent_recs_per_inode (int blocksize) +{ +int size; + + size = blocksize - offsetof(struct ocfs2_xattr_block , + xb_attrs.xb_root.xt_list.l_recs); + +return (size /sizeof (struct ocfs2_extent_rec )); +}I remember with 512, there is no xattr in inode.
This function only used in index block, it's not for inode block.
Quoted 2 lines
Quoted 1 line
+ for (i =
le16_to_cpu(el->l_next_free_rec)- 1; i >= 0; i--) {no
le16_to_cpuin tools. there are also some below, please remove them.
ok.
Quoted 3 lines
Quoted 1 line
+ ret =
io_read_block(ost->ost_fs->fs_io, blkno, block_num, bhs);bucket size isn't block size. So you can't just read and handle the first block for a bucket. the same for the write.
So I read block_num blocks not first block.
Quoted 2 lines
Quoted 1 line
+ if (
di->i_dyn_features&OCFS2_HAS_XATTR_FL) {you mean
inline_xattrhere?
my fault. I mean OCFS2_INLINE_XATTR_FL.
Quoted 2 lines
Quoted 1 line
+ if (!(xb->xb_flags &
OCFS2_XATTR_INDEXED)) {you should handle
xb_flagsswap first.
ok.
Thanks for review.
tiger
PATCH 2/2 ocfs2-tools: Add extended attribute support in fsck.ocfs2
Quoted 14 lines · Tiger Yang
Quoted 10 lines · Tao Ma
fsck.ocfs2/xattr.c line 42
Quoted 9 lines
fsck.ocfs2/xattr.c new file +9
-0+static inline int ocfs2_xattr_extent_recs_per_inode (int blocksize) +{ +int size; + + size = blocksize - offsetof(struct ocfs2_xattr_block , + xb_attrs.xb_root.xt_list.l_recs); + +return (size /sizeof (struct ocfs2_extent_rec )); +}I remember with 512, there is no xattr in inode.
Quoted 1 line
This function only used in index block, it's not for inode block.
So could you please rename it as it isn't concerned with inode?
btw, next time please send your patch to ocfs2-tools-devel since it is tools' patches.
Regards,
Tao
PATCH 1/2 ocfs2-tools: Add extended attribute support in mkfs.ocfs2
In reply to Tiger Yanginclude/ocfs2-kernel/ocfs2_fs.h
Quoted 4 lines · Tiger Yang
include/ocfs2-kernel/ocfs2_fs.h +0
-0
You've got an ancient version of the xattr ocfs2_fs.h here.
include/ocfs2-kernel/ocfs2_fs.h struct ocfs2_group_desc · line 738
Quoted 8 lines
include/ocfs2-kernel/ocfs2_fs.h +8
-0+struct ocfs2_xattr_entry { +__le32 xe_name_hash; +__le16 xe_name_offset; +__u8 xe_name_len; +__u8 xe_type :7 ; +__u8 xe_local :1 ; +__le64 xe_value_size; +};
We removed the bitfields.
Quoted 5 lines
include/ocfs2-kernel/ocfs2_fs.h +5
-0+struct ocfs2_xattr_block { +/*00*/ __u8 xb_signature[8 ]; +__le16 xb_suballoc_slot; +__le16 xb_suballoc_bit; +__le32 xb_fs_generation;
include/ocfs2-kernel/ocfs2_fs.h struct ocfs2_group_desc · line 776
Quoted 10 lines
include/ocfs2-kernel/ocfs2_fs.h +10
-0+/*10*/ __le32 xb_csum; +__le16 xb_flags; +__le16 xb_reserved0; +__le64 xb_blkno; +/*20*/ __le64 xb_reserved1[2 ]; +/*30*/ union { +struct ocfs2_xattr_header xb_header; +struct ocfs2_xattr_tree_root xb_root; + } xb_attrs; +};
This got shuffled around for a 64bit checksum field. Etc. Can
you sync up with Tao?
Joel
Signature · 9 lines
"The nice thing about egotists is that they don't talk about other
people."
- Lucille S. Harper
Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127PATCH 1/2 ocfs2-tools: Add extended attribute support in mkfs.ocfs2
Quoted 10 lines · Joel Becker
include/ocfs2-kernel/ocfs2_fs.h struct ocfs2_group_desc · line 738
Quoted 8 lines
include/ocfs2-kernel/ocfs2_fs.h +8
-0+struct ocfs2_xattr_entry { +__le32 xe_name_hash; +__le16 xe_name_offset; +__u8 xe_name_len; +__u8 xe_type :7 ; +__u8 xe_local :1 ; +__le64 xe_value_size; +};We removed the bitfields.
Do we really remove the bitfields? We have no space for new u8 in xattr_entry.
Mark said we just need change the bottom bit for xe_local.
Quoted 4 lines
This got shuffled around for a 64bit checksum field. Etc. Can
you sync up with Tao?
sure. I will sync up those data struct with Tao.
Thanks,
tiger
PATCH 1/2 ocfs2-tools: Add extended attribute support in mkfs.ocfs2
Quoted 12 lines · Tiger Yang
Quoted 9 lines · Joel Becker
include/ocfs2-kernel/ocfs2_fs.h struct ocfs2_group_desc · line 738
Quoted 8 lines
include/ocfs2-kernel/ocfs2_fs.h +8
-0+struct ocfs2_xattr_entry { +__le32 xe_name_hash; +__le16 xe_name_offset; +__u8 xe_name_len; +__u8 xe_type :7 ; +__u8 xe_local :1 ; +__le64 xe_value_size; +};We removed the bitfields.
Quoted 3 lines
Do we really remove the bitfields? We have no space for new u8 in
xattr_entry.
Mark said we just need change the bottom bit forxe_local.
Yes, tiger may be right. Here is the original mail link.
http://oss.oracle.com/pipermail/ocfs2-devel/2008-July/002489.html
FYI.
Regards,
Tao
PATCH 1/2 ocfs2-tools: Add extended attribute support in mkfs.ocfs2
In reply to Tiger YangQuoted 13 lines · Tiger Yang
Quoted 10 lines · Joel Becker
include/ocfs2-kernel/ocfs2_fs.h struct ocfs2_group_desc · line 738
Quoted 8 lines
include/ocfs2-kernel/ocfs2_fs.h +8
-0+struct ocfs2_xattr_entry { +__le32 xe_name_hash; +__le16 xe_name_offset; +__u8 xe_name_len; +__u8 xe_type :7 ; +__u8 xe_local :1 ; +__le64 xe_value_size; +};We removed the bitfields.
Quoted 3 lines
Do we really remove the bitfields? We have no space for new u8 in
xattr_entry.
Mark said we just need change the bottom bit forxe_local.
We don't add an extra u8. We just define the single u8 and will
use masking to flag out the local bit.
Here's the structure:
struct ocfs2_xattr_entry {
__le32 xe_name_hash;
__le16 xe_name_offset;
__u8 xe_name_len;
__u8 xe_type;
__le64 xe_value_size;
};And you'd access xe_type with something like this:
static inline int xe_get_type(struct ocfs2_xattr_entry *xe)
{
return xe->xe_type & 0xFE;
}static inline int xe_is_local(struct ocfs2_xattr_entry *xe)
{
return xe->xe_type & 0x01;
} Something like that. Mark might have a preferred way to create
the accessor functions. The point is, defining the bitfields (:7, :1) isn't a portable thing to do for on-disk structures.
Joel
Signature · 10 lines
"I'm so tired of being tired, Sure as night will follow day. Most things I worry about Never happen anyway." Joel Becker Principal Software Developer Oracle E-mail: joel.becker at oracle.com Phone: (650) 506-8127