diff options
author | Christoph Hellwig <hch@infradead.org> | 2013-12-12 19:00:43 -0500 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2013-12-12 19:00:43 -0500 |
commit | 3de559fbd04d67473b9be2bd183823c40c4b7557 (patch) | |
tree | aa3ba1c495f9a57362d4e9c77e6005bb43a44cde /fs/xfs/xfs_inode_item.c | |
parent | ce9641d6c981aad0463b2d1455f0b60e5c8671c5 (diff) |
xfs: refactor xfs_inode_item_format
Split out a function to handle the data and attr fork, as well as a
helper for the really old v1 inodes.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs/xfs_inode_item.c')
-rw-r--r-- | fs/xfs/xfs_inode_item.c | 165 |
1 files changed, 89 insertions, 76 deletions
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 050d2540f7b4..2ad12dcf8311 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c | |||
@@ -180,63 +180,41 @@ xfs_inode_item_format_extents( | |||
180 | } | 180 | } |
181 | 181 | ||
182 | /* | 182 | /* |
183 | * This is called to fill in the vector of log iovecs for the | 183 | * If this is a v1 format inode, then we need to log it as such. This means |
184 | * given inode log item. It fills the first item with an inode | 184 | * that we have to copy the link count from the new field to the old. We |
185 | * log format structure, the second with the on-disk inode structure, | 185 | * don't have to worry about the new fields, because nothing trusts them as |
186 | * and a possible third and/or fourth with the inode data/extents/b-tree | 186 | * long as the old inode version number is there. |
187 | * root and inode attributes data/extents/b-tree root. | ||
188 | */ | 187 | */ |
189 | STATIC void | 188 | STATIC void |
190 | xfs_inode_item_format( | 189 | xfs_inode_item_format_v1_inode( |
191 | struct xfs_log_item *lip, | 190 | struct xfs_inode *ip) |
192 | struct xfs_log_iovec *vecp) | 191 | { |
192 | if (!xfs_sb_version_hasnlink(&ip->i_mount->m_sb)) { | ||
193 | /* | ||
194 | * Convert it back. | ||
195 | */ | ||
196 | ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1); | ||
197 | ip->i_d.di_onlink = ip->i_d.di_nlink; | ||
198 | } else { | ||
199 | /* | ||
200 | * The superblock version has already been bumped, | ||
201 | * so just make the conversion to the new inode | ||
202 | * format permanent. | ||
203 | */ | ||
204 | ip->i_d.di_version = 2; | ||
205 | ip->i_d.di_onlink = 0; | ||
206 | memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); | ||
207 | } | ||
208 | } | ||
209 | |||
210 | STATIC struct xfs_log_iovec * | ||
211 | xfs_inode_item_format_data_fork( | ||
212 | struct xfs_inode_log_item *iip, | ||
213 | struct xfs_log_iovec *vecp, | ||
214 | int *nvecs) | ||
193 | { | 215 | { |
194 | struct xfs_inode_log_item *iip = INODE_ITEM(lip); | ||
195 | struct xfs_inode *ip = iip->ili_inode; | 216 | struct xfs_inode *ip = iip->ili_inode; |
196 | uint nvecs; | ||
197 | size_t data_bytes; | 217 | size_t data_bytes; |
198 | xfs_mount_t *mp; | ||
199 | |||
200 | vecp->i_addr = &iip->ili_format; | ||
201 | vecp->i_len = sizeof(xfs_inode_log_format_t); | ||
202 | vecp->i_type = XLOG_REG_TYPE_IFORMAT; | ||
203 | vecp++; | ||
204 | nvecs = 1; | ||
205 | |||
206 | vecp->i_addr = &ip->i_d; | ||
207 | vecp->i_len = xfs_icdinode_size(ip->i_d.di_version); | ||
208 | vecp->i_type = XLOG_REG_TYPE_ICORE; | ||
209 | vecp++; | ||
210 | nvecs++; | ||
211 | |||
212 | /* | ||
213 | * If this is really an old format inode, then we need to | ||
214 | * log it as such. This means that we have to copy the link | ||
215 | * count from the new field to the old. We don't have to worry | ||
216 | * about the new fields, because nothing trusts them as long as | ||
217 | * the old inode version number is there. If the superblock already | ||
218 | * has a new version number, then we don't bother converting back. | ||
219 | */ | ||
220 | mp = ip->i_mount; | ||
221 | ASSERT(ip->i_d.di_version == 1 || xfs_sb_version_hasnlink(&mp->m_sb)); | ||
222 | if (ip->i_d.di_version == 1) { | ||
223 | if (!xfs_sb_version_hasnlink(&mp->m_sb)) { | ||
224 | /* | ||
225 | * Convert it back. | ||
226 | */ | ||
227 | ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1); | ||
228 | ip->i_d.di_onlink = ip->i_d.di_nlink; | ||
229 | } else { | ||
230 | /* | ||
231 | * The superblock version has already been bumped, | ||
232 | * so just make the conversion to the new inode | ||
233 | * format permanent. | ||
234 | */ | ||
235 | ip->i_d.di_version = 2; | ||
236 | ip->i_d.di_onlink = 0; | ||
237 | memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); | ||
238 | } | ||
239 | } | ||
240 | 218 | ||
241 | switch (ip->i_d.di_format) { | 219 | switch (ip->i_d.di_format) { |
242 | case XFS_DINODE_FMT_EXTENTS: | 220 | case XFS_DINODE_FMT_EXTENTS: |
@@ -271,12 +249,11 @@ xfs_inode_item_format( | |||
271 | ASSERT(vecp->i_len <= ip->i_df.if_bytes); | 249 | ASSERT(vecp->i_len <= ip->i_df.if_bytes); |
272 | iip->ili_format.ilf_dsize = vecp->i_len; | 250 | iip->ili_format.ilf_dsize = vecp->i_len; |
273 | vecp++; | 251 | vecp++; |
274 | nvecs++; | 252 | (*nvecs)++; |
275 | } else { | 253 | } else { |
276 | iip->ili_fields &= ~XFS_ILOG_DEXT; | 254 | iip->ili_fields &= ~XFS_ILOG_DEXT; |
277 | } | 255 | } |
278 | break; | 256 | break; |
279 | |||
280 | case XFS_DINODE_FMT_BTREE: | 257 | case XFS_DINODE_FMT_BTREE: |
281 | iip->ili_fields &= | 258 | iip->ili_fields &= |
282 | ~(XFS_ILOG_DDATA | XFS_ILOG_DEXT | | 259 | ~(XFS_ILOG_DDATA | XFS_ILOG_DEXT | |
@@ -289,7 +266,7 @@ xfs_inode_item_format( | |||
289 | vecp->i_len = ip->i_df.if_broot_bytes; | 266 | vecp->i_len = ip->i_df.if_broot_bytes; |
290 | vecp->i_type = XLOG_REG_TYPE_IBROOT; | 267 | vecp->i_type = XLOG_REG_TYPE_IBROOT; |
291 | vecp++; | 268 | vecp++; |
292 | nvecs++; | 269 | (*nvecs)++; |
293 | iip->ili_format.ilf_dsize = ip->i_df.if_broot_bytes; | 270 | iip->ili_format.ilf_dsize = ip->i_df.if_broot_bytes; |
294 | } else { | 271 | } else { |
295 | ASSERT(!(iip->ili_fields & | 272 | ASSERT(!(iip->ili_fields & |
@@ -297,7 +274,6 @@ xfs_inode_item_format( | |||
297 | iip->ili_fields &= ~XFS_ILOG_DBROOT; | 274 | iip->ili_fields &= ~XFS_ILOG_DBROOT; |
298 | } | 275 | } |
299 | break; | 276 | break; |
300 | |||
301 | case XFS_DINODE_FMT_LOCAL: | 277 | case XFS_DINODE_FMT_LOCAL: |
302 | iip->ili_fields &= | 278 | iip->ili_fields &= |
303 | ~(XFS_ILOG_DEXT | XFS_ILOG_DBROOT | | 279 | ~(XFS_ILOG_DEXT | XFS_ILOG_DBROOT | |
@@ -319,13 +295,12 @@ xfs_inode_item_format( | |||
319 | vecp->i_len = (int)data_bytes; | 295 | vecp->i_len = (int)data_bytes; |
320 | vecp->i_type = XLOG_REG_TYPE_ILOCAL; | 296 | vecp->i_type = XLOG_REG_TYPE_ILOCAL; |
321 | vecp++; | 297 | vecp++; |
322 | nvecs++; | 298 | (*nvecs)++; |
323 | iip->ili_format.ilf_dsize = (unsigned)data_bytes; | 299 | iip->ili_format.ilf_dsize = (unsigned)data_bytes; |
324 | } else { | 300 | } else { |
325 | iip->ili_fields &= ~XFS_ILOG_DDATA; | 301 | iip->ili_fields &= ~XFS_ILOG_DDATA; |
326 | } | 302 | } |
327 | break; | 303 | break; |
328 | |||
329 | case XFS_DINODE_FMT_DEV: | 304 | case XFS_DINODE_FMT_DEV: |
330 | iip->ili_fields &= | 305 | iip->ili_fields &= |
331 | ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | | 306 | ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | |
@@ -335,7 +310,6 @@ xfs_inode_item_format( | |||
335 | ip->i_df.if_u2.if_rdev; | 310 | ip->i_df.if_u2.if_rdev; |
336 | } | 311 | } |
337 | break; | 312 | break; |
338 | |||
339 | case XFS_DINODE_FMT_UUID: | 313 | case XFS_DINODE_FMT_UUID: |
340 | iip->ili_fields &= | 314 | iip->ili_fields &= |
341 | ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | | 315 | ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | |
@@ -345,20 +319,22 @@ xfs_inode_item_format( | |||
345 | ip->i_df.if_u2.if_uuid; | 319 | ip->i_df.if_u2.if_uuid; |
346 | } | 320 | } |
347 | break; | 321 | break; |
348 | |||
349 | default: | 322 | default: |
350 | ASSERT(0); | 323 | ASSERT(0); |
351 | break; | 324 | break; |
352 | } | 325 | } |
353 | 326 | ||
354 | /* | 327 | return vecp; |
355 | * If there are no attributes associated with the file, then we're done. | 328 | } |
356 | */ | 329 | |
357 | if (!XFS_IFORK_Q(ip)) { | 330 | STATIC struct xfs_log_iovec * |
358 | iip->ili_fields &= | 331 | xfs_inode_item_format_attr_fork( |
359 | ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT); | 332 | struct xfs_inode_log_item *iip, |
360 | goto out; | 333 | struct xfs_log_iovec *vecp, |
361 | } | 334 | int *nvecs) |
335 | { | ||
336 | struct xfs_inode *ip = iip->ili_inode; | ||
337 | size_t data_bytes; | ||
362 | 338 | ||
363 | switch (ip->i_d.di_aformat) { | 339 | switch (ip->i_d.di_aformat) { |
364 | case XFS_DINODE_FMT_EXTENTS: | 340 | case XFS_DINODE_FMT_EXTENTS: |
@@ -386,12 +362,11 @@ xfs_inode_item_format( | |||
386 | #endif | 362 | #endif |
387 | iip->ili_format.ilf_asize = vecp->i_len; | 363 | iip->ili_format.ilf_asize = vecp->i_len; |
388 | vecp++; | 364 | vecp++; |
389 | nvecs++; | 365 | (*nvecs)++; |
390 | } else { | 366 | } else { |
391 | iip->ili_fields &= ~XFS_ILOG_AEXT; | 367 | iip->ili_fields &= ~XFS_ILOG_AEXT; |
392 | } | 368 | } |
393 | break; | 369 | break; |
394 | |||
395 | case XFS_DINODE_FMT_BTREE: | 370 | case XFS_DINODE_FMT_BTREE: |
396 | iip->ili_fields &= | 371 | iip->ili_fields &= |
397 | ~(XFS_ILOG_ADATA | XFS_ILOG_AEXT); | 372 | ~(XFS_ILOG_ADATA | XFS_ILOG_AEXT); |
@@ -404,13 +379,12 @@ xfs_inode_item_format( | |||
404 | vecp->i_len = ip->i_afp->if_broot_bytes; | 379 | vecp->i_len = ip->i_afp->if_broot_bytes; |
405 | vecp->i_type = XLOG_REG_TYPE_IATTR_BROOT; | 380 | vecp->i_type = XLOG_REG_TYPE_IATTR_BROOT; |
406 | vecp++; | 381 | vecp++; |
407 | nvecs++; | 382 | (*nvecs)++; |
408 | iip->ili_format.ilf_asize = ip->i_afp->if_broot_bytes; | 383 | iip->ili_format.ilf_asize = ip->i_afp->if_broot_bytes; |
409 | } else { | 384 | } else { |
410 | iip->ili_fields &= ~XFS_ILOG_ABROOT; | 385 | iip->ili_fields &= ~XFS_ILOG_ABROOT; |
411 | } | 386 | } |
412 | break; | 387 | break; |
413 | |||
414 | case XFS_DINODE_FMT_LOCAL: | 388 | case XFS_DINODE_FMT_LOCAL: |
415 | iip->ili_fields &= | 389 | iip->ili_fields &= |
416 | ~(XFS_ILOG_AEXT | XFS_ILOG_ABROOT); | 390 | ~(XFS_ILOG_AEXT | XFS_ILOG_ABROOT); |
@@ -431,19 +405,59 @@ xfs_inode_item_format( | |||
431 | vecp->i_len = (int)data_bytes; | 405 | vecp->i_len = (int)data_bytes; |
432 | vecp->i_type = XLOG_REG_TYPE_IATTR_LOCAL; | 406 | vecp->i_type = XLOG_REG_TYPE_IATTR_LOCAL; |
433 | vecp++; | 407 | vecp++; |
434 | nvecs++; | 408 | (*nvecs)++; |
435 | iip->ili_format.ilf_asize = (unsigned)data_bytes; | 409 | iip->ili_format.ilf_asize = (unsigned)data_bytes; |
436 | } else { | 410 | } else { |
437 | iip->ili_fields &= ~XFS_ILOG_ADATA; | 411 | iip->ili_fields &= ~XFS_ILOG_ADATA; |
438 | } | 412 | } |
439 | break; | 413 | break; |
440 | |||
441 | default: | 414 | default: |
442 | ASSERT(0); | 415 | ASSERT(0); |
443 | break; | 416 | break; |
444 | } | 417 | } |
445 | 418 | ||
446 | out: | 419 | return vecp; |
420 | } | ||
421 | |||
422 | /* | ||
423 | * This is called to fill in the vector of log iovecs for the given inode | ||
424 | * log item. It fills the first item with an inode log format structure, | ||
425 | * the second with the on-disk inode structure, and a possible third and/or | ||
426 | * fourth with the inode data/extents/b-tree root and inode attributes | ||
427 | * data/extents/b-tree root. | ||
428 | */ | ||
429 | STATIC void | ||
430 | xfs_inode_item_format( | ||
431 | struct xfs_log_item *lip, | ||
432 | struct xfs_log_iovec *vecp) | ||
433 | { | ||
434 | struct xfs_inode_log_item *iip = INODE_ITEM(lip); | ||
435 | struct xfs_inode *ip = iip->ili_inode; | ||
436 | uint nvecs; | ||
437 | |||
438 | vecp->i_addr = &iip->ili_format; | ||
439 | vecp->i_len = sizeof(xfs_inode_log_format_t); | ||
440 | vecp->i_type = XLOG_REG_TYPE_IFORMAT; | ||
441 | vecp++; | ||
442 | nvecs = 1; | ||
443 | |||
444 | vecp->i_addr = &ip->i_d; | ||
445 | vecp->i_len = xfs_icdinode_size(ip->i_d.di_version); | ||
446 | vecp->i_type = XLOG_REG_TYPE_ICORE; | ||
447 | vecp++; | ||
448 | nvecs++; | ||
449 | |||
450 | if (ip->i_d.di_version == 1) | ||
451 | xfs_inode_item_format_v1_inode(ip); | ||
452 | |||
453 | vecp = xfs_inode_item_format_data_fork(iip, vecp, &nvecs); | ||
454 | if (XFS_IFORK_Q(ip)) { | ||
455 | vecp = xfs_inode_item_format_attr_fork(iip, vecp, &nvecs); | ||
456 | } else { | ||
457 | iip->ili_fields &= | ||
458 | ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT); | ||
459 | } | ||
460 | |||
447 | /* | 461 | /* |
448 | * Now update the log format that goes out to disk from the in-core | 462 | * Now update the log format that goes out to disk from the in-core |
449 | * values. We always write the inode core to make the arithmetic | 463 | * values. We always write the inode core to make the arithmetic |
@@ -455,7 +469,6 @@ out: | |||
455 | iip->ili_format.ilf_size = nvecs; | 469 | iip->ili_format.ilf_size = nvecs; |
456 | } | 470 | } |
457 | 471 | ||
458 | |||
459 | /* | 472 | /* |
460 | * This is called to pin the inode associated with the inode log | 473 | * This is called to pin the inode associated with the inode log |
461 | * item in memory so it cannot be written out. | 474 | * item in memory so it cannot be written out. |