aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_inode_item.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2012-02-29 04:53:53 -0500
committerBen Myers <bpm@sgi.com>2012-03-13 18:05:08 -0400
commit339a5f5dd9d3ac3d68a594d81507e1eab77ed223 (patch)
tree53419a7d43830e399ca7eaaa15488d68423bbd80 /fs/xfs/xfs_inode_item.c
parent8a9c9980f24f6d86e0ec0150ed35fba45d0c9f88 (diff)
xfs: make xfs_inode_item_size idempotent
Move all code messing with the inode log item flags into xfs_inode_item_format to make sure xfs_inode_item_size really only calculates the the number of vectors, but doesn't modify any state of the inode item. Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Mark Tinguely <tinguely@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_inode_item.c')
-rw-r--r--fs/xfs/xfs_inode_item.c215
1 files changed, 83 insertions, 132 deletions
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index 7a60da64f31..965d3d08362 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 &=
69 ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT |
70 XFS_ILOG_DEV | XFS_ILOG_UUID);
71 if ((iip->ili_format.ilf_fields & XFS_ILOG_DEXT) && 62 if ((iip->ili_format.ilf_fields & XFS_ILOG_DEXT) &&
72 (ip->i_d.di_nextents > 0) && 63 ip->i_d.di_nextents > 0 &&
73 (ip->i_df.if_bytes > 0)) { 64 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 &=
83 ~(XFS_ILOG_DDATA | XFS_ILOG_DEXT |
84 XFS_ILOG_DEV | XFS_ILOG_UUID);
85 if ((iip->ili_format.ilf_fields & XFS_ILOG_DBROOT) && 69 if ((iip->ili_format.ilf_fields & XFS_ILOG_DBROOT) &&
86 (ip->i_df.if_broot_bytes > 0)) { 70 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 &=
109 ~(XFS_ILOG_DEXT | XFS_ILOG_DBROOT |
110 XFS_ILOG_DEV | XFS_ILOG_UUID);
111 if ((iip->ili_format.ilf_fields & XFS_ILOG_DDATA) && 75 if ((iip->ili_format.ilf_fields & XFS_ILOG_DDATA) &&
112 (ip->i_df.if_bytes > 0)) { 76 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 &=
155 ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT);
156 if ((iip->ili_format.ilf_fields & XFS_ILOG_AEXT) && 98 if ((iip->ili_format.ilf_fields & XFS_ILOG_AEXT) &&
157 (ip->i_d.di_anextents > 0) && 99 ip->i_d.di_anextents > 0 &&
158 (ip->i_afp->if_bytes > 0)) { 100 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 &=
168 ~(XFS_ILOG_ADATA | XFS_ILOG_AEXT);
169 if ((iip->ili_format.ilf_fields & XFS_ILOG_ABROOT) && 105 if ((iip->ili_format.ilf_fields & XFS_ILOG_ABROOT) &&
170 (ip->i_afp->if_broot_bytes > 0)) { 106 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 &=
180 ~(XFS_ILOG_AEXT | XFS_ILOG_ABROOT);
181 if ((iip->ili_format.ilf_fields & XFS_ILOG_ADATA) && 111 if ((iip->ili_format.ilf_fields & XFS_ILOG_ADATA) &&
182 (ip->i_afp->if_bytes > 0)) { 112 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:
@@ -292,16 +218,17 @@ xfs_inode_item_format(
292 218
293 switch (ip->i_d.di_format) { 219 switch (ip->i_d.di_format) {
294 case XFS_DINODE_FMT_EXTENTS: 220 case XFS_DINODE_FMT_EXTENTS:
295 ASSERT(!(iip->ili_format.ilf_fields & 221 iip->ili_format.ilf_fields &=
296 (XFS_ILOG_DDATA | XFS_ILOG_DBROOT | 222 ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT |
297 XFS_ILOG_DEV | XFS_ILOG_UUID))); 223 XFS_ILOG_DEV | XFS_ILOG_UUID);
298 if (iip->ili_format.ilf_fields & XFS_ILOG_DEXT) { 224
299 ASSERT(ip->i_df.if_bytes > 0); 225 if ((iip->ili_format.ilf_fields & XFS_ILOG_DEXT) &&
226 ip->i_d.di_nextents > 0 &&
227 ip->i_df.if_bytes > 0) {
300 ASSERT(ip->i_df.if_u1.if_extents != NULL); 228 ASSERT(ip->i_df.if_u1.if_extents != NULL);
301 ASSERT(ip->i_d.di_nextents > 0); 229 ASSERT(ip->i_df.if_bytes / sizeof(xfs_bmbt_rec_t) > 0);
302 ASSERT(iip->ili_extents_buf == NULL); 230 ASSERT(iip->ili_extents_buf == NULL);
303 ASSERT((ip->i_df.if_bytes / 231
304 (uint)sizeof(xfs_bmbt_rec_t)) > 0);
305#ifdef XFS_NATIVE_HOST 232#ifdef XFS_NATIVE_HOST
306 if (ip->i_d.di_nextents == ip->i_df.if_bytes / 233 if (ip->i_d.di_nextents == ip->i_df.if_bytes /
307 (uint)sizeof(xfs_bmbt_rec_t)) { 234 (uint)sizeof(xfs_bmbt_rec_t)) {
@@ -323,15 +250,18 @@ xfs_inode_item_format(
323 iip->ili_format.ilf_dsize = vecp->i_len; 250 iip->ili_format.ilf_dsize = vecp->i_len;
324 vecp++; 251 vecp++;
325 nvecs++; 252 nvecs++;
253 } else {
254 iip->ili_format.ilf_fields &= ~XFS_ILOG_DEXT;
326 } 255 }
327 break; 256 break;
328 257
329 case XFS_DINODE_FMT_BTREE: 258 case XFS_DINODE_FMT_BTREE:
330 ASSERT(!(iip->ili_format.ilf_fields & 259 iip->ili_format.ilf_fields &=
331 (XFS_ILOG_DDATA | XFS_ILOG_DEXT | 260 ~(XFS_ILOG_DDATA | XFS_ILOG_DEXT |
332 XFS_ILOG_DEV | XFS_ILOG_UUID))); 261 XFS_ILOG_DEV | XFS_ILOG_UUID);
333 if (iip->ili_format.ilf_fields & XFS_ILOG_DBROOT) { 262
334 ASSERT(ip->i_df.if_broot_bytes > 0); 263 if ((iip->ili_format.ilf_fields & XFS_ILOG_DBROOT) &&
264 ip->i_df.if_broot_bytes > 0) {
335 ASSERT(ip->i_df.if_broot != NULL); 265 ASSERT(ip->i_df.if_broot != NULL);
336 vecp->i_addr = ip->i_df.if_broot; 266 vecp->i_addr = ip->i_df.if_broot;
337 vecp->i_len = ip->i_df.if_broot_bytes; 267 vecp->i_len = ip->i_df.if_broot_bytes;
@@ -339,15 +269,30 @@ xfs_inode_item_format(
339 vecp++; 269 vecp++;
340 nvecs++; 270 nvecs++;
341 iip->ili_format.ilf_dsize = ip->i_df.if_broot_bytes; 271 iip->ili_format.ilf_dsize = ip->i_df.if_broot_bytes;
272 } else {
273 ASSERT(!(iip->ili_format.ilf_fields &
274 XFS_ILOG_DBROOT));
275#ifdef XFS_TRANS_DEBUG
276 if (iip->ili_root_size > 0) {
277 ASSERT(iip->ili_root_size ==
278 ip->i_df.if_broot_bytes);
279 ASSERT(memcmp(iip->ili_orig_root,
280 ip->i_df.if_broot,
281 iip->ili_root_size) == 0);
282 } else {
283 ASSERT(ip->i_df.if_broot_bytes == 0);
284 }
285#endif
286 iip->ili_format.ilf_fields &= ~XFS_ILOG_DBROOT;
342 } 287 }
343 break; 288 break;
344 289
345 case XFS_DINODE_FMT_LOCAL: 290 case XFS_DINODE_FMT_LOCAL:
346 ASSERT(!(iip->ili_format.ilf_fields & 291 iip->ili_format.ilf_fields &=
347 (XFS_ILOG_DBROOT | XFS_ILOG_DEXT | 292 ~(XFS_ILOG_DEXT | XFS_ILOG_DBROOT |
348 XFS_ILOG_DEV | XFS_ILOG_UUID))); 293 XFS_ILOG_DEV | XFS_ILOG_UUID);
349 if (iip->ili_format.ilf_fields & XFS_ILOG_DDATA) { 294 if ((iip->ili_format.ilf_fields & XFS_ILOG_DDATA) &&
350 ASSERT(ip->i_df.if_bytes > 0); 295 ip->i_df.if_bytes > 0) {
351 ASSERT(ip->i_df.if_u1.if_data != NULL); 296 ASSERT(ip->i_df.if_u1.if_data != NULL);
352 ASSERT(ip->i_d.di_size > 0); 297 ASSERT(ip->i_d.di_size > 0);
353 298
@@ -365,13 +310,15 @@ xfs_inode_item_format(
365 vecp++; 310 vecp++;
366 nvecs++; 311 nvecs++;
367 iip->ili_format.ilf_dsize = (unsigned)data_bytes; 312 iip->ili_format.ilf_dsize = (unsigned)data_bytes;
313 } else {
314 iip->ili_format.ilf_fields &= ~XFS_ILOG_DDATA;
368 } 315 }
369 break; 316 break;
370 317
371 case XFS_DINODE_FMT_DEV: 318 case XFS_DINODE_FMT_DEV:
372 ASSERT(!(iip->ili_format.ilf_fields & 319 iip->ili_format.ilf_fields &=
373 (XFS_ILOG_DBROOT | XFS_ILOG_DEXT | 320 ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT |
374 XFS_ILOG_DDATA | XFS_ILOG_UUID))); 321 XFS_ILOG_DEXT | XFS_ILOG_UUID);
375 if (iip->ili_format.ilf_fields & XFS_ILOG_DEV) { 322 if (iip->ili_format.ilf_fields & XFS_ILOG_DEV) {
376 iip->ili_format.ilf_u.ilfu_rdev = 323 iip->ili_format.ilf_u.ilfu_rdev =
377 ip->i_df.if_u2.if_rdev; 324 ip->i_df.if_u2.if_rdev;
@@ -379,9 +326,9 @@ xfs_inode_item_format(
379 break; 326 break;
380 327
381 case XFS_DINODE_FMT_UUID: 328 case XFS_DINODE_FMT_UUID:
382 ASSERT(!(iip->ili_format.ilf_fields & 329 iip->ili_format.ilf_fields &=
383 (XFS_ILOG_DBROOT | XFS_ILOG_DEXT | 330 ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT |
384 XFS_ILOG_DDATA | XFS_ILOG_DEV))); 331 XFS_ILOG_DEXT | XFS_ILOG_DEV);
385 if (iip->ili_format.ilf_fields & XFS_ILOG_UUID) { 332 if (iip->ili_format.ilf_fields & XFS_ILOG_UUID) {
386 iip->ili_format.ilf_u.ilfu_uuid = 333 iip->ili_format.ilf_u.ilfu_uuid =
387 ip->i_df.if_u2.if_uuid; 334 ip->i_df.if_u2.if_uuid;
@@ -394,31 +341,26 @@ xfs_inode_item_format(
394 } 341 }
395 342
396 /* 343 /*
397 * If there are no attributes associated with the file, 344 * If there are no attributes associated with the file, then we're done.
398 * then we're done.
399 * Assert that no attribute-related log flags are set.
400 */ 345 */
401 if (!XFS_IFORK_Q(ip)) { 346 if (!XFS_IFORK_Q(ip)) {
402 iip->ili_format.ilf_size = nvecs; 347 iip->ili_format.ilf_size = nvecs;
403 ASSERT(!(iip->ili_format.ilf_fields & 348 iip->ili_format.ilf_fields &=
404 (XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT))); 349 ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT);
405 return; 350 return;
406 } 351 }
407 352
408 switch (ip->i_d.di_aformat) { 353 switch (ip->i_d.di_aformat) {
409 case XFS_DINODE_FMT_EXTENTS: 354 case XFS_DINODE_FMT_EXTENTS:
410 ASSERT(!(iip->ili_format.ilf_fields & 355 iip->ili_format.ilf_fields &=
411 (XFS_ILOG_ADATA | XFS_ILOG_ABROOT))); 356 ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT);
412 if (iip->ili_format.ilf_fields & XFS_ILOG_AEXT) { 357
413#ifdef DEBUG 358 if ((iip->ili_format.ilf_fields & XFS_ILOG_AEXT) &&
414 int nrecs = ip->i_afp->if_bytes / 359 ip->i_d.di_anextents > 0 &&
415 (uint)sizeof(xfs_bmbt_rec_t); 360 ip->i_afp->if_bytes > 0) {
416 ASSERT(nrecs > 0); 361 ASSERT(ip->i_afp->if_bytes / sizeof(xfs_bmbt_rec_t) ==
417 ASSERT(nrecs == ip->i_d.di_anextents); 362 ip->i_d.di_anextents);
418 ASSERT(ip->i_afp->if_bytes > 0);
419 ASSERT(ip->i_afp->if_u1.if_extents != NULL); 363 ASSERT(ip->i_afp->if_u1.if_extents != NULL);
420 ASSERT(ip->i_d.di_anextents > 0);
421#endif
422#ifdef XFS_NATIVE_HOST 364#ifdef XFS_NATIVE_HOST
423 /* 365 /*
424 * There are not delayed allocation extents 366 * There are not delayed allocation extents
@@ -435,29 +377,36 @@ xfs_inode_item_format(
435 iip->ili_format.ilf_asize = vecp->i_len; 377 iip->ili_format.ilf_asize = vecp->i_len;
436 vecp++; 378 vecp++;
437 nvecs++; 379 nvecs++;
380 } else {
381 iip->ili_format.ilf_fields &= ~XFS_ILOG_AEXT;
438 } 382 }
439 break; 383 break;
440 384
441 case XFS_DINODE_FMT_BTREE: 385 case XFS_DINODE_FMT_BTREE:
442 ASSERT(!(iip->ili_format.ilf_fields & 386 iip->ili_format.ilf_fields &=
443 (XFS_ILOG_ADATA | XFS_ILOG_AEXT))); 387 ~(XFS_ILOG_ADATA | XFS_ILOG_AEXT);
444 if (iip->ili_format.ilf_fields & XFS_ILOG_ABROOT) { 388
445 ASSERT(ip->i_afp->if_broot_bytes > 0); 389 if ((iip->ili_format.ilf_fields & XFS_ILOG_ABROOT) &&
390 ip->i_afp->if_broot_bytes > 0) {
446 ASSERT(ip->i_afp->if_broot != NULL); 391 ASSERT(ip->i_afp->if_broot != NULL);
392
447 vecp->i_addr = ip->i_afp->if_broot; 393 vecp->i_addr = ip->i_afp->if_broot;
448 vecp->i_len = ip->i_afp->if_broot_bytes; 394 vecp->i_len = ip->i_afp->if_broot_bytes;
449 vecp->i_type = XLOG_REG_TYPE_IATTR_BROOT; 395 vecp->i_type = XLOG_REG_TYPE_IATTR_BROOT;
450 vecp++; 396 vecp++;
451 nvecs++; 397 nvecs++;
452 iip->ili_format.ilf_asize = ip->i_afp->if_broot_bytes; 398 iip->ili_format.ilf_asize = ip->i_afp->if_broot_bytes;
399 } else {
400 iip->ili_format.ilf_fields &= ~XFS_ILOG_ABROOT;
453 } 401 }
454 break; 402 break;
455 403
456 case XFS_DINODE_FMT_LOCAL: 404 case XFS_DINODE_FMT_LOCAL:
457 ASSERT(!(iip->ili_format.ilf_fields & 405 iip->ili_format.ilf_fields &=
458 (XFS_ILOG_ABROOT | XFS_ILOG_AEXT))); 406 ~(XFS_ILOG_AEXT | XFS_ILOG_ABROOT);
459 if (iip->ili_format.ilf_fields & XFS_ILOG_ADATA) { 407
460 ASSERT(ip->i_afp->if_bytes > 0); 408 if ((iip->ili_format.ilf_fields & XFS_ILOG_ADATA) &&
409 ip->i_afp->if_bytes > 0) {
461 ASSERT(ip->i_afp->if_u1.if_data != NULL); 410 ASSERT(ip->i_afp->if_u1.if_data != NULL);
462 411
463 vecp->i_addr = ip->i_afp->if_u1.if_data; 412 vecp->i_addr = ip->i_afp->if_u1.if_data;
@@ -474,6 +423,8 @@ xfs_inode_item_format(
474 vecp++; 423 vecp++;
475 nvecs++; 424 nvecs++;
476 iip->ili_format.ilf_asize = (unsigned)data_bytes; 425 iip->ili_format.ilf_asize = (unsigned)data_bytes;
426 } else {
427 iip->ili_format.ilf_fields &= ~XFS_ILOG_ADATA;
477 } 428 }
478 break; 429 break;
479 430