#define HFSPLUS_I_RSRC 0 /* represents a resource fork */ #define HFSPLUS_I_CAT_DIRTY 1 /* has changes in the catalog tree */ #define HFSPLUS_I_EXT_DIRTY 2 /* has changes in the extent tree */ #define HFSPLUS_I_ALLOC_DIRTY 3 /* has changes in the allocation file */ #define HFSPLUS_I_ATTR_DIRTY 4 /* has changes in the attributes tree */
/* * Mark an inode dirty, and also mark the btree in which the * specific type of metadata is stored. * For data or metadata that gets written back by into the catalog btree * by hfsplus_write_inode a plain mark_inode_dirty call is enough.
*/ staticinlinevoid hfsplus_mark_inode_dirty(struct inode *inode, unsignedint flag)
{
set_bit(flag, &HFSPLUS_I(inode)->flags);
mark_inode_dirty(inode);
}
struct hfs_find_data { /* filled by caller */
hfsplus_btree_key *search_key;
hfsplus_btree_key *key; /* filled by find */ struct hfs_btree *tree; struct hfs_bnode *bnode; /* filled by findrec */ int record; int keyoffset, keylength; int entryoffset, entrylength;
};
/* bnode.c */ void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len);
u16 hfs_bnode_read_u16(struct hfs_bnode *node, int off);
u8 hfs_bnode_read_u8(struct hfs_bnode *node, int off); void hfs_bnode_read_key(struct hfs_bnode *node, void *key, int off); void hfs_bnode_write(struct hfs_bnode *node, void *buf, int off, int len); void hfs_bnode_write_u16(struct hfs_bnode *node, int off, u16 data); void hfs_bnode_clear(struct hfs_bnode *node, int off, int len); void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst, struct hfs_bnode *src_node, int src, int len); void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len); void hfs_bnode_dump(struct hfs_bnode *node); void hfs_bnode_unlink(struct hfs_bnode *node); struct hfs_bnode *hfs_bnode_findhash(struct hfs_btree *tree, u32 cnid); void hfs_bnode_unhash(struct hfs_bnode *node); struct hfs_bnode *hfs_bnode_find(struct hfs_btree *tree, u32 num); void hfs_bnode_free(struct hfs_bnode *node); struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num); void hfs_bnode_get(struct hfs_bnode *node); void hfs_bnode_put(struct hfs_bnode *node); bool hfs_bnode_need_zeroout(struct hfs_btree *tree);
/* brec.c */
u16 hfs_brec_lenoff(struct hfs_bnode *node, u16 rec, u16 *off);
u16 hfs_brec_keylen(struct hfs_bnode *node, u16 rec); int hfs_brec_insert(struct hfs_find_data *fd, void *entry, int entry_len); int hfs_brec_remove(struct hfs_find_data *fd);
/* bfind.c */ int hfs_find_init(struct hfs_btree *tree, struct hfs_find_data *fd); void hfs_find_exit(struct hfs_find_data *fd); int hfs_find_1st_rec_by_cnid(struct hfs_bnode *bnode, struct hfs_find_data *fd, int *begin, int *end, int *cur_rec); int hfs_find_rec_by_key(struct hfs_bnode *bnode, struct hfs_find_data *fd, int *begin, int *end, int *cur_rec); int __hfs_brec_find(struct hfs_bnode *bnode, struct hfs_find_data *fd,
search_strategy_t rec_found); int hfs_brec_find(struct hfs_find_data *fd, search_strategy_t do_key_compare); int hfs_brec_read(struct hfs_find_data *fd, void *rec, int rec_len); int hfs_brec_goto(struct hfs_find_data *fd, int cnt);
/* unicode.c */ int hfsplus_strcasecmp(conststruct hfsplus_unistr *s1, conststruct hfsplus_unistr *s2); int hfsplus_strcmp(conststruct hfsplus_unistr *s1, conststruct hfsplus_unistr *s2); int hfsplus_uni2asc_str(struct super_block *sb, conststruct hfsplus_unistr *ustr, char *astr, int *len_p); int hfsplus_uni2asc_xattr_str(struct super_block *sb, conststruct hfsplus_attr_unistr *ustr, char *astr, int *len_p); int hfsplus_asc2uni(struct super_block *sb, struct hfsplus_unistr *ustr, int max_unistr_len, constchar *astr, int len); int hfsplus_hash_dentry(conststruct dentry *dentry, struct qstr *str); int hfsplus_compare_dentry(conststruct dentry *dentry, unsignedint len, constchar *str, conststruct qstr *name);
/* wrapper.c */ int hfsplus_submit_bio(struct super_block *sb, sector_t sector, void *buf, void **data, blk_opf_t opf); int hfsplus_read_wrapper(struct super_block *sb);
/* * time helpers: convert between 1904-base and 1970-base timestamps * * HFS+ implementations are highly inconsistent, this one matches the * traditional behavior of 64-bit Linux, giving the most useful * time range between 1970 and 2106, by treating any on-disk timestamp * under HFSPLUS_UTC_OFFSET (Jan 1 1970) as a time between 2040 and 2106.
*/ #define HFSPLUS_UTC_OFFSET 2082844800U
switch (tree->cnid) { case HFSPLUS_CAT_CNID: class = CATALOG_BTREE_MUTEX; break; case HFSPLUS_EXT_CNID: class = EXTENTS_BTREE_MUTEX; break; case HFSPLUS_ATTR_CNID: class = ATTR_BTREE_MUTEX; break; default:
BUG();
} returnclass;
}
staticinline bool is_bnode_offset_valid(struct hfs_bnode *node, int off)
{ bool is_valid = off < node->tree->node_size;
if (!is_valid) {
pr_err("requested invalid offset: " "NODE: id %u, type %#x, height %u, " "node_size %u, offset %d\n",
node->this, node->type, node->height,
node->tree->node_size, off);
}
return is_valid;
}
staticinline int check_and_correct_requested_length(struct hfs_bnode *node, int off, int len)
{ unsignedint node_size;
if (!is_bnode_offset_valid(node, off)) return 0;
node_size = node->tree->node_size;
if ((off + len) > node_size) { int new_len = (int)node_size - off;
pr_err("requested length has been corrected: " "NODE: id %u, type %#x, height %u, " "node_size %u, offset %d, " "requested_len %d, corrected_len %d\n",
node->this, node->type, node->height,
node->tree->node_size, off, len, new_len);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.