Commit 847fff5ca881670ca8ec617afeb943950f0c804b

Authored by Barry Naujok
Committed by Lachlan McIlroy
1 parent 24ee0e49c9

[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

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__ */
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,
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
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
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
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
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
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
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)) &&
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);
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;