Commit 847fff5ca881670ca8ec617afeb943950f0c804b
Committed by
Lachlan McIlroy
1 parent
24ee0e49c9
Exists in
master
and in
7 other branches
[XFS] Sync up kernel and user-space headers
SGI-PV: 986558 SGI-Modid: xfs-linux-melb:xfs-kern:32231a Signed-off-by: Barry Naujok <bnaujok@sgi.com> Signed-off-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Showing 14 changed files with 383 additions and 389 deletions Inline Diff
fs/xfs/xfs_ag.h
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License as | 6 | * modify it under the terms of the GNU General Public License as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | * | 8 | * |
9 | * This program is distributed in the hope that it would be useful, | 9 | * This program is distributed in the hope that it would be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. | 12 | * GNU General Public License for more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License | 14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write the Free Software Foundation, | 15 | * along with this program; if not, write the Free Software Foundation, |
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ | 17 | */ |
18 | #ifndef __XFS_AG_H__ | 18 | #ifndef __XFS_AG_H__ |
19 | #define __XFS_AG_H__ | 19 | #define __XFS_AG_H__ |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * Allocation group header | 22 | * Allocation group header |
23 | * This is divided into three structures, placed in sequential 512-byte | 23 | * This is divided into three structures, placed in sequential 512-byte |
24 | * buffers after a copy of the superblock (also in a 512-byte buffer). | 24 | * buffers after a copy of the superblock (also in a 512-byte buffer). |
25 | */ | 25 | */ |
26 | 26 | ||
27 | struct xfs_buf; | 27 | struct xfs_buf; |
28 | struct xfs_mount; | 28 | struct xfs_mount; |
29 | struct xfs_trans; | 29 | struct xfs_trans; |
30 | 30 | ||
31 | #define XFS_AGF_MAGIC 0x58414746 /* 'XAGF' */ | 31 | #define XFS_AGF_MAGIC 0x58414746 /* 'XAGF' */ |
32 | #define XFS_AGI_MAGIC 0x58414749 /* 'XAGI' */ | 32 | #define XFS_AGI_MAGIC 0x58414749 /* 'XAGI' */ |
33 | #define XFS_AGF_VERSION 1 | 33 | #define XFS_AGF_VERSION 1 |
34 | #define XFS_AGI_VERSION 1 | 34 | #define XFS_AGI_VERSION 1 |
35 | 35 | ||
36 | #define XFS_AGF_GOOD_VERSION(v) ((v) == XFS_AGF_VERSION) | 36 | #define XFS_AGF_GOOD_VERSION(v) ((v) == XFS_AGF_VERSION) |
37 | #define XFS_AGI_GOOD_VERSION(v) ((v) == XFS_AGI_VERSION) | 37 | #define XFS_AGI_GOOD_VERSION(v) ((v) == XFS_AGI_VERSION) |
38 | 38 | ||
39 | /* | 39 | /* |
40 | * Btree number 0 is bno, 1 is cnt. This value gives the size of the | 40 | * Btree number 0 is bno, 1 is cnt. This value gives the size of the |
41 | * arrays below. | 41 | * arrays below. |
42 | */ | 42 | */ |
43 | #define XFS_BTNUM_AGF ((int)XFS_BTNUM_CNTi + 1) | 43 | #define XFS_BTNUM_AGF ((int)XFS_BTNUM_CNTi + 1) |
44 | 44 | ||
45 | /* | 45 | /* |
46 | * The second word of agf_levels in the first a.g. overlaps the EFS | 46 | * The second word of agf_levels in the first a.g. overlaps the EFS |
47 | * superblock's magic number. Since the magic numbers valid for EFS | 47 | * superblock's magic number. Since the magic numbers valid for EFS |
48 | * are > 64k, our value cannot be confused for an EFS superblock's. | 48 | * are > 64k, our value cannot be confused for an EFS superblock's. |
49 | */ | 49 | */ |
50 | 50 | ||
51 | typedef struct xfs_agf { | 51 | typedef struct xfs_agf { |
52 | /* | 52 | /* |
53 | * Common allocation group header information | 53 | * Common allocation group header information |
54 | */ | 54 | */ |
55 | __be32 agf_magicnum; /* magic number == XFS_AGF_MAGIC */ | 55 | __be32 agf_magicnum; /* magic number == XFS_AGF_MAGIC */ |
56 | __be32 agf_versionnum; /* header version == XFS_AGF_VERSION */ | 56 | __be32 agf_versionnum; /* header version == XFS_AGF_VERSION */ |
57 | __be32 agf_seqno; /* sequence # starting from 0 */ | 57 | __be32 agf_seqno; /* sequence # starting from 0 */ |
58 | __be32 agf_length; /* size in blocks of a.g. */ | 58 | __be32 agf_length; /* size in blocks of a.g. */ |
59 | /* | 59 | /* |
60 | * Freespace information | 60 | * Freespace information |
61 | */ | 61 | */ |
62 | __be32 agf_roots[XFS_BTNUM_AGF]; /* root blocks */ | 62 | __be32 agf_roots[XFS_BTNUM_AGF]; /* root blocks */ |
63 | __be32 agf_spare0; /* spare field */ | 63 | __be32 agf_spare0; /* spare field */ |
64 | __be32 agf_levels[XFS_BTNUM_AGF]; /* btree levels */ | 64 | __be32 agf_levels[XFS_BTNUM_AGF]; /* btree levels */ |
65 | __be32 agf_spare1; /* spare field */ | 65 | __be32 agf_spare1; /* spare field */ |
66 | __be32 agf_flfirst; /* first freelist block's index */ | 66 | __be32 agf_flfirst; /* first freelist block's index */ |
67 | __be32 agf_fllast; /* last freelist block's index */ | 67 | __be32 agf_fllast; /* last freelist block's index */ |
68 | __be32 agf_flcount; /* count of blocks in freelist */ | 68 | __be32 agf_flcount; /* count of blocks in freelist */ |
69 | __be32 agf_freeblks; /* total free blocks */ | 69 | __be32 agf_freeblks; /* total free blocks */ |
70 | __be32 agf_longest; /* longest free space */ | 70 | __be32 agf_longest; /* longest free space */ |
71 | __be32 agf_btreeblks; /* # of blocks held in AGF btrees */ | 71 | __be32 agf_btreeblks; /* # of blocks held in AGF btrees */ |
72 | } xfs_agf_t; | 72 | } xfs_agf_t; |
73 | 73 | ||
74 | #define XFS_AGF_MAGICNUM 0x00000001 | 74 | #define XFS_AGF_MAGICNUM 0x00000001 |
75 | #define XFS_AGF_VERSIONNUM 0x00000002 | 75 | #define XFS_AGF_VERSIONNUM 0x00000002 |
76 | #define XFS_AGF_SEQNO 0x00000004 | 76 | #define XFS_AGF_SEQNO 0x00000004 |
77 | #define XFS_AGF_LENGTH 0x00000008 | 77 | #define XFS_AGF_LENGTH 0x00000008 |
78 | #define XFS_AGF_ROOTS 0x00000010 | 78 | #define XFS_AGF_ROOTS 0x00000010 |
79 | #define XFS_AGF_LEVELS 0x00000020 | 79 | #define XFS_AGF_LEVELS 0x00000020 |
80 | #define XFS_AGF_FLFIRST 0x00000040 | 80 | #define XFS_AGF_FLFIRST 0x00000040 |
81 | #define XFS_AGF_FLLAST 0x00000080 | 81 | #define XFS_AGF_FLLAST 0x00000080 |
82 | #define XFS_AGF_FLCOUNT 0x00000100 | 82 | #define XFS_AGF_FLCOUNT 0x00000100 |
83 | #define XFS_AGF_FREEBLKS 0x00000200 | 83 | #define XFS_AGF_FREEBLKS 0x00000200 |
84 | #define XFS_AGF_LONGEST 0x00000400 | 84 | #define XFS_AGF_LONGEST 0x00000400 |
85 | #define XFS_AGF_BTREEBLKS 0x00000800 | 85 | #define XFS_AGF_BTREEBLKS 0x00000800 |
86 | #define XFS_AGF_NUM_BITS 12 | 86 | #define XFS_AGF_NUM_BITS 12 |
87 | #define XFS_AGF_ALL_BITS ((1 << XFS_AGF_NUM_BITS) - 1) | 87 | #define XFS_AGF_ALL_BITS ((1 << XFS_AGF_NUM_BITS) - 1) |
88 | 88 | ||
89 | /* disk block (xfs_daddr_t) in the AG */ | 89 | /* disk block (xfs_daddr_t) in the AG */ |
90 | #define XFS_AGF_DADDR(mp) ((xfs_daddr_t)(1 << (mp)->m_sectbb_log)) | 90 | #define XFS_AGF_DADDR(mp) ((xfs_daddr_t)(1 << (mp)->m_sectbb_log)) |
91 | #define XFS_AGF_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGF_DADDR(mp)) | 91 | #define XFS_AGF_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGF_DADDR(mp)) |
92 | #define XFS_BUF_TO_AGF(bp) ((xfs_agf_t *)XFS_BUF_PTR(bp)) | 92 | #define XFS_BUF_TO_AGF(bp) ((xfs_agf_t *)XFS_BUF_PTR(bp)) |
93 | 93 | ||
94 | 94 | ||
95 | /* | 95 | /* |
96 | * Size of the unlinked inode hash table in the agi. | 96 | * Size of the unlinked inode hash table in the agi. |
97 | */ | 97 | */ |
98 | #define XFS_AGI_UNLINKED_BUCKETS 64 | 98 | #define XFS_AGI_UNLINKED_BUCKETS 64 |
99 | 99 | ||
100 | typedef struct xfs_agi { | 100 | typedef struct xfs_agi { |
101 | /* | 101 | /* |
102 | * Common allocation group header information | 102 | * Common allocation group header information |
103 | */ | 103 | */ |
104 | __be32 agi_magicnum; /* magic number == XFS_AGI_MAGIC */ | 104 | __be32 agi_magicnum; /* magic number == XFS_AGI_MAGIC */ |
105 | __be32 agi_versionnum; /* header version == XFS_AGI_VERSION */ | 105 | __be32 agi_versionnum; /* header version == XFS_AGI_VERSION */ |
106 | __be32 agi_seqno; /* sequence # starting from 0 */ | 106 | __be32 agi_seqno; /* sequence # starting from 0 */ |
107 | __be32 agi_length; /* size in blocks of a.g. */ | 107 | __be32 agi_length; /* size in blocks of a.g. */ |
108 | /* | 108 | /* |
109 | * Inode information | 109 | * Inode information |
110 | * Inodes are mapped by interpreting the inode number, so no | 110 | * Inodes are mapped by interpreting the inode number, so no |
111 | * mapping data is needed here. | 111 | * mapping data is needed here. |
112 | */ | 112 | */ |
113 | __be32 agi_count; /* count of allocated inodes */ | 113 | __be32 agi_count; /* count of allocated inodes */ |
114 | __be32 agi_root; /* root of inode btree */ | 114 | __be32 agi_root; /* root of inode btree */ |
115 | __be32 agi_level; /* levels in inode btree */ | 115 | __be32 agi_level; /* levels in inode btree */ |
116 | __be32 agi_freecount; /* number of free inodes */ | 116 | __be32 agi_freecount; /* number of free inodes */ |
117 | __be32 agi_newino; /* new inode just allocated */ | 117 | __be32 agi_newino; /* new inode just allocated */ |
118 | __be32 agi_dirino; /* last directory inode chunk */ | 118 | __be32 agi_dirino; /* last directory inode chunk */ |
119 | /* | 119 | /* |
120 | * Hash table of inodes which have been unlinked but are | 120 | * Hash table of inodes which have been unlinked but are |
121 | * still being referenced. | 121 | * still being referenced. |
122 | */ | 122 | */ |
123 | __be32 agi_unlinked[XFS_AGI_UNLINKED_BUCKETS]; | 123 | __be32 agi_unlinked[XFS_AGI_UNLINKED_BUCKETS]; |
124 | } xfs_agi_t; | 124 | } xfs_agi_t; |
125 | 125 | ||
126 | #define XFS_AGI_MAGICNUM 0x00000001 | 126 | #define XFS_AGI_MAGICNUM 0x00000001 |
127 | #define XFS_AGI_VERSIONNUM 0x00000002 | 127 | #define XFS_AGI_VERSIONNUM 0x00000002 |
128 | #define XFS_AGI_SEQNO 0x00000004 | 128 | #define XFS_AGI_SEQNO 0x00000004 |
129 | #define XFS_AGI_LENGTH 0x00000008 | 129 | #define XFS_AGI_LENGTH 0x00000008 |
130 | #define XFS_AGI_COUNT 0x00000010 | 130 | #define XFS_AGI_COUNT 0x00000010 |
131 | #define XFS_AGI_ROOT 0x00000020 | 131 | #define XFS_AGI_ROOT 0x00000020 |
132 | #define XFS_AGI_LEVEL 0x00000040 | 132 | #define XFS_AGI_LEVEL 0x00000040 |
133 | #define XFS_AGI_FREECOUNT 0x00000080 | 133 | #define XFS_AGI_FREECOUNT 0x00000080 |
134 | #define XFS_AGI_NEWINO 0x00000100 | 134 | #define XFS_AGI_NEWINO 0x00000100 |
135 | #define XFS_AGI_DIRINO 0x00000200 | 135 | #define XFS_AGI_DIRINO 0x00000200 |
136 | #define XFS_AGI_UNLINKED 0x00000400 | 136 | #define XFS_AGI_UNLINKED 0x00000400 |
137 | #define XFS_AGI_NUM_BITS 11 | 137 | #define XFS_AGI_NUM_BITS 11 |
138 | #define XFS_AGI_ALL_BITS ((1 << XFS_AGI_NUM_BITS) - 1) | 138 | #define XFS_AGI_ALL_BITS ((1 << XFS_AGI_NUM_BITS) - 1) |
139 | 139 | ||
140 | /* disk block (xfs_daddr_t) in the AG */ | 140 | /* disk block (xfs_daddr_t) in the AG */ |
141 | #define XFS_AGI_DADDR(mp) ((xfs_daddr_t)(2 << (mp)->m_sectbb_log)) | 141 | #define XFS_AGI_DADDR(mp) ((xfs_daddr_t)(2 << (mp)->m_sectbb_log)) |
142 | #define XFS_AGI_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGI_DADDR(mp)) | 142 | #define XFS_AGI_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGI_DADDR(mp)) |
143 | #define XFS_BUF_TO_AGI(bp) ((xfs_agi_t *)XFS_BUF_PTR(bp)) | 143 | #define XFS_BUF_TO_AGI(bp) ((xfs_agi_t *)XFS_BUF_PTR(bp)) |
144 | 144 | ||
145 | /* | 145 | /* |
146 | * The third a.g. block contains the a.g. freelist, an array | 146 | * The third a.g. block contains the a.g. freelist, an array |
147 | * of block pointers to blocks owned by the allocation btree code. | 147 | * of block pointers to blocks owned by the allocation btree code. |
148 | */ | 148 | */ |
149 | #define XFS_AGFL_DADDR(mp) ((xfs_daddr_t)(3 << (mp)->m_sectbb_log)) | 149 | #define XFS_AGFL_DADDR(mp) ((xfs_daddr_t)(3 << (mp)->m_sectbb_log)) |
150 | #define XFS_AGFL_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGFL_DADDR(mp)) | 150 | #define XFS_AGFL_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGFL_DADDR(mp)) |
151 | #define XFS_AGFL_SIZE(mp) ((mp)->m_sb.sb_sectsize / sizeof(xfs_agblock_t)) | 151 | #define XFS_AGFL_SIZE(mp) ((mp)->m_sb.sb_sectsize / sizeof(xfs_agblock_t)) |
152 | #define XFS_BUF_TO_AGFL(bp) ((xfs_agfl_t *)XFS_BUF_PTR(bp)) | 152 | #define XFS_BUF_TO_AGFL(bp) ((xfs_agfl_t *)XFS_BUF_PTR(bp)) |
153 | 153 | ||
154 | typedef struct xfs_agfl { | 154 | typedef struct xfs_agfl { |
155 | __be32 agfl_bno[1]; /* actually XFS_AGFL_SIZE(mp) */ | 155 | __be32 agfl_bno[1]; /* actually XFS_AGFL_SIZE(mp) */ |
156 | } xfs_agfl_t; | 156 | } xfs_agfl_t; |
157 | 157 | ||
158 | /* | 158 | /* |
159 | * Busy block/extent entry. Used in perag to mark blocks that have been freed | 159 | * Busy block/extent entry. Used in perag to mark blocks that have been freed |
160 | * but whose transactions aren't committed to disk yet. | 160 | * but whose transactions aren't committed to disk yet. |
161 | */ | 161 | */ |
162 | typedef struct xfs_perag_busy { | 162 | typedef struct xfs_perag_busy { |
163 | xfs_agblock_t busy_start; | 163 | xfs_agblock_t busy_start; |
164 | xfs_extlen_t busy_length; | 164 | xfs_extlen_t busy_length; |
165 | struct xfs_trans *busy_tp; /* transaction that did the free */ | 165 | struct xfs_trans *busy_tp; /* transaction that did the free */ |
166 | } xfs_perag_busy_t; | 166 | } xfs_perag_busy_t; |
167 | 167 | ||
168 | /* | 168 | /* |
169 | * Per-ag incore structure, copies of information in agf and agi, | 169 | * Per-ag incore structure, copies of information in agf and agi, |
170 | * to improve the performance of allocation group selection. | 170 | * to improve the performance of allocation group selection. |
171 | * | 171 | * |
172 | * pick sizes which fit in allocation buckets well | 172 | * pick sizes which fit in allocation buckets well |
173 | */ | 173 | */ |
174 | #if (BITS_PER_LONG == 32) | 174 | #if (BITS_PER_LONG == 32) |
175 | #define XFS_PAGB_NUM_SLOTS 84 | 175 | #define XFS_PAGB_NUM_SLOTS 84 |
176 | #elif (BITS_PER_LONG == 64) | 176 | #elif (BITS_PER_LONG == 64) |
177 | #define XFS_PAGB_NUM_SLOTS 128 | 177 | #define XFS_PAGB_NUM_SLOTS 128 |
178 | #endif | 178 | #endif |
179 | 179 | ||
180 | typedef struct xfs_perag | 180 | typedef struct xfs_perag |
181 | { | 181 | { |
182 | char pagf_init; /* this agf's entry is initialized */ | 182 | char pagf_init; /* this agf's entry is initialized */ |
183 | char pagi_init; /* this agi's entry is initialized */ | 183 | char pagi_init; /* this agi's entry is initialized */ |
184 | char pagf_metadata; /* the agf is preferred to be metadata */ | 184 | char pagf_metadata; /* the agf is preferred to be metadata */ |
185 | char pagi_inodeok; /* The agi is ok for inodes */ | 185 | char pagi_inodeok; /* The agi is ok for inodes */ |
186 | __uint8_t pagf_levels[XFS_BTNUM_AGF]; | 186 | __uint8_t pagf_levels[XFS_BTNUM_AGF]; |
187 | /* # of levels in bno & cnt btree */ | 187 | /* # of levels in bno & cnt btree */ |
188 | __uint32_t pagf_flcount; /* count of blocks in freelist */ | 188 | __uint32_t pagf_flcount; /* count of blocks in freelist */ |
189 | xfs_extlen_t pagf_freeblks; /* total free blocks */ | 189 | xfs_extlen_t pagf_freeblks; /* total free blocks */ |
190 | xfs_extlen_t pagf_longest; /* longest free space */ | 190 | xfs_extlen_t pagf_longest; /* longest free space */ |
191 | __uint32_t pagf_btreeblks; /* # of blocks held in AGF btrees */ | 191 | __uint32_t pagf_btreeblks; /* # of blocks held in AGF btrees */ |
192 | xfs_agino_t pagi_freecount; /* number of free inodes */ | 192 | xfs_agino_t pagi_freecount; /* number of free inodes */ |
193 | xfs_agino_t pagi_count; /* number of allocated inodes */ | 193 | xfs_agino_t pagi_count; /* number of allocated inodes */ |
194 | int pagb_count; /* pagb slots in use */ | 194 | int pagb_count; /* pagb slots in use */ |
195 | xfs_perag_busy_t *pagb_list; /* unstable blocks */ | ||
195 | #ifdef __KERNEL__ | 196 | #ifdef __KERNEL__ |
196 | spinlock_t pagb_lock; /* lock for pagb_list */ | 197 | spinlock_t pagb_lock; /* lock for pagb_list */ |
197 | #endif | 198 | |
198 | xfs_perag_busy_t *pagb_list; /* unstable blocks */ | ||
199 | atomic_t pagf_fstrms; /* # of filestreams active in this AG */ | 199 | atomic_t pagf_fstrms; /* # of filestreams active in this AG */ |
200 | 200 | ||
201 | int pag_ici_init; /* incore inode cache initialised */ | 201 | int pag_ici_init; /* incore inode cache initialised */ |
202 | rwlock_t pag_ici_lock; /* incore inode lock */ | 202 | rwlock_t pag_ici_lock; /* incore inode lock */ |
203 | struct radix_tree_root pag_ici_root; /* incore inode cache root */ | 203 | struct radix_tree_root pag_ici_root; /* incore inode cache root */ |
204 | #endif | ||
204 | } xfs_perag_t; | 205 | } xfs_perag_t; |
205 | 206 | ||
206 | #define XFS_AG_MAXLEVELS(mp) ((mp)->m_ag_maxlevels) | 207 | #define XFS_AG_MAXLEVELS(mp) ((mp)->m_ag_maxlevels) |
207 | #define XFS_MIN_FREELIST_RAW(bl,cl,mp) \ | 208 | #define XFS_MIN_FREELIST_RAW(bl,cl,mp) \ |
208 | (MIN(bl + 1, XFS_AG_MAXLEVELS(mp)) + MIN(cl + 1, XFS_AG_MAXLEVELS(mp))) | 209 | (MIN(bl + 1, XFS_AG_MAXLEVELS(mp)) + MIN(cl + 1, XFS_AG_MAXLEVELS(mp))) |
209 | #define XFS_MIN_FREELIST(a,mp) \ | 210 | #define XFS_MIN_FREELIST(a,mp) \ |
210 | (XFS_MIN_FREELIST_RAW( \ | 211 | (XFS_MIN_FREELIST_RAW( \ |
211 | be32_to_cpu((a)->agf_levels[XFS_BTNUM_BNOi]), \ | 212 | be32_to_cpu((a)->agf_levels[XFS_BTNUM_BNOi]), \ |
212 | be32_to_cpu((a)->agf_levels[XFS_BTNUM_CNTi]), mp)) | 213 | be32_to_cpu((a)->agf_levels[XFS_BTNUM_CNTi]), mp)) |
213 | #define XFS_MIN_FREELIST_PAG(pag,mp) \ | 214 | #define XFS_MIN_FREELIST_PAG(pag,mp) \ |
214 | (XFS_MIN_FREELIST_RAW( \ | 215 | (XFS_MIN_FREELIST_RAW( \ |
215 | (uint_t)(pag)->pagf_levels[XFS_BTNUM_BNOi], \ | 216 | (uint_t)(pag)->pagf_levels[XFS_BTNUM_BNOi], \ |
216 | (uint_t)(pag)->pagf_levels[XFS_BTNUM_CNTi], mp)) | 217 | (uint_t)(pag)->pagf_levels[XFS_BTNUM_CNTi], mp)) |
217 | 218 | ||
218 | #define XFS_AGB_TO_FSB(mp,agno,agbno) \ | 219 | #define XFS_AGB_TO_FSB(mp,agno,agbno) \ |
219 | (((xfs_fsblock_t)(agno) << (mp)->m_sb.sb_agblklog) | (agbno)) | 220 | (((xfs_fsblock_t)(agno) << (mp)->m_sb.sb_agblklog) | (agbno)) |
220 | #define XFS_FSB_TO_AGNO(mp,fsbno) \ | 221 | #define XFS_FSB_TO_AGNO(mp,fsbno) \ |
221 | ((xfs_agnumber_t)((fsbno) >> (mp)->m_sb.sb_agblklog)) | 222 | ((xfs_agnumber_t)((fsbno) >> (mp)->m_sb.sb_agblklog)) |
222 | #define XFS_FSB_TO_AGBNO(mp,fsbno) \ | 223 | #define XFS_FSB_TO_AGBNO(mp,fsbno) \ |
223 | ((xfs_agblock_t)((fsbno) & XFS_MASK32LO((mp)->m_sb.sb_agblklog))) | 224 | ((xfs_agblock_t)((fsbno) & XFS_MASK32LO((mp)->m_sb.sb_agblklog))) |
224 | #define XFS_AGB_TO_DADDR(mp,agno,agbno) \ | 225 | #define XFS_AGB_TO_DADDR(mp,agno,agbno) \ |
225 | ((xfs_daddr_t)XFS_FSB_TO_BB(mp, \ | 226 | ((xfs_daddr_t)XFS_FSB_TO_BB(mp, \ |
226 | (xfs_fsblock_t)(agno) * (mp)->m_sb.sb_agblocks + (agbno))) | 227 | (xfs_fsblock_t)(agno) * (mp)->m_sb.sb_agblocks + (agbno))) |
227 | #define XFS_AG_DADDR(mp,agno,d) (XFS_AGB_TO_DADDR(mp, agno, 0) + (d)) | 228 | #define XFS_AG_DADDR(mp,agno,d) (XFS_AGB_TO_DADDR(mp, agno, 0) + (d)) |
228 | 229 | ||
229 | /* | 230 | /* |
230 | * For checking for bad ranges of xfs_daddr_t's, covering multiple | 231 | * For checking for bad ranges of xfs_daddr_t's, covering multiple |
231 | * allocation groups or a single xfs_daddr_t that's a superblock copy. | 232 | * allocation groups or a single xfs_daddr_t that's a superblock copy. |
232 | */ | 233 | */ |
233 | #define XFS_AG_CHECK_DADDR(mp,d,len) \ | 234 | #define XFS_AG_CHECK_DADDR(mp,d,len) \ |
234 | ((len) == 1 ? \ | 235 | ((len) == 1 ? \ |
235 | ASSERT((d) == XFS_SB_DADDR || \ | 236 | ASSERT((d) == XFS_SB_DADDR || \ |
236 | XFS_DADDR_TO_AGBNO(mp, d) != XFS_SB_DADDR) : \ | 237 | XFS_DADDR_TO_AGBNO(mp, d) != XFS_SB_DADDR) : \ |
237 | ASSERT(XFS_DADDR_TO_AGNO(mp, d) == \ | 238 | ASSERT(XFS_DADDR_TO_AGNO(mp, d) == \ |
238 | XFS_DADDR_TO_AGNO(mp, (d) + (len) - 1))) | 239 | XFS_DADDR_TO_AGNO(mp, (d) + (len) - 1))) |
239 | 240 | ||
240 | #endif /* __XFS_AG_H__ */ | 241 | #endif /* __XFS_AG_H__ */ |
fs/xfs/xfs_alloc.h
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License as | 6 | * modify it under the terms of the GNU General Public License as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | * | 8 | * |
9 | * This program is distributed in the hope that it would be useful, | 9 | * This program is distributed in the hope that it would be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. | 12 | * GNU General Public License for more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License | 14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write the Free Software Foundation, | 15 | * along with this program; if not, write the Free Software Foundation, |
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ | 17 | */ |
18 | #ifndef __XFS_ALLOC_H__ | 18 | #ifndef __XFS_ALLOC_H__ |
19 | #define __XFS_ALLOC_H__ | 19 | #define __XFS_ALLOC_H__ |
20 | 20 | ||
21 | struct xfs_buf; | 21 | struct xfs_buf; |
22 | struct xfs_mount; | 22 | struct xfs_mount; |
23 | struct xfs_perag; | 23 | struct xfs_perag; |
24 | struct xfs_trans; | 24 | struct xfs_trans; |
25 | 25 | ||
26 | /* | 26 | /* |
27 | * Freespace allocation types. Argument to xfs_alloc_[v]extent. | 27 | * Freespace allocation types. Argument to xfs_alloc_[v]extent. |
28 | */ | 28 | */ |
29 | typedef enum xfs_alloctype | 29 | typedef enum xfs_alloctype |
30 | { | 30 | { |
31 | XFS_ALLOCTYPE_ANY_AG, /* allocate anywhere, use rotor */ | 31 | XFS_ALLOCTYPE_ANY_AG, /* allocate anywhere, use rotor */ |
32 | XFS_ALLOCTYPE_FIRST_AG, /* ... start at ag 0 */ | 32 | XFS_ALLOCTYPE_FIRST_AG, /* ... start at ag 0 */ |
33 | XFS_ALLOCTYPE_START_AG, /* anywhere, start in this a.g. */ | 33 | XFS_ALLOCTYPE_START_AG, /* anywhere, start in this a.g. */ |
34 | XFS_ALLOCTYPE_THIS_AG, /* anywhere in this a.g. */ | 34 | XFS_ALLOCTYPE_THIS_AG, /* anywhere in this a.g. */ |
35 | XFS_ALLOCTYPE_START_BNO, /* near this block else anywhere */ | 35 | XFS_ALLOCTYPE_START_BNO, /* near this block else anywhere */ |
36 | XFS_ALLOCTYPE_NEAR_BNO, /* in this a.g. and near this block */ | 36 | XFS_ALLOCTYPE_NEAR_BNO, /* in this a.g. and near this block */ |
37 | XFS_ALLOCTYPE_THIS_BNO /* at exactly this block */ | 37 | XFS_ALLOCTYPE_THIS_BNO /* at exactly this block */ |
38 | } xfs_alloctype_t; | 38 | } xfs_alloctype_t; |
39 | 39 | ||
40 | /* | 40 | /* |
41 | * Flags for xfs_alloc_fix_freelist. | 41 | * Flags for xfs_alloc_fix_freelist. |
42 | */ | 42 | */ |
43 | #define XFS_ALLOC_FLAG_TRYLOCK 0x00000001 /* use trylock for buffer locking */ | 43 | #define XFS_ALLOC_FLAG_TRYLOCK 0x00000001 /* use trylock for buffer locking */ |
44 | #define XFS_ALLOC_FLAG_FREEING 0x00000002 /* indicate caller is freeing extents*/ | 44 | #define XFS_ALLOC_FLAG_FREEING 0x00000002 /* indicate caller is freeing extents*/ |
45 | 45 | ||
46 | /* | 46 | /* |
47 | * In order to avoid ENOSPC-related deadlock caused by | 47 | * In order to avoid ENOSPC-related deadlock caused by |
48 | * out-of-order locking of AGF buffer (PV 947395), we place | 48 | * out-of-order locking of AGF buffer (PV 947395), we place |
49 | * constraints on the relationship among actual allocations for | 49 | * constraints on the relationship among actual allocations for |
50 | * data blocks, freelist blocks, and potential file data bmap | 50 | * data blocks, freelist blocks, and potential file data bmap |
51 | * btree blocks. However, these restrictions may result in no | 51 | * btree blocks. However, these restrictions may result in no |
52 | * actual space allocated for a delayed extent, for example, a data | 52 | * actual space allocated for a delayed extent, for example, a data |
53 | * block in a certain AG is allocated but there is no additional | 53 | * block in a certain AG is allocated but there is no additional |
54 | * block for the additional bmap btree block due to a split of the | 54 | * block for the additional bmap btree block due to a split of the |
55 | * bmap btree of the file. The result of this may lead to an | 55 | * bmap btree of the file. The result of this may lead to an |
56 | * infinite loop in xfssyncd when the file gets flushed to disk and | 56 | * infinite loop in xfssyncd when the file gets flushed to disk and |
57 | * all delayed extents need to be actually allocated. To get around | 57 | * all delayed extents need to be actually allocated. To get around |
58 | * this, we explicitly set aside a few blocks which will not be | 58 | * this, we explicitly set aside a few blocks which will not be |
59 | * reserved in delayed allocation. Considering the minimum number of | 59 | * reserved in delayed allocation. Considering the minimum number of |
60 | * needed freelist blocks is 4 fsbs _per AG_, a potential split of file's bmap | 60 | * needed freelist blocks is 4 fsbs _per AG_, a potential split of file's bmap |
61 | * btree requires 1 fsb, so we set the number of set-aside blocks | 61 | * btree requires 1 fsb, so we set the number of set-aside blocks |
62 | * to 4 + 4*agcount. | 62 | * to 4 + 4*agcount. |
63 | */ | 63 | */ |
64 | #define XFS_ALLOC_SET_ASIDE(mp) (4 + ((mp)->m_sb.sb_agcount * 4)) | 64 | #define XFS_ALLOC_SET_ASIDE(mp) (4 + ((mp)->m_sb.sb_agcount * 4)) |
65 | 65 | ||
66 | /* | 66 | /* |
67 | * Argument structure for xfs_alloc routines. | 67 | * Argument structure for xfs_alloc routines. |
68 | * This is turned into a structure to avoid having 20 arguments passed | 68 | * This is turned into a structure to avoid having 20 arguments passed |
69 | * down several levels of the stack. | 69 | * down several levels of the stack. |
70 | */ | 70 | */ |
71 | typedef struct xfs_alloc_arg { | 71 | typedef struct xfs_alloc_arg { |
72 | struct xfs_trans *tp; /* transaction pointer */ | 72 | struct xfs_trans *tp; /* transaction pointer */ |
73 | struct xfs_mount *mp; /* file system mount point */ | 73 | struct xfs_mount *mp; /* file system mount point */ |
74 | struct xfs_buf *agbp; /* buffer for a.g. freelist header */ | 74 | struct xfs_buf *agbp; /* buffer for a.g. freelist header */ |
75 | struct xfs_perag *pag; /* per-ag struct for this agno */ | 75 | struct xfs_perag *pag; /* per-ag struct for this agno */ |
76 | xfs_fsblock_t fsbno; /* file system block number */ | 76 | xfs_fsblock_t fsbno; /* file system block number */ |
77 | xfs_agnumber_t agno; /* allocation group number */ | 77 | xfs_agnumber_t agno; /* allocation group number */ |
78 | xfs_agblock_t agbno; /* allocation group-relative block # */ | 78 | xfs_agblock_t agbno; /* allocation group-relative block # */ |
79 | xfs_extlen_t minlen; /* minimum size of extent */ | 79 | xfs_extlen_t minlen; /* minimum size of extent */ |
80 | xfs_extlen_t maxlen; /* maximum size of extent */ | 80 | xfs_extlen_t maxlen; /* maximum size of extent */ |
81 | xfs_extlen_t mod; /* mod value for extent size */ | 81 | xfs_extlen_t mod; /* mod value for extent size */ |
82 | xfs_extlen_t prod; /* prod value for extent size */ | 82 | xfs_extlen_t prod; /* prod value for extent size */ |
83 | xfs_extlen_t minleft; /* min blocks must be left after us */ | 83 | xfs_extlen_t minleft; /* min blocks must be left after us */ |
84 | xfs_extlen_t total; /* total blocks needed in xaction */ | 84 | xfs_extlen_t total; /* total blocks needed in xaction */ |
85 | xfs_extlen_t alignment; /* align answer to multiple of this */ | 85 | xfs_extlen_t alignment; /* align answer to multiple of this */ |
86 | xfs_extlen_t minalignslop; /* slop for minlen+alignment calcs */ | 86 | xfs_extlen_t minalignslop; /* slop for minlen+alignment calcs */ |
87 | xfs_extlen_t len; /* output: actual size of extent */ | 87 | xfs_extlen_t len; /* output: actual size of extent */ |
88 | xfs_alloctype_t type; /* allocation type XFS_ALLOCTYPE_... */ | 88 | xfs_alloctype_t type; /* allocation type XFS_ALLOCTYPE_... */ |
89 | xfs_alloctype_t otype; /* original allocation type */ | 89 | xfs_alloctype_t otype; /* original allocation type */ |
90 | char wasdel; /* set if allocation was prev delayed */ | 90 | char wasdel; /* set if allocation was prev delayed */ |
91 | char wasfromfl; /* set if allocation is from freelist */ | 91 | char wasfromfl; /* set if allocation is from freelist */ |
92 | char isfl; /* set if is freelist blocks - !acctg */ | 92 | char isfl; /* set if is freelist blocks - !acctg */ |
93 | char userdata; /* set if this is user data */ | 93 | char userdata; /* set if this is user data */ |
94 | xfs_fsblock_t firstblock; /* io first block allocated */ | 94 | xfs_fsblock_t firstblock; /* io first block allocated */ |
95 | } xfs_alloc_arg_t; | 95 | } xfs_alloc_arg_t; |
96 | 96 | ||
97 | /* | 97 | /* |
98 | * Defines for userdata | 98 | * Defines for userdata |
99 | */ | 99 | */ |
100 | #define XFS_ALLOC_USERDATA 1 /* allocation is for user data*/ | 100 | #define XFS_ALLOC_USERDATA 1 /* allocation is for user data*/ |
101 | #define XFS_ALLOC_INITIAL_USER_DATA 2 /* special case start of file */ | 101 | #define XFS_ALLOC_INITIAL_USER_DATA 2 /* special case start of file */ |
102 | 102 | ||
103 | 103 | ||
104 | #ifdef __KERNEL__ | 104 | #ifdef __KERNEL__ |
105 | 105 | ||
106 | #if defined(XFS_ALLOC_TRACE) | 106 | #if defined(XFS_ALLOC_TRACE) |
107 | /* | 107 | /* |
108 | * Allocation tracing buffer size. | 108 | * Allocation tracing buffer size. |
109 | */ | 109 | */ |
110 | #define XFS_ALLOC_TRACE_SIZE 4096 | 110 | #define XFS_ALLOC_TRACE_SIZE 4096 |
111 | extern ktrace_t *xfs_alloc_trace_buf; | 111 | extern ktrace_t *xfs_alloc_trace_buf; |
112 | 112 | ||
113 | /* | 113 | /* |
114 | * Types for alloc tracing. | 114 | * Types for alloc tracing. |
115 | */ | 115 | */ |
116 | #define XFS_ALLOC_KTRACE_ALLOC 1 | 116 | #define XFS_ALLOC_KTRACE_ALLOC 1 |
117 | #define XFS_ALLOC_KTRACE_FREE 2 | 117 | #define XFS_ALLOC_KTRACE_FREE 2 |
118 | #define XFS_ALLOC_KTRACE_MODAGF 3 | 118 | #define XFS_ALLOC_KTRACE_MODAGF 3 |
119 | #define XFS_ALLOC_KTRACE_BUSY 4 | 119 | #define XFS_ALLOC_KTRACE_BUSY 4 |
120 | #define XFS_ALLOC_KTRACE_UNBUSY 5 | 120 | #define XFS_ALLOC_KTRACE_UNBUSY 5 |
121 | #define XFS_ALLOC_KTRACE_BUSYSEARCH 6 | 121 | #define XFS_ALLOC_KTRACE_BUSYSEARCH 6 |
122 | #endif | 122 | #endif |
123 | 123 | ||
124 | void | ||
125 | xfs_alloc_mark_busy(xfs_trans_t *tp, | ||
126 | xfs_agnumber_t agno, | ||
127 | xfs_agblock_t bno, | ||
128 | xfs_extlen_t len); | ||
129 | |||
130 | void | ||
131 | xfs_alloc_clear_busy(xfs_trans_t *tp, | ||
132 | xfs_agnumber_t ag, | ||
133 | int idx); | ||
134 | |||
135 | #endif /* __KERNEL__ */ | ||
136 | |||
124 | /* | 137 | /* |
125 | * Compute and fill in value of m_ag_maxlevels. | 138 | * Compute and fill in value of m_ag_maxlevels. |
126 | */ | 139 | */ |
127 | void | 140 | void |
128 | xfs_alloc_compute_maxlevels( | 141 | xfs_alloc_compute_maxlevels( |
129 | struct xfs_mount *mp); /* file system mount structure */ | 142 | struct xfs_mount *mp); /* file system mount structure */ |
130 | 143 | ||
131 | /* | 144 | /* |
132 | * Get a block from the freelist. | 145 | * Get a block from the freelist. |
133 | * Returns with the buffer for the block gotten. | 146 | * Returns with the buffer for the block gotten. |
134 | */ | 147 | */ |
135 | int /* error */ | 148 | int /* error */ |
136 | xfs_alloc_get_freelist( | 149 | xfs_alloc_get_freelist( |
137 | struct xfs_trans *tp, /* transaction pointer */ | 150 | struct xfs_trans *tp, /* transaction pointer */ |
138 | struct xfs_buf *agbp, /* buffer containing the agf structure */ | 151 | struct xfs_buf *agbp, /* buffer containing the agf structure */ |
139 | xfs_agblock_t *bnop, /* block address retrieved from freelist */ | 152 | xfs_agblock_t *bnop, /* block address retrieved from freelist */ |
140 | int btreeblk); /* destination is a AGF btree */ | 153 | int btreeblk); /* destination is a AGF btree */ |
141 | 154 | ||
142 | /* | 155 | /* |
143 | * Log the given fields from the agf structure. | 156 | * Log the given fields from the agf structure. |
144 | */ | 157 | */ |
145 | void | 158 | void |
146 | xfs_alloc_log_agf( | 159 | xfs_alloc_log_agf( |
147 | struct xfs_trans *tp, /* transaction pointer */ | 160 | struct xfs_trans *tp, /* transaction pointer */ |
148 | struct xfs_buf *bp, /* buffer for a.g. freelist header */ | 161 | struct xfs_buf *bp, /* buffer for a.g. freelist header */ |
149 | int fields);/* mask of fields to be logged (XFS_AGF_...) */ | 162 | int fields);/* mask of fields to be logged (XFS_AGF_...) */ |
150 | 163 | ||
151 | /* | 164 | /* |
152 | * Interface for inode allocation to force the pag data to be initialized. | 165 | * Interface for inode allocation to force the pag data to be initialized. |
153 | */ | 166 | */ |
154 | int /* error */ | 167 | int /* error */ |
155 | xfs_alloc_pagf_init( | 168 | xfs_alloc_pagf_init( |
156 | struct xfs_mount *mp, /* file system mount structure */ | 169 | struct xfs_mount *mp, /* file system mount structure */ |
157 | struct xfs_trans *tp, /* transaction pointer */ | 170 | struct xfs_trans *tp, /* transaction pointer */ |
158 | xfs_agnumber_t agno, /* allocation group number */ | 171 | xfs_agnumber_t agno, /* allocation group number */ |
159 | int flags); /* XFS_ALLOC_FLAGS_... */ | 172 | int flags); /* XFS_ALLOC_FLAGS_... */ |
160 | 173 | ||
161 | /* | 174 | /* |
162 | * Put the block on the freelist for the allocation group. | 175 | * Put the block on the freelist for the allocation group. |
163 | */ | 176 | */ |
164 | int /* error */ | 177 | int /* error */ |
165 | xfs_alloc_put_freelist( | 178 | xfs_alloc_put_freelist( |
166 | struct xfs_trans *tp, /* transaction pointer */ | 179 | struct xfs_trans *tp, /* transaction pointer */ |
167 | struct xfs_buf *agbp, /* buffer for a.g. freelist header */ | 180 | struct xfs_buf *agbp, /* buffer for a.g. freelist header */ |
168 | struct xfs_buf *agflbp,/* buffer for a.g. free block array */ | 181 | struct xfs_buf *agflbp,/* buffer for a.g. free block array */ |
169 | xfs_agblock_t bno, /* block being freed */ | 182 | xfs_agblock_t bno, /* block being freed */ |
170 | int btreeblk); /* owner was a AGF btree */ | 183 | int btreeblk); /* owner was a AGF btree */ |
171 | 184 | ||
172 | /* | 185 | /* |
173 | * Read in the allocation group header (free/alloc section). | 186 | * Read in the allocation group header (free/alloc section). |
174 | */ | 187 | */ |
175 | int /* error */ | 188 | int /* error */ |
176 | xfs_alloc_read_agf( | 189 | xfs_alloc_read_agf( |
177 | struct xfs_mount *mp, /* mount point structure */ | 190 | struct xfs_mount *mp, /* mount point structure */ |
178 | struct xfs_trans *tp, /* transaction pointer */ | 191 | struct xfs_trans *tp, /* transaction pointer */ |
179 | xfs_agnumber_t agno, /* allocation group number */ | 192 | xfs_agnumber_t agno, /* allocation group number */ |
180 | int flags, /* XFS_ALLOC_FLAG_... */ | 193 | int flags, /* XFS_ALLOC_FLAG_... */ |
181 | struct xfs_buf **bpp); /* buffer for the ag freelist header */ | 194 | struct xfs_buf **bpp); /* buffer for the ag freelist header */ |
182 | 195 | ||
183 | /* | 196 | /* |
184 | * Allocate an extent (variable-size). | 197 | * Allocate an extent (variable-size). |
185 | */ | 198 | */ |
186 | int /* error */ | 199 | int /* error */ |
187 | xfs_alloc_vextent( | 200 | xfs_alloc_vextent( |
188 | xfs_alloc_arg_t *args); /* allocation argument structure */ | 201 | xfs_alloc_arg_t *args); /* allocation argument structure */ |
189 | 202 | ||
190 | /* | 203 | /* |
191 | * Free an extent. | 204 | * Free an extent. |
192 | */ | 205 | */ |
193 | int /* error */ | 206 | int /* error */ |
194 | xfs_free_extent( | 207 | xfs_free_extent( |
195 | struct xfs_trans *tp, /* transaction pointer */ | 208 | struct xfs_trans *tp, /* transaction pointer */ |
196 | xfs_fsblock_t bno, /* starting block number of extent */ | 209 | xfs_fsblock_t bno, /* starting block number of extent */ |
197 | xfs_extlen_t len); /* length of extent */ | 210 | xfs_extlen_t len); /* length of extent */ |
198 | |||
199 | void | ||
200 | xfs_alloc_mark_busy(xfs_trans_t *tp, | ||
201 | xfs_agnumber_t agno, |
fs/xfs/xfs_arch.h
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License as | 6 | * modify it under the terms of the GNU General Public License as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | * | 8 | * |
9 | * This program is distributed in the hope that it would be useful, | 9 | * This program is distributed in the hope that it would be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. | 12 | * GNU General Public License for more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License | 14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write the Free Software Foundation, | 15 | * along with this program; if not, write the Free Software Foundation, |
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ | 17 | */ |
18 | #ifndef __XFS_ARCH_H__ | 18 | #ifndef __XFS_ARCH_H__ |
19 | #define __XFS_ARCH_H__ | 19 | #define __XFS_ARCH_H__ |
20 | 20 | ||
21 | #ifndef XFS_BIG_INUMS | 21 | #ifndef XFS_BIG_INUMS |
22 | # error XFS_BIG_INUMS must be defined true or false | 22 | # error XFS_BIG_INUMS must be defined true or false |
23 | #endif | 23 | #endif |
24 | 24 | ||
25 | #ifdef __KERNEL__ | 25 | #ifdef __KERNEL__ |
26 | 26 | ||
27 | #include <asm/byteorder.h> | 27 | #include <asm/byteorder.h> |
28 | 28 | ||
29 | #ifdef __BIG_ENDIAN | 29 | #ifdef __BIG_ENDIAN |
30 | #define XFS_NATIVE_HOST 1 | 30 | #define XFS_NATIVE_HOST 1 |
31 | #else | 31 | #else |
32 | #undef XFS_NATIVE_HOST | 32 | #undef XFS_NATIVE_HOST |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | #else /* __KERNEL__ */ | 35 | #else /* __KERNEL__ */ |
36 | 36 | ||
37 | #if __BYTE_ORDER == __BIG_ENDIAN | 37 | #if __BYTE_ORDER == __BIG_ENDIAN |
38 | #define XFS_NATIVE_HOST 1 | 38 | #define XFS_NATIVE_HOST 1 |
39 | #else | 39 | #else |
40 | #undef XFS_NATIVE_HOST | 40 | #undef XFS_NATIVE_HOST |
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | #ifdef XFS_NATIVE_HOST | 43 | #ifdef XFS_NATIVE_HOST |
44 | #define cpu_to_be16(val) ((__be16)(val)) | 44 | #define cpu_to_be16(val) ((__force __be16)(__u16)(val)) |
45 | #define cpu_to_be32(val) ((__be32)(val)) | 45 | #define cpu_to_be32(val) ((__force __be32)(__u32)(val)) |
46 | #define cpu_to_be64(val) ((__be64)(val)) | 46 | #define cpu_to_be64(val) ((__force __be64)(__u64)(val)) |
47 | #define be16_to_cpu(val) ((__uint16_t)(val)) | 47 | #define be16_to_cpu(val) ((__force __u16)(__be16)(val)) |
48 | #define be32_to_cpu(val) ((__uint32_t)(val)) | 48 | #define be32_to_cpu(val) ((__force __u32)(__be32)(val)) |
49 | #define be64_to_cpu(val) ((__uint64_t)(val)) | 49 | #define be64_to_cpu(val) ((__force __u64)(__be64)(val)) |
50 | #else | 50 | #else |
51 | #define cpu_to_be16(val) (__swab16((__uint16_t)(val))) | 51 | #define cpu_to_be16(val) ((__force __be16)__swab16((__u16)(val))) |
52 | #define cpu_to_be32(val) (__swab32((__uint32_t)(val))) | 52 | #define cpu_to_be32(val) ((__force __be32)__swab32((__u32)(val))) |
53 | #define cpu_to_be64(val) (__swab64((__uint64_t)(val))) | 53 | #define cpu_to_be64(val) ((__force __be64)__swab64((__u64)(val))) |
54 | #define be16_to_cpu(val) (__swab16((__be16)(val))) | 54 | #define be16_to_cpu(val) (__swab16((__force __u16)(__be16)(val))) |
55 | #define be32_to_cpu(val) (__swab32((__be32)(val))) | 55 | #define be32_to_cpu(val) (__swab32((__force __u32)(__be32)(val))) |
56 | #define be64_to_cpu(val) (__swab64((__be64)(val))) | 56 | #define be64_to_cpu(val) (__swab64((__force __u64)(__be64)(val))) |
57 | #endif | 57 | #endif |
58 | |||
59 | static inline void be16_add_cpu(__be16 *a, __s16 b) | ||
60 | { | ||
61 | *a = cpu_to_be16(be16_to_cpu(*a) + b); | ||
62 | } | ||
63 | |||
64 | static inline void be32_add_cpu(__be32 *a, __s32 b) | ||
65 | { | ||
66 | *a = cpu_to_be32(be32_to_cpu(*a) + b); | ||
67 | } | ||
68 | |||
69 | static inline void be64_add_cpu(__be64 *a, __s64 b) | ||
70 | { | ||
71 | *a = cpu_to_be64(be64_to_cpu(*a) + b); | ||
72 | } | ||
58 | 73 | ||
59 | #endif /* __KERNEL__ */ | 74 | #endif /* __KERNEL__ */ |
60 | 75 | ||
61 | /* do we need conversion? */ | 76 | /* do we need conversion? */ |
62 | #define ARCH_NOCONVERT 1 | 77 | #define ARCH_NOCONVERT 1 |
63 | #ifdef XFS_NATIVE_HOST | 78 | #ifdef XFS_NATIVE_HOST |
64 | # define ARCH_CONVERT ARCH_NOCONVERT | 79 | # define ARCH_CONVERT ARCH_NOCONVERT |
65 | #else | 80 | #else |
66 | # define ARCH_CONVERT 0 | 81 | # define ARCH_CONVERT 0 |
67 | #endif | 82 | #endif |
68 | 83 | ||
69 | /* generic swapping macros */ | 84 | /* generic swapping macros */ |
70 | 85 | ||
71 | #ifndef HAVE_SWABMACROS | 86 | #ifndef HAVE_SWABMACROS |
72 | #define INT_SWAP16(type,var) ((typeof(type))(__swab16((__u16)(var)))) | 87 | #define INT_SWAP16(type,var) ((typeof(type))(__swab16((__u16)(var)))) |
73 | #define INT_SWAP32(type,var) ((typeof(type))(__swab32((__u32)(var)))) | 88 | #define INT_SWAP32(type,var) ((typeof(type))(__swab32((__u32)(var)))) |
74 | #define INT_SWAP64(type,var) ((typeof(type))(__swab64((__u64)(var)))) | 89 | #define INT_SWAP64(type,var) ((typeof(type))(__swab64((__u64)(var)))) |
75 | #endif | 90 | #endif |
76 | 91 | ||
77 | #define INT_SWAP(type, var) \ | 92 | #define INT_SWAP(type, var) \ |
78 | ((sizeof(type) == 8) ? INT_SWAP64(type,var) : \ | 93 | ((sizeof(type) == 8) ? INT_SWAP64(type,var) : \ |
79 | ((sizeof(type) == 4) ? INT_SWAP32(type,var) : \ | 94 | ((sizeof(type) == 4) ? INT_SWAP32(type,var) : \ |
80 | ((sizeof(type) == 2) ? INT_SWAP16(type,var) : \ | 95 | ((sizeof(type) == 2) ? INT_SWAP16(type,var) : \ |
81 | (var)))) | 96 | (var)))) |
82 | 97 | ||
83 | /* | 98 | /* |
84 | * get and set integers from potentially unaligned locations | 99 | * get and set integers from potentially unaligned locations |
85 | */ | 100 | */ |
86 | 101 | ||
87 | #define INT_GET_UNALIGNED_16_BE(pointer) \ | 102 | #define INT_GET_UNALIGNED_16_BE(pointer) \ |
88 | ((__u16)((((__u8*)(pointer))[0] << 8) | (((__u8*)(pointer))[1]))) | 103 | ((__u16)((((__u8*)(pointer))[0] << 8) | (((__u8*)(pointer))[1]))) |
89 | #define INT_SET_UNALIGNED_16_BE(pointer,value) \ | 104 | #define INT_SET_UNALIGNED_16_BE(pointer,value) \ |
90 | { \ | 105 | { \ |
91 | ((__u8*)(pointer))[0] = (((value) >> 8) & 0xff); \ | 106 | ((__u8*)(pointer))[0] = (((value) >> 8) & 0xff); \ |
92 | ((__u8*)(pointer))[1] = (((value) ) & 0xff); \ | 107 | ((__u8*)(pointer))[1] = (((value) ) & 0xff); \ |
93 | } | 108 | } |
94 | 109 | ||
95 | /* does not return a value */ | 110 | /* does not return a value */ |
96 | #define INT_SET(reference,arch,valueref) \ | 111 | #define INT_SET(reference,arch,valueref) \ |
97 | (__builtin_constant_p(valueref) ? \ | 112 | (__builtin_constant_p(valueref) ? \ |
98 | (void)( (reference) = ( ((arch) != ARCH_NOCONVERT) ? (INT_SWAP((reference),(valueref))) : (valueref)) ) : \ | 113 | (void)( (reference) = ( ((arch) != ARCH_NOCONVERT) ? (INT_SWAP((reference),(valueref))) : (valueref)) ) : \ |
99 | (void)( \ | 114 | (void)( \ |
100 | ((reference) = (valueref)), \ | 115 | ((reference) = (valueref)), \ |
101 | ( ((arch) != ARCH_NOCONVERT) ? (reference) = INT_SWAP((reference),(reference)) : 0 ) \ | 116 | ( ((arch) != ARCH_NOCONVERT) ? (reference) = INT_SWAP((reference),(reference)) : 0 ) \ |
102 | ) \ | 117 | ) \ |
103 | ) | 118 | ) |
104 | 119 | ||
105 | /* | 120 | /* |
106 | * In directories inode numbers are stored as unaligned arrays of unsigned | 121 | * In directories inode numbers are stored as unaligned arrays of unsigned |
107 | * 8bit integers on disk. | 122 | * 8bit integers on disk. |
108 | * | 123 | * |
109 | * For v1 directories or v2 directories that contain inode numbers that | 124 | * For v1 directories or v2 directories that contain inode numbers that |
110 | * do not fit into 32bit the array has eight members, but the first member | 125 | * do not fit into 32bit the array has eight members, but the first member |
111 | * is always zero: | 126 | * is always zero: |
112 | * | 127 | * |
113 | * |unused|48-55|40-47|32-39|24-31|16-23| 8-15| 0- 7| | 128 | * |unused|48-55|40-47|32-39|24-31|16-23| 8-15| 0- 7| |
114 | * | 129 | * |
115 | * For v2 directories that only contain entries with inode numbers that fit | 130 | * For v2 directories that only contain entries with inode numbers that fit |
116 | * into 32bits a four-member array is used: | 131 | * into 32bits a four-member array is used: |
117 | * | 132 | * |
118 | * |24-31|16-23| 8-15| 0- 7| | 133 | * |24-31|16-23| 8-15| 0- 7| |
119 | */ | 134 | */ |
120 | 135 | ||
121 | #define XFS_GET_DIR_INO4(di) \ | 136 | #define XFS_GET_DIR_INO4(di) \ |
122 | (((__u32)(di).i[0] << 24) | ((di).i[1] << 16) | ((di).i[2] << 8) | ((di).i[3])) | 137 | (((__u32)(di).i[0] << 24) | ((di).i[1] << 16) | ((di).i[2] << 8) | ((di).i[3])) |
123 | 138 | ||
124 | #define XFS_PUT_DIR_INO4(from, di) \ | 139 | #define XFS_PUT_DIR_INO4(from, di) \ |
125 | do { \ | 140 | do { \ |
126 | (di).i[0] = (((from) & 0xff000000ULL) >> 24); \ | 141 | (di).i[0] = (((from) & 0xff000000ULL) >> 24); \ |
127 | (di).i[1] = (((from) & 0x00ff0000ULL) >> 16); \ | 142 | (di).i[1] = (((from) & 0x00ff0000ULL) >> 16); \ |
128 | (di).i[2] = (((from) & 0x0000ff00ULL) >> 8); \ | 143 | (di).i[2] = (((from) & 0x0000ff00ULL) >> 8); \ |
129 | (di).i[3] = ((from) & 0x000000ffULL); \ | 144 | (di).i[3] = ((from) & 0x000000ffULL); \ |
130 | } while (0) | 145 | } while (0) |
131 | 146 | ||
132 | #define XFS_DI_HI(di) \ | 147 | #define XFS_DI_HI(di) \ |
133 | (((__u32)(di).i[1] << 16) | ((di).i[2] << 8) | ((di).i[3])) | 148 | (((__u32)(di).i[1] << 16) | ((di).i[2] << 8) | ((di).i[3])) |
134 | #define XFS_DI_LO(di) \ | 149 | #define XFS_DI_LO(di) \ |
135 | (((__u32)(di).i[4] << 24) | ((di).i[5] << 16) | ((di).i[6] << 8) | ((di).i[7])) | 150 | (((__u32)(di).i[4] << 24) | ((di).i[5] << 16) | ((di).i[6] << 8) | ((di).i[7])) |
136 | 151 | ||
137 | #define XFS_GET_DIR_INO8(di) \ | 152 | #define XFS_GET_DIR_INO8(di) \ |
138 | (((xfs_ino_t)XFS_DI_LO(di) & 0xffffffffULL) | \ | 153 | (((xfs_ino_t)XFS_DI_LO(di) & 0xffffffffULL) | \ |
139 | ((xfs_ino_t)XFS_DI_HI(di) << 32)) | 154 | ((xfs_ino_t)XFS_DI_HI(di) << 32)) |
140 | 155 | ||
141 | #define XFS_PUT_DIR_INO8(from, di) \ | 156 | #define XFS_PUT_DIR_INO8(from, di) \ |
142 | do { \ | 157 | do { \ |
143 | (di).i[0] = 0; \ | 158 | (di).i[0] = 0; \ |
144 | (di).i[1] = (((from) & 0x00ff000000000000ULL) >> 48); \ | 159 | (di).i[1] = (((from) & 0x00ff000000000000ULL) >> 48); \ |
145 | (di).i[2] = (((from) & 0x0000ff0000000000ULL) >> 40); \ | 160 | (di).i[2] = (((from) & 0x0000ff0000000000ULL) >> 40); \ |
146 | (di).i[3] = (((from) & 0x000000ff00000000ULL) >> 32); \ | 161 | (di).i[3] = (((from) & 0x000000ff00000000ULL) >> 32); \ |
147 | (di).i[4] = (((from) & 0x00000000ff000000ULL) >> 24); \ | 162 | (di).i[4] = (((from) & 0x00000000ff000000ULL) >> 24); \ |
148 | (di).i[5] = (((from) & 0x0000000000ff0000ULL) >> 16); \ | 163 | (di).i[5] = (((from) & 0x0000000000ff0000ULL) >> 16); \ |
149 | (di).i[6] = (((from) & 0x000000000000ff00ULL) >> 8); \ | 164 | (di).i[6] = (((from) & 0x000000000000ff00ULL) >> 8); \ |
150 | (di).i[7] = ((from) & 0x00000000000000ffULL); \ | 165 | (di).i[7] = ((from) & 0x00000000000000ffULL); \ |
151 | } while (0) | 166 | } while (0) |
152 | 167 | ||
153 | #endif /* __XFS_ARCH_H__ */ | 168 | #endif /* __XFS_ARCH_H__ */ |
154 | 169 |
fs/xfs/xfs_bit.h
1 | /* | 1 | /* |
2 | * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License as | 6 | * modify it under the terms of the GNU General Public License as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | * | 8 | * |
9 | * This program is distributed in the hope that it would be useful, | 9 | * This program is distributed in the hope that it would be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. | 12 | * GNU General Public License for more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License | 14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write the Free Software Foundation, | 15 | * along with this program; if not, write the Free Software Foundation, |
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ | 17 | */ |
18 | #ifndef __XFS_BIT_H__ | 18 | #ifndef __XFS_BIT_H__ |
19 | #define __XFS_BIT_H__ | 19 | #define __XFS_BIT_H__ |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * XFS bit manipulation routines. | 22 | * XFS bit manipulation routines. |
23 | */ | 23 | */ |
24 | 24 | ||
25 | /* | 25 | /* |
26 | * masks with n high/low bits set, 32-bit values & 64-bit values | 26 | * masks with n high/low bits set, 32-bit values & 64-bit values |
27 | */ | 27 | */ |
28 | #define XFS_MASK32HI(n) xfs_mask32hi(n) | 28 | #define XFS_MASK32HI(n) xfs_mask32hi(n) |
29 | static inline __uint32_t xfs_mask32hi(int n) | 29 | static inline __uint32_t xfs_mask32hi(int n) |
30 | { | 30 | { |
31 | return (__uint32_t)-1 << (32 - (n)); | 31 | return (__uint32_t)-1 << (32 - (n)); |
32 | } | 32 | } |
33 | #define XFS_MASK64HI(n) xfs_mask64hi(n) | 33 | #define XFS_MASK64HI(n) xfs_mask64hi(n) |
34 | static inline __uint64_t xfs_mask64hi(int n) | 34 | static inline __uint64_t xfs_mask64hi(int n) |
35 | { | 35 | { |
36 | return (__uint64_t)-1 << (64 - (n)); | 36 | return (__uint64_t)-1 << (64 - (n)); |
37 | } | 37 | } |
38 | #define XFS_MASK32LO(n) xfs_mask32lo(n) | 38 | #define XFS_MASK32LO(n) xfs_mask32lo(n) |
39 | static inline __uint32_t xfs_mask32lo(int n) | 39 | static inline __uint32_t xfs_mask32lo(int n) |
40 | { | 40 | { |
41 | return ((__uint32_t)1 << (n)) - 1; | 41 | return ((__uint32_t)1 << (n)) - 1; |
42 | } | 42 | } |
43 | #define XFS_MASK64LO(n) xfs_mask64lo(n) | 43 | #define XFS_MASK64LO(n) xfs_mask64lo(n) |
44 | static inline __uint64_t xfs_mask64lo(int n) | 44 | static inline __uint64_t xfs_mask64lo(int n) |
45 | { | 45 | { |
46 | return ((__uint64_t)1 << (n)) - 1; | 46 | return ((__uint64_t)1 << (n)) - 1; |
47 | } | 47 | } |
48 | 48 | ||
49 | /* Get high bit set out of 32-bit argument, -1 if none set */ | 49 | /* Get high bit set out of 32-bit argument, -1 if none set */ |
50 | static inline int xfs_highbit32(__uint32_t v) | 50 | static inline int xfs_highbit32(__uint32_t v) |
51 | { | 51 | { |
52 | return fls(v) - 1; | 52 | return fls(v) - 1; |
53 | } | 53 | } |
54 | 54 | ||
55 | /* Get high bit set out of 64-bit argument, -1 if none set */ | 55 | /* Get high bit set out of 64-bit argument, -1 if none set */ |
56 | static inline int xfs_highbit64(__uint64_t v) | 56 | static inline int xfs_highbit64(__uint64_t v) |
57 | { | 57 | { |
58 | return fls64(v) - 1; | 58 | return fls64(v) - 1; |
59 | } | 59 | } |
60 | 60 | ||
61 | /* Get low bit set out of 32-bit argument, -1 if none set */ | 61 | /* Get low bit set out of 32-bit argument, -1 if none set */ |
62 | static inline int xfs_lowbit32(__uint32_t v) | 62 | static inline int xfs_lowbit32(__uint32_t v) |
63 | { | 63 | { |
64 | unsigned long t = v; | 64 | return ffs(v) - 1; |
65 | return (v) ? find_first_bit(&t, 32) : -1; | ||
66 | } | 65 | } |
67 | 66 | ||
68 | /* Get low bit set out of 64-bit argument, -1 if none set */ | 67 | /* Get low bit set out of 64-bit argument, -1 if none set */ |
69 | static inline int xfs_lowbit64(__uint64_t v) | 68 | static inline int xfs_lowbit64(__uint64_t v) |
70 | { | 69 | { |
71 | __uint32_t w = (__uint32_t)v; | 70 | __uint32_t w = (__uint32_t)v; |
72 | int n = 0; | 71 | int n = 0; |
73 | 72 | ||
74 | if (w) { /* lower bits */ | 73 | if (w) { /* lower bits */ |
75 | n = ffs(w); | 74 | n = ffs(w); |
76 | } else { /* upper bits */ | 75 | } else { /* upper bits */ |
77 | w = (__uint32_t)(v >> 32); | 76 | w = (__uint32_t)(v >> 32); |
78 | if (w && (n = ffs(w))) | 77 | if (w && (n = ffs(w))) |
79 | n += 32; | 78 | n += 32; |
80 | } | 79 | } |
81 | return n - 1; | 80 | return n - 1; |
82 | } | 81 | } |
83 | 82 | ||
84 | /* Return whether bitmap is empty (1 == empty) */ | 83 | /* Return whether bitmap is empty (1 == empty) */ |
85 | extern int xfs_bitmap_empty(uint *map, uint size); | 84 | extern int xfs_bitmap_empty(uint *map, uint size); |
86 | 85 | ||
87 | /* Count continuous one bits in map starting with start_bit */ | 86 | /* Count continuous one bits in map starting with start_bit */ |
88 | extern int xfs_contig_bits(uint *map, uint size, uint start_bit); | 87 | extern int xfs_contig_bits(uint *map, uint size, uint start_bit); |
89 | 88 | ||
90 | /* Find next set bit in map */ | 89 | /* Find next set bit in map */ |
91 | extern int xfs_next_bit(uint *map, uint size, uint start_bit); | 90 | extern int xfs_next_bit(uint *map, uint size, uint start_bit); |
92 | 91 | ||
93 | #endif /* __XFS_BIT_H__ */ | 92 | #endif /* __XFS_BIT_H__ */ |
94 | 93 |
fs/xfs/xfs_bmap.h
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License as | 6 | * modify it under the terms of the GNU General Public License as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | * | 8 | * |
9 | * This program is distributed in the hope that it would be useful, | 9 | * This program is distributed in the hope that it would be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. | 12 | * GNU General Public License for more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License | 14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write the Free Software Foundation, | 15 | * along with this program; if not, write the Free Software Foundation, |
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ | 17 | */ |
18 | #ifndef __XFS_BMAP_H__ | 18 | #ifndef __XFS_BMAP_H__ |
19 | #define __XFS_BMAP_H__ | 19 | #define __XFS_BMAP_H__ |
20 | 20 | ||
21 | struct getbmap; | 21 | struct getbmap; |
22 | struct xfs_bmbt_irec; | 22 | struct xfs_bmbt_irec; |
23 | struct xfs_ifork; | 23 | struct xfs_ifork; |
24 | struct xfs_inode; | 24 | struct xfs_inode; |
25 | struct xfs_mount; | 25 | struct xfs_mount; |
26 | struct xfs_trans; | 26 | struct xfs_trans; |
27 | 27 | ||
28 | extern kmem_zone_t *xfs_bmap_free_item_zone; | 28 | extern kmem_zone_t *xfs_bmap_free_item_zone; |
29 | 29 | ||
30 | /* | 30 | /* |
31 | * DELTA: describe a change to the in-core extent list. | 31 | * DELTA: describe a change to the in-core extent list. |
32 | * | 32 | * |
33 | * Internally the use of xed_blockount is somewhat funky. | 33 | * Internally the use of xed_blockount is somewhat funky. |
34 | * xed_blockcount contains an offset much of the time because this | 34 | * xed_blockcount contains an offset much of the time because this |
35 | * makes merging changes easier. (xfs_fileoff_t and xfs_filblks_t are | 35 | * makes merging changes easier. (xfs_fileoff_t and xfs_filblks_t are |
36 | * the same underlying type). | 36 | * the same underlying type). |
37 | */ | 37 | */ |
38 | typedef struct xfs_extdelta | 38 | typedef struct xfs_extdelta |
39 | { | 39 | { |
40 | xfs_fileoff_t xed_startoff; /* offset of range */ | 40 | xfs_fileoff_t xed_startoff; /* offset of range */ |
41 | xfs_filblks_t xed_blockcount; /* blocks in range */ | 41 | xfs_filblks_t xed_blockcount; /* blocks in range */ |
42 | } xfs_extdelta_t; | 42 | } xfs_extdelta_t; |
43 | 43 | ||
44 | /* | 44 | /* |
45 | * List of extents to be free "later". | 45 | * List of extents to be free "later". |
46 | * The list is kept sorted on xbf_startblock. | 46 | * The list is kept sorted on xbf_startblock. |
47 | */ | 47 | */ |
48 | typedef struct xfs_bmap_free_item | 48 | typedef struct xfs_bmap_free_item |
49 | { | 49 | { |
50 | xfs_fsblock_t xbfi_startblock;/* starting fs block number */ | 50 | xfs_fsblock_t xbfi_startblock;/* starting fs block number */ |
51 | xfs_extlen_t xbfi_blockcount;/* number of blocks in extent */ | 51 | xfs_extlen_t xbfi_blockcount;/* number of blocks in extent */ |
52 | struct xfs_bmap_free_item *xbfi_next; /* link to next entry */ | 52 | struct xfs_bmap_free_item *xbfi_next; /* link to next entry */ |
53 | } xfs_bmap_free_item_t; | 53 | } xfs_bmap_free_item_t; |
54 | 54 | ||
55 | /* | 55 | /* |
56 | * Header for free extent list. | 56 | * Header for free extent list. |
57 | * | 57 | * |
58 | * xbf_low is used by the allocator to activate the lowspace algorithm - | 58 | * xbf_low is used by the allocator to activate the lowspace algorithm - |
59 | * when free space is running low the extent allocator may choose to | 59 | * when free space is running low the extent allocator may choose to |
60 | * allocate an extent from an AG without leaving sufficient space for | 60 | * allocate an extent from an AG without leaving sufficient space for |
61 | * a btree split when inserting the new extent. In this case the allocator | 61 | * a btree split when inserting the new extent. In this case the allocator |
62 | * will enable the lowspace algorithm which is supposed to allow further | 62 | * will enable the lowspace algorithm which is supposed to allow further |
63 | * allocations (such as btree splits and newroots) to allocate from | 63 | * allocations (such as btree splits and newroots) to allocate from |
64 | * sequential AGs. In order to avoid locking AGs out of order the lowspace | 64 | * sequential AGs. In order to avoid locking AGs out of order the lowspace |
65 | * algorithm will start searching for free space from AG 0. If the correct | 65 | * algorithm will start searching for free space from AG 0. If the correct |
66 | * transaction reservations have been made then this algorithm will eventually | 66 | * transaction reservations have been made then this algorithm will eventually |
67 | * find all the space it needs. | 67 | * find all the space it needs. |
68 | */ | 68 | */ |
69 | typedef struct xfs_bmap_free | 69 | typedef struct xfs_bmap_free |
70 | { | 70 | { |
71 | xfs_bmap_free_item_t *xbf_first; /* list of to-be-free extents */ | 71 | xfs_bmap_free_item_t *xbf_first; /* list of to-be-free extents */ |
72 | int xbf_count; /* count of items on list */ | 72 | int xbf_count; /* count of items on list */ |
73 | int xbf_low; /* alloc in low mode */ | 73 | int xbf_low; /* alloc in low mode */ |
74 | } xfs_bmap_free_t; | 74 | } xfs_bmap_free_t; |
75 | 75 | ||
76 | #define XFS_BMAP_MAX_NMAP 4 | 76 | #define XFS_BMAP_MAX_NMAP 4 |
77 | 77 | ||
78 | /* | 78 | /* |
79 | * Flags for xfs_bmapi | 79 | * Flags for xfs_bmapi |
80 | */ | 80 | */ |
81 | #define XFS_BMAPI_WRITE 0x001 /* write operation: allocate space */ | 81 | #define XFS_BMAPI_WRITE 0x001 /* write operation: allocate space */ |
82 | #define XFS_BMAPI_DELAY 0x002 /* delayed write operation */ | 82 | #define XFS_BMAPI_DELAY 0x002 /* delayed write operation */ |
83 | #define XFS_BMAPI_ENTIRE 0x004 /* return entire extent, not trimmed */ | 83 | #define XFS_BMAPI_ENTIRE 0x004 /* return entire extent, not trimmed */ |
84 | #define XFS_BMAPI_METADATA 0x008 /* mapping metadata not user data */ | 84 | #define XFS_BMAPI_METADATA 0x008 /* mapping metadata not user data */ |
85 | #define XFS_BMAPI_EXACT 0x010 /* allocate only to spec'd bounds */ | 85 | #define XFS_BMAPI_EXACT 0x010 /* allocate only to spec'd bounds */ |
86 | #define XFS_BMAPI_ATTRFORK 0x020 /* use attribute fork not data */ | 86 | #define XFS_BMAPI_ATTRFORK 0x020 /* use attribute fork not data */ |
87 | #define XFS_BMAPI_ASYNC 0x040 /* bunmapi xactions can be async */ | 87 | #define XFS_BMAPI_ASYNC 0x040 /* bunmapi xactions can be async */ |
88 | #define XFS_BMAPI_RSVBLOCKS 0x080 /* OK to alloc. reserved data blocks */ | 88 | #define XFS_BMAPI_RSVBLOCKS 0x080 /* OK to alloc. reserved data blocks */ |
89 | #define XFS_BMAPI_PREALLOC 0x100 /* preallocation op: unwritten space */ | 89 | #define XFS_BMAPI_PREALLOC 0x100 /* preallocation op: unwritten space */ |
90 | #define XFS_BMAPI_IGSTATE 0x200 /* Ignore state - */ | 90 | #define XFS_BMAPI_IGSTATE 0x200 /* Ignore state - */ |
91 | /* combine contig. space */ | 91 | /* combine contig. space */ |
92 | #define XFS_BMAPI_CONTIG 0x400 /* must allocate only one extent */ | 92 | #define XFS_BMAPI_CONTIG 0x400 /* must allocate only one extent */ |
93 | /* XFS_BMAPI_DIRECT_IO 0x800 */ | 93 | /* XFS_BMAPI_DIRECT_IO 0x800 */ |
94 | #define XFS_BMAPI_CONVERT 0x1000 /* unwritten extent conversion - */ | 94 | #define XFS_BMAPI_CONVERT 0x1000 /* unwritten extent conversion - */ |
95 | /* need write cache flushing and no */ | 95 | /* need write cache flushing and no */ |
96 | /* additional allocation alignments */ | 96 | /* additional allocation alignments */ |
97 | 97 | ||
98 | #define XFS_BMAPI_AFLAG(w) xfs_bmapi_aflag(w) | 98 | #define XFS_BMAPI_AFLAG(w) xfs_bmapi_aflag(w) |
99 | static inline int xfs_bmapi_aflag(int w) | 99 | static inline int xfs_bmapi_aflag(int w) |
100 | { | 100 | { |
101 | return (w == XFS_ATTR_FORK ? XFS_BMAPI_ATTRFORK : 0); | 101 | return (w == XFS_ATTR_FORK ? XFS_BMAPI_ATTRFORK : 0); |
102 | } | 102 | } |
103 | 103 | ||
104 | /* | 104 | /* |
105 | * Special values for xfs_bmbt_irec_t br_startblock field. | 105 | * Special values for xfs_bmbt_irec_t br_startblock field. |
106 | */ | 106 | */ |
107 | #define DELAYSTARTBLOCK ((xfs_fsblock_t)-1LL) | 107 | #define DELAYSTARTBLOCK ((xfs_fsblock_t)-1LL) |
108 | #define HOLESTARTBLOCK ((xfs_fsblock_t)-2LL) | 108 | #define HOLESTARTBLOCK ((xfs_fsblock_t)-2LL) |
109 | 109 | ||
110 | #define XFS_BMAP_INIT(flp,fbp) xfs_bmap_init(flp,fbp) | 110 | #define XFS_BMAP_INIT(flp,fbp) xfs_bmap_init(flp,fbp) |
111 | static inline void xfs_bmap_init(xfs_bmap_free_t *flp, xfs_fsblock_t *fbp) | 111 | static inline void xfs_bmap_init(xfs_bmap_free_t *flp, xfs_fsblock_t *fbp) |
112 | { | 112 | { |
113 | ((flp)->xbf_first = NULL, (flp)->xbf_count = 0, \ | 113 | ((flp)->xbf_first = NULL, (flp)->xbf_count = 0, \ |
114 | (flp)->xbf_low = 0, *(fbp) = NULLFSBLOCK); | 114 | (flp)->xbf_low = 0, *(fbp) = NULLFSBLOCK); |
115 | } | 115 | } |
116 | 116 | ||
117 | /* | 117 | /* |
118 | * Argument structure for xfs_bmap_alloc. | 118 | * Argument structure for xfs_bmap_alloc. |
119 | */ | 119 | */ |
120 | typedef struct xfs_bmalloca { | 120 | typedef struct xfs_bmalloca { |
121 | xfs_fsblock_t firstblock; /* i/o first block allocated */ | 121 | xfs_fsblock_t firstblock; /* i/o first block allocated */ |
122 | xfs_fsblock_t rval; /* starting block of new extent */ | 122 | xfs_fsblock_t rval; /* starting block of new extent */ |
123 | xfs_fileoff_t off; /* offset in file filling in */ | 123 | xfs_fileoff_t off; /* offset in file filling in */ |
124 | struct xfs_trans *tp; /* transaction pointer */ | 124 | struct xfs_trans *tp; /* transaction pointer */ |
125 | struct xfs_inode *ip; /* incore inode pointer */ | 125 | struct xfs_inode *ip; /* incore inode pointer */ |
126 | struct xfs_bmbt_irec *prevp; /* extent before the new one */ | 126 | struct xfs_bmbt_irec *prevp; /* extent before the new one */ |
127 | struct xfs_bmbt_irec *gotp; /* extent after, or delayed */ | 127 | struct xfs_bmbt_irec *gotp; /* extent after, or delayed */ |
128 | xfs_extlen_t alen; /* i/o length asked/allocated */ | 128 | xfs_extlen_t alen; /* i/o length asked/allocated */ |
129 | xfs_extlen_t total; /* total blocks needed for xaction */ | 129 | xfs_extlen_t total; /* total blocks needed for xaction */ |
130 | xfs_extlen_t minlen; /* mininum allocation size (blocks) */ | 130 | xfs_extlen_t minlen; /* mininum allocation size (blocks) */ |
131 | xfs_extlen_t minleft; /* amount must be left after alloc */ | 131 | xfs_extlen_t minleft; /* amount must be left after alloc */ |
132 | char eof; /* set if allocating past last extent */ | 132 | char eof; /* set if allocating past last extent */ |
133 | char wasdel; /* replacing a delayed allocation */ | 133 | char wasdel; /* replacing a delayed allocation */ |
134 | char userdata;/* set if is user data */ | 134 | char userdata;/* set if is user data */ |
135 | char low; /* low on space, using seq'l ags */ | 135 | char low; /* low on space, using seq'l ags */ |
136 | char aeof; /* allocated space at eof */ | 136 | char aeof; /* allocated space at eof */ |
137 | char conv; /* overwriting unwritten extents */ | 137 | char conv; /* overwriting unwritten extents */ |
138 | } xfs_bmalloca_t; | 138 | } xfs_bmalloca_t; |
139 | 139 | ||
140 | #ifdef __KERNEL__ | 140 | #if defined(__KERNEL__) && defined(XFS_BMAP_TRACE) |
141 | |||
142 | #if defined(XFS_BMAP_TRACE) | ||
143 | /* | 141 | /* |
144 | * Trace operations for bmap extent tracing | 142 | * Trace operations for bmap extent tracing |
145 | */ | 143 | */ |
146 | #define XFS_BMAP_KTRACE_DELETE 1 | 144 | #define XFS_BMAP_KTRACE_DELETE 1 |
147 | #define XFS_BMAP_KTRACE_INSERT 2 | 145 | #define XFS_BMAP_KTRACE_INSERT 2 |
148 | #define XFS_BMAP_KTRACE_PRE_UP 3 | 146 | #define XFS_BMAP_KTRACE_PRE_UP 3 |
149 | #define XFS_BMAP_KTRACE_POST_UP 4 | 147 | #define XFS_BMAP_KTRACE_POST_UP 4 |
150 | 148 | ||
151 | #define XFS_BMAP_TRACE_SIZE 4096 /* size of global trace buffer */ | 149 | #define XFS_BMAP_TRACE_SIZE 4096 /* size of global trace buffer */ |
152 | #define XFS_BMAP_KTRACE_SIZE 32 /* size of per-inode trace buffer */ | 150 | #define XFS_BMAP_KTRACE_SIZE 32 /* size of per-inode trace buffer */ |
153 | extern ktrace_t *xfs_bmap_trace_buf; | 151 | extern ktrace_t *xfs_bmap_trace_buf; |
154 | 152 | ||
155 | /* | 153 | /* |
156 | * Add bmap trace insert entries for all the contents of the extent list. | 154 | * Add bmap trace insert entries for all the contents of the extent list. |
157 | */ | 155 | */ |
158 | void | 156 | void |
159 | xfs_bmap_trace_exlist( | 157 | xfs_bmap_trace_exlist( |
160 | const char *fname, /* function name */ | 158 | const char *fname, /* function name */ |
161 | struct xfs_inode *ip, /* incore inode pointer */ | 159 | struct xfs_inode *ip, /* incore inode pointer */ |
162 | xfs_extnum_t cnt, /* count of entries in list */ | 160 | xfs_extnum_t cnt, /* count of entries in list */ |
163 | int whichfork); /* data or attr fork */ | 161 | int whichfork); /* data or attr fork */ |
164 | #define XFS_BMAP_TRACE_EXLIST(ip,c,w) \ | 162 | #define XFS_BMAP_TRACE_EXLIST(ip,c,w) \ |
165 | xfs_bmap_trace_exlist(__func__,ip,c,w) | 163 | xfs_bmap_trace_exlist(__func__,ip,c,w) |
166 | #else | 164 | |
165 | #else /* __KERNEL__ && XFS_BMAP_TRACE */ | ||
166 | |||
167 | #define XFS_BMAP_TRACE_EXLIST(ip,c,w) | 167 | #define XFS_BMAP_TRACE_EXLIST(ip,c,w) |
168 | #endif | ||
169 | 168 | ||
169 | #endif /* __KERNEL__ && XFS_BMAP_TRACE */ | ||
170 | |||
170 | /* | 171 | /* |
171 | * Convert inode from non-attributed to attributed. | 172 | * Convert inode from non-attributed to attributed. |
172 | * Must not be in a transaction, ip must not be locked. | 173 | * Must not be in a transaction, ip must not be locked. |
173 | */ | 174 | */ |
174 | int /* error code */ | 175 | int /* error code */ |
175 | xfs_bmap_add_attrfork( | 176 | xfs_bmap_add_attrfork( |
176 | struct xfs_inode *ip, /* incore inode pointer */ | 177 | struct xfs_inode *ip, /* incore inode pointer */ |
177 | int size, /* space needed for new attribute */ | 178 | int size, /* space needed for new attribute */ |
178 | int rsvd); /* flag for reserved block allocation */ | 179 | int rsvd); /* flag for reserved block allocation */ |
179 | 180 | ||
180 | /* | 181 | /* |
181 | * Add the extent to the list of extents to be free at transaction end. | 182 | * Add the extent to the list of extents to be free at transaction end. |
182 | * The list is maintained sorted (by block number). | 183 | * The list is maintained sorted (by block number). |
183 | */ | 184 | */ |
184 | void | 185 | void |
185 | xfs_bmap_add_free( | 186 | xfs_bmap_add_free( |
186 | xfs_fsblock_t bno, /* fs block number of extent */ | 187 | xfs_fsblock_t bno, /* fs block number of extent */ |
187 | xfs_filblks_t len, /* length of extent */ | 188 | xfs_filblks_t len, /* length of extent */ |
188 | xfs_bmap_free_t *flist, /* list of extents */ | 189 | xfs_bmap_free_t *flist, /* list of extents */ |
189 | struct xfs_mount *mp); /* mount point structure */ | 190 | struct xfs_mount *mp); /* mount point structure */ |
190 | 191 | ||
191 | /* | 192 | /* |
192 | * Routine to clean up the free list data structure when | 193 | * Routine to clean up the free list data structure when |
193 | * an error occurs during a transaction. | 194 | * an error occurs during a transaction. |
194 | */ | 195 | */ |
195 | void | 196 | void |
196 | xfs_bmap_cancel( | 197 | xfs_bmap_cancel( |
197 | xfs_bmap_free_t *flist); /* free list to clean up */ | 198 | xfs_bmap_free_t *flist); /* free list to clean up */ |
198 | 199 | ||
199 | /* | 200 | /* |
200 | * Compute and fill in the value of the maximum depth of a bmap btree | 201 | * Compute and fill in the value of the maximum depth of a bmap btree |
201 | * in this filesystem. Done once, during mount. | 202 | * in this filesystem. Done once, during mount. |
202 | */ | 203 | */ |
203 | void | 204 | void |
204 | xfs_bmap_compute_maxlevels( | 205 | xfs_bmap_compute_maxlevels( |
205 | struct xfs_mount *mp, /* file system mount structure */ | 206 | struct xfs_mount *mp, /* file system mount structure */ |
206 | int whichfork); /* data or attr fork */ | 207 | int whichfork); /* data or attr fork */ |
207 | 208 | ||
208 | /* | 209 | /* |
209 | * Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi | ||
210 | * caller. Frees all the extents that need freeing, which must be done | ||
211 | * last due to locking considerations. | ||
212 | * | ||
213 | * Return 1 if the given transaction was committed and a new one allocated, | ||
214 | * and 0 otherwise. | ||
215 | */ | ||
216 | int /* error */ | ||
217 | xfs_bmap_finish( | ||
218 | struct xfs_trans **tp, /* transaction pointer addr */ | ||
219 | xfs_bmap_free_t *flist, /* i/o: list extents to free */ | ||
220 | int *committed); /* xact committed or not */ | ||
221 | |||
222 | /* | ||
223 | * Returns the file-relative block number of the first unused block in the file. | 210 | * Returns the file-relative block number of the first unused block in the file. |
224 | * This is the lowest-address hole if the file has holes, else the first block | 211 | * This is the lowest-address hole if the file has holes, else the first block |
225 | * past the end of file. | 212 | * past the end of file. |
226 | */ | 213 | */ |
227 | int /* error */ | 214 | int /* error */ |
228 | xfs_bmap_first_unused( | 215 | xfs_bmap_first_unused( |
229 | struct xfs_trans *tp, /* transaction pointer */ | 216 | struct xfs_trans *tp, /* transaction pointer */ |
230 | struct xfs_inode *ip, /* incore inode */ | 217 | struct xfs_inode *ip, /* incore inode */ |
231 | xfs_extlen_t len, /* size of hole to find */ | 218 | xfs_extlen_t len, /* size of hole to find */ |
232 | xfs_fileoff_t *unused, /* unused block num */ | 219 | xfs_fileoff_t *unused, /* unused block num */ |
233 | int whichfork); /* data or attr fork */ | 220 | int whichfork); /* data or attr fork */ |
234 | 221 | ||
235 | /* | 222 | /* |
236 | * Returns the file-relative block number of the last block + 1 before | 223 | * Returns the file-relative block number of the last block + 1 before |
237 | * last_block (input value) in the file. | 224 | * last_block (input value) in the file. |
238 | * This is not based on i_size, it is based on the extent list. | 225 | * This is not based on i_size, it is based on the extent list. |
239 | * Returns 0 for local files, as they do not have an extent list. | 226 | * Returns 0 for local files, as they do not have an extent list. |
240 | */ | 227 | */ |
241 | int /* error */ | 228 | int /* error */ |
242 | xfs_bmap_last_before( | 229 | xfs_bmap_last_before( |
243 | struct xfs_trans *tp, /* transaction pointer */ | 230 | struct xfs_trans *tp, /* transaction pointer */ |
244 | struct xfs_inode *ip, /* incore inode */ | 231 | struct xfs_inode *ip, /* incore inode */ |
245 | xfs_fileoff_t *last_block, /* last block */ | 232 | xfs_fileoff_t *last_block, /* last block */ |
246 | int whichfork); /* data or attr fork */ | 233 | int whichfork); /* data or attr fork */ |
247 | 234 | ||
248 | /* | 235 | /* |
249 | * Returns the file-relative block number of the first block past eof in | 236 | * Returns the file-relative block number of the first block past eof in |
250 | * the file. This is not based on i_size, it is based on the extent list. | 237 | * the file. This is not based on i_size, it is based on the extent list. |
251 | * Returns 0 for local files, as they do not have an extent list. | 238 | * Returns 0 for local files, as they do not have an extent list. |
252 | */ | 239 | */ |
253 | int /* error */ | 240 | int /* error */ |
254 | xfs_bmap_last_offset( | 241 | xfs_bmap_last_offset( |
255 | struct xfs_trans *tp, /* transaction pointer */ | 242 | struct xfs_trans *tp, /* transaction pointer */ |
256 | struct xfs_inode *ip, /* incore inode */ | 243 | struct xfs_inode *ip, /* incore inode */ |
257 | xfs_fileoff_t *unused, /* last block num */ | 244 | xfs_fileoff_t *unused, /* last block num */ |
258 | int whichfork); /* data or attr fork */ | 245 | int whichfork); /* data or attr fork */ |
259 | 246 | ||
260 | /* | 247 | /* |
261 | * Returns whether the selected fork of the inode has exactly one | 248 | * Returns whether the selected fork of the inode has exactly one |
262 | * block or not. For the data fork we check this matches di_size, | 249 | * block or not. For the data fork we check this matches di_size, |
263 | * implying the file's range is 0..bsize-1. | 250 | * implying the file's range is 0..bsize-1. |
264 | */ | 251 | */ |
265 | int | 252 | int |
266 | xfs_bmap_one_block( | 253 | xfs_bmap_one_block( |
267 | struct xfs_inode *ip, /* incore inode */ | 254 | struct xfs_inode *ip, /* incore inode */ |
268 | int whichfork); /* data or attr fork */ | 255 | int whichfork); /* data or attr fork */ |
269 | 256 | ||
270 | /* | 257 | /* |
271 | * Read in the extents to iu_extents. | 258 | * Read in the extents to iu_extents. |
272 | * All inode fields are set up by caller, we just traverse the btree | 259 | * All inode fields are set up by caller, we just traverse the btree |
273 | * and copy the records in. | 260 | * and copy the records in. |
274 | */ | 261 | */ |
275 | int /* error */ | 262 | int /* error */ |
276 | xfs_bmap_read_extents( | 263 | xfs_bmap_read_extents( |
277 | struct xfs_trans *tp, /* transaction pointer */ | 264 | struct xfs_trans *tp, /* transaction pointer */ |
278 | struct xfs_inode *ip, /* incore inode */ | 265 | struct xfs_inode *ip, /* incore inode */ |
279 | int whichfork); /* data or attr fork */ | 266 | int whichfork); /* data or attr fork */ |
280 | 267 | ||
281 | /* | 268 | /* |
282 | * Map file blocks to filesystem blocks. | 269 | * Map file blocks to filesystem blocks. |
283 | * File range is given by the bno/len pair. | 270 | * File range is given by the bno/len pair. |
284 | * Adds blocks to file if a write ("flags & XFS_BMAPI_WRITE" set) | 271 | * Adds blocks to file if a write ("flags & XFS_BMAPI_WRITE" set) |
285 | * into a hole or past eof. | 272 | * into a hole or past eof. |
286 | * Only allocates blocks from a single allocation group, | 273 | * Only allocates blocks from a single allocation group, |
287 | * to avoid locking problems. | 274 | * to avoid locking problems. |
288 | * The returned value in "firstblock" from the first call in a transaction | 275 | * The returned value in "firstblock" from the first call in a transaction |
289 | * must be remembered and presented to subsequent calls in "firstblock". | 276 | * must be remembered and presented to subsequent calls in "firstblock". |
290 | * An upper bound for the number of blocks to be allocated is supplied to | 277 | * An upper bound for the number of blocks to be allocated is supplied to |
291 | * the first call in "total"; if no allocation group has that many free | 278 | * the first call in "total"; if no allocation group has that many free |
292 | * blocks then the call will fail (return NULLFSBLOCK in "firstblock"). | 279 | * blocks then the call will fail (return NULLFSBLOCK in "firstblock"). |
293 | */ | 280 | */ |
294 | int /* error */ | 281 | int /* error */ |
295 | xfs_bmapi( | 282 | xfs_bmapi( |
296 | struct xfs_trans *tp, /* transaction pointer */ | 283 | struct xfs_trans *tp, /* transaction pointer */ |
297 | struct xfs_inode *ip, /* incore inode */ | 284 | struct xfs_inode *ip, /* incore inode */ |
298 | xfs_fileoff_t bno, /* starting file offs. mapped */ | 285 | xfs_fileoff_t bno, /* starting file offs. mapped */ |
299 | xfs_filblks_t len, /* length to map in file */ | 286 | xfs_filblks_t len, /* length to map in file */ |
300 | int flags, /* XFS_BMAPI_... */ | 287 | int flags, /* XFS_BMAPI_... */ |
301 | xfs_fsblock_t *firstblock, /* first allocated block | 288 | xfs_fsblock_t *firstblock, /* first allocated block |
302 | controls a.g. for allocs */ | 289 | controls a.g. for allocs */ |
303 | xfs_extlen_t total, /* total blocks needed */ | 290 | xfs_extlen_t total, /* total blocks needed */ |
304 | struct xfs_bmbt_irec *mval, /* output: map values */ | 291 | struct xfs_bmbt_irec *mval, /* output: map values */ |
305 | int *nmap, /* i/o: mval size/count */ | 292 | int *nmap, /* i/o: mval size/count */ |
306 | xfs_bmap_free_t *flist, /* i/o: list extents to free */ | 293 | xfs_bmap_free_t *flist, /* i/o: list extents to free */ |
307 | xfs_extdelta_t *delta); /* o: change made to incore | 294 | xfs_extdelta_t *delta); /* o: change made to incore |
308 | extents */ | 295 | extents */ |
309 | 296 | ||
310 | /* | 297 | /* |
311 | * Map file blocks to filesystem blocks, simple version. | 298 | * Map file blocks to filesystem blocks, simple version. |
312 | * One block only, read-only. | 299 | * One block only, read-only. |
313 | * For flags, only the XFS_BMAPI_ATTRFORK flag is examined. | 300 | * For flags, only the XFS_BMAPI_ATTRFORK flag is examined. |
314 | * For the other flag values, the effect is as if XFS_BMAPI_METADATA | 301 | * For the other flag values, the effect is as if XFS_BMAPI_METADATA |
315 | * was set and all the others were clear. | 302 | * was set and all the others were clear. |
316 | */ | 303 | */ |
317 | int /* error */ | 304 | int /* error */ |
318 | xfs_bmapi_single( | 305 | xfs_bmapi_single( |
319 | struct xfs_trans *tp, /* transaction pointer */ | 306 | struct xfs_trans *tp, /* transaction pointer */ |
320 | struct xfs_inode *ip, /* incore inode */ | 307 | struct xfs_inode *ip, /* incore inode */ |
321 | int whichfork, /* data or attr fork */ | 308 | int whichfork, /* data or attr fork */ |
322 | xfs_fsblock_t *fsb, /* output: mapped block */ | 309 | xfs_fsblock_t *fsb, /* output: mapped block */ |
323 | xfs_fileoff_t bno); /* starting file offs. mapped */ | 310 | xfs_fileoff_t bno); /* starting file offs. mapped */ |
324 | 311 | ||
325 | /* | 312 | /* |
326 | * Unmap (remove) blocks from a file. | 313 | * Unmap (remove) blocks from a file. |
327 | * If nexts is nonzero then the number of extents to remove is limited to | 314 | * If nexts is nonzero then the number of extents to remove is limited to |
328 | * that value. If not all extents in the block range can be removed then | 315 | * that value. If not all extents in the block range can be removed then |
329 | * *done is set. | 316 | * *done is set. |
330 | */ | 317 | */ |
331 | int /* error */ | 318 | int /* error */ |
332 | xfs_bunmapi( | 319 | xfs_bunmapi( |
333 | struct xfs_trans *tp, /* transaction pointer */ | 320 | struct xfs_trans *tp, /* transaction pointer */ |
334 | struct xfs_inode *ip, /* incore inode */ | 321 | struct xfs_inode *ip, /* incore inode */ |
335 | xfs_fileoff_t bno, /* starting offset to unmap */ | 322 | xfs_fileoff_t bno, /* starting offset to unmap */ |
336 | xfs_filblks_t len, /* length to unmap in file */ | 323 | xfs_filblks_t len, /* length to unmap in file */ |
337 | int flags, /* XFS_BMAPI_... */ | 324 | int flags, /* XFS_BMAPI_... */ |
338 | xfs_extnum_t nexts, /* number of extents max */ | 325 | xfs_extnum_t nexts, /* number of extents max */ |
339 | xfs_fsblock_t *firstblock, /* first allocated block | 326 | xfs_fsblock_t *firstblock, /* first allocated block |
340 | controls a.g. for allocs */ | 327 | controls a.g. for allocs */ |
341 | xfs_bmap_free_t *flist, /* i/o: list extents to free */ | 328 | xfs_bmap_free_t *flist, /* i/o: list extents to free */ |
342 | xfs_extdelta_t *delta, /* o: change made to incore | 329 | xfs_extdelta_t *delta, /* o: change made to incore |
343 | extents */ | 330 | extents */ |
344 | int *done); /* set if not done yet */ | 331 | int *done); /* set if not done yet */ |
345 | 332 | ||
346 | /* | 333 | /* |
334 | * Check an extent list, which has just been read, for | ||
335 | * any bit in the extent flag field. | ||
336 | */ | ||
337 | int | ||
338 | xfs_check_nostate_extents( | ||
339 | struct xfs_ifork *ifp, | ||
340 | xfs_extnum_t idx, | ||
341 | xfs_extnum_t num); | ||
342 | |||
343 | #ifdef __KERNEL__ | ||
344 | |||
345 | /* | ||
346 | * Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi | ||
347 | * caller. Frees all the extents that need freeing, which must be done | ||
348 | * last due to locking considerations. | ||
349 | * | ||
350 | * Return 1 if the given transaction was committed and a new one allocated, | ||
351 | * and 0 otherwise. | ||
352 | */ | ||
353 | int /* error */ | ||
354 | xfs_bmap_finish( | ||
355 | struct xfs_trans **tp, /* transaction pointer addr */ | ||
356 | xfs_bmap_free_t *flist, /* i/o: list extents to free */ | ||
357 | int *committed); /* xact committed or not */ | ||
358 | |||
359 | /* | ||
347 | * Fcntl interface to xfs_bmapi. | 360 | * Fcntl interface to xfs_bmapi. |
348 | */ | 361 | */ |
349 | int /* error code */ | 362 | int /* error code */ |
350 | xfs_getbmap( | 363 | xfs_getbmap( |
351 | xfs_inode_t *ip, | 364 | xfs_inode_t *ip, |
352 | struct getbmap *bmv, /* user bmap structure */ | 365 | struct getbmap *bmv, /* user bmap structure */ |
353 | void __user *ap, /* pointer to user's array */ | 366 | void __user *ap, /* pointer to user's array */ |
354 | int iflags); /* interface flags */ | 367 | int iflags); /* interface flags */ |
355 | 368 | ||
356 | /* | 369 | /* |
357 | * Check if the endoff is outside the last extent. If so the caller will grow | 370 | * Check if the endoff is outside the last extent. If so the caller will grow |
358 | * the allocation to a stripe unit boundary | 371 | * the allocation to a stripe unit boundary |
359 | */ | 372 | */ |
360 | int | 373 | int |
361 | xfs_bmap_eof( | 374 | xfs_bmap_eof( |
362 | struct xfs_inode *ip, | 375 | struct xfs_inode *ip, |
363 | xfs_fileoff_t endoff, | 376 | xfs_fileoff_t endoff, |
364 | int whichfork, | 377 | int whichfork, |
365 | int *eof); | 378 | int *eof); |
366 | 379 | ||
367 | /* | 380 | /* |
368 | * Count fsblocks of the given fork. | 381 | * Count fsblocks of the given fork. |
369 | */ | 382 | */ |
370 | int | 383 | int |
371 | xfs_bmap_count_blocks( | 384 | xfs_bmap_count_blocks( |
372 | xfs_trans_t *tp, | 385 | xfs_trans_t *tp, |
373 | struct xfs_inode *ip, | 386 | struct xfs_inode *ip, |
374 | int whichfork, | 387 | int whichfork, |
fs/xfs/xfs_bmap_btree.h
1 | /* | 1 | /* |
2 | * Copyright (c) 2000,2002-2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000,2002-2005 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License as | 6 | * modify it under the terms of the GNU General Public License as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | * | 8 | * |
9 | * This program is distributed in the hope that it would be useful, | 9 | * This program is distributed in the hope that it would be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. | 12 | * GNU General Public License for more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License | 14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write the Free Software Foundation, | 15 | * along with this program; if not, write the Free Software Foundation, |
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ | 17 | */ |
18 | #ifndef __XFS_BMAP_BTREE_H__ | 18 | #ifndef __XFS_BMAP_BTREE_H__ |
19 | #define __XFS_BMAP_BTREE_H__ | 19 | #define __XFS_BMAP_BTREE_H__ |
20 | 20 | ||
21 | #define XFS_BMAP_MAGIC 0x424d4150 /* 'BMAP' */ | 21 | #define XFS_BMAP_MAGIC 0x424d4150 /* 'BMAP' */ |
22 | 22 | ||
23 | struct xfs_btree_cur; | 23 | struct xfs_btree_cur; |
24 | struct xfs_btree_lblock; | 24 | struct xfs_btree_lblock; |
25 | struct xfs_mount; | 25 | struct xfs_mount; |
26 | struct xfs_inode; | 26 | struct xfs_inode; |
27 | struct xfs_trans; | 27 | struct xfs_trans; |
28 | 28 | ||
29 | /* | 29 | /* |
30 | * Bmap root header, on-disk form only. | 30 | * Bmap root header, on-disk form only. |
31 | */ | 31 | */ |
32 | typedef struct xfs_bmdr_block { | 32 | typedef struct xfs_bmdr_block { |
33 | __be16 bb_level; /* 0 is a leaf */ | 33 | __be16 bb_level; /* 0 is a leaf */ |
34 | __be16 bb_numrecs; /* current # of data records */ | 34 | __be16 bb_numrecs; /* current # of data records */ |
35 | } xfs_bmdr_block_t; | 35 | } xfs_bmdr_block_t; |
36 | 36 | ||
37 | /* | 37 | /* |
38 | * Bmap btree record and extent descriptor. | 38 | * Bmap btree record and extent descriptor. |
39 | * l0:63 is an extent flag (value 1 indicates non-normal). | 39 | * l0:63 is an extent flag (value 1 indicates non-normal). |
40 | * l0:9-62 are startoff. | 40 | * l0:9-62 are startoff. |
41 | * l0:0-8 and l1:21-63 are startblock. | 41 | * l0:0-8 and l1:21-63 are startblock. |
42 | * l1:0-20 are blockcount. | 42 | * l1:0-20 are blockcount. |
43 | */ | 43 | */ |
44 | #define BMBT_EXNTFLAG_BITLEN 1 | 44 | #define BMBT_EXNTFLAG_BITLEN 1 |
45 | #define BMBT_STARTOFF_BITLEN 54 | 45 | #define BMBT_STARTOFF_BITLEN 54 |
46 | #define BMBT_STARTBLOCK_BITLEN 52 | 46 | #define BMBT_STARTBLOCK_BITLEN 52 |
47 | #define BMBT_BLOCKCOUNT_BITLEN 21 | 47 | #define BMBT_BLOCKCOUNT_BITLEN 21 |
48 | 48 | ||
49 | 49 | ||
50 | #define BMBT_USE_64 1 | 50 | #define BMBT_USE_64 1 |
51 | 51 | ||
52 | typedef struct xfs_bmbt_rec_32 | 52 | typedef struct xfs_bmbt_rec_32 |
53 | { | 53 | { |
54 | __uint32_t l0, l1, l2, l3; | 54 | __uint32_t l0, l1, l2, l3; |
55 | } xfs_bmbt_rec_32_t; | 55 | } xfs_bmbt_rec_32_t; |
56 | typedef struct xfs_bmbt_rec_64 | 56 | typedef struct xfs_bmbt_rec_64 |
57 | { | 57 | { |
58 | __be64 l0, l1; | 58 | __be64 l0, l1; |
59 | } xfs_bmbt_rec_64_t; | 59 | } xfs_bmbt_rec_64_t; |
60 | 60 | ||
61 | typedef __uint64_t xfs_bmbt_rec_base_t; /* use this for casts */ | 61 | typedef __uint64_t xfs_bmbt_rec_base_t; /* use this for casts */ |
62 | typedef xfs_bmbt_rec_64_t xfs_bmbt_rec_t, xfs_bmdr_rec_t; | 62 | typedef xfs_bmbt_rec_64_t xfs_bmbt_rec_t, xfs_bmdr_rec_t; |
63 | 63 | ||
64 | typedef struct xfs_bmbt_rec_host { | 64 | typedef struct xfs_bmbt_rec_host { |
65 | __uint64_t l0, l1; | 65 | __uint64_t l0, l1; |
66 | } xfs_bmbt_rec_host_t; | 66 | } xfs_bmbt_rec_host_t; |
67 | 67 | ||
68 | /* | 68 | /* |
69 | * Values and macros for delayed-allocation startblock fields. | 69 | * Values and macros for delayed-allocation startblock fields. |
70 | */ | 70 | */ |
71 | #define STARTBLOCKVALBITS 17 | 71 | #define STARTBLOCKVALBITS 17 |
72 | #define STARTBLOCKMASKBITS (15 + XFS_BIG_BLKNOS * 20) | 72 | #define STARTBLOCKMASKBITS (15 + XFS_BIG_BLKNOS * 20) |
73 | #define DSTARTBLOCKMASKBITS (15 + 20) | 73 | #define DSTARTBLOCKMASKBITS (15 + 20) |
74 | #define STARTBLOCKMASK \ | 74 | #define STARTBLOCKMASK \ |
75 | (((((xfs_fsblock_t)1) << STARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS) | 75 | (((((xfs_fsblock_t)1) << STARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS) |
76 | #define DSTARTBLOCKMASK \ | 76 | #define DSTARTBLOCKMASK \ |
77 | (((((xfs_dfsbno_t)1) << DSTARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS) | 77 | (((((xfs_dfsbno_t)1) << DSTARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS) |
78 | 78 | ||
79 | #define ISNULLSTARTBLOCK(x) isnullstartblock(x) | 79 | #define ISNULLSTARTBLOCK(x) isnullstartblock(x) |
80 | static inline int isnullstartblock(xfs_fsblock_t x) | 80 | static inline int isnullstartblock(xfs_fsblock_t x) |
81 | { | 81 | { |
82 | return ((x) & STARTBLOCKMASK) == STARTBLOCKMASK; | 82 | return ((x) & STARTBLOCKMASK) == STARTBLOCKMASK; |
83 | } | 83 | } |
84 | 84 | ||
85 | #define ISNULLDSTARTBLOCK(x) isnulldstartblock(x) | 85 | #define ISNULLDSTARTBLOCK(x) isnulldstartblock(x) |
86 | static inline int isnulldstartblock(xfs_dfsbno_t x) | 86 | static inline int isnulldstartblock(xfs_dfsbno_t x) |
87 | { | 87 | { |
88 | return ((x) & DSTARTBLOCKMASK) == DSTARTBLOCKMASK; | 88 | return ((x) & DSTARTBLOCKMASK) == DSTARTBLOCKMASK; |
89 | } | 89 | } |
90 | 90 | ||
91 | #define NULLSTARTBLOCK(k) nullstartblock(k) | 91 | #define NULLSTARTBLOCK(k) nullstartblock(k) |
92 | static inline xfs_fsblock_t nullstartblock(int k) | 92 | static inline xfs_fsblock_t nullstartblock(int k) |
93 | { | 93 | { |
94 | ASSERT(k < (1 << STARTBLOCKVALBITS)); | 94 | ASSERT(k < (1 << STARTBLOCKVALBITS)); |
95 | return STARTBLOCKMASK | (k); | 95 | return STARTBLOCKMASK | (k); |
96 | } | 96 | } |
97 | 97 | ||
98 | #define STARTBLOCKVAL(x) startblockval(x) | 98 | #define STARTBLOCKVAL(x) startblockval(x) |
99 | static inline xfs_filblks_t startblockval(xfs_fsblock_t x) | 99 | static inline xfs_filblks_t startblockval(xfs_fsblock_t x) |
100 | { | 100 | { |
101 | return (xfs_filblks_t)((x) & ~STARTBLOCKMASK); | 101 | return (xfs_filblks_t)((x) & ~STARTBLOCKMASK); |
102 | } | 102 | } |
103 | 103 | ||
104 | /* | 104 | /* |
105 | * Possible extent formats. | 105 | * Possible extent formats. |
106 | */ | 106 | */ |
107 | typedef enum { | 107 | typedef enum { |
108 | XFS_EXTFMT_NOSTATE = 0, | 108 | XFS_EXTFMT_NOSTATE = 0, |
109 | XFS_EXTFMT_HASSTATE | 109 | XFS_EXTFMT_HASSTATE |
110 | } xfs_exntfmt_t; | 110 | } xfs_exntfmt_t; |
111 | 111 | ||
112 | /* | 112 | /* |
113 | * Possible extent states. | 113 | * Possible extent states. |
114 | */ | 114 | */ |
115 | typedef enum { | 115 | typedef enum { |
116 | XFS_EXT_NORM, XFS_EXT_UNWRITTEN, | 116 | XFS_EXT_NORM, XFS_EXT_UNWRITTEN, |
117 | XFS_EXT_DMAPI_OFFLINE, XFS_EXT_INVALID | 117 | XFS_EXT_DMAPI_OFFLINE, XFS_EXT_INVALID |
118 | } xfs_exntst_t; | 118 | } xfs_exntst_t; |
119 | 119 | ||
120 | /* | 120 | /* |
121 | * Extent state and extent format macros. | 121 | * Extent state and extent format macros. |
122 | */ | 122 | */ |
123 | #define XFS_EXTFMT_INODE(x) \ | 123 | #define XFS_EXTFMT_INODE(x) \ |
124 | (xfs_sb_version_hasextflgbit(&((x)->i_mount->m_sb)) ? \ | 124 | (xfs_sb_version_hasextflgbit(&((x)->i_mount->m_sb)) ? \ |
125 | XFS_EXTFMT_HASSTATE : XFS_EXTFMT_NOSTATE) | 125 | XFS_EXTFMT_HASSTATE : XFS_EXTFMT_NOSTATE) |
126 | #define ISUNWRITTEN(x) ((x)->br_state == XFS_EXT_UNWRITTEN) | 126 | #define ISUNWRITTEN(x) ((x)->br_state == XFS_EXT_UNWRITTEN) |
127 | 127 | ||
128 | /* | 128 | /* |
129 | * Incore version of above. | 129 | * Incore version of above. |
130 | */ | 130 | */ |
131 | typedef struct xfs_bmbt_irec | 131 | typedef struct xfs_bmbt_irec |
132 | { | 132 | { |
133 | xfs_fileoff_t br_startoff; /* starting file offset */ | 133 | xfs_fileoff_t br_startoff; /* starting file offset */ |
134 | xfs_fsblock_t br_startblock; /* starting block number */ | 134 | xfs_fsblock_t br_startblock; /* starting block number */ |
135 | xfs_filblks_t br_blockcount; /* number of blocks */ | 135 | xfs_filblks_t br_blockcount; /* number of blocks */ |
136 | xfs_exntst_t br_state; /* extent state */ | 136 | xfs_exntst_t br_state; /* extent state */ |
137 | } xfs_bmbt_irec_t; | 137 | } xfs_bmbt_irec_t; |
138 | 138 | ||
139 | /* | 139 | /* |
140 | * Key structure for non-leaf levels of the tree. | 140 | * Key structure for non-leaf levels of the tree. |
141 | */ | 141 | */ |
142 | typedef struct xfs_bmbt_key { | 142 | typedef struct xfs_bmbt_key { |
143 | __be64 br_startoff; /* starting file offset */ | 143 | __be64 br_startoff; /* starting file offset */ |
144 | } xfs_bmbt_key_t, xfs_bmdr_key_t; | 144 | } xfs_bmbt_key_t, xfs_bmdr_key_t; |
145 | 145 | ||
146 | /* btree pointer type */ | 146 | /* btree pointer type */ |
147 | typedef __be64 xfs_bmbt_ptr_t, xfs_bmdr_ptr_t; | 147 | typedef __be64 xfs_bmbt_ptr_t, xfs_bmdr_ptr_t; |
148 | 148 | ||
149 | /* btree block header type */ | 149 | /* btree block header type */ |
150 | typedef struct xfs_btree_lblock xfs_bmbt_block_t; | 150 | typedef struct xfs_btree_lblock xfs_bmbt_block_t; |
151 | 151 | ||
152 | #define XFS_BUF_TO_BMBT_BLOCK(bp) ((xfs_bmbt_block_t *)XFS_BUF_PTR(bp)) | 152 | #define XFS_BUF_TO_BMBT_BLOCK(bp) ((xfs_bmbt_block_t *)XFS_BUF_PTR(bp)) |
153 | 153 | ||
154 | #define XFS_BMAP_RBLOCK_DSIZE(lev,cur) ((cur)->bc_private.b.forksize) | 154 | #define XFS_BMAP_RBLOCK_DSIZE(lev,cur) ((cur)->bc_private.b.forksize) |
155 | #define XFS_BMAP_RBLOCK_ISIZE(lev,cur) \ | 155 | #define XFS_BMAP_RBLOCK_ISIZE(lev,cur) \ |
156 | ((int)XFS_IFORK_PTR((cur)->bc_private.b.ip, \ | 156 | ((int)XFS_IFORK_PTR((cur)->bc_private.b.ip, \ |
157 | (cur)->bc_private.b.whichfork)->if_broot_bytes) | 157 | (cur)->bc_private.b.whichfork)->if_broot_bytes) |
158 | 158 | ||
159 | #define XFS_BMAP_BLOCK_DMAXRECS(lev,cur) \ | 159 | #define XFS_BMAP_BLOCK_DMAXRECS(lev,cur) \ |
160 | (((lev) == (cur)->bc_nlevels - 1 ? \ | 160 | (((lev) == (cur)->bc_nlevels - 1 ? \ |
161 | XFS_BTREE_BLOCK_MAXRECS(XFS_BMAP_RBLOCK_DSIZE(lev,cur), \ | 161 | XFS_BTREE_BLOCK_MAXRECS(XFS_BMAP_RBLOCK_DSIZE(lev,cur), \ |
162 | xfs_bmdr, (lev) == 0) : \ | 162 | xfs_bmdr, (lev) == 0) : \ |
163 | ((cur)->bc_mp->m_bmap_dmxr[(lev) != 0]))) | 163 | ((cur)->bc_mp->m_bmap_dmxr[(lev) != 0]))) |
164 | #define XFS_BMAP_BLOCK_IMAXRECS(lev,cur) \ | 164 | #define XFS_BMAP_BLOCK_IMAXRECS(lev,cur) \ |
165 | (((lev) == (cur)->bc_nlevels - 1 ? \ | 165 | (((lev) == (cur)->bc_nlevels - 1 ? \ |
166 | XFS_BTREE_BLOCK_MAXRECS(XFS_BMAP_RBLOCK_ISIZE(lev,cur),\ | 166 | XFS_BTREE_BLOCK_MAXRECS(XFS_BMAP_RBLOCK_ISIZE(lev,cur),\ |
167 | xfs_bmbt, (lev) == 0) : \ | 167 | xfs_bmbt, (lev) == 0) : \ |
168 | ((cur)->bc_mp->m_bmap_dmxr[(lev) != 0]))) | 168 | ((cur)->bc_mp->m_bmap_dmxr[(lev) != 0]))) |
169 | 169 | ||
170 | #define XFS_BMAP_BLOCK_DMINRECS(lev,cur) \ | 170 | #define XFS_BMAP_BLOCK_DMINRECS(lev,cur) \ |
171 | (((lev) == (cur)->bc_nlevels - 1 ? \ | 171 | (((lev) == (cur)->bc_nlevels - 1 ? \ |
172 | XFS_BTREE_BLOCK_MINRECS(XFS_BMAP_RBLOCK_DSIZE(lev,cur),\ | 172 | XFS_BTREE_BLOCK_MINRECS(XFS_BMAP_RBLOCK_DSIZE(lev,cur),\ |
173 | xfs_bmdr, (lev) == 0) : \ | 173 | xfs_bmdr, (lev) == 0) : \ |
174 | ((cur)->bc_mp->m_bmap_dmnr[(lev) != 0]))) | 174 | ((cur)->bc_mp->m_bmap_dmnr[(lev) != 0]))) |
175 | #define XFS_BMAP_BLOCK_IMINRECS(lev,cur) \ | 175 | #define XFS_BMAP_BLOCK_IMINRECS(lev,cur) \ |
176 | (((lev) == (cur)->bc_nlevels - 1 ? \ | 176 | (((lev) == (cur)->bc_nlevels - 1 ? \ |
177 | XFS_BTREE_BLOCK_MINRECS(XFS_BMAP_RBLOCK_ISIZE(lev,cur),\ | 177 | XFS_BTREE_BLOCK_MINRECS(XFS_BMAP_RBLOCK_ISIZE(lev,cur),\ |
178 | xfs_bmbt, (lev) == 0) : \ | 178 | xfs_bmbt, (lev) == 0) : \ |
179 | ((cur)->bc_mp->m_bmap_dmnr[(lev) != 0]))) | 179 | ((cur)->bc_mp->m_bmap_dmnr[(lev) != 0]))) |
180 | 180 | ||
181 | #define XFS_BMAP_REC_DADDR(bb,i,cur) (XFS_BTREE_REC_ADDR(xfs_bmbt, bb, i)) | 181 | #define XFS_BMAP_REC_DADDR(bb,i,cur) (XFS_BTREE_REC_ADDR(xfs_bmbt, bb, i)) |
182 | 182 | ||
183 | #define XFS_BMAP_REC_IADDR(bb,i,cur) (XFS_BTREE_REC_ADDR(xfs_bmbt, bb, i)) | 183 | #define XFS_BMAP_REC_IADDR(bb,i,cur) (XFS_BTREE_REC_ADDR(xfs_bmbt, bb, i)) |
184 | 184 | ||
185 | #define XFS_BMAP_KEY_DADDR(bb,i,cur) \ | 185 | #define XFS_BMAP_KEY_DADDR(bb,i,cur) \ |
186 | (XFS_BTREE_KEY_ADDR(xfs_bmbt, bb, i)) | 186 | (XFS_BTREE_KEY_ADDR(xfs_bmbt, bb, i)) |
187 | 187 | ||
188 | #define XFS_BMAP_KEY_IADDR(bb,i,cur) \ | 188 | #define XFS_BMAP_KEY_IADDR(bb,i,cur) \ |
189 | (XFS_BTREE_KEY_ADDR(xfs_bmbt, bb, i)) | 189 | (XFS_BTREE_KEY_ADDR(xfs_bmbt, bb, i)) |
190 | 190 | ||
191 | #define XFS_BMAP_PTR_DADDR(bb,i,cur) \ | 191 | #define XFS_BMAP_PTR_DADDR(bb,i,cur) \ |
192 | (XFS_BTREE_PTR_ADDR(xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS( \ | 192 | (XFS_BTREE_PTR_ADDR(xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS( \ |
193 | be16_to_cpu((bb)->bb_level), cur))) | 193 | be16_to_cpu((bb)->bb_level), cur))) |
194 | #define XFS_BMAP_PTR_IADDR(bb,i,cur) \ | 194 | #define XFS_BMAP_PTR_IADDR(bb,i,cur) \ |
195 | (XFS_BTREE_PTR_ADDR(xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS( \ | 195 | (XFS_BTREE_PTR_ADDR(xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS( \ |
196 | be16_to_cpu((bb)->bb_level), cur))) | 196 | be16_to_cpu((bb)->bb_level), cur))) |
197 | 197 | ||
198 | /* | 198 | /* |
199 | * These are to be used when we know the size of the block and | 199 | * These are to be used when we know the size of the block and |
200 | * we don't have a cursor. | 200 | * we don't have a cursor. |
201 | */ | 201 | */ |
202 | #define XFS_BMAP_BROOT_REC_ADDR(bb,i,sz) \ | 202 | #define XFS_BMAP_BROOT_REC_ADDR(bb,i,sz) \ |
203 | (XFS_BTREE_REC_ADDR(xfs_bmbt,bb,i)) | 203 | (XFS_BTREE_REC_ADDR(xfs_bmbt,bb,i)) |
204 | #define XFS_BMAP_BROOT_KEY_ADDR(bb,i,sz) \ | 204 | #define XFS_BMAP_BROOT_KEY_ADDR(bb,i,sz) \ |
205 | (XFS_BTREE_KEY_ADDR(xfs_bmbt,bb,i)) | 205 | (XFS_BTREE_KEY_ADDR(xfs_bmbt,bb,i)) |
206 | #define XFS_BMAP_BROOT_PTR_ADDR(bb,i,sz) \ | 206 | #define XFS_BMAP_BROOT_PTR_ADDR(bb,i,sz) \ |
207 | (XFS_BTREE_PTR_ADDR(xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz))) | 207 | (XFS_BTREE_PTR_ADDR(xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz))) |
208 | 208 | ||
209 | #define XFS_BMAP_BROOT_NUMRECS(bb) be16_to_cpu((bb)->bb_numrecs) | 209 | #define XFS_BMAP_BROOT_NUMRECS(bb) be16_to_cpu((bb)->bb_numrecs) |
210 | #define XFS_BMAP_BROOT_MAXRECS(sz) XFS_BTREE_BLOCK_MAXRECS(sz,xfs_bmbt,0) | 210 | #define XFS_BMAP_BROOT_MAXRECS(sz) XFS_BTREE_BLOCK_MAXRECS(sz,xfs_bmbt,0) |
211 | 211 | ||
212 | #define XFS_BMAP_BROOT_SPACE_CALC(nrecs) \ | 212 | #define XFS_BMAP_BROOT_SPACE_CALC(nrecs) \ |
213 | (int)(sizeof(xfs_bmbt_block_t) + \ | 213 | (int)(sizeof(xfs_bmbt_block_t) + \ |
214 | ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t)))) | 214 | ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t)))) |
215 | 215 | ||
216 | #define XFS_BMAP_BROOT_SPACE(bb) \ | 216 | #define XFS_BMAP_BROOT_SPACE(bb) \ |
217 | (XFS_BMAP_BROOT_SPACE_CALC(be16_to_cpu((bb)->bb_numrecs))) | 217 | (XFS_BMAP_BROOT_SPACE_CALC(be16_to_cpu((bb)->bb_numrecs))) |
218 | #define XFS_BMDR_SPACE_CALC(nrecs) \ | 218 | #define XFS_BMDR_SPACE_CALC(nrecs) \ |
219 | (int)(sizeof(xfs_bmdr_block_t) + \ | 219 | (int)(sizeof(xfs_bmdr_block_t) + \ |
220 | ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t)))) | 220 | ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t)))) |
221 | 221 | ||
222 | /* | 222 | /* |
223 | * Maximum number of bmap btree levels. | 223 | * Maximum number of bmap btree levels. |
224 | */ | 224 | */ |
225 | #define XFS_BM_MAXLEVELS(mp,w) ((mp)->m_bm_maxlevels[(w)]) | 225 | #define XFS_BM_MAXLEVELS(mp,w) ((mp)->m_bm_maxlevels[(w)]) |
226 | 226 | ||
227 | #define XFS_BMAP_SANITY_CHECK(mp,bb,level) \ | 227 | #define XFS_BMAP_SANITY_CHECK(mp,bb,level) \ |
228 | (be32_to_cpu((bb)->bb_magic) == XFS_BMAP_MAGIC && \ | 228 | (be32_to_cpu((bb)->bb_magic) == XFS_BMAP_MAGIC && \ |
229 | be16_to_cpu((bb)->bb_level) == level && \ | 229 | be16_to_cpu((bb)->bb_level) == level && \ |
230 | be16_to_cpu((bb)->bb_numrecs) > 0 && \ | 230 | be16_to_cpu((bb)->bb_numrecs) > 0 && \ |
231 | be16_to_cpu((bb)->bb_numrecs) <= (mp)->m_bmap_dmxr[(level) != 0]) | 231 | be16_to_cpu((bb)->bb_numrecs) <= (mp)->m_bmap_dmxr[(level) != 0]) |
232 | 232 | ||
233 | 233 | ||
234 | #ifdef __KERNEL__ | ||
235 | |||
236 | /* | 234 | /* |
237 | * Prototypes for xfs_bmap.c to call. | 235 | * Prototypes for xfs_bmap.c to call. |
238 | */ | 236 | */ |
239 | extern void xfs_bmdr_to_bmbt(xfs_bmdr_block_t *, int, xfs_bmbt_block_t *, int); | 237 | extern void xfs_bmdr_to_bmbt(xfs_bmdr_block_t *, int, xfs_bmbt_block_t *, int); |
240 | extern void xfs_bmbt_get_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s); | 238 | extern void xfs_bmbt_get_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s); |
241 | extern xfs_filblks_t xfs_bmbt_get_blockcount(xfs_bmbt_rec_host_t *r); | 239 | extern xfs_filblks_t xfs_bmbt_get_blockcount(xfs_bmbt_rec_host_t *r); |
242 | extern xfs_fsblock_t xfs_bmbt_get_startblock(xfs_bmbt_rec_host_t *r); | 240 | extern xfs_fsblock_t xfs_bmbt_get_startblock(xfs_bmbt_rec_host_t *r); |
243 | extern xfs_fileoff_t xfs_bmbt_get_startoff(xfs_bmbt_rec_host_t *r); | 241 | extern xfs_fileoff_t xfs_bmbt_get_startoff(xfs_bmbt_rec_host_t *r); |
244 | extern xfs_exntst_t xfs_bmbt_get_state(xfs_bmbt_rec_host_t *r); | 242 | extern xfs_exntst_t xfs_bmbt_get_state(xfs_bmbt_rec_host_t *r); |
245 | 243 | ||
246 | extern void xfs_bmbt_disk_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s); | 244 | extern void xfs_bmbt_disk_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s); |
247 | extern xfs_filblks_t xfs_bmbt_disk_get_blockcount(xfs_bmbt_rec_t *r); | 245 | extern xfs_filblks_t xfs_bmbt_disk_get_blockcount(xfs_bmbt_rec_t *r); |
248 | extern xfs_fileoff_t xfs_bmbt_disk_get_startoff(xfs_bmbt_rec_t *r); | 246 | extern xfs_fileoff_t xfs_bmbt_disk_get_startoff(xfs_bmbt_rec_t *r); |
249 | 247 | ||
250 | extern void xfs_bmbt_set_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s); | 248 | extern void xfs_bmbt_set_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s); |
251 | extern void xfs_bmbt_set_allf(xfs_bmbt_rec_host_t *r, xfs_fileoff_t o, | 249 | extern void xfs_bmbt_set_allf(xfs_bmbt_rec_host_t *r, xfs_fileoff_t o, |
252 | xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v); | 250 | xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v); |
253 | extern void xfs_bmbt_set_blockcount(xfs_bmbt_rec_host_t *r, xfs_filblks_t v); | 251 | extern void xfs_bmbt_set_blockcount(xfs_bmbt_rec_host_t *r, xfs_filblks_t v); |
254 | extern void xfs_bmbt_set_startblock(xfs_bmbt_rec_host_t *r, xfs_fsblock_t v); | 252 | extern void xfs_bmbt_set_startblock(xfs_bmbt_rec_host_t *r, xfs_fsblock_t v); |
255 | extern void xfs_bmbt_set_startoff(xfs_bmbt_rec_host_t *r, xfs_fileoff_t v); | 253 | extern void xfs_bmbt_set_startoff(xfs_bmbt_rec_host_t *r, xfs_fileoff_t v); |
256 | extern void xfs_bmbt_set_state(xfs_bmbt_rec_host_t *r, xfs_exntst_t v); | 254 | extern void xfs_bmbt_set_state(xfs_bmbt_rec_host_t *r, xfs_exntst_t v); |
257 | 255 | ||
258 | extern void xfs_bmbt_disk_set_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s); | 256 | extern void xfs_bmbt_disk_set_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s); |
259 | extern void xfs_bmbt_disk_set_allf(xfs_bmbt_rec_t *r, xfs_fileoff_t o, | 257 | extern void xfs_bmbt_disk_set_allf(xfs_bmbt_rec_t *r, xfs_fileoff_t o, |
260 | xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v); | 258 | xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v); |
261 | 259 | ||
262 | extern void xfs_bmbt_to_bmdr(xfs_bmbt_block_t *, int, xfs_bmdr_block_t *, int); | 260 | extern void xfs_bmbt_to_bmdr(xfs_bmbt_block_t *, int, xfs_bmdr_block_t *, int); |
263 | 261 | ||
264 | extern struct xfs_btree_cur *xfs_bmbt_init_cursor(struct xfs_mount *, | 262 | extern struct xfs_btree_cur *xfs_bmbt_init_cursor(struct xfs_mount *, |
265 | struct xfs_trans *, struct xfs_inode *, int); | 263 | struct xfs_trans *, struct xfs_inode *, int); |
266 | 264 | ||
267 | #endif /* __KERNEL__ */ | ||
268 | 265 | ||
269 | #endif /* __XFS_BMAP_BTREE_H__ */ | 266 | #endif /* __XFS_BMAP_BTREE_H__ */ |
270 | 267 |
fs/xfs/xfs_btree.h
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License as | 6 | * modify it under the terms of the GNU General Public License as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | * | 8 | * |
9 | * This program is distributed in the hope that it would be useful, | 9 | * This program is distributed in the hope that it would be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. | 12 | * GNU General Public License for more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License | 14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write the Free Software Foundation, | 15 | * along with this program; if not, write the Free Software Foundation, |
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ | 17 | */ |
18 | #ifndef __XFS_BTREE_H__ | 18 | #ifndef __XFS_BTREE_H__ |
19 | #define __XFS_BTREE_H__ | 19 | #define __XFS_BTREE_H__ |
20 | 20 | ||
21 | struct xfs_buf; | 21 | struct xfs_buf; |
22 | struct xfs_bmap_free; | 22 | struct xfs_bmap_free; |
23 | struct xfs_inode; | 23 | struct xfs_inode; |
24 | struct xfs_mount; | 24 | struct xfs_mount; |
25 | struct xfs_trans; | 25 | struct xfs_trans; |
26 | 26 | ||
27 | extern kmem_zone_t *xfs_btree_cur_zone; | 27 | extern kmem_zone_t *xfs_btree_cur_zone; |
28 | 28 | ||
29 | /* | 29 | /* |
30 | * This nonsense is to make -wlint happy. | 30 | * This nonsense is to make -wlint happy. |
31 | */ | 31 | */ |
32 | #define XFS_LOOKUP_EQ ((xfs_lookup_t)XFS_LOOKUP_EQi) | 32 | #define XFS_LOOKUP_EQ ((xfs_lookup_t)XFS_LOOKUP_EQi) |
33 | #define XFS_LOOKUP_LE ((xfs_lookup_t)XFS_LOOKUP_LEi) | 33 | #define XFS_LOOKUP_LE ((xfs_lookup_t)XFS_LOOKUP_LEi) |
34 | #define XFS_LOOKUP_GE ((xfs_lookup_t)XFS_LOOKUP_GEi) | 34 | #define XFS_LOOKUP_GE ((xfs_lookup_t)XFS_LOOKUP_GEi) |
35 | 35 | ||
36 | #define XFS_BTNUM_BNO ((xfs_btnum_t)XFS_BTNUM_BNOi) | 36 | #define XFS_BTNUM_BNO ((xfs_btnum_t)XFS_BTNUM_BNOi) |
37 | #define XFS_BTNUM_CNT ((xfs_btnum_t)XFS_BTNUM_CNTi) | 37 | #define XFS_BTNUM_CNT ((xfs_btnum_t)XFS_BTNUM_CNTi) |
38 | #define XFS_BTNUM_BMAP ((xfs_btnum_t)XFS_BTNUM_BMAPi) | 38 | #define XFS_BTNUM_BMAP ((xfs_btnum_t)XFS_BTNUM_BMAPi) |
39 | #define XFS_BTNUM_INO ((xfs_btnum_t)XFS_BTNUM_INOi) | 39 | #define XFS_BTNUM_INO ((xfs_btnum_t)XFS_BTNUM_INOi) |
40 | 40 | ||
41 | /* | 41 | /* |
42 | * Short form header: space allocation btrees. | 42 | * Short form header: space allocation btrees. |
43 | */ | 43 | */ |
44 | typedef struct xfs_btree_sblock { | 44 | typedef struct xfs_btree_sblock { |
45 | __be32 bb_magic; /* magic number for block type */ | 45 | __be32 bb_magic; /* magic number for block type */ |
46 | __be16 bb_level; /* 0 is a leaf */ | 46 | __be16 bb_level; /* 0 is a leaf */ |
47 | __be16 bb_numrecs; /* current # of data records */ | 47 | __be16 bb_numrecs; /* current # of data records */ |
48 | __be32 bb_leftsib; /* left sibling block or NULLAGBLOCK */ | 48 | __be32 bb_leftsib; /* left sibling block or NULLAGBLOCK */ |
49 | __be32 bb_rightsib; /* right sibling block or NULLAGBLOCK */ | 49 | __be32 bb_rightsib; /* right sibling block or NULLAGBLOCK */ |
50 | } xfs_btree_sblock_t; | 50 | } xfs_btree_sblock_t; |
51 | 51 | ||
52 | /* | 52 | /* |
53 | * Long form header: bmap btrees. | 53 | * Long form header: bmap btrees. |
54 | */ | 54 | */ |
55 | typedef struct xfs_btree_lblock { | 55 | typedef struct xfs_btree_lblock { |
56 | __be32 bb_magic; /* magic number for block type */ | 56 | __be32 bb_magic; /* magic number for block type */ |
57 | __be16 bb_level; /* 0 is a leaf */ | 57 | __be16 bb_level; /* 0 is a leaf */ |
58 | __be16 bb_numrecs; /* current # of data records */ | 58 | __be16 bb_numrecs; /* current # of data records */ |
59 | __be64 bb_leftsib; /* left sibling block or NULLDFSBNO */ | 59 | __be64 bb_leftsib; /* left sibling block or NULLDFSBNO */ |
60 | __be64 bb_rightsib; /* right sibling block or NULLDFSBNO */ | 60 | __be64 bb_rightsib; /* right sibling block or NULLDFSBNO */ |
61 | } xfs_btree_lblock_t; | 61 | } xfs_btree_lblock_t; |
62 | 62 | ||
63 | /* | 63 | /* |
64 | * Combined header and structure, used by common code. | 64 | * Combined header and structure, used by common code. |
65 | */ | 65 | */ |
66 | typedef struct xfs_btree_block { | 66 | typedef struct xfs_btree_block { |
67 | __be32 bb_magic; /* magic number for block type */ | 67 | __be32 bb_magic; /* magic number for block type */ |
68 | __be16 bb_level; /* 0 is a leaf */ | 68 | __be16 bb_level; /* 0 is a leaf */ |
69 | __be16 bb_numrecs; /* current # of data records */ | 69 | __be16 bb_numrecs; /* current # of data records */ |
70 | union { | 70 | union { |
71 | struct { | 71 | struct { |
72 | __be32 bb_leftsib; | 72 | __be32 bb_leftsib; |
73 | __be32 bb_rightsib; | 73 | __be32 bb_rightsib; |
74 | } s; /* short form pointers */ | 74 | } s; /* short form pointers */ |
75 | struct { | 75 | struct { |
76 | __be64 bb_leftsib; | 76 | __be64 bb_leftsib; |
77 | __be64 bb_rightsib; | 77 | __be64 bb_rightsib; |
78 | } l; /* long form pointers */ | 78 | } l; /* long form pointers */ |
79 | } bb_u; /* rest */ | 79 | } bb_u; /* rest */ |
80 | } xfs_btree_block_t; | 80 | } xfs_btree_block_t; |
81 | 81 | ||
82 | /* | 82 | /* |
83 | * Generic key, ptr and record wrapper structures. | 83 | * Generic key, ptr and record wrapper structures. |
84 | * | 84 | * |
85 | * These are disk format structures, and are converted where necessary | 85 | * These are disk format structures, and are converted where necessary |
86 | * by the btree specific code that needs to interpret them. | 86 | * by the btree specific code that needs to interpret them. |
87 | */ | 87 | */ |
88 | union xfs_btree_ptr { | 88 | union xfs_btree_ptr { |
89 | __be32 s; /* short form ptr */ | 89 | __be32 s; /* short form ptr */ |
90 | __be64 l; /* long form ptr */ | 90 | __be64 l; /* long form ptr */ |
91 | }; | 91 | }; |
92 | 92 | ||
93 | union xfs_btree_key { | 93 | union xfs_btree_key { |
94 | xfs_bmbt_key_t bmbt; | 94 | xfs_bmbt_key_t bmbt; |
95 | xfs_bmdr_key_t bmbr; /* bmbt root block */ | 95 | xfs_bmdr_key_t bmbr; /* bmbt root block */ |
96 | xfs_alloc_key_t alloc; | 96 | xfs_alloc_key_t alloc; |
97 | xfs_inobt_key_t inobt; | 97 | xfs_inobt_key_t inobt; |
98 | }; | 98 | }; |
99 | 99 | ||
100 | union xfs_btree_rec { | 100 | union xfs_btree_rec { |
101 | xfs_bmbt_rec_t bmbt; | 101 | xfs_bmbt_rec_t bmbt; |
102 | xfs_bmdr_rec_t bmbr; /* bmbt root block */ | 102 | xfs_bmdr_rec_t bmbr; /* bmbt root block */ |
103 | xfs_alloc_rec_t alloc; | 103 | xfs_alloc_rec_t alloc; |
104 | xfs_inobt_rec_t inobt; | 104 | xfs_inobt_rec_t inobt; |
105 | }; | 105 | }; |
106 | 106 | ||
107 | /* | 107 | /* |
108 | * For logging record fields. | 108 | * For logging record fields. |
109 | */ | 109 | */ |
110 | #define XFS_BB_MAGIC 0x01 | 110 | #define XFS_BB_MAGIC 0x01 |
111 | #define XFS_BB_LEVEL 0x02 | 111 | #define XFS_BB_LEVEL 0x02 |
112 | #define XFS_BB_NUMRECS 0x04 | 112 | #define XFS_BB_NUMRECS 0x04 |
113 | #define XFS_BB_LEFTSIB 0x08 | 113 | #define XFS_BB_LEFTSIB 0x08 |
114 | #define XFS_BB_RIGHTSIB 0x10 | 114 | #define XFS_BB_RIGHTSIB 0x10 |
115 | #define XFS_BB_NUM_BITS 5 | 115 | #define XFS_BB_NUM_BITS 5 |
116 | #define XFS_BB_ALL_BITS ((1 << XFS_BB_NUM_BITS) - 1) | 116 | #define XFS_BB_ALL_BITS ((1 << XFS_BB_NUM_BITS) - 1) |
117 | 117 | ||
118 | /* | 118 | /* |
119 | * Magic numbers for btree blocks. | 119 | * Magic numbers for btree blocks. |
120 | */ | 120 | */ |
121 | extern const __uint32_t xfs_magics[]; | 121 | extern const __uint32_t xfs_magics[]; |
122 | 122 | ||
123 | /* | 123 | /* |
124 | * Generic stats interface | 124 | * Generic stats interface |
125 | */ | 125 | */ |
126 | #define __XFS_BTREE_STATS_INC(type, stat) \ | 126 | #define __XFS_BTREE_STATS_INC(type, stat) \ |
127 | XFS_STATS_INC(xs_ ## type ## _2_ ## stat) | 127 | XFS_STATS_INC(xs_ ## type ## _2_ ## stat) |
128 | #define XFS_BTREE_STATS_INC(cur, stat) \ | 128 | #define XFS_BTREE_STATS_INC(cur, stat) \ |
129 | do { \ | 129 | do { \ |
130 | switch (cur->bc_btnum) { \ | 130 | switch (cur->bc_btnum) { \ |
131 | case XFS_BTNUM_BNO: __XFS_BTREE_STATS_INC(abtb, stat); break; \ | 131 | case XFS_BTNUM_BNO: __XFS_BTREE_STATS_INC(abtb, stat); break; \ |
132 | case XFS_BTNUM_CNT: __XFS_BTREE_STATS_INC(abtc, stat); break; \ | 132 | case XFS_BTNUM_CNT: __XFS_BTREE_STATS_INC(abtc, stat); break; \ |
133 | case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(bmbt, stat); break; \ | 133 | case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(bmbt, stat); break; \ |
134 | case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(ibt, stat); break; \ | 134 | case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(ibt, stat); break; \ |
135 | case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ | 135 | case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ |
136 | } \ | 136 | } \ |
137 | } while (0) | 137 | } while (0) |
138 | 138 | ||
139 | #define __XFS_BTREE_STATS_ADD(type, stat, val) \ | 139 | #define __XFS_BTREE_STATS_ADD(type, stat, val) \ |
140 | XFS_STATS_ADD(xs_ ## type ## _2_ ## stat, val) | 140 | XFS_STATS_ADD(xs_ ## type ## _2_ ## stat, val) |
141 | #define XFS_BTREE_STATS_ADD(cur, stat, val) \ | 141 | #define XFS_BTREE_STATS_ADD(cur, stat, val) \ |
142 | do { \ | 142 | do { \ |
143 | switch (cur->bc_btnum) { \ | 143 | switch (cur->bc_btnum) { \ |
144 | case XFS_BTNUM_BNO: __XFS_BTREE_STATS_ADD(abtb, stat, val); break; \ | 144 | case XFS_BTNUM_BNO: __XFS_BTREE_STATS_ADD(abtb, stat, val); break; \ |
145 | case XFS_BTNUM_CNT: __XFS_BTREE_STATS_ADD(abtc, stat, val); break; \ | 145 | case XFS_BTNUM_CNT: __XFS_BTREE_STATS_ADD(abtc, stat, val); break; \ |
146 | case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_ADD(bmbt, stat, val); break; \ | 146 | case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_ADD(bmbt, stat, val); break; \ |
147 | case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(ibt, stat, val); break; \ | 147 | case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(ibt, stat, val); break; \ |
148 | case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ | 148 | case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ |
149 | } \ | 149 | } \ |
150 | } while (0) | 150 | } while (0) |
151 | /* | 151 | /* |
152 | * Maximum and minimum records in a btree block. | 152 | * Maximum and minimum records in a btree block. |
153 | * Given block size, type prefix, and leaf flag (0 or 1). | 153 | * Given block size, type prefix, and leaf flag (0 or 1). |
154 | * The divisor below is equivalent to lf ? (e1) : (e2) but that produces | 154 | * The divisor below is equivalent to lf ? (e1) : (e2) but that produces |
155 | * compiler warnings. | 155 | * compiler warnings. |
156 | */ | 156 | */ |
157 | #define XFS_BTREE_BLOCK_MAXRECS(bsz,t,lf) \ | 157 | #define XFS_BTREE_BLOCK_MAXRECS(bsz,t,lf) \ |
158 | ((int)(((bsz) - (uint)sizeof(t ## _block_t)) / \ | 158 | ((int)(((bsz) - (uint)sizeof(t ## _block_t)) / \ |
159 | (((lf) * (uint)sizeof(t ## _rec_t)) + \ | 159 | (((lf) * (uint)sizeof(t ## _rec_t)) + \ |
160 | ((1 - (lf)) * \ | 160 | ((1 - (lf)) * \ |
161 | ((uint)sizeof(t ## _key_t) + (uint)sizeof(t ## _ptr_t)))))) | 161 | ((uint)sizeof(t ## _key_t) + (uint)sizeof(t ## _ptr_t)))))) |
162 | #define XFS_BTREE_BLOCK_MINRECS(bsz,t,lf) \ | 162 | #define XFS_BTREE_BLOCK_MINRECS(bsz,t,lf) \ |
163 | (XFS_BTREE_BLOCK_MAXRECS(bsz,t,lf) / 2) | 163 | (XFS_BTREE_BLOCK_MAXRECS(bsz,t,lf) / 2) |
164 | 164 | ||
165 | /* | 165 | /* |
166 | * Record, key, and pointer address calculation macros. | 166 | * Record, key, and pointer address calculation macros. |
167 | * Given block size, type prefix, block pointer, and index of requested entry | 167 | * Given block size, type prefix, block pointer, and index of requested entry |
168 | * (first entry numbered 1). | 168 | * (first entry numbered 1). |
169 | */ | 169 | */ |
170 | #define XFS_BTREE_REC_ADDR(t,bb,i) \ | 170 | #define XFS_BTREE_REC_ADDR(t,bb,i) \ |
171 | ((t ## _rec_t *)((char *)(bb) + sizeof(t ## _block_t) + \ | 171 | ((t ## _rec_t *)((char *)(bb) + sizeof(t ## _block_t) + \ |
172 | ((i) - 1) * sizeof(t ## _rec_t))) | 172 | ((i) - 1) * sizeof(t ## _rec_t))) |
173 | #define XFS_BTREE_KEY_ADDR(t,bb,i) \ | 173 | #define XFS_BTREE_KEY_ADDR(t,bb,i) \ |
174 | ((t ## _key_t *)((char *)(bb) + sizeof(t ## _block_t) + \ | 174 | ((t ## _key_t *)((char *)(bb) + sizeof(t ## _block_t) + \ |
175 | ((i) - 1) * sizeof(t ## _key_t))) | 175 | ((i) - 1) * sizeof(t ## _key_t))) |
176 | #define XFS_BTREE_PTR_ADDR(t,bb,i,mxr) \ | 176 | #define XFS_BTREE_PTR_ADDR(t,bb,i,mxr) \ |
177 | ((t ## _ptr_t *)((char *)(bb) + sizeof(t ## _block_t) + \ | 177 | ((t ## _ptr_t *)((char *)(bb) + sizeof(t ## _block_t) + \ |
178 | (mxr) * sizeof(t ## _key_t) + ((i) - 1) * sizeof(t ## _ptr_t))) | 178 | (mxr) * sizeof(t ## _key_t) + ((i) - 1) * sizeof(t ## _ptr_t))) |
179 | 179 | ||
180 | #define XFS_BTREE_MAXLEVELS 8 /* max of all btrees */ | 180 | #define XFS_BTREE_MAXLEVELS 8 /* max of all btrees */ |
181 | 181 | ||
182 | struct xfs_btree_ops { | 182 | struct xfs_btree_ops { |
183 | /* size of the key and record structures */ | 183 | /* size of the key and record structures */ |
184 | size_t key_len; | 184 | size_t key_len; |
185 | size_t rec_len; | 185 | size_t rec_len; |
186 | 186 | ||
187 | /* cursor operations */ | 187 | /* cursor operations */ |
188 | struct xfs_btree_cur *(*dup_cursor)(struct xfs_btree_cur *); | 188 | struct xfs_btree_cur *(*dup_cursor)(struct xfs_btree_cur *); |
189 | void (*update_cursor)(struct xfs_btree_cur *src, | 189 | void (*update_cursor)(struct xfs_btree_cur *src, |
190 | struct xfs_btree_cur *dst); | 190 | struct xfs_btree_cur *dst); |
191 | 191 | ||
192 | /* update btree root pointer */ | 192 | /* update btree root pointer */ |
193 | void (*set_root)(struct xfs_btree_cur *cur, | 193 | void (*set_root)(struct xfs_btree_cur *cur, |
194 | union xfs_btree_ptr *nptr, int level_change); | 194 | union xfs_btree_ptr *nptr, int level_change); |
195 | int (*kill_root)(struct xfs_btree_cur *cur, struct xfs_buf *bp, | 195 | int (*kill_root)(struct xfs_btree_cur *cur, struct xfs_buf *bp, |
196 | int level, union xfs_btree_ptr *newroot); | 196 | int level, union xfs_btree_ptr *newroot); |
197 | 197 | ||
198 | /* block allocation / freeing */ | 198 | /* block allocation / freeing */ |
199 | int (*alloc_block)(struct xfs_btree_cur *cur, | 199 | int (*alloc_block)(struct xfs_btree_cur *cur, |
200 | union xfs_btree_ptr *start_bno, | 200 | union xfs_btree_ptr *start_bno, |
201 | union xfs_btree_ptr *new_bno, | 201 | union xfs_btree_ptr *new_bno, |
202 | int length, int *stat); | 202 | int length, int *stat); |
203 | int (*free_block)(struct xfs_btree_cur *cur, struct xfs_buf *bp); | 203 | int (*free_block)(struct xfs_btree_cur *cur, struct xfs_buf *bp); |
204 | 204 | ||
205 | /* update last record information */ | 205 | /* update last record information */ |
206 | void (*update_lastrec)(struct xfs_btree_cur *cur, | 206 | void (*update_lastrec)(struct xfs_btree_cur *cur, |
207 | struct xfs_btree_block *block, | 207 | struct xfs_btree_block *block, |
208 | union xfs_btree_rec *rec, | 208 | union xfs_btree_rec *rec, |
209 | int ptr, int reason); | 209 | int ptr, int reason); |
210 | 210 | ||
211 | /* records in block/level */ | 211 | /* records in block/level */ |
212 | int (*get_minrecs)(struct xfs_btree_cur *cur, int level); | 212 | int (*get_minrecs)(struct xfs_btree_cur *cur, int level); |
213 | int (*get_maxrecs)(struct xfs_btree_cur *cur, int level); | 213 | int (*get_maxrecs)(struct xfs_btree_cur *cur, int level); |
214 | 214 | ||
215 | /* records on disk. Matter for the root in inode case. */ | 215 | /* records on disk. Matter for the root in inode case. */ |
216 | int (*get_dmaxrecs)(struct xfs_btree_cur *cur, int level); | 216 | int (*get_dmaxrecs)(struct xfs_btree_cur *cur, int level); |
217 | 217 | ||
218 | /* init values of btree structures */ | 218 | /* init values of btree structures */ |
219 | void (*init_key_from_rec)(union xfs_btree_key *key, | 219 | void (*init_key_from_rec)(union xfs_btree_key *key, |
220 | union xfs_btree_rec *rec); | 220 | union xfs_btree_rec *rec); |
221 | void (*init_rec_from_key)(union xfs_btree_key *key, | 221 | void (*init_rec_from_key)(union xfs_btree_key *key, |
222 | union xfs_btree_rec *rec); | 222 | union xfs_btree_rec *rec); |
223 | void (*init_rec_from_cur)(struct xfs_btree_cur *cur, | 223 | void (*init_rec_from_cur)(struct xfs_btree_cur *cur, |
224 | union xfs_btree_rec *rec); | 224 | union xfs_btree_rec *rec); |
225 | void (*init_ptr_from_cur)(struct xfs_btree_cur *cur, | 225 | void (*init_ptr_from_cur)(struct xfs_btree_cur *cur, |
226 | union xfs_btree_ptr *ptr); | 226 | union xfs_btree_ptr *ptr); |
227 | 227 | ||
228 | /* difference between key value and cursor value */ | 228 | /* difference between key value and cursor value */ |
229 | __int64_t (*key_diff)(struct xfs_btree_cur *cur, | 229 | __int64_t (*key_diff)(struct xfs_btree_cur *cur, |
230 | union xfs_btree_key *key); | 230 | union xfs_btree_key *key); |
231 | 231 | ||
232 | #ifdef DEBUG | 232 | #ifdef DEBUG |
233 | /* check that k1 is lower than k2 */ | 233 | /* check that k1 is lower than k2 */ |
234 | int (*keys_inorder)(struct xfs_btree_cur *cur, | 234 | int (*keys_inorder)(struct xfs_btree_cur *cur, |
235 | union xfs_btree_key *k1, | 235 | union xfs_btree_key *k1, |
236 | union xfs_btree_key *k2); | 236 | union xfs_btree_key *k2); |
237 | 237 | ||
238 | /* check that r1 is lower than r2 */ | 238 | /* check that r1 is lower than r2 */ |
239 | int (*recs_inorder)(struct xfs_btree_cur *cur, | 239 | int (*recs_inorder)(struct xfs_btree_cur *cur, |
240 | union xfs_btree_rec *r1, | 240 | union xfs_btree_rec *r1, |
241 | union xfs_btree_rec *r2); | 241 | union xfs_btree_rec *r2); |
242 | #endif | 242 | #endif |
243 | 243 | ||
244 | /* btree tracing */ | 244 | /* btree tracing */ |
245 | #ifdef XFS_BTREE_TRACE | 245 | #ifdef XFS_BTREE_TRACE |
246 | void (*trace_enter)(struct xfs_btree_cur *, const char *, | 246 | void (*trace_enter)(struct xfs_btree_cur *, const char *, |
247 | char *, int, int, __psunsigned_t, | 247 | char *, int, int, __psunsigned_t, |
248 | __psunsigned_t, __psunsigned_t, | 248 | __psunsigned_t, __psunsigned_t, |
249 | __psunsigned_t, __psunsigned_t, | 249 | __psunsigned_t, __psunsigned_t, |
250 | __psunsigned_t, __psunsigned_t, | 250 | __psunsigned_t, __psunsigned_t, |
251 | __psunsigned_t, __psunsigned_t, | 251 | __psunsigned_t, __psunsigned_t, |
252 | __psunsigned_t, __psunsigned_t); | 252 | __psunsigned_t, __psunsigned_t); |
253 | void (*trace_cursor)(struct xfs_btree_cur *, __uint32_t *, | 253 | void (*trace_cursor)(struct xfs_btree_cur *, __uint32_t *, |
254 | __uint64_t *, __uint64_t *); | 254 | __uint64_t *, __uint64_t *); |
255 | void (*trace_key)(struct xfs_btree_cur *, | 255 | void (*trace_key)(struct xfs_btree_cur *, |
256 | union xfs_btree_key *, __uint64_t *, | 256 | union xfs_btree_key *, __uint64_t *, |
257 | __uint64_t *); | 257 | __uint64_t *); |
258 | void (*trace_record)(struct xfs_btree_cur *, | 258 | void (*trace_record)(struct xfs_btree_cur *, |
259 | union xfs_btree_rec *, __uint64_t *, | 259 | union xfs_btree_rec *, __uint64_t *, |
260 | __uint64_t *, __uint64_t *); | 260 | __uint64_t *, __uint64_t *); |
261 | #endif | 261 | #endif |
262 | }; | 262 | }; |
263 | 263 | ||
264 | /* | 264 | /* |
265 | * Reasons for the update_lastrec method to be called. | 265 | * Reasons for the update_lastrec method to be called. |
266 | */ | 266 | */ |
267 | #define LASTREC_UPDATE 0 | 267 | #define LASTREC_UPDATE 0 |
268 | #define LASTREC_INSREC 1 | 268 | #define LASTREC_INSREC 1 |
269 | #define LASTREC_DELREC 2 | 269 | #define LASTREC_DELREC 2 |
270 | 270 | ||
271 | 271 | ||
272 | /* | 272 | /* |
273 | * Btree cursor structure. | 273 | * Btree cursor structure. |
274 | * This collects all information needed by the btree code in one place. | 274 | * This collects all information needed by the btree code in one place. |
275 | */ | 275 | */ |
276 | typedef struct xfs_btree_cur | 276 | typedef struct xfs_btree_cur |
277 | { | 277 | { |
278 | struct xfs_trans *bc_tp; /* transaction we're in, if any */ | 278 | struct xfs_trans *bc_tp; /* transaction we're in, if any */ |
279 | struct xfs_mount *bc_mp; /* file system mount struct */ | 279 | struct xfs_mount *bc_mp; /* file system mount struct */ |
280 | const struct xfs_btree_ops *bc_ops; | 280 | const struct xfs_btree_ops *bc_ops; |
281 | uint bc_flags; /* btree features - below */ | 281 | uint bc_flags; /* btree features - below */ |
282 | union { | 282 | union { |
283 | xfs_alloc_rec_incore_t a; | 283 | xfs_alloc_rec_incore_t a; |
284 | xfs_bmbt_irec_t b; | 284 | xfs_bmbt_irec_t b; |
285 | xfs_inobt_rec_incore_t i; | 285 | xfs_inobt_rec_incore_t i; |
286 | } bc_rec; /* current insert/search record value */ | 286 | } bc_rec; /* current insert/search record value */ |
287 | struct xfs_buf *bc_bufs[XFS_BTREE_MAXLEVELS]; /* buf ptr per level */ | 287 | struct xfs_buf *bc_bufs[XFS_BTREE_MAXLEVELS]; /* buf ptr per level */ |
288 | int bc_ptrs[XFS_BTREE_MAXLEVELS]; /* key/record # */ | 288 | int bc_ptrs[XFS_BTREE_MAXLEVELS]; /* key/record # */ |
289 | __uint8_t bc_ra[XFS_BTREE_MAXLEVELS]; /* readahead bits */ | 289 | __uint8_t bc_ra[XFS_BTREE_MAXLEVELS]; /* readahead bits */ |
290 | #define XFS_BTCUR_LEFTRA 1 /* left sibling has been read-ahead */ | 290 | #define XFS_BTCUR_LEFTRA 1 /* left sibling has been read-ahead */ |
291 | #define XFS_BTCUR_RIGHTRA 2 /* right sibling has been read-ahead */ | 291 | #define XFS_BTCUR_RIGHTRA 2 /* right sibling has been read-ahead */ |
292 | __uint8_t bc_nlevels; /* number of levels in the tree */ | 292 | __uint8_t bc_nlevels; /* number of levels in the tree */ |
293 | __uint8_t bc_blocklog; /* log2(blocksize) of btree blocks */ | 293 | __uint8_t bc_blocklog; /* log2(blocksize) of btree blocks */ |
294 | xfs_btnum_t bc_btnum; /* identifies which btree type */ | 294 | xfs_btnum_t bc_btnum; /* identifies which btree type */ |
295 | union { | 295 | union { |
296 | struct { /* needed for BNO, CNT, INO */ | 296 | struct { /* needed for BNO, CNT, INO */ |
297 | struct xfs_buf *agbp; /* agf/agi buffer pointer */ | 297 | struct xfs_buf *agbp; /* agf/agi buffer pointer */ |
298 | xfs_agnumber_t agno; /* ag number */ | 298 | xfs_agnumber_t agno; /* ag number */ |
299 | } a; | 299 | } a; |
300 | struct { /* needed for BMAP */ | 300 | struct { /* needed for BMAP */ |
301 | struct xfs_inode *ip; /* pointer to our inode */ | 301 | struct xfs_inode *ip; /* pointer to our inode */ |
302 | struct xfs_bmap_free *flist; /* list to free after */ | 302 | struct xfs_bmap_free *flist; /* list to free after */ |
303 | xfs_fsblock_t firstblock; /* 1st blk allocated */ | 303 | xfs_fsblock_t firstblock; /* 1st blk allocated */ |
304 | int allocated; /* count of alloced */ | 304 | int allocated; /* count of alloced */ |
305 | short forksize; /* fork's inode space */ | 305 | short forksize; /* fork's inode space */ |
306 | char whichfork; /* data or attr fork */ | 306 | char whichfork; /* data or attr fork */ |
307 | char flags; /* flags */ | 307 | char flags; /* flags */ |
308 | #define XFS_BTCUR_BPRV_WASDEL 1 /* was delayed */ | 308 | #define XFS_BTCUR_BPRV_WASDEL 1 /* was delayed */ |
309 | } b; | 309 | } b; |
310 | } bc_private; /* per-btree type data */ | 310 | } bc_private; /* per-btree type data */ |
311 | } xfs_btree_cur_t; | 311 | } xfs_btree_cur_t; |
312 | 312 | ||
313 | /* cursor flags */ | 313 | /* cursor flags */ |
314 | #define XFS_BTREE_LONG_PTRS (1<<0) /* pointers are 64bits long */ | 314 | #define XFS_BTREE_LONG_PTRS (1<<0) /* pointers are 64bits long */ |
315 | #define XFS_BTREE_ROOT_IN_INODE (1<<1) /* root may be variable size */ | 315 | #define XFS_BTREE_ROOT_IN_INODE (1<<1) /* root may be variable size */ |
316 | #define XFS_BTREE_LASTREC_UPDATE (1<<2) /* track last rec externally */ | 316 | #define XFS_BTREE_LASTREC_UPDATE (1<<2) /* track last rec externally */ |
317 | 317 | ||
318 | 318 | ||
319 | #define XFS_BTREE_NOERROR 0 | 319 | #define XFS_BTREE_NOERROR 0 |
320 | #define XFS_BTREE_ERROR 1 | 320 | #define XFS_BTREE_ERROR 1 |
321 | 321 | ||
322 | /* | 322 | /* |
323 | * Convert from buffer to btree block header. | 323 | * Convert from buffer to btree block header. |
324 | */ | 324 | */ |
325 | #define XFS_BUF_TO_BLOCK(bp) ((xfs_btree_block_t *)XFS_BUF_PTR(bp)) | 325 | #define XFS_BUF_TO_BLOCK(bp) ((xfs_btree_block_t *)XFS_BUF_PTR(bp)) |
326 | #define XFS_BUF_TO_LBLOCK(bp) ((xfs_btree_lblock_t *)XFS_BUF_PTR(bp)) | 326 | #define XFS_BUF_TO_LBLOCK(bp) ((xfs_btree_lblock_t *)XFS_BUF_PTR(bp)) |
327 | #define XFS_BUF_TO_SBLOCK(bp) ((xfs_btree_sblock_t *)XFS_BUF_PTR(bp)) | 327 | #define XFS_BUF_TO_SBLOCK(bp) ((xfs_btree_sblock_t *)XFS_BUF_PTR(bp)) |
328 | 328 | ||
329 | 329 | ||
330 | #ifdef __KERNEL__ | ||
331 | |||
332 | /* | 330 | /* |
333 | * Check that long form block header is ok. | 331 | * Check that long form block header is ok. |
334 | */ | 332 | */ |
335 | int /* error (0 or EFSCORRUPTED) */ | 333 | int /* error (0 or EFSCORRUPTED) */ |
336 | xfs_btree_check_lblock( | 334 | xfs_btree_check_lblock( |
337 | struct xfs_btree_cur *cur, /* btree cursor */ | 335 | struct xfs_btree_cur *cur, /* btree cursor */ |
338 | struct xfs_btree_lblock *block, /* btree long form block pointer */ | 336 | struct xfs_btree_lblock *block, /* btree long form block pointer */ |
339 | int level, /* level of the btree block */ | 337 | int level, /* level of the btree block */ |
340 | struct xfs_buf *bp); /* buffer containing block, if any */ | 338 | struct xfs_buf *bp); /* buffer containing block, if any */ |
341 | 339 | ||
342 | /* | 340 | /* |
343 | * Check that block header is ok. | 341 | * Check that block header is ok. |
344 | */ | 342 | */ |
345 | int | 343 | int |
346 | xfs_btree_check_block( | 344 | xfs_btree_check_block( |
347 | struct xfs_btree_cur *cur, /* btree cursor */ | 345 | struct xfs_btree_cur *cur, /* btree cursor */ |
348 | struct xfs_btree_block *block, /* generic btree block pointer */ | 346 | struct xfs_btree_block *block, /* generic btree block pointer */ |
349 | int level, /* level of the btree block */ | 347 | int level, /* level of the btree block */ |
350 | struct xfs_buf *bp); /* buffer containing block, if any */ | 348 | struct xfs_buf *bp); /* buffer containing block, if any */ |
351 | 349 | ||
352 | /* | 350 | /* |
353 | * Check that (long) pointer is ok. | 351 | * Check that (long) pointer is ok. |
354 | */ | 352 | */ |
355 | int /* error (0 or EFSCORRUPTED) */ | 353 | int /* error (0 or EFSCORRUPTED) */ |
356 | xfs_btree_check_lptr( | 354 | xfs_btree_check_lptr( |
357 | struct xfs_btree_cur *cur, /* btree cursor */ | 355 | struct xfs_btree_cur *cur, /* btree cursor */ |
358 | xfs_dfsbno_t ptr, /* btree block disk address */ | 356 | xfs_dfsbno_t ptr, /* btree block disk address */ |
359 | int level); /* btree block level */ | 357 | int level); /* btree block level */ |
360 | 358 | ||
361 | /* | 359 | /* |
362 | * Delete the btree cursor. | 360 | * Delete the btree cursor. |
363 | */ | 361 | */ |
364 | void | 362 | void |
365 | xfs_btree_del_cursor( | 363 | xfs_btree_del_cursor( |
366 | xfs_btree_cur_t *cur, /* btree cursor */ | 364 | xfs_btree_cur_t *cur, /* btree cursor */ |
367 | int error); /* del because of error */ | 365 | int error); /* del because of error */ |
368 | 366 | ||
369 | /* | 367 | /* |
370 | * Duplicate the btree cursor. | 368 | * Duplicate the btree cursor. |
371 | * Allocate a new one, copy the record, re-get the buffers. | 369 | * Allocate a new one, copy the record, re-get the buffers. |
372 | */ | 370 | */ |
373 | int /* error */ | 371 | int /* error */ |
374 | xfs_btree_dup_cursor( | 372 | xfs_btree_dup_cursor( |
375 | xfs_btree_cur_t *cur, /* input cursor */ | 373 | xfs_btree_cur_t *cur, /* input cursor */ |
376 | xfs_btree_cur_t **ncur);/* output cursor */ | 374 | xfs_btree_cur_t **ncur);/* output cursor */ |
377 | 375 | ||
378 | /* | 376 | /* |
379 | * Get a buffer for the block, return it with no data read. | 377 | * Get a buffer for the block, return it with no data read. |
380 | * Long-form addressing. | 378 | * Long-form addressing. |
381 | */ | 379 | */ |
382 | struct xfs_buf * /* buffer for fsbno */ | 380 | struct xfs_buf * /* buffer for fsbno */ |
383 | xfs_btree_get_bufl( | 381 | xfs_btree_get_bufl( |
384 | struct xfs_mount *mp, /* file system mount point */ | 382 | struct xfs_mount *mp, /* file system mount point */ |
385 | struct xfs_trans *tp, /* transaction pointer */ | 383 | struct xfs_trans *tp, /* transaction pointer */ |
386 | xfs_fsblock_t fsbno, /* file system block number */ | 384 | xfs_fsblock_t fsbno, /* file system block number */ |
387 | uint lock); /* lock flags for get_buf */ | 385 | uint lock); /* lock flags for get_buf */ |
388 | 386 | ||
389 | /* | 387 | /* |
390 | * Get a buffer for the block, return it with no data read. | 388 | * Get a buffer for the block, return it with no data read. |
391 | * Short-form addressing. | 389 | * Short-form addressing. |
392 | */ | 390 | */ |
393 | struct xfs_buf * /* buffer for agno/agbno */ | 391 | struct xfs_buf * /* buffer for agno/agbno */ |
394 | xfs_btree_get_bufs( | 392 | xfs_btree_get_bufs( |
395 | struct xfs_mount *mp, /* file system mount point */ | 393 | struct xfs_mount *mp, /* file system mount point */ |
396 | struct xfs_trans *tp, /* transaction pointer */ | 394 | struct xfs_trans *tp, /* transaction pointer */ |
397 | xfs_agnumber_t agno, /* allocation group number */ | 395 | xfs_agnumber_t agno, /* allocation group number */ |
398 | xfs_agblock_t agbno, /* allocation group block number */ | 396 | xfs_agblock_t agbno, /* allocation group block number */ |
399 | uint lock); /* lock flags for get_buf */ | 397 | uint lock); /* lock flags for get_buf */ |
400 | 398 | ||
401 | /* | 399 | /* |
402 | * Check for the cursor referring to the last block at the given level. | 400 | * Check for the cursor referring to the last block at the given level. |
403 | */ | 401 | */ |
404 | int /* 1=is last block, 0=not last block */ | 402 | int /* 1=is last block, 0=not last block */ |
405 | xfs_btree_islastblock( | 403 | xfs_btree_islastblock( |
406 | xfs_btree_cur_t *cur, /* btree cursor */ | 404 | xfs_btree_cur_t *cur, /* btree cursor */ |
407 | int level); /* level to check */ | 405 | int level); /* level to check */ |
408 | 406 | ||
409 | /* | 407 | /* |
410 | * Compute first and last byte offsets for the fields given. | 408 | * Compute first and last byte offsets for the fields given. |
411 | * Interprets the offsets table, which contains struct field offsets. | 409 | * Interprets the offsets table, which contains struct field offsets. |
412 | */ | 410 | */ |
413 | void | 411 | void |
414 | xfs_btree_offsets( | 412 | xfs_btree_offsets( |
415 | __int64_t fields, /* bitmask of fields */ | 413 | __int64_t fields, /* bitmask of fields */ |
416 | const short *offsets,/* table of field offsets */ | 414 | const short *offsets,/* table of field offsets */ |
417 | int nbits, /* number of bits to inspect */ | 415 | int nbits, /* number of bits to inspect */ |
418 | int *first, /* output: first byte offset */ | 416 | int *first, /* output: first byte offset */ |
419 | int *last); /* output: last byte offset */ | 417 | int *last); /* output: last byte offset */ |
420 | 418 | ||
421 | /* | 419 | /* |
422 | * Get a buffer for the block, return it read in. | 420 | * Get a buffer for the block, return it read in. |
423 | * Long-form addressing. | 421 | * Long-form addressing. |
424 | */ | 422 | */ |
425 | int /* error */ | 423 | int /* error */ |
426 | xfs_btree_read_bufl( | 424 | xfs_btree_read_bufl( |
427 | struct xfs_mount *mp, /* file system mount point */ | 425 | struct xfs_mount *mp, /* file system mount point */ |
428 | struct xfs_trans *tp, /* transaction pointer */ | 426 | struct xfs_trans *tp, /* transaction pointer */ |
429 | xfs_fsblock_t fsbno, /* file system block number */ | 427 | xfs_fsblock_t fsbno, /* file system block number */ |
430 | uint lock, /* lock flags for read_buf */ | 428 | uint lock, /* lock flags for read_buf */ |
431 | struct xfs_buf **bpp, /* buffer for fsbno */ | 429 | struct xfs_buf **bpp, /* buffer for fsbno */ |
432 | int refval);/* ref count value for buffer */ | 430 | int refval);/* ref count value for buffer */ |
433 | 431 | ||
434 | /* | 432 | /* |
435 | * Get a buffer for the block, return it read in. | 433 | * Get a buffer for the block, return it read in. |
436 | * Short-form addressing. | 434 | * Short-form addressing. |
437 | */ | 435 | */ |
438 | int /* error */ | 436 | int /* error */ |
439 | xfs_btree_read_bufs( | 437 | xfs_btree_read_bufs( |
440 | struct xfs_mount *mp, /* file system mount point */ | 438 | struct xfs_mount *mp, /* file system mount point */ |
441 | struct xfs_trans *tp, /* transaction pointer */ | 439 | struct xfs_trans *tp, /* transaction pointer */ |
442 | xfs_agnumber_t agno, /* allocation group number */ | 440 | xfs_agnumber_t agno, /* allocation group number */ |
443 | xfs_agblock_t agbno, /* allocation group block number */ | 441 | xfs_agblock_t agbno, /* allocation group block number */ |
444 | uint lock, /* lock flags for read_buf */ | 442 | uint lock, /* lock flags for read_buf */ |
445 | struct xfs_buf **bpp, /* buffer for agno/agbno */ | 443 | struct xfs_buf **bpp, /* buffer for agno/agbno */ |
446 | int refval);/* ref count value for buffer */ | 444 | int refval);/* ref count value for buffer */ |
447 | 445 | ||
448 | /* | 446 | /* |
449 | * Read-ahead the block, don't wait for it, don't return a buffer. | 447 | * Read-ahead the block, don't wait for it, don't return a buffer. |
450 | * Long-form addressing. | 448 | * Long-form addressing. |
451 | */ | 449 | */ |
452 | void /* error */ | 450 | void /* error */ |
453 | xfs_btree_reada_bufl( | 451 | xfs_btree_reada_bufl( |
454 | struct xfs_mount *mp, /* file system mount point */ | 452 | struct xfs_mount *mp, /* file system mount point */ |
455 | xfs_fsblock_t fsbno, /* file system block number */ | 453 | xfs_fsblock_t fsbno, /* file system block number */ |
456 | xfs_extlen_t count); /* count of filesystem blocks */ | 454 | xfs_extlen_t count); /* count of filesystem blocks */ |
457 | 455 | ||
458 | /* | 456 | /* |
459 | * Read-ahead the block, don't wait for it, don't return a buffer. | 457 | * Read-ahead the block, don't wait for it, don't return a buffer. |
460 | * Short-form addressing. | 458 | * Short-form addressing. |
461 | */ | 459 | */ |
462 | void /* error */ | 460 | void /* error */ |
463 | xfs_btree_reada_bufs( | 461 | xfs_btree_reada_bufs( |
464 | struct xfs_mount *mp, /* file system mount point */ | 462 | struct xfs_mount *mp, /* file system mount point */ |
465 | xfs_agnumber_t agno, /* allocation group number */ | 463 | xfs_agnumber_t agno, /* allocation group number */ |
466 | xfs_agblock_t agbno, /* allocation group block number */ | 464 | xfs_agblock_t agbno, /* allocation group block number */ |
467 | xfs_extlen_t count); /* count of filesystem blocks */ | 465 | xfs_extlen_t count); /* count of filesystem blocks */ |
468 | 466 | ||
469 | /* | 467 | /* |
470 | * Set the buffer for level "lev" in the cursor to bp, releasing | 468 | * Set the buffer for level "lev" in the cursor to bp, releasing |
471 | * any previous buffer. | 469 | * any previous buffer. |
472 | */ | 470 | */ |
473 | void | 471 | void |
474 | xfs_btree_setbuf( | 472 | xfs_btree_setbuf( |
475 | xfs_btree_cur_t *cur, /* btree cursor */ | 473 | xfs_btree_cur_t *cur, /* btree cursor */ |
476 | int lev, /* level in btree */ | 474 | int lev, /* level in btree */ |
477 | struct xfs_buf *bp); /* new buffer to set */ | 475 | struct xfs_buf *bp); /* new buffer to set */ |
478 | 476 | ||
479 | 477 | ||
480 | /* | 478 | /* |
481 | * Common btree core entry points. | 479 | * Common btree core entry points. |
482 | */ | 480 | */ |
483 | int xfs_btree_increment(struct xfs_btree_cur *, int, int *); | 481 | int xfs_btree_increment(struct xfs_btree_cur *, int, int *); |
484 | int xfs_btree_decrement(struct xfs_btree_cur *, int, int *); | 482 | int xfs_btree_decrement(struct xfs_btree_cur *, int, int *); |
485 | int xfs_btree_lookup(struct xfs_btree_cur *, xfs_lookup_t, int *); | 483 | int xfs_btree_lookup(struct xfs_btree_cur *, xfs_lookup_t, int *); |
486 | int xfs_btree_update(struct xfs_btree_cur *, union xfs_btree_rec *); | 484 | int xfs_btree_update(struct xfs_btree_cur *, union xfs_btree_rec *); |
487 | int xfs_btree_new_iroot(struct xfs_btree_cur *, int *, int *); | 485 | int xfs_btree_new_iroot(struct xfs_btree_cur *, int *, int *); |
488 | int xfs_btree_kill_iroot(struct xfs_btree_cur *); | 486 | int xfs_btree_kill_iroot(struct xfs_btree_cur *); |
489 | int xfs_btree_insert(struct xfs_btree_cur *, int *); | 487 | int xfs_btree_insert(struct xfs_btree_cur *, int *); |
490 | int xfs_btree_delete(struct xfs_btree_cur *, int *); | 488 | int xfs_btree_delete(struct xfs_btree_cur *, int *); |
491 | int xfs_btree_get_rec(struct xfs_btree_cur *, union xfs_btree_rec **, int *); | 489 | int xfs_btree_get_rec(struct xfs_btree_cur *, union xfs_btree_rec **, int *); |
492 | 490 | ||
493 | /* | 491 | /* |
494 | * Internal btree helpers also used by xfs_bmap.c. | 492 | * Internal btree helpers also used by xfs_bmap.c. |
495 | */ | 493 | */ |
496 | void xfs_btree_log_block(struct xfs_btree_cur *, struct xfs_buf *, int); | 494 | void xfs_btree_log_block(struct xfs_btree_cur *, struct xfs_buf *, int); |
497 | void xfs_btree_log_recs(struct xfs_btree_cur *, struct xfs_buf *, int, int); | 495 | void xfs_btree_log_recs(struct xfs_btree_cur *, struct xfs_buf *, int, int); |
498 | 496 | ||
499 | /* | 497 | /* |
500 | * Helpers. | 498 | * Helpers. |
501 | */ | 499 | */ |
502 | static inline int xfs_btree_get_numrecs(struct xfs_btree_block *block) | 500 | static inline int xfs_btree_get_numrecs(struct xfs_btree_block *block) |
503 | { | 501 | { |
504 | return be16_to_cpu(block->bb_numrecs); | 502 | return be16_to_cpu(block->bb_numrecs); |
505 | } | 503 | } |
506 | 504 | ||
507 | static inline void xfs_btree_set_numrecs(struct xfs_btree_block *block, | 505 | static inline void xfs_btree_set_numrecs(struct xfs_btree_block *block, |
508 | __uint16_t numrecs) | 506 | __uint16_t numrecs) |
509 | { | 507 | { |
510 | block->bb_numrecs = cpu_to_be16(numrecs); | 508 | block->bb_numrecs = cpu_to_be16(numrecs); |
511 | } | 509 | } |
512 | 510 | ||
513 | static inline int xfs_btree_get_level(struct xfs_btree_block *block) | 511 | static inline int xfs_btree_get_level(struct xfs_btree_block *block) |
514 | { | 512 | { |
515 | return be16_to_cpu(block->bb_level); | 513 | return be16_to_cpu(block->bb_level); |
516 | } | 514 | } |
517 | |||
518 | #endif /* __KERNEL__ */ | ||
519 | 515 | ||
520 | 516 | ||
521 | /* | 517 | /* |
522 | * Min and max functions for extlen, agblock, fileoff, and filblks types. | 518 | * Min and max functions for extlen, agblock, fileoff, and filblks types. |
523 | */ | 519 | */ |
524 | #define XFS_EXTLEN_MIN(a,b) min_t(xfs_extlen_t, (a), (b)) | 520 | #define XFS_EXTLEN_MIN(a,b) min_t(xfs_extlen_t, (a), (b)) |
525 | #define XFS_EXTLEN_MAX(a,b) max_t(xfs_extlen_t, (a), (b)) | 521 | #define XFS_EXTLEN_MAX(a,b) max_t(xfs_extlen_t, (a), (b)) |
526 | #define XFS_AGBLOCK_MIN(a,b) min_t(xfs_agblock_t, (a), (b)) | 522 | #define XFS_AGBLOCK_MIN(a,b) min_t(xfs_agblock_t, (a), (b)) |
527 | #define XFS_AGBLOCK_MAX(a,b) max_t(xfs_agblock_t, (a), (b)) | 523 | #define XFS_AGBLOCK_MAX(a,b) max_t(xfs_agblock_t, (a), (b)) |
528 | #define XFS_FILEOFF_MIN(a,b) min_t(xfs_fileoff_t, (a), (b)) | 524 | #define XFS_FILEOFF_MIN(a,b) min_t(xfs_fileoff_t, (a), (b)) |
529 | #define XFS_FILEOFF_MAX(a,b) max_t(xfs_fileoff_t, (a), (b)) | 525 | #define XFS_FILEOFF_MAX(a,b) max_t(xfs_fileoff_t, (a), (b)) |
530 | #define XFS_FILBLKS_MIN(a,b) min_t(xfs_filblks_t, (a), (b)) | 526 | #define XFS_FILBLKS_MIN(a,b) min_t(xfs_filblks_t, (a), (b)) |
531 | #define XFS_FILBLKS_MAX(a,b) max_t(xfs_filblks_t, (a), (b)) | 527 | #define XFS_FILBLKS_MAX(a,b) max_t(xfs_filblks_t, (a), (b)) |
532 | 528 | ||
533 | #define XFS_FSB_SANITY_CHECK(mp,fsb) \ | 529 | #define XFS_FSB_SANITY_CHECK(mp,fsb) \ |
534 | (XFS_FSB_TO_AGNO(mp, fsb) < mp->m_sb.sb_agcount && \ | 530 | (XFS_FSB_TO_AGNO(mp, fsb) < mp->m_sb.sb_agcount && \ |
535 | XFS_FSB_TO_AGBNO(mp, fsb) < mp->m_sb.sb_agblocks) | 531 | XFS_FSB_TO_AGBNO(mp, fsb) < mp->m_sb.sb_agblocks) |
536 | 532 | ||
537 | #endif /* __XFS_BTREE_H__ */ | 533 | #endif /* __XFS_BTREE_H__ */ |
538 | 534 |
fs/xfs/xfs_da_btree.h
1 | /* | 1 | /* |
2 | * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License as | 6 | * modify it under the terms of the GNU General Public License as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | * | 8 | * |
9 | * This program is distributed in the hope that it would be useful, | 9 | * This program is distributed in the hope that it would be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. | 12 | * GNU General Public License for more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License | 14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write the Free Software Foundation, | 15 | * along with this program; if not, write the Free Software Foundation, |
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ | 17 | */ |
18 | #ifndef __XFS_DA_BTREE_H__ | 18 | #ifndef __XFS_DA_BTREE_H__ |
19 | #define __XFS_DA_BTREE_H__ | 19 | #define __XFS_DA_BTREE_H__ |
20 | 20 | ||
21 | struct xfs_buf; | 21 | struct xfs_buf; |
22 | struct xfs_bmap_free; | 22 | struct xfs_bmap_free; |
23 | struct xfs_inode; | 23 | struct xfs_inode; |
24 | struct xfs_mount; | 24 | struct xfs_mount; |
25 | struct xfs_trans; | 25 | struct xfs_trans; |
26 | struct zone; | 26 | struct zone; |
27 | 27 | ||
28 | /*======================================================================== | 28 | /*======================================================================== |
29 | * Directory Structure when greater than XFS_LBSIZE(mp) bytes. | 29 | * Directory Structure when greater than XFS_LBSIZE(mp) bytes. |
30 | *========================================================================*/ | 30 | *========================================================================*/ |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * This structure is common to both leaf nodes and non-leaf nodes in the Btree. | 33 | * This structure is common to both leaf nodes and non-leaf nodes in the Btree. |
34 | * | 34 | * |
35 | * Is is used to manage a doubly linked list of all blocks at the same | 35 | * Is is used to manage a doubly linked list of all blocks at the same |
36 | * level in the Btree, and to identify which type of block this is. | 36 | * level in the Btree, and to identify which type of block this is. |
37 | */ | 37 | */ |
38 | #define XFS_DA_NODE_MAGIC 0xfebe /* magic number: non-leaf blocks */ | 38 | #define XFS_DA_NODE_MAGIC 0xfebe /* magic number: non-leaf blocks */ |
39 | #define XFS_ATTR_LEAF_MAGIC 0xfbee /* magic number: attribute leaf blks */ | 39 | #define XFS_ATTR_LEAF_MAGIC 0xfbee /* magic number: attribute leaf blks */ |
40 | #define XFS_DIR2_LEAF1_MAGIC 0xd2f1 /* magic number: v2 dirlf single blks */ | 40 | #define XFS_DIR2_LEAF1_MAGIC 0xd2f1 /* magic number: v2 dirlf single blks */ |
41 | #define XFS_DIR2_LEAFN_MAGIC 0xd2ff /* magic number: v2 dirlf multi blks */ | 41 | #define XFS_DIR2_LEAFN_MAGIC 0xd2ff /* magic number: v2 dirlf multi blks */ |
42 | 42 | ||
43 | typedef struct xfs_da_blkinfo { | 43 | typedef struct xfs_da_blkinfo { |
44 | __be32 forw; /* previous block in list */ | 44 | __be32 forw; /* previous block in list */ |
45 | __be32 back; /* following block in list */ | 45 | __be32 back; /* following block in list */ |
46 | __be16 magic; /* validity check on block */ | 46 | __be16 magic; /* validity check on block */ |
47 | __be16 pad; /* unused */ | 47 | __be16 pad; /* unused */ |
48 | } xfs_da_blkinfo_t; | 48 | } xfs_da_blkinfo_t; |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * This is the structure of the root and intermediate nodes in the Btree. | 51 | * This is the structure of the root and intermediate nodes in the Btree. |
52 | * The leaf nodes are defined above. | 52 | * The leaf nodes are defined above. |
53 | * | 53 | * |
54 | * Entries are not packed. | 54 | * Entries are not packed. |
55 | * | 55 | * |
56 | * Since we have duplicate keys, use a binary search but always follow | 56 | * Since we have duplicate keys, use a binary search but always follow |
57 | * all match in the block, not just the first match found. | 57 | * all match in the block, not just the first match found. |
58 | */ | 58 | */ |
59 | #define XFS_DA_NODE_MAXDEPTH 5 /* max depth of Btree */ | 59 | #define XFS_DA_NODE_MAXDEPTH 5 /* max depth of Btree */ |
60 | 60 | ||
61 | typedef struct xfs_da_intnode { | 61 | typedef struct xfs_da_intnode { |
62 | struct xfs_da_node_hdr { /* constant-structure header block */ | 62 | struct xfs_da_node_hdr { /* constant-structure header block */ |
63 | xfs_da_blkinfo_t info; /* block type, links, etc. */ | 63 | xfs_da_blkinfo_t info; /* block type, links, etc. */ |
64 | __be16 count; /* count of active entries */ | 64 | __be16 count; /* count of active entries */ |
65 | __be16 level; /* level above leaves (leaf == 0) */ | 65 | __be16 level; /* level above leaves (leaf == 0) */ |
66 | } hdr; | 66 | } hdr; |
67 | struct xfs_da_node_entry { | 67 | struct xfs_da_node_entry { |
68 | __be32 hashval; /* hash value for this descendant */ | 68 | __be32 hashval; /* hash value for this descendant */ |
69 | __be32 before; /* Btree block before this key */ | 69 | __be32 before; /* Btree block before this key */ |
70 | } btree[1]; /* variable sized array of keys */ | 70 | } btree[1]; /* variable sized array of keys */ |
71 | } xfs_da_intnode_t; | 71 | } xfs_da_intnode_t; |
72 | typedef struct xfs_da_node_hdr xfs_da_node_hdr_t; | 72 | typedef struct xfs_da_node_hdr xfs_da_node_hdr_t; |
73 | typedef struct xfs_da_node_entry xfs_da_node_entry_t; | 73 | typedef struct xfs_da_node_entry xfs_da_node_entry_t; |
74 | 74 | ||
75 | #define XFS_LBSIZE(mp) (mp)->m_sb.sb_blocksize | 75 | #define XFS_LBSIZE(mp) (mp)->m_sb.sb_blocksize |
76 | 76 | ||
77 | /*======================================================================== | 77 | /*======================================================================== |
78 | * Btree searching and modification structure definitions. | 78 | * Btree searching and modification structure definitions. |
79 | *========================================================================*/ | 79 | *========================================================================*/ |
80 | 80 | ||
81 | /* | 81 | /* |
82 | * Search comparison results | 82 | * Search comparison results |
83 | */ | 83 | */ |
84 | enum xfs_dacmp { | 84 | enum xfs_dacmp { |
85 | XFS_CMP_DIFFERENT, /* names are completely different */ | 85 | XFS_CMP_DIFFERENT, /* names are completely different */ |
86 | XFS_CMP_EXACT, /* names are exactly the same */ | 86 | XFS_CMP_EXACT, /* names are exactly the same */ |
87 | XFS_CMP_CASE /* names are same but differ in case */ | 87 | XFS_CMP_CASE /* names are same but differ in case */ |
88 | }; | 88 | }; |
89 | 89 | ||
90 | /* | 90 | /* |
91 | * Structure to ease passing around component names. | 91 | * Structure to ease passing around component names. |
92 | */ | 92 | */ |
93 | typedef struct xfs_da_args { | 93 | typedef struct xfs_da_args { |
94 | const uchar_t *name; /* string (maybe not NULL terminated) */ | 94 | const uchar_t *name; /* string (maybe not NULL terminated) */ |
95 | int namelen; /* length of string (maybe no NULL) */ | 95 | int namelen; /* length of string (maybe no NULL) */ |
96 | uchar_t *value; /* set of bytes (maybe contain NULLs) */ | 96 | uchar_t *value; /* set of bytes (maybe contain NULLs) */ |
97 | int valuelen; /* length of value */ | 97 | int valuelen; /* length of value */ |
98 | int flags; /* argument flags (eg: ATTR_NOCREATE) */ | 98 | int flags; /* argument flags (eg: ATTR_NOCREATE) */ |
99 | xfs_dahash_t hashval; /* hash value of name */ | 99 | xfs_dahash_t hashval; /* hash value of name */ |
100 | xfs_ino_t inumber; /* input/output inode number */ | 100 | xfs_ino_t inumber; /* input/output inode number */ |
101 | struct xfs_inode *dp; /* directory inode to manipulate */ | 101 | struct xfs_inode *dp; /* directory inode to manipulate */ |
102 | xfs_fsblock_t *firstblock; /* ptr to firstblock for bmap calls */ | 102 | xfs_fsblock_t *firstblock; /* ptr to firstblock for bmap calls */ |
103 | struct xfs_bmap_free *flist; /* ptr to freelist for bmap_finish */ | 103 | struct xfs_bmap_free *flist; /* ptr to freelist for bmap_finish */ |
104 | struct xfs_trans *trans; /* current trans (changes over time) */ | 104 | struct xfs_trans *trans; /* current trans (changes over time) */ |
105 | xfs_extlen_t total; /* total blocks needed, for 1st bmap */ | 105 | xfs_extlen_t total; /* total blocks needed, for 1st bmap */ |
106 | int whichfork; /* data or attribute fork */ | 106 | int whichfork; /* data or attribute fork */ |
107 | xfs_dablk_t blkno; /* blkno of attr leaf of interest */ | 107 | xfs_dablk_t blkno; /* blkno of attr leaf of interest */ |
108 | int index; /* index of attr of interest in blk */ | 108 | int index; /* index of attr of interest in blk */ |
109 | xfs_dablk_t rmtblkno; /* remote attr value starting blkno */ | 109 | xfs_dablk_t rmtblkno; /* remote attr value starting blkno */ |
110 | int rmtblkcnt; /* remote attr value block count */ | 110 | int rmtblkcnt; /* remote attr value block count */ |
111 | xfs_dablk_t blkno2; /* blkno of 2nd attr leaf of interest */ | 111 | xfs_dablk_t blkno2; /* blkno of 2nd attr leaf of interest */ |
112 | int index2; /* index of 2nd attr in blk */ | 112 | int index2; /* index of 2nd attr in blk */ |
113 | xfs_dablk_t rmtblkno2; /* remote attr value starting blkno */ | 113 | xfs_dablk_t rmtblkno2; /* remote attr value starting blkno */ |
114 | int rmtblkcnt2; /* remote attr value block count */ | 114 | int rmtblkcnt2; /* remote attr value block count */ |
115 | int op_flags; /* operation flags */ | 115 | int op_flags; /* operation flags */ |
116 | enum xfs_dacmp cmpresult; /* name compare result for lookups */ | 116 | enum xfs_dacmp cmpresult; /* name compare result for lookups */ |
117 | } xfs_da_args_t; | 117 | } xfs_da_args_t; |
118 | 118 | ||
119 | /* | 119 | /* |
120 | * Operation flags: | 120 | * Operation flags: |
121 | */ | 121 | */ |
122 | #define XFS_DA_OP_JUSTCHECK 0x0001 /* check for ok with no space */ | 122 | #define XFS_DA_OP_JUSTCHECK 0x0001 /* check for ok with no space */ |
123 | #define XFS_DA_OP_RENAME 0x0002 /* this is an atomic rename op */ | 123 | #define XFS_DA_OP_RENAME 0x0002 /* this is an atomic rename op */ |
124 | #define XFS_DA_OP_ADDNAME 0x0004 /* this is an add operation */ | 124 | #define XFS_DA_OP_ADDNAME 0x0004 /* this is an add operation */ |
125 | #define XFS_DA_OP_OKNOENT 0x0008 /* lookup/add op, ENOENT ok, else die */ | 125 | #define XFS_DA_OP_OKNOENT 0x0008 /* lookup/add op, ENOENT ok, else die */ |
126 | #define XFS_DA_OP_CILOOKUP 0x0010 /* lookup to return CI name if found */ | 126 | #define XFS_DA_OP_CILOOKUP 0x0010 /* lookup to return CI name if found */ |
127 | 127 | ||
128 | /* | 128 | /* |
129 | * Structure to describe buffer(s) for a block. | 129 | * Structure to describe buffer(s) for a block. |
130 | * This is needed in the directory version 2 format case, when | 130 | * This is needed in the directory version 2 format case, when |
131 | * multiple non-contiguous fsblocks might be needed to cover one | 131 | * multiple non-contiguous fsblocks might be needed to cover one |
132 | * logical directory block. | 132 | * logical directory block. |
133 | * If the buffer count is 1 then the data pointer points to the | 133 | * If the buffer count is 1 then the data pointer points to the |
134 | * same place as the b_addr field for the buffer, else to kmem_alloced memory. | 134 | * same place as the b_addr field for the buffer, else to kmem_alloced memory. |
135 | */ | 135 | */ |
136 | typedef struct xfs_dabuf { | 136 | typedef struct xfs_dabuf { |
137 | int nbuf; /* number of buffer pointers present */ | 137 | int nbuf; /* number of buffer pointers present */ |
138 | short dirty; /* data needs to be copied back */ | 138 | short dirty; /* data needs to be copied back */ |
139 | short bbcount; /* how large is data in bbs */ | 139 | short bbcount; /* how large is data in bbs */ |
140 | void *data; /* pointer for buffers' data */ | 140 | void *data; /* pointer for buffers' data */ |
141 | #ifdef XFS_DABUF_DEBUG | 141 | #ifdef XFS_DABUF_DEBUG |
142 | inst_t *ra; /* return address of caller to make */ | 142 | inst_t *ra; /* return address of caller to make */ |
143 | struct xfs_dabuf *next; /* next in global chain */ | 143 | struct xfs_dabuf *next; /* next in global chain */ |
144 | struct xfs_dabuf *prev; /* previous in global chain */ | 144 | struct xfs_dabuf *prev; /* previous in global chain */ |
145 | struct xfs_buftarg *target; /* device for buffer */ | 145 | struct xfs_buftarg *target; /* device for buffer */ |
146 | xfs_daddr_t blkno; /* daddr first in bps[0] */ | 146 | xfs_daddr_t blkno; /* daddr first in bps[0] */ |
147 | #endif | 147 | #endif |
148 | struct xfs_buf *bps[1]; /* actually nbuf of these */ | 148 | struct xfs_buf *bps[1]; /* actually nbuf of these */ |
149 | } xfs_dabuf_t; | 149 | } xfs_dabuf_t; |
150 | #define XFS_DA_BUF_SIZE(n) \ | 150 | #define XFS_DA_BUF_SIZE(n) \ |
151 | (sizeof(xfs_dabuf_t) + sizeof(struct xfs_buf *) * ((n) - 1)) | 151 | (sizeof(xfs_dabuf_t) + sizeof(struct xfs_buf *) * ((n) - 1)) |
152 | 152 | ||
153 | #ifdef XFS_DABUF_DEBUG | 153 | #ifdef XFS_DABUF_DEBUG |
154 | extern xfs_dabuf_t *xfs_dabuf_global_list; | 154 | extern xfs_dabuf_t *xfs_dabuf_global_list; |
155 | #endif | 155 | #endif |
156 | 156 | ||
157 | /* | 157 | /* |
158 | * Storage for holding state during Btree searches and split/join ops. | 158 | * Storage for holding state during Btree searches and split/join ops. |
159 | * | 159 | * |
160 | * Only need space for 5 intermediate nodes. With a minimum of 62-way | 160 | * Only need space for 5 intermediate nodes. With a minimum of 62-way |
161 | * fanout to the Btree, we can support over 900 million directory blocks, | 161 | * fanout to the Btree, we can support over 900 million directory blocks, |
162 | * which is slightly more than enough. | 162 | * which is slightly more than enough. |
163 | */ | 163 | */ |
164 | typedef struct xfs_da_state_blk { | 164 | typedef struct xfs_da_state_blk { |
165 | xfs_dabuf_t *bp; /* buffer containing block */ | 165 | xfs_dabuf_t *bp; /* buffer containing block */ |
166 | xfs_dablk_t blkno; /* filesystem blkno of buffer */ | 166 | xfs_dablk_t blkno; /* filesystem blkno of buffer */ |
167 | xfs_daddr_t disk_blkno; /* on-disk blkno (in BBs) of buffer */ | 167 | xfs_daddr_t disk_blkno; /* on-disk blkno (in BBs) of buffer */ |
168 | int index; /* relevant index into block */ | 168 | int index; /* relevant index into block */ |
169 | xfs_dahash_t hashval; /* last hash value in block */ | 169 | xfs_dahash_t hashval; /* last hash value in block */ |
170 | int magic; /* blk's magic number, ie: blk type */ | 170 | int magic; /* blk's magic number, ie: blk type */ |
171 | } xfs_da_state_blk_t; | 171 | } xfs_da_state_blk_t; |
172 | 172 | ||
173 | typedef struct xfs_da_state_path { | 173 | typedef struct xfs_da_state_path { |
174 | int active; /* number of active levels */ | 174 | int active; /* number of active levels */ |
175 | xfs_da_state_blk_t blk[XFS_DA_NODE_MAXDEPTH]; | 175 | xfs_da_state_blk_t blk[XFS_DA_NODE_MAXDEPTH]; |
176 | } xfs_da_state_path_t; | 176 | } xfs_da_state_path_t; |
177 | 177 | ||
178 | typedef struct xfs_da_state { | 178 | typedef struct xfs_da_state { |
179 | xfs_da_args_t *args; /* filename arguments */ | 179 | xfs_da_args_t *args; /* filename arguments */ |
180 | struct xfs_mount *mp; /* filesystem mount point */ | 180 | struct xfs_mount *mp; /* filesystem mount point */ |
181 | unsigned int blocksize; /* logical block size */ | 181 | unsigned int blocksize; /* logical block size */ |
182 | unsigned int node_ents; /* how many entries in danode */ | 182 | unsigned int node_ents; /* how many entries in danode */ |
183 | xfs_da_state_path_t path; /* search/split paths */ | 183 | xfs_da_state_path_t path; /* search/split paths */ |
184 | xfs_da_state_path_t altpath; /* alternate path for join */ | 184 | xfs_da_state_path_t altpath; /* alternate path for join */ |
185 | unsigned char inleaf; /* insert into 1->lf, 0->splf */ | 185 | unsigned char inleaf; /* insert into 1->lf, 0->splf */ |
186 | unsigned char extravalid; /* T/F: extrablk is in use */ | 186 | unsigned char extravalid; /* T/F: extrablk is in use */ |
187 | unsigned char extraafter; /* T/F: extrablk is after new */ | 187 | unsigned char extraafter; /* T/F: extrablk is after new */ |
188 | xfs_da_state_blk_t extrablk; /* for double-splits on leafs */ | 188 | xfs_da_state_blk_t extrablk; /* for double-splits on leafs */ |
189 | /* for dirv2 extrablk is data */ | 189 | /* for dirv2 extrablk is data */ |
190 | } xfs_da_state_t; | 190 | } xfs_da_state_t; |
191 | 191 | ||
192 | /* | 192 | /* |
193 | * Utility macros to aid in logging changed structure fields. | 193 | * Utility macros to aid in logging changed structure fields. |
194 | */ | 194 | */ |
195 | #define XFS_DA_LOGOFF(BASE, ADDR) ((char *)(ADDR) - (char *)(BASE)) | 195 | #define XFS_DA_LOGOFF(BASE, ADDR) ((char *)(ADDR) - (char *)(BASE)) |
196 | #define XFS_DA_LOGRANGE(BASE, ADDR, SIZE) \ | 196 | #define XFS_DA_LOGRANGE(BASE, ADDR, SIZE) \ |
197 | (uint)(XFS_DA_LOGOFF(BASE, ADDR)), \ | 197 | (uint)(XFS_DA_LOGOFF(BASE, ADDR)), \ |
198 | (uint)(XFS_DA_LOGOFF(BASE, ADDR)+(SIZE)-1) | 198 | (uint)(XFS_DA_LOGOFF(BASE, ADDR)+(SIZE)-1) |
199 | 199 | ||
200 | /* | 200 | /* |
201 | * Name ops for directory and/or attr name operations | 201 | * Name ops for directory and/or attr name operations |
202 | */ | 202 | */ |
203 | struct xfs_nameops { | 203 | struct xfs_nameops { |
204 | xfs_dahash_t (*hashname)(struct xfs_name *); | 204 | xfs_dahash_t (*hashname)(struct xfs_name *); |
205 | enum xfs_dacmp (*compname)(struct xfs_da_args *, const char *, int); | 205 | enum xfs_dacmp (*compname)(struct xfs_da_args *, const char *, int); |
206 | }; | 206 | }; |
207 | 207 | ||
208 | 208 | ||
209 | #ifdef __KERNEL__ | ||
210 | /*======================================================================== | 209 | /*======================================================================== |
211 | * Function prototypes for the kernel. | 210 | * Function prototypes. |
212 | *========================================================================*/ | 211 | *========================================================================*/ |
213 | 212 | ||
214 | /* | 213 | /* |
215 | * Routines used for growing the Btree. | 214 | * Routines used for growing the Btree. |
216 | */ | 215 | */ |
217 | int xfs_da_node_create(xfs_da_args_t *args, xfs_dablk_t blkno, int level, | 216 | int xfs_da_node_create(xfs_da_args_t *args, xfs_dablk_t blkno, int level, |
218 | xfs_dabuf_t **bpp, int whichfork); | 217 | xfs_dabuf_t **bpp, int whichfork); |
219 | int xfs_da_split(xfs_da_state_t *state); | 218 | int xfs_da_split(xfs_da_state_t *state); |
220 | 219 | ||
221 | /* | 220 | /* |
222 | * Routines used for shrinking the Btree. | 221 | * Routines used for shrinking the Btree. |
223 | */ | 222 | */ |
224 | int xfs_da_join(xfs_da_state_t *state); | 223 | int xfs_da_join(xfs_da_state_t *state); |
225 | void xfs_da_fixhashpath(xfs_da_state_t *state, | 224 | void xfs_da_fixhashpath(xfs_da_state_t *state, |
226 | xfs_da_state_path_t *path_to_to_fix); | 225 | xfs_da_state_path_t *path_to_to_fix); |
227 | 226 | ||
228 | /* | 227 | /* |
229 | * Routines used for finding things in the Btree. | 228 | * Routines used for finding things in the Btree. |
230 | */ | 229 | */ |
231 | int xfs_da_node_lookup_int(xfs_da_state_t *state, int *result); | 230 | int xfs_da_node_lookup_int(xfs_da_state_t *state, int *result); |
232 | int xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path, | 231 | int xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path, |
233 | int forward, int release, int *result); | 232 | int forward, int release, int *result); |
234 | /* | 233 | /* |
235 | * Utility routines. | 234 | * Utility routines. |
236 | */ | 235 | */ |
237 | int xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, | 236 | int xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, |
238 | xfs_da_state_blk_t *new_blk); | 237 | xfs_da_state_blk_t *new_blk); |
239 | 238 | ||
240 | /* | 239 | /* |
241 | * Utility routines. | 240 | * Utility routines. |
242 | */ | 241 | */ |
243 | int xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno); | 242 | int xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno); |
244 | int xfs_da_get_buf(struct xfs_trans *trans, struct xfs_inode *dp, | 243 | int xfs_da_get_buf(struct xfs_trans *trans, struct xfs_inode *dp, |
245 | xfs_dablk_t bno, xfs_daddr_t mappedbno, | 244 | xfs_dablk_t bno, xfs_daddr_t mappedbno, |
246 | xfs_dabuf_t **bp, int whichfork); | 245 | xfs_dabuf_t **bp, int whichfork); |
247 | int xfs_da_read_buf(struct xfs_trans *trans, struct xfs_inode *dp, | 246 | int xfs_da_read_buf(struct xfs_trans *trans, struct xfs_inode *dp, |
248 | xfs_dablk_t bno, xfs_daddr_t mappedbno, | 247 | xfs_dablk_t bno, xfs_daddr_t mappedbno, |
249 | xfs_dabuf_t **bpp, int whichfork); | 248 | xfs_dabuf_t **bpp, int whichfork); |
250 | xfs_daddr_t xfs_da_reada_buf(struct xfs_trans *trans, struct xfs_inode *dp, | 249 | xfs_daddr_t xfs_da_reada_buf(struct xfs_trans *trans, struct xfs_inode *dp, |
251 | xfs_dablk_t bno, int whichfork); | 250 | xfs_dablk_t bno, int whichfork); |
252 | int xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, | 251 | int xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, |
253 | xfs_dabuf_t *dead_buf); | 252 | xfs_dabuf_t *dead_buf); |
254 | 253 | ||
255 | uint xfs_da_hashname(const uchar_t *name_string, int name_length); | 254 | uint xfs_da_hashname(const uchar_t *name_string, int name_length); |
256 | enum xfs_dacmp xfs_da_compname(struct xfs_da_args *args, | 255 | enum xfs_dacmp xfs_da_compname(struct xfs_da_args *args, |
257 | const char *name, int len); | 256 | const char *name, int len); |
258 | 257 | ||
259 | 258 | ||
260 | xfs_da_state_t *xfs_da_state_alloc(void); | 259 | xfs_da_state_t *xfs_da_state_alloc(void); |
261 | void xfs_da_state_free(xfs_da_state_t *state); | 260 | void xfs_da_state_free(xfs_da_state_t *state); |
262 | 261 | ||
263 | void xfs_da_buf_done(xfs_dabuf_t *dabuf); | 262 | void xfs_da_buf_done(xfs_dabuf_t *dabuf); |
264 | void xfs_da_log_buf(struct xfs_trans *tp, xfs_dabuf_t *dabuf, uint first, | 263 | void xfs_da_log_buf(struct xfs_trans *tp, xfs_dabuf_t *dabuf, uint first, |
265 | uint last); | 264 | uint last); |
266 | void xfs_da_brelse(struct xfs_trans *tp, xfs_dabuf_t *dabuf); | 265 | void xfs_da_brelse(struct xfs_trans *tp, xfs_dabuf_t *dabuf); |
267 | void xfs_da_binval(struct xfs_trans *tp, xfs_dabuf_t *dabuf); | 266 | void xfs_da_binval(struct xfs_trans *tp, xfs_dabuf_t *dabuf); |
268 | xfs_daddr_t xfs_da_blkno(xfs_dabuf_t *dabuf); | 267 | xfs_daddr_t xfs_da_blkno(xfs_dabuf_t *dabuf); |
269 | 268 | ||
270 | extern struct kmem_zone *xfs_da_state_zone; | 269 | extern struct kmem_zone *xfs_da_state_zone; |
271 | extern struct kmem_zone *xfs_dabuf_zone; | 270 | extern struct kmem_zone *xfs_dabuf_zone; |
272 | #endif /* __KERNEL__ */ | ||
273 | 271 | ||
274 | #endif /* __XFS_DA_BTREE_H__ */ | 272 | #endif /* __XFS_DA_BTREE_H__ */ |
275 | 273 |
fs/xfs/xfs_ialloc.h
1 | /* | 1 | /* |
2 | * Copyright (c) 2000,2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000,2005 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License as | 6 | * modify it under the terms of the GNU General Public License as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | * | 8 | * |
9 | * This program is distributed in the hope that it would be useful, | 9 | * This program is distributed in the hope that it would be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. | 12 | * GNU General Public License for more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License | 14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write the Free Software Foundation, | 15 | * along with this program; if not, write the Free Software Foundation, |
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ | 17 | */ |
18 | #ifndef __XFS_IALLOC_H__ | 18 | #ifndef __XFS_IALLOC_H__ |
19 | #define __XFS_IALLOC_H__ | 19 | #define __XFS_IALLOC_H__ |
20 | 20 | ||
21 | struct xfs_buf; | 21 | struct xfs_buf; |
22 | struct xfs_dinode; | 22 | struct xfs_dinode; |
23 | struct xfs_mount; | 23 | struct xfs_mount; |
24 | struct xfs_trans; | 24 | struct xfs_trans; |
25 | 25 | ||
26 | /* | 26 | /* |
27 | * Allocation parameters for inode allocation. | 27 | * Allocation parameters for inode allocation. |
28 | */ | 28 | */ |
29 | #define XFS_IALLOC_INODES(mp) (mp)->m_ialloc_inos | 29 | #define XFS_IALLOC_INODES(mp) (mp)->m_ialloc_inos |
30 | #define XFS_IALLOC_BLOCKS(mp) (mp)->m_ialloc_blks | 30 | #define XFS_IALLOC_BLOCKS(mp) (mp)->m_ialloc_blks |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * Move inodes in clusters of this size. | 33 | * Move inodes in clusters of this size. |
34 | */ | 34 | */ |
35 | #define XFS_INODE_BIG_CLUSTER_SIZE 8192 | 35 | #define XFS_INODE_BIG_CLUSTER_SIZE 8192 |
36 | #define XFS_INODE_CLUSTER_SIZE(mp) (mp)->m_inode_cluster_size | 36 | #define XFS_INODE_CLUSTER_SIZE(mp) (mp)->m_inode_cluster_size |
37 | 37 | ||
38 | /* | 38 | /* |
39 | * Make an inode pointer out of the buffer/offset. | 39 | * Make an inode pointer out of the buffer/offset. |
40 | */ | 40 | */ |
41 | #define XFS_MAKE_IPTR(mp,b,o) xfs_make_iptr(mp,b,o) | 41 | #define XFS_MAKE_IPTR(mp,b,o) xfs_make_iptr(mp,b,o) |
42 | static inline struct xfs_dinode * | 42 | static inline struct xfs_dinode * |
43 | xfs_make_iptr(struct xfs_mount *mp, struct xfs_buf *b, int o) | 43 | xfs_make_iptr(struct xfs_mount *mp, struct xfs_buf *b, int o) |
44 | { | 44 | { |
45 | return (xfs_dinode_t *) | 45 | return (xfs_dinode_t *) |
46 | (xfs_buf_offset(b, o << (mp)->m_sb.sb_inodelog)); | 46 | (xfs_buf_offset(b, o << (mp)->m_sb.sb_inodelog)); |
47 | } | 47 | } |
48 | 48 | ||
49 | /* | 49 | /* |
50 | * Find a free (set) bit in the inode bitmask. | 50 | * Find a free (set) bit in the inode bitmask. |
51 | */ | 51 | */ |
52 | #define XFS_IALLOC_FIND_FREE(fp) xfs_ialloc_find_free(fp) | 52 | #define XFS_IALLOC_FIND_FREE(fp) xfs_ialloc_find_free(fp) |
53 | static inline int xfs_ialloc_find_free(xfs_inofree_t *fp) | 53 | static inline int xfs_ialloc_find_free(xfs_inofree_t *fp) |
54 | { | 54 | { |
55 | return xfs_lowbit64(*fp); | 55 | return xfs_lowbit64(*fp); |
56 | } | 56 | } |
57 | 57 | ||
58 | 58 | ||
59 | #ifdef __KERNEL__ | ||
60 | /* | 59 | /* |
61 | * Allocate an inode on disk. | 60 | * Allocate an inode on disk. |
62 | * Mode is used to tell whether the new inode will need space, and whether | 61 | * Mode is used to tell whether the new inode will need space, and whether |
63 | * it is a directory. | 62 | * it is a directory. |
64 | * | 63 | * |
65 | * To work within the constraint of one allocation per transaction, | 64 | * To work within the constraint of one allocation per transaction, |
66 | * xfs_dialloc() is designed to be called twice if it has to do an | 65 | * xfs_dialloc() is designed to be called twice if it has to do an |
67 | * allocation to make more free inodes. If an inode is | 66 | * allocation to make more free inodes. If an inode is |
68 | * available without an allocation, agbp would be set to the current | 67 | * available without an allocation, agbp would be set to the current |
69 | * agbp and alloc_done set to false. | 68 | * agbp and alloc_done set to false. |
70 | * If an allocation needed to be done, agbp would be set to the | 69 | * If an allocation needed to be done, agbp would be set to the |
71 | * inode header of the allocation group and alloc_done set to true. | 70 | * inode header of the allocation group and alloc_done set to true. |
72 | * The caller should then commit the current transaction and allocate a new | 71 | * The caller should then commit the current transaction and allocate a new |
73 | * transaction. xfs_dialloc() should then be called again with | 72 | * transaction. xfs_dialloc() should then be called again with |
74 | * the agbp value returned from the previous call. | 73 | * the agbp value returned from the previous call. |
75 | * | 74 | * |
76 | * Once we successfully pick an inode its number is returned and the | 75 | * Once we successfully pick an inode its number is returned and the |
77 | * on-disk data structures are updated. The inode itself is not read | 76 | * on-disk data structures are updated. The inode itself is not read |
78 | * in, since doing so would break ordering constraints with xfs_reclaim. | 77 | * in, since doing so would break ordering constraints with xfs_reclaim. |
79 | * | 78 | * |
80 | * *agbp should be set to NULL on the first call, *alloc_done set to FALSE. | 79 | * *agbp should be set to NULL on the first call, *alloc_done set to FALSE. |
81 | */ | 80 | */ |
82 | int /* error */ | 81 | int /* error */ |
83 | xfs_dialloc( | 82 | xfs_dialloc( |
84 | struct xfs_trans *tp, /* transaction pointer */ | 83 | struct xfs_trans *tp, /* transaction pointer */ |
85 | xfs_ino_t parent, /* parent inode (directory) */ | 84 | xfs_ino_t parent, /* parent inode (directory) */ |
86 | mode_t mode, /* mode bits for new inode */ | 85 | mode_t mode, /* mode bits for new inode */ |
87 | int okalloc, /* ok to allocate more space */ | 86 | int okalloc, /* ok to allocate more space */ |
88 | struct xfs_buf **agbp, /* buf for a.g. inode header */ | 87 | struct xfs_buf **agbp, /* buf for a.g. inode header */ |
89 | boolean_t *alloc_done, /* an allocation was done to replenish | 88 | boolean_t *alloc_done, /* an allocation was done to replenish |
90 | the free inodes */ | 89 | the free inodes */ |
91 | xfs_ino_t *inop); /* inode number allocated */ | 90 | xfs_ino_t *inop); /* inode number allocated */ |
92 | 91 | ||
93 | /* | 92 | /* |
94 | * Free disk inode. Carefully avoids touching the incore inode, all | 93 | * Free disk inode. Carefully avoids touching the incore inode, all |
95 | * manipulations incore are the caller's responsibility. | 94 | * manipulations incore are the caller's responsibility. |
96 | * The on-disk inode is not changed by this operation, only the | 95 | * The on-disk inode is not changed by this operation, only the |
97 | * btree (free inode mask) is changed. | 96 | * btree (free inode mask) is changed. |
98 | */ | 97 | */ |
99 | int /* error */ | 98 | int /* error */ |
100 | xfs_difree( | 99 | xfs_difree( |
101 | struct xfs_trans *tp, /* transaction pointer */ | 100 | struct xfs_trans *tp, /* transaction pointer */ |
102 | xfs_ino_t inode, /* inode to be freed */ | 101 | xfs_ino_t inode, /* inode to be freed */ |
103 | struct xfs_bmap_free *flist, /* extents to free */ | 102 | struct xfs_bmap_free *flist, /* extents to free */ |
104 | int *delete, /* set if inode cluster was deleted */ | 103 | int *delete, /* set if inode cluster was deleted */ |
105 | xfs_ino_t *first_ino); /* first inode in deleted cluster */ | 104 | xfs_ino_t *first_ino); /* first inode in deleted cluster */ |
106 | 105 | ||
107 | /* | 106 | /* |
108 | * Return the location of the inode in bno/len/off, | 107 | * Return the location of the inode in bno/len/off, |
109 | * for mapping it into a buffer. | 108 | * for mapping it into a buffer. |
110 | */ | 109 | */ |
111 | int | 110 | int |
112 | xfs_dilocate( | 111 | xfs_dilocate( |
113 | struct xfs_mount *mp, /* file system mount structure */ | 112 | struct xfs_mount *mp, /* file system mount structure */ |
114 | struct xfs_trans *tp, /* transaction pointer */ | 113 | struct xfs_trans *tp, /* transaction pointer */ |
115 | xfs_ino_t ino, /* inode to locate */ | 114 | xfs_ino_t ino, /* inode to locate */ |
116 | xfs_fsblock_t *bno, /* output: block containing inode */ | 115 | xfs_fsblock_t *bno, /* output: block containing inode */ |
117 | int *len, /* output: num blocks in cluster*/ | 116 | int *len, /* output: num blocks in cluster*/ |
118 | int *off, /* output: index in block of inode */ | 117 | int *off, /* output: index in block of inode */ |
119 | uint flags); /* flags for inode btree lookup */ | 118 | uint flags); /* flags for inode btree lookup */ |
120 | 119 | ||
121 | /* | 120 | /* |
122 | * Compute and fill in value of m_in_maxlevels. | 121 | * Compute and fill in value of m_in_maxlevels. |
123 | */ | 122 | */ |
124 | void | 123 | void |
125 | xfs_ialloc_compute_maxlevels( | 124 | xfs_ialloc_compute_maxlevels( |
126 | struct xfs_mount *mp); /* file system mount structure */ | 125 | struct xfs_mount *mp); /* file system mount structure */ |
127 | 126 | ||
128 | /* | 127 | /* |
129 | * Log specified fields for the ag hdr (inode section) | 128 | * Log specified fields for the ag hdr (inode section) |
130 | */ | 129 | */ |
131 | void | 130 | void |
132 | xfs_ialloc_log_agi( | 131 | xfs_ialloc_log_agi( |
133 | struct xfs_trans *tp, /* transaction pointer */ | 132 | struct xfs_trans *tp, /* transaction pointer */ |
134 | struct xfs_buf *bp, /* allocation group header buffer */ | 133 | struct xfs_buf *bp, /* allocation group header buffer */ |
135 | int fields); /* bitmask of fields to log */ | 134 | int fields); /* bitmask of fields to log */ |
136 | 135 | ||
137 | /* | 136 | /* |
138 | * Read in the allocation group header (inode allocation section) | 137 | * Read in the allocation group header (inode allocation section) |
139 | */ | 138 | */ |
140 | int /* error */ | 139 | int /* error */ |
141 | xfs_ialloc_read_agi( | 140 | xfs_ialloc_read_agi( |
142 | struct xfs_mount *mp, /* file system mount structure */ | 141 | struct xfs_mount *mp, /* file system mount structure */ |
143 | struct xfs_trans *tp, /* transaction pointer */ | 142 | struct xfs_trans *tp, /* transaction pointer */ |
144 | xfs_agnumber_t agno, /* allocation group number */ | 143 | xfs_agnumber_t agno, /* allocation group number */ |
145 | struct xfs_buf **bpp); /* allocation group hdr buf */ | 144 | struct xfs_buf **bpp); /* allocation group hdr buf */ |
146 | 145 | ||
147 | /* | 146 | /* |
148 | * Read in the allocation group header to initialise the per-ag data | 147 | * Read in the allocation group header to initialise the per-ag data |
149 | * in the mount structure | 148 | * in the mount structure |
150 | */ | 149 | */ |
151 | int | 150 | int |
152 | xfs_ialloc_pagi_init( | 151 | xfs_ialloc_pagi_init( |
153 | struct xfs_mount *mp, /* file system mount structure */ | 152 | struct xfs_mount *mp, /* file system mount structure */ |
154 | struct xfs_trans *tp, /* transaction pointer */ | 153 | struct xfs_trans *tp, /* transaction pointer */ |
155 | xfs_agnumber_t agno); /* allocation group number */ | 154 | xfs_agnumber_t agno); /* allocation group number */ |
156 | 155 | ||
157 | /* | 156 | /* |
158 | * Lookup the first record greater than or equal to ino | 157 | * Lookup the first record greater than or equal to ino |
159 | * in the btree given by cur. | 158 | * in the btree given by cur. |
160 | */ | 159 | */ |
161 | int xfs_inobt_lookup_ge(struct xfs_btree_cur *cur, xfs_agino_t ino, | 160 | int xfs_inobt_lookup_ge(struct xfs_btree_cur *cur, xfs_agino_t ino, |
162 | __int32_t fcnt, xfs_inofree_t free, int *stat); | 161 | __int32_t fcnt, xfs_inofree_t free, int *stat); |
163 | 162 | ||
164 | /* | 163 | /* |
165 | * Lookup the first record less than or equal to ino | 164 | * Lookup the first record less than or equal to ino |
166 | * in the btree given by cur. | 165 | * in the btree given by cur. |
167 | */ | 166 | */ |
168 | int xfs_inobt_lookup_le(struct xfs_btree_cur *cur, xfs_agino_t ino, | 167 | int xfs_inobt_lookup_le(struct xfs_btree_cur *cur, xfs_agino_t ino, |
169 | __int32_t fcnt, xfs_inofree_t free, int *stat); | 168 | __int32_t fcnt, xfs_inofree_t free, int *stat); |
170 | 169 | ||
171 | /* | 170 | /* |
172 | * Get the data from the pointed-to record. | 171 | * Get the data from the pointed-to record. |
173 | */ | 172 | */ |
174 | extern int xfs_inobt_get_rec(struct xfs_btree_cur *cur, xfs_agino_t *ino, | 173 | extern int xfs_inobt_get_rec(struct xfs_btree_cur *cur, xfs_agino_t *ino, |
175 | __int32_t *fcnt, xfs_inofree_t *free, int *stat); | 174 | __int32_t *fcnt, xfs_inofree_t *free, int *stat); |
176 | |||
177 | #endif /* __KERNEL__ */ | ||
178 | 175 | ||
179 | #endif /* __XFS_IALLOC_H__ */ | 176 | #endif /* __XFS_IALLOC_H__ */ |
180 | 177 |
fs/xfs/xfs_imap.h
1 | /* | 1 | /* |
2 | * Copyright (c) 2000,2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000,2005 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License as | 6 | * modify it under the terms of the GNU General Public License as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | * | 8 | * |
9 | * This program is distributed in the hope that it would be useful, | 9 | * This program is distributed in the hope that it would be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. | 12 | * GNU General Public License for more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License | 14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write the Free Software Foundation, | 15 | * along with this program; if not, write the Free Software Foundation, |
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ | 17 | */ |
18 | #ifndef __XFS_IMAP_H__ | 18 | #ifndef __XFS_IMAP_H__ |
19 | #define __XFS_IMAP_H__ | 19 | #define __XFS_IMAP_H__ |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * This is the structure passed to xfs_imap() to map | 22 | * This is the structure passed to xfs_imap() to map |
23 | * an inode number to its on disk location. | 23 | * an inode number to its on disk location. |
24 | */ | 24 | */ |
25 | typedef struct xfs_imap { | 25 | typedef struct xfs_imap { |
26 | xfs_daddr_t im_blkno; /* starting BB of inode chunk */ | 26 | xfs_daddr_t im_blkno; /* starting BB of inode chunk */ |
27 | uint im_len; /* length in BBs of inode chunk */ | 27 | uint im_len; /* length in BBs of inode chunk */ |
28 | xfs_agblock_t im_agblkno; /* logical block of inode chunk in ag */ | 28 | xfs_agblock_t im_agblkno; /* logical block of inode chunk in ag */ |
29 | ushort im_ioffset; /* inode offset in block in "inodes" */ | 29 | ushort im_ioffset; /* inode offset in block in "inodes" */ |
30 | ushort im_boffset; /* inode offset in block in bytes */ | 30 | ushort im_boffset; /* inode offset in block in bytes */ |
31 | } xfs_imap_t; | 31 | } xfs_imap_t; |
32 | 32 | ||
33 | #ifdef __KERNEL__ | ||
34 | struct xfs_mount; | 33 | struct xfs_mount; |
35 | struct xfs_trans; | 34 | struct xfs_trans; |
36 | int xfs_imap(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, | 35 | int xfs_imap(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, |
37 | xfs_imap_t *, uint); | 36 | xfs_imap_t *, uint); |
38 | #endif | ||
39 | 37 | ||
40 | #endif /* __XFS_IMAP_H__ */ | 38 | #endif /* __XFS_IMAP_H__ */ |
41 | 39 |
fs/xfs/xfs_inode.h
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License as | 6 | * modify it under the terms of the GNU General Public License as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | * | 8 | * |
9 | * This program is distributed in the hope that it would be useful, | 9 | * This program is distributed in the hope that it would be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. | 12 | * GNU General Public License for more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License | 14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write the Free Software Foundation, | 15 | * along with this program; if not, write the Free Software Foundation, |
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ | 17 | */ |
18 | #ifndef __XFS_INODE_H__ | 18 | #ifndef __XFS_INODE_H__ |
19 | #define __XFS_INODE_H__ | 19 | #define __XFS_INODE_H__ |
20 | 20 | ||
21 | struct xfs_dinode; | 21 | struct xfs_dinode; |
22 | struct xfs_dinode_core; | 22 | struct xfs_dinode_core; |
23 | struct xfs_inode; | ||
23 | 24 | ||
24 | |||
25 | /* | 25 | /* |
26 | * Fork identifiers. | 26 | * Fork identifiers. |
27 | */ | 27 | */ |
28 | #define XFS_DATA_FORK 0 | 28 | #define XFS_DATA_FORK 0 |
29 | #define XFS_ATTR_FORK 1 | 29 | #define XFS_ATTR_FORK 1 |
30 | 30 | ||
31 | /* | 31 | /* |
32 | * The following xfs_ext_irec_t struct introduces a second (top) level | 32 | * The following xfs_ext_irec_t struct introduces a second (top) level |
33 | * to the in-core extent allocation scheme. These structs are allocated | 33 | * to the in-core extent allocation scheme. These structs are allocated |
34 | * in a contiguous block, creating an indirection array where each entry | 34 | * in a contiguous block, creating an indirection array where each entry |
35 | * (irec) contains a pointer to a buffer of in-core extent records which | 35 | * (irec) contains a pointer to a buffer of in-core extent records which |
36 | * it manages. Each extent buffer is 4k in size, since 4k is the system | 36 | * it manages. Each extent buffer is 4k in size, since 4k is the system |
37 | * page size on Linux i386 and systems with larger page sizes don't seem | 37 | * page size on Linux i386 and systems with larger page sizes don't seem |
38 | * to gain much, if anything, by using their native page size as the | 38 | * to gain much, if anything, by using their native page size as the |
39 | * extent buffer size. Also, using 4k extent buffers everywhere provides | 39 | * extent buffer size. Also, using 4k extent buffers everywhere provides |
40 | * a consistent interface for CXFS across different platforms. | 40 | * a consistent interface for CXFS across different platforms. |
41 | * | 41 | * |
42 | * There is currently no limit on the number of irec's (extent lists) | 42 | * There is currently no limit on the number of irec's (extent lists) |
43 | * allowed, so heavily fragmented files may require an indirection array | 43 | * allowed, so heavily fragmented files may require an indirection array |
44 | * which spans multiple system pages of memory. The number of extents | 44 | * which spans multiple system pages of memory. The number of extents |
45 | * which would require this amount of contiguous memory is very large | 45 | * which would require this amount of contiguous memory is very large |
46 | * and should not cause problems in the foreseeable future. However, | 46 | * and should not cause problems in the foreseeable future. However, |
47 | * if the memory needed for the contiguous array ever becomes a problem, | 47 | * if the memory needed for the contiguous array ever becomes a problem, |
48 | * it is possible that a third level of indirection may be required. | 48 | * it is possible that a third level of indirection may be required. |
49 | */ | 49 | */ |
50 | typedef struct xfs_ext_irec { | 50 | typedef struct xfs_ext_irec { |
51 | xfs_bmbt_rec_host_t *er_extbuf; /* block of extent records */ | 51 | xfs_bmbt_rec_host_t *er_extbuf; /* block of extent records */ |
52 | xfs_extnum_t er_extoff; /* extent offset in file */ | 52 | xfs_extnum_t er_extoff; /* extent offset in file */ |
53 | xfs_extnum_t er_extcount; /* number of extents in page/block */ | 53 | xfs_extnum_t er_extcount; /* number of extents in page/block */ |
54 | } xfs_ext_irec_t; | 54 | } xfs_ext_irec_t; |
55 | 55 | ||
56 | /* | 56 | /* |
57 | * File incore extent information, present for each of data & attr forks. | 57 | * File incore extent information, present for each of data & attr forks. |
58 | */ | 58 | */ |
59 | #define XFS_IEXT_BUFSZ 4096 | 59 | #define XFS_IEXT_BUFSZ 4096 |
60 | #define XFS_LINEAR_EXTS (XFS_IEXT_BUFSZ / (uint)sizeof(xfs_bmbt_rec_t)) | 60 | #define XFS_LINEAR_EXTS (XFS_IEXT_BUFSZ / (uint)sizeof(xfs_bmbt_rec_t)) |
61 | #define XFS_INLINE_EXTS 2 | 61 | #define XFS_INLINE_EXTS 2 |
62 | #define XFS_INLINE_DATA 32 | 62 | #define XFS_INLINE_DATA 32 |
63 | typedef struct xfs_ifork { | 63 | typedef struct xfs_ifork { |
64 | int if_bytes; /* bytes in if_u1 */ | 64 | int if_bytes; /* bytes in if_u1 */ |
65 | int if_real_bytes; /* bytes allocated in if_u1 */ | 65 | int if_real_bytes; /* bytes allocated in if_u1 */ |
66 | xfs_bmbt_block_t *if_broot; /* file's incore btree root */ | 66 | xfs_bmbt_block_t *if_broot; /* file's incore btree root */ |
67 | short if_broot_bytes; /* bytes allocated for root */ | 67 | short if_broot_bytes; /* bytes allocated for root */ |
68 | unsigned char if_flags; /* per-fork flags */ | 68 | unsigned char if_flags; /* per-fork flags */ |
69 | unsigned char if_ext_max; /* max # of extent records */ | 69 | unsigned char if_ext_max; /* max # of extent records */ |
70 | xfs_extnum_t if_lastex; /* last if_extents used */ | 70 | xfs_extnum_t if_lastex; /* last if_extents used */ |
71 | union { | 71 | union { |
72 | xfs_bmbt_rec_host_t *if_extents;/* linear map file exts */ | 72 | xfs_bmbt_rec_host_t *if_extents;/* linear map file exts */ |
73 | xfs_ext_irec_t *if_ext_irec; /* irec map file exts */ | 73 | xfs_ext_irec_t *if_ext_irec; /* irec map file exts */ |
74 | char *if_data; /* inline file data */ | 74 | char *if_data; /* inline file data */ |
75 | } if_u1; | 75 | } if_u1; |
76 | union { | 76 | union { |
77 | xfs_bmbt_rec_host_t if_inline_ext[XFS_INLINE_EXTS]; | 77 | xfs_bmbt_rec_host_t if_inline_ext[XFS_INLINE_EXTS]; |
78 | /* very small file extents */ | 78 | /* very small file extents */ |
79 | char if_inline_data[XFS_INLINE_DATA]; | 79 | char if_inline_data[XFS_INLINE_DATA]; |
80 | /* very small file data */ | 80 | /* very small file data */ |
81 | xfs_dev_t if_rdev; /* dev number if special */ | 81 | xfs_dev_t if_rdev; /* dev number if special */ |
82 | uuid_t if_uuid; /* mount point value */ | 82 | uuid_t if_uuid; /* mount point value */ |
83 | } if_u2; | 83 | } if_u2; |
84 | } xfs_ifork_t; | 84 | } xfs_ifork_t; |
85 | 85 | ||
86 | /* | 86 | /* |
87 | * Flags for xfs_ichgtime(). | ||
88 | */ | ||
89 | #define XFS_ICHGTIME_MOD 0x1 /* data fork modification timestamp */ | ||
90 | #define XFS_ICHGTIME_CHG 0x2 /* inode field change timestamp */ | ||
91 | |||
92 | /* | ||
93 | * Per-fork incore inode flags. | ||
94 | */ | ||
95 | #define XFS_IFINLINE 0x01 /* Inline data is read in */ | ||
96 | #define XFS_IFEXTENTS 0x02 /* All extent pointers are read in */ | ||
97 | #define XFS_IFBROOT 0x04 /* i_broot points to the bmap b-tree root */ | ||
98 | #define XFS_IFEXTIREC 0x08 /* Indirection array of extent blocks */ | ||
99 | |||
100 | /* | ||
101 | * Flags for xfs_itobp(), xfs_imap() and xfs_dilocate(). | ||
102 | */ | ||
103 | #define XFS_IMAP_LOOKUP 0x1 | ||
104 | #define XFS_IMAP_BULKSTAT 0x2 | ||
105 | |||
106 | #ifdef __KERNEL__ | ||
107 | struct bhv_desc; | ||
108 | struct cred; | ||
109 | struct ktrace; | ||
110 | struct xfs_buf; | ||
111 | struct xfs_bmap_free; | ||
112 | struct xfs_bmbt_irec; | ||
113 | struct xfs_bmbt_block; | ||
114 | struct xfs_inode; | ||
115 | struct xfs_inode_log_item; | ||
116 | struct xfs_mount; | ||
117 | struct xfs_trans; | ||
118 | struct xfs_dquot; | ||
119 | |||
120 | #if defined(XFS_ILOCK_TRACE) | ||
121 | #define XFS_ILOCK_KTRACE_SIZE 32 | ||
122 | extern ktrace_t *xfs_ilock_trace_buf; | ||
123 | extern void xfs_ilock_trace(struct xfs_inode *, int, unsigned int, inst_t *); | ||
124 | #else | ||
125 | #define xfs_ilock_trace(i,n,f,ra) | ||
126 | #endif | ||
127 | |||
128 | typedef struct dm_attrs_s { | ||
129 | __uint32_t da_dmevmask; /* DMIG event mask */ | ||
130 | __uint16_t da_dmstate; /* DMIG state info */ | ||
131 | __uint16_t da_pad; /* DMIG extra padding */ | ||
132 | } dm_attrs_t; | ||
133 | |||
134 | /* | ||
135 | * This is the xfs in-core inode structure. | 87 | * This is the xfs in-core inode structure. |
136 | * Most of the on-disk inode is embedded in the i_d field. | 88 | * Most of the on-disk inode is embedded in the i_d field. |
137 | * | 89 | * |
138 | * The extent pointers/inline file space, however, are managed | 90 | * The extent pointers/inline file space, however, are managed |
139 | * separately. The memory for this information is pointed to by | 91 | * separately. The memory for this information is pointed to by |
140 | * the if_u1 unions depending on the type of the data. | 92 | * the if_u1 unions depending on the type of the data. |
141 | * This is used to linearize the array of extents for fast in-core | 93 | * This is used to linearize the array of extents for fast in-core |
142 | * access. This is used until the file's number of extents | 94 | * access. This is used until the file's number of extents |
143 | * surpasses XFS_MAX_INCORE_EXTENTS, at which point all extent pointers | 95 | * surpasses XFS_MAX_INCORE_EXTENTS, at which point all extent pointers |
144 | * are accessed through the buffer cache. | 96 | * are accessed through the buffer cache. |
145 | * | 97 | * |
146 | * Other state kept in the in-core inode is used for identification, | 98 | * Other state kept in the in-core inode is used for identification, |
147 | * locking, transactional updating, etc of the inode. | 99 | * locking, transactional updating, etc of the inode. |
148 | * | 100 | * |
149 | * Generally, we do not want to hold the i_rlock while holding the | 101 | * Generally, we do not want to hold the i_rlock while holding the |
150 | * i_ilock. Hierarchy is i_iolock followed by i_rlock. | 102 | * i_ilock. Hierarchy is i_iolock followed by i_rlock. |
151 | * | 103 | * |
152 | * xfs_iptr_t contains all the inode fields upto and including the | 104 | * xfs_iptr_t contains all the inode fields upto and including the |
153 | * i_mnext and i_mprev fields, it is used as a marker in the inode | 105 | * i_mnext and i_mprev fields, it is used as a marker in the inode |
154 | * chain off the mount structure by xfs_sync calls. | 106 | * chain off the mount structure by xfs_sync calls. |
155 | */ | 107 | */ |
156 | 108 | ||
157 | typedef struct xfs_ictimestamp { | 109 | typedef struct xfs_ictimestamp { |
158 | __int32_t t_sec; /* timestamp seconds */ | 110 | __int32_t t_sec; /* timestamp seconds */ |
159 | __int32_t t_nsec; /* timestamp nanoseconds */ | 111 | __int32_t t_nsec; /* timestamp nanoseconds */ |
160 | } xfs_ictimestamp_t; | 112 | } xfs_ictimestamp_t; |
161 | 113 | ||
162 | /* | 114 | /* |
163 | * NOTE: This structure must be kept identical to struct xfs_dinode_core | 115 | * NOTE: This structure must be kept identical to struct xfs_dinode_core |
164 | * in xfs_dinode.h except for the endianess annotations. | 116 | * in xfs_dinode.h except for the endianess annotations. |
165 | */ | 117 | */ |
166 | typedef struct xfs_icdinode { | 118 | typedef struct xfs_icdinode { |
167 | __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */ | 119 | __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */ |
168 | __uint16_t di_mode; /* mode and type of file */ | 120 | __uint16_t di_mode; /* mode and type of file */ |
169 | __int8_t di_version; /* inode version */ | 121 | __int8_t di_version; /* inode version */ |
170 | __int8_t di_format; /* format of di_c data */ | 122 | __int8_t di_format; /* format of di_c data */ |
171 | __uint16_t di_onlink; /* old number of links to file */ | 123 | __uint16_t di_onlink; /* old number of links to file */ |
172 | __uint32_t di_uid; /* owner's user id */ | 124 | __uint32_t di_uid; /* owner's user id */ |
173 | __uint32_t di_gid; /* owner's group id */ | 125 | __uint32_t di_gid; /* owner's group id */ |
174 | __uint32_t di_nlink; /* number of links to file */ | 126 | __uint32_t di_nlink; /* number of links to file */ |
175 | __uint16_t di_projid; /* owner's project id */ | 127 | __uint16_t di_projid; /* owner's project id */ |
176 | __uint8_t di_pad[8]; /* unused, zeroed space */ | 128 | __uint8_t di_pad[8]; /* unused, zeroed space */ |
177 | __uint16_t di_flushiter; /* incremented on flush */ | 129 | __uint16_t di_flushiter; /* incremented on flush */ |
178 | xfs_ictimestamp_t di_atime; /* time last accessed */ | 130 | xfs_ictimestamp_t di_atime; /* time last accessed */ |
179 | xfs_ictimestamp_t di_mtime; /* time last modified */ | 131 | xfs_ictimestamp_t di_mtime; /* time last modified */ |
180 | xfs_ictimestamp_t di_ctime; /* time created/inode modified */ | 132 | xfs_ictimestamp_t di_ctime; /* time created/inode modified */ |
181 | xfs_fsize_t di_size; /* number of bytes in file */ | 133 | xfs_fsize_t di_size; /* number of bytes in file */ |
182 | xfs_drfsbno_t di_nblocks; /* # of direct & btree blocks used */ | 134 | xfs_drfsbno_t di_nblocks; /* # of direct & btree blocks used */ |
183 | xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ | 135 | xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ |
184 | xfs_extnum_t di_nextents; /* number of extents in data fork */ | 136 | xfs_extnum_t di_nextents; /* number of extents in data fork */ |
185 | xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/ | 137 | xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/ |
186 | __uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */ | 138 | __uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */ |
187 | __int8_t di_aformat; /* format of attr fork's data */ | 139 | __int8_t di_aformat; /* format of attr fork's data */ |
188 | __uint32_t di_dmevmask; /* DMIG event mask */ | 140 | __uint32_t di_dmevmask; /* DMIG event mask */ |
189 | __uint16_t di_dmstate; /* DMIG state info */ | 141 | __uint16_t di_dmstate; /* DMIG state info */ |
190 | __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */ | 142 | __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */ |
191 | __uint32_t di_gen; /* generation number */ | 143 | __uint32_t di_gen; /* generation number */ |
192 | } xfs_icdinode_t; | 144 | } xfs_icdinode_t; |
193 | 145 | ||
146 | /* | ||
147 | * Flags for xfs_ichgtime(). | ||
148 | */ | ||
149 | #define XFS_ICHGTIME_MOD 0x1 /* data fork modification timestamp */ | ||
150 | #define XFS_ICHGTIME_CHG 0x2 /* inode field change timestamp */ | ||
151 | |||
152 | /* | ||
153 | * Per-fork incore inode flags. | ||
154 | */ | ||
155 | #define XFS_IFINLINE 0x01 /* Inline data is read in */ | ||
156 | #define XFS_IFEXTENTS 0x02 /* All extent pointers are read in */ | ||
157 | #define XFS_IFBROOT 0x04 /* i_broot points to the bmap b-tree root */ | ||
158 | #define XFS_IFEXTIREC 0x08 /* Indirection array of extent blocks */ | ||
159 | |||
160 | /* | ||
161 | * Flags for xfs_itobp(), xfs_imap() and xfs_dilocate(). | ||
162 | */ | ||
163 | #define XFS_IMAP_LOOKUP 0x1 | ||
164 | #define XFS_IMAP_BULKSTAT 0x2 | ||
165 | |||
166 | /* | ||
167 | * Fork handling. | ||
168 | */ | ||
169 | |||
170 | #define XFS_IFORK_Q(ip) ((ip)->i_d.di_forkoff != 0) | ||
171 | #define XFS_IFORK_BOFF(ip) ((int)((ip)->i_d.di_forkoff << 3)) | ||
172 | |||
173 | #define XFS_IFORK_PTR(ip,w) \ | ||
174 | ((w) == XFS_DATA_FORK ? \ | ||
175 | &(ip)->i_df : \ | ||
176 | (ip)->i_afp) | ||
177 | #define XFS_IFORK_DSIZE(ip) \ | ||
178 | (XFS_IFORK_Q(ip) ? \ | ||
179 | XFS_IFORK_BOFF(ip) : \ | ||
180 | XFS_LITINO((ip)->i_mount)) | ||
181 | #define XFS_IFORK_ASIZE(ip) \ | ||
182 | (XFS_IFORK_Q(ip) ? \ | ||
183 | XFS_LITINO((ip)->i_mount) - XFS_IFORK_BOFF(ip) : \ | ||
184 | 0) | ||
185 | #define XFS_IFORK_SIZE(ip,w) \ | ||
186 | ((w) == XFS_DATA_FORK ? \ | ||
187 | XFS_IFORK_DSIZE(ip) : \ | ||
188 | XFS_IFORK_ASIZE(ip)) | ||
189 | #define XFS_IFORK_FORMAT(ip,w) \ | ||
190 | ((w) == XFS_DATA_FORK ? \ | ||
191 | (ip)->i_d.di_format : \ | ||
192 | (ip)->i_d.di_aformat) | ||
193 | #define XFS_IFORK_FMT_SET(ip,w,n) \ | ||
194 | ((w) == XFS_DATA_FORK ? \ | ||
195 | ((ip)->i_d.di_format = (n)) : \ | ||
196 | ((ip)->i_d.di_aformat = (n))) | ||
197 | #define XFS_IFORK_NEXTENTS(ip,w) \ | ||
198 | ((w) == XFS_DATA_FORK ? \ | ||
199 | (ip)->i_d.di_nextents : \ | ||
200 | (ip)->i_d.di_anextents) | ||
201 | #define XFS_IFORK_NEXT_SET(ip,w,n) \ | ||
202 | ((w) == XFS_DATA_FORK ? \ | ||
203 | ((ip)->i_d.di_nextents = (n)) : \ | ||
204 | ((ip)->i_d.di_anextents = (n))) | ||
205 | |||
206 | |||
207 | |||
208 | #ifdef __KERNEL__ | ||
209 | |||
210 | struct bhv_desc; | ||
211 | struct cred; | ||
212 | struct ktrace; | ||
213 | struct xfs_buf; | ||
214 | struct xfs_bmap_free; | ||
215 | struct xfs_bmbt_irec; | ||
216 | struct xfs_bmbt_block; | ||
217 | struct xfs_inode_log_item; | ||
218 | struct xfs_mount; | ||
219 | struct xfs_trans; | ||
220 | struct xfs_dquot; | ||
221 | |||
222 | #if defined(XFS_ILOCK_TRACE) | ||
223 | #define XFS_ILOCK_KTRACE_SIZE 32 | ||
224 | extern ktrace_t *xfs_ilock_trace_buf; | ||
225 | extern void xfs_ilock_trace(struct xfs_inode *, int, unsigned int, inst_t *); | ||
226 | #else | ||
227 | #define xfs_ilock_trace(i,n,f,ra) | ||
228 | #endif | ||
229 | |||
230 | typedef struct dm_attrs_s { | ||
231 | __uint32_t da_dmevmask; /* DMIG event mask */ | ||
232 | __uint16_t da_dmstate; /* DMIG state info */ | ||
233 | __uint16_t da_pad; /* DMIG extra padding */ | ||
234 | } dm_attrs_t; | ||
235 | |||
194 | typedef struct { | 236 | typedef struct { |
195 | struct xfs_inode *ip_mnext; /* next inode in mount list */ | 237 | struct xfs_inode *ip_mnext; /* next inode in mount list */ |
196 | struct xfs_inode *ip_mprev; /* ptr to prev inode */ | 238 | struct xfs_inode *ip_mprev; /* ptr to prev inode */ |
197 | struct xfs_mount *ip_mount; /* fs mount struct ptr */ | 239 | struct xfs_mount *ip_mount; /* fs mount struct ptr */ |
198 | } xfs_iptr_t; | 240 | } xfs_iptr_t; |
199 | 241 | ||
200 | typedef struct xfs_inode { | 242 | typedef struct xfs_inode { |
201 | /* Inode linking and identification information. */ | 243 | /* Inode linking and identification information. */ |
202 | struct xfs_inode *i_mnext; /* next inode in mount list */ | 244 | struct xfs_inode *i_mnext; /* next inode in mount list */ |
203 | struct xfs_inode *i_mprev; /* ptr to prev inode */ | 245 | struct xfs_inode *i_mprev; /* ptr to prev inode */ |
204 | struct xfs_mount *i_mount; /* fs mount struct ptr */ | 246 | struct xfs_mount *i_mount; /* fs mount struct ptr */ |
205 | struct list_head i_reclaim; /* reclaim list */ | 247 | struct list_head i_reclaim; /* reclaim list */ |
206 | struct inode *i_vnode; /* vnode backpointer */ | 248 | struct inode *i_vnode; /* vnode backpointer */ |
207 | struct xfs_dquot *i_udquot; /* user dquot */ | 249 | struct xfs_dquot *i_udquot; /* user dquot */ |
208 | struct xfs_dquot *i_gdquot; /* group dquot */ | 250 | struct xfs_dquot *i_gdquot; /* group dquot */ |
209 | 251 | ||
210 | /* Inode location stuff */ | 252 | /* Inode location stuff */ |
211 | xfs_ino_t i_ino; /* inode number (agno/agino)*/ | 253 | xfs_ino_t i_ino; /* inode number (agno/agino)*/ |
212 | xfs_daddr_t i_blkno; /* blkno of inode buffer */ | 254 | xfs_daddr_t i_blkno; /* blkno of inode buffer */ |
213 | ushort i_len; /* len of inode buffer */ | 255 | ushort i_len; /* len of inode buffer */ |
214 | ushort i_boffset; /* off of inode in buffer */ | 256 | ushort i_boffset; /* off of inode in buffer */ |
215 | 257 | ||
216 | /* Extent information. */ | 258 | /* Extent information. */ |
217 | xfs_ifork_t *i_afp; /* attribute fork pointer */ | 259 | xfs_ifork_t *i_afp; /* attribute fork pointer */ |
218 | xfs_ifork_t i_df; /* data fork */ | 260 | xfs_ifork_t i_df; /* data fork */ |
219 | 261 | ||
220 | /* Transaction and locking information. */ | 262 | /* Transaction and locking information. */ |
221 | struct xfs_trans *i_transp; /* ptr to owning transaction*/ | 263 | struct xfs_trans *i_transp; /* ptr to owning transaction*/ |
222 | struct xfs_inode_log_item *i_itemp; /* logging information */ | 264 | struct xfs_inode_log_item *i_itemp; /* logging information */ |
223 | mrlock_t i_lock; /* inode lock */ | 265 | mrlock_t i_lock; /* inode lock */ |
224 | mrlock_t i_iolock; /* inode IO lock */ | 266 | mrlock_t i_iolock; /* inode IO lock */ |
225 | struct completion i_flush; /* inode flush completion q */ | 267 | struct completion i_flush; /* inode flush completion q */ |
226 | atomic_t i_pincount; /* inode pin count */ | 268 | atomic_t i_pincount; /* inode pin count */ |
227 | wait_queue_head_t i_ipin_wait; /* inode pinning wait queue */ | 269 | wait_queue_head_t i_ipin_wait; /* inode pinning wait queue */ |
228 | spinlock_t i_flags_lock; /* inode i_flags lock */ | 270 | spinlock_t i_flags_lock; /* inode i_flags lock */ |
229 | /* Miscellaneous state. */ | 271 | /* Miscellaneous state. */ |
230 | unsigned short i_flags; /* see defined flags below */ | 272 | unsigned short i_flags; /* see defined flags below */ |
231 | unsigned char i_update_core; /* timestamps/size is dirty */ | 273 | unsigned char i_update_core; /* timestamps/size is dirty */ |
232 | unsigned char i_update_size; /* di_size field is dirty */ | 274 | unsigned char i_update_size; /* di_size field is dirty */ |
233 | unsigned int i_gen; /* generation count */ | 275 | unsigned int i_gen; /* generation count */ |
234 | unsigned int i_delayed_blks; /* count of delay alloc blks */ | 276 | unsigned int i_delayed_blks; /* count of delay alloc blks */ |
235 | 277 | ||
236 | xfs_icdinode_t i_d; /* most of ondisk inode */ | 278 | xfs_icdinode_t i_d; /* most of ondisk inode */ |
237 | 279 | ||
238 | xfs_fsize_t i_size; /* in-memory size */ | 280 | xfs_fsize_t i_size; /* in-memory size */ |
239 | xfs_fsize_t i_new_size; /* size when write completes */ | 281 | xfs_fsize_t i_new_size; /* size when write completes */ |
240 | atomic_t i_iocount; /* outstanding I/O count */ | 282 | atomic_t i_iocount; /* outstanding I/O count */ |
241 | /* Trace buffers per inode. */ | 283 | /* Trace buffers per inode. */ |
242 | #ifdef XFS_INODE_TRACE | 284 | #ifdef XFS_INODE_TRACE |
243 | struct ktrace *i_trace; /* general inode trace */ | 285 | struct ktrace *i_trace; /* general inode trace */ |
244 | #endif | 286 | #endif |
245 | #ifdef XFS_BMAP_TRACE | 287 | #ifdef XFS_BMAP_TRACE |
246 | struct ktrace *i_xtrace; /* inode extent list trace */ | 288 | struct ktrace *i_xtrace; /* inode extent list trace */ |
247 | #endif | 289 | #endif |
248 | #ifdef XFS_BTREE_TRACE | 290 | #ifdef XFS_BTREE_TRACE |
249 | struct ktrace *i_btrace; /* inode bmap btree trace */ | 291 | struct ktrace *i_btrace; /* inode bmap btree trace */ |
250 | #endif | 292 | #endif |
251 | #ifdef XFS_RW_TRACE | 293 | #ifdef XFS_RW_TRACE |
252 | struct ktrace *i_rwtrace; /* inode read/write trace */ | 294 | struct ktrace *i_rwtrace; /* inode read/write trace */ |
253 | #endif | 295 | #endif |
254 | #ifdef XFS_ILOCK_TRACE | 296 | #ifdef XFS_ILOCK_TRACE |
255 | struct ktrace *i_lock_trace; /* inode lock/unlock trace */ | 297 | struct ktrace *i_lock_trace; /* inode lock/unlock trace */ |
256 | #endif | 298 | #endif |
257 | #ifdef XFS_DIR2_TRACE | 299 | #ifdef XFS_DIR2_TRACE |
258 | struct ktrace *i_dir_trace; /* inode directory trace */ | 300 | struct ktrace *i_dir_trace; /* inode directory trace */ |
259 | #endif | 301 | #endif |
260 | } xfs_inode_t; | 302 | } xfs_inode_t; |
261 | 303 | ||
262 | #define XFS_ISIZE(ip) (((ip)->i_d.di_mode & S_IFMT) == S_IFREG) ? \ | 304 | #define XFS_ISIZE(ip) (((ip)->i_d.di_mode & S_IFMT) == S_IFREG) ? \ |
263 | (ip)->i_size : (ip)->i_d.di_size; | 305 | (ip)->i_size : (ip)->i_d.di_size; |
264 | 306 | ||
265 | /* Convert from vfs inode to xfs inode */ | 307 | /* Convert from vfs inode to xfs inode */ |
266 | static inline struct xfs_inode *XFS_I(struct inode *inode) | 308 | static inline struct xfs_inode *XFS_I(struct inode *inode) |
267 | { | 309 | { |
268 | return (struct xfs_inode *)inode->i_private; | 310 | return (struct xfs_inode *)inode->i_private; |
269 | } | 311 | } |
270 | 312 | ||
271 | /* convert from xfs inode to vfs inode */ | 313 | /* convert from xfs inode to vfs inode */ |
272 | static inline struct inode *VFS_I(struct xfs_inode *ip) | 314 | static inline struct inode *VFS_I(struct xfs_inode *ip) |
273 | { | 315 | { |
274 | return (struct inode *)ip->i_vnode; | 316 | return (struct inode *)ip->i_vnode; |
275 | } | 317 | } |
276 | 318 | ||
277 | /* | 319 | /* |
278 | * i_flags helper functions | 320 | * i_flags helper functions |
279 | */ | 321 | */ |
280 | static inline void | 322 | static inline void |
281 | __xfs_iflags_set(xfs_inode_t *ip, unsigned short flags) | 323 | __xfs_iflags_set(xfs_inode_t *ip, unsigned short flags) |
282 | { | 324 | { |
283 | ip->i_flags |= flags; | 325 | ip->i_flags |= flags; |
284 | } | 326 | } |
285 | 327 | ||
286 | static inline void | 328 | static inline void |
287 | xfs_iflags_set(xfs_inode_t *ip, unsigned short flags) | 329 | xfs_iflags_set(xfs_inode_t *ip, unsigned short flags) |
288 | { | 330 | { |
289 | spin_lock(&ip->i_flags_lock); | 331 | spin_lock(&ip->i_flags_lock); |
290 | __xfs_iflags_set(ip, flags); | 332 | __xfs_iflags_set(ip, flags); |
291 | spin_unlock(&ip->i_flags_lock); | 333 | spin_unlock(&ip->i_flags_lock); |
292 | } | 334 | } |
293 | 335 | ||
294 | static inline void | 336 | static inline void |
295 | xfs_iflags_clear(xfs_inode_t *ip, unsigned short flags) | 337 | xfs_iflags_clear(xfs_inode_t *ip, unsigned short flags) |
296 | { | 338 | { |
297 | spin_lock(&ip->i_flags_lock); | 339 | spin_lock(&ip->i_flags_lock); |
298 | ip->i_flags &= ~flags; | 340 | ip->i_flags &= ~flags; |
299 | spin_unlock(&ip->i_flags_lock); | 341 | spin_unlock(&ip->i_flags_lock); |
300 | } | 342 | } |
301 | 343 | ||
302 | static inline int | 344 | static inline int |
303 | __xfs_iflags_test(xfs_inode_t *ip, unsigned short flags) | 345 | __xfs_iflags_test(xfs_inode_t *ip, unsigned short flags) |
304 | { | 346 | { |
305 | return (ip->i_flags & flags); | 347 | return (ip->i_flags & flags); |
306 | } | 348 | } |
307 | 349 | ||
308 | static inline int | 350 | static inline int |
309 | xfs_iflags_test(xfs_inode_t *ip, unsigned short flags) | 351 | xfs_iflags_test(xfs_inode_t *ip, unsigned short flags) |
310 | { | 352 | { |
311 | int ret; | 353 | int ret; |
312 | spin_lock(&ip->i_flags_lock); | 354 | spin_lock(&ip->i_flags_lock); |
313 | ret = __xfs_iflags_test(ip, flags); | 355 | ret = __xfs_iflags_test(ip, flags); |
314 | spin_unlock(&ip->i_flags_lock); | 356 | spin_unlock(&ip->i_flags_lock); |
315 | return ret; | 357 | return ret; |
316 | } | 358 | } |
317 | 359 | ||
318 | static inline int | 360 | static inline int |
319 | xfs_iflags_test_and_clear(xfs_inode_t *ip, unsigned short flags) | 361 | xfs_iflags_test_and_clear(xfs_inode_t *ip, unsigned short flags) |
320 | { | 362 | { |
321 | int ret; | 363 | int ret; |
322 | 364 | ||
323 | spin_lock(&ip->i_flags_lock); | 365 | spin_lock(&ip->i_flags_lock); |
324 | ret = ip->i_flags & flags; | 366 | ret = ip->i_flags & flags; |
325 | if (ret) | 367 | if (ret) |
326 | ip->i_flags &= ~flags; | 368 | ip->i_flags &= ~flags; |
327 | spin_unlock(&ip->i_flags_lock); | 369 | spin_unlock(&ip->i_flags_lock); |
328 | return ret; | 370 | return ret; |
329 | } | 371 | } |
330 | #endif /* __KERNEL__ */ | ||
331 | 372 | ||
332 | |||
333 | /* | 373 | /* |
334 | * Fork handling. | 374 | * Manage the i_flush queue embedded in the inode. This completion |
375 | * queue synchronizes processes attempting to flush the in-core | ||
376 | * inode back to disk. | ||
335 | */ | 377 | */ |
378 | static inline void xfs_iflock(xfs_inode_t *ip) | ||
379 | { | ||
380 | wait_for_completion(&ip->i_flush); | ||
381 | } | ||
336 | 382 | ||
337 | #define XFS_IFORK_Q(ip) ((ip)->i_d.di_forkoff != 0) | 383 | static inline int xfs_iflock_nowait(xfs_inode_t *ip) |
338 | #define XFS_IFORK_BOFF(ip) ((int)((ip)->i_d.di_forkoff << 3)) | 384 | { |
385 | return try_wait_for_completion(&ip->i_flush); | ||
386 | } | ||
339 | 387 | ||
340 | #define XFS_IFORK_PTR(ip,w) \ | 388 | static inline void xfs_ifunlock(xfs_inode_t *ip) |
341 | ((w) == XFS_DATA_FORK ? \ | 389 | { |
342 | &(ip)->i_df : \ | 390 | complete(&ip->i_flush); |
343 | (ip)->i_afp) | 391 | } |
344 | #define XFS_IFORK_DSIZE(ip) \ | ||
345 | (XFS_IFORK_Q(ip) ? \ | ||
346 | XFS_IFORK_BOFF(ip) : \ | ||
347 | XFS_LITINO((ip)->i_mount)) | ||
348 | #define XFS_IFORK_ASIZE(ip) \ | ||
349 | (XFS_IFORK_Q(ip) ? \ | ||
350 | XFS_LITINO((ip)->i_mount) - XFS_IFORK_BOFF(ip) : \ | ||
351 | 0) | ||
352 | #define XFS_IFORK_SIZE(ip,w) \ | ||
353 | ((w) == XFS_DATA_FORK ? \ | ||
354 | XFS_IFORK_DSIZE(ip) : \ | ||
355 | XFS_IFORK_ASIZE(ip)) | ||
356 | #define XFS_IFORK_FORMAT(ip,w) \ | ||
357 | ((w) == XFS_DATA_FORK ? \ | ||
358 | (ip)->i_d.di_format : \ | ||
359 | (ip)->i_d.di_aformat) | ||
360 | #define XFS_IFORK_FMT_SET(ip,w,n) \ | ||
361 | ((w) == XFS_DATA_FORK ? \ | ||
362 | ((ip)->i_d.di_format = (n)) : \ | ||
363 | ((ip)->i_d.di_aformat = (n))) | ||
364 | #define XFS_IFORK_NEXTENTS(ip,w) \ | ||
365 | ((w) == XFS_DATA_FORK ? \ | ||
366 | (ip)->i_d.di_nextents : \ | ||
367 | (ip)->i_d.di_anextents) | ||
368 | #define XFS_IFORK_NEXT_SET(ip,w,n) \ | ||
369 | ((w) == XFS_DATA_FORK ? \ | ||
370 | ((ip)->i_d.di_nextents = (n)) : \ | ||
371 | ((ip)->i_d.di_anextents = (n))) | ||
372 | 392 | ||
373 | #ifdef __KERNEL__ | ||
374 | |||
375 | /* | 393 | /* |
376 | * In-core inode flags. | 394 | * In-core inode flags. |
377 | */ | 395 | */ |
378 | #define XFS_IGRIO 0x0001 /* inode used for guaranteed rate i/o */ | 396 | #define XFS_IGRIO 0x0001 /* inode used for guaranteed rate i/o */ |
379 | #define XFS_IUIOSZ 0x0002 /* inode i/o sizes have been explicitly set */ | 397 | #define XFS_IUIOSZ 0x0002 /* inode i/o sizes have been explicitly set */ |
380 | #define XFS_IQUIESCE 0x0004 /* we have started quiescing for this inode */ | 398 | #define XFS_IQUIESCE 0x0004 /* we have started quiescing for this inode */ |
381 | #define XFS_IRECLAIM 0x0008 /* we have started reclaiming this inode */ | 399 | #define XFS_IRECLAIM 0x0008 /* we have started reclaiming this inode */ |
382 | #define XFS_ISTALE 0x0010 /* inode has been staled */ | 400 | #define XFS_ISTALE 0x0010 /* inode has been staled */ |
383 | #define XFS_IRECLAIMABLE 0x0020 /* inode can be reclaimed */ | 401 | #define XFS_IRECLAIMABLE 0x0020 /* inode can be reclaimed */ |
384 | #define XFS_INEW 0x0040 | 402 | #define XFS_INEW 0x0040 |
385 | #define XFS_IFILESTREAM 0x0080 /* inode is in a filestream directory */ | 403 | #define XFS_IFILESTREAM 0x0080 /* inode is in a filestream directory */ |
386 | #define XFS_IMODIFIED 0x0100 /* XFS inode state possibly differs */ | 404 | #define XFS_IMODIFIED 0x0100 /* XFS inode state possibly differs */ |
387 | /* to the Linux inode state. */ | 405 | /* to the Linux inode state. */ |
388 | #define XFS_ITRUNCATED 0x0200 /* truncated down so flush-on-close */ | 406 | #define XFS_ITRUNCATED 0x0200 /* truncated down so flush-on-close */ |
389 | 407 | ||
390 | /* | 408 | /* |
391 | * Flags for inode locking. | 409 | * Flags for inode locking. |
392 | * Bit ranges: 1<<1 - 1<<16-1 -- iolock/ilock modes (bitfield) | 410 | * Bit ranges: 1<<1 - 1<<16-1 -- iolock/ilock modes (bitfield) |
393 | * 1<<16 - 1<<32-1 -- lockdep annotation (integers) | 411 | * 1<<16 - 1<<32-1 -- lockdep annotation (integers) |
394 | */ | 412 | */ |
395 | #define XFS_IOLOCK_EXCL (1<<0) | 413 | #define XFS_IOLOCK_EXCL (1<<0) |
396 | #define XFS_IOLOCK_SHARED (1<<1) | 414 | #define XFS_IOLOCK_SHARED (1<<1) |
397 | #define XFS_ILOCK_EXCL (1<<2) | 415 | #define XFS_ILOCK_EXCL (1<<2) |
398 | #define XFS_ILOCK_SHARED (1<<3) | 416 | #define XFS_ILOCK_SHARED (1<<3) |
399 | #define XFS_IUNLOCK_NONOTIFY (1<<4) | 417 | #define XFS_IUNLOCK_NONOTIFY (1<<4) |
400 | 418 | ||
401 | #define XFS_LOCK_MASK (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED \ | 419 | #define XFS_LOCK_MASK (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED \ |
402 | | XFS_ILOCK_EXCL | XFS_ILOCK_SHARED) | 420 | | XFS_ILOCK_EXCL | XFS_ILOCK_SHARED) |
403 | 421 | ||
404 | /* | 422 | /* |
405 | * Flags for lockdep annotations. | 423 | * Flags for lockdep annotations. |
406 | * | 424 | * |
407 | * XFS_I[O]LOCK_PARENT - for operations that require locking two inodes | 425 | * XFS_I[O]LOCK_PARENT - for operations that require locking two inodes |
408 | * (ie directory operations that require locking a directory inode and | 426 | * (ie directory operations that require locking a directory inode and |
409 | * an entry inode). The first inode gets locked with this flag so it | 427 | * an entry inode). The first inode gets locked with this flag so it |
410 | * gets a lockdep subclass of 1 and the second lock will have a lockdep | 428 | * gets a lockdep subclass of 1 and the second lock will have a lockdep |
411 | * subclass of 0. | 429 | * subclass of 0. |
412 | * | 430 | * |
413 | * XFS_LOCK_INUMORDER - for locking several inodes at the some time | 431 | * XFS_LOCK_INUMORDER - for locking several inodes at the some time |
414 | * with xfs_lock_inodes(). This flag is used as the starting subclass | 432 | * with xfs_lock_inodes(). This flag is used as the starting subclass |
415 | * and each subsequent lock acquired will increment the subclass by one. | 433 | * and each subsequent lock acquired will increment the subclass by one. |
416 | * So the first lock acquired will have a lockdep subclass of 2, the | 434 | * So the first lock acquired will have a lockdep subclass of 2, the |
417 | * second lock will have a lockdep subclass of 3, and so on. It is | 435 | * second lock will have a lockdep subclass of 3, and so on. It is |
418 | * the responsibility of the class builder to shift this to the correct | 436 | * the responsibility of the class builder to shift this to the correct |
419 | * portion of the lock_mode lockdep mask. | 437 | * portion of the lock_mode lockdep mask. |
420 | */ | 438 | */ |
421 | #define XFS_LOCK_PARENT 1 | 439 | #define XFS_LOCK_PARENT 1 |
422 | #define XFS_LOCK_INUMORDER 2 | 440 | #define XFS_LOCK_INUMORDER 2 |
423 | 441 | ||
424 | #define XFS_IOLOCK_SHIFT 16 | 442 | #define XFS_IOLOCK_SHIFT 16 |
425 | #define XFS_IOLOCK_PARENT (XFS_LOCK_PARENT << XFS_IOLOCK_SHIFT) | 443 | #define XFS_IOLOCK_PARENT (XFS_LOCK_PARENT << XFS_IOLOCK_SHIFT) |
426 | 444 | ||
427 | #define XFS_ILOCK_SHIFT 24 | 445 | #define XFS_ILOCK_SHIFT 24 |
428 | #define XFS_ILOCK_PARENT (XFS_LOCK_PARENT << XFS_ILOCK_SHIFT) | 446 | #define XFS_ILOCK_PARENT (XFS_LOCK_PARENT << XFS_ILOCK_SHIFT) |
429 | 447 | ||
430 | #define XFS_IOLOCK_DEP_MASK 0x00ff0000 | 448 | #define XFS_IOLOCK_DEP_MASK 0x00ff0000 |
431 | #define XFS_ILOCK_DEP_MASK 0xff000000 | 449 | #define XFS_ILOCK_DEP_MASK 0xff000000 |
432 | #define XFS_LOCK_DEP_MASK (XFS_IOLOCK_DEP_MASK | XFS_ILOCK_DEP_MASK) | 450 | #define XFS_LOCK_DEP_MASK (XFS_IOLOCK_DEP_MASK | XFS_ILOCK_DEP_MASK) |
433 | 451 | ||
434 | #define XFS_IOLOCK_DEP(flags) (((flags) & XFS_IOLOCK_DEP_MASK) >> XFS_IOLOCK_SHIFT) | 452 | #define XFS_IOLOCK_DEP(flags) (((flags) & XFS_IOLOCK_DEP_MASK) >> XFS_IOLOCK_SHIFT) |
435 | #define XFS_ILOCK_DEP(flags) (((flags) & XFS_ILOCK_DEP_MASK) >> XFS_ILOCK_SHIFT) | 453 | #define XFS_ILOCK_DEP(flags) (((flags) & XFS_ILOCK_DEP_MASK) >> XFS_ILOCK_SHIFT) |
436 | 454 | ||
437 | /* | 455 | /* |
438 | * Flags for xfs_iflush() | 456 | * Flags for xfs_iflush() |
439 | */ | 457 | */ |
440 | #define XFS_IFLUSH_DELWRI_ELSE_SYNC 1 | 458 | #define XFS_IFLUSH_DELWRI_ELSE_SYNC 1 |
441 | #define XFS_IFLUSH_DELWRI_ELSE_ASYNC 2 | 459 | #define XFS_IFLUSH_DELWRI_ELSE_ASYNC 2 |
442 | #define XFS_IFLUSH_SYNC 3 | 460 | #define XFS_IFLUSH_SYNC 3 |
443 | #define XFS_IFLUSH_ASYNC 4 | 461 | #define XFS_IFLUSH_ASYNC 4 |
444 | #define XFS_IFLUSH_DELWRI 5 | 462 | #define XFS_IFLUSH_DELWRI 5 |
445 | #define XFS_IFLUSH_ASYNC_NOBLOCK 6 | 463 | #define XFS_IFLUSH_ASYNC_NOBLOCK 6 |
446 | 464 | ||
447 | /* | 465 | /* |
448 | * Flags for xfs_itruncate_start(). | 466 | * Flags for xfs_itruncate_start(). |
449 | */ | 467 | */ |
450 | #define XFS_ITRUNC_DEFINITE 0x1 | 468 | #define XFS_ITRUNC_DEFINITE 0x1 |
451 | #define XFS_ITRUNC_MAYBE 0x2 | 469 | #define XFS_ITRUNC_MAYBE 0x2 |
452 | 470 | ||
453 | /* | 471 | /* |
454 | * For multiple groups support: if S_ISGID bit is set in the parent | 472 | * For multiple groups support: if S_ISGID bit is set in the parent |
455 | * directory, group of new file is set to that of the parent, and | 473 | * directory, group of new file is set to that of the parent, and |
456 | * new subdirectory gets S_ISGID bit from parent. | 474 | * new subdirectory gets S_ISGID bit from parent. |
457 | */ | 475 | */ |
458 | #define XFS_INHERIT_GID(pip) \ | 476 | #define XFS_INHERIT_GID(pip) \ |
459 | (((pip)->i_mount->m_flags & XFS_MOUNT_GRPID) || \ | 477 | (((pip)->i_mount->m_flags & XFS_MOUNT_GRPID) || \ |
460 | ((pip)->i_d.di_mode & S_ISGID)) | 478 | ((pip)->i_d.di_mode & S_ISGID)) |
461 | 479 | ||
462 | /* | 480 | /* |
463 | * Flags for xfs_iget() | 481 | * Flags for xfs_iget() |
464 | */ | 482 | */ |
465 | #define XFS_IGET_CREATE 0x1 | 483 | #define XFS_IGET_CREATE 0x1 |
466 | #define XFS_IGET_BULKSTAT 0x2 | 484 | #define XFS_IGET_BULKSTAT 0x2 |
467 | 485 | ||
468 | /* | 486 | /* |
469 | * xfs_iget.c prototypes. | 487 | * xfs_iget.c prototypes. |
470 | */ | 488 | */ |
471 | void xfs_ihash_init(struct xfs_mount *); | 489 | void xfs_ihash_init(struct xfs_mount *); |
472 | void xfs_ihash_free(struct xfs_mount *); | 490 | void xfs_ihash_free(struct xfs_mount *); |
473 | xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t, | 491 | xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t, |
474 | struct xfs_trans *); | 492 | struct xfs_trans *); |
475 | int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, | 493 | int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, |
476 | uint, uint, xfs_inode_t **, xfs_daddr_t); | 494 | uint, uint, xfs_inode_t **, xfs_daddr_t); |
477 | void xfs_iput(xfs_inode_t *, uint); | 495 | void xfs_iput(xfs_inode_t *, uint); |
478 | void xfs_iput_new(xfs_inode_t *, uint); | 496 | void xfs_iput_new(xfs_inode_t *, uint); |
479 | void xfs_ilock(xfs_inode_t *, uint); | 497 | void xfs_ilock(xfs_inode_t *, uint); |
480 | int xfs_ilock_nowait(xfs_inode_t *, uint); | 498 | int xfs_ilock_nowait(xfs_inode_t *, uint); |
481 | void xfs_iunlock(xfs_inode_t *, uint); | 499 | void xfs_iunlock(xfs_inode_t *, uint); |
482 | void xfs_ilock_demote(xfs_inode_t *, uint); | 500 | void xfs_ilock_demote(xfs_inode_t *, uint); |
483 | int xfs_isilocked(xfs_inode_t *, uint); | 501 | int xfs_isilocked(xfs_inode_t *, uint); |
484 | uint xfs_ilock_map_shared(xfs_inode_t *); | 502 | uint xfs_ilock_map_shared(xfs_inode_t *); |
485 | void xfs_iunlock_map_shared(xfs_inode_t *, uint); | 503 | void xfs_iunlock_map_shared(xfs_inode_t *, uint); |
486 | void xfs_ireclaim(xfs_inode_t *); | 504 | void xfs_ireclaim(xfs_inode_t *); |
487 | int xfs_finish_reclaim(xfs_inode_t *, int, int); | 505 | int xfs_finish_reclaim(xfs_inode_t *, int, int); |
488 | int xfs_finish_reclaim_all(struct xfs_mount *, int); | 506 | int xfs_finish_reclaim_all(struct xfs_mount *, int); |
489 | 507 | ||
490 | /* | 508 | /* |
491 | * xfs_inode.c prototypes. | 509 | * xfs_inode.c prototypes. |
492 | */ | 510 | */ |
493 | int xfs_itobp(struct xfs_mount *, struct xfs_trans *, | ||
494 | xfs_inode_t *, struct xfs_dinode **, struct xfs_buf **, | ||
495 | xfs_daddr_t, uint, uint); | ||
496 | int xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, | 511 | int xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, |
497 | xfs_inode_t **, xfs_daddr_t, uint); | 512 | xfs_inode_t **, xfs_daddr_t, uint); |
498 | int xfs_iread_extents(struct xfs_trans *, xfs_inode_t *, int); | ||
499 | int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, | 513 | int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, |
500 | xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t, | 514 | xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t, |
501 | int, struct xfs_buf **, boolean_t *, xfs_inode_t **); | 515 | int, struct xfs_buf **, boolean_t *, xfs_inode_t **); |
502 | void xfs_dinode_from_disk(struct xfs_icdinode *, | ||
503 | struct xfs_dinode_core *); | ||
504 | void xfs_dinode_to_disk(struct xfs_dinode_core *, |
fs/xfs/xfs_inode_item.h
1 | /* | 1 | /* |
2 | * Copyright (c) 2000,2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000,2005 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License as | 6 | * modify it under the terms of the GNU General Public License as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | * | 8 | * |
9 | * This program is distributed in the hope that it would be useful, | 9 | * This program is distributed in the hope that it would be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. | 12 | * GNU General Public License for more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License | 14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write the Free Software Foundation, | 15 | * along with this program; if not, write the Free Software Foundation, |
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ | 17 | */ |
18 | #ifndef __XFS_INODE_ITEM_H__ | 18 | #ifndef __XFS_INODE_ITEM_H__ |
19 | #define __XFS_INODE_ITEM_H__ | 19 | #define __XFS_INODE_ITEM_H__ |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * This is the structure used to lay out an inode log item in the | 22 | * This is the structure used to lay out an inode log item in the |
23 | * log. The size of the inline data/extents/b-tree root to be logged | 23 | * log. The size of the inline data/extents/b-tree root to be logged |
24 | * (if any) is indicated in the ilf_dsize field. Changes to this structure | 24 | * (if any) is indicated in the ilf_dsize field. Changes to this structure |
25 | * must be added on to the end. | 25 | * must be added on to the end. |
26 | */ | 26 | */ |
27 | typedef struct xfs_inode_log_format { | 27 | typedef struct xfs_inode_log_format { |
28 | __uint16_t ilf_type; /* inode log item type */ | 28 | __uint16_t ilf_type; /* inode log item type */ |
29 | __uint16_t ilf_size; /* size of this item */ | 29 | __uint16_t ilf_size; /* size of this item */ |
30 | __uint32_t ilf_fields; /* flags for fields logged */ | 30 | __uint32_t ilf_fields; /* flags for fields logged */ |
31 | __uint16_t ilf_asize; /* size of attr d/ext/root */ | 31 | __uint16_t ilf_asize; /* size of attr d/ext/root */ |
32 | __uint16_t ilf_dsize; /* size of data/ext/root */ | 32 | __uint16_t ilf_dsize; /* size of data/ext/root */ |
33 | __uint64_t ilf_ino; /* inode number */ | 33 | __uint64_t ilf_ino; /* inode number */ |
34 | union { | 34 | union { |
35 | __uint32_t ilfu_rdev; /* rdev value for dev inode*/ | 35 | __uint32_t ilfu_rdev; /* rdev value for dev inode*/ |
36 | uuid_t ilfu_uuid; /* mount point value */ | 36 | uuid_t ilfu_uuid; /* mount point value */ |
37 | } ilf_u; | 37 | } ilf_u; |
38 | __int64_t ilf_blkno; /* blkno of inode buffer */ | 38 | __int64_t ilf_blkno; /* blkno of inode buffer */ |
39 | __int32_t ilf_len; /* len of inode buffer */ | 39 | __int32_t ilf_len; /* len of inode buffer */ |
40 | __int32_t ilf_boffset; /* off of inode in buffer */ | 40 | __int32_t ilf_boffset; /* off of inode in buffer */ |
41 | } xfs_inode_log_format_t; | 41 | } xfs_inode_log_format_t; |
42 | 42 | ||
43 | #ifndef HAVE_FORMAT32 | 43 | #ifndef HAVE_FORMAT32 |
44 | typedef struct xfs_inode_log_format_32 { | 44 | typedef struct xfs_inode_log_format_32 { |
45 | __uint16_t ilf_type; /* inode log item type */ | 45 | __uint16_t ilf_type; /* inode log item type */ |
46 | __uint16_t ilf_size; /* size of this item */ | 46 | __uint16_t ilf_size; /* size of this item */ |
47 | __uint32_t ilf_fields; /* flags for fields logged */ | 47 | __uint32_t ilf_fields; /* flags for fields logged */ |
48 | __uint16_t ilf_asize; /* size of attr d/ext/root */ | 48 | __uint16_t ilf_asize; /* size of attr d/ext/root */ |
49 | __uint16_t ilf_dsize; /* size of data/ext/root */ | 49 | __uint16_t ilf_dsize; /* size of data/ext/root */ |
50 | __uint64_t ilf_ino; /* inode number */ | 50 | __uint64_t ilf_ino; /* inode number */ |
51 | union { | 51 | union { |
52 | __uint32_t ilfu_rdev; /* rdev value for dev inode*/ | 52 | __uint32_t ilfu_rdev; /* rdev value for dev inode*/ |
53 | uuid_t ilfu_uuid; /* mount point value */ | 53 | uuid_t ilfu_uuid; /* mount point value */ |
54 | } ilf_u; | 54 | } ilf_u; |
55 | __int64_t ilf_blkno; /* blkno of inode buffer */ | 55 | __int64_t ilf_blkno; /* blkno of inode buffer */ |
56 | __int32_t ilf_len; /* len of inode buffer */ | 56 | __int32_t ilf_len; /* len of inode buffer */ |
57 | __int32_t ilf_boffset; /* off of inode in buffer */ | 57 | __int32_t ilf_boffset; /* off of inode in buffer */ |
58 | } __attribute__((packed)) xfs_inode_log_format_32_t; | 58 | } __attribute__((packed)) xfs_inode_log_format_32_t; |
59 | #endif | 59 | #endif |
60 | 60 | ||
61 | typedef struct xfs_inode_log_format_64 { | 61 | typedef struct xfs_inode_log_format_64 { |
62 | __uint16_t ilf_type; /* inode log item type */ | 62 | __uint16_t ilf_type; /* inode log item type */ |
63 | __uint16_t ilf_size; /* size of this item */ | 63 | __uint16_t ilf_size; /* size of this item */ |
64 | __uint32_t ilf_fields; /* flags for fields logged */ | 64 | __uint32_t ilf_fields; /* flags for fields logged */ |
65 | __uint16_t ilf_asize; /* size of attr d/ext/root */ | 65 | __uint16_t ilf_asize; /* size of attr d/ext/root */ |
66 | __uint16_t ilf_dsize; /* size of data/ext/root */ | 66 | __uint16_t ilf_dsize; /* size of data/ext/root */ |
67 | __uint32_t ilf_pad; /* pad for 64 bit boundary */ | 67 | __uint32_t ilf_pad; /* pad for 64 bit boundary */ |
68 | __uint64_t ilf_ino; /* inode number */ | 68 | __uint64_t ilf_ino; /* inode number */ |
69 | union { | 69 | union { |
70 | __uint32_t ilfu_rdev; /* rdev value for dev inode*/ | 70 | __uint32_t ilfu_rdev; /* rdev value for dev inode*/ |
71 | uuid_t ilfu_uuid; /* mount point value */ | 71 | uuid_t ilfu_uuid; /* mount point value */ |
72 | } ilf_u; | 72 | } ilf_u; |
73 | __int64_t ilf_blkno; /* blkno of inode buffer */ | 73 | __int64_t ilf_blkno; /* blkno of inode buffer */ |
74 | __int32_t ilf_len; /* len of inode buffer */ | 74 | __int32_t ilf_len; /* len of inode buffer */ |
75 | __int32_t ilf_boffset; /* off of inode in buffer */ | 75 | __int32_t ilf_boffset; /* off of inode in buffer */ |
76 | } xfs_inode_log_format_64_t; | 76 | } xfs_inode_log_format_64_t; |
77 | 77 | ||
78 | /* | 78 | /* |
79 | * Flags for xfs_trans_log_inode flags field. | 79 | * Flags for xfs_trans_log_inode flags field. |
80 | */ | 80 | */ |
81 | #define XFS_ILOG_CORE 0x001 /* log standard inode fields */ | 81 | #define XFS_ILOG_CORE 0x001 /* log standard inode fields */ |
82 | #define XFS_ILOG_DDATA 0x002 /* log i_df.if_data */ | 82 | #define XFS_ILOG_DDATA 0x002 /* log i_df.if_data */ |
83 | #define XFS_ILOG_DEXT 0x004 /* log i_df.if_extents */ | 83 | #define XFS_ILOG_DEXT 0x004 /* log i_df.if_extents */ |
84 | #define XFS_ILOG_DBROOT 0x008 /* log i_df.i_broot */ | 84 | #define XFS_ILOG_DBROOT 0x008 /* log i_df.i_broot */ |
85 | #define XFS_ILOG_DEV 0x010 /* log the dev field */ | 85 | #define XFS_ILOG_DEV 0x010 /* log the dev field */ |
86 | #define XFS_ILOG_UUID 0x020 /* log the uuid field */ | 86 | #define XFS_ILOG_UUID 0x020 /* log the uuid field */ |
87 | #define XFS_ILOG_ADATA 0x040 /* log i_af.if_data */ | 87 | #define XFS_ILOG_ADATA 0x040 /* log i_af.if_data */ |
88 | #define XFS_ILOG_AEXT 0x080 /* log i_af.if_extents */ | 88 | #define XFS_ILOG_AEXT 0x080 /* log i_af.if_extents */ |
89 | #define XFS_ILOG_ABROOT 0x100 /* log i_af.i_broot */ | 89 | #define XFS_ILOG_ABROOT 0x100 /* log i_af.i_broot */ |
90 | 90 | ||
91 | #define XFS_ILOG_NONCORE (XFS_ILOG_DDATA | XFS_ILOG_DEXT | \ | 91 | #define XFS_ILOG_NONCORE (XFS_ILOG_DDATA | XFS_ILOG_DEXT | \ |
92 | XFS_ILOG_DBROOT | XFS_ILOG_DEV | \ | 92 | XFS_ILOG_DBROOT | XFS_ILOG_DEV | \ |
93 | XFS_ILOG_UUID | XFS_ILOG_ADATA | \ | 93 | XFS_ILOG_UUID | XFS_ILOG_ADATA | \ |
94 | XFS_ILOG_AEXT | XFS_ILOG_ABROOT) | 94 | XFS_ILOG_AEXT | XFS_ILOG_ABROOT) |
95 | 95 | ||
96 | #define XFS_ILOG_DFORK (XFS_ILOG_DDATA | XFS_ILOG_DEXT | \ | 96 | #define XFS_ILOG_DFORK (XFS_ILOG_DDATA | XFS_ILOG_DEXT | \ |
97 | XFS_ILOG_DBROOT) | 97 | XFS_ILOG_DBROOT) |
98 | 98 | ||
99 | #define XFS_ILOG_AFORK (XFS_ILOG_ADATA | XFS_ILOG_AEXT | \ | 99 | #define XFS_ILOG_AFORK (XFS_ILOG_ADATA | XFS_ILOG_AEXT | \ |
100 | XFS_ILOG_ABROOT) | 100 | XFS_ILOG_ABROOT) |
101 | 101 | ||
102 | #define XFS_ILOG_ALL (XFS_ILOG_CORE | XFS_ILOG_DDATA | \ | 102 | #define XFS_ILOG_ALL (XFS_ILOG_CORE | XFS_ILOG_DDATA | \ |
103 | XFS_ILOG_DEXT | XFS_ILOG_DBROOT | \ | 103 | XFS_ILOG_DEXT | XFS_ILOG_DBROOT | \ |
104 | XFS_ILOG_DEV | XFS_ILOG_UUID | \ | 104 | XFS_ILOG_DEV | XFS_ILOG_UUID | \ |
105 | XFS_ILOG_ADATA | XFS_ILOG_AEXT | \ | 105 | XFS_ILOG_ADATA | XFS_ILOG_AEXT | \ |
106 | XFS_ILOG_ABROOT) | 106 | XFS_ILOG_ABROOT) |
107 | 107 | ||
108 | #define XFS_ILI_HOLD 0x1 | 108 | #define XFS_ILI_HOLD 0x1 |
109 | #define XFS_ILI_IOLOCKED_EXCL 0x2 | 109 | #define XFS_ILI_IOLOCKED_EXCL 0x2 |
110 | #define XFS_ILI_IOLOCKED_SHARED 0x4 | 110 | #define XFS_ILI_IOLOCKED_SHARED 0x4 |
111 | 111 | ||
112 | #define XFS_ILI_IOLOCKED_ANY (XFS_ILI_IOLOCKED_EXCL | XFS_ILI_IOLOCKED_SHARED) | 112 | #define XFS_ILI_IOLOCKED_ANY (XFS_ILI_IOLOCKED_EXCL | XFS_ILI_IOLOCKED_SHARED) |
113 | 113 | ||
114 | 114 | ||
115 | #define XFS_ILOG_FBROOT(w) xfs_ilog_fbroot(w) | ||
116 | static inline int xfs_ilog_fbroot(int w) | ||
117 | { | ||
118 | return (w == XFS_DATA_FORK ? XFS_ILOG_DBROOT : XFS_ILOG_ABROOT); | ||
119 | } | ||
120 | |||
121 | #define XFS_ILOG_FEXT(w) xfs_ilog_fext(w) | ||
122 | static inline int xfs_ilog_fext(int w) | ||
123 | { | ||
124 | return (w == XFS_DATA_FORK ? XFS_ILOG_DEXT : XFS_ILOG_AEXT); | ||
125 | } | ||
126 | |||
127 | #define XFS_ILOG_FDATA(w) xfs_ilog_fdata(w) | ||
128 | static inline int xfs_ilog_fdata(int w) | ||
129 | { | ||
130 | return (w == XFS_DATA_FORK ? XFS_ILOG_DDATA : XFS_ILOG_ADATA); | ||
131 | } | ||
132 | |||
115 | #ifdef __KERNEL__ | 133 | #ifdef __KERNEL__ |
116 | 134 | ||
117 | struct xfs_buf; | 135 | struct xfs_buf; |
118 | struct xfs_bmbt_rec_64; | 136 | struct xfs_bmbt_rec_64; |
119 | struct xfs_inode; | 137 | struct xfs_inode; |
120 | struct xfs_mount; | 138 | struct xfs_mount; |
121 | 139 | ||
122 | 140 | ||
123 | typedef struct xfs_inode_log_item { | 141 | typedef struct xfs_inode_log_item { |
124 | xfs_log_item_t ili_item; /* common portion */ | 142 | xfs_log_item_t ili_item; /* common portion */ |
125 | struct xfs_inode *ili_inode; /* inode ptr */ | 143 | struct xfs_inode *ili_inode; /* inode ptr */ |
126 | xfs_lsn_t ili_flush_lsn; /* lsn at last flush */ | 144 | xfs_lsn_t ili_flush_lsn; /* lsn at last flush */ |
127 | xfs_lsn_t ili_last_lsn; /* lsn at last transaction */ | 145 | xfs_lsn_t ili_last_lsn; /* lsn at last transaction */ |
128 | unsigned short ili_ilock_recur; /* lock recursion count */ | 146 | unsigned short ili_ilock_recur; /* lock recursion count */ |
129 | unsigned short ili_iolock_recur; /* lock recursion count */ | 147 | unsigned short ili_iolock_recur; /* lock recursion count */ |
130 | unsigned short ili_flags; /* misc flags */ | 148 | unsigned short ili_flags; /* misc flags */ |
131 | unsigned short ili_logged; /* flushed logged data */ | 149 | unsigned short ili_logged; /* flushed logged data */ |
132 | unsigned int ili_last_fields; /* fields when flushed */ | 150 | unsigned int ili_last_fields; /* fields when flushed */ |
133 | struct xfs_bmbt_rec_64 *ili_extents_buf; /* array of logged | 151 | struct xfs_bmbt_rec_64 *ili_extents_buf; /* array of logged |
134 | data exts */ | 152 | data exts */ |
135 | struct xfs_bmbt_rec_64 *ili_aextents_buf; /* array of logged | 153 | struct xfs_bmbt_rec_64 *ili_aextents_buf; /* array of logged |
136 | attr exts */ | 154 | attr exts */ |
137 | unsigned int ili_pushbuf_flag; /* one bit used in push_ail */ | 155 | unsigned int ili_pushbuf_flag; /* one bit used in push_ail */ |
138 | 156 | ||
139 | #ifdef DEBUG | 157 | #ifdef DEBUG |
140 | uint64_t ili_push_owner; /* one who sets pushbuf_flag | 158 | uint64_t ili_push_owner; /* one who sets pushbuf_flag |
141 | above gets to push the buf */ | 159 | above gets to push the buf */ |
142 | #endif | 160 | #endif |
143 | #ifdef XFS_TRANS_DEBUG | 161 | #ifdef XFS_TRANS_DEBUG |
144 | int ili_root_size; | 162 | int ili_root_size; |
145 | char *ili_orig_root; | 163 | char *ili_orig_root; |
146 | #endif | 164 | #endif |
147 | xfs_inode_log_format_t ili_format; /* logged structure */ | 165 | xfs_inode_log_format_t ili_format; /* logged structure */ |
148 | } xfs_inode_log_item_t; | 166 | } xfs_inode_log_item_t; |
149 | 167 | ||
150 | 168 | ||
151 | #define XFS_ILOG_FDATA(w) xfs_ilog_fdata(w) | ||
152 | static inline int xfs_ilog_fdata(int w) | ||
153 | { | ||
154 | return (w == XFS_DATA_FORK ? XFS_ILOG_DDATA : XFS_ILOG_ADATA); | ||
155 | } | ||
156 | |||
157 | #endif /* __KERNEL__ */ | ||
158 | |||
159 | #define XFS_ILOG_FBROOT(w) xfs_ilog_fbroot(w) | ||
160 | static inline int xfs_ilog_fbroot(int w) | ||
161 | { | ||
162 | return (w == XFS_DATA_FORK ? XFS_ILOG_DBROOT : XFS_ILOG_ABROOT); | ||
163 | } | ||
164 | |||
165 | #define XFS_ILOG_FEXT(w) xfs_ilog_fext(w) | ||
166 | static inline int xfs_ilog_fext(int w) | ||
167 | { | ||
168 | return (w == XFS_DATA_FORK ? XFS_ILOG_DEXT : XFS_ILOG_AEXT); | ||
169 | } | ||
170 | |||
171 | static inline int xfs_inode_clean(xfs_inode_t *ip) | 169 | static inline int xfs_inode_clean(xfs_inode_t *ip) |
172 | { | 170 | { |
173 | return (!ip->i_itemp || | 171 | return (!ip->i_itemp || |
174 | !(ip->i_itemp->ili_format.ilf_fields & XFS_ILOG_ALL)) && | 172 | !(ip->i_itemp->ili_format.ilf_fields & XFS_ILOG_ALL)) && |
fs/xfs/xfs_mount.h
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2005 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License as | 6 | * modify it under the terms of the GNU General Public License as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | * | 8 | * |
9 | * This program is distributed in the hope that it would be useful, | 9 | * This program is distributed in the hope that it would be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. | 12 | * GNU General Public License for more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License | 14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write the Free Software Foundation, | 15 | * along with this program; if not, write the Free Software Foundation, |
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ | 17 | */ |
18 | #ifndef __XFS_MOUNT_H__ | 18 | #ifndef __XFS_MOUNT_H__ |
19 | #define __XFS_MOUNT_H__ | 19 | #define __XFS_MOUNT_H__ |
20 | 20 | ||
21 | 21 | ||
22 | typedef struct xfs_trans_reservations { | 22 | typedef struct xfs_trans_reservations { |
23 | uint tr_write; /* extent alloc trans */ | 23 | uint tr_write; /* extent alloc trans */ |
24 | uint tr_itruncate; /* truncate trans */ | 24 | uint tr_itruncate; /* truncate trans */ |
25 | uint tr_rename; /* rename trans */ | 25 | uint tr_rename; /* rename trans */ |
26 | uint tr_link; /* link trans */ | 26 | uint tr_link; /* link trans */ |
27 | uint tr_remove; /* unlink trans */ | 27 | uint tr_remove; /* unlink trans */ |
28 | uint tr_symlink; /* symlink trans */ | 28 | uint tr_symlink; /* symlink trans */ |
29 | uint tr_create; /* create trans */ | 29 | uint tr_create; /* create trans */ |
30 | uint tr_mkdir; /* mkdir trans */ | 30 | uint tr_mkdir; /* mkdir trans */ |
31 | uint tr_ifree; /* inode free trans */ | 31 | uint tr_ifree; /* inode free trans */ |
32 | uint tr_ichange; /* inode update trans */ | 32 | uint tr_ichange; /* inode update trans */ |
33 | uint tr_growdata; /* fs data section grow trans */ | 33 | uint tr_growdata; /* fs data section grow trans */ |
34 | uint tr_swrite; /* sync write inode trans */ | 34 | uint tr_swrite; /* sync write inode trans */ |
35 | uint tr_addafork; /* cvt inode to attributed trans */ | 35 | uint tr_addafork; /* cvt inode to attributed trans */ |
36 | uint tr_writeid; /* write setuid/setgid file */ | 36 | uint tr_writeid; /* write setuid/setgid file */ |
37 | uint tr_attrinval; /* attr fork buffer invalidation */ | 37 | uint tr_attrinval; /* attr fork buffer invalidation */ |
38 | uint tr_attrset; /* set/create an attribute */ | 38 | uint tr_attrset; /* set/create an attribute */ |
39 | uint tr_attrrm; /* remove an attribute */ | 39 | uint tr_attrrm; /* remove an attribute */ |
40 | uint tr_clearagi; /* clear bad agi unlinked ino bucket */ | 40 | uint tr_clearagi; /* clear bad agi unlinked ino bucket */ |
41 | uint tr_growrtalloc; /* grow realtime allocations */ | 41 | uint tr_growrtalloc; /* grow realtime allocations */ |
42 | uint tr_growrtzero; /* grow realtime zeroing */ | 42 | uint tr_growrtzero; /* grow realtime zeroing */ |
43 | uint tr_growrtfree; /* grow realtime freeing */ | 43 | uint tr_growrtfree; /* grow realtime freeing */ |
44 | } xfs_trans_reservations_t; | 44 | } xfs_trans_reservations_t; |
45 | 45 | ||
46 | #ifndef __KERNEL__ | 46 | #ifndef __KERNEL__ |
47 | /* | 47 | |
48 | * Moved here from xfs_ag.h to avoid reordering header files | ||
49 | */ | ||
50 | #define XFS_DADDR_TO_AGNO(mp,d) \ | 48 | #define XFS_DADDR_TO_AGNO(mp,d) \ |
51 | ((xfs_agnumber_t)(XFS_BB_TO_FSBT(mp, d) / (mp)->m_sb.sb_agblocks)) | 49 | ((xfs_agnumber_t)(XFS_BB_TO_FSBT(mp, d) / (mp)->m_sb.sb_agblocks)) |
52 | #define XFS_DADDR_TO_AGBNO(mp,d) \ | 50 | #define XFS_DADDR_TO_AGBNO(mp,d) \ |
53 | ((xfs_agblock_t)(XFS_BB_TO_FSBT(mp, d) % (mp)->m_sb.sb_agblocks)) | 51 | ((xfs_agblock_t)(XFS_BB_TO_FSBT(mp, d) % (mp)->m_sb.sb_agblocks)) |
54 | #else | 52 | |
53 | #else /* __KERNEL__ */ | ||
54 | |||
55 | struct cred; | 55 | struct cred; |
56 | struct log; | 56 | struct log; |
57 | struct xfs_mount_args; | 57 | struct xfs_mount_args; |
58 | struct xfs_inode; | 58 | struct xfs_inode; |
59 | struct xfs_bmbt_irec; | 59 | struct xfs_bmbt_irec; |
60 | struct xfs_bmap_free; | 60 | struct xfs_bmap_free; |
61 | struct xfs_extdelta; | 61 | struct xfs_extdelta; |
62 | struct xfs_swapext; | 62 | struct xfs_swapext; |
63 | struct xfs_mru_cache; | 63 | struct xfs_mru_cache; |
64 | struct xfs_nameops; | 64 | struct xfs_nameops; |
65 | 65 | ||
66 | /* | 66 | /* |
67 | * Prototypes and functions for the Data Migration subsystem. | 67 | * Prototypes and functions for the Data Migration subsystem. |
68 | */ | 68 | */ |
69 | 69 | ||
70 | typedef int (*xfs_send_data_t)(int, struct xfs_inode *, | 70 | typedef int (*xfs_send_data_t)(int, struct xfs_inode *, |
71 | xfs_off_t, size_t, int, int *); | 71 | xfs_off_t, size_t, int, int *); |
72 | typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint); | 72 | typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint); |
73 | typedef int (*xfs_send_destroy_t)(struct xfs_inode *, dm_right_t); | 73 | typedef int (*xfs_send_destroy_t)(struct xfs_inode *, dm_right_t); |
74 | typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct xfs_mount *, | 74 | typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct xfs_mount *, |
75 | struct xfs_inode *, dm_right_t, | 75 | struct xfs_inode *, dm_right_t, |
76 | struct xfs_inode *, dm_right_t, | 76 | struct xfs_inode *, dm_right_t, |
77 | const char *, const char *, mode_t, int, int); | 77 | const char *, const char *, mode_t, int, int); |
78 | typedef int (*xfs_send_mount_t)(struct xfs_mount *, dm_right_t, | 78 | typedef int (*xfs_send_mount_t)(struct xfs_mount *, dm_right_t, |
79 | char *, char *); | 79 | char *, char *); |
80 | typedef void (*xfs_send_unmount_t)(struct xfs_mount *, struct xfs_inode *, | 80 | typedef void (*xfs_send_unmount_t)(struct xfs_mount *, struct xfs_inode *, |
81 | dm_right_t, mode_t, int, int); | 81 | dm_right_t, mode_t, int, int); |
82 | 82 | ||
83 | typedef struct xfs_dmops { | 83 | typedef struct xfs_dmops { |
84 | xfs_send_data_t xfs_send_data; | 84 | xfs_send_data_t xfs_send_data; |
85 | xfs_send_mmap_t xfs_send_mmap; | 85 | xfs_send_mmap_t xfs_send_mmap; |
86 | xfs_send_destroy_t xfs_send_destroy; | 86 | xfs_send_destroy_t xfs_send_destroy; |
87 | xfs_send_namesp_t xfs_send_namesp; | 87 | xfs_send_namesp_t xfs_send_namesp; |
88 | xfs_send_mount_t xfs_send_mount; | 88 | xfs_send_mount_t xfs_send_mount; |
89 | xfs_send_unmount_t xfs_send_unmount; | 89 | xfs_send_unmount_t xfs_send_unmount; |
90 | } xfs_dmops_t; | 90 | } xfs_dmops_t; |
91 | 91 | ||
92 | #define XFS_SEND_DATA(mp, ev,ip,off,len,fl,lock) \ | 92 | #define XFS_SEND_DATA(mp, ev,ip,off,len,fl,lock) \ |
93 | (*(mp)->m_dm_ops->xfs_send_data)(ev,ip,off,len,fl,lock) | 93 | (*(mp)->m_dm_ops->xfs_send_data)(ev,ip,off,len,fl,lock) |
94 | #define XFS_SEND_MMAP(mp, vma,fl) \ | 94 | #define XFS_SEND_MMAP(mp, vma,fl) \ |
95 | (*(mp)->m_dm_ops->xfs_send_mmap)(vma,fl) | 95 | (*(mp)->m_dm_ops->xfs_send_mmap)(vma,fl) |
96 | #define XFS_SEND_DESTROY(mp, ip,right) \ | 96 | #define XFS_SEND_DESTROY(mp, ip,right) \ |
97 | (*(mp)->m_dm_ops->xfs_send_destroy)(ip,right) | 97 | (*(mp)->m_dm_ops->xfs_send_destroy)(ip,right) |
98 | #define XFS_SEND_NAMESP(mp, ev,b1,r1,b2,r2,n1,n2,mode,rval,fl) \ | 98 | #define XFS_SEND_NAMESP(mp, ev,b1,r1,b2,r2,n1,n2,mode,rval,fl) \ |
99 | (*(mp)->m_dm_ops->xfs_send_namesp)(ev,NULL,b1,r1,b2,r2,n1,n2,mode,rval,fl) | 99 | (*(mp)->m_dm_ops->xfs_send_namesp)(ev,NULL,b1,r1,b2,r2,n1,n2,mode,rval,fl) |
100 | #define XFS_SEND_PREUNMOUNT(mp,b1,r1,b2,r2,n1,n2,mode,rval,fl) \ | 100 | #define XFS_SEND_PREUNMOUNT(mp,b1,r1,b2,r2,n1,n2,mode,rval,fl) \ |
101 | (*(mp)->m_dm_ops->xfs_send_namesp)(DM_EVENT_PREUNMOUNT,mp,b1,r1,b2,r2,n1,n2,mode,rval,fl) | 101 | (*(mp)->m_dm_ops->xfs_send_namesp)(DM_EVENT_PREUNMOUNT,mp,b1,r1,b2,r2,n1,n2,mode,rval,fl) |
102 | #define XFS_SEND_MOUNT(mp,right,path,name) \ | 102 | #define XFS_SEND_MOUNT(mp,right,path,name) \ |
103 | (*(mp)->m_dm_ops->xfs_send_mount)(mp,right,path,name) | 103 | (*(mp)->m_dm_ops->xfs_send_mount)(mp,right,path,name) |
104 | #define XFS_SEND_UNMOUNT(mp, ip,right,mode,rval,fl) \ | 104 | #define XFS_SEND_UNMOUNT(mp, ip,right,mode,rval,fl) \ |
105 | (*(mp)->m_dm_ops->xfs_send_unmount)(mp,ip,right,mode,rval,fl) | 105 | (*(mp)->m_dm_ops->xfs_send_unmount)(mp,ip,right,mode,rval,fl) |
106 | 106 | ||
107 | 107 | ||
108 | /* | 108 | /* |
109 | * Prototypes and functions for the Quota Management subsystem. | 109 | * Prototypes and functions for the Quota Management subsystem. |
110 | */ | 110 | */ |
111 | 111 | ||
112 | struct xfs_dquot; | 112 | struct xfs_dquot; |
113 | struct xfs_dqtrxops; | 113 | struct xfs_dqtrxops; |
114 | struct xfs_quotainfo; | 114 | struct xfs_quotainfo; |
115 | 115 | ||
116 | typedef int (*xfs_qminit_t)(struct xfs_mount *, uint *, uint *); | 116 | typedef int (*xfs_qminit_t)(struct xfs_mount *, uint *, uint *); |
117 | typedef int (*xfs_qmmount_t)(struct xfs_mount *, uint, uint); | 117 | typedef int (*xfs_qmmount_t)(struct xfs_mount *, uint, uint); |
118 | typedef int (*xfs_qmunmount_t)(struct xfs_mount *); | 118 | typedef int (*xfs_qmunmount_t)(struct xfs_mount *); |
119 | typedef void (*xfs_qmdone_t)(struct xfs_mount *); | 119 | typedef void (*xfs_qmdone_t)(struct xfs_mount *); |
120 | typedef void (*xfs_dqrele_t)(struct xfs_dquot *); | 120 | typedef void (*xfs_dqrele_t)(struct xfs_dquot *); |
121 | typedef int (*xfs_dqattach_t)(struct xfs_inode *, uint); | 121 | typedef int (*xfs_dqattach_t)(struct xfs_inode *, uint); |
122 | typedef void (*xfs_dqdetach_t)(struct xfs_inode *); | 122 | typedef void (*xfs_dqdetach_t)(struct xfs_inode *); |
123 | typedef int (*xfs_dqpurgeall_t)(struct xfs_mount *, uint); | 123 | typedef int (*xfs_dqpurgeall_t)(struct xfs_mount *, uint); |
124 | typedef int (*xfs_dqvopalloc_t)(struct xfs_mount *, | 124 | typedef int (*xfs_dqvopalloc_t)(struct xfs_mount *, |
125 | struct xfs_inode *, uid_t, gid_t, prid_t, uint, | 125 | struct xfs_inode *, uid_t, gid_t, prid_t, uint, |
126 | struct xfs_dquot **, struct xfs_dquot **); | 126 | struct xfs_dquot **, struct xfs_dquot **); |
127 | typedef void (*xfs_dqvopcreate_t)(struct xfs_trans *, struct xfs_inode *, | 127 | typedef void (*xfs_dqvopcreate_t)(struct xfs_trans *, struct xfs_inode *, |
128 | struct xfs_dquot *, struct xfs_dquot *); | 128 | struct xfs_dquot *, struct xfs_dquot *); |
129 | typedef int (*xfs_dqvoprename_t)(struct xfs_inode **); | 129 | typedef int (*xfs_dqvoprename_t)(struct xfs_inode **); |
130 | typedef struct xfs_dquot * (*xfs_dqvopchown_t)( | 130 | typedef struct xfs_dquot * (*xfs_dqvopchown_t)( |
131 | struct xfs_trans *, struct xfs_inode *, | 131 | struct xfs_trans *, struct xfs_inode *, |
132 | struct xfs_dquot **, struct xfs_dquot *); | 132 | struct xfs_dquot **, struct xfs_dquot *); |
133 | typedef int (*xfs_dqvopchownresv_t)(struct xfs_trans *, struct xfs_inode *, | 133 | typedef int (*xfs_dqvopchownresv_t)(struct xfs_trans *, struct xfs_inode *, |
134 | struct xfs_dquot *, struct xfs_dquot *, uint); | 134 | struct xfs_dquot *, struct xfs_dquot *, uint); |
135 | typedef void (*xfs_dqstatvfs_t)(struct xfs_inode *, bhv_statvfs_t *); | 135 | typedef void (*xfs_dqstatvfs_t)(struct xfs_inode *, bhv_statvfs_t *); |
136 | typedef int (*xfs_dqsync_t)(struct xfs_mount *, int flags); | 136 | typedef int (*xfs_dqsync_t)(struct xfs_mount *, int flags); |
137 | typedef int (*xfs_quotactl_t)(struct xfs_mount *, int, int, xfs_caddr_t); | 137 | typedef int (*xfs_quotactl_t)(struct xfs_mount *, int, int, xfs_caddr_t); |
138 | 138 | ||
139 | typedef struct xfs_qmops { | 139 | typedef struct xfs_qmops { |
140 | xfs_qminit_t xfs_qminit; | 140 | xfs_qminit_t xfs_qminit; |
141 | xfs_qmdone_t xfs_qmdone; | 141 | xfs_qmdone_t xfs_qmdone; |
142 | xfs_qmmount_t xfs_qmmount; | 142 | xfs_qmmount_t xfs_qmmount; |
143 | xfs_qmunmount_t xfs_qmunmount; | 143 | xfs_qmunmount_t xfs_qmunmount; |
144 | xfs_dqrele_t xfs_dqrele; | 144 | xfs_dqrele_t xfs_dqrele; |
145 | xfs_dqattach_t xfs_dqattach; | 145 | xfs_dqattach_t xfs_dqattach; |
146 | xfs_dqdetach_t xfs_dqdetach; | 146 | xfs_dqdetach_t xfs_dqdetach; |
147 | xfs_dqpurgeall_t xfs_dqpurgeall; | 147 | xfs_dqpurgeall_t xfs_dqpurgeall; |
148 | xfs_dqvopalloc_t xfs_dqvopalloc; | 148 | xfs_dqvopalloc_t xfs_dqvopalloc; |
149 | xfs_dqvopcreate_t xfs_dqvopcreate; | 149 | xfs_dqvopcreate_t xfs_dqvopcreate; |
150 | xfs_dqvoprename_t xfs_dqvoprename; | 150 | xfs_dqvoprename_t xfs_dqvoprename; |
151 | xfs_dqvopchown_t xfs_dqvopchown; | 151 | xfs_dqvopchown_t xfs_dqvopchown; |
152 | xfs_dqvopchownresv_t xfs_dqvopchownresv; | 152 | xfs_dqvopchownresv_t xfs_dqvopchownresv; |
153 | xfs_dqstatvfs_t xfs_dqstatvfs; | 153 | xfs_dqstatvfs_t xfs_dqstatvfs; |
154 | xfs_dqsync_t xfs_dqsync; | 154 | xfs_dqsync_t xfs_dqsync; |
155 | xfs_quotactl_t xfs_quotactl; | 155 | xfs_quotactl_t xfs_quotactl; |
156 | struct xfs_dqtrxops *xfs_dqtrxops; | 156 | struct xfs_dqtrxops *xfs_dqtrxops; |
157 | } xfs_qmops_t; | 157 | } xfs_qmops_t; |
158 | 158 | ||
159 | #define XFS_QM_INIT(mp, mnt, fl) \ | 159 | #define XFS_QM_INIT(mp, mnt, fl) \ |
160 | (*(mp)->m_qm_ops->xfs_qminit)(mp, mnt, fl) | 160 | (*(mp)->m_qm_ops->xfs_qminit)(mp, mnt, fl) |
161 | #define XFS_QM_MOUNT(mp, mnt, fl) \ | 161 | #define XFS_QM_MOUNT(mp, mnt, fl) \ |
162 | (*(mp)->m_qm_ops->xfs_qmmount)(mp, mnt, fl) | 162 | (*(mp)->m_qm_ops->xfs_qmmount)(mp, mnt, fl) |
163 | #define XFS_QM_UNMOUNT(mp) \ | 163 | #define XFS_QM_UNMOUNT(mp) \ |
164 | (*(mp)->m_qm_ops->xfs_qmunmount)(mp) | 164 | (*(mp)->m_qm_ops->xfs_qmunmount)(mp) |
165 | #define XFS_QM_DONE(mp) \ | 165 | #define XFS_QM_DONE(mp) \ |
166 | (*(mp)->m_qm_ops->xfs_qmdone)(mp) | 166 | (*(mp)->m_qm_ops->xfs_qmdone)(mp) |
167 | #define XFS_QM_DQRELE(mp, dq) \ | 167 | #define XFS_QM_DQRELE(mp, dq) \ |
168 | (*(mp)->m_qm_ops->xfs_dqrele)(dq) | 168 | (*(mp)->m_qm_ops->xfs_dqrele)(dq) |
169 | #define XFS_QM_DQATTACH(mp, ip, fl) \ | 169 | #define XFS_QM_DQATTACH(mp, ip, fl) \ |
170 | (*(mp)->m_qm_ops->xfs_dqattach)(ip, fl) | 170 | (*(mp)->m_qm_ops->xfs_dqattach)(ip, fl) |
171 | #define XFS_QM_DQDETACH(mp, ip) \ | 171 | #define XFS_QM_DQDETACH(mp, ip) \ |
172 | (*(mp)->m_qm_ops->xfs_dqdetach)(ip) | 172 | (*(mp)->m_qm_ops->xfs_dqdetach)(ip) |
173 | #define XFS_QM_DQPURGEALL(mp, fl) \ | 173 | #define XFS_QM_DQPURGEALL(mp, fl) \ |
174 | (*(mp)->m_qm_ops->xfs_dqpurgeall)(mp, fl) | 174 | (*(mp)->m_qm_ops->xfs_dqpurgeall)(mp, fl) |
175 | #define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, prid, fl, dq1, dq2) \ | 175 | #define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, prid, fl, dq1, dq2) \ |
176 | (*(mp)->m_qm_ops->xfs_dqvopalloc)(mp, ip, uid, gid, prid, fl, dq1, dq2) | 176 | (*(mp)->m_qm_ops->xfs_dqvopalloc)(mp, ip, uid, gid, prid, fl, dq1, dq2) |
177 | #define XFS_QM_DQVOPCREATE(mp, tp, ip, dq1, dq2) \ | 177 | #define XFS_QM_DQVOPCREATE(mp, tp, ip, dq1, dq2) \ |
178 | (*(mp)->m_qm_ops->xfs_dqvopcreate)(tp, ip, dq1, dq2) | 178 | (*(mp)->m_qm_ops->xfs_dqvopcreate)(tp, ip, dq1, dq2) |
179 | #define XFS_QM_DQVOPRENAME(mp, ip) \ | 179 | #define XFS_QM_DQVOPRENAME(mp, ip) \ |
180 | (*(mp)->m_qm_ops->xfs_dqvoprename)(ip) | 180 | (*(mp)->m_qm_ops->xfs_dqvoprename)(ip) |
181 | #define XFS_QM_DQVOPCHOWN(mp, tp, ip, dqp, dq) \ | 181 | #define XFS_QM_DQVOPCHOWN(mp, tp, ip, dqp, dq) \ |
182 | (*(mp)->m_qm_ops->xfs_dqvopchown)(tp, ip, dqp, dq) | 182 | (*(mp)->m_qm_ops->xfs_dqvopchown)(tp, ip, dqp, dq) |
183 | #define XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, dq1, dq2, fl) \ | 183 | #define XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, dq1, dq2, fl) \ |
184 | (*(mp)->m_qm_ops->xfs_dqvopchownresv)(tp, ip, dq1, dq2, fl) | 184 | (*(mp)->m_qm_ops->xfs_dqvopchownresv)(tp, ip, dq1, dq2, fl) |
185 | #define XFS_QM_DQSTATVFS(ip, statp) \ | 185 | #define XFS_QM_DQSTATVFS(ip, statp) \ |
186 | (*(ip)->i_mount->m_qm_ops->xfs_dqstatvfs)(ip, statp) | 186 | (*(ip)->i_mount->m_qm_ops->xfs_dqstatvfs)(ip, statp) |
187 | #define XFS_QM_DQSYNC(mp, flags) \ | 187 | #define XFS_QM_DQSYNC(mp, flags) \ |
188 | (*(mp)->m_qm_ops->xfs_dqsync)(mp, flags) | 188 | (*(mp)->m_qm_ops->xfs_dqsync)(mp, flags) |
189 | #define XFS_QM_QUOTACTL(mp, cmd, id, addr) \ | 189 | #define XFS_QM_QUOTACTL(mp, cmd, id, addr) \ |
190 | (*(mp)->m_qm_ops->xfs_quotactl)(mp, cmd, id, addr) | 190 | (*(mp)->m_qm_ops->xfs_quotactl)(mp, cmd, id, addr) |
191 | 191 | ||
192 | #ifdef HAVE_PERCPU_SB | 192 | #ifdef HAVE_PERCPU_SB |
193 | 193 | ||
194 | /* | 194 | /* |
195 | * Valid per-cpu incore superblock counters. Note that if you add new counters, | 195 | * Valid per-cpu incore superblock counters. Note that if you add new counters, |
196 | * you may need to define new counter disabled bit field descriptors as there | 196 | * you may need to define new counter disabled bit field descriptors as there |
197 | * are more possible fields in the superblock that can fit in a bitfield on a | 197 | * are more possible fields in the superblock that can fit in a bitfield on a |
198 | * 32 bit platform. The XFS_SBS_* values for the current current counters just | 198 | * 32 bit platform. The XFS_SBS_* values for the current current counters just |
199 | * fit. | 199 | * fit. |
200 | */ | 200 | */ |
201 | typedef struct xfs_icsb_cnts { | 201 | typedef struct xfs_icsb_cnts { |
202 | uint64_t icsb_fdblocks; | 202 | uint64_t icsb_fdblocks; |
203 | uint64_t icsb_ifree; | 203 | uint64_t icsb_ifree; |
204 | uint64_t icsb_icount; | 204 | uint64_t icsb_icount; |
205 | unsigned long icsb_flags; | 205 | unsigned long icsb_flags; |
206 | } xfs_icsb_cnts_t; | 206 | } xfs_icsb_cnts_t; |
207 | 207 | ||
208 | #define XFS_ICSB_FLAG_LOCK (1 << 0) /* counter lock bit */ | 208 | #define XFS_ICSB_FLAG_LOCK (1 << 0) /* counter lock bit */ |
209 | 209 | ||
210 | #define XFS_ICSB_LAZY_COUNT (1 << 1) /* accuracy not needed */ | 210 | #define XFS_ICSB_LAZY_COUNT (1 << 1) /* accuracy not needed */ |
211 | 211 | ||
212 | extern int xfs_icsb_init_counters(struct xfs_mount *); | 212 | extern int xfs_icsb_init_counters(struct xfs_mount *); |
213 | extern void xfs_icsb_reinit_counters(struct xfs_mount *); | 213 | extern void xfs_icsb_reinit_counters(struct xfs_mount *); |
214 | extern void xfs_icsb_destroy_counters(struct xfs_mount *); | 214 | extern void xfs_icsb_destroy_counters(struct xfs_mount *); |
215 | extern void xfs_icsb_sync_counters(struct xfs_mount *, int); | 215 | extern void xfs_icsb_sync_counters(struct xfs_mount *, int); |
216 | extern void xfs_icsb_sync_counters_locked(struct xfs_mount *, int); | 216 | extern void xfs_icsb_sync_counters_locked(struct xfs_mount *, int); |
217 | 217 | ||
218 | #else | 218 | #else |
219 | #define xfs_icsb_init_counters(mp) (0) | 219 | #define xfs_icsb_init_counters(mp) (0) |
220 | #define xfs_icsb_destroy_counters(mp) do { } while (0) | 220 | #define xfs_icsb_destroy_counters(mp) do { } while (0) |
221 | #define xfs_icsb_reinit_counters(mp) do { } while (0) | 221 | #define xfs_icsb_reinit_counters(mp) do { } while (0) |
222 | #define xfs_icsb_sync_counters(mp, flags) do { } while (0) | 222 | #define xfs_icsb_sync_counters(mp, flags) do { } while (0) |
223 | #define xfs_icsb_sync_counters_locked(mp, flags) do { } while (0) | 223 | #define xfs_icsb_sync_counters_locked(mp, flags) do { } while (0) |
224 | #endif | 224 | #endif |
225 | 225 | ||
226 | typedef struct xfs_ail { | 226 | typedef struct xfs_ail { |
227 | struct list_head xa_ail; | 227 | struct list_head xa_ail; |
228 | uint xa_gen; | 228 | uint xa_gen; |
229 | struct task_struct *xa_task; | 229 | struct task_struct *xa_task; |
230 | xfs_lsn_t xa_target; | 230 | xfs_lsn_t xa_target; |
231 | } xfs_ail_t; | 231 | } xfs_ail_t; |
232 | 232 | ||
233 | typedef struct xfs_mount { | 233 | typedef struct xfs_mount { |
234 | struct super_block *m_super; | 234 | struct super_block *m_super; |
235 | xfs_tid_t m_tid; /* next unused tid for fs */ | 235 | xfs_tid_t m_tid; /* next unused tid for fs */ |
236 | spinlock_t m_ail_lock; /* fs AIL mutex */ | 236 | spinlock_t m_ail_lock; /* fs AIL mutex */ |
237 | xfs_ail_t m_ail; /* fs active log item list */ | 237 | xfs_ail_t m_ail; /* fs active log item list */ |
238 | xfs_sb_t m_sb; /* copy of fs superblock */ | 238 | xfs_sb_t m_sb; /* copy of fs superblock */ |
239 | spinlock_t m_sb_lock; /* sb counter lock */ | 239 | spinlock_t m_sb_lock; /* sb counter lock */ |
240 | struct xfs_buf *m_sb_bp; /* buffer for superblock */ | 240 | struct xfs_buf *m_sb_bp; /* buffer for superblock */ |
241 | char *m_fsname; /* filesystem name */ | 241 | char *m_fsname; /* filesystem name */ |
242 | int m_fsname_len; /* strlen of fs name */ | 242 | int m_fsname_len; /* strlen of fs name */ |
243 | char *m_rtname; /* realtime device name */ | 243 | char *m_rtname; /* realtime device name */ |
244 | char *m_logname; /* external log device name */ | 244 | char *m_logname; /* external log device name */ |
245 | int m_bsize; /* fs logical block size */ | 245 | int m_bsize; /* fs logical block size */ |
246 | xfs_agnumber_t m_agfrotor; /* last ag where space found */ | 246 | xfs_agnumber_t m_agfrotor; /* last ag where space found */ |
247 | xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */ | 247 | xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */ |
248 | spinlock_t m_agirotor_lock;/* .. and lock protecting it */ | 248 | spinlock_t m_agirotor_lock;/* .. and lock protecting it */ |
249 | xfs_agnumber_t m_maxagi; /* highest inode alloc group */ | 249 | xfs_agnumber_t m_maxagi; /* highest inode alloc group */ |
250 | struct xfs_inode *m_inodes; /* active inode list */ | 250 | struct xfs_inode *m_inodes; /* active inode list */ |
251 | struct list_head m_del_inodes; /* inodes to reclaim */ | 251 | struct list_head m_del_inodes; /* inodes to reclaim */ |
252 | mutex_t m_ilock; /* inode list mutex */ | 252 | mutex_t m_ilock; /* inode list mutex */ |
253 | uint m_ireclaims; /* count of calls to reclaim*/ | 253 | uint m_ireclaims; /* count of calls to reclaim*/ |
254 | uint m_readio_log; /* min read size log bytes */ | 254 | uint m_readio_log; /* min read size log bytes */ |
255 | uint m_readio_blocks; /* min read size blocks */ | 255 | uint m_readio_blocks; /* min read size blocks */ |
256 | uint m_writeio_log; /* min write size log bytes */ | 256 | uint m_writeio_log; /* min write size log bytes */ |
257 | uint m_writeio_blocks; /* min write size blocks */ | 257 | uint m_writeio_blocks; /* min write size blocks */ |
258 | struct log *m_log; /* log specific stuff */ | 258 | struct log *m_log; /* log specific stuff */ |
259 | int m_logbufs; /* number of log buffers */ | 259 | int m_logbufs; /* number of log buffers */ |
260 | int m_logbsize; /* size of each log buffer */ | 260 | int m_logbsize; /* size of each log buffer */ |
261 | uint m_rsumlevels; /* rt summary levels */ | 261 | uint m_rsumlevels; /* rt summary levels */ |
262 | uint m_rsumsize; /* size of rt summary, bytes */ | 262 | uint m_rsumsize; /* size of rt summary, bytes */ |
263 | struct xfs_inode *m_rbmip; /* pointer to bitmap inode */ | 263 | struct xfs_inode *m_rbmip; /* pointer to bitmap inode */ |
264 | struct xfs_inode *m_rsumip; /* pointer to summary inode */ | 264 | struct xfs_inode *m_rsumip; /* pointer to summary inode */ |
265 | struct xfs_inode *m_rootip; /* pointer to root directory */ | 265 | struct xfs_inode *m_rootip; /* pointer to root directory */ |
266 | struct xfs_quotainfo *m_quotainfo; /* disk quota information */ | 266 | struct xfs_quotainfo *m_quotainfo; /* disk quota information */ |
267 | xfs_buftarg_t *m_ddev_targp; /* saves taking the address */ | 267 | xfs_buftarg_t *m_ddev_targp; /* saves taking the address */ |
268 | xfs_buftarg_t *m_logdev_targp;/* ptr to log device */ | 268 | xfs_buftarg_t *m_logdev_targp;/* ptr to log device */ |
269 | xfs_buftarg_t *m_rtdev_targp; /* ptr to rt device */ | 269 | xfs_buftarg_t *m_rtdev_targp; /* ptr to rt device */ |
270 | __uint8_t m_blkbit_log; /* blocklog + NBBY */ | 270 | __uint8_t m_blkbit_log; /* blocklog + NBBY */ |
271 | __uint8_t m_blkbb_log; /* blocklog - BBSHIFT */ | 271 | __uint8_t m_blkbb_log; /* blocklog - BBSHIFT */ |
272 | __uint8_t m_agno_log; /* log #ag's */ | 272 | __uint8_t m_agno_log; /* log #ag's */ |
273 | __uint8_t m_agino_log; /* #bits for agino in inum */ | 273 | __uint8_t m_agino_log; /* #bits for agino in inum */ |
274 | __uint16_t m_inode_cluster_size;/* min inode buf size */ | 274 | __uint16_t m_inode_cluster_size;/* min inode buf size */ |
275 | uint m_blockmask; /* sb_blocksize-1 */ | 275 | uint m_blockmask; /* sb_blocksize-1 */ |
276 | uint m_blockwsize; /* sb_blocksize in words */ | 276 | uint m_blockwsize; /* sb_blocksize in words */ |
277 | uint m_blockwmask; /* blockwsize-1 */ | 277 | uint m_blockwmask; /* blockwsize-1 */ |
278 | uint m_alloc_mxr[2]; /* XFS_ALLOC_BLOCK_MAXRECS */ | 278 | uint m_alloc_mxr[2]; /* XFS_ALLOC_BLOCK_MAXRECS */ |
279 | uint m_alloc_mnr[2]; /* XFS_ALLOC_BLOCK_MINRECS */ | 279 | uint m_alloc_mnr[2]; /* XFS_ALLOC_BLOCK_MINRECS */ |
280 | uint m_bmap_dmxr[2]; /* XFS_BMAP_BLOCK_DMAXRECS */ | 280 | uint m_bmap_dmxr[2]; /* XFS_BMAP_BLOCK_DMAXRECS */ |
281 | uint m_bmap_dmnr[2]; /* XFS_BMAP_BLOCK_DMINRECS */ | 281 | uint m_bmap_dmnr[2]; /* XFS_BMAP_BLOCK_DMINRECS */ |
282 | uint m_inobt_mxr[2]; /* XFS_INOBT_BLOCK_MAXRECS */ | 282 | uint m_inobt_mxr[2]; /* XFS_INOBT_BLOCK_MAXRECS */ |
283 | uint m_inobt_mnr[2]; /* XFS_INOBT_BLOCK_MINRECS */ | 283 | uint m_inobt_mnr[2]; /* XFS_INOBT_BLOCK_MINRECS */ |
284 | uint m_ag_maxlevels; /* XFS_AG_MAXLEVELS */ | 284 | uint m_ag_maxlevels; /* XFS_AG_MAXLEVELS */ |
285 | uint m_bm_maxlevels[2]; /* XFS_BM_MAXLEVELS */ | 285 | uint m_bm_maxlevels[2]; /* XFS_BM_MAXLEVELS */ |
286 | uint m_in_maxlevels; /* XFS_IN_MAXLEVELS */ | 286 | uint m_in_maxlevels; /* XFS_IN_MAXLEVELS */ |
287 | struct xfs_perag *m_perag; /* per-ag accounting info */ | 287 | struct xfs_perag *m_perag; /* per-ag accounting info */ |
288 | struct rw_semaphore m_peraglock; /* lock for m_perag (pointer) */ | 288 | struct rw_semaphore m_peraglock; /* lock for m_perag (pointer) */ |
289 | struct mutex m_growlock; /* growfs mutex */ | 289 | struct mutex m_growlock; /* growfs mutex */ |
290 | int m_fixedfsid[2]; /* unchanged for life of FS */ | 290 | int m_fixedfsid[2]; /* unchanged for life of FS */ |
291 | uint m_dmevmask; /* DMI events for this FS */ | 291 | uint m_dmevmask; /* DMI events for this FS */ |
292 | __uint64_t m_flags; /* global mount flags */ | 292 | __uint64_t m_flags; /* global mount flags */ |
293 | uint m_attroffset; /* inode attribute offset */ | 293 | uint m_attroffset; /* inode attribute offset */ |
294 | uint m_dir_node_ents; /* #entries in a dir danode */ | 294 | uint m_dir_node_ents; /* #entries in a dir danode */ |
295 | uint m_attr_node_ents; /* #entries in attr danode */ | 295 | uint m_attr_node_ents; /* #entries in attr danode */ |
296 | int m_ialloc_inos; /* inodes in inode allocation */ | 296 | int m_ialloc_inos; /* inodes in inode allocation */ |
297 | int m_ialloc_blks; /* blocks in inode allocation */ | 297 | int m_ialloc_blks; /* blocks in inode allocation */ |
298 | int m_litino; /* size of inode union area */ | 298 | int m_litino; /* size of inode union area */ |
299 | int m_inoalign_mask;/* mask sb_inoalignmt if used */ | 299 | int m_inoalign_mask;/* mask sb_inoalignmt if used */ |
300 | uint m_qflags; /* quota status flags */ | 300 | uint m_qflags; /* quota status flags */ |
301 | xfs_trans_reservations_t m_reservations;/* precomputed res values */ | 301 | xfs_trans_reservations_t m_reservations;/* precomputed res values */ |
302 | __uint64_t m_maxicount; /* maximum inode count */ | 302 | __uint64_t m_maxicount; /* maximum inode count */ |
303 | __uint64_t m_maxioffset; /* maximum inode offset */ | 303 | __uint64_t m_maxioffset; /* maximum inode offset */ |
304 | __uint64_t m_resblks; /* total reserved blocks */ | 304 | __uint64_t m_resblks; /* total reserved blocks */ |
305 | __uint64_t m_resblks_avail;/* available reserved blocks */ | 305 | __uint64_t m_resblks_avail;/* available reserved blocks */ |
306 | #if XFS_BIG_INUMS | 306 | #if XFS_BIG_INUMS |
307 | xfs_ino_t m_inoadd; /* add value for ino64_offset */ | 307 | xfs_ino_t m_inoadd; /* add value for ino64_offset */ |
308 | #endif | 308 | #endif |
309 | int m_dalign; /* stripe unit */ | 309 | int m_dalign; /* stripe unit */ |
310 | int m_swidth; /* stripe width */ | 310 | int m_swidth; /* stripe width */ |
311 | int m_sinoalign; /* stripe unit inode alignment */ | 311 | int m_sinoalign; /* stripe unit inode alignment */ |
312 | int m_attr_magicpct;/* 37% of the blocksize */ | 312 | int m_attr_magicpct;/* 37% of the blocksize */ |
313 | int m_dir_magicpct; /* 37% of the dir blocksize */ | 313 | int m_dir_magicpct; /* 37% of the dir blocksize */ |
314 | __uint8_t m_mk_sharedro; /* mark shared ro on unmount */ | 314 | __uint8_t m_mk_sharedro; /* mark shared ro on unmount */ |
315 | __uint8_t m_inode_quiesce;/* call quiesce on new inodes. | 315 | __uint8_t m_inode_quiesce;/* call quiesce on new inodes. |
316 | field governed by m_ilock */ | 316 | field governed by m_ilock */ |
317 | __uint8_t m_sectbb_log; /* sectlog - BBSHIFT */ | 317 | __uint8_t m_sectbb_log; /* sectlog - BBSHIFT */ |
318 | const struct xfs_nameops *m_dirnameops; /* vector of dir name ops */ | 318 | const struct xfs_nameops *m_dirnameops; /* vector of dir name ops */ |
319 | int m_dirblksize; /* directory block sz--bytes */ | 319 | int m_dirblksize; /* directory block sz--bytes */ |
320 | int m_dirblkfsbs; /* directory block sz--fsbs */ | 320 | int m_dirblkfsbs; /* directory block sz--fsbs */ |
321 | xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */ | 321 | xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */ |
322 | xfs_dablk_t m_dirleafblk; /* blockno of dir non-data v2 */ | 322 | xfs_dablk_t m_dirleafblk; /* blockno of dir non-data v2 */ |
323 | xfs_dablk_t m_dirfreeblk; /* blockno of dirfreeindex v2 */ | 323 | xfs_dablk_t m_dirfreeblk; /* blockno of dirfreeindex v2 */ |
324 | uint m_chsize; /* size of next field */ | 324 | uint m_chsize; /* size of next field */ |
325 | struct xfs_chash *m_chash; /* fs private inode per-cluster | 325 | struct xfs_chash *m_chash; /* fs private inode per-cluster |
326 | * hash table */ | 326 | * hash table */ |
327 | struct xfs_dmops *m_dm_ops; /* vector of DMI ops */ | 327 | struct xfs_dmops *m_dm_ops; /* vector of DMI ops */ |
328 | struct xfs_qmops *m_qm_ops; /* vector of XQM ops */ | 328 | struct xfs_qmops *m_qm_ops; /* vector of XQM ops */ |
329 | atomic_t m_active_trans; /* number trans frozen */ | 329 | atomic_t m_active_trans; /* number trans frozen */ |
330 | #ifdef HAVE_PERCPU_SB | 330 | #ifdef HAVE_PERCPU_SB |
331 | xfs_icsb_cnts_t *m_sb_cnts; /* per-cpu superblock counters */ | 331 | xfs_icsb_cnts_t *m_sb_cnts; /* per-cpu superblock counters */ |
332 | unsigned long m_icsb_counters; /* disabled per-cpu counters */ | 332 | unsigned long m_icsb_counters; /* disabled per-cpu counters */ |
333 | struct notifier_block m_icsb_notifier; /* hotplug cpu notifier */ | 333 | struct notifier_block m_icsb_notifier; /* hotplug cpu notifier */ |
334 | struct mutex m_icsb_mutex; /* balancer sync lock */ | 334 | struct mutex m_icsb_mutex; /* balancer sync lock */ |
335 | #endif | 335 | #endif |
336 | struct xfs_mru_cache *m_filestream; /* per-mount filestream data */ | 336 | struct xfs_mru_cache *m_filestream; /* per-mount filestream data */ |
337 | struct task_struct *m_sync_task; /* generalised sync thread */ | 337 | struct task_struct *m_sync_task; /* generalised sync thread */ |
338 | bhv_vfs_sync_work_t m_sync_work; /* work item for VFS_SYNC */ | 338 | bhv_vfs_sync_work_t m_sync_work; /* work item for VFS_SYNC */ |
339 | struct list_head m_sync_list; /* sync thread work item list */ | 339 | struct list_head m_sync_list; /* sync thread work item list */ |
340 | spinlock_t m_sync_lock; /* work item list lock */ | 340 | spinlock_t m_sync_lock; /* work item list lock */ |
341 | int m_sync_seq; /* sync thread generation no. */ | 341 | int m_sync_seq; /* sync thread generation no. */ |
342 | wait_queue_head_t m_wait_single_sync_task; | 342 | wait_queue_head_t m_wait_single_sync_task; |
343 | } xfs_mount_t; | 343 | } xfs_mount_t; |
344 | 344 | ||
345 | /* | 345 | /* |
346 | * Flags for m_flags. | 346 | * Flags for m_flags. |
347 | */ | 347 | */ |
348 | #define XFS_MOUNT_WSYNC (1ULL << 0) /* for nfs - all metadata ops | 348 | #define XFS_MOUNT_WSYNC (1ULL << 0) /* for nfs - all metadata ops |
349 | must be synchronous except | 349 | must be synchronous except |
350 | for space allocations */ | 350 | for space allocations */ |
351 | #define XFS_MOUNT_INO64 (1ULL << 1) | 351 | #define XFS_MOUNT_INO64 (1ULL << 1) |
352 | #define XFS_MOUNT_DMAPI (1ULL << 2) /* dmapi is enabled */ | 352 | #define XFS_MOUNT_DMAPI (1ULL << 2) /* dmapi is enabled */ |
353 | #define XFS_MOUNT_WAS_CLEAN (1ULL << 3) | 353 | #define XFS_MOUNT_WAS_CLEAN (1ULL << 3) |
354 | #define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem | 354 | #define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem |
355 | operations, typically for | 355 | operations, typically for |
356 | disk errors in metadata */ | 356 | disk errors in metadata */ |
357 | #define XFS_MOUNT_RETERR (1ULL << 6) /* return alignment errors to | 357 | #define XFS_MOUNT_RETERR (1ULL << 6) /* return alignment errors to |
358 | user */ | 358 | user */ |
359 | #define XFS_MOUNT_NOALIGN (1ULL << 7) /* turn off stripe alignment | 359 | #define XFS_MOUNT_NOALIGN (1ULL << 7) /* turn off stripe alignment |
360 | allocations */ | 360 | allocations */ |
361 | #define XFS_MOUNT_ATTR2 (1ULL << 8) /* allow use of attr2 format */ | 361 | #define XFS_MOUNT_ATTR2 (1ULL << 8) /* allow use of attr2 format */ |
362 | #define XFS_MOUNT_GRPID (1ULL << 9) /* group-ID assigned from directory */ | 362 | #define XFS_MOUNT_GRPID (1ULL << 9) /* group-ID assigned from directory */ |
363 | #define XFS_MOUNT_NORECOVERY (1ULL << 10) /* no recovery - dirty fs */ | 363 | #define XFS_MOUNT_NORECOVERY (1ULL << 10) /* no recovery - dirty fs */ |
364 | #define XFS_MOUNT_SHARED (1ULL << 11) /* shared mount */ | 364 | #define XFS_MOUNT_SHARED (1ULL << 11) /* shared mount */ |
365 | #define XFS_MOUNT_DFLT_IOSIZE (1ULL << 12) /* set default i/o size */ | 365 | #define XFS_MOUNT_DFLT_IOSIZE (1ULL << 12) /* set default i/o size */ |
366 | #define XFS_MOUNT_OSYNCISOSYNC (1ULL << 13) /* o_sync is REALLY o_sync */ | 366 | #define XFS_MOUNT_OSYNCISOSYNC (1ULL << 13) /* o_sync is REALLY o_sync */ |
367 | /* osyncisdsync is now default*/ | 367 | /* osyncisdsync is now default*/ |
368 | #define XFS_MOUNT_32BITINODES (1ULL << 14) /* do not create inodes above | 368 | #define XFS_MOUNT_32BITINODES (1ULL << 14) /* do not create inodes above |
369 | * 32 bits in size */ | 369 | * 32 bits in size */ |
370 | #define XFS_MOUNT_SMALL_INUMS (1ULL << 15) /* users wants 32bit inodes */ | 370 | #define XFS_MOUNT_SMALL_INUMS (1ULL << 15) /* users wants 32bit inodes */ |
371 | #define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */ | 371 | #define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */ |
372 | #define XFS_MOUNT_BARRIER (1ULL << 17) | 372 | #define XFS_MOUNT_BARRIER (1ULL << 17) |
373 | #define XFS_MOUNT_IKEEP (1ULL << 18) /* keep empty inode clusters*/ | 373 | #define XFS_MOUNT_IKEEP (1ULL << 18) /* keep empty inode clusters*/ |
374 | #define XFS_MOUNT_SWALLOC (1ULL << 19) /* turn on stripe width | 374 | #define XFS_MOUNT_SWALLOC (1ULL << 19) /* turn on stripe width |
375 | * allocation */ | 375 | * allocation */ |
376 | #define XFS_MOUNT_RDONLY (1ULL << 20) /* read-only fs */ | 376 | #define XFS_MOUNT_RDONLY (1ULL << 20) /* read-only fs */ |
377 | #define XFS_MOUNT_DIRSYNC (1ULL << 21) /* synchronous directory ops */ | 377 | #define XFS_MOUNT_DIRSYNC (1ULL << 21) /* synchronous directory ops */ |
378 | #define XFS_MOUNT_COMPAT_IOSIZE (1ULL << 22) /* don't report large preferred | 378 | #define XFS_MOUNT_COMPAT_IOSIZE (1ULL << 22) /* don't report large preferred |
379 | * I/O size in stat() */ | 379 | * I/O size in stat() */ |
380 | #define XFS_MOUNT_NO_PERCPU_SB (1ULL << 23) /* don't use per-cpu superblock | 380 | #define XFS_MOUNT_NO_PERCPU_SB (1ULL << 23) /* don't use per-cpu superblock |
381 | counters */ | 381 | counters */ |
382 | #define XFS_MOUNT_FILESTREAMS (1ULL << 24) /* enable the filestreams | 382 | #define XFS_MOUNT_FILESTREAMS (1ULL << 24) /* enable the filestreams |
383 | allocator */ | 383 | allocator */ |
384 | #define XFS_MOUNT_NOATTR2 (1ULL << 25) /* disable use of attr2 format */ | 384 | #define XFS_MOUNT_NOATTR2 (1ULL << 25) /* disable use of attr2 format */ |
385 | 385 | ||
386 | 386 | ||
387 | /* | 387 | /* |
388 | * Default minimum read and write sizes. | 388 | * Default minimum read and write sizes. |
389 | */ | 389 | */ |
390 | #define XFS_READIO_LOG_LARGE 16 | 390 | #define XFS_READIO_LOG_LARGE 16 |
391 | #define XFS_WRITEIO_LOG_LARGE 16 | 391 | #define XFS_WRITEIO_LOG_LARGE 16 |
392 | 392 | ||
393 | /* | 393 | /* |
394 | * Max and min values for mount-option defined I/O | 394 | * Max and min values for mount-option defined I/O |
395 | * preallocation sizes. | 395 | * preallocation sizes. |
396 | */ | 396 | */ |
397 | #define XFS_MAX_IO_LOG 30 /* 1G */ | 397 | #define XFS_MAX_IO_LOG 30 /* 1G */ |
398 | #define XFS_MIN_IO_LOG PAGE_SHIFT | 398 | #define XFS_MIN_IO_LOG PAGE_SHIFT |
399 | 399 | ||
400 | /* | 400 | /* |
401 | * Synchronous read and write sizes. This should be | 401 | * Synchronous read and write sizes. This should be |
402 | * better for NFSv2 wsync filesystems. | 402 | * better for NFSv2 wsync filesystems. |
403 | */ | 403 | */ |
404 | #define XFS_WSYNC_READIO_LOG 15 /* 32K */ | 404 | #define XFS_WSYNC_READIO_LOG 15 /* 32K */ |
405 | #define XFS_WSYNC_WRITEIO_LOG 14 /* 16K */ | 405 | #define XFS_WSYNC_WRITEIO_LOG 14 /* 16K */ |
406 | 406 | ||
407 | /* | 407 | /* |
408 | * Allow large block sizes to be reported to userspace programs if the | 408 | * Allow large block sizes to be reported to userspace programs if the |
409 | * "largeio" mount option is used. | 409 | * "largeio" mount option is used. |
410 | * | 410 | * |
411 | * If compatibility mode is specified, simply return the basic unit of caching | 411 | * If compatibility mode is specified, simply return the basic unit of caching |
412 | * so that we don't get inefficient read/modify/write I/O from user apps. | 412 | * so that we don't get inefficient read/modify/write I/O from user apps. |
413 | * Otherwise.... | 413 | * Otherwise.... |
414 | * | 414 | * |
415 | * If the underlying volume is a stripe, then return the stripe width in bytes | 415 | * If the underlying volume is a stripe, then return the stripe width in bytes |
416 | * as the recommended I/O size. It is not a stripe and we've set a default | 416 | * as the recommended I/O size. It is not a stripe and we've set a default |
417 | * buffered I/O size, return that, otherwise return the compat default. | 417 | * buffered I/O size, return that, otherwise return the compat default. |
418 | */ | 418 | */ |
419 | static inline unsigned long | 419 | static inline unsigned long |
420 | xfs_preferred_iosize(xfs_mount_t *mp) | 420 | xfs_preferred_iosize(xfs_mount_t *mp) |
421 | { | 421 | { |
422 | if (mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE) | 422 | if (mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE) |
423 | return PAGE_CACHE_SIZE; | 423 | return PAGE_CACHE_SIZE; |
424 | return (mp->m_swidth ? | 424 | return (mp->m_swidth ? |
425 | (mp->m_swidth << mp->m_sb.sb_blocklog) : | 425 | (mp->m_swidth << mp->m_sb.sb_blocklog) : |
426 | ((mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) ? | 426 | ((mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) ? |
427 | (1 << (int)MAX(mp->m_readio_log, mp->m_writeio_log)) : | 427 | (1 << (int)MAX(mp->m_readio_log, mp->m_writeio_log)) : |
428 | PAGE_CACHE_SIZE)); | 428 | PAGE_CACHE_SIZE)); |
429 | } | 429 | } |
430 | 430 | ||
431 | #define XFS_MAXIOFFSET(mp) ((mp)->m_maxioffset) | 431 | #define XFS_MAXIOFFSET(mp) ((mp)->m_maxioffset) |
432 | 432 | ||
433 | #define XFS_LAST_UNMOUNT_WAS_CLEAN(mp) \ | 433 | #define XFS_LAST_UNMOUNT_WAS_CLEAN(mp) \ |
434 | ((mp)->m_flags & XFS_MOUNT_WAS_CLEAN) | 434 | ((mp)->m_flags & XFS_MOUNT_WAS_CLEAN) |
435 | #define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN) | 435 | #define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN) |
436 | void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname, | 436 | void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname, |
437 | int lnnum); | 437 | int lnnum); |
438 | #define xfs_force_shutdown(m,f) \ | 438 | #define xfs_force_shutdown(m,f) \ |
439 | xfs_do_force_shutdown(m, f, __FILE__, __LINE__) | 439 | xfs_do_force_shutdown(m, f, __FILE__, __LINE__) |
440 | 440 | ||
441 | /* | 441 | /* |
442 | * Flags for xfs_mountfs | 442 | * Flags for xfs_mountfs |
443 | */ | 443 | */ |
444 | #define XFS_MFSI_QUIET 0x40 /* Be silent if mount errors found */ | 444 | #define XFS_MFSI_QUIET 0x40 /* Be silent if mount errors found */ |
445 | 445 | ||
446 | #define XFS_DADDR_TO_AGNO(mp,d) xfs_daddr_to_agno(mp,d) | 446 | #define XFS_DADDR_TO_AGNO(mp,d) xfs_daddr_to_agno(mp,d) |
447 | static inline xfs_agnumber_t | 447 | static inline xfs_agnumber_t |
448 | xfs_daddr_to_agno(struct xfs_mount *mp, xfs_daddr_t d) | 448 | xfs_daddr_to_agno(struct xfs_mount *mp, xfs_daddr_t d) |
449 | { | 449 | { |
450 | xfs_daddr_t ld = XFS_BB_TO_FSBT(mp, d); | 450 | xfs_daddr_t ld = XFS_BB_TO_FSBT(mp, d); |
451 | do_div(ld, mp->m_sb.sb_agblocks); | 451 | do_div(ld, mp->m_sb.sb_agblocks); |
452 | return (xfs_agnumber_t) ld; | 452 | return (xfs_agnumber_t) ld; |
453 | } | 453 | } |
454 | 454 | ||
455 | #define XFS_DADDR_TO_AGBNO(mp,d) xfs_daddr_to_agbno(mp,d) | 455 | #define XFS_DADDR_TO_AGBNO(mp,d) xfs_daddr_to_agbno(mp,d) |
456 | static inline xfs_agblock_t | 456 | static inline xfs_agblock_t |
457 | xfs_daddr_to_agbno(struct xfs_mount *mp, xfs_daddr_t d) | 457 | xfs_daddr_to_agbno(struct xfs_mount *mp, xfs_daddr_t d) |
458 | { | 458 | { |
459 | xfs_daddr_t ld = XFS_BB_TO_FSBT(mp, d); | 459 | xfs_daddr_t ld = XFS_BB_TO_FSBT(mp, d); |
460 | return (xfs_agblock_t) do_div(ld, mp->m_sb.sb_agblocks); | 460 | return (xfs_agblock_t) do_div(ld, mp->m_sb.sb_agblocks); |
461 | } | 461 | } |
462 | 462 | ||
463 | /* | 463 | /* |
464 | * perag get/put wrappers for eventual ref counting | 464 | * perag get/put wrappers for eventual ref counting |
465 | */ | 465 | */ |
466 | static inline xfs_perag_t * | 466 | static inline xfs_perag_t * |
467 | xfs_get_perag(struct xfs_mount *mp, xfs_ino_t ino) | 467 | xfs_get_perag(struct xfs_mount *mp, xfs_ino_t ino) |
468 | { | 468 | { |
469 | return &mp->m_perag[XFS_INO_TO_AGNO(mp, ino)]; | 469 | return &mp->m_perag[XFS_INO_TO_AGNO(mp, ino)]; |
470 | } | 470 | } |
471 | 471 | ||
472 | static inline void | 472 | static inline void |
473 | xfs_put_perag(struct xfs_mount *mp, xfs_perag_t *pag) | 473 | xfs_put_perag(struct xfs_mount *mp, xfs_perag_t *pag) |
474 | { | 474 | { |
475 | /* nothing to see here, move along */ | 475 | /* nothing to see here, move along */ |
476 | } | 476 | } |
477 | 477 | ||
478 | /* | 478 | /* |
479 | * Per-cpu superblock locking functions | 479 | * Per-cpu superblock locking functions |
480 | */ | 480 | */ |
481 | #ifdef HAVE_PERCPU_SB | 481 | #ifdef HAVE_PERCPU_SB |
482 | STATIC_INLINE void | 482 | STATIC_INLINE void |
483 | xfs_icsb_lock(xfs_mount_t *mp) | 483 | xfs_icsb_lock(xfs_mount_t *mp) |
484 | { | 484 | { |
485 | mutex_lock(&mp->m_icsb_mutex); | 485 | mutex_lock(&mp->m_icsb_mutex); |
486 | } | 486 | } |
487 | 487 | ||
488 | STATIC_INLINE void | 488 | STATIC_INLINE void |
489 | xfs_icsb_unlock(xfs_mount_t *mp) | 489 | xfs_icsb_unlock(xfs_mount_t *mp) |
490 | { | 490 | { |
491 | mutex_unlock(&mp->m_icsb_mutex); | 491 | mutex_unlock(&mp->m_icsb_mutex); |
492 | } | 492 | } |
493 | #else | 493 | #else |
494 | #define xfs_icsb_lock(mp) | 494 | #define xfs_icsb_lock(mp) |
495 | #define xfs_icsb_unlock(mp) | 495 | #define xfs_icsb_unlock(mp) |
496 | #endif | 496 | #endif |
497 | 497 | ||
498 | /* | 498 | /* |
499 | * This structure is for use by the xfs_mod_incore_sb_batch() routine. | 499 | * This structure is for use by the xfs_mod_incore_sb_batch() routine. |
500 | * xfs_growfs can specify a few fields which are more than int limit | 500 | * xfs_growfs can specify a few fields which are more than int limit |
501 | */ | 501 | */ |
502 | typedef struct xfs_mod_sb { | 502 | typedef struct xfs_mod_sb { |
503 | xfs_sb_field_t msb_field; /* Field to modify, see below */ | 503 | xfs_sb_field_t msb_field; /* Field to modify, see below */ |
504 | int64_t msb_delta; /* Change to make to specified field */ | 504 | int64_t msb_delta; /* Change to make to specified field */ |
505 | } xfs_mod_sb_t; | 505 | } xfs_mod_sb_t; |
506 | 506 | ||
507 | #define XFS_MOUNT_ILOCK(mp) mutex_lock(&((mp)->m_ilock)) | 507 | #define XFS_MOUNT_ILOCK(mp) mutex_lock(&((mp)->m_ilock)) |
508 | #define XFS_MOUNT_IUNLOCK(mp) mutex_unlock(&((mp)->m_ilock)) | 508 | #define XFS_MOUNT_IUNLOCK(mp) mutex_unlock(&((mp)->m_ilock)) |
509 | 509 | ||
510 | extern void xfs_mod_sb(xfs_trans_t *, __int64_t); | ||
511 | extern int xfs_log_sbcount(xfs_mount_t *, uint); | 510 | extern int xfs_log_sbcount(xfs_mount_t *, uint); |
512 | extern int xfs_mountfs(xfs_mount_t *mp); | 511 | extern int xfs_mountfs(xfs_mount_t *mp); |
513 | extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); | 512 | extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); |
514 | 513 | ||
515 | extern void xfs_unmountfs(xfs_mount_t *); | 514 | extern void xfs_unmountfs(xfs_mount_t *); |
516 | extern int xfs_unmountfs_writesb(xfs_mount_t *); | 515 | extern int xfs_unmountfs_writesb(xfs_mount_t *); |
517 | extern int xfs_unmount_flush(xfs_mount_t *, int); | 516 | extern int xfs_unmount_flush(xfs_mount_t *, int); |
518 | extern int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int64_t, int); | 517 | extern int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int64_t, int); |
519 | extern int xfs_mod_incore_sb_unlocked(xfs_mount_t *, xfs_sb_field_t, | 518 | extern int xfs_mod_incore_sb_unlocked(xfs_mount_t *, xfs_sb_field_t, |
520 | int64_t, int); | 519 | int64_t, int); |
521 | extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *, | 520 | extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *, |
522 | uint, int); | 521 | uint, int); |
523 | extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int); | 522 | extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int); |
524 | extern int xfs_readsb(xfs_mount_t *, int); | 523 | extern int xfs_readsb(xfs_mount_t *, int); |
525 | extern void xfs_freesb(xfs_mount_t *); | 524 | extern void xfs_freesb(xfs_mount_t *); |
526 | extern int xfs_fs_writable(xfs_mount_t *); | 525 | extern int xfs_fs_writable(xfs_mount_t *); |
527 | extern int xfs_syncsub(xfs_mount_t *, int, int *); | 526 | extern int xfs_syncsub(xfs_mount_t *, int, int *); |
528 | extern int xfs_sync_inodes(xfs_mount_t *, int, int *); | 527 | extern int xfs_sync_inodes(xfs_mount_t *, int, int *); |
529 | extern xfs_agnumber_t xfs_initialize_perag(xfs_mount_t *, xfs_agnumber_t); | ||
530 | extern void xfs_sb_from_disk(struct xfs_sb *, struct xfs_dsb *); | ||
531 | extern void xfs_sb_to_disk(struct xfs_dsb *, struct xfs_sb *, __int64_t); | ||
532 | extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t); | 528 | extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t); |
533 | 529 | ||
534 | extern int xfs_dmops_get(struct xfs_mount *, struct xfs_mount_args *); | 530 | extern int xfs_dmops_get(struct xfs_mount *, struct xfs_mount_args *); |
535 | extern void xfs_dmops_put(struct xfs_mount *); | 531 | extern void xfs_dmops_put(struct xfs_mount *); |
536 | extern int xfs_qmops_get(struct xfs_mount *, struct xfs_mount_args *); | 532 | extern int xfs_qmops_get(struct xfs_mount *, struct xfs_mount_args *); |
537 | extern void xfs_qmops_put(struct xfs_mount *); | 533 | extern void xfs_qmops_put(struct xfs_mount *); |
538 | 534 | ||
539 | extern struct xfs_dmops xfs_dmcore_xfs; | 535 | extern struct xfs_dmops xfs_dmcore_xfs; |
540 | 536 | ||
541 | #endif /* __KERNEL__ */ | 537 | #endif /* __KERNEL__ */ |
538 | |||
539 | extern void xfs_mod_sb(struct xfs_trans *, __int64_t); |
fs/xfs/xfs_trans.h
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License as | 6 | * modify it under the terms of the GNU General Public License as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | * | 8 | * |
9 | * This program is distributed in the hope that it would be useful, | 9 | * This program is distributed in the hope that it would be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. | 12 | * GNU General Public License for more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License | 14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write the Free Software Foundation, | 15 | * along with this program; if not, write the Free Software Foundation, |
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ | 17 | */ |
18 | #ifndef __XFS_TRANS_H__ | 18 | #ifndef __XFS_TRANS_H__ |
19 | #define __XFS_TRANS_H__ | 19 | #define __XFS_TRANS_H__ |
20 | 20 | ||
21 | struct xfs_log_item; | ||
22 | |||
21 | /* | 23 | /* |
22 | * This is the structure written in the log at the head of | 24 | * This is the structure written in the log at the head of |
23 | * every transaction. It identifies the type and id of the | 25 | * every transaction. It identifies the type and id of the |
24 | * transaction, and contains the number of items logged by | 26 | * transaction, and contains the number of items logged by |
25 | * the transaction so we know how many to expect during recovery. | 27 | * the transaction so we know how many to expect during recovery. |
26 | * | 28 | * |
27 | * Do not change the below structure without redoing the code in | 29 | * Do not change the below structure without redoing the code in |
28 | * xlog_recover_add_to_trans() and xlog_recover_add_to_cont_trans(). | 30 | * xlog_recover_add_to_trans() and xlog_recover_add_to_cont_trans(). |
29 | */ | 31 | */ |
30 | typedef struct xfs_trans_header { | 32 | typedef struct xfs_trans_header { |
31 | uint th_magic; /* magic number */ | 33 | uint th_magic; /* magic number */ |
32 | uint th_type; /* transaction type */ | 34 | uint th_type; /* transaction type */ |
33 | __int32_t th_tid; /* transaction id (unused) */ | 35 | __int32_t th_tid; /* transaction id (unused) */ |
34 | uint th_num_items; /* num items logged by trans */ | 36 | uint th_num_items; /* num items logged by trans */ |
35 | } xfs_trans_header_t; | 37 | } xfs_trans_header_t; |
36 | 38 | ||
37 | #define XFS_TRANS_HEADER_MAGIC 0x5452414e /* TRAN */ | 39 | #define XFS_TRANS_HEADER_MAGIC 0x5452414e /* TRAN */ |
38 | 40 | ||
39 | /* | 41 | /* |
40 | * Log item types. | 42 | * Log item types. |
41 | */ | 43 | */ |
42 | #define XFS_LI_EFI 0x1236 | 44 | #define XFS_LI_EFI 0x1236 |
43 | #define XFS_LI_EFD 0x1237 | 45 | #define XFS_LI_EFD 0x1237 |
44 | #define XFS_LI_IUNLINK 0x1238 | 46 | #define XFS_LI_IUNLINK 0x1238 |
45 | #define XFS_LI_INODE 0x123b /* aligned ino chunks, var-size ibufs */ | 47 | #define XFS_LI_INODE 0x123b /* aligned ino chunks, var-size ibufs */ |
46 | #define XFS_LI_BUF 0x123c /* v2 bufs, variable sized inode bufs */ | 48 | #define XFS_LI_BUF 0x123c /* v2 bufs, variable sized inode bufs */ |
47 | #define XFS_LI_DQUOT 0x123d | 49 | #define XFS_LI_DQUOT 0x123d |
48 | #define XFS_LI_QUOTAOFF 0x123e | 50 | #define XFS_LI_QUOTAOFF 0x123e |
49 | 51 | ||
50 | /* | 52 | /* |
51 | * Transaction types. Used to distinguish types of buffers. | 53 | * Transaction types. Used to distinguish types of buffers. |
52 | */ | 54 | */ |
53 | #define XFS_TRANS_SETATTR_NOT_SIZE 1 | 55 | #define XFS_TRANS_SETATTR_NOT_SIZE 1 |
54 | #define XFS_TRANS_SETATTR_SIZE 2 | 56 | #define XFS_TRANS_SETATTR_SIZE 2 |
55 | #define XFS_TRANS_INACTIVE 3 | 57 | #define XFS_TRANS_INACTIVE 3 |
56 | #define XFS_TRANS_CREATE 4 | 58 | #define XFS_TRANS_CREATE 4 |
57 | #define XFS_TRANS_CREATE_TRUNC 5 | 59 | #define XFS_TRANS_CREATE_TRUNC 5 |
58 | #define XFS_TRANS_TRUNCATE_FILE 6 | 60 | #define XFS_TRANS_TRUNCATE_FILE 6 |
59 | #define XFS_TRANS_REMOVE 7 | 61 | #define XFS_TRANS_REMOVE 7 |
60 | #define XFS_TRANS_LINK 8 | 62 | #define XFS_TRANS_LINK 8 |
61 | #define XFS_TRANS_RENAME 9 | 63 | #define XFS_TRANS_RENAME 9 |
62 | #define XFS_TRANS_MKDIR 10 | 64 | #define XFS_TRANS_MKDIR 10 |
63 | #define XFS_TRANS_RMDIR 11 | 65 | #define XFS_TRANS_RMDIR 11 |
64 | #define XFS_TRANS_SYMLINK 12 | 66 | #define XFS_TRANS_SYMLINK 12 |
65 | #define XFS_TRANS_SET_DMATTRS 13 | 67 | #define XFS_TRANS_SET_DMATTRS 13 |
66 | #define XFS_TRANS_GROWFS 14 | 68 | #define XFS_TRANS_GROWFS 14 |
67 | #define XFS_TRANS_STRAT_WRITE 15 | 69 | #define XFS_TRANS_STRAT_WRITE 15 |
68 | #define XFS_TRANS_DIOSTRAT 16 | 70 | #define XFS_TRANS_DIOSTRAT 16 |
69 | #define XFS_TRANS_WRITE_SYNC 17 | 71 | #define XFS_TRANS_WRITE_SYNC 17 |
70 | #define XFS_TRANS_WRITEID 18 | 72 | #define XFS_TRANS_WRITEID 18 |
71 | #define XFS_TRANS_ADDAFORK 19 | 73 | #define XFS_TRANS_ADDAFORK 19 |
72 | #define XFS_TRANS_ATTRINVAL 20 | 74 | #define XFS_TRANS_ATTRINVAL 20 |
73 | #define XFS_TRANS_ATRUNCATE 21 | 75 | #define XFS_TRANS_ATRUNCATE 21 |
74 | #define XFS_TRANS_ATTR_SET 22 | 76 | #define XFS_TRANS_ATTR_SET 22 |
75 | #define XFS_TRANS_ATTR_RM 23 | 77 | #define XFS_TRANS_ATTR_RM 23 |
76 | #define XFS_TRANS_ATTR_FLAG 24 | 78 | #define XFS_TRANS_ATTR_FLAG 24 |
77 | #define XFS_TRANS_CLEAR_AGI_BUCKET 25 | 79 | #define XFS_TRANS_CLEAR_AGI_BUCKET 25 |
78 | #define XFS_TRANS_QM_SBCHANGE 26 | 80 | #define XFS_TRANS_QM_SBCHANGE 26 |
79 | /* | 81 | /* |
80 | * Dummy entries since we use the transaction type to index into the | 82 | * Dummy entries since we use the transaction type to index into the |
81 | * trans_type[] in xlog_recover_print_trans_head() | 83 | * trans_type[] in xlog_recover_print_trans_head() |
82 | */ | 84 | */ |
83 | #define XFS_TRANS_DUMMY1 27 | 85 | #define XFS_TRANS_DUMMY1 27 |
84 | #define XFS_TRANS_DUMMY2 28 | 86 | #define XFS_TRANS_DUMMY2 28 |
85 | #define XFS_TRANS_QM_QUOTAOFF 29 | 87 | #define XFS_TRANS_QM_QUOTAOFF 29 |
86 | #define XFS_TRANS_QM_DQALLOC 30 | 88 | #define XFS_TRANS_QM_DQALLOC 30 |
87 | #define XFS_TRANS_QM_SETQLIM 31 | 89 | #define XFS_TRANS_QM_SETQLIM 31 |
88 | #define XFS_TRANS_QM_DQCLUSTER 32 | 90 | #define XFS_TRANS_QM_DQCLUSTER 32 |
89 | #define XFS_TRANS_QM_QINOCREATE 33 | 91 | #define XFS_TRANS_QM_QINOCREATE 33 |
90 | #define XFS_TRANS_QM_QUOTAOFF_END 34 | 92 | #define XFS_TRANS_QM_QUOTAOFF_END 34 |
91 | #define XFS_TRANS_SB_UNIT 35 | 93 | #define XFS_TRANS_SB_UNIT 35 |
92 | #define XFS_TRANS_FSYNC_TS 36 | 94 | #define XFS_TRANS_FSYNC_TS 36 |
93 | #define XFS_TRANS_GROWFSRT_ALLOC 37 | 95 | #define XFS_TRANS_GROWFSRT_ALLOC 37 |
94 | #define XFS_TRANS_GROWFSRT_ZERO 38 | 96 | #define XFS_TRANS_GROWFSRT_ZERO 38 |
95 | #define XFS_TRANS_GROWFSRT_FREE 39 | 97 | #define XFS_TRANS_GROWFSRT_FREE 39 |
96 | #define XFS_TRANS_SWAPEXT 40 | 98 | #define XFS_TRANS_SWAPEXT 40 |
97 | #define XFS_TRANS_SB_COUNT 41 | 99 | #define XFS_TRANS_SB_COUNT 41 |
98 | #define XFS_TRANS_TYPE_MAX 41 | 100 | #define XFS_TRANS_TYPE_MAX 41 |
99 | /* new transaction types need to be reflected in xfs_logprint(8) */ | 101 | /* new transaction types need to be reflected in xfs_logprint(8) */ |
100 | 102 | ||
101 | |||
102 | #ifdef __KERNEL__ | ||
103 | struct xfs_buf; | ||
104 | struct xfs_buftarg; | ||
105 | struct xfs_efd_log_item; | ||
106 | struct xfs_efi_log_item; | ||
107 | struct xfs_inode; | ||
108 | struct xfs_item_ops; | ||
109 | struct xfs_log_iovec; | ||
110 | struct xfs_log_item; | ||
111 | struct xfs_log_item_desc; | ||
112 | struct xfs_mount; | ||
113 | struct xfs_trans; | ||
114 | struct xfs_dquot_acct; | ||
115 | |||
116 | typedef struct xfs_log_item { | ||
117 | struct list_head li_ail; /* AIL pointers */ | ||
118 | xfs_lsn_t li_lsn; /* last on-disk lsn */ | ||
119 | struct xfs_log_item_desc *li_desc; /* ptr to current desc*/ | ||
120 | struct xfs_mount *li_mountp; /* ptr to fs mount */ | ||
121 | uint li_type; /* item type */ | ||
122 | uint li_flags; /* misc flags */ | ||
123 | struct xfs_log_item *li_bio_list; /* buffer item list */ | ||
124 | void (*li_cb)(struct xfs_buf *, | ||
125 | struct xfs_log_item *); | ||
126 | /* buffer item iodone */ | ||
127 | /* callback func */ | ||
128 | struct xfs_item_ops *li_ops; /* function list */ | ||
129 | } xfs_log_item_t; | ||
130 | |||
131 | #define XFS_LI_IN_AIL 0x1 | ||
132 | #define XFS_LI_ABORTED 0x2 | ||
133 | |||
134 | typedef struct xfs_item_ops { | ||
135 | uint (*iop_size)(xfs_log_item_t *); | ||
136 | void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *); | ||
137 | void (*iop_pin)(xfs_log_item_t *); | ||
138 | void (*iop_unpin)(xfs_log_item_t *, int); | ||
139 | void (*iop_unpin_remove)(xfs_log_item_t *, struct xfs_trans *); | ||
140 | uint (*iop_trylock)(xfs_log_item_t *); | ||
141 | void (*iop_unlock)(xfs_log_item_t *); | ||
142 | xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t); | ||
143 | void (*iop_push)(xfs_log_item_t *); | ||
144 | void (*iop_pushbuf)(xfs_log_item_t *); | ||
145 | void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t); | ||
146 | } xfs_item_ops_t; | ||
147 | |||
148 | #define IOP_SIZE(ip) (*(ip)->li_ops->iop_size)(ip) | ||
149 | #define IOP_FORMAT(ip,vp) (*(ip)->li_ops->iop_format)(ip, vp) | ||
150 | #define IOP_PIN(ip) (*(ip)->li_ops->iop_pin)(ip) | ||
151 | #define IOP_UNPIN(ip, flags) (*(ip)->li_ops->iop_unpin)(ip, flags) | ||
152 | #define IOP_UNPIN_REMOVE(ip,tp) (*(ip)->li_ops->iop_unpin_remove)(ip, tp) | ||
153 | #define IOP_TRYLOCK(ip) (*(ip)->li_ops->iop_trylock)(ip) | ||
154 | #define IOP_UNLOCK(ip) (*(ip)->li_ops->iop_unlock)(ip) | ||
155 | #define IOP_COMMITTED(ip, lsn) (*(ip)->li_ops->iop_committed)(ip, lsn) | ||
156 | #define IOP_PUSH(ip) (*(ip)->li_ops->iop_push)(ip) | ||
157 | #define IOP_PUSHBUF(ip) (*(ip)->li_ops->iop_pushbuf)(ip) | ||
158 | #define IOP_COMMITTING(ip, lsn) (*(ip)->li_ops->iop_committing)(ip, lsn) | ||
159 | |||
160 | /* | 103 | /* |
161 | * Return values for the IOP_TRYLOCK() routines. | ||
162 | */ | ||
163 | #define XFS_ITEM_SUCCESS 0 | ||
164 | #define XFS_ITEM_PINNED 1 | ||
165 | #define XFS_ITEM_LOCKED 2 | ||
166 | #define XFS_ITEM_FLUSHING 3 | ||
167 | #define XFS_ITEM_PUSHBUF 4 | ||
168 | |||
169 | #endif /* __KERNEL__ */ | ||
170 | |||
171 | /* | ||
172 | * This structure is used to track log items associated with | 104 | * This structure is used to track log items associated with |
173 | * a transaction. It points to the log item and keeps some | 105 | * a transaction. It points to the log item and keeps some |
174 | * flags to track the state of the log item. It also tracks | 106 | * flags to track the state of the log item. It also tracks |
175 | * the amount of space needed to log the item it describes | 107 | * the amount of space needed to log the item it describes |
176 | * once we get to commit processing (see xfs_trans_commit()). | 108 | * once we get to commit processing (see xfs_trans_commit()). |
177 | */ | 109 | */ |
178 | typedef struct xfs_log_item_desc { | 110 | typedef struct xfs_log_item_desc { |
179 | xfs_log_item_t *lid_item; | 111 | struct xfs_log_item *lid_item; |
180 | ushort lid_size; | 112 | ushort lid_size; |
181 | unsigned char lid_flags; | 113 | unsigned char lid_flags; |
182 | unsigned char lid_index; | 114 | unsigned char lid_index; |
183 | } xfs_log_item_desc_t; | 115 | } xfs_log_item_desc_t; |
184 | 116 | ||
185 | #define XFS_LID_DIRTY 0x1 | 117 | #define XFS_LID_DIRTY 0x1 |
186 | #define XFS_LID_PINNED 0x2 | 118 | #define XFS_LID_PINNED 0x2 |
187 | #define XFS_LID_BUF_STALE 0x8 | 119 | #define XFS_LID_BUF_STALE 0x8 |
188 | 120 | ||
189 | /* | 121 | /* |
190 | * This structure is used to maintain a chunk list of log_item_desc | 122 | * This structure is used to maintain a chunk list of log_item_desc |
191 | * structures. The free field is a bitmask indicating which descriptors | 123 | * structures. The free field is a bitmask indicating which descriptors |
192 | * in this chunk's array are free. The unused field is the first value | 124 | * in this chunk's array are free. The unused field is the first value |
193 | * not used since this chunk was allocated. | 125 | * not used since this chunk was allocated. |
194 | */ | 126 | */ |
195 | #define XFS_LIC_NUM_SLOTS 15 | 127 | #define XFS_LIC_NUM_SLOTS 15 |
196 | typedef struct xfs_log_item_chunk { | 128 | typedef struct xfs_log_item_chunk { |
197 | struct xfs_log_item_chunk *lic_next; | 129 | struct xfs_log_item_chunk *lic_next; |
198 | ushort lic_free; | 130 | ushort lic_free; |
199 | ushort lic_unused; | 131 | ushort lic_unused; |
200 | xfs_log_item_desc_t lic_descs[XFS_LIC_NUM_SLOTS]; | 132 | xfs_log_item_desc_t lic_descs[XFS_LIC_NUM_SLOTS]; |
201 | } xfs_log_item_chunk_t; | 133 | } xfs_log_item_chunk_t; |
202 | 134 | ||
203 | #define XFS_LIC_MAX_SLOT (XFS_LIC_NUM_SLOTS - 1) | 135 | #define XFS_LIC_MAX_SLOT (XFS_LIC_NUM_SLOTS - 1) |
204 | #define XFS_LIC_FREEMASK ((1 << XFS_LIC_NUM_SLOTS) - 1) | 136 | #define XFS_LIC_FREEMASK ((1 << XFS_LIC_NUM_SLOTS) - 1) |
205 | 137 | ||
206 | 138 | ||
207 | /* | 139 | /* |
208 | * Initialize the given chunk. Set the chunk's free descriptor mask | 140 | * Initialize the given chunk. Set the chunk's free descriptor mask |
209 | * to indicate that all descriptors are free. The caller gets to set | 141 | * to indicate that all descriptors are free. The caller gets to set |
210 | * lic_unused to the right value (0 matches all free). The | 142 | * lic_unused to the right value (0 matches all free). The |
211 | * lic_descs.lid_index values are set up as each desc is allocated. | 143 | * lic_descs.lid_index values are set up as each desc is allocated. |
212 | */ | 144 | */ |
213 | static inline void xfs_lic_init(xfs_log_item_chunk_t *cp) | 145 | static inline void xfs_lic_init(xfs_log_item_chunk_t *cp) |
214 | { | 146 | { |
215 | cp->lic_free = XFS_LIC_FREEMASK; | 147 | cp->lic_free = XFS_LIC_FREEMASK; |
216 | } | 148 | } |
217 | 149 | ||
218 | static inline void xfs_lic_init_slot(xfs_log_item_chunk_t *cp, int slot) | 150 | static inline void xfs_lic_init_slot(xfs_log_item_chunk_t *cp, int slot) |
219 | { | 151 | { |
220 | cp->lic_descs[slot].lid_index = (unsigned char)(slot); | 152 | cp->lic_descs[slot].lid_index = (unsigned char)(slot); |
221 | } | 153 | } |
222 | 154 | ||
223 | static inline int xfs_lic_vacancy(xfs_log_item_chunk_t *cp) | 155 | static inline int xfs_lic_vacancy(xfs_log_item_chunk_t *cp) |
224 | { | 156 | { |
225 | return cp->lic_free & XFS_LIC_FREEMASK; | 157 | return cp->lic_free & XFS_LIC_FREEMASK; |
226 | } | 158 | } |
227 | 159 | ||
228 | static inline void xfs_lic_all_free(xfs_log_item_chunk_t *cp) | 160 | static inline void xfs_lic_all_free(xfs_log_item_chunk_t *cp) |
229 | { | 161 | { |
230 | cp->lic_free = XFS_LIC_FREEMASK; | 162 | cp->lic_free = XFS_LIC_FREEMASK; |
231 | } | 163 | } |
232 | 164 | ||
233 | static inline int xfs_lic_are_all_free(xfs_log_item_chunk_t *cp) | 165 | static inline int xfs_lic_are_all_free(xfs_log_item_chunk_t *cp) |
234 | { | 166 | { |
235 | return ((cp->lic_free & XFS_LIC_FREEMASK) == XFS_LIC_FREEMASK); | 167 | return ((cp->lic_free & XFS_LIC_FREEMASK) == XFS_LIC_FREEMASK); |
236 | } | 168 | } |
237 | 169 | ||
238 | static inline int xfs_lic_isfree(xfs_log_item_chunk_t *cp, int slot) | 170 | static inline int xfs_lic_isfree(xfs_log_item_chunk_t *cp, int slot) |
239 | { | 171 | { |
240 | return (cp->lic_free & (1 << slot)); | 172 | return (cp->lic_free & (1 << slot)); |
241 | } | 173 | } |
242 | 174 | ||
243 | static inline void xfs_lic_claim(xfs_log_item_chunk_t *cp, int slot) | 175 | static inline void xfs_lic_claim(xfs_log_item_chunk_t *cp, int slot) |
244 | { | 176 | { |
245 | cp->lic_free &= ~(1 << slot); | 177 | cp->lic_free &= ~(1 << slot); |
246 | } | 178 | } |
247 | 179 | ||
248 | static inline void xfs_lic_relse(xfs_log_item_chunk_t *cp, int slot) | 180 | static inline void xfs_lic_relse(xfs_log_item_chunk_t *cp, int slot) |
249 | { | 181 | { |
250 | cp->lic_free |= 1 << slot; | 182 | cp->lic_free |= 1 << slot; |
251 | } | 183 | } |
252 | 184 | ||
253 | static inline xfs_log_item_desc_t * | 185 | static inline xfs_log_item_desc_t * |
254 | xfs_lic_slot(xfs_log_item_chunk_t *cp, int slot) | 186 | xfs_lic_slot(xfs_log_item_chunk_t *cp, int slot) |
255 | { | 187 | { |
256 | return &(cp->lic_descs[slot]); | 188 | return &(cp->lic_descs[slot]); |
257 | } | 189 | } |
258 | 190 | ||
259 | static inline int xfs_lic_desc_to_slot(xfs_log_item_desc_t *dp) | 191 | static inline int xfs_lic_desc_to_slot(xfs_log_item_desc_t *dp) |
260 | { | 192 | { |
261 | return (uint)dp->lid_index; | 193 | return (uint)dp->lid_index; |
262 | } | 194 | } |
263 | 195 | ||
264 | /* | 196 | /* |
265 | * Calculate the address of a chunk given a descriptor pointer: | 197 | * Calculate the address of a chunk given a descriptor pointer: |
266 | * dp - dp->lid_index give the address of the start of the lic_descs array. | 198 | * dp - dp->lid_index give the address of the start of the lic_descs array. |
267 | * From this we subtract the offset of the lic_descs field in a chunk. | 199 | * From this we subtract the offset of the lic_descs field in a chunk. |
268 | * All of this yields the address of the chunk, which is | 200 | * All of this yields the address of the chunk, which is |
269 | * cast to a chunk pointer. | 201 | * cast to a chunk pointer. |
270 | */ | 202 | */ |
271 | static inline xfs_log_item_chunk_t * | 203 | static inline xfs_log_item_chunk_t * |
272 | xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp) | 204 | xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp) |
273 | { | 205 | { |
274 | return (xfs_log_item_chunk_t*) \ | 206 | return (xfs_log_item_chunk_t*) \ |
275 | (((xfs_caddr_t)((dp) - (dp)->lid_index)) - \ | 207 | (((xfs_caddr_t)((dp) - (dp)->lid_index)) - \ |
276 | (xfs_caddr_t)(((xfs_log_item_chunk_t*)0)->lic_descs)); | 208 | (xfs_caddr_t)(((xfs_log_item_chunk_t*)0)->lic_descs)); |
277 | } | 209 | } |
278 | 210 | ||
279 | #ifdef __KERNEL__ | ||
280 | /* | ||
281 | * This structure is used to maintain a list of block ranges that have been | ||
282 | * freed in the transaction. The ranges are listed in the perag[] busy list | ||
283 | * between when they're freed and the transaction is committed to disk. | ||
284 | */ | ||
285 | |||
286 | typedef struct xfs_log_busy_slot { | ||
287 | xfs_agnumber_t lbc_ag; | ||
288 | ushort lbc_idx; /* index in perag.busy[] */ | ||
289 | } xfs_log_busy_slot_t; | ||
290 | |||
291 | #define XFS_LBC_NUM_SLOTS 31 | ||
292 | typedef struct xfs_log_busy_chunk { | ||
293 | struct xfs_log_busy_chunk *lbc_next; | ||
294 | uint lbc_free; /* free slots bitmask */ | ||
295 | ushort lbc_unused; /* first unused */ | ||
296 | xfs_log_busy_slot_t lbc_busy[XFS_LBC_NUM_SLOTS]; | ||
297 | } xfs_log_busy_chunk_t; | ||
298 | |||
299 | #define XFS_LBC_MAX_SLOT (XFS_LBC_NUM_SLOTS - 1) | ||
300 | #define XFS_LBC_FREEMASK ((1U << XFS_LBC_NUM_SLOTS) - 1) | ||
301 | |||
302 | #define XFS_LBC_INIT(cp) ((cp)->lbc_free = XFS_LBC_FREEMASK) | ||
303 | #define XFS_LBC_CLAIM(cp, slot) ((cp)->lbc_free &= ~(1 << (slot))) | ||
304 | #define XFS_LBC_SLOT(cp, slot) (&((cp)->lbc_busy[(slot)])) | ||
305 | #define XFS_LBC_VACANCY(cp) (((cp)->lbc_free) & XFS_LBC_FREEMASK) | ||
306 | #define XFS_LBC_ISFREE(cp, slot) ((cp)->lbc_free & (1 << (slot))) | ||
307 | |||
308 | /* | ||
309 | * This is the type of function which can be given to xfs_trans_callback() | ||
310 | * to be called upon the transaction's commit to disk. | ||
311 | */ | ||
312 | typedef void (*xfs_trans_callback_t)(struct xfs_trans *, void *); | ||
313 | |||
314 | /* | ||
315 | * This is the structure maintained for every active transaction. | ||
316 | */ | ||
317 | typedef struct xfs_trans { | ||
318 | unsigned int t_magic; /* magic number */ | ||
319 | xfs_log_callback_t t_logcb; /* log callback struct */ | ||
320 | unsigned int t_type; /* transaction type */ | ||
321 | unsigned int t_log_res; /* amt of log space resvd */ | ||
322 | unsigned int t_log_count; /* count for perm log res */ | ||
323 | unsigned int t_blk_res; /* # of blocks resvd */ | ||
324 | unsigned int t_blk_res_used; /* # of resvd blocks used */ | ||
325 | unsigned int t_rtx_res; /* # of rt extents resvd */ | ||
326 | unsigned int t_rtx_res_used; /* # of resvd rt extents used */ | ||
327 | xfs_log_ticket_t t_ticket; /* log mgr ticket */ | ||
328 | xfs_lsn_t t_lsn; /* log seq num of start of | ||
329 | * transaction. */ | ||
330 | xfs_lsn_t t_commit_lsn; /* log seq num of end of | ||
331 | * transaction. */ | ||
332 | struct xfs_mount *t_mountp; /* ptr to fs mount struct */ | ||
333 | struct xfs_dquot_acct *t_dqinfo; /* acctg info for dquots */ | ||
334 | xfs_trans_callback_t t_callback; /* transaction callback */ | ||
335 | void *t_callarg; /* callback arg */ | ||
336 | unsigned int t_flags; /* misc flags */ | ||
337 | int64_t t_icount_delta; /* superblock icount change */ | ||
338 | int64_t t_ifree_delta; /* superblock ifree change */ | ||
339 | int64_t t_fdblocks_delta; /* superblock fdblocks chg */ | ||
340 | int64_t t_res_fdblocks_delta; /* on-disk only chg */ | ||
341 | int64_t t_frextents_delta;/* superblock freextents chg*/ | ||
342 | int64_t t_res_frextents_delta; /* on-disk only chg */ | ||
343 | #ifdef DEBUG | ||
344 | int64_t t_ag_freeblks_delta; /* debugging counter */ | ||
345 | int64_t t_ag_flist_delta; /* debugging counter */ | ||
346 | int64_t t_ag_btree_delta; /* debugging counter */ | ||
347 | #endif | ||
348 | int64_t t_dblocks_delta;/* superblock dblocks change */ | ||
349 | int64_t t_agcount_delta;/* superblock agcount change */ | ||
350 | int64_t t_imaxpct_delta;/* superblock imaxpct change */ | ||
351 | int64_t t_rextsize_delta;/* superblock rextsize chg */ | ||
352 | int64_t t_rbmblocks_delta;/* superblock rbmblocks chg */ | ||
353 | int64_t t_rblocks_delta;/* superblock rblocks change */ | ||
354 | int64_t t_rextents_delta;/* superblocks rextents chg */ | ||
355 | int64_t t_rextslog_delta;/* superblocks rextslog chg */ | ||
356 | unsigned int t_items_free; /* log item descs free */ | ||
357 | xfs_log_item_chunk_t t_items; /* first log item desc chunk */ | ||
358 | xfs_trans_header_t t_header; /* header for in-log trans */ | ||
359 | unsigned int t_busy_free; /* busy descs free */ | ||
360 | xfs_log_busy_chunk_t t_busy; /* busy/async free blocks */ | ||
361 | unsigned long t_pflags; /* saved process flags state */ | ||
362 | } xfs_trans_t; | ||
363 | |||
364 | #endif /* __KERNEL__ */ | ||
365 | |||
366 | |||
367 | #define XFS_TRANS_MAGIC 0x5452414E /* 'TRAN' */ | 211 | #define XFS_TRANS_MAGIC 0x5452414E /* 'TRAN' */ |
368 | /* | 212 | /* |
369 | * Values for t_flags. | 213 | * Values for t_flags. |
370 | */ | 214 | */ |
371 | #define XFS_TRANS_DIRTY 0x01 /* something needs to be logged */ | 215 | #define XFS_TRANS_DIRTY 0x01 /* something needs to be logged */ |
372 | #define XFS_TRANS_SB_DIRTY 0x02 /* superblock is modified */ | 216 | #define XFS_TRANS_SB_DIRTY 0x02 /* superblock is modified */ |
373 | #define XFS_TRANS_PERM_LOG_RES 0x04 /* xact took a permanent log res */ | 217 | #define XFS_TRANS_PERM_LOG_RES 0x04 /* xact took a permanent log res */ |
374 | #define XFS_TRANS_SYNC 0x08 /* make commit synchronous */ | 218 | #define XFS_TRANS_SYNC 0x08 /* make commit synchronous */ |
375 | #define XFS_TRANS_DQ_DIRTY 0x10 /* at least one dquot in trx dirty */ | 219 | #define XFS_TRANS_DQ_DIRTY 0x10 /* at least one dquot in trx dirty */ |
376 | #define XFS_TRANS_RESERVE 0x20 /* OK to use reserved data blocks */ | 220 | #define XFS_TRANS_RESERVE 0x20 /* OK to use reserved data blocks */ |
377 | 221 | ||
378 | /* | 222 | /* |
379 | * Values for call flags parameter. | 223 | * Values for call flags parameter. |
380 | */ | 224 | */ |
381 | #define XFS_TRANS_NOSLEEP 0x1 | 225 | #define XFS_TRANS_NOSLEEP 0x1 |
382 | #define XFS_TRANS_WAIT 0x2 | 226 | #define XFS_TRANS_WAIT 0x2 |
383 | #define XFS_TRANS_RELEASE_LOG_RES 0x4 | 227 | #define XFS_TRANS_RELEASE_LOG_RES 0x4 |
384 | #define XFS_TRANS_ABORT 0x8 | 228 | #define XFS_TRANS_ABORT 0x8 |
385 | 229 | ||
386 | /* | 230 | /* |
387 | * Field values for xfs_trans_mod_sb. | 231 | * Field values for xfs_trans_mod_sb. |
388 | */ | 232 | */ |
389 | #define XFS_TRANS_SB_ICOUNT 0x00000001 | 233 | #define XFS_TRANS_SB_ICOUNT 0x00000001 |
390 | #define XFS_TRANS_SB_IFREE 0x00000002 | 234 | #define XFS_TRANS_SB_IFREE 0x00000002 |
391 | #define XFS_TRANS_SB_FDBLOCKS 0x00000004 | 235 | #define XFS_TRANS_SB_FDBLOCKS 0x00000004 |
392 | #define XFS_TRANS_SB_RES_FDBLOCKS 0x00000008 | 236 | #define XFS_TRANS_SB_RES_FDBLOCKS 0x00000008 |
393 | #define XFS_TRANS_SB_FREXTENTS 0x00000010 | 237 | #define XFS_TRANS_SB_FREXTENTS 0x00000010 |
394 | #define XFS_TRANS_SB_RES_FREXTENTS 0x00000020 | 238 | #define XFS_TRANS_SB_RES_FREXTENTS 0x00000020 |
395 | #define XFS_TRANS_SB_DBLOCKS 0x00000040 | 239 | #define XFS_TRANS_SB_DBLOCKS 0x00000040 |
396 | #define XFS_TRANS_SB_AGCOUNT 0x00000080 | 240 | #define XFS_TRANS_SB_AGCOUNT 0x00000080 |
397 | #define XFS_TRANS_SB_IMAXPCT 0x00000100 | 241 | #define XFS_TRANS_SB_IMAXPCT 0x00000100 |
398 | #define XFS_TRANS_SB_REXTSIZE 0x00000200 | 242 | #define XFS_TRANS_SB_REXTSIZE 0x00000200 |
399 | #define XFS_TRANS_SB_RBMBLOCKS 0x00000400 | 243 | #define XFS_TRANS_SB_RBMBLOCKS 0x00000400 |
400 | #define XFS_TRANS_SB_RBLOCKS 0x00000800 | 244 | #define XFS_TRANS_SB_RBLOCKS 0x00000800 |
401 | #define XFS_TRANS_SB_REXTENTS 0x00001000 | 245 | #define XFS_TRANS_SB_REXTENTS 0x00001000 |
402 | #define XFS_TRANS_SB_REXTSLOG 0x00002000 | 246 | #define XFS_TRANS_SB_REXTSLOG 0x00002000 |
403 | 247 | ||
404 | 248 | ||
405 | /* | 249 | /* |
406 | * Various log reservation values. | 250 | * Various log reservation values. |
407 | * These are based on the size of the file system block | 251 | * These are based on the size of the file system block |
408 | * because that is what most transactions manipulate. | 252 | * because that is what most transactions manipulate. |
409 | * Each adds in an additional 128 bytes per item logged to | 253 | * Each adds in an additional 128 bytes per item logged to |
410 | * try to account for the overhead of the transaction mechanism. | 254 | * try to account for the overhead of the transaction mechanism. |
411 | * | 255 | * |
412 | * Note: | 256 | * Note: |
413 | * Most of the reservations underestimate the number of allocation | 257 | * Most of the reservations underestimate the number of allocation |
414 | * groups into which they could free extents in the xfs_bmap_finish() | 258 | * groups into which they could free extents in the xfs_bmap_finish() |
415 | * call. This is because the number in the worst case is quite high | 259 | * call. This is because the number in the worst case is quite high |
416 | * and quite unusual. In order to fix this we need to change | 260 | * and quite unusual. In order to fix this we need to change |
417 | * xfs_bmap_finish() to free extents in only a single AG at a time. | 261 | * xfs_bmap_finish() to free extents in only a single AG at a time. |
418 | * This will require changes to the EFI code as well, however, so that | 262 | * This will require changes to the EFI code as well, however, so that |
419 | * the EFI for the extents not freed is logged again in each transaction. | 263 | * the EFI for the extents not freed is logged again in each transaction. |
420 | * See bug 261917. | 264 | * See bug 261917. |
421 | */ | 265 | */ |
422 | 266 | ||
423 | /* | 267 | /* |
424 | * Per-extent log reservation for the allocation btree changes | 268 | * Per-extent log reservation for the allocation btree changes |
425 | * involved in freeing or allocating an extent. | 269 | * involved in freeing or allocating an extent. |
426 | * 2 trees * (2 blocks/level * max depth - 1) * block size | 270 | * 2 trees * (2 blocks/level * max depth - 1) * block size |
427 | */ | 271 | */ |
428 | #define XFS_ALLOCFREE_LOG_RES(mp,nx) \ | 272 | #define XFS_ALLOCFREE_LOG_RES(mp,nx) \ |
429 | ((nx) * (2 * XFS_FSB_TO_B((mp), 2 * XFS_AG_MAXLEVELS(mp) - 1))) | 273 | ((nx) * (2 * XFS_FSB_TO_B((mp), 2 * XFS_AG_MAXLEVELS(mp) - 1))) |
430 | #define XFS_ALLOCFREE_LOG_COUNT(mp,nx) \ | 274 | #define XFS_ALLOCFREE_LOG_COUNT(mp,nx) \ |
431 | ((nx) * (2 * (2 * XFS_AG_MAXLEVELS(mp) - 1))) | 275 | ((nx) * (2 * (2 * XFS_AG_MAXLEVELS(mp) - 1))) |
432 | 276 | ||
433 | /* | 277 | /* |
434 | * Per-directory log reservation for any directory change. | 278 | * Per-directory log reservation for any directory change. |
435 | * dir blocks: (1 btree block per level + data block + free block) * dblock size | 279 | * dir blocks: (1 btree block per level + data block + free block) * dblock size |
436 | * bmap btree: (levels + 2) * max depth * block size | 280 | * bmap btree: (levels + 2) * max depth * block size |
437 | * v2 directory blocks can be fragmented below the dirblksize down to the fsb | 281 | * v2 directory blocks can be fragmented below the dirblksize down to the fsb |
438 | * size, so account for that in the DAENTER macros. | 282 | * size, so account for that in the DAENTER macros. |
439 | */ | 283 | */ |
440 | #define XFS_DIROP_LOG_RES(mp) \ | 284 | #define XFS_DIROP_LOG_RES(mp) \ |
441 | (XFS_FSB_TO_B(mp, XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK)) + \ | 285 | (XFS_FSB_TO_B(mp, XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK)) + \ |
442 | (XFS_FSB_TO_B(mp, XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1))) | 286 | (XFS_FSB_TO_B(mp, XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1))) |
443 | #define XFS_DIROP_LOG_COUNT(mp) \ | 287 | #define XFS_DIROP_LOG_COUNT(mp) \ |
444 | (XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK) + \ | 288 | (XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK) + \ |
445 | XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1) | 289 | XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1) |
446 | 290 | ||
447 | /* | 291 | /* |
448 | * In a write transaction we can allocate a maximum of 2 | 292 | * In a write transaction we can allocate a maximum of 2 |
449 | * extents. This gives: | 293 | * extents. This gives: |
450 | * the inode getting the new extents: inode size | 294 | * the inode getting the new extents: inode size |
451 | * the inode\'s bmap btree: max depth * block size | 295 | * the inode\'s bmap btree: max depth * block size |
452 | * the agfs of the ags from which the extents are allocated: 2 * sector | 296 | * the agfs of the ags from which the extents are allocated: 2 * sector |
453 | * the superblock free block counter: sector size | 297 | * the superblock free block counter: sector size |
454 | * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size | 298 | * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size |
455 | * And the bmap_finish transaction can free bmap blocks in a join: | 299 | * And the bmap_finish transaction can free bmap blocks in a join: |
456 | * the agfs of the ags containing the blocks: 2 * sector size | 300 | * the agfs of the ags containing the blocks: 2 * sector size |
457 | * the agfls of the ags containing the blocks: 2 * sector size | 301 | * the agfls of the ags containing the blocks: 2 * sector size |
458 | * the super block free block counter: sector size | 302 | * the super block free block counter: sector size |
459 | * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size | 303 | * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size |
460 | */ | 304 | */ |
461 | #define XFS_CALC_WRITE_LOG_RES(mp) \ | 305 | #define XFS_CALC_WRITE_LOG_RES(mp) \ |
462 | (MAX( \ | 306 | (MAX( \ |
463 | ((mp)->m_sb.sb_inodesize + \ | 307 | ((mp)->m_sb.sb_inodesize + \ |
464 | XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) + \ | 308 | XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) + \ |
465 | (2 * (mp)->m_sb.sb_sectsize) + \ | 309 | (2 * (mp)->m_sb.sb_sectsize) + \ |
466 | (mp)->m_sb.sb_sectsize + \ | 310 | (mp)->m_sb.sb_sectsize + \ |
467 | XFS_ALLOCFREE_LOG_RES(mp, 2) + \ | 311 | XFS_ALLOCFREE_LOG_RES(mp, 2) + \ |
468 | (128 * (4 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))),\ | 312 | (128 * (4 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))),\ |
469 | ((2 * (mp)->m_sb.sb_sectsize) + \ | 313 | ((2 * (mp)->m_sb.sb_sectsize) + \ |
470 | (2 * (mp)->m_sb.sb_sectsize) + \ | 314 | (2 * (mp)->m_sb.sb_sectsize) + \ |
471 | (mp)->m_sb.sb_sectsize + \ | 315 | (mp)->m_sb.sb_sectsize + \ |
472 | XFS_ALLOCFREE_LOG_RES(mp, 2) + \ | 316 | XFS_ALLOCFREE_LOG_RES(mp, 2) + \ |
473 | (128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))))) | 317 | (128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))))) |
474 | 318 | ||
475 | #define XFS_WRITE_LOG_RES(mp) ((mp)->m_reservations.tr_write) | 319 | #define XFS_WRITE_LOG_RES(mp) ((mp)->m_reservations.tr_write) |
476 | 320 | ||
477 | /* | 321 | /* |
478 | * In truncating a file we free up to two extents at once. We can modify: | 322 | * In truncating a file we free up to two extents at once. We can modify: |
479 | * the inode being truncated: inode size | 323 | * the inode being truncated: inode size |
480 | * the inode\'s bmap btree: (max depth + 1) * block size | 324 | * the inode\'s bmap btree: (max depth + 1) * block size |
481 | * And the bmap_finish transaction can free the blocks and bmap blocks: | 325 | * And the bmap_finish transaction can free the blocks and bmap blocks: |
482 | * the agf for each of the ags: 4 * sector size | 326 | * the agf for each of the ags: 4 * sector size |
483 | * the agfl for each of the ags: 4 * sector size | 327 | * the agfl for each of the ags: 4 * sector size |
484 | * the super block to reflect the freed blocks: sector size | 328 | * the super block to reflect the freed blocks: sector size |
485 | * worst case split in allocation btrees per extent assuming 4 extents: | 329 | * worst case split in allocation btrees per extent assuming 4 extents: |
486 | * 4 exts * 2 trees * (2 * max depth - 1) * block size | 330 | * 4 exts * 2 trees * (2 * max depth - 1) * block size |
487 | * the inode btree: max depth * blocksize | 331 | * the inode btree: max depth * blocksize |
488 | * the allocation btrees: 2 trees * (max depth - 1) * block size | 332 | * the allocation btrees: 2 trees * (max depth - 1) * block size |
489 | */ | 333 | */ |
490 | #define XFS_CALC_ITRUNCATE_LOG_RES(mp) \ | 334 | #define XFS_CALC_ITRUNCATE_LOG_RES(mp) \ |
491 | (MAX( \ | 335 | (MAX( \ |
492 | ((mp)->m_sb.sb_inodesize + \ | 336 | ((mp)->m_sb.sb_inodesize + \ |
493 | XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1) + \ | 337 | XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1) + \ |
494 | (128 * (2 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)))), \ | 338 | (128 * (2 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)))), \ |
495 | ((4 * (mp)->m_sb.sb_sectsize) + \ | 339 | ((4 * (mp)->m_sb.sb_sectsize) + \ |
496 | (4 * (mp)->m_sb.sb_sectsize) + \ | 340 | (4 * (mp)->m_sb.sb_sectsize) + \ |
497 | (mp)->m_sb.sb_sectsize + \ | 341 | (mp)->m_sb.sb_sectsize + \ |
498 | XFS_ALLOCFREE_LOG_RES(mp, 4) + \ | 342 | XFS_ALLOCFREE_LOG_RES(mp, 4) + \ |
499 | (128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4))) + \ | 343 | (128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4))) + \ |
500 | (128 * 5) + \ | 344 | (128 * 5) + \ |
501 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ | 345 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ |
502 | (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \ | 346 | (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \ |
503 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))))) | 347 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))))) |
504 | 348 | ||
505 | #define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate) | 349 | #define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate) |
506 | 350 | ||
507 | /* | 351 | /* |
508 | * In renaming a files we can modify: | 352 | * In renaming a files we can modify: |
509 | * the four inodes involved: 4 * inode size | 353 | * the four inodes involved: 4 * inode size |
510 | * the two directory btrees: 2 * (max depth + v2) * dir block size | 354 | * the two directory btrees: 2 * (max depth + v2) * dir block size |
511 | * the two directory bmap btrees: 2 * max depth * block size | 355 | * the two directory bmap btrees: 2 * max depth * block size |
512 | * And the bmap_finish transaction can free dir and bmap blocks (two sets | 356 | * And the bmap_finish transaction can free dir and bmap blocks (two sets |
513 | * of bmap blocks) giving: | 357 | * of bmap blocks) giving: |
514 | * the agf for the ags in which the blocks live: 3 * sector size | 358 | * the agf for the ags in which the blocks live: 3 * sector size |
515 | * the agfl for the ags in which the blocks live: 3 * sector size | 359 | * the agfl for the ags in which the blocks live: 3 * sector size |
516 | * the superblock for the free block count: sector size | 360 | * the superblock for the free block count: sector size |
517 | * the allocation btrees: 3 exts * 2 trees * (2 * max depth - 1) * block size | 361 | * the allocation btrees: 3 exts * 2 trees * (2 * max depth - 1) * block size |
518 | */ | 362 | */ |
519 | #define XFS_CALC_RENAME_LOG_RES(mp) \ | 363 | #define XFS_CALC_RENAME_LOG_RES(mp) \ |
520 | (MAX( \ | 364 | (MAX( \ |
521 | ((4 * (mp)->m_sb.sb_inodesize) + \ | 365 | ((4 * (mp)->m_sb.sb_inodesize) + \ |
522 | (2 * XFS_DIROP_LOG_RES(mp)) + \ | 366 | (2 * XFS_DIROP_LOG_RES(mp)) + \ |
523 | (128 * (4 + 2 * XFS_DIROP_LOG_COUNT(mp)))), \ | 367 | (128 * (4 + 2 * XFS_DIROP_LOG_COUNT(mp)))), \ |
524 | ((3 * (mp)->m_sb.sb_sectsize) + \ | 368 | ((3 * (mp)->m_sb.sb_sectsize) + \ |
525 | (3 * (mp)->m_sb.sb_sectsize) + \ | 369 | (3 * (mp)->m_sb.sb_sectsize) + \ |
526 | (mp)->m_sb.sb_sectsize + \ | 370 | (mp)->m_sb.sb_sectsize + \ |
527 | XFS_ALLOCFREE_LOG_RES(mp, 3) + \ | 371 | XFS_ALLOCFREE_LOG_RES(mp, 3) + \ |
528 | (128 * (7 + XFS_ALLOCFREE_LOG_COUNT(mp, 3)))))) | 372 | (128 * (7 + XFS_ALLOCFREE_LOG_COUNT(mp, 3)))))) |
529 | 373 | ||
530 | #define XFS_RENAME_LOG_RES(mp) ((mp)->m_reservations.tr_rename) | 374 | #define XFS_RENAME_LOG_RES(mp) ((mp)->m_reservations.tr_rename) |
531 | 375 | ||
532 | /* | 376 | /* |
533 | * For creating a link to an inode: | 377 | * For creating a link to an inode: |
534 | * the parent directory inode: inode size | 378 | * the parent directory inode: inode size |
535 | * the linked inode: inode size | 379 | * the linked inode: inode size |
536 | * the directory btree could split: (max depth + v2) * dir block size | 380 | * the directory btree could split: (max depth + v2) * dir block size |
537 | * the directory bmap btree could join or split: (max depth + v2) * blocksize | 381 | * the directory bmap btree could join or split: (max depth + v2) * blocksize |
538 | * And the bmap_finish transaction can free some bmap blocks giving: | 382 | * And the bmap_finish transaction can free some bmap blocks giving: |
539 | * the agf for the ag in which the blocks live: sector size | 383 | * the agf for the ag in which the blocks live: sector size |
540 | * the agfl for the ag in which the blocks live: sector size | 384 | * the agfl for the ag in which the blocks live: sector size |
541 | * the superblock for the free block count: sector size | 385 | * the superblock for the free block count: sector size |
542 | * the allocation btrees: 2 trees * (2 * max depth - 1) * block size | 386 | * the allocation btrees: 2 trees * (2 * max depth - 1) * block size |
543 | */ | 387 | */ |
544 | #define XFS_CALC_LINK_LOG_RES(mp) \ | 388 | #define XFS_CALC_LINK_LOG_RES(mp) \ |
545 | (MAX( \ | 389 | (MAX( \ |
546 | ((mp)->m_sb.sb_inodesize + \ | 390 | ((mp)->m_sb.sb_inodesize + \ |
547 | (mp)->m_sb.sb_inodesize + \ | 391 | (mp)->m_sb.sb_inodesize + \ |
548 | XFS_DIROP_LOG_RES(mp) + \ | 392 | XFS_DIROP_LOG_RES(mp) + \ |
549 | (128 * (2 + XFS_DIROP_LOG_COUNT(mp)))), \ | 393 | (128 * (2 + XFS_DIROP_LOG_COUNT(mp)))), \ |
550 | ((mp)->m_sb.sb_sectsize + \ | 394 | ((mp)->m_sb.sb_sectsize + \ |
551 | (mp)->m_sb.sb_sectsize + \ | 395 | (mp)->m_sb.sb_sectsize + \ |
552 | (mp)->m_sb.sb_sectsize + \ | 396 | (mp)->m_sb.sb_sectsize + \ |
553 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ | 397 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ |
554 | (128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1)))))) | 398 | (128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1)))))) |
555 | 399 | ||
556 | #define XFS_LINK_LOG_RES(mp) ((mp)->m_reservations.tr_link) | 400 | #define XFS_LINK_LOG_RES(mp) ((mp)->m_reservations.tr_link) |
557 | 401 | ||
558 | /* | 402 | /* |
559 | * For removing a directory entry we can modify: | 403 | * For removing a directory entry we can modify: |
560 | * the parent directory inode: inode size | 404 | * the parent directory inode: inode size |
561 | * the removed inode: inode size | 405 | * the removed inode: inode size |
562 | * the directory btree could join: (max depth + v2) * dir block size | 406 | * the directory btree could join: (max depth + v2) * dir block size |
563 | * the directory bmap btree could join or split: (max depth + v2) * blocksize | 407 | * the directory bmap btree could join or split: (max depth + v2) * blocksize |
564 | * And the bmap_finish transaction can free the dir and bmap blocks giving: | 408 | * And the bmap_finish transaction can free the dir and bmap blocks giving: |
565 | * the agf for the ag in which the blocks live: 2 * sector size | 409 | * the agf for the ag in which the blocks live: 2 * sector size |
566 | * the agfl for the ag in which the blocks live: 2 * sector size | 410 | * the agfl for the ag in which the blocks live: 2 * sector size |
567 | * the superblock for the free block count: sector size | 411 | * the superblock for the free block count: sector size |
568 | * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size | 412 | * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size |
569 | */ | 413 | */ |
570 | #define XFS_CALC_REMOVE_LOG_RES(mp) \ | 414 | #define XFS_CALC_REMOVE_LOG_RES(mp) \ |
571 | (MAX( \ | 415 | (MAX( \ |
572 | ((mp)->m_sb.sb_inodesize + \ | 416 | ((mp)->m_sb.sb_inodesize + \ |
573 | (mp)->m_sb.sb_inodesize + \ | 417 | (mp)->m_sb.sb_inodesize + \ |
574 | XFS_DIROP_LOG_RES(mp) + \ | 418 | XFS_DIROP_LOG_RES(mp) + \ |
575 | (128 * (2 + XFS_DIROP_LOG_COUNT(mp)))), \ | 419 | (128 * (2 + XFS_DIROP_LOG_COUNT(mp)))), \ |
576 | ((2 * (mp)->m_sb.sb_sectsize) + \ | 420 | ((2 * (mp)->m_sb.sb_sectsize) + \ |
577 | (2 * (mp)->m_sb.sb_sectsize) + \ | 421 | (2 * (mp)->m_sb.sb_sectsize) + \ |
578 | (mp)->m_sb.sb_sectsize + \ | 422 | (mp)->m_sb.sb_sectsize + \ |
579 | XFS_ALLOCFREE_LOG_RES(mp, 2) + \ | 423 | XFS_ALLOCFREE_LOG_RES(mp, 2) + \ |
580 | (128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))))) | 424 | (128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))))) |
581 | 425 | ||
582 | #define XFS_REMOVE_LOG_RES(mp) ((mp)->m_reservations.tr_remove) | 426 | #define XFS_REMOVE_LOG_RES(mp) ((mp)->m_reservations.tr_remove) |
583 | 427 | ||
584 | /* | 428 | /* |
585 | * For symlink we can modify: | 429 | * For symlink we can modify: |
586 | * the parent directory inode: inode size | 430 | * the parent directory inode: inode size |
587 | * the new inode: inode size | 431 | * the new inode: inode size |
588 | * the inode btree entry: 1 block | 432 | * the inode btree entry: 1 block |
589 | * the directory btree: (max depth + v2) * dir block size | 433 | * the directory btree: (max depth + v2) * dir block size |
590 | * the directory inode\'s bmap btree: (max depth + v2) * block size | 434 | * the directory inode\'s bmap btree: (max depth + v2) * block size |
591 | * the blocks for the symlink: 1 KB | 435 | * the blocks for the symlink: 1 KB |
592 | * Or in the first xact we allocate some inodes giving: | 436 | * Or in the first xact we allocate some inodes giving: |
593 | * the agi and agf of the ag getting the new inodes: 2 * sectorsize | 437 | * the agi and agf of the ag getting the new inodes: 2 * sectorsize |
594 | * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize | 438 | * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize |
595 | * the inode btree: max depth * blocksize | 439 | * the inode btree: max depth * blocksize |
596 | * the allocation btrees: 2 trees * (2 * max depth - 1) * block size | 440 | * the allocation btrees: 2 trees * (2 * max depth - 1) * block size |
597 | */ | 441 | */ |
598 | #define XFS_CALC_SYMLINK_LOG_RES(mp) \ | 442 | #define XFS_CALC_SYMLINK_LOG_RES(mp) \ |
599 | (MAX( \ | 443 | (MAX( \ |
600 | ((mp)->m_sb.sb_inodesize + \ | 444 | ((mp)->m_sb.sb_inodesize + \ |
601 | (mp)->m_sb.sb_inodesize + \ | 445 | (mp)->m_sb.sb_inodesize + \ |
602 | XFS_FSB_TO_B(mp, 1) + \ | 446 | XFS_FSB_TO_B(mp, 1) + \ |
603 | XFS_DIROP_LOG_RES(mp) + \ | 447 | XFS_DIROP_LOG_RES(mp) + \ |
604 | 1024 + \ | 448 | 1024 + \ |
605 | (128 * (4 + XFS_DIROP_LOG_COUNT(mp)))), \ | 449 | (128 * (4 + XFS_DIROP_LOG_COUNT(mp)))), \ |
606 | (2 * (mp)->m_sb.sb_sectsize + \ | 450 | (2 * (mp)->m_sb.sb_sectsize + \ |
607 | XFS_FSB_TO_B((mp), XFS_IALLOC_BLOCKS((mp))) + \ | 451 | XFS_FSB_TO_B((mp), XFS_IALLOC_BLOCKS((mp))) + \ |
608 | XFS_FSB_TO_B((mp), XFS_IN_MAXLEVELS(mp)) + \ | 452 | XFS_FSB_TO_B((mp), XFS_IN_MAXLEVELS(mp)) + \ |
609 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ | 453 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ |
610 | (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \ | 454 | (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \ |
611 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))))) | 455 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))))) |
612 | 456 | ||
613 | #define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_reservations.tr_symlink) | 457 | #define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_reservations.tr_symlink) |
614 | 458 | ||
615 | /* | 459 | /* |
616 | * For create we can modify: | 460 | * For create we can modify: |
617 | * the parent directory inode: inode size | 461 | * the parent directory inode: inode size |
618 | * the new inode: inode size | 462 | * the new inode: inode size |
619 | * the inode btree entry: block size | 463 | * the inode btree entry: block size |
620 | * the superblock for the nlink flag: sector size | 464 | * the superblock for the nlink flag: sector size |
621 | * the directory btree: (max depth + v2) * dir block size | 465 | * the directory btree: (max depth + v2) * dir block size |
622 | * the directory inode\'s bmap btree: (max depth + v2) * block size | 466 | * the directory inode\'s bmap btree: (max depth + v2) * block size |
623 | * Or in the first xact we allocate some inodes giving: | 467 | * Or in the first xact we allocate some inodes giving: |
624 | * the agi and agf of the ag getting the new inodes: 2 * sectorsize | 468 | * the agi and agf of the ag getting the new inodes: 2 * sectorsize |
625 | * the superblock for the nlink flag: sector size | 469 | * the superblock for the nlink flag: sector size |
626 | * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize | 470 | * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize |
627 | * the inode btree: max depth * blocksize | 471 | * the inode btree: max depth * blocksize |
628 | * the allocation btrees: 2 trees * (max depth - 1) * block size | 472 | * the allocation btrees: 2 trees * (max depth - 1) * block size |
629 | */ | 473 | */ |
630 | #define XFS_CALC_CREATE_LOG_RES(mp) \ | 474 | #define XFS_CALC_CREATE_LOG_RES(mp) \ |
631 | (MAX( \ | 475 | (MAX( \ |
632 | ((mp)->m_sb.sb_inodesize + \ | 476 | ((mp)->m_sb.sb_inodesize + \ |
633 | (mp)->m_sb.sb_inodesize + \ | 477 | (mp)->m_sb.sb_inodesize + \ |
634 | (mp)->m_sb.sb_sectsize + \ | 478 | (mp)->m_sb.sb_sectsize + \ |
635 | XFS_FSB_TO_B(mp, 1) + \ | 479 | XFS_FSB_TO_B(mp, 1) + \ |
636 | XFS_DIROP_LOG_RES(mp) + \ | 480 | XFS_DIROP_LOG_RES(mp) + \ |
637 | (128 * (3 + XFS_DIROP_LOG_COUNT(mp)))), \ | 481 | (128 * (3 + XFS_DIROP_LOG_COUNT(mp)))), \ |
638 | (3 * (mp)->m_sb.sb_sectsize + \ | 482 | (3 * (mp)->m_sb.sb_sectsize + \ |
639 | XFS_FSB_TO_B((mp), XFS_IALLOC_BLOCKS((mp))) + \ | 483 | XFS_FSB_TO_B((mp), XFS_IALLOC_BLOCKS((mp))) + \ |
640 | XFS_FSB_TO_B((mp), XFS_IN_MAXLEVELS(mp)) + \ | 484 | XFS_FSB_TO_B((mp), XFS_IN_MAXLEVELS(mp)) + \ |
641 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ | 485 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ |
642 | (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \ | 486 | (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \ |
643 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))))) | 487 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))))) |
644 | 488 | ||
645 | #define XFS_CREATE_LOG_RES(mp) ((mp)->m_reservations.tr_create) | 489 | #define XFS_CREATE_LOG_RES(mp) ((mp)->m_reservations.tr_create) |
646 | 490 | ||
647 | /* | 491 | /* |
648 | * Making a new directory is the same as creating a new file. | 492 | * Making a new directory is the same as creating a new file. |
649 | */ | 493 | */ |
650 | #define XFS_CALC_MKDIR_LOG_RES(mp) XFS_CALC_CREATE_LOG_RES(mp) | 494 | #define XFS_CALC_MKDIR_LOG_RES(mp) XFS_CALC_CREATE_LOG_RES(mp) |
651 | 495 | ||
652 | #define XFS_MKDIR_LOG_RES(mp) ((mp)->m_reservations.tr_mkdir) | 496 | #define XFS_MKDIR_LOG_RES(mp) ((mp)->m_reservations.tr_mkdir) |
653 | 497 | ||
654 | /* | 498 | /* |
655 | * In freeing an inode we can modify: | 499 | * In freeing an inode we can modify: |
656 | * the inode being freed: inode size | 500 | * the inode being freed: inode size |
657 | * the super block free inode counter: sector size | 501 | * the super block free inode counter: sector size |
658 | * the agi hash list and counters: sector size | 502 | * the agi hash list and counters: sector size |
659 | * the inode btree entry: block size | 503 | * the inode btree entry: block size |
660 | * the on disk inode before ours in the agi hash list: inode cluster size | 504 | * the on disk inode before ours in the agi hash list: inode cluster size |
661 | * the inode btree: max depth * blocksize | 505 | * the inode btree: max depth * blocksize |
662 | * the allocation btrees: 2 trees * (max depth - 1) * block size | 506 | * the allocation btrees: 2 trees * (max depth - 1) * block size |
663 | */ | 507 | */ |
664 | #define XFS_CALC_IFREE_LOG_RES(mp) \ | 508 | #define XFS_CALC_IFREE_LOG_RES(mp) \ |
665 | ((mp)->m_sb.sb_inodesize + \ | 509 | ((mp)->m_sb.sb_inodesize + \ |
666 | (mp)->m_sb.sb_sectsize + \ | 510 | (mp)->m_sb.sb_sectsize + \ |
667 | (mp)->m_sb.sb_sectsize + \ | 511 | (mp)->m_sb.sb_sectsize + \ |
668 | XFS_FSB_TO_B((mp), 1) + \ | 512 | XFS_FSB_TO_B((mp), 1) + \ |
669 | MAX((__uint16_t)XFS_FSB_TO_B((mp), 1), XFS_INODE_CLUSTER_SIZE(mp)) + \ | 513 | MAX((__uint16_t)XFS_FSB_TO_B((mp), 1), XFS_INODE_CLUSTER_SIZE(mp)) + \ |
670 | (128 * 5) + \ | 514 | (128 * 5) + \ |
671 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ | 515 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ |
672 | (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \ | 516 | (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \ |
673 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) | 517 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) |
674 | 518 | ||
675 | 519 | ||
676 | #define XFS_IFREE_LOG_RES(mp) ((mp)->m_reservations.tr_ifree) | 520 | #define XFS_IFREE_LOG_RES(mp) ((mp)->m_reservations.tr_ifree) |
677 | 521 | ||
678 | /* | 522 | /* |
679 | * When only changing the inode we log the inode and possibly the superblock | 523 | * When only changing the inode we log the inode and possibly the superblock |
680 | * We also add a bit of slop for the transaction stuff. | 524 | * We also add a bit of slop for the transaction stuff. |
681 | */ | 525 | */ |
682 | #define XFS_CALC_ICHANGE_LOG_RES(mp) ((mp)->m_sb.sb_inodesize + \ | 526 | #define XFS_CALC_ICHANGE_LOG_RES(mp) ((mp)->m_sb.sb_inodesize + \ |
683 | (mp)->m_sb.sb_sectsize + 512) | 527 | (mp)->m_sb.sb_sectsize + 512) |
684 | 528 | ||
685 | #define XFS_ICHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_ichange) | 529 | #define XFS_ICHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_ichange) |
686 | 530 | ||
687 | /* | 531 | /* |
688 | * Growing the data section of the filesystem. | 532 | * Growing the data section of the filesystem. |
689 | * superblock | 533 | * superblock |
690 | * agi and agf | 534 | * agi and agf |
691 | * allocation btrees | 535 | * allocation btrees |
692 | */ | 536 | */ |
693 | #define XFS_CALC_GROWDATA_LOG_RES(mp) \ | 537 | #define XFS_CALC_GROWDATA_LOG_RES(mp) \ |
694 | ((mp)->m_sb.sb_sectsize * 3 + \ | 538 | ((mp)->m_sb.sb_sectsize * 3 + \ |
695 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ | 539 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ |
696 | (128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) | 540 | (128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) |
697 | 541 | ||
698 | #define XFS_GROWDATA_LOG_RES(mp) ((mp)->m_reservations.tr_growdata) | 542 | #define XFS_GROWDATA_LOG_RES(mp) ((mp)->m_reservations.tr_growdata) |
699 | 543 | ||
700 | /* | 544 | /* |
701 | * Growing the rt section of the filesystem. | 545 | * Growing the rt section of the filesystem. |
702 | * In the first set of transactions (ALLOC) we allocate space to the | 546 | * In the first set of transactions (ALLOC) we allocate space to the |
703 | * bitmap or summary files. | 547 | * bitmap or summary files. |
704 | * superblock: sector size | 548 | * superblock: sector size |
705 | * agf of the ag from which the extent is allocated: sector size | 549 | * agf of the ag from which the extent is allocated: sector size |
706 | * bmap btree for bitmap/summary inode: max depth * blocksize | 550 | * bmap btree for bitmap/summary inode: max depth * blocksize |
707 | * bitmap/summary inode: inode size | 551 | * bitmap/summary inode: inode size |
708 | * allocation btrees for 1 block alloc: 2 * (2 * maxdepth - 1) * blocksize | 552 | * allocation btrees for 1 block alloc: 2 * (2 * maxdepth - 1) * blocksize |
709 | */ | 553 | */ |
710 | #define XFS_CALC_GROWRTALLOC_LOG_RES(mp) \ | 554 | #define XFS_CALC_GROWRTALLOC_LOG_RES(mp) \ |
711 | (2 * (mp)->m_sb.sb_sectsize + \ | 555 | (2 * (mp)->m_sb.sb_sectsize + \ |
712 | XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) + \ | 556 | XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) + \ |
713 | (mp)->m_sb.sb_inodesize + \ | 557 | (mp)->m_sb.sb_inodesize + \ |
714 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ | 558 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ |
715 | (128 * \ | 559 | (128 * \ |
716 | (3 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + \ | 560 | (3 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + \ |
717 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) | 561 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) |
718 | 562 | ||
719 | #define XFS_GROWRTALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_growrtalloc) | 563 | #define XFS_GROWRTALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_growrtalloc) |
720 | 564 | ||
721 | /* | 565 | /* |
722 | * Growing the rt section of the filesystem. | 566 | * Growing the rt section of the filesystem. |
723 | * In the second set of transactions (ZERO) we zero the new metadata blocks. | 567 | * In the second set of transactions (ZERO) we zero the new metadata blocks. |
724 | * one bitmap/summary block: blocksize | 568 | * one bitmap/summary block: blocksize |
725 | */ | 569 | */ |
726 | #define XFS_CALC_GROWRTZERO_LOG_RES(mp) \ | 570 | #define XFS_CALC_GROWRTZERO_LOG_RES(mp) \ |
727 | ((mp)->m_sb.sb_blocksize + 128) | 571 | ((mp)->m_sb.sb_blocksize + 128) |
728 | 572 | ||
729 | #define XFS_GROWRTZERO_LOG_RES(mp) ((mp)->m_reservations.tr_growrtzero) | 573 | #define XFS_GROWRTZERO_LOG_RES(mp) ((mp)->m_reservations.tr_growrtzero) |
730 | 574 | ||
731 | /* | 575 | /* |
732 | * Growing the rt section of the filesystem. | 576 | * Growing the rt section of the filesystem. |
733 | * In the third set of transactions (FREE) we update metadata without | 577 | * In the third set of transactions (FREE) we update metadata without |
734 | * allocating any new blocks. | 578 | * allocating any new blocks. |
735 | * superblock: sector size | 579 | * superblock: sector size |
736 | * bitmap inode: inode size | 580 | * bitmap inode: inode size |
737 | * summary inode: inode size | 581 | * summary inode: inode size |
738 | * one bitmap block: blocksize | 582 | * one bitmap block: blocksize |
739 | * summary blocks: new summary size | 583 | * summary blocks: new summary size |
740 | */ | 584 | */ |
741 | #define XFS_CALC_GROWRTFREE_LOG_RES(mp) \ | 585 | #define XFS_CALC_GROWRTFREE_LOG_RES(mp) \ |
742 | ((mp)->m_sb.sb_sectsize + \ | 586 | ((mp)->m_sb.sb_sectsize + \ |
743 | 2 * (mp)->m_sb.sb_inodesize + \ | 587 | 2 * (mp)->m_sb.sb_inodesize + \ |
744 | (mp)->m_sb.sb_blocksize + \ | 588 | (mp)->m_sb.sb_blocksize + \ |
745 | (mp)->m_rsumsize + \ | 589 | (mp)->m_rsumsize + \ |
746 | (128 * 5)) | 590 | (128 * 5)) |
747 | 591 | ||
748 | #define XFS_GROWRTFREE_LOG_RES(mp) ((mp)->m_reservations.tr_growrtfree) | 592 | #define XFS_GROWRTFREE_LOG_RES(mp) ((mp)->m_reservations.tr_growrtfree) |
749 | 593 | ||
750 | /* | 594 | /* |
751 | * Logging the inode modification timestamp on a synchronous write. | 595 | * Logging the inode modification timestamp on a synchronous write. |
752 | * inode | 596 | * inode |
753 | */ | 597 | */ |
754 | #define XFS_CALC_SWRITE_LOG_RES(mp) \ | 598 | #define XFS_CALC_SWRITE_LOG_RES(mp) \ |
755 | ((mp)->m_sb.sb_inodesize + 128) | 599 | ((mp)->m_sb.sb_inodesize + 128) |
756 | 600 | ||
757 | #define XFS_SWRITE_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) | 601 | #define XFS_SWRITE_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) |
758 | 602 | ||
759 | /* | 603 | /* |
760 | * Logging the inode timestamps on an fsync -- same as SWRITE | 604 | * Logging the inode timestamps on an fsync -- same as SWRITE |
761 | * as long as SWRITE logs the entire inode core | 605 | * as long as SWRITE logs the entire inode core |
762 | */ | 606 | */ |
763 | #define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) | 607 | #define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) |
764 | 608 | ||
765 | /* | 609 | /* |
766 | * Logging the inode mode bits when writing a setuid/setgid file | 610 | * Logging the inode mode bits when writing a setuid/setgid file |
767 | * inode | 611 | * inode |
768 | */ | 612 | */ |
769 | #define XFS_CALC_WRITEID_LOG_RES(mp) \ | 613 | #define XFS_CALC_WRITEID_LOG_RES(mp) \ |
770 | ((mp)->m_sb.sb_inodesize + 128) | 614 | ((mp)->m_sb.sb_inodesize + 128) |
771 | 615 | ||
772 | #define XFS_WRITEID_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) | 616 | #define XFS_WRITEID_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) |
773 | 617 | ||
774 | /* | 618 | /* |
775 | * Converting the inode from non-attributed to attributed. | 619 | * Converting the inode from non-attributed to attributed. |
776 | * the inode being converted: inode size | 620 | * the inode being converted: inode size |
777 | * agf block and superblock (for block allocation) | 621 | * agf block and superblock (for block allocation) |
778 | * the new block (directory sized) | 622 | * the new block (directory sized) |
779 | * bmap blocks for the new directory block | 623 | * bmap blocks for the new directory block |
780 | * allocation btrees | 624 | * allocation btrees |
781 | */ | 625 | */ |
782 | #define XFS_CALC_ADDAFORK_LOG_RES(mp) \ | 626 | #define XFS_CALC_ADDAFORK_LOG_RES(mp) \ |
783 | ((mp)->m_sb.sb_inodesize + \ | 627 | ((mp)->m_sb.sb_inodesize + \ |
784 | (mp)->m_sb.sb_sectsize * 2 + \ | 628 | (mp)->m_sb.sb_sectsize * 2 + \ |
785 | (mp)->m_dirblksize + \ | 629 | (mp)->m_dirblksize + \ |
786 | XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1)) + \ | 630 | XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1)) + \ |
787 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ | 631 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ |
788 | (128 * (4 + (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \ | 632 | (128 * (4 + (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \ |
789 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) | 633 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) |
790 | 634 | ||
791 | #define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork) | 635 | #define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork) |
792 | 636 | ||
793 | /* | 637 | /* |
794 | * Removing the attribute fork of a file | 638 | * Removing the attribute fork of a file |
795 | * the inode being truncated: inode size | 639 | * the inode being truncated: inode size |
796 | * the inode\'s bmap btree: max depth * block size | 640 | * the inode\'s bmap btree: max depth * block size |
797 | * And the bmap_finish transaction can free the blocks and bmap blocks: | 641 | * And the bmap_finish transaction can free the blocks and bmap blocks: |
798 | * the agf for each of the ags: 4 * sector size | 642 | * the agf for each of the ags: 4 * sector size |
799 | * the agfl for each of the ags: 4 * sector size | 643 | * the agfl for each of the ags: 4 * sector size |
800 | * the super block to reflect the freed blocks: sector size | 644 | * the super block to reflect the freed blocks: sector size |
801 | * worst case split in allocation btrees per extent assuming 4 extents: | 645 | * worst case split in allocation btrees per extent assuming 4 extents: |
802 | * 4 exts * 2 trees * (2 * max depth - 1) * block size | 646 | * 4 exts * 2 trees * (2 * max depth - 1) * block size |
803 | */ | 647 | */ |
804 | #define XFS_CALC_ATTRINVAL_LOG_RES(mp) \ | 648 | #define XFS_CALC_ATTRINVAL_LOG_RES(mp) \ |
805 | (MAX( \ | 649 | (MAX( \ |
806 | ((mp)->m_sb.sb_inodesize + \ | 650 | ((mp)->m_sb.sb_inodesize + \ |
807 | XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + \ | 651 | XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + \ |
808 | (128 * (1 + XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)))), \ | 652 | (128 * (1 + XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)))), \ |
809 | ((4 * (mp)->m_sb.sb_sectsize) + \ | 653 | ((4 * (mp)->m_sb.sb_sectsize) + \ |
810 | (4 * (mp)->m_sb.sb_sectsize) + \ | 654 | (4 * (mp)->m_sb.sb_sectsize) + \ |
811 | (mp)->m_sb.sb_sectsize + \ | 655 | (mp)->m_sb.sb_sectsize + \ |
812 | XFS_ALLOCFREE_LOG_RES(mp, 4) + \ | 656 | XFS_ALLOCFREE_LOG_RES(mp, 4) + \ |
813 | (128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4)))))) | 657 | (128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4)))))) |
814 | 658 | ||
815 | #define XFS_ATTRINVAL_LOG_RES(mp) ((mp)->m_reservations.tr_attrinval) | 659 | #define XFS_ATTRINVAL_LOG_RES(mp) ((mp)->m_reservations.tr_attrinval) |
816 | 660 | ||
817 | /* | 661 | /* |
818 | * Setting an attribute. | 662 | * Setting an attribute. |
819 | * the inode getting the attribute | 663 | * the inode getting the attribute |
820 | * the superblock for allocations | 664 | * the superblock for allocations |
821 | * the agfs extents are allocated from | 665 | * the agfs extents are allocated from |
822 | * the attribute btree * max depth | 666 | * the attribute btree * max depth |
823 | * the inode allocation btree | 667 | * the inode allocation btree |
824 | * Since attribute transaction space is dependent on the size of the attribute, | 668 | * Since attribute transaction space is dependent on the size of the attribute, |
825 | * the calculation is done partially at mount time and partially at runtime. | 669 | * the calculation is done partially at mount time and partially at runtime. |
826 | */ | 670 | */ |
827 | #define XFS_CALC_ATTRSET_LOG_RES(mp) \ | 671 | #define XFS_CALC_ATTRSET_LOG_RES(mp) \ |
828 | ((mp)->m_sb.sb_inodesize + \ | 672 | ((mp)->m_sb.sb_inodesize + \ |
829 | (mp)->m_sb.sb_sectsize + \ | 673 | (mp)->m_sb.sb_sectsize + \ |
830 | XFS_FSB_TO_B((mp), XFS_DA_NODE_MAXDEPTH) + \ | 674 | XFS_FSB_TO_B((mp), XFS_DA_NODE_MAXDEPTH) + \ |
831 | (128 * (2 + XFS_DA_NODE_MAXDEPTH))) | 675 | (128 * (2 + XFS_DA_NODE_MAXDEPTH))) |
832 | 676 | ||
833 | #define XFS_ATTRSET_LOG_RES(mp, ext) \ | 677 | #define XFS_ATTRSET_LOG_RES(mp, ext) \ |
834 | ((mp)->m_reservations.tr_attrset + \ | 678 | ((mp)->m_reservations.tr_attrset + \ |
835 | (ext * (mp)->m_sb.sb_sectsize) + \ | 679 | (ext * (mp)->m_sb.sb_sectsize) + \ |
836 | (ext * XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))) + \ | 680 | (ext * XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))) + \ |
837 | (128 * (ext + (ext * XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))))) | 681 | (128 * (ext + (ext * XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))))) |
838 | 682 | ||
839 | /* | 683 | /* |
840 | * Removing an attribute. | 684 | * Removing an attribute. |
841 | * the inode: inode size | 685 | * the inode: inode size |
842 | * the attribute btree could join: max depth * block size | 686 | * the attribute btree could join: max depth * block size |
843 | * the inode bmap btree could join or split: max depth * block size | 687 | * the inode bmap btree could join or split: max depth * block size |
844 | * And the bmap_finish transaction can free the attr blocks freed giving: | 688 | * And the bmap_finish transaction can free the attr blocks freed giving: |
845 | * the agf for the ag in which the blocks live: 2 * sector size | 689 | * the agf for the ag in which the blocks live: 2 * sector size |
846 | * the agfl for the ag in which the blocks live: 2 * sector size | 690 | * the agfl for the ag in which the blocks live: 2 * sector size |
847 | * the superblock for the free block count: sector size | 691 | * the superblock for the free block count: sector size |
848 | * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size | 692 | * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size |
849 | */ | 693 | */ |
850 | #define XFS_CALC_ATTRRM_LOG_RES(mp) \ | 694 | #define XFS_CALC_ATTRRM_LOG_RES(mp) \ |
851 | (MAX( \ | 695 | (MAX( \ |
852 | ((mp)->m_sb.sb_inodesize + \ | 696 | ((mp)->m_sb.sb_inodesize + \ |
853 | XFS_FSB_TO_B((mp), XFS_DA_NODE_MAXDEPTH) + \ | 697 | XFS_FSB_TO_B((mp), XFS_DA_NODE_MAXDEPTH) + \ |
854 | XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + \ | 698 | XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + \ |
855 | (128 * (1 + XFS_DA_NODE_MAXDEPTH + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)))), \ | 699 | (128 * (1 + XFS_DA_NODE_MAXDEPTH + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)))), \ |
856 | ((2 * (mp)->m_sb.sb_sectsize) + \ | 700 | ((2 * (mp)->m_sb.sb_sectsize) + \ |
857 | (2 * (mp)->m_sb.sb_sectsize) + \ | 701 | (2 * (mp)->m_sb.sb_sectsize) + \ |
858 | (mp)->m_sb.sb_sectsize + \ | 702 | (mp)->m_sb.sb_sectsize + \ |
859 | XFS_ALLOCFREE_LOG_RES(mp, 2) + \ | 703 | XFS_ALLOCFREE_LOG_RES(mp, 2) + \ |
860 | (128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))))) | 704 | (128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))))) |
861 | 705 | ||
862 | #define XFS_ATTRRM_LOG_RES(mp) ((mp)->m_reservations.tr_attrrm) | 706 | #define XFS_ATTRRM_LOG_RES(mp) ((mp)->m_reservations.tr_attrrm) |
863 | 707 | ||
864 | /* | 708 | /* |
865 | * Clearing a bad agino number in an agi hash bucket. | 709 | * Clearing a bad agino number in an agi hash bucket. |
866 | */ | 710 | */ |
867 | #define XFS_CALC_CLEAR_AGI_BUCKET_LOG_RES(mp) \ | 711 | #define XFS_CALC_CLEAR_AGI_BUCKET_LOG_RES(mp) \ |
868 | ((mp)->m_sb.sb_sectsize + 128) | 712 | ((mp)->m_sb.sb_sectsize + 128) |
869 | 713 | ||
870 | #define XFS_CLEAR_AGI_BUCKET_LOG_RES(mp) ((mp)->m_reservations.tr_clearagi) | 714 | #define XFS_CLEAR_AGI_BUCKET_LOG_RES(mp) ((mp)->m_reservations.tr_clearagi) |
871 | 715 | ||
872 | 716 | ||
873 | /* | 717 | /* |
874 | * Various log count values. | 718 | * Various log count values. |
875 | */ | 719 | */ |
876 | #define XFS_DEFAULT_LOG_COUNT 1 | 720 | #define XFS_DEFAULT_LOG_COUNT 1 |
877 | #define XFS_DEFAULT_PERM_LOG_COUNT 2 | 721 | #define XFS_DEFAULT_PERM_LOG_COUNT 2 |
878 | #define XFS_ITRUNCATE_LOG_COUNT 2 | 722 | #define XFS_ITRUNCATE_LOG_COUNT 2 |
879 | #define XFS_INACTIVE_LOG_COUNT 2 | 723 | #define XFS_INACTIVE_LOG_COUNT 2 |
880 | #define XFS_CREATE_LOG_COUNT 2 | 724 | #define XFS_CREATE_LOG_COUNT 2 |
881 | #define XFS_MKDIR_LOG_COUNT 3 | 725 | #define XFS_MKDIR_LOG_COUNT 3 |
882 | #define XFS_SYMLINK_LOG_COUNT 3 | 726 | #define XFS_SYMLINK_LOG_COUNT 3 |
883 | #define XFS_REMOVE_LOG_COUNT 2 | 727 | #define XFS_REMOVE_LOG_COUNT 2 |
884 | #define XFS_LINK_LOG_COUNT 2 | 728 | #define XFS_LINK_LOG_COUNT 2 |
885 | #define XFS_RENAME_LOG_COUNT 2 | 729 | #define XFS_RENAME_LOG_COUNT 2 |
886 | #define XFS_WRITE_LOG_COUNT 2 | 730 | #define XFS_WRITE_LOG_COUNT 2 |
887 | #define XFS_ADDAFORK_LOG_COUNT 2 | 731 | #define XFS_ADDAFORK_LOG_COUNT 2 |
888 | #define XFS_ATTRINVAL_LOG_COUNT 1 | 732 | #define XFS_ATTRINVAL_LOG_COUNT 1 |
889 | #define XFS_ATTRSET_LOG_COUNT 3 | 733 | #define XFS_ATTRSET_LOG_COUNT 3 |
890 | #define XFS_ATTRRM_LOG_COUNT 3 | 734 | #define XFS_ATTRRM_LOG_COUNT 3 |
891 | 735 | ||
892 | /* | 736 | /* |
893 | * Here we centralize the specification of XFS meta-data buffer | 737 | * Here we centralize the specification of XFS meta-data buffer |
894 | * reference count values. This determine how hard the buffer | 738 | * reference count values. This determine how hard the buffer |
895 | * cache tries to hold onto the buffer. | 739 | * cache tries to hold onto the buffer. |
896 | */ | 740 | */ |
897 | #define XFS_AGF_REF 4 | 741 | #define XFS_AGF_REF 4 |
898 | #define XFS_AGI_REF 4 | 742 | #define XFS_AGI_REF 4 |
899 | #define XFS_AGFL_REF 3 | 743 | #define XFS_AGFL_REF 3 |
900 | #define XFS_INO_BTREE_REF 3 | 744 | #define XFS_INO_BTREE_REF 3 |
901 | #define XFS_ALLOC_BTREE_REF 2 | 745 | #define XFS_ALLOC_BTREE_REF 2 |
902 | #define XFS_BMAP_BTREE_REF 2 | 746 | #define XFS_BMAP_BTREE_REF 2 |
903 | #define XFS_DIR_BTREE_REF 2 | 747 | #define XFS_DIR_BTREE_REF 2 |
904 | #define XFS_ATTR_BTREE_REF 1 | 748 | #define XFS_ATTR_BTREE_REF 1 |
905 | #define XFS_INO_REF 1 | 749 | #define XFS_INO_REF 1 |
906 | #define XFS_DQUOT_REF 1 | 750 | #define XFS_DQUOT_REF 1 |
907 | 751 | ||
908 | #ifdef __KERNEL__ | 752 | #ifdef __KERNEL__ |
753 | |||
754 | struct xfs_buf; | ||
755 | struct xfs_buftarg; | ||
756 | struct xfs_efd_log_item; | ||
757 | struct xfs_efi_log_item; | ||
758 | struct xfs_inode; | ||
759 | struct xfs_item_ops; | ||
760 | struct xfs_log_iovec; | ||
761 | struct xfs_log_item_desc; | ||
762 | struct xfs_mount; | ||
763 | struct xfs_trans; | ||
764 | struct xfs_dquot_acct; | ||
765 | |||
766 | typedef struct xfs_log_item { | ||
767 | struct list_head li_ail; /* AIL pointers */ | ||
768 | xfs_lsn_t li_lsn; /* last on-disk lsn */ | ||
769 | struct xfs_log_item_desc *li_desc; /* ptr to current desc*/ | ||
770 | struct xfs_mount *li_mountp; /* ptr to fs mount */ | ||
771 | uint li_type; /* item type */ | ||
772 | uint li_flags; /* misc flags */ | ||
773 | struct xfs_log_item *li_bio_list; /* buffer item list */ | ||
774 | void (*li_cb)(struct xfs_buf *, | ||
775 | struct xfs_log_item *); | ||
776 | /* buffer item iodone */ | ||
777 | /* callback func */ | ||
778 | struct xfs_item_ops *li_ops; /* function list */ | ||
779 | } xfs_log_item_t; | ||
780 | |||
781 | #define XFS_LI_IN_AIL 0x1 | ||
782 | #define XFS_LI_ABORTED 0x2 | ||
783 | |||
784 | typedef struct xfs_item_ops { | ||
785 | uint (*iop_size)(xfs_log_item_t *); | ||
786 | void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *); | ||
787 | void (*iop_pin)(xfs_log_item_t *); | ||
788 | void (*iop_unpin)(xfs_log_item_t *, int); | ||
789 | void (*iop_unpin_remove)(xfs_log_item_t *, struct xfs_trans *); | ||
790 | uint (*iop_trylock)(xfs_log_item_t *); | ||
791 | void (*iop_unlock)(xfs_log_item_t *); | ||
792 | xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t); | ||
793 | void (*iop_push)(xfs_log_item_t *); | ||
794 | void (*iop_pushbuf)(xfs_log_item_t *); | ||
795 | void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t); | ||
796 | } xfs_item_ops_t; | ||
797 | |||
798 | #define IOP_SIZE(ip) (*(ip)->li_ops->iop_size)(ip) | ||
799 | #define IOP_FORMAT(ip,vp) (*(ip)->li_ops->iop_format)(ip, vp) | ||
800 | #define IOP_PIN(ip) (*(ip)->li_ops->iop_pin)(ip) | ||
801 | #define IOP_UNPIN(ip, flags) (*(ip)->li_ops->iop_unpin)(ip, flags) | ||
802 | #define IOP_UNPIN_REMOVE(ip,tp) (*(ip)->li_ops->iop_unpin_remove)(ip, tp) | ||
803 | #define IOP_TRYLOCK(ip) (*(ip)->li_ops->iop_trylock)(ip) | ||
804 | #define IOP_UNLOCK(ip) (*(ip)->li_ops->iop_unlock)(ip) | ||
805 | #define IOP_COMMITTED(ip, lsn) (*(ip)->li_ops->iop_committed)(ip, lsn) | ||
806 | #define IOP_PUSH(ip) (*(ip)->li_ops->iop_push)(ip) | ||
807 | #define IOP_PUSHBUF(ip) (*(ip)->li_ops->iop_pushbuf)(ip) | ||
808 | #define IOP_COMMITTING(ip, lsn) (*(ip)->li_ops->iop_committing)(ip, lsn) | ||
809 | |||
909 | /* | 810 | /* |
811 | * Return values for the IOP_TRYLOCK() routines. | ||
812 | */ | ||
813 | #define XFS_ITEM_SUCCESS 0 | ||
814 | #define XFS_ITEM_PINNED 1 | ||
815 | #define XFS_ITEM_LOCKED 2 | ||
816 | #define XFS_ITEM_FLUSHING 3 | ||
817 | #define XFS_ITEM_PUSHBUF 4 | ||
818 | |||
819 | /* | ||
820 | * This structure is used to maintain a list of block ranges that have been | ||
821 | * freed in the transaction. The ranges are listed in the perag[] busy list | ||
822 | * between when they're freed and the transaction is committed to disk. | ||
823 | */ | ||
824 | |||
825 | typedef struct xfs_log_busy_slot { | ||
826 | xfs_agnumber_t lbc_ag; | ||
827 | ushort lbc_idx; /* index in perag.busy[] */ | ||
828 | } xfs_log_busy_slot_t; | ||
829 | |||
830 | #define XFS_LBC_NUM_SLOTS 31 | ||
831 | typedef struct xfs_log_busy_chunk { | ||
832 | struct xfs_log_busy_chunk *lbc_next; | ||
833 | uint lbc_free; /* free slots bitmask */ | ||
834 | ushort lbc_unused; /* first unused */ | ||
835 | xfs_log_busy_slot_t lbc_busy[XFS_LBC_NUM_SLOTS]; | ||
836 | } xfs_log_busy_chunk_t; |