diff options
Diffstat (limited to 'fs/jfs/jfs_imap.c')
-rw-r--r-- | fs/jfs/jfs_imap.c | 70 |
1 files changed, 36 insertions, 34 deletions
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index 783831301625..6a0aa7e2cbef 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c | |||
@@ -2573,9 +2573,18 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) | |||
2573 | goto out; | 2573 | goto out; |
2574 | } | 2574 | } |
2575 | 2575 | ||
2576 | /* assign a buffer for the page */ | 2576 | /* |
2577 | mp = get_metapage(ipimap, xaddr, PSIZE, 1); | 2577 | * start transaction of update of the inode map |
2578 | if (!mp) { | 2578 | * addressing structure pointing to the new iag page; |
2579 | */ | ||
2580 | tid = txBegin(sb, COMMIT_FORCE); | ||
2581 | down(&JFS_IP(ipimap)->commit_sem); | ||
2582 | |||
2583 | /* update the inode map addressing structure to point to it */ | ||
2584 | if ((rc = | ||
2585 | xtInsert(tid, ipimap, 0, blkno, xlen, &xaddr, 0))) { | ||
2586 | txEnd(tid); | ||
2587 | up(&JFS_IP(ipimap)->commit_sem); | ||
2579 | /* Free the blocks allocated for the iag since it was | 2588 | /* Free the blocks allocated for the iag since it was |
2580 | * not successfully added to the inode map | 2589 | * not successfully added to the inode map |
2581 | */ | 2590 | */ |
@@ -2584,6 +2593,29 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) | |||
2584 | /* release the inode map lock */ | 2593 | /* release the inode map lock */ |
2585 | IWRITE_UNLOCK(ipimap); | 2594 | IWRITE_UNLOCK(ipimap); |
2586 | 2595 | ||
2596 | goto out; | ||
2597 | } | ||
2598 | |||
2599 | /* update the inode map's inode to reflect the extension */ | ||
2600 | ipimap->i_size += PSIZE; | ||
2601 | inode_add_bytes(ipimap, PSIZE); | ||
2602 | |||
2603 | /* assign a buffer for the page */ | ||
2604 | mp = get_metapage(ipimap, blkno, PSIZE, 0); | ||
2605 | if (!mp) { | ||
2606 | /* | ||
2607 | * This is very unlikely since we just created the | ||
2608 | * extent, but let's try to handle it correctly | ||
2609 | */ | ||
2610 | xtTruncate(tid, ipimap, ipimap->i_size - PSIZE, | ||
2611 | COMMIT_PWMAP); | ||
2612 | |||
2613 | txAbort(tid, 0); | ||
2614 | txEnd(tid); | ||
2615 | |||
2616 | /* release the inode map lock */ | ||
2617 | IWRITE_UNLOCK(ipimap); | ||
2618 | |||
2587 | rc = -EIO; | 2619 | rc = -EIO; |
2588 | goto out; | 2620 | goto out; |
2589 | } | 2621 | } |
@@ -2605,41 +2637,11 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) | |||
2605 | iagp->inosmap[i] = cpu_to_le32(ONES); | 2637 | iagp->inosmap[i] = cpu_to_le32(ONES); |
2606 | 2638 | ||
2607 | /* | 2639 | /* |
2608 | * Invalidate the page after writing and syncing it. | 2640 | * Write and sync the metapage |
2609 | * After it's initialized, we access it in a different | ||
2610 | * address space | ||
2611 | */ | 2641 | */ |
2612 | set_bit(META_discard, &mp->flag); | ||
2613 | flush_metapage(mp); | 2642 | flush_metapage(mp); |
2614 | 2643 | ||
2615 | /* | 2644 | /* |
2616 | * start tyransaction of update of the inode map | ||
2617 | * addressing structure pointing to the new iag page; | ||
2618 | */ | ||
2619 | tid = txBegin(sb, COMMIT_FORCE); | ||
2620 | down(&JFS_IP(ipimap)->commit_sem); | ||
2621 | |||
2622 | /* update the inode map addressing structure to point to it */ | ||
2623 | if ((rc = | ||
2624 | xtInsert(tid, ipimap, 0, blkno, xlen, &xaddr, 0))) { | ||
2625 | txEnd(tid); | ||
2626 | up(&JFS_IP(ipimap)->commit_sem); | ||
2627 | /* Free the blocks allocated for the iag since it was | ||
2628 | * not successfully added to the inode map | ||
2629 | */ | ||
2630 | dbFree(ipimap, xaddr, (s64) xlen); | ||
2631 | |||
2632 | /* release the inode map lock */ | ||
2633 | IWRITE_UNLOCK(ipimap); | ||
2634 | |||
2635 | goto out; | ||
2636 | } | ||
2637 | |||
2638 | /* update the inode map's inode to reflect the extension */ | ||
2639 | ipimap->i_size += PSIZE; | ||
2640 | inode_add_bytes(ipimap, PSIZE); | ||
2641 | |||
2642 | /* | ||
2643 | * txCommit(COMMIT_FORCE) will synchronously write address | 2645 | * txCommit(COMMIT_FORCE) will synchronously write address |
2644 | * index pages and inode after commit in careful update order | 2646 | * index pages and inode after commit in careful update order |
2645 | * of address index pages (right to left, bottom up); | 2647 | * of address index pages (right to left, bottom up); |