|
@@ -2573,9 +2573,18 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
- /* assign a buffer for the page */
|
|
|
- mp = get_metapage(ipimap, xaddr, PSIZE, 1);
|
|
|
- if (!mp) {
|
|
|
+ /*
|
|
|
+ * start transaction of update of the inode map
|
|
|
+ * addressing structure pointing to the new iag page;
|
|
|
+ */
|
|
|
+ tid = txBegin(sb, COMMIT_FORCE);
|
|
|
+ down(&JFS_IP(ipimap)->commit_sem);
|
|
|
+
|
|
|
+ /* update the inode map addressing structure to point to it */
|
|
|
+ if ((rc =
|
|
|
+ xtInsert(tid, ipimap, 0, blkno, xlen, &xaddr, 0))) {
|
|
|
+ txEnd(tid);
|
|
|
+ up(&JFS_IP(ipimap)->commit_sem);
|
|
|
/* Free the blocks allocated for the iag since it was
|
|
|
* not successfully added to the inode map
|
|
|
*/
|
|
@@ -2584,6 +2593,29 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
|
|
|
/* release the inode map lock */
|
|
|
IWRITE_UNLOCK(ipimap);
|
|
|
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* update the inode map's inode to reflect the extension */
|
|
|
+ ipimap->i_size += PSIZE;
|
|
|
+ inode_add_bytes(ipimap, PSIZE);
|
|
|
+
|
|
|
+ /* assign a buffer for the page */
|
|
|
+ mp = get_metapage(ipimap, blkno, PSIZE, 0);
|
|
|
+ if (!mp) {
|
|
|
+ /*
|
|
|
+ * This is very unlikely since we just created the
|
|
|
+ * extent, but let's try to handle it correctly
|
|
|
+ */
|
|
|
+ xtTruncate(tid, ipimap, ipimap->i_size - PSIZE,
|
|
|
+ COMMIT_PWMAP);
|
|
|
+
|
|
|
+ txAbort(tid, 0);
|
|
|
+ txEnd(tid);
|
|
|
+
|
|
|
+ /* release the inode map lock */
|
|
|
+ IWRITE_UNLOCK(ipimap);
|
|
|
+
|
|
|
rc = -EIO;
|
|
|
goto out;
|
|
|
}
|
|
@@ -2605,40 +2637,10 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
|
|
|
iagp->inosmap[i] = cpu_to_le32(ONES);
|
|
|
|
|
|
/*
|
|
|
- * Invalidate the page after writing and syncing it.
|
|
|
- * After it's initialized, we access it in a different
|
|
|
- * address space
|
|
|
+ * Write and sync the metapage
|
|
|
*/
|
|
|
- set_bit(META_discard, &mp->flag);
|
|
|
flush_metapage(mp);
|
|
|
|
|
|
- /*
|
|
|
- * start tyransaction of update of the inode map
|
|
|
- * addressing structure pointing to the new iag page;
|
|
|
- */
|
|
|
- tid = txBegin(sb, COMMIT_FORCE);
|
|
|
- down(&JFS_IP(ipimap)->commit_sem);
|
|
|
-
|
|
|
- /* update the inode map addressing structure to point to it */
|
|
|
- if ((rc =
|
|
|
- xtInsert(tid, ipimap, 0, blkno, xlen, &xaddr, 0))) {
|
|
|
- txEnd(tid);
|
|
|
- up(&JFS_IP(ipimap)->commit_sem);
|
|
|
- /* Free the blocks allocated for the iag since it was
|
|
|
- * not successfully added to the inode map
|
|
|
- */
|
|
|
- dbFree(ipimap, xaddr, (s64) xlen);
|
|
|
-
|
|
|
- /* release the inode map lock */
|
|
|
- IWRITE_UNLOCK(ipimap);
|
|
|
-
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
- /* update the inode map's inode to reflect the extension */
|
|
|
- ipimap->i_size += PSIZE;
|
|
|
- inode_add_bytes(ipimap, PSIZE);
|
|
|
-
|
|
|
/*
|
|
|
* txCommit(COMMIT_FORCE) will synchronously write address
|
|
|
* index pages and inode after commit in careful update order
|