diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 12:19:22 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 12:19:22 -0400 |
commit | 49d99a2f9c4d033cc3965958a1397b1fad573dd3 (patch) | |
tree | cda1849d49d40d2f25773e86605c55bc6745cf1f /fs/xfs/xfs_inode_item.c | |
parent | 1c3ddfe5ab886c4dc0443535e95ad8e41c41d0e5 (diff) | |
parent | f074211f6041305b645669464343d504f4e6a290 (diff) |
Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs
Pull XFS updates from Ben Myers:
"Scalability improvements for dquots, log grant code cleanups, plus
bugfixes and cleanups large and small"
Fix up various trivial conflicts that were due to some of the earlier
patches already having been integrated into v3.3 as bugfixes, and then
there were development patches on top of those. Easily merged by just
taking the newer version from the pulled branch.
* 'for-linus' of git://oss.sgi.com/xfs/xfs: (45 commits)
xfs: fallback to vmalloc for large buffers in xfs_getbmap
xfs: fallback to vmalloc for large buffers in xfs_attrmulti_attr_get
xfs: remove remaining scraps of struct xfs_iomap
xfs: fix inode lookup race
xfs: clean up minor sparse warnings
xfs: remove the global xfs_Gqm structure
xfs: remove the per-filesystem list of dquots
xfs: use per-filesystem radix trees for dquot lookup
xfs: per-filesystem dquot LRU lists
xfs: use common code for quota statistics
xfs: reimplement fdatasync support
xfs: split in-core and on-disk inode log item fields
xfs: make xfs_inode_item_size idempotent
xfs: log timestamp updates
xfs: log file size updates at I/O completion time
xfs: log file size updates as part of unwritten extent conversion
xfs: do not require an ioend for new EOF calculation
xfs: use per-filesystem I/O completion workqueues
quota: make Q_XQUOTASYNC a noop
xfs: include reservations in quota reporting
...
Diffstat (limited to 'fs/xfs/xfs_inode_item.c')
-rw-r--r-- | fs/xfs/xfs_inode_item.c | 297 |
1 files changed, 107 insertions, 190 deletions
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 91d71dcd4852..05d924efceaf 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c | |||
@@ -57,77 +57,28 @@ xfs_inode_item_size( | |||
57 | struct xfs_inode *ip = iip->ili_inode; | 57 | struct xfs_inode *ip = iip->ili_inode; |
58 | uint nvecs = 2; | 58 | uint nvecs = 2; |
59 | 59 | ||
60 | /* | ||
61 | * Only log the data/extents/b-tree root if there is something | ||
62 | * left to log. | ||
63 | */ | ||
64 | iip->ili_format.ilf_fields |= XFS_ILOG_CORE; | ||
65 | |||
66 | switch (ip->i_d.di_format) { | 60 | switch (ip->i_d.di_format) { |
67 | case XFS_DINODE_FMT_EXTENTS: | 61 | case XFS_DINODE_FMT_EXTENTS: |
68 | iip->ili_format.ilf_fields &= | 62 | if ((iip->ili_fields & XFS_ILOG_DEXT) && |
69 | ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | | 63 | ip->i_d.di_nextents > 0 && |
70 | XFS_ILOG_DEV | XFS_ILOG_UUID); | 64 | ip->i_df.if_bytes > 0) |
71 | if ((iip->ili_format.ilf_fields & XFS_ILOG_DEXT) && | ||
72 | (ip->i_d.di_nextents > 0) && | ||
73 | (ip->i_df.if_bytes > 0)) { | ||
74 | ASSERT(ip->i_df.if_u1.if_extents != NULL); | ||
75 | nvecs++; | 65 | nvecs++; |
76 | } else { | ||
77 | iip->ili_format.ilf_fields &= ~XFS_ILOG_DEXT; | ||
78 | } | ||
79 | break; | 66 | break; |
80 | 67 | ||
81 | case XFS_DINODE_FMT_BTREE: | 68 | case XFS_DINODE_FMT_BTREE: |
82 | iip->ili_format.ilf_fields &= | 69 | if ((iip->ili_fields & XFS_ILOG_DBROOT) && |
83 | ~(XFS_ILOG_DDATA | XFS_ILOG_DEXT | | 70 | ip->i_df.if_broot_bytes > 0) |
84 | XFS_ILOG_DEV | XFS_ILOG_UUID); | ||
85 | if ((iip->ili_format.ilf_fields & XFS_ILOG_DBROOT) && | ||
86 | (ip->i_df.if_broot_bytes > 0)) { | ||
87 | ASSERT(ip->i_df.if_broot != NULL); | ||
88 | nvecs++; | 71 | nvecs++; |
89 | } else { | ||
90 | ASSERT(!(iip->ili_format.ilf_fields & | ||
91 | XFS_ILOG_DBROOT)); | ||
92 | #ifdef XFS_TRANS_DEBUG | ||
93 | if (iip->ili_root_size > 0) { | ||
94 | ASSERT(iip->ili_root_size == | ||
95 | ip->i_df.if_broot_bytes); | ||
96 | ASSERT(memcmp(iip->ili_orig_root, | ||
97 | ip->i_df.if_broot, | ||
98 | iip->ili_root_size) == 0); | ||
99 | } else { | ||
100 | ASSERT(ip->i_df.if_broot_bytes == 0); | ||
101 | } | ||
102 | #endif | ||
103 | iip->ili_format.ilf_fields &= ~XFS_ILOG_DBROOT; | ||
104 | } | ||
105 | break; | 72 | break; |
106 | 73 | ||
107 | case XFS_DINODE_FMT_LOCAL: | 74 | case XFS_DINODE_FMT_LOCAL: |
108 | iip->ili_format.ilf_fields &= | 75 | if ((iip->ili_fields & XFS_ILOG_DDATA) && |
109 | ~(XFS_ILOG_DEXT | XFS_ILOG_DBROOT | | 76 | ip->i_df.if_bytes > 0) |
110 | XFS_ILOG_DEV | XFS_ILOG_UUID); | ||
111 | if ((iip->ili_format.ilf_fields & XFS_ILOG_DDATA) && | ||
112 | (ip->i_df.if_bytes > 0)) { | ||
113 | ASSERT(ip->i_df.if_u1.if_data != NULL); | ||
114 | ASSERT(ip->i_d.di_size > 0); | ||
115 | nvecs++; | 77 | nvecs++; |
116 | } else { | ||
117 | iip->ili_format.ilf_fields &= ~XFS_ILOG_DDATA; | ||
118 | } | ||
119 | break; | 78 | break; |
120 | 79 | ||
121 | case XFS_DINODE_FMT_DEV: | 80 | case XFS_DINODE_FMT_DEV: |
122 | iip->ili_format.ilf_fields &= | ||
123 | ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | | ||
124 | XFS_ILOG_DEXT | XFS_ILOG_UUID); | ||
125 | break; | ||
126 | |||
127 | case XFS_DINODE_FMT_UUID: | 81 | case XFS_DINODE_FMT_UUID: |
128 | iip->ili_format.ilf_fields &= | ||
129 | ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | | ||
130 | XFS_ILOG_DEXT | XFS_ILOG_DEV); | ||
131 | break; | 82 | break; |
132 | 83 | ||
133 | default: | 84 | default: |
@@ -135,56 +86,31 @@ xfs_inode_item_size( | |||
135 | break; | 86 | break; |
136 | } | 87 | } |
137 | 88 | ||
138 | /* | 89 | if (!XFS_IFORK_Q(ip)) |
139 | * If there are no attributes associated with this file, | ||
140 | * then there cannot be anything more to log. | ||
141 | * Clear all attribute-related log flags. | ||
142 | */ | ||
143 | if (!XFS_IFORK_Q(ip)) { | ||
144 | iip->ili_format.ilf_fields &= | ||
145 | ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT); | ||
146 | return nvecs; | 90 | return nvecs; |
147 | } | 91 | |
148 | 92 | ||
149 | /* | 93 | /* |
150 | * Log any necessary attribute data. | 94 | * Log any necessary attribute data. |
151 | */ | 95 | */ |
152 | switch (ip->i_d.di_aformat) { | 96 | switch (ip->i_d.di_aformat) { |
153 | case XFS_DINODE_FMT_EXTENTS: | 97 | case XFS_DINODE_FMT_EXTENTS: |
154 | iip->ili_format.ilf_fields &= | 98 | if ((iip->ili_fields & XFS_ILOG_AEXT) && |
155 | ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT); | 99 | ip->i_d.di_anextents > 0 && |
156 | if ((iip->ili_format.ilf_fields & XFS_ILOG_AEXT) && | 100 | ip->i_afp->if_bytes > 0) |
157 | (ip->i_d.di_anextents > 0) && | ||
158 | (ip->i_afp->if_bytes > 0)) { | ||
159 | ASSERT(ip->i_afp->if_u1.if_extents != NULL); | ||
160 | nvecs++; | 101 | nvecs++; |
161 | } else { | ||
162 | iip->ili_format.ilf_fields &= ~XFS_ILOG_AEXT; | ||
163 | } | ||
164 | break; | 102 | break; |
165 | 103 | ||
166 | case XFS_DINODE_FMT_BTREE: | 104 | case XFS_DINODE_FMT_BTREE: |
167 | iip->ili_format.ilf_fields &= | 105 | if ((iip->ili_fields & XFS_ILOG_ABROOT) && |
168 | ~(XFS_ILOG_ADATA | XFS_ILOG_AEXT); | 106 | ip->i_afp->if_broot_bytes > 0) |
169 | if ((iip->ili_format.ilf_fields & XFS_ILOG_ABROOT) && | ||
170 | (ip->i_afp->if_broot_bytes > 0)) { | ||
171 | ASSERT(ip->i_afp->if_broot != NULL); | ||
172 | nvecs++; | 107 | nvecs++; |
173 | } else { | ||
174 | iip->ili_format.ilf_fields &= ~XFS_ILOG_ABROOT; | ||
175 | } | ||
176 | break; | 108 | break; |
177 | 109 | ||
178 | case XFS_DINODE_FMT_LOCAL: | 110 | case XFS_DINODE_FMT_LOCAL: |
179 | iip->ili_format.ilf_fields &= | 111 | if ((iip->ili_fields & XFS_ILOG_ADATA) && |
180 | ~(XFS_ILOG_AEXT | XFS_ILOG_ABROOT); | 112 | ip->i_afp->if_bytes > 0) |
181 | if ((iip->ili_format.ilf_fields & XFS_ILOG_ADATA) && | ||
182 | (ip->i_afp->if_bytes > 0)) { | ||
183 | ASSERT(ip->i_afp->if_u1.if_data != NULL); | ||
184 | nvecs++; | 113 | nvecs++; |
185 | } else { | ||
186 | iip->ili_format.ilf_fields &= ~XFS_ILOG_ADATA; | ||
187 | } | ||
188 | break; | 114 | break; |
189 | 115 | ||
190 | default: | 116 | default: |
@@ -254,48 +180,11 @@ xfs_inode_item_format( | |||
254 | vecp++; | 180 | vecp++; |
255 | nvecs = 1; | 181 | nvecs = 1; |
256 | 182 | ||
257 | /* | ||
258 | * Clear i_update_core if the timestamps (or any other | ||
259 | * non-transactional modification) need flushing/logging | ||
260 | * and we're about to log them with the rest of the core. | ||
261 | * | ||
262 | * This is the same logic as xfs_iflush() but this code can't | ||
263 | * run at the same time as xfs_iflush because we're in commit | ||
264 | * processing here and so we have the inode lock held in | ||
265 | * exclusive mode. Although it doesn't really matter | ||
266 | * for the timestamps if both routines were to grab the | ||
267 | * timestamps or not. That would be ok. | ||
268 | * | ||
269 | * We clear i_update_core before copying out the data. | ||
270 | * This is for coordination with our timestamp updates | ||
271 | * that don't hold the inode lock. They will always | ||
272 | * update the timestamps BEFORE setting i_update_core, | ||
273 | * so if we clear i_update_core after they set it we | ||
274 | * are guaranteed to see their updates to the timestamps | ||
275 | * either here. Likewise, if they set it after we clear it | ||
276 | * here, we'll see it either on the next commit of this | ||
277 | * inode or the next time the inode gets flushed via | ||
278 | * xfs_iflush(). This depends on strongly ordered memory | ||
279 | * semantics, but we have that. We use the SYNCHRONIZE | ||
280 | * macro to make sure that the compiler does not reorder | ||
281 | * the i_update_core access below the data copy below. | ||
282 | */ | ||
283 | if (ip->i_update_core) { | ||
284 | ip->i_update_core = 0; | ||
285 | SYNCHRONIZE(); | ||
286 | } | ||
287 | |||
288 | /* | ||
289 | * Make sure to get the latest timestamps from the Linux inode. | ||
290 | */ | ||
291 | xfs_synchronize_times(ip); | ||
292 | |||
293 | vecp->i_addr = &ip->i_d; | 183 | vecp->i_addr = &ip->i_d; |
294 | vecp->i_len = sizeof(struct xfs_icdinode); | 184 | vecp->i_len = sizeof(struct xfs_icdinode); |
295 | vecp->i_type = XLOG_REG_TYPE_ICORE; | 185 | vecp->i_type = XLOG_REG_TYPE_ICORE; |
296 | vecp++; | 186 | vecp++; |
297 | nvecs++; | 187 | nvecs++; |
298 | iip->ili_format.ilf_fields |= XFS_ILOG_CORE; | ||
299 | 188 | ||
300 | /* | 189 | /* |
301 | * If this is really an old format inode, then we need to | 190 | * If this is really an old format inode, then we need to |
@@ -328,16 +217,17 @@ xfs_inode_item_format( | |||
328 | 217 | ||
329 | switch (ip->i_d.di_format) { | 218 | switch (ip->i_d.di_format) { |
330 | case XFS_DINODE_FMT_EXTENTS: | 219 | case XFS_DINODE_FMT_EXTENTS: |
331 | ASSERT(!(iip->ili_format.ilf_fields & | 220 | iip->ili_fields &= |
332 | (XFS_ILOG_DDATA | XFS_ILOG_DBROOT | | 221 | ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | |
333 | XFS_ILOG_DEV | XFS_ILOG_UUID))); | 222 | XFS_ILOG_DEV | XFS_ILOG_UUID); |
334 | if (iip->ili_format.ilf_fields & XFS_ILOG_DEXT) { | 223 | |
335 | ASSERT(ip->i_df.if_bytes > 0); | 224 | if ((iip->ili_fields & XFS_ILOG_DEXT) && |
225 | ip->i_d.di_nextents > 0 && | ||
226 | ip->i_df.if_bytes > 0) { | ||
336 | ASSERT(ip->i_df.if_u1.if_extents != NULL); | 227 | ASSERT(ip->i_df.if_u1.if_extents != NULL); |
337 | ASSERT(ip->i_d.di_nextents > 0); | 228 | ASSERT(ip->i_df.if_bytes / sizeof(xfs_bmbt_rec_t) > 0); |
338 | ASSERT(iip->ili_extents_buf == NULL); | 229 | ASSERT(iip->ili_extents_buf == NULL); |
339 | ASSERT((ip->i_df.if_bytes / | 230 | |
340 | (uint)sizeof(xfs_bmbt_rec_t)) > 0); | ||
341 | #ifdef XFS_NATIVE_HOST | 231 | #ifdef XFS_NATIVE_HOST |
342 | if (ip->i_d.di_nextents == ip->i_df.if_bytes / | 232 | if (ip->i_d.di_nextents == ip->i_df.if_bytes / |
343 | (uint)sizeof(xfs_bmbt_rec_t)) { | 233 | (uint)sizeof(xfs_bmbt_rec_t)) { |
@@ -359,15 +249,18 @@ xfs_inode_item_format( | |||
359 | iip->ili_format.ilf_dsize = vecp->i_len; | 249 | iip->ili_format.ilf_dsize = vecp->i_len; |
360 | vecp++; | 250 | vecp++; |
361 | nvecs++; | 251 | nvecs++; |
252 | } else { | ||
253 | iip->ili_fields &= ~XFS_ILOG_DEXT; | ||
362 | } | 254 | } |
363 | break; | 255 | break; |
364 | 256 | ||
365 | case XFS_DINODE_FMT_BTREE: | 257 | case XFS_DINODE_FMT_BTREE: |
366 | ASSERT(!(iip->ili_format.ilf_fields & | 258 | iip->ili_fields &= |
367 | (XFS_ILOG_DDATA | XFS_ILOG_DEXT | | 259 | ~(XFS_ILOG_DDATA | XFS_ILOG_DEXT | |
368 | XFS_ILOG_DEV | XFS_ILOG_UUID))); | 260 | XFS_ILOG_DEV | XFS_ILOG_UUID); |
369 | if (iip->ili_format.ilf_fields & XFS_ILOG_DBROOT) { | 261 | |
370 | ASSERT(ip->i_df.if_broot_bytes > 0); | 262 | if ((iip->ili_fields & XFS_ILOG_DBROOT) && |
263 | ip->i_df.if_broot_bytes > 0) { | ||
371 | ASSERT(ip->i_df.if_broot != NULL); | 264 | ASSERT(ip->i_df.if_broot != NULL); |
372 | vecp->i_addr = ip->i_df.if_broot; | 265 | vecp->i_addr = ip->i_df.if_broot; |
373 | vecp->i_len = ip->i_df.if_broot_bytes; | 266 | vecp->i_len = ip->i_df.if_broot_bytes; |
@@ -375,15 +268,30 @@ xfs_inode_item_format( | |||
375 | vecp++; | 268 | vecp++; |
376 | nvecs++; | 269 | nvecs++; |
377 | iip->ili_format.ilf_dsize = ip->i_df.if_broot_bytes; | 270 | iip->ili_format.ilf_dsize = ip->i_df.if_broot_bytes; |
271 | } else { | ||
272 | ASSERT(!(iip->ili_fields & | ||
273 | XFS_ILOG_DBROOT)); | ||
274 | #ifdef XFS_TRANS_DEBUG | ||
275 | if (iip->ili_root_size > 0) { | ||
276 | ASSERT(iip->ili_root_size == | ||
277 | ip->i_df.if_broot_bytes); | ||
278 | ASSERT(memcmp(iip->ili_orig_root, | ||
279 | ip->i_df.if_broot, | ||
280 | iip->ili_root_size) == 0); | ||
281 | } else { | ||
282 | ASSERT(ip->i_df.if_broot_bytes == 0); | ||
283 | } | ||
284 | #endif | ||
285 | iip->ili_fields &= ~XFS_ILOG_DBROOT; | ||
378 | } | 286 | } |
379 | break; | 287 | break; |
380 | 288 | ||
381 | case XFS_DINODE_FMT_LOCAL: | 289 | case XFS_DINODE_FMT_LOCAL: |
382 | ASSERT(!(iip->ili_format.ilf_fields & | 290 | iip->ili_fields &= |
383 | (XFS_ILOG_DBROOT | XFS_ILOG_DEXT | | 291 | ~(XFS_ILOG_DEXT | XFS_ILOG_DBROOT | |
384 | XFS_ILOG_DEV | XFS_ILOG_UUID))); | 292 | XFS_ILOG_DEV | XFS_ILOG_UUID); |
385 | if (iip->ili_format.ilf_fields & XFS_ILOG_DDATA) { | 293 | if ((iip->ili_fields & XFS_ILOG_DDATA) && |
386 | ASSERT(ip->i_df.if_bytes > 0); | 294 | ip->i_df.if_bytes > 0) { |
387 | ASSERT(ip->i_df.if_u1.if_data != NULL); | 295 | ASSERT(ip->i_df.if_u1.if_data != NULL); |
388 | ASSERT(ip->i_d.di_size > 0); | 296 | ASSERT(ip->i_d.di_size > 0); |
389 | 297 | ||
@@ -401,24 +309,26 @@ xfs_inode_item_format( | |||
401 | vecp++; | 309 | vecp++; |
402 | nvecs++; | 310 | nvecs++; |
403 | iip->ili_format.ilf_dsize = (unsigned)data_bytes; | 311 | iip->ili_format.ilf_dsize = (unsigned)data_bytes; |
312 | } else { | ||
313 | iip->ili_fields &= ~XFS_ILOG_DDATA; | ||
404 | } | 314 | } |
405 | break; | 315 | break; |
406 | 316 | ||
407 | case XFS_DINODE_FMT_DEV: | 317 | case XFS_DINODE_FMT_DEV: |
408 | ASSERT(!(iip->ili_format.ilf_fields & | 318 | iip->ili_fields &= |
409 | (XFS_ILOG_DBROOT | XFS_ILOG_DEXT | | 319 | ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | |
410 | XFS_ILOG_DDATA | XFS_ILOG_UUID))); | 320 | XFS_ILOG_DEXT | XFS_ILOG_UUID); |
411 | if (iip->ili_format.ilf_fields & XFS_ILOG_DEV) { | 321 | if (iip->ili_fields & XFS_ILOG_DEV) { |
412 | iip->ili_format.ilf_u.ilfu_rdev = | 322 | iip->ili_format.ilf_u.ilfu_rdev = |
413 | ip->i_df.if_u2.if_rdev; | 323 | ip->i_df.if_u2.if_rdev; |
414 | } | 324 | } |
415 | break; | 325 | break; |
416 | 326 | ||
417 | case XFS_DINODE_FMT_UUID: | 327 | case XFS_DINODE_FMT_UUID: |
418 | ASSERT(!(iip->ili_format.ilf_fields & | 328 | iip->ili_fields &= |
419 | (XFS_ILOG_DBROOT | XFS_ILOG_DEXT | | 329 | ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | |
420 | XFS_ILOG_DDATA | XFS_ILOG_DEV))); | 330 | XFS_ILOG_DEXT | XFS_ILOG_DEV); |
421 | if (iip->ili_format.ilf_fields & XFS_ILOG_UUID) { | 331 | if (iip->ili_fields & XFS_ILOG_UUID) { |
422 | iip->ili_format.ilf_u.ilfu_uuid = | 332 | iip->ili_format.ilf_u.ilfu_uuid = |
423 | ip->i_df.if_u2.if_uuid; | 333 | ip->i_df.if_u2.if_uuid; |
424 | } | 334 | } |
@@ -430,31 +340,25 @@ xfs_inode_item_format( | |||
430 | } | 340 | } |
431 | 341 | ||
432 | /* | 342 | /* |
433 | * If there are no attributes associated with the file, | 343 | * If there are no attributes associated with the file, then we're done. |
434 | * then we're done. | ||
435 | * Assert that no attribute-related log flags are set. | ||
436 | */ | 344 | */ |
437 | if (!XFS_IFORK_Q(ip)) { | 345 | if (!XFS_IFORK_Q(ip)) { |
438 | iip->ili_format.ilf_size = nvecs; | 346 | iip->ili_fields &= |
439 | ASSERT(!(iip->ili_format.ilf_fields & | 347 | ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT); |
440 | (XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT))); | 348 | goto out; |
441 | return; | ||
442 | } | 349 | } |
443 | 350 | ||
444 | switch (ip->i_d.di_aformat) { | 351 | switch (ip->i_d.di_aformat) { |
445 | case XFS_DINODE_FMT_EXTENTS: | 352 | case XFS_DINODE_FMT_EXTENTS: |
446 | ASSERT(!(iip->ili_format.ilf_fields & | 353 | iip->ili_fields &= |
447 | (XFS_ILOG_ADATA | XFS_ILOG_ABROOT))); | 354 | ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT); |
448 | if (iip->ili_format.ilf_fields & XFS_ILOG_AEXT) { | 355 | |
449 | #ifdef DEBUG | 356 | if ((iip->ili_fields & XFS_ILOG_AEXT) && |
450 | int nrecs = ip->i_afp->if_bytes / | 357 | ip->i_d.di_anextents > 0 && |
451 | (uint)sizeof(xfs_bmbt_rec_t); | 358 | ip->i_afp->if_bytes > 0) { |
452 | ASSERT(nrecs > 0); | 359 | ASSERT(ip->i_afp->if_bytes / sizeof(xfs_bmbt_rec_t) == |
453 | ASSERT(nrecs == ip->i_d.di_anextents); | 360 | ip->i_d.di_anextents); |
454 | ASSERT(ip->i_afp->if_bytes > 0); | ||
455 | ASSERT(ip->i_afp->if_u1.if_extents != NULL); | 361 | ASSERT(ip->i_afp->if_u1.if_extents != NULL); |
456 | ASSERT(ip->i_d.di_anextents > 0); | ||
457 | #endif | ||
458 | #ifdef XFS_NATIVE_HOST | 362 | #ifdef XFS_NATIVE_HOST |
459 | /* | 363 | /* |
460 | * There are not delayed allocation extents | 364 | * There are not delayed allocation extents |
@@ -471,29 +375,36 @@ xfs_inode_item_format( | |||
471 | iip->ili_format.ilf_asize = vecp->i_len; | 375 | iip->ili_format.ilf_asize = vecp->i_len; |
472 | vecp++; | 376 | vecp++; |
473 | nvecs++; | 377 | nvecs++; |
378 | } else { | ||
379 | iip->ili_fields &= ~XFS_ILOG_AEXT; | ||
474 | } | 380 | } |
475 | break; | 381 | break; |
476 | 382 | ||
477 | case XFS_DINODE_FMT_BTREE: | 383 | case XFS_DINODE_FMT_BTREE: |
478 | ASSERT(!(iip->ili_format.ilf_fields & | 384 | iip->ili_fields &= |
479 | (XFS_ILOG_ADATA | XFS_ILOG_AEXT))); | 385 | ~(XFS_ILOG_ADATA | XFS_ILOG_AEXT); |
480 | if (iip->ili_format.ilf_fields & XFS_ILOG_ABROOT) { | 386 | |
481 | ASSERT(ip->i_afp->if_broot_bytes > 0); | 387 | if ((iip->ili_fields & XFS_ILOG_ABROOT) && |
388 | ip->i_afp->if_broot_bytes > 0) { | ||
482 | ASSERT(ip->i_afp->if_broot != NULL); | 389 | ASSERT(ip->i_afp->if_broot != NULL); |
390 | |||
483 | vecp->i_addr = ip->i_afp->if_broot; | 391 | vecp->i_addr = ip->i_afp->if_broot; |
484 | vecp->i_len = ip->i_afp->if_broot_bytes; | 392 | vecp->i_len = ip->i_afp->if_broot_bytes; |
485 | vecp->i_type = XLOG_REG_TYPE_IATTR_BROOT; | 393 | vecp->i_type = XLOG_REG_TYPE_IATTR_BROOT; |
486 | vecp++; | 394 | vecp++; |
487 | nvecs++; | 395 | nvecs++; |
488 | iip->ili_format.ilf_asize = ip->i_afp->if_broot_bytes; | 396 | iip->ili_format.ilf_asize = ip->i_afp->if_broot_bytes; |
397 | } else { | ||
398 | iip->ili_fields &= ~XFS_ILOG_ABROOT; | ||
489 | } | 399 | } |
490 | break; | 400 | break; |
491 | 401 | ||
492 | case XFS_DINODE_FMT_LOCAL: | 402 | case XFS_DINODE_FMT_LOCAL: |
493 | ASSERT(!(iip->ili_format.ilf_fields & | 403 | iip->ili_fields &= |
494 | (XFS_ILOG_ABROOT | XFS_ILOG_AEXT))); | 404 | ~(XFS_ILOG_AEXT | XFS_ILOG_ABROOT); |
495 | if (iip->ili_format.ilf_fields & XFS_ILOG_ADATA) { | 405 | |
496 | ASSERT(ip->i_afp->if_bytes > 0); | 406 | if ((iip->ili_fields & XFS_ILOG_ADATA) && |
407 | ip->i_afp->if_bytes > 0) { | ||
497 | ASSERT(ip->i_afp->if_u1.if_data != NULL); | 408 | ASSERT(ip->i_afp->if_u1.if_data != NULL); |
498 | 409 | ||
499 | vecp->i_addr = ip->i_afp->if_u1.if_data; | 410 | vecp->i_addr = ip->i_afp->if_u1.if_data; |
@@ -510,6 +421,8 @@ xfs_inode_item_format( | |||
510 | vecp++; | 421 | vecp++; |
511 | nvecs++; | 422 | nvecs++; |
512 | iip->ili_format.ilf_asize = (unsigned)data_bytes; | 423 | iip->ili_format.ilf_asize = (unsigned)data_bytes; |
424 | } else { | ||
425 | iip->ili_fields &= ~XFS_ILOG_ADATA; | ||
513 | } | 426 | } |
514 | break; | 427 | break; |
515 | 428 | ||
@@ -518,6 +431,15 @@ xfs_inode_item_format( | |||
518 | break; | 431 | break; |
519 | } | 432 | } |
520 | 433 | ||
434 | out: | ||
435 | /* | ||
436 | * Now update the log format that goes out to disk from the in-core | ||
437 | * values. We always write the inode core to make the arithmetic | ||
438 | * games in recovery easier, which isn't a big deal as just about any | ||
439 | * transaction would dirty it anyway. | ||
440 | */ | ||
441 | iip->ili_format.ilf_fields = XFS_ILOG_CORE | | ||
442 | (iip->ili_fields & ~XFS_ILOG_TIMESTAMP); | ||
521 | iip->ili_format.ilf_size = nvecs; | 443 | iip->ili_format.ilf_size = nvecs; |
522 | } | 444 | } |
523 | 445 | ||
@@ -596,17 +518,13 @@ xfs_inode_item_trylock( | |||
596 | /* Stale items should force out the iclog */ | 518 | /* Stale items should force out the iclog */ |
597 | if (ip->i_flags & XFS_ISTALE) { | 519 | if (ip->i_flags & XFS_ISTALE) { |
598 | xfs_ifunlock(ip); | 520 | xfs_ifunlock(ip); |
599 | /* | 521 | xfs_iunlock(ip, XFS_ILOCK_SHARED); |
600 | * we hold the AIL lock - notify the unlock routine of this | ||
601 | * so it doesn't try to get the lock again. | ||
602 | */ | ||
603 | xfs_iunlock(ip, XFS_ILOCK_SHARED|XFS_IUNLOCK_NONOTIFY); | ||
604 | return XFS_ITEM_PINNED; | 522 | return XFS_ITEM_PINNED; |
605 | } | 523 | } |
606 | 524 | ||
607 | #ifdef DEBUG | 525 | #ifdef DEBUG |
608 | if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) { | 526 | if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) { |
609 | ASSERT(iip->ili_format.ilf_fields != 0); | 527 | ASSERT(iip->ili_fields != 0); |
610 | ASSERT(iip->ili_logged == 0); | 528 | ASSERT(iip->ili_logged == 0); |
611 | ASSERT(lip->li_flags & XFS_LI_IN_AIL); | 529 | ASSERT(lip->li_flags & XFS_LI_IN_AIL); |
612 | } | 530 | } |
@@ -638,7 +556,7 @@ xfs_inode_item_unlock( | |||
638 | if (iip->ili_extents_buf != NULL) { | 556 | if (iip->ili_extents_buf != NULL) { |
639 | ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS); | 557 | ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS); |
640 | ASSERT(ip->i_d.di_nextents > 0); | 558 | ASSERT(ip->i_d.di_nextents > 0); |
641 | ASSERT(iip->ili_format.ilf_fields & XFS_ILOG_DEXT); | 559 | ASSERT(iip->ili_fields & XFS_ILOG_DEXT); |
642 | ASSERT(ip->i_df.if_bytes > 0); | 560 | ASSERT(ip->i_df.if_bytes > 0); |
643 | kmem_free(iip->ili_extents_buf); | 561 | kmem_free(iip->ili_extents_buf); |
644 | iip->ili_extents_buf = NULL; | 562 | iip->ili_extents_buf = NULL; |
@@ -646,7 +564,7 @@ xfs_inode_item_unlock( | |||
646 | if (iip->ili_aextents_buf != NULL) { | 564 | if (iip->ili_aextents_buf != NULL) { |
647 | ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS); | 565 | ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS); |
648 | ASSERT(ip->i_d.di_anextents > 0); | 566 | ASSERT(ip->i_d.di_anextents > 0); |
649 | ASSERT(iip->ili_format.ilf_fields & XFS_ILOG_AEXT); | 567 | ASSERT(iip->ili_fields & XFS_ILOG_AEXT); |
650 | ASSERT(ip->i_afp->if_bytes > 0); | 568 | ASSERT(ip->i_afp->if_bytes > 0); |
651 | kmem_free(iip->ili_aextents_buf); | 569 | kmem_free(iip->ili_aextents_buf); |
652 | iip->ili_aextents_buf = NULL; | 570 | iip->ili_aextents_buf = NULL; |
@@ -761,8 +679,7 @@ xfs_inode_item_push( | |||
761 | * lock without sleeping, then there must not have been | 679 | * lock without sleeping, then there must not have been |
762 | * anyone in the process of flushing the inode. | 680 | * anyone in the process of flushing the inode. |
763 | */ | 681 | */ |
764 | ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || | 682 | ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || iip->ili_fields != 0); |
765 | iip->ili_format.ilf_fields != 0); | ||
766 | 683 | ||
767 | /* | 684 | /* |
768 | * Push the inode to it's backing buffer. This will not remove the | 685 | * Push the inode to it's backing buffer. This will not remove the |
@@ -985,7 +902,7 @@ xfs_iflush_abort( | |||
985 | * Clear the inode logging fields so no more flushes are | 902 | * Clear the inode logging fields so no more flushes are |
986 | * attempted. | 903 | * attempted. |
987 | */ | 904 | */ |
988 | iip->ili_format.ilf_fields = 0; | 905 | iip->ili_fields = 0; |
989 | } | 906 | } |
990 | /* | 907 | /* |
991 | * Release the inode's flush lock since we're done with it. | 908 | * Release the inode's flush lock since we're done with it. |