18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2007 Oracle. All rights reserved. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#ifndef BTRFS_INODE_H 78c2ecf20Sopenharmony_ci#define BTRFS_INODE_H 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/hash.h> 108c2ecf20Sopenharmony_ci#include <linux/refcount.h> 118c2ecf20Sopenharmony_ci#include "extent_map.h" 128c2ecf20Sopenharmony_ci#include "extent_io.h" 138c2ecf20Sopenharmony_ci#include "ordered-data.h" 148c2ecf20Sopenharmony_ci#include "delayed-inode.h" 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci/* 178c2ecf20Sopenharmony_ci * ordered_data_close is set by truncate when a file that used 188c2ecf20Sopenharmony_ci * to have good data has been truncated to zero. When it is set 198c2ecf20Sopenharmony_ci * the btrfs file release call will add this inode to the 208c2ecf20Sopenharmony_ci * ordered operations list so that we make sure to flush out any 218c2ecf20Sopenharmony_ci * new data the application may have written before commit. 228c2ecf20Sopenharmony_ci */ 238c2ecf20Sopenharmony_cienum { 248c2ecf20Sopenharmony_ci BTRFS_INODE_FLUSH_ON_CLOSE, 258c2ecf20Sopenharmony_ci BTRFS_INODE_DUMMY, 268c2ecf20Sopenharmony_ci BTRFS_INODE_IN_DEFRAG, 278c2ecf20Sopenharmony_ci BTRFS_INODE_HAS_ASYNC_EXTENT, 288c2ecf20Sopenharmony_ci /* 298c2ecf20Sopenharmony_ci * Always set under the VFS' inode lock, otherwise it can cause races 308c2ecf20Sopenharmony_ci * during fsync (we start as a fast fsync and then end up in a full 318c2ecf20Sopenharmony_ci * fsync racing with ordered extent completion). 328c2ecf20Sopenharmony_ci */ 338c2ecf20Sopenharmony_ci BTRFS_INODE_NEEDS_FULL_SYNC, 348c2ecf20Sopenharmony_ci BTRFS_INODE_COPY_EVERYTHING, 358c2ecf20Sopenharmony_ci BTRFS_INODE_IN_DELALLOC_LIST, 368c2ecf20Sopenharmony_ci BTRFS_INODE_HAS_PROPS, 378c2ecf20Sopenharmony_ci BTRFS_INODE_SNAPSHOT_FLUSH, 388c2ecf20Sopenharmony_ci /* 398c2ecf20Sopenharmony_ci * Set and used when logging an inode and it serves to signal that an 408c2ecf20Sopenharmony_ci * inode does not have xattrs, so subsequent fsyncs can avoid searching 418c2ecf20Sopenharmony_ci * for xattrs to log. This bit must be cleared whenever a xattr is added 428c2ecf20Sopenharmony_ci * to an inode. 438c2ecf20Sopenharmony_ci */ 448c2ecf20Sopenharmony_ci BTRFS_INODE_NO_XATTRS, 458c2ecf20Sopenharmony_ci /* 468c2ecf20Sopenharmony_ci * Set when we are in a context where we need to start a transaction and 478c2ecf20Sopenharmony_ci * have dirty pages with the respective file range locked. This is to 488c2ecf20Sopenharmony_ci * ensure that when reserving space for the transaction, if we are low 498c2ecf20Sopenharmony_ci * on available space and need to flush delalloc, we will not flush 508c2ecf20Sopenharmony_ci * delalloc for this inode, because that could result in a deadlock (on 518c2ecf20Sopenharmony_ci * the file range, inode's io_tree). 528c2ecf20Sopenharmony_ci */ 538c2ecf20Sopenharmony_ci BTRFS_INODE_NO_DELALLOC_FLUSH, 548c2ecf20Sopenharmony_ci}; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci/* in memory btrfs inode */ 578c2ecf20Sopenharmony_cistruct btrfs_inode { 588c2ecf20Sopenharmony_ci /* which subvolume this inode belongs to */ 598c2ecf20Sopenharmony_ci struct btrfs_root *root; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci /* key used to find this inode on disk. This is used by the code 628c2ecf20Sopenharmony_ci * to read in roots of subvolumes 638c2ecf20Sopenharmony_ci */ 648c2ecf20Sopenharmony_ci struct btrfs_key location; 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci /* 678c2ecf20Sopenharmony_ci * Lock for counters and all fields used to determine if the inode is in 688c2ecf20Sopenharmony_ci * the log or not (last_trans, last_sub_trans, last_log_commit, 698c2ecf20Sopenharmony_ci * logged_trans). 708c2ecf20Sopenharmony_ci */ 718c2ecf20Sopenharmony_ci spinlock_t lock; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci /* the extent_tree has caches of all the extent mappings to disk */ 748c2ecf20Sopenharmony_ci struct extent_map_tree extent_tree; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci /* the io_tree does range state (DIRTY, LOCKED etc) */ 778c2ecf20Sopenharmony_ci struct extent_io_tree io_tree; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci /* special utility tree used to record which mirrors have already been 808c2ecf20Sopenharmony_ci * tried when checksums fail for a given block 818c2ecf20Sopenharmony_ci */ 828c2ecf20Sopenharmony_ci struct extent_io_tree io_failure_tree; 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci /* 858c2ecf20Sopenharmony_ci * Keep track of where the inode has extent items mapped in order to 868c2ecf20Sopenharmony_ci * make sure the i_size adjustments are accurate 878c2ecf20Sopenharmony_ci */ 888c2ecf20Sopenharmony_ci struct extent_io_tree file_extent_tree; 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci /* held while logging the inode in tree-log.c */ 918c2ecf20Sopenharmony_ci struct mutex log_mutex; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci /* used to order data wrt metadata */ 948c2ecf20Sopenharmony_ci struct btrfs_ordered_inode_tree ordered_tree; 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci /* list of all the delalloc inodes in the FS. There are times we need 978c2ecf20Sopenharmony_ci * to write all the delalloc pages to disk, and this list is used 988c2ecf20Sopenharmony_ci * to walk them all. 998c2ecf20Sopenharmony_ci */ 1008c2ecf20Sopenharmony_ci struct list_head delalloc_inodes; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci /* node for the red-black tree that links inodes in subvolume root */ 1038c2ecf20Sopenharmony_ci struct rb_node rb_node; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci unsigned long runtime_flags; 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci /* Keep track of who's O_SYNC/fsyncing currently */ 1088c2ecf20Sopenharmony_ci atomic_t sync_writers; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci /* full 64 bit generation number, struct vfs_inode doesn't have a big 1118c2ecf20Sopenharmony_ci * enough field for this. 1128c2ecf20Sopenharmony_ci */ 1138c2ecf20Sopenharmony_ci u64 generation; 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci /* 1168c2ecf20Sopenharmony_ci * transid of the trans_handle that last modified this inode 1178c2ecf20Sopenharmony_ci */ 1188c2ecf20Sopenharmony_ci u64 last_trans; 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci /* 1218c2ecf20Sopenharmony_ci * transid that last logged this inode 1228c2ecf20Sopenharmony_ci */ 1238c2ecf20Sopenharmony_ci u64 logged_trans; 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci /* 1268c2ecf20Sopenharmony_ci * log transid when this inode was last modified 1278c2ecf20Sopenharmony_ci */ 1288c2ecf20Sopenharmony_ci int last_sub_trans; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci /* a local copy of root's last_log_commit */ 1318c2ecf20Sopenharmony_ci int last_log_commit; 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci /* total number of bytes pending delalloc, used by stat to calc the 1348c2ecf20Sopenharmony_ci * real block usage of the file 1358c2ecf20Sopenharmony_ci */ 1368c2ecf20Sopenharmony_ci u64 delalloc_bytes; 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci /* 1398c2ecf20Sopenharmony_ci * Total number of bytes pending delalloc that fall within a file 1408c2ecf20Sopenharmony_ci * range that is either a hole or beyond EOF (and no prealloc extent 1418c2ecf20Sopenharmony_ci * exists in the range). This is always <= delalloc_bytes. 1428c2ecf20Sopenharmony_ci */ 1438c2ecf20Sopenharmony_ci u64 new_delalloc_bytes; 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci /* 1468c2ecf20Sopenharmony_ci * total number of bytes pending defrag, used by stat to check whether 1478c2ecf20Sopenharmony_ci * it needs COW. 1488c2ecf20Sopenharmony_ci */ 1498c2ecf20Sopenharmony_ci u64 defrag_bytes; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci /* 1528c2ecf20Sopenharmony_ci * the size of the file stored in the metadata on disk. data=ordered 1538c2ecf20Sopenharmony_ci * means the in-memory i_size might be larger than the size on disk 1548c2ecf20Sopenharmony_ci * because not all the blocks are written yet. 1558c2ecf20Sopenharmony_ci */ 1568c2ecf20Sopenharmony_ci u64 disk_i_size; 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci /* 1598c2ecf20Sopenharmony_ci * if this is a directory then index_cnt is the counter for the index 1608c2ecf20Sopenharmony_ci * number for new files that are created 1618c2ecf20Sopenharmony_ci */ 1628c2ecf20Sopenharmony_ci u64 index_cnt; 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci /* Cache the directory index number to speed the dir/file remove */ 1658c2ecf20Sopenharmony_ci u64 dir_index; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci /* the fsync log has some corner cases that mean we have to check 1688c2ecf20Sopenharmony_ci * directories to see if any unlinks have been done before 1698c2ecf20Sopenharmony_ci * the directory was logged. See tree-log.c for all the 1708c2ecf20Sopenharmony_ci * details 1718c2ecf20Sopenharmony_ci */ 1728c2ecf20Sopenharmony_ci u64 last_unlink_trans; 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci /* 1758c2ecf20Sopenharmony_ci * The id/generation of the last transaction where this inode was 1768c2ecf20Sopenharmony_ci * either the source or the destination of a clone/dedupe operation. 1778c2ecf20Sopenharmony_ci * Used when logging an inode to know if there are shared extents that 1788c2ecf20Sopenharmony_ci * need special care when logging checksum items, to avoid duplicate 1798c2ecf20Sopenharmony_ci * checksum items in a log (which can lead to a corruption where we end 1808c2ecf20Sopenharmony_ci * up with missing checksum ranges after log replay). 1818c2ecf20Sopenharmony_ci * Protected by the vfs inode lock. 1828c2ecf20Sopenharmony_ci */ 1838c2ecf20Sopenharmony_ci u64 last_reflink_trans; 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci /* 1868c2ecf20Sopenharmony_ci * Number of bytes outstanding that are going to need csums. This is 1878c2ecf20Sopenharmony_ci * used in ENOSPC accounting. 1888c2ecf20Sopenharmony_ci */ 1898c2ecf20Sopenharmony_ci u64 csum_bytes; 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci /* flags field from the on disk inode */ 1928c2ecf20Sopenharmony_ci u32 flags; 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci /* 1958c2ecf20Sopenharmony_ci * Counters to keep track of the number of extent item's we may use due 1968c2ecf20Sopenharmony_ci * to delalloc and such. outstanding_extents is the number of extent 1978c2ecf20Sopenharmony_ci * items we think we'll end up using, and reserved_extents is the number 1988c2ecf20Sopenharmony_ci * of extent items we've reserved metadata for. 1998c2ecf20Sopenharmony_ci */ 2008c2ecf20Sopenharmony_ci unsigned outstanding_extents; 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ci struct btrfs_block_rsv block_rsv; 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci /* 2058c2ecf20Sopenharmony_ci * Cached values of inode properties 2068c2ecf20Sopenharmony_ci */ 2078c2ecf20Sopenharmony_ci unsigned prop_compress; /* per-file compression algorithm */ 2088c2ecf20Sopenharmony_ci /* 2098c2ecf20Sopenharmony_ci * Force compression on the file using the defrag ioctl, could be 2108c2ecf20Sopenharmony_ci * different from prop_compress and takes precedence if set 2118c2ecf20Sopenharmony_ci */ 2128c2ecf20Sopenharmony_ci unsigned defrag_compress; 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci struct btrfs_delayed_node *delayed_node; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci /* File creation time. */ 2178c2ecf20Sopenharmony_ci struct timespec64 i_otime; 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci /* Hook into fs_info->delayed_iputs */ 2208c2ecf20Sopenharmony_ci struct list_head delayed_iput; 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci /* 2238c2ecf20Sopenharmony_ci * To avoid races between lockless (i_mutex not held) direct IO writes 2248c2ecf20Sopenharmony_ci * and concurrent fsync requests. Direct IO writes must acquire read 2258c2ecf20Sopenharmony_ci * access on this semaphore for creating an extent map and its 2268c2ecf20Sopenharmony_ci * corresponding ordered extent. The fast fsync path must acquire write 2278c2ecf20Sopenharmony_ci * access on this semaphore before it collects ordered extents and 2288c2ecf20Sopenharmony_ci * extent maps. 2298c2ecf20Sopenharmony_ci */ 2308c2ecf20Sopenharmony_ci struct rw_semaphore dio_sem; 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci struct inode vfs_inode; 2338c2ecf20Sopenharmony_ci}; 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_cistatic inline u32 btrfs_inode_sectorsize(const struct btrfs_inode *inode) 2368c2ecf20Sopenharmony_ci{ 2378c2ecf20Sopenharmony_ci return inode->root->fs_info->sectorsize; 2388c2ecf20Sopenharmony_ci} 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_cistatic inline struct btrfs_inode *BTRFS_I(const struct inode *inode) 2418c2ecf20Sopenharmony_ci{ 2428c2ecf20Sopenharmony_ci return container_of(inode, struct btrfs_inode, vfs_inode); 2438c2ecf20Sopenharmony_ci} 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_cistatic inline unsigned long btrfs_inode_hash(u64 objectid, 2468c2ecf20Sopenharmony_ci const struct btrfs_root *root) 2478c2ecf20Sopenharmony_ci{ 2488c2ecf20Sopenharmony_ci u64 h = objectid ^ (root->root_key.objectid * GOLDEN_RATIO_PRIME); 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci#if BITS_PER_LONG == 32 2518c2ecf20Sopenharmony_ci h = (h >> 32) ^ (h & 0xffffffff); 2528c2ecf20Sopenharmony_ci#endif 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci return (unsigned long)h; 2558c2ecf20Sopenharmony_ci} 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_cistatic inline void btrfs_insert_inode_hash(struct inode *inode) 2588c2ecf20Sopenharmony_ci{ 2598c2ecf20Sopenharmony_ci unsigned long h = btrfs_inode_hash(inode->i_ino, BTRFS_I(inode)->root); 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci __insert_inode_hash(inode, h); 2628c2ecf20Sopenharmony_ci} 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_cistatic inline u64 btrfs_ino(const struct btrfs_inode *inode) 2658c2ecf20Sopenharmony_ci{ 2668c2ecf20Sopenharmony_ci u64 ino = inode->location.objectid; 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci /* 2698c2ecf20Sopenharmony_ci * !ino: btree_inode 2708c2ecf20Sopenharmony_ci * type == BTRFS_ROOT_ITEM_KEY: subvol dir 2718c2ecf20Sopenharmony_ci */ 2728c2ecf20Sopenharmony_ci if (!ino || inode->location.type == BTRFS_ROOT_ITEM_KEY) 2738c2ecf20Sopenharmony_ci ino = inode->vfs_inode.i_ino; 2748c2ecf20Sopenharmony_ci return ino; 2758c2ecf20Sopenharmony_ci} 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_cistatic inline void btrfs_i_size_write(struct btrfs_inode *inode, u64 size) 2788c2ecf20Sopenharmony_ci{ 2798c2ecf20Sopenharmony_ci i_size_write(&inode->vfs_inode, size); 2808c2ecf20Sopenharmony_ci inode->disk_i_size = size; 2818c2ecf20Sopenharmony_ci} 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_cistatic inline bool btrfs_is_free_space_inode(struct btrfs_inode *inode) 2848c2ecf20Sopenharmony_ci{ 2858c2ecf20Sopenharmony_ci struct btrfs_root *root = inode->root; 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci if (root == root->fs_info->tree_root && 2888c2ecf20Sopenharmony_ci btrfs_ino(inode) != BTRFS_BTREE_INODE_OBJECTID) 2898c2ecf20Sopenharmony_ci return true; 2908c2ecf20Sopenharmony_ci if (inode->location.objectid == BTRFS_FREE_INO_OBJECTID) 2918c2ecf20Sopenharmony_ci return true; 2928c2ecf20Sopenharmony_ci return false; 2938c2ecf20Sopenharmony_ci} 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_cistatic inline bool is_data_inode(struct inode *inode) 2968c2ecf20Sopenharmony_ci{ 2978c2ecf20Sopenharmony_ci return btrfs_ino(BTRFS_I(inode)) != BTRFS_BTREE_INODE_OBJECTID; 2988c2ecf20Sopenharmony_ci} 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_cistatic inline void btrfs_mod_outstanding_extents(struct btrfs_inode *inode, 3018c2ecf20Sopenharmony_ci int mod) 3028c2ecf20Sopenharmony_ci{ 3038c2ecf20Sopenharmony_ci lockdep_assert_held(&inode->lock); 3048c2ecf20Sopenharmony_ci inode->outstanding_extents += mod; 3058c2ecf20Sopenharmony_ci if (btrfs_is_free_space_inode(inode)) 3068c2ecf20Sopenharmony_ci return; 3078c2ecf20Sopenharmony_ci trace_btrfs_inode_mod_outstanding_extents(inode->root, btrfs_ino(inode), 3088c2ecf20Sopenharmony_ci mod); 3098c2ecf20Sopenharmony_ci} 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci/* 3128c2ecf20Sopenharmony_ci * Called every time after doing a buffered, direct IO or memory mapped write. 3138c2ecf20Sopenharmony_ci * 3148c2ecf20Sopenharmony_ci * This is to ensure that if we write to a file that was previously fsynced in 3158c2ecf20Sopenharmony_ci * the current transaction, then try to fsync it again in the same transaction, 3168c2ecf20Sopenharmony_ci * we will know that there were changes in the file and that it needs to be 3178c2ecf20Sopenharmony_ci * logged. 3188c2ecf20Sopenharmony_ci */ 3198c2ecf20Sopenharmony_cistatic inline void btrfs_set_inode_last_sub_trans(struct btrfs_inode *inode) 3208c2ecf20Sopenharmony_ci{ 3218c2ecf20Sopenharmony_ci spin_lock(&inode->lock); 3228c2ecf20Sopenharmony_ci inode->last_sub_trans = inode->root->log_transid; 3238c2ecf20Sopenharmony_ci spin_unlock(&inode->lock); 3248c2ecf20Sopenharmony_ci} 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_cistatic inline int btrfs_inode_in_log(struct btrfs_inode *inode, u64 generation) 3278c2ecf20Sopenharmony_ci{ 3288c2ecf20Sopenharmony_ci int ret = 0; 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ci spin_lock(&inode->lock); 3318c2ecf20Sopenharmony_ci if (inode->logged_trans == generation && 3328c2ecf20Sopenharmony_ci inode->last_sub_trans <= inode->last_log_commit && 3338c2ecf20Sopenharmony_ci inode->last_sub_trans <= inode->root->last_log_commit) { 3348c2ecf20Sopenharmony_ci /* 3358c2ecf20Sopenharmony_ci * After a ranged fsync we might have left some extent maps 3368c2ecf20Sopenharmony_ci * (that fall outside the fsync's range). So return false 3378c2ecf20Sopenharmony_ci * here if the list isn't empty, to make sure btrfs_log_inode() 3388c2ecf20Sopenharmony_ci * will be called and process those extent maps. 3398c2ecf20Sopenharmony_ci */ 3408c2ecf20Sopenharmony_ci smp_mb(); 3418c2ecf20Sopenharmony_ci if (list_empty(&inode->extent_tree.modified_extents)) 3428c2ecf20Sopenharmony_ci ret = 1; 3438c2ecf20Sopenharmony_ci } 3448c2ecf20Sopenharmony_ci spin_unlock(&inode->lock); 3458c2ecf20Sopenharmony_ci return ret; 3468c2ecf20Sopenharmony_ci} 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_cistruct btrfs_dio_private { 3498c2ecf20Sopenharmony_ci struct inode *inode; 3508c2ecf20Sopenharmony_ci u64 logical_offset; 3518c2ecf20Sopenharmony_ci u64 disk_bytenr; 3528c2ecf20Sopenharmony_ci u64 bytes; 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ci /* 3558c2ecf20Sopenharmony_ci * References to this structure. There is one reference per in-flight 3568c2ecf20Sopenharmony_ci * bio plus one while we're still setting up. 3578c2ecf20Sopenharmony_ci */ 3588c2ecf20Sopenharmony_ci refcount_t refs; 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci /* dio_bio came from fs/direct-io.c */ 3618c2ecf20Sopenharmony_ci struct bio *dio_bio; 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_ci /* Array of checksums */ 3648c2ecf20Sopenharmony_ci u8 csums[]; 3658c2ecf20Sopenharmony_ci}; 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_ci/* Array of bytes with variable length, hexadecimal format 0x1234 */ 3688c2ecf20Sopenharmony_ci#define CSUM_FMT "0x%*phN" 3698c2ecf20Sopenharmony_ci#define CSUM_FMT_VALUE(size, bytes) size, bytes 3708c2ecf20Sopenharmony_ci 3718c2ecf20Sopenharmony_cistatic inline void btrfs_print_data_csum_error(struct btrfs_inode *inode, 3728c2ecf20Sopenharmony_ci u64 logical_start, u8 *csum, u8 *csum_expected, int mirror_num) 3738c2ecf20Sopenharmony_ci{ 3748c2ecf20Sopenharmony_ci struct btrfs_root *root = inode->root; 3758c2ecf20Sopenharmony_ci struct btrfs_super_block *sb = root->fs_info->super_copy; 3768c2ecf20Sopenharmony_ci const u16 csum_size = btrfs_super_csum_size(sb); 3778c2ecf20Sopenharmony_ci 3788c2ecf20Sopenharmony_ci /* Output minus objectid, which is more meaningful */ 3798c2ecf20Sopenharmony_ci if (root->root_key.objectid >= BTRFS_LAST_FREE_OBJECTID) 3808c2ecf20Sopenharmony_ci btrfs_warn_rl(root->fs_info, 3818c2ecf20Sopenharmony_ci"csum failed root %lld ino %lld off %llu csum " CSUM_FMT " expected csum " CSUM_FMT " mirror %d", 3828c2ecf20Sopenharmony_ci root->root_key.objectid, btrfs_ino(inode), 3838c2ecf20Sopenharmony_ci logical_start, 3848c2ecf20Sopenharmony_ci CSUM_FMT_VALUE(csum_size, csum), 3858c2ecf20Sopenharmony_ci CSUM_FMT_VALUE(csum_size, csum_expected), 3868c2ecf20Sopenharmony_ci mirror_num); 3878c2ecf20Sopenharmony_ci else 3888c2ecf20Sopenharmony_ci btrfs_warn_rl(root->fs_info, 3898c2ecf20Sopenharmony_ci"csum failed root %llu ino %llu off %llu csum " CSUM_FMT " expected csum " CSUM_FMT " mirror %d", 3908c2ecf20Sopenharmony_ci root->root_key.objectid, btrfs_ino(inode), 3918c2ecf20Sopenharmony_ci logical_start, 3928c2ecf20Sopenharmony_ci CSUM_FMT_VALUE(csum_size, csum), 3938c2ecf20Sopenharmony_ci CSUM_FMT_VALUE(csum_size, csum_expected), 3948c2ecf20Sopenharmony_ci mirror_num); 3958c2ecf20Sopenharmony_ci} 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_ci#endif 398