18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * linux/fs/hfsplus/inode.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2001 68c2ecf20Sopenharmony_ci * Brad Boyer (flar@allandria.com) 78c2ecf20Sopenharmony_ci * (C) 2003 Ardis Technologies <roman@ardistech.com> 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * Inode handling routines 108c2ecf20Sopenharmony_ci */ 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <linux/blkdev.h> 138c2ecf20Sopenharmony_ci#include <linux/mm.h> 148c2ecf20Sopenharmony_ci#include <linux/fs.h> 158c2ecf20Sopenharmony_ci#include <linux/pagemap.h> 168c2ecf20Sopenharmony_ci#include <linux/mpage.h> 178c2ecf20Sopenharmony_ci#include <linux/sched.h> 188c2ecf20Sopenharmony_ci#include <linux/cred.h> 198c2ecf20Sopenharmony_ci#include <linux/uio.h> 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#include "hfsplus_fs.h" 228c2ecf20Sopenharmony_ci#include "hfsplus_raw.h" 238c2ecf20Sopenharmony_ci#include "xattr.h" 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_cistatic int hfsplus_readpage(struct file *file, struct page *page) 268c2ecf20Sopenharmony_ci{ 278c2ecf20Sopenharmony_ci return block_read_full_page(page, hfsplus_get_block); 288c2ecf20Sopenharmony_ci} 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_cistatic int hfsplus_writepage(struct page *page, struct writeback_control *wbc) 318c2ecf20Sopenharmony_ci{ 328c2ecf20Sopenharmony_ci return block_write_full_page(page, hfsplus_get_block, wbc); 338c2ecf20Sopenharmony_ci} 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistatic void hfsplus_write_failed(struct address_space *mapping, loff_t to) 368c2ecf20Sopenharmony_ci{ 378c2ecf20Sopenharmony_ci struct inode *inode = mapping->host; 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci if (to > inode->i_size) { 408c2ecf20Sopenharmony_ci truncate_pagecache(inode, inode->i_size); 418c2ecf20Sopenharmony_ci hfsplus_file_truncate(inode); 428c2ecf20Sopenharmony_ci } 438c2ecf20Sopenharmony_ci} 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_cistatic int hfsplus_write_begin(struct file *file, struct address_space *mapping, 468c2ecf20Sopenharmony_ci loff_t pos, unsigned len, unsigned flags, 478c2ecf20Sopenharmony_ci struct page **pagep, void **fsdata) 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci int ret; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci *pagep = NULL; 528c2ecf20Sopenharmony_ci ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata, 538c2ecf20Sopenharmony_ci hfsplus_get_block, 548c2ecf20Sopenharmony_ci &HFSPLUS_I(mapping->host)->phys_size); 558c2ecf20Sopenharmony_ci if (unlikely(ret)) 568c2ecf20Sopenharmony_ci hfsplus_write_failed(mapping, pos + len); 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci return ret; 598c2ecf20Sopenharmony_ci} 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_cistatic sector_t hfsplus_bmap(struct address_space *mapping, sector_t block) 628c2ecf20Sopenharmony_ci{ 638c2ecf20Sopenharmony_ci return generic_block_bmap(mapping, block, hfsplus_get_block); 648c2ecf20Sopenharmony_ci} 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_cistatic int hfsplus_releasepage(struct page *page, gfp_t mask) 678c2ecf20Sopenharmony_ci{ 688c2ecf20Sopenharmony_ci struct inode *inode = page->mapping->host; 698c2ecf20Sopenharmony_ci struct super_block *sb = inode->i_sb; 708c2ecf20Sopenharmony_ci struct hfs_btree *tree; 718c2ecf20Sopenharmony_ci struct hfs_bnode *node; 728c2ecf20Sopenharmony_ci u32 nidx; 738c2ecf20Sopenharmony_ci int i, res = 1; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci switch (inode->i_ino) { 768c2ecf20Sopenharmony_ci case HFSPLUS_EXT_CNID: 778c2ecf20Sopenharmony_ci tree = HFSPLUS_SB(sb)->ext_tree; 788c2ecf20Sopenharmony_ci break; 798c2ecf20Sopenharmony_ci case HFSPLUS_CAT_CNID: 808c2ecf20Sopenharmony_ci tree = HFSPLUS_SB(sb)->cat_tree; 818c2ecf20Sopenharmony_ci break; 828c2ecf20Sopenharmony_ci case HFSPLUS_ATTR_CNID: 838c2ecf20Sopenharmony_ci tree = HFSPLUS_SB(sb)->attr_tree; 848c2ecf20Sopenharmony_ci break; 858c2ecf20Sopenharmony_ci default: 868c2ecf20Sopenharmony_ci BUG(); 878c2ecf20Sopenharmony_ci return 0; 888c2ecf20Sopenharmony_ci } 898c2ecf20Sopenharmony_ci if (!tree) 908c2ecf20Sopenharmony_ci return 0; 918c2ecf20Sopenharmony_ci if (tree->node_size >= PAGE_SIZE) { 928c2ecf20Sopenharmony_ci nidx = page->index >> 938c2ecf20Sopenharmony_ci (tree->node_size_shift - PAGE_SHIFT); 948c2ecf20Sopenharmony_ci spin_lock(&tree->hash_lock); 958c2ecf20Sopenharmony_ci node = hfs_bnode_findhash(tree, nidx); 968c2ecf20Sopenharmony_ci if (!node) 978c2ecf20Sopenharmony_ci ; 988c2ecf20Sopenharmony_ci else if (atomic_read(&node->refcnt)) 998c2ecf20Sopenharmony_ci res = 0; 1008c2ecf20Sopenharmony_ci if (res && node) { 1018c2ecf20Sopenharmony_ci hfs_bnode_unhash(node); 1028c2ecf20Sopenharmony_ci hfs_bnode_free(node); 1038c2ecf20Sopenharmony_ci } 1048c2ecf20Sopenharmony_ci spin_unlock(&tree->hash_lock); 1058c2ecf20Sopenharmony_ci } else { 1068c2ecf20Sopenharmony_ci nidx = page->index << 1078c2ecf20Sopenharmony_ci (PAGE_SHIFT - tree->node_size_shift); 1088c2ecf20Sopenharmony_ci i = 1 << (PAGE_SHIFT - tree->node_size_shift); 1098c2ecf20Sopenharmony_ci spin_lock(&tree->hash_lock); 1108c2ecf20Sopenharmony_ci do { 1118c2ecf20Sopenharmony_ci node = hfs_bnode_findhash(tree, nidx++); 1128c2ecf20Sopenharmony_ci if (!node) 1138c2ecf20Sopenharmony_ci continue; 1148c2ecf20Sopenharmony_ci if (atomic_read(&node->refcnt)) { 1158c2ecf20Sopenharmony_ci res = 0; 1168c2ecf20Sopenharmony_ci break; 1178c2ecf20Sopenharmony_ci } 1188c2ecf20Sopenharmony_ci hfs_bnode_unhash(node); 1198c2ecf20Sopenharmony_ci hfs_bnode_free(node); 1208c2ecf20Sopenharmony_ci } while (--i && nidx < tree->node_count); 1218c2ecf20Sopenharmony_ci spin_unlock(&tree->hash_lock); 1228c2ecf20Sopenharmony_ci } 1238c2ecf20Sopenharmony_ci return res ? try_to_free_buffers(page) : 0; 1248c2ecf20Sopenharmony_ci} 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_cistatic ssize_t hfsplus_direct_IO(struct kiocb *iocb, struct iov_iter *iter) 1278c2ecf20Sopenharmony_ci{ 1288c2ecf20Sopenharmony_ci struct file *file = iocb->ki_filp; 1298c2ecf20Sopenharmony_ci struct address_space *mapping = file->f_mapping; 1308c2ecf20Sopenharmony_ci struct inode *inode = mapping->host; 1318c2ecf20Sopenharmony_ci size_t count = iov_iter_count(iter); 1328c2ecf20Sopenharmony_ci ssize_t ret; 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci ret = blockdev_direct_IO(iocb, inode, iter, hfsplus_get_block); 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci /* 1378c2ecf20Sopenharmony_ci * In case of error extending write may have instantiated a few 1388c2ecf20Sopenharmony_ci * blocks outside i_size. Trim these off again. 1398c2ecf20Sopenharmony_ci */ 1408c2ecf20Sopenharmony_ci if (unlikely(iov_iter_rw(iter) == WRITE && ret < 0)) { 1418c2ecf20Sopenharmony_ci loff_t isize = i_size_read(inode); 1428c2ecf20Sopenharmony_ci loff_t end = iocb->ki_pos + count; 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci if (end > isize) 1458c2ecf20Sopenharmony_ci hfsplus_write_failed(mapping, end); 1468c2ecf20Sopenharmony_ci } 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci return ret; 1498c2ecf20Sopenharmony_ci} 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_cistatic int hfsplus_writepages(struct address_space *mapping, 1528c2ecf20Sopenharmony_ci struct writeback_control *wbc) 1538c2ecf20Sopenharmony_ci{ 1548c2ecf20Sopenharmony_ci return mpage_writepages(mapping, wbc, hfsplus_get_block); 1558c2ecf20Sopenharmony_ci} 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ciconst struct address_space_operations hfsplus_btree_aops = { 1588c2ecf20Sopenharmony_ci .readpage = hfsplus_readpage, 1598c2ecf20Sopenharmony_ci .writepage = hfsplus_writepage, 1608c2ecf20Sopenharmony_ci .write_begin = hfsplus_write_begin, 1618c2ecf20Sopenharmony_ci .write_end = generic_write_end, 1628c2ecf20Sopenharmony_ci .bmap = hfsplus_bmap, 1638c2ecf20Sopenharmony_ci .releasepage = hfsplus_releasepage, 1648c2ecf20Sopenharmony_ci}; 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ciconst struct address_space_operations hfsplus_aops = { 1678c2ecf20Sopenharmony_ci .readpage = hfsplus_readpage, 1688c2ecf20Sopenharmony_ci .writepage = hfsplus_writepage, 1698c2ecf20Sopenharmony_ci .write_begin = hfsplus_write_begin, 1708c2ecf20Sopenharmony_ci .write_end = generic_write_end, 1718c2ecf20Sopenharmony_ci .bmap = hfsplus_bmap, 1728c2ecf20Sopenharmony_ci .direct_IO = hfsplus_direct_IO, 1738c2ecf20Sopenharmony_ci .writepages = hfsplus_writepages, 1748c2ecf20Sopenharmony_ci}; 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ciconst struct dentry_operations hfsplus_dentry_operations = { 1778c2ecf20Sopenharmony_ci .d_hash = hfsplus_hash_dentry, 1788c2ecf20Sopenharmony_ci .d_compare = hfsplus_compare_dentry, 1798c2ecf20Sopenharmony_ci}; 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_cistatic void hfsplus_get_perms(struct inode *inode, 1828c2ecf20Sopenharmony_ci struct hfsplus_perm *perms, int dir) 1838c2ecf20Sopenharmony_ci{ 1848c2ecf20Sopenharmony_ci struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); 1858c2ecf20Sopenharmony_ci u16 mode; 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci mode = be16_to_cpu(perms->mode); 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci i_uid_write(inode, be32_to_cpu(perms->owner)); 1908c2ecf20Sopenharmony_ci if ((test_bit(HFSPLUS_SB_UID, &sbi->flags)) || (!i_uid_read(inode) && !mode)) 1918c2ecf20Sopenharmony_ci inode->i_uid = sbi->uid; 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci i_gid_write(inode, be32_to_cpu(perms->group)); 1948c2ecf20Sopenharmony_ci if ((test_bit(HFSPLUS_SB_GID, &sbi->flags)) || (!i_gid_read(inode) && !mode)) 1958c2ecf20Sopenharmony_ci inode->i_gid = sbi->gid; 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci if (dir) { 1988c2ecf20Sopenharmony_ci mode = mode ? (mode & S_IALLUGO) : (S_IRWXUGO & ~(sbi->umask)); 1998c2ecf20Sopenharmony_ci mode |= S_IFDIR; 2008c2ecf20Sopenharmony_ci } else if (!mode) 2018c2ecf20Sopenharmony_ci mode = S_IFREG | ((S_IRUGO|S_IWUGO) & ~(sbi->umask)); 2028c2ecf20Sopenharmony_ci inode->i_mode = mode; 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci HFSPLUS_I(inode)->userflags = perms->userflags; 2058c2ecf20Sopenharmony_ci if (perms->rootflags & HFSPLUS_FLG_IMMUTABLE) 2068c2ecf20Sopenharmony_ci inode->i_flags |= S_IMMUTABLE; 2078c2ecf20Sopenharmony_ci else 2088c2ecf20Sopenharmony_ci inode->i_flags &= ~S_IMMUTABLE; 2098c2ecf20Sopenharmony_ci if (perms->rootflags & HFSPLUS_FLG_APPEND) 2108c2ecf20Sopenharmony_ci inode->i_flags |= S_APPEND; 2118c2ecf20Sopenharmony_ci else 2128c2ecf20Sopenharmony_ci inode->i_flags &= ~S_APPEND; 2138c2ecf20Sopenharmony_ci} 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_cistatic int hfsplus_file_open(struct inode *inode, struct file *file) 2168c2ecf20Sopenharmony_ci{ 2178c2ecf20Sopenharmony_ci if (HFSPLUS_IS_RSRC(inode)) 2188c2ecf20Sopenharmony_ci inode = HFSPLUS_I(inode)->rsrc_inode; 2198c2ecf20Sopenharmony_ci if (!(file->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS) 2208c2ecf20Sopenharmony_ci return -EOVERFLOW; 2218c2ecf20Sopenharmony_ci atomic_inc(&HFSPLUS_I(inode)->opencnt); 2228c2ecf20Sopenharmony_ci return 0; 2238c2ecf20Sopenharmony_ci} 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_cistatic int hfsplus_file_release(struct inode *inode, struct file *file) 2268c2ecf20Sopenharmony_ci{ 2278c2ecf20Sopenharmony_ci struct super_block *sb = inode->i_sb; 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci if (HFSPLUS_IS_RSRC(inode)) 2308c2ecf20Sopenharmony_ci inode = HFSPLUS_I(inode)->rsrc_inode; 2318c2ecf20Sopenharmony_ci if (atomic_dec_and_test(&HFSPLUS_I(inode)->opencnt)) { 2328c2ecf20Sopenharmony_ci inode_lock(inode); 2338c2ecf20Sopenharmony_ci hfsplus_file_truncate(inode); 2348c2ecf20Sopenharmony_ci if (inode->i_flags & S_DEAD) { 2358c2ecf20Sopenharmony_ci hfsplus_delete_cat(inode->i_ino, 2368c2ecf20Sopenharmony_ci HFSPLUS_SB(sb)->hidden_dir, NULL); 2378c2ecf20Sopenharmony_ci hfsplus_delete_inode(inode); 2388c2ecf20Sopenharmony_ci } 2398c2ecf20Sopenharmony_ci inode_unlock(inode); 2408c2ecf20Sopenharmony_ci } 2418c2ecf20Sopenharmony_ci return 0; 2428c2ecf20Sopenharmony_ci} 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_cistatic int hfsplus_setattr(struct dentry *dentry, struct iattr *attr) 2458c2ecf20Sopenharmony_ci{ 2468c2ecf20Sopenharmony_ci struct inode *inode = d_inode(dentry); 2478c2ecf20Sopenharmony_ci int error; 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci error = setattr_prepare(dentry, attr); 2508c2ecf20Sopenharmony_ci if (error) 2518c2ecf20Sopenharmony_ci return error; 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci if ((attr->ia_valid & ATTR_SIZE) && 2548c2ecf20Sopenharmony_ci attr->ia_size != i_size_read(inode)) { 2558c2ecf20Sopenharmony_ci inode_dio_wait(inode); 2568c2ecf20Sopenharmony_ci if (attr->ia_size > inode->i_size) { 2578c2ecf20Sopenharmony_ci error = generic_cont_expand_simple(inode, 2588c2ecf20Sopenharmony_ci attr->ia_size); 2598c2ecf20Sopenharmony_ci if (error) 2608c2ecf20Sopenharmony_ci return error; 2618c2ecf20Sopenharmony_ci } 2628c2ecf20Sopenharmony_ci truncate_setsize(inode, attr->ia_size); 2638c2ecf20Sopenharmony_ci hfsplus_file_truncate(inode); 2648c2ecf20Sopenharmony_ci inode->i_mtime = inode->i_ctime = current_time(inode); 2658c2ecf20Sopenharmony_ci } 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci setattr_copy(inode, attr); 2688c2ecf20Sopenharmony_ci mark_inode_dirty(inode); 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci return 0; 2718c2ecf20Sopenharmony_ci} 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ciint hfsplus_getattr(const struct path *path, struct kstat *stat, 2748c2ecf20Sopenharmony_ci u32 request_mask, unsigned int query_flags) 2758c2ecf20Sopenharmony_ci{ 2768c2ecf20Sopenharmony_ci struct inode *inode = d_inode(path->dentry); 2778c2ecf20Sopenharmony_ci struct hfsplus_inode_info *hip = HFSPLUS_I(inode); 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci if (inode->i_flags & S_APPEND) 2808c2ecf20Sopenharmony_ci stat->attributes |= STATX_ATTR_APPEND; 2818c2ecf20Sopenharmony_ci if (inode->i_flags & S_IMMUTABLE) 2828c2ecf20Sopenharmony_ci stat->attributes |= STATX_ATTR_IMMUTABLE; 2838c2ecf20Sopenharmony_ci if (hip->userflags & HFSPLUS_FLG_NODUMP) 2848c2ecf20Sopenharmony_ci stat->attributes |= STATX_ATTR_NODUMP; 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci stat->attributes_mask |= STATX_ATTR_APPEND | STATX_ATTR_IMMUTABLE | 2878c2ecf20Sopenharmony_ci STATX_ATTR_NODUMP; 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_ci generic_fillattr(inode, stat); 2908c2ecf20Sopenharmony_ci return 0; 2918c2ecf20Sopenharmony_ci} 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ciint hfsplus_file_fsync(struct file *file, loff_t start, loff_t end, 2948c2ecf20Sopenharmony_ci int datasync) 2958c2ecf20Sopenharmony_ci{ 2968c2ecf20Sopenharmony_ci struct inode *inode = file->f_mapping->host; 2978c2ecf20Sopenharmony_ci struct hfsplus_inode_info *hip = HFSPLUS_I(inode); 2988c2ecf20Sopenharmony_ci struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); 2998c2ecf20Sopenharmony_ci int error = 0, error2; 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci error = file_write_and_wait_range(file, start, end); 3028c2ecf20Sopenharmony_ci if (error) 3038c2ecf20Sopenharmony_ci return error; 3048c2ecf20Sopenharmony_ci inode_lock(inode); 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_ci /* 3078c2ecf20Sopenharmony_ci * Sync inode metadata into the catalog and extent trees. 3088c2ecf20Sopenharmony_ci */ 3098c2ecf20Sopenharmony_ci sync_inode_metadata(inode, 1); 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci /* 3128c2ecf20Sopenharmony_ci * And explicitly write out the btrees. 3138c2ecf20Sopenharmony_ci */ 3148c2ecf20Sopenharmony_ci if (test_and_clear_bit(HFSPLUS_I_CAT_DIRTY, &hip->flags)) 3158c2ecf20Sopenharmony_ci error = filemap_write_and_wait(sbi->cat_tree->inode->i_mapping); 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci if (test_and_clear_bit(HFSPLUS_I_EXT_DIRTY, &hip->flags)) { 3188c2ecf20Sopenharmony_ci error2 = 3198c2ecf20Sopenharmony_ci filemap_write_and_wait(sbi->ext_tree->inode->i_mapping); 3208c2ecf20Sopenharmony_ci if (!error) 3218c2ecf20Sopenharmony_ci error = error2; 3228c2ecf20Sopenharmony_ci } 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci if (test_and_clear_bit(HFSPLUS_I_ATTR_DIRTY, &hip->flags)) { 3258c2ecf20Sopenharmony_ci if (sbi->attr_tree) { 3268c2ecf20Sopenharmony_ci error2 = 3278c2ecf20Sopenharmony_ci filemap_write_and_wait( 3288c2ecf20Sopenharmony_ci sbi->attr_tree->inode->i_mapping); 3298c2ecf20Sopenharmony_ci if (!error) 3308c2ecf20Sopenharmony_ci error = error2; 3318c2ecf20Sopenharmony_ci } else { 3328c2ecf20Sopenharmony_ci pr_err("sync non-existent attributes tree\n"); 3338c2ecf20Sopenharmony_ci } 3348c2ecf20Sopenharmony_ci } 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ci if (test_and_clear_bit(HFSPLUS_I_ALLOC_DIRTY, &hip->flags)) { 3378c2ecf20Sopenharmony_ci error2 = filemap_write_and_wait(sbi->alloc_file->i_mapping); 3388c2ecf20Sopenharmony_ci if (!error) 3398c2ecf20Sopenharmony_ci error = error2; 3408c2ecf20Sopenharmony_ci } 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_ci if (!test_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags)) 3438c2ecf20Sopenharmony_ci blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL); 3448c2ecf20Sopenharmony_ci 3458c2ecf20Sopenharmony_ci inode_unlock(inode); 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_ci return error; 3488c2ecf20Sopenharmony_ci} 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_cistatic const struct inode_operations hfsplus_file_inode_operations = { 3518c2ecf20Sopenharmony_ci .setattr = hfsplus_setattr, 3528c2ecf20Sopenharmony_ci .getattr = hfsplus_getattr, 3538c2ecf20Sopenharmony_ci .listxattr = hfsplus_listxattr, 3548c2ecf20Sopenharmony_ci}; 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_cistatic const struct file_operations hfsplus_file_operations = { 3578c2ecf20Sopenharmony_ci .llseek = generic_file_llseek, 3588c2ecf20Sopenharmony_ci .read_iter = generic_file_read_iter, 3598c2ecf20Sopenharmony_ci .write_iter = generic_file_write_iter, 3608c2ecf20Sopenharmony_ci .mmap = generic_file_mmap, 3618c2ecf20Sopenharmony_ci .splice_read = generic_file_splice_read, 3628c2ecf20Sopenharmony_ci .fsync = hfsplus_file_fsync, 3638c2ecf20Sopenharmony_ci .open = hfsplus_file_open, 3648c2ecf20Sopenharmony_ci .release = hfsplus_file_release, 3658c2ecf20Sopenharmony_ci .unlocked_ioctl = hfsplus_ioctl, 3668c2ecf20Sopenharmony_ci}; 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_cistruct inode *hfsplus_new_inode(struct super_block *sb, struct inode *dir, 3698c2ecf20Sopenharmony_ci umode_t mode) 3708c2ecf20Sopenharmony_ci{ 3718c2ecf20Sopenharmony_ci struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); 3728c2ecf20Sopenharmony_ci struct inode *inode = new_inode(sb); 3738c2ecf20Sopenharmony_ci struct hfsplus_inode_info *hip; 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_ci if (!inode) 3768c2ecf20Sopenharmony_ci return NULL; 3778c2ecf20Sopenharmony_ci 3788c2ecf20Sopenharmony_ci inode->i_ino = sbi->next_cnid++; 3798c2ecf20Sopenharmony_ci inode_init_owner(inode, dir, mode); 3808c2ecf20Sopenharmony_ci set_nlink(inode, 1); 3818c2ecf20Sopenharmony_ci inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_ci hip = HFSPLUS_I(inode); 3848c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&hip->open_dir_list); 3858c2ecf20Sopenharmony_ci spin_lock_init(&hip->open_dir_lock); 3868c2ecf20Sopenharmony_ci mutex_init(&hip->extents_lock); 3878c2ecf20Sopenharmony_ci atomic_set(&hip->opencnt, 0); 3888c2ecf20Sopenharmony_ci hip->extent_state = 0; 3898c2ecf20Sopenharmony_ci hip->flags = 0; 3908c2ecf20Sopenharmony_ci hip->userflags = 0; 3918c2ecf20Sopenharmony_ci hip->subfolders = 0; 3928c2ecf20Sopenharmony_ci memset(hip->first_extents, 0, sizeof(hfsplus_extent_rec)); 3938c2ecf20Sopenharmony_ci memset(hip->cached_extents, 0, sizeof(hfsplus_extent_rec)); 3948c2ecf20Sopenharmony_ci hip->alloc_blocks = 0; 3958c2ecf20Sopenharmony_ci hip->first_blocks = 0; 3968c2ecf20Sopenharmony_ci hip->cached_start = 0; 3978c2ecf20Sopenharmony_ci hip->cached_blocks = 0; 3988c2ecf20Sopenharmony_ci hip->phys_size = 0; 3998c2ecf20Sopenharmony_ci hip->fs_blocks = 0; 4008c2ecf20Sopenharmony_ci hip->rsrc_inode = NULL; 4018c2ecf20Sopenharmony_ci if (S_ISDIR(inode->i_mode)) { 4028c2ecf20Sopenharmony_ci inode->i_size = 2; 4038c2ecf20Sopenharmony_ci sbi->folder_count++; 4048c2ecf20Sopenharmony_ci inode->i_op = &hfsplus_dir_inode_operations; 4058c2ecf20Sopenharmony_ci inode->i_fop = &hfsplus_dir_operations; 4068c2ecf20Sopenharmony_ci } else if (S_ISREG(inode->i_mode)) { 4078c2ecf20Sopenharmony_ci sbi->file_count++; 4088c2ecf20Sopenharmony_ci inode->i_op = &hfsplus_file_inode_operations; 4098c2ecf20Sopenharmony_ci inode->i_fop = &hfsplus_file_operations; 4108c2ecf20Sopenharmony_ci inode->i_mapping->a_ops = &hfsplus_aops; 4118c2ecf20Sopenharmony_ci hip->clump_blocks = sbi->data_clump_blocks; 4128c2ecf20Sopenharmony_ci } else if (S_ISLNK(inode->i_mode)) { 4138c2ecf20Sopenharmony_ci sbi->file_count++; 4148c2ecf20Sopenharmony_ci inode->i_op = &page_symlink_inode_operations; 4158c2ecf20Sopenharmony_ci inode_nohighmem(inode); 4168c2ecf20Sopenharmony_ci inode->i_mapping->a_ops = &hfsplus_aops; 4178c2ecf20Sopenharmony_ci hip->clump_blocks = 1; 4188c2ecf20Sopenharmony_ci } else 4198c2ecf20Sopenharmony_ci sbi->file_count++; 4208c2ecf20Sopenharmony_ci insert_inode_hash(inode); 4218c2ecf20Sopenharmony_ci mark_inode_dirty(inode); 4228c2ecf20Sopenharmony_ci hfsplus_mark_mdb_dirty(sb); 4238c2ecf20Sopenharmony_ci 4248c2ecf20Sopenharmony_ci return inode; 4258c2ecf20Sopenharmony_ci} 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_civoid hfsplus_delete_inode(struct inode *inode) 4288c2ecf20Sopenharmony_ci{ 4298c2ecf20Sopenharmony_ci struct super_block *sb = inode->i_sb; 4308c2ecf20Sopenharmony_ci 4318c2ecf20Sopenharmony_ci if (S_ISDIR(inode->i_mode)) { 4328c2ecf20Sopenharmony_ci HFSPLUS_SB(sb)->folder_count--; 4338c2ecf20Sopenharmony_ci hfsplus_mark_mdb_dirty(sb); 4348c2ecf20Sopenharmony_ci return; 4358c2ecf20Sopenharmony_ci } 4368c2ecf20Sopenharmony_ci HFSPLUS_SB(sb)->file_count--; 4378c2ecf20Sopenharmony_ci if (S_ISREG(inode->i_mode)) { 4388c2ecf20Sopenharmony_ci if (!inode->i_nlink) { 4398c2ecf20Sopenharmony_ci inode->i_size = 0; 4408c2ecf20Sopenharmony_ci hfsplus_file_truncate(inode); 4418c2ecf20Sopenharmony_ci } 4428c2ecf20Sopenharmony_ci } else if (S_ISLNK(inode->i_mode)) { 4438c2ecf20Sopenharmony_ci inode->i_size = 0; 4448c2ecf20Sopenharmony_ci hfsplus_file_truncate(inode); 4458c2ecf20Sopenharmony_ci } 4468c2ecf20Sopenharmony_ci hfsplus_mark_mdb_dirty(sb); 4478c2ecf20Sopenharmony_ci} 4488c2ecf20Sopenharmony_ci 4498c2ecf20Sopenharmony_civoid hfsplus_inode_read_fork(struct inode *inode, struct hfsplus_fork_raw *fork) 4508c2ecf20Sopenharmony_ci{ 4518c2ecf20Sopenharmony_ci struct super_block *sb = inode->i_sb; 4528c2ecf20Sopenharmony_ci struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); 4538c2ecf20Sopenharmony_ci struct hfsplus_inode_info *hip = HFSPLUS_I(inode); 4548c2ecf20Sopenharmony_ci u32 count; 4558c2ecf20Sopenharmony_ci int i; 4568c2ecf20Sopenharmony_ci 4578c2ecf20Sopenharmony_ci memcpy(&hip->first_extents, &fork->extents, sizeof(hfsplus_extent_rec)); 4588c2ecf20Sopenharmony_ci for (count = 0, i = 0; i < 8; i++) 4598c2ecf20Sopenharmony_ci count += be32_to_cpu(fork->extents[i].block_count); 4608c2ecf20Sopenharmony_ci hip->first_blocks = count; 4618c2ecf20Sopenharmony_ci memset(hip->cached_extents, 0, sizeof(hfsplus_extent_rec)); 4628c2ecf20Sopenharmony_ci hip->cached_start = 0; 4638c2ecf20Sopenharmony_ci hip->cached_blocks = 0; 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_ci hip->alloc_blocks = be32_to_cpu(fork->total_blocks); 4668c2ecf20Sopenharmony_ci hip->phys_size = inode->i_size = be64_to_cpu(fork->total_size); 4678c2ecf20Sopenharmony_ci hip->fs_blocks = 4688c2ecf20Sopenharmony_ci (inode->i_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits; 4698c2ecf20Sopenharmony_ci inode_set_bytes(inode, hip->fs_blocks << sb->s_blocksize_bits); 4708c2ecf20Sopenharmony_ci hip->clump_blocks = 4718c2ecf20Sopenharmony_ci be32_to_cpu(fork->clump_size) >> sbi->alloc_blksz_shift; 4728c2ecf20Sopenharmony_ci if (!hip->clump_blocks) { 4738c2ecf20Sopenharmony_ci hip->clump_blocks = HFSPLUS_IS_RSRC(inode) ? 4748c2ecf20Sopenharmony_ci sbi->rsrc_clump_blocks : 4758c2ecf20Sopenharmony_ci sbi->data_clump_blocks; 4768c2ecf20Sopenharmony_ci } 4778c2ecf20Sopenharmony_ci} 4788c2ecf20Sopenharmony_ci 4798c2ecf20Sopenharmony_civoid hfsplus_inode_write_fork(struct inode *inode, 4808c2ecf20Sopenharmony_ci struct hfsplus_fork_raw *fork) 4818c2ecf20Sopenharmony_ci{ 4828c2ecf20Sopenharmony_ci memcpy(&fork->extents, &HFSPLUS_I(inode)->first_extents, 4838c2ecf20Sopenharmony_ci sizeof(hfsplus_extent_rec)); 4848c2ecf20Sopenharmony_ci fork->total_size = cpu_to_be64(inode->i_size); 4858c2ecf20Sopenharmony_ci fork->total_blocks = cpu_to_be32(HFSPLUS_I(inode)->alloc_blocks); 4868c2ecf20Sopenharmony_ci} 4878c2ecf20Sopenharmony_ci 4888c2ecf20Sopenharmony_ciint hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) 4898c2ecf20Sopenharmony_ci{ 4908c2ecf20Sopenharmony_ci hfsplus_cat_entry entry; 4918c2ecf20Sopenharmony_ci int res = 0; 4928c2ecf20Sopenharmony_ci u16 type; 4938c2ecf20Sopenharmony_ci 4948c2ecf20Sopenharmony_ci type = hfs_bnode_read_u16(fd->bnode, fd->entryoffset); 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_ci HFSPLUS_I(inode)->linkid = 0; 4978c2ecf20Sopenharmony_ci if (type == HFSPLUS_FOLDER) { 4988c2ecf20Sopenharmony_ci struct hfsplus_cat_folder *folder = &entry.folder; 4998c2ecf20Sopenharmony_ci 5008c2ecf20Sopenharmony_ci if (fd->entrylength < sizeof(struct hfsplus_cat_folder)) { 5018c2ecf20Sopenharmony_ci pr_err("bad catalog folder entry\n"); 5028c2ecf20Sopenharmony_ci res = -EIO; 5038c2ecf20Sopenharmony_ci goto out; 5048c2ecf20Sopenharmony_ci } 5058c2ecf20Sopenharmony_ci hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, 5068c2ecf20Sopenharmony_ci sizeof(struct hfsplus_cat_folder)); 5078c2ecf20Sopenharmony_ci hfsplus_get_perms(inode, &folder->permissions, 1); 5088c2ecf20Sopenharmony_ci set_nlink(inode, 1); 5098c2ecf20Sopenharmony_ci inode->i_size = 2 + be32_to_cpu(folder->valence); 5108c2ecf20Sopenharmony_ci inode->i_atime = hfsp_mt2ut(folder->access_date); 5118c2ecf20Sopenharmony_ci inode->i_mtime = hfsp_mt2ut(folder->content_mod_date); 5128c2ecf20Sopenharmony_ci inode->i_ctime = hfsp_mt2ut(folder->attribute_mod_date); 5138c2ecf20Sopenharmony_ci HFSPLUS_I(inode)->create_date = folder->create_date; 5148c2ecf20Sopenharmony_ci HFSPLUS_I(inode)->fs_blocks = 0; 5158c2ecf20Sopenharmony_ci if (folder->flags & cpu_to_be16(HFSPLUS_HAS_FOLDER_COUNT)) { 5168c2ecf20Sopenharmony_ci HFSPLUS_I(inode)->subfolders = 5178c2ecf20Sopenharmony_ci be32_to_cpu(folder->subfolders); 5188c2ecf20Sopenharmony_ci } 5198c2ecf20Sopenharmony_ci inode->i_op = &hfsplus_dir_inode_operations; 5208c2ecf20Sopenharmony_ci inode->i_fop = &hfsplus_dir_operations; 5218c2ecf20Sopenharmony_ci } else if (type == HFSPLUS_FILE) { 5228c2ecf20Sopenharmony_ci struct hfsplus_cat_file *file = &entry.file; 5238c2ecf20Sopenharmony_ci 5248c2ecf20Sopenharmony_ci if (fd->entrylength < sizeof(struct hfsplus_cat_file)) { 5258c2ecf20Sopenharmony_ci pr_err("bad catalog file entry\n"); 5268c2ecf20Sopenharmony_ci res = -EIO; 5278c2ecf20Sopenharmony_ci goto out; 5288c2ecf20Sopenharmony_ci } 5298c2ecf20Sopenharmony_ci hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, 5308c2ecf20Sopenharmony_ci sizeof(struct hfsplus_cat_file)); 5318c2ecf20Sopenharmony_ci 5328c2ecf20Sopenharmony_ci hfsplus_inode_read_fork(inode, HFSPLUS_IS_RSRC(inode) ? 5338c2ecf20Sopenharmony_ci &file->rsrc_fork : &file->data_fork); 5348c2ecf20Sopenharmony_ci hfsplus_get_perms(inode, &file->permissions, 0); 5358c2ecf20Sopenharmony_ci set_nlink(inode, 1); 5368c2ecf20Sopenharmony_ci if (S_ISREG(inode->i_mode)) { 5378c2ecf20Sopenharmony_ci if (file->permissions.dev) 5388c2ecf20Sopenharmony_ci set_nlink(inode, 5398c2ecf20Sopenharmony_ci be32_to_cpu(file->permissions.dev)); 5408c2ecf20Sopenharmony_ci inode->i_op = &hfsplus_file_inode_operations; 5418c2ecf20Sopenharmony_ci inode->i_fop = &hfsplus_file_operations; 5428c2ecf20Sopenharmony_ci inode->i_mapping->a_ops = &hfsplus_aops; 5438c2ecf20Sopenharmony_ci } else if (S_ISLNK(inode->i_mode)) { 5448c2ecf20Sopenharmony_ci inode->i_op = &page_symlink_inode_operations; 5458c2ecf20Sopenharmony_ci inode_nohighmem(inode); 5468c2ecf20Sopenharmony_ci inode->i_mapping->a_ops = &hfsplus_aops; 5478c2ecf20Sopenharmony_ci } else { 5488c2ecf20Sopenharmony_ci init_special_inode(inode, inode->i_mode, 5498c2ecf20Sopenharmony_ci be32_to_cpu(file->permissions.dev)); 5508c2ecf20Sopenharmony_ci } 5518c2ecf20Sopenharmony_ci inode->i_atime = hfsp_mt2ut(file->access_date); 5528c2ecf20Sopenharmony_ci inode->i_mtime = hfsp_mt2ut(file->content_mod_date); 5538c2ecf20Sopenharmony_ci inode->i_ctime = hfsp_mt2ut(file->attribute_mod_date); 5548c2ecf20Sopenharmony_ci HFSPLUS_I(inode)->create_date = file->create_date; 5558c2ecf20Sopenharmony_ci } else { 5568c2ecf20Sopenharmony_ci pr_err("bad catalog entry used to create inode\n"); 5578c2ecf20Sopenharmony_ci res = -EIO; 5588c2ecf20Sopenharmony_ci } 5598c2ecf20Sopenharmony_ciout: 5608c2ecf20Sopenharmony_ci return res; 5618c2ecf20Sopenharmony_ci} 5628c2ecf20Sopenharmony_ci 5638c2ecf20Sopenharmony_ciint hfsplus_cat_write_inode(struct inode *inode) 5648c2ecf20Sopenharmony_ci{ 5658c2ecf20Sopenharmony_ci struct inode *main_inode = inode; 5668c2ecf20Sopenharmony_ci struct hfs_find_data fd; 5678c2ecf20Sopenharmony_ci hfsplus_cat_entry entry; 5688c2ecf20Sopenharmony_ci int res = 0; 5698c2ecf20Sopenharmony_ci 5708c2ecf20Sopenharmony_ci if (HFSPLUS_IS_RSRC(inode)) 5718c2ecf20Sopenharmony_ci main_inode = HFSPLUS_I(inode)->rsrc_inode; 5728c2ecf20Sopenharmony_ci 5738c2ecf20Sopenharmony_ci if (!main_inode->i_nlink) 5748c2ecf20Sopenharmony_ci return 0; 5758c2ecf20Sopenharmony_ci 5768c2ecf20Sopenharmony_ci if (hfs_find_init(HFSPLUS_SB(main_inode->i_sb)->cat_tree, &fd)) 5778c2ecf20Sopenharmony_ci /* panic? */ 5788c2ecf20Sopenharmony_ci return -EIO; 5798c2ecf20Sopenharmony_ci 5808c2ecf20Sopenharmony_ci if (hfsplus_find_cat(main_inode->i_sb, main_inode->i_ino, &fd)) 5818c2ecf20Sopenharmony_ci /* panic? */ 5828c2ecf20Sopenharmony_ci goto out; 5838c2ecf20Sopenharmony_ci 5848c2ecf20Sopenharmony_ci if (S_ISDIR(main_inode->i_mode)) { 5858c2ecf20Sopenharmony_ci struct hfsplus_cat_folder *folder = &entry.folder; 5868c2ecf20Sopenharmony_ci 5878c2ecf20Sopenharmony_ci if (fd.entrylength < sizeof(struct hfsplus_cat_folder)) { 5888c2ecf20Sopenharmony_ci pr_err("bad catalog folder entry\n"); 5898c2ecf20Sopenharmony_ci res = -EIO; 5908c2ecf20Sopenharmony_ci goto out; 5918c2ecf20Sopenharmony_ci } 5928c2ecf20Sopenharmony_ci hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, 5938c2ecf20Sopenharmony_ci sizeof(struct hfsplus_cat_folder)); 5948c2ecf20Sopenharmony_ci /* simple node checks? */ 5958c2ecf20Sopenharmony_ci hfsplus_cat_set_perms(inode, &folder->permissions); 5968c2ecf20Sopenharmony_ci folder->access_date = hfsp_ut2mt(inode->i_atime); 5978c2ecf20Sopenharmony_ci folder->content_mod_date = hfsp_ut2mt(inode->i_mtime); 5988c2ecf20Sopenharmony_ci folder->attribute_mod_date = hfsp_ut2mt(inode->i_ctime); 5998c2ecf20Sopenharmony_ci folder->valence = cpu_to_be32(inode->i_size - 2); 6008c2ecf20Sopenharmony_ci if (folder->flags & cpu_to_be16(HFSPLUS_HAS_FOLDER_COUNT)) { 6018c2ecf20Sopenharmony_ci folder->subfolders = 6028c2ecf20Sopenharmony_ci cpu_to_be32(HFSPLUS_I(inode)->subfolders); 6038c2ecf20Sopenharmony_ci } 6048c2ecf20Sopenharmony_ci hfs_bnode_write(fd.bnode, &entry, fd.entryoffset, 6058c2ecf20Sopenharmony_ci sizeof(struct hfsplus_cat_folder)); 6068c2ecf20Sopenharmony_ci } else if (HFSPLUS_IS_RSRC(inode)) { 6078c2ecf20Sopenharmony_ci struct hfsplus_cat_file *file = &entry.file; 6088c2ecf20Sopenharmony_ci hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, 6098c2ecf20Sopenharmony_ci sizeof(struct hfsplus_cat_file)); 6108c2ecf20Sopenharmony_ci hfsplus_inode_write_fork(inode, &file->rsrc_fork); 6118c2ecf20Sopenharmony_ci hfs_bnode_write(fd.bnode, &entry, fd.entryoffset, 6128c2ecf20Sopenharmony_ci sizeof(struct hfsplus_cat_file)); 6138c2ecf20Sopenharmony_ci } else { 6148c2ecf20Sopenharmony_ci struct hfsplus_cat_file *file = &entry.file; 6158c2ecf20Sopenharmony_ci 6168c2ecf20Sopenharmony_ci if (fd.entrylength < sizeof(struct hfsplus_cat_file)) { 6178c2ecf20Sopenharmony_ci pr_err("bad catalog file entry\n"); 6188c2ecf20Sopenharmony_ci res = -EIO; 6198c2ecf20Sopenharmony_ci goto out; 6208c2ecf20Sopenharmony_ci } 6218c2ecf20Sopenharmony_ci hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, 6228c2ecf20Sopenharmony_ci sizeof(struct hfsplus_cat_file)); 6238c2ecf20Sopenharmony_ci hfsplus_inode_write_fork(inode, &file->data_fork); 6248c2ecf20Sopenharmony_ci hfsplus_cat_set_perms(inode, &file->permissions); 6258c2ecf20Sopenharmony_ci if (HFSPLUS_FLG_IMMUTABLE & 6268c2ecf20Sopenharmony_ci (file->permissions.rootflags | 6278c2ecf20Sopenharmony_ci file->permissions.userflags)) 6288c2ecf20Sopenharmony_ci file->flags |= cpu_to_be16(HFSPLUS_FILE_LOCKED); 6298c2ecf20Sopenharmony_ci else 6308c2ecf20Sopenharmony_ci file->flags &= cpu_to_be16(~HFSPLUS_FILE_LOCKED); 6318c2ecf20Sopenharmony_ci file->access_date = hfsp_ut2mt(inode->i_atime); 6328c2ecf20Sopenharmony_ci file->content_mod_date = hfsp_ut2mt(inode->i_mtime); 6338c2ecf20Sopenharmony_ci file->attribute_mod_date = hfsp_ut2mt(inode->i_ctime); 6348c2ecf20Sopenharmony_ci hfs_bnode_write(fd.bnode, &entry, fd.entryoffset, 6358c2ecf20Sopenharmony_ci sizeof(struct hfsplus_cat_file)); 6368c2ecf20Sopenharmony_ci } 6378c2ecf20Sopenharmony_ci 6388c2ecf20Sopenharmony_ci set_bit(HFSPLUS_I_CAT_DIRTY, &HFSPLUS_I(inode)->flags); 6398c2ecf20Sopenharmony_ciout: 6408c2ecf20Sopenharmony_ci hfs_find_exit(&fd); 6418c2ecf20Sopenharmony_ci return res; 6428c2ecf20Sopenharmony_ci} 643