hfsplus_fs.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * linux/include/linux/hfsplus_fs.h
  4. *
  5. * Copyright (C) 1999
  6. * Brad Boyer (flar@pants.nu)
  7. * (C) 2003 Ardis Technologies <roman@ardistech.com>
  8. *
  9. */
  10. #ifndef _LINUX_HFSPLUS_FS_H
  11. #define _LINUX_HFSPLUS_FS_H
  12. #include <linux/fs.h>
  13. #include <linux/mutex.h>
  14. #include <linux/buffer_head.h>
  15. #include <linux/blkdev.h>
  16. #include <linux/fs_context.h>
  17. #include "hfsplus_raw.h"
  18. /* Runtime config options */
  19. #define HFSPLUS_DEF_CR_TYPE 0x3F3F3F3F /* '????' */
  20. #define HFSPLUS_TYPE_DATA 0x00
  21. #define HFSPLUS_TYPE_RSRC 0xFF
  22. typedef int (*btree_keycmp)(const hfsplus_btree_key *,
  23. const hfsplus_btree_key *);
  24. #define NODE_HASH_SIZE 256
  25. /* B-tree mutex nested subclasses */
  26. enum hfsplus_btree_mutex_classes {
  27. CATALOG_BTREE_MUTEX,
  28. EXTENTS_BTREE_MUTEX,
  29. ATTR_BTREE_MUTEX,
  30. };
  31. /* An HFS+ BTree held in memory */
  32. struct hfs_btree {
  33. struct super_block *sb;
  34. struct inode *inode;
  35. btree_keycmp keycmp;
  36. u32 cnid;
  37. u32 root;
  38. u32 leaf_count;
  39. u32 leaf_head;
  40. u32 leaf_tail;
  41. u32 node_count;
  42. u32 free_nodes;
  43. u32 attributes;
  44. unsigned int node_size;
  45. unsigned int node_size_shift;
  46. unsigned int max_key_len;
  47. unsigned int depth;
  48. struct mutex tree_lock;
  49. unsigned int pages_per_bnode;
  50. spinlock_t hash_lock;
  51. struct hfs_bnode *node_hash[NODE_HASH_SIZE];
  52. int node_hash_cnt;
  53. };
  54. struct page;
  55. /* An HFS+ BTree node in memory */
  56. struct hfs_bnode {
  57. struct hfs_btree *tree;
  58. u32 prev;
  59. u32 this;
  60. u32 next;
  61. u32 parent;
  62. u16 num_recs;
  63. u8 type;
  64. u8 height;
  65. struct hfs_bnode *next_hash;
  66. unsigned long flags;
  67. wait_queue_head_t lock_wq;
  68. atomic_t refcnt;
  69. unsigned int page_offset;
  70. struct page *page[];
  71. };
  72. #define HFS_BNODE_LOCK 0
  73. #define HFS_BNODE_ERROR 1
  74. #define HFS_BNODE_NEW 2
  75. #define HFS_BNODE_DIRTY 3
  76. #define HFS_BNODE_DELETED 4
  77. /*
  78. * Attributes file states
  79. */
  80. #define HFSPLUS_EMPTY_ATTR_TREE 0
  81. #define HFSPLUS_CREATING_ATTR_TREE 1
  82. #define HFSPLUS_VALID_ATTR_TREE 2
  83. #define HFSPLUS_FAILED_ATTR_TREE 3
  84. /*
  85. * HFS+ superblock info (built from Volume Header on disk)
  86. */
  87. struct hfsplus_vh;
  88. struct hfs_btree;
  89. struct hfsplus_sb_info {
  90. void *s_vhdr_buf;
  91. struct hfsplus_vh *s_vhdr;
  92. void *s_backup_vhdr_buf;
  93. struct hfsplus_vh *s_backup_vhdr;
  94. struct hfs_btree *ext_tree;
  95. struct hfs_btree *cat_tree;
  96. struct hfs_btree *attr_tree;
  97. atomic_t attr_tree_state;
  98. struct inode *alloc_file;
  99. struct inode *hidden_dir;
  100. struct nls_table *nls;
  101. /* Runtime variables */
  102. u32 blockoffset;
  103. u32 min_io_size;
  104. sector_t part_start;
  105. sector_t sect_count;
  106. int fs_shift;
  107. /* immutable data from the volume header */
  108. u32 alloc_blksz;
  109. int alloc_blksz_shift;
  110. u32 total_blocks;
  111. u32 data_clump_blocks, rsrc_clump_blocks;
  112. /* mutable data from the volume header, protected by alloc_mutex */
  113. u32 free_blocks;
  114. struct mutex alloc_mutex;
  115. /* mutable data from the volume header, protected by vh_mutex */
  116. u32 next_cnid;
  117. u32 file_count;
  118. u32 folder_count;
  119. struct mutex vh_mutex;
  120. /* Config options */
  121. u32 creator;
  122. u32 type;
  123. umode_t umask;
  124. kuid_t uid;
  125. kgid_t gid;
  126. int part, session;
  127. unsigned long flags;
  128. int work_queued; /* non-zero delayed work is queued */
  129. struct delayed_work sync_work; /* FS sync delayed work */
  130. spinlock_t work_lock; /* protects sync_work and work_queued */
  131. struct rcu_head rcu;
  132. };
  133. #define HFSPLUS_SB_WRITEBACKUP 0
  134. #define HFSPLUS_SB_NODECOMPOSE 1
  135. #define HFSPLUS_SB_FORCE 2
  136. #define HFSPLUS_SB_HFSX 3
  137. #define HFSPLUS_SB_CASEFOLD 4
  138. #define HFSPLUS_SB_NOBARRIER 5
  139. #define HFSPLUS_SB_UID 6
  140. #define HFSPLUS_SB_GID 7
  141. static inline struct hfsplus_sb_info *HFSPLUS_SB(struct super_block *sb)
  142. {
  143. return sb->s_fs_info;
  144. }
  145. struct hfsplus_inode_info {
  146. atomic_t opencnt;
  147. /*
  148. * Extent allocation information, protected by extents_lock.
  149. */
  150. u32 first_blocks;
  151. u32 clump_blocks;
  152. u32 alloc_blocks;
  153. u32 cached_start;
  154. u32 cached_blocks;
  155. hfsplus_extent_rec first_extents;
  156. hfsplus_extent_rec cached_extents;
  157. unsigned int extent_state;
  158. struct mutex extents_lock;
  159. /*
  160. * Immutable data.
  161. */
  162. struct inode *rsrc_inode;
  163. __be32 create_date;
  164. /*
  165. * Protected by sbi->vh_mutex.
  166. */
  167. u32 linkid;
  168. /*
  169. * Accessed using atomic bitops.
  170. */
  171. unsigned long flags;
  172. /*
  173. * Protected by i_mutex.
  174. */
  175. sector_t fs_blocks;
  176. u8 userflags; /* BSD user file flags */
  177. u32 subfolders; /* Subfolder count (HFSX only) */
  178. struct list_head open_dir_list;
  179. spinlock_t open_dir_lock;
  180. loff_t phys_size;
  181. struct inode vfs_inode;
  182. };
  183. #define HFSPLUS_EXT_DIRTY 0x0001
  184. #define HFSPLUS_EXT_NEW 0x0002
  185. #define HFSPLUS_I_RSRC 0 /* represents a resource fork */
  186. #define HFSPLUS_I_CAT_DIRTY 1 /* has changes in the catalog tree */
  187. #define HFSPLUS_I_EXT_DIRTY 2 /* has changes in the extent tree */
  188. #define HFSPLUS_I_ALLOC_DIRTY 3 /* has changes in the allocation file */
  189. #define HFSPLUS_I_ATTR_DIRTY 4 /* has changes in the attributes tree */
  190. #define HFSPLUS_IS_RSRC(inode) \
  191. test_bit(HFSPLUS_I_RSRC, &HFSPLUS_I(inode)->flags)
  192. static inline struct hfsplus_inode_info *HFSPLUS_I(struct inode *inode)
  193. {
  194. return container_of(inode, struct hfsplus_inode_info, vfs_inode);
  195. }
  196. /*
  197. * Mark an inode dirty, and also mark the btree in which the
  198. * specific type of metadata is stored.
  199. * For data or metadata that gets written back by into the catalog btree
  200. * by hfsplus_write_inode a plain mark_inode_dirty call is enough.
  201. */
  202. static inline void hfsplus_mark_inode_dirty(struct inode *inode,
  203. unsigned int flag)
  204. {
  205. set_bit(flag, &HFSPLUS_I(inode)->flags);
  206. mark_inode_dirty(inode);
  207. }
  208. struct hfs_find_data {
  209. /* filled by caller */
  210. hfsplus_btree_key *search_key;
  211. hfsplus_btree_key *key;
  212. /* filled by find */
  213. struct hfs_btree *tree;
  214. struct hfs_bnode *bnode;
  215. /* filled by findrec */
  216. int record;
  217. int keyoffset, keylength;
  218. int entryoffset, entrylength;
  219. };
  220. struct hfsplus_readdir_data {
  221. struct list_head list;
  222. struct file *file;
  223. struct hfsplus_cat_key key;
  224. };
  225. /*
  226. * Find minimum acceptible I/O size for an hfsplus sb.
  227. */
  228. static inline unsigned short hfsplus_min_io_size(struct super_block *sb)
  229. {
  230. return max_t(unsigned short, HFSPLUS_SB(sb)->min_io_size,
  231. HFSPLUS_SECTOR_SIZE);
  232. }
  233. #define hfs_btree_open hfsplus_btree_open
  234. #define hfs_btree_close hfsplus_btree_close
  235. #define hfs_btree_write hfsplus_btree_write
  236. #define hfs_bmap_reserve hfsplus_bmap_reserve
  237. #define hfs_bmap_alloc hfsplus_bmap_alloc
  238. #define hfs_bmap_free hfsplus_bmap_free
  239. #define hfs_bnode_read hfsplus_bnode_read
  240. #define hfs_bnode_read_u16 hfsplus_bnode_read_u16
  241. #define hfs_bnode_read_u8 hfsplus_bnode_read_u8
  242. #define hfs_bnode_read_key hfsplus_bnode_read_key
  243. #define hfs_bnode_write hfsplus_bnode_write
  244. #define hfs_bnode_write_u16 hfsplus_bnode_write_u16
  245. #define hfs_bnode_clear hfsplus_bnode_clear
  246. #define hfs_bnode_copy hfsplus_bnode_copy
  247. #define hfs_bnode_move hfsplus_bnode_move
  248. #define hfs_bnode_dump hfsplus_bnode_dump
  249. #define hfs_bnode_unlink hfsplus_bnode_unlink
  250. #define hfs_bnode_findhash hfsplus_bnode_findhash
  251. #define hfs_bnode_find hfsplus_bnode_find
  252. #define hfs_bnode_unhash hfsplus_bnode_unhash
  253. #define hfs_bnode_free hfsplus_bnode_free
  254. #define hfs_bnode_create hfsplus_bnode_create
  255. #define hfs_bnode_get hfsplus_bnode_get
  256. #define hfs_bnode_put hfsplus_bnode_put
  257. #define hfs_brec_lenoff hfsplus_brec_lenoff
  258. #define hfs_brec_keylen hfsplus_brec_keylen
  259. #define hfs_brec_insert hfsplus_brec_insert
  260. #define hfs_brec_remove hfsplus_brec_remove
  261. #define hfs_find_init hfsplus_find_init
  262. #define hfs_find_exit hfsplus_find_exit
  263. #define __hfs_brec_find __hfsplus_brec_find
  264. #define hfs_brec_find hfsplus_brec_find
  265. #define hfs_brec_read hfsplus_brec_read
  266. #define hfs_brec_goto hfsplus_brec_goto
  267. #define hfs_part_find hfsplus_part_find
  268. /*
  269. * hfs+-specific ioctl for making the filesystem bootable
  270. */
  271. #define HFSPLUS_IOC_BLESS _IO('h', 0x80)
  272. typedef int (*search_strategy_t)(struct hfs_bnode *,
  273. struct hfs_find_data *,
  274. int *, int *, int *);
  275. /*
  276. * Functions in any *.c used in other files
  277. */
  278. /* attributes.c */
  279. int __init hfsplus_create_attr_tree_cache(void);
  280. void hfsplus_destroy_attr_tree_cache(void);
  281. int hfsplus_attr_bin_cmp_key(const hfsplus_btree_key *k1,
  282. const hfsplus_btree_key *k2);
  283. int hfsplus_attr_build_key(struct super_block *sb, hfsplus_btree_key *key,
  284. u32 cnid, const char *name);
  285. hfsplus_attr_entry *hfsplus_alloc_attr_entry(void);
  286. void hfsplus_destroy_attr_entry(hfsplus_attr_entry *entry);
  287. int hfsplus_find_attr(struct super_block *sb, u32 cnid, const char *name,
  288. struct hfs_find_data *fd);
  289. int hfsplus_attr_exists(struct inode *inode, const char *name);
  290. int hfsplus_create_attr(struct inode *inode, const char *name,
  291. const void *value, size_t size);
  292. int hfsplus_delete_attr(struct inode *inode, const char *name);
  293. int hfsplus_delete_all_attrs(struct inode *dir, u32 cnid);
  294. int hfsplus_replace_attr(struct inode *inode,
  295. const char *name,
  296. const void *value, size_t size);
  297. /* bitmap.c */
  298. int hfsplus_block_allocate(struct super_block *sb, u32 size, u32 offset,
  299. u32 *max);
  300. int hfsplus_block_free(struct super_block *sb, u32 offset, u32 count);
  301. /* btree.c */
  302. u32 hfsplus_calc_btree_clump_size(u32 block_size, u32 node_size, u64 sectors,
  303. int file_id);
  304. struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id);
  305. void hfs_btree_close(struct hfs_btree *tree);
  306. int hfs_btree_write(struct hfs_btree *tree);
  307. int hfs_bmap_reserve(struct hfs_btree *tree, u32 rsvd_nodes);
  308. struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree);
  309. void hfs_bmap_free(struct hfs_bnode *node);
  310. /* bnode.c */
  311. void hfs_bnode_read(struct hfs_bnode *node, void *buf, u32 off, u32 len);
  312. u16 hfs_bnode_read_u16(struct hfs_bnode *node, u32 off);
  313. u8 hfs_bnode_read_u8(struct hfs_bnode *node, u32 off);
  314. void hfs_bnode_read_key(struct hfs_bnode *node, void *key, u32 off);
  315. void hfs_bnode_write(struct hfs_bnode *node, void *buf, u32 off, u32 len);
  316. void hfs_bnode_write_u16(struct hfs_bnode *node, u32 off, u16 data);
  317. void hfs_bnode_clear(struct hfs_bnode *node, u32 off, u32 len);
  318. void hfs_bnode_copy(struct hfs_bnode *dst_node, u32 dst,
  319. struct hfs_bnode *src_node, u32 src, u32 len);
  320. void hfs_bnode_move(struct hfs_bnode *node, u32 dst, u32 src, u32 len);
  321. void hfs_bnode_dump(struct hfs_bnode *node);
  322. void hfs_bnode_unlink(struct hfs_bnode *node);
  323. struct hfs_bnode *hfs_bnode_findhash(struct hfs_btree *tree, u32 cnid);
  324. void hfs_bnode_unhash(struct hfs_bnode *node);
  325. struct hfs_bnode *hfs_bnode_find(struct hfs_btree *tree, u32 num);
  326. void hfs_bnode_free(struct hfs_bnode *node);
  327. struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num);
  328. void hfs_bnode_get(struct hfs_bnode *node);
  329. void hfs_bnode_put(struct hfs_bnode *node);
  330. bool hfs_bnode_need_zeroout(struct hfs_btree *tree);
  331. /* brec.c */
  332. u16 hfs_brec_lenoff(struct hfs_bnode *node, u16 rec, u16 *off);
  333. u16 hfs_brec_keylen(struct hfs_bnode *node, u16 rec);
  334. int hfs_brec_insert(struct hfs_find_data *fd, void *entry, u32 entry_len);
  335. int hfs_brec_remove(struct hfs_find_data *fd);
  336. /* bfind.c */
  337. int hfs_find_init(struct hfs_btree *tree, struct hfs_find_data *fd);
  338. void hfs_find_exit(struct hfs_find_data *fd);
  339. int hfs_find_1st_rec_by_cnid(struct hfs_bnode *bnode, struct hfs_find_data *fd,
  340. int *begin, int *end, int *cur_rec);
  341. int hfs_find_rec_by_key(struct hfs_bnode *bnode, struct hfs_find_data *fd,
  342. int *begin, int *end, int *cur_rec);
  343. int __hfs_brec_find(struct hfs_bnode *bnode, struct hfs_find_data *fd,
  344. search_strategy_t rec_found);
  345. int hfs_brec_find(struct hfs_find_data *fd, search_strategy_t do_key_compare);
  346. int hfs_brec_read(struct hfs_find_data *fd, void *rec, u32 rec_len);
  347. int hfs_brec_goto(struct hfs_find_data *fd, int cnt);
  348. /* catalog.c */
  349. int hfsplus_cat_case_cmp_key(const hfsplus_btree_key *k1,
  350. const hfsplus_btree_key *k2);
  351. int hfsplus_cat_bin_cmp_key(const hfsplus_btree_key *k1,
  352. const hfsplus_btree_key *k2);
  353. int hfsplus_cat_build_key(struct super_block *sb, hfsplus_btree_key *key,
  354. u32 parent, const struct qstr *str);
  355. void hfsplus_cat_build_key_with_cnid(struct super_block *sb,
  356. hfsplus_btree_key *key, u32 parent);
  357. void hfsplus_cat_set_perms(struct inode *inode, struct hfsplus_perm *perms);
  358. int hfsplus_find_cat(struct super_block *sb, u32 cnid,
  359. struct hfs_find_data *fd);
  360. int hfsplus_create_cat(u32 cnid, struct inode *dir, const struct qstr *str,
  361. struct inode *inode);
  362. int hfsplus_delete_cat(u32 cnid, struct inode *dir, const struct qstr *str);
  363. int hfsplus_rename_cat(u32 cnid, struct inode *src_dir, const struct qstr *src_name,
  364. struct inode *dst_dir, const struct qstr *dst_name);
  365. /* dir.c */
  366. extern const struct inode_operations hfsplus_dir_inode_operations;
  367. extern const struct file_operations hfsplus_dir_operations;
  368. /* extents.c */
  369. int hfsplus_ext_cmp_key(const hfsplus_btree_key *k1,
  370. const hfsplus_btree_key *k2);
  371. int hfsplus_ext_write_extent(struct inode *inode);
  372. int hfsplus_get_block(struct inode *inode, sector_t iblock,
  373. struct buffer_head *bh_result, int create);
  374. int hfsplus_free_fork(struct super_block *sb, u32 cnid,
  375. struct hfsplus_fork_raw *fork, int type);
  376. int hfsplus_file_extend(struct inode *inode, bool zeroout);
  377. void hfsplus_file_truncate(struct inode *inode);
  378. /* inode.c */
  379. extern const struct address_space_operations hfsplus_aops;
  380. extern const struct address_space_operations hfsplus_btree_aops;
  381. extern const struct dentry_operations hfsplus_dentry_operations;
  382. int hfsplus_write_begin(const struct kiocb *iocb,
  383. struct address_space *mapping,
  384. loff_t pos, unsigned len, struct folio **foliop,
  385. void **fsdata);
  386. struct inode *hfsplus_new_inode(struct super_block *sb, struct inode *dir,
  387. umode_t mode);
  388. void hfsplus_delete_inode(struct inode *inode);
  389. void hfsplus_inode_read_fork(struct inode *inode,
  390. struct hfsplus_fork_raw *fork);
  391. void hfsplus_inode_write_fork(struct inode *inode,
  392. struct hfsplus_fork_raw *fork);
  393. int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd);
  394. int hfsplus_cat_write_inode(struct inode *inode);
  395. int hfsplus_getattr(struct mnt_idmap *idmap, const struct path *path,
  396. struct kstat *stat, u32 request_mask,
  397. unsigned int query_flags);
  398. int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end,
  399. int datasync);
  400. int hfsplus_fileattr_get(struct dentry *dentry, struct file_kattr *fa);
  401. int hfsplus_fileattr_set(struct mnt_idmap *idmap,
  402. struct dentry *dentry, struct file_kattr *fa);
  403. /* ioctl.c */
  404. long hfsplus_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
  405. /* options.c */
  406. void hfsplus_fill_defaults(struct hfsplus_sb_info *opts);
  407. int hfsplus_parse_param(struct fs_context *fc, struct fs_parameter *param);
  408. int hfsplus_show_options(struct seq_file *seq, struct dentry *root);
  409. /* part_tbl.c */
  410. int hfs_part_find(struct super_block *sb, sector_t *part_start,
  411. sector_t *part_size);
  412. /* super.c */
  413. struct inode *hfsplus_iget(struct super_block *sb, unsigned long ino);
  414. void hfsplus_mark_mdb_dirty(struct super_block *sb);
  415. void hfsplus_prepare_volume_header_for_commit(struct hfsplus_vh *vhdr);
  416. int hfsplus_commit_superblock(struct super_block *sb);
  417. /* tables.c */
  418. extern u16 hfsplus_case_fold_table[];
  419. extern u16 hfsplus_decompose_table[];
  420. extern u16 hfsplus_compose_table[];
  421. /* unicode.c */
  422. int hfsplus_strcasecmp(const struct hfsplus_unistr *s1,
  423. const struct hfsplus_unistr *s2);
  424. int hfsplus_strcmp(const struct hfsplus_unistr *s1,
  425. const struct hfsplus_unistr *s2);
  426. int hfsplus_uni2asc_str(struct super_block *sb,
  427. const struct hfsplus_unistr *ustr, char *astr,
  428. int *len_p);
  429. int hfsplus_uni2asc_xattr_str(struct super_block *sb,
  430. const struct hfsplus_attr_unistr *ustr,
  431. char *astr, int *len_p);
  432. int hfsplus_asc2uni(struct super_block *sb, struct hfsplus_unistr *ustr,
  433. int max_unistr_len, const char *astr, int len);
  434. int hfsplus_hash_dentry(const struct dentry *dentry, struct qstr *str);
  435. int hfsplus_compare_dentry(const struct dentry *dentry, unsigned int len,
  436. const char *str, const struct qstr *name);
  437. /* wrapper.c */
  438. int hfsplus_submit_bio(struct super_block *sb, sector_t sector, void *buf,
  439. void **data, blk_opf_t opf);
  440. int hfsplus_read_wrapper(struct super_block *sb);
  441. /*
  442. * time helpers: convert between 1904-base and 1970-base timestamps
  443. *
  444. * HFS+ implementations are highly inconsistent, this one matches the
  445. * traditional behavior of 64-bit Linux, giving the most useful
  446. * time range between 1970 and 2106, by treating any on-disk timestamp
  447. * under HFSPLUS_UTC_OFFSET (Jan 1 1970) as a time between 2040 and 2106.
  448. */
  449. #define HFSPLUS_UTC_OFFSET 2082844800U
  450. static inline time64_t __hfsp_mt2ut(__be32 mt)
  451. {
  452. time64_t ut = (u32)(be32_to_cpu(mt) - HFSPLUS_UTC_OFFSET);
  453. return ut;
  454. }
  455. static inline __be32 __hfsp_ut2mt(time64_t ut)
  456. {
  457. return cpu_to_be32(lower_32_bits(ut) + HFSPLUS_UTC_OFFSET);
  458. }
  459. static inline enum hfsplus_btree_mutex_classes
  460. hfsplus_btree_lock_class(struct hfs_btree *tree)
  461. {
  462. enum hfsplus_btree_mutex_classes class;
  463. switch (tree->cnid) {
  464. case HFSPLUS_CAT_CNID:
  465. class = CATALOG_BTREE_MUTEX;
  466. break;
  467. case HFSPLUS_EXT_CNID:
  468. class = EXTENTS_BTREE_MUTEX;
  469. break;
  470. case HFSPLUS_ATTR_CNID:
  471. class = ATTR_BTREE_MUTEX;
  472. break;
  473. default:
  474. BUG();
  475. }
  476. return class;
  477. }
  478. static inline
  479. bool is_bnode_offset_valid(struct hfs_bnode *node, u32 off)
  480. {
  481. bool is_valid = off < node->tree->node_size;
  482. if (!is_valid) {
  483. pr_err("requested invalid offset: "
  484. "NODE: id %u, type %#x, height %u, "
  485. "node_size %u, offset %u\n",
  486. node->this, node->type, node->height,
  487. node->tree->node_size, off);
  488. }
  489. return is_valid;
  490. }
  491. static inline
  492. u32 check_and_correct_requested_length(struct hfs_bnode *node, u32 off, u32 len)
  493. {
  494. unsigned int node_size;
  495. if (!is_bnode_offset_valid(node, off))
  496. return 0;
  497. node_size = node->tree->node_size;
  498. if ((off + len) > node_size) {
  499. u32 new_len = node_size - off;
  500. pr_err("requested length has been corrected: "
  501. "NODE: id %u, type %#x, height %u, "
  502. "node_size %u, offset %u, "
  503. "requested_len %u, corrected_len %u\n",
  504. node->this, node->type, node->height,
  505. node->tree->node_size, off, len, new_len);
  506. return new_len;
  507. }
  508. return len;
  509. }
  510. /* compatibility */
  511. #define hfsp_mt2ut(t) (struct timespec64){ .tv_sec = __hfsp_mt2ut(t) }
  512. #define hfsp_ut2mt(t) __hfsp_ut2mt((t).tv_sec)
  513. #define hfsp_now2mt() __hfsp_ut2mt(ktime_get_real_seconds())
  514. #endif