diff options
-rw-r--r-- | fs/xfs/quota/xfs_qm.c | 4 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm_syscalls.c | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.c | 52 | ||||
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 27 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.c | 35 | ||||
-rw-r--r-- | fs/xfs/xfs_rtalloc.c | 38 | ||||
-rw-r--r-- | fs/xfs/xfs_vfsops.c | 15 | ||||
-rw-r--r-- | fs/xfs/xfs_vnodeops.c | 28 |
8 files changed, 115 insertions, 88 deletions
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 6aa3445cabad..40ea56409561 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c | |||
@@ -2392,9 +2392,9 @@ xfs_qm_write_sb_changes( | |||
2392 | } | 2392 | } |
2393 | 2393 | ||
2394 | xfs_mod_sb(tp, flags); | 2394 | xfs_mod_sb(tp, flags); |
2395 | (void) xfs_trans_commit(tp, 0); | 2395 | error = xfs_trans_commit(tp, 0); |
2396 | 2396 | ||
2397 | return 0; | 2397 | return error; |
2398 | } | 2398 | } |
2399 | 2399 | ||
2400 | 2400 | ||
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index 556018d24cad..8342823dbdc3 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c | |||
@@ -734,12 +734,12 @@ xfs_qm_scall_setqlim( | |||
734 | xfs_trans_log_dquot(tp, dqp); | 734 | xfs_trans_log_dquot(tp, dqp); |
735 | 735 | ||
736 | xfs_dqtrace_entry(dqp, "Q_SETQLIM: COMMIT"); | 736 | xfs_dqtrace_entry(dqp, "Q_SETQLIM: COMMIT"); |
737 | xfs_trans_commit(tp, 0); | 737 | error = xfs_trans_commit(tp, 0); |
738 | xfs_qm_dqprint(dqp); | 738 | xfs_qm_dqprint(dqp); |
739 | xfs_qm_dqrele(dqp); | 739 | xfs_qm_dqrele(dqp); |
740 | mutex_unlock(&(XFS_QI_QOFFLOCK(mp))); | 740 | mutex_unlock(&(XFS_QI_QOFFLOCK(mp))); |
741 | 741 | ||
742 | return (0); | 742 | return error; |
743 | } | 743 | } |
744 | 744 | ||
745 | STATIC int | 745 | STATIC int |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index d7514f8317df..63e66890f063 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -1699,33 +1699,16 @@ xfs_itruncate_finish( | |||
1699 | * blocks in the file system, but oh well. | 1699 | * blocks in the file system, but oh well. |
1700 | */ | 1700 | */ |
1701 | xfs_bmap_cancel(&free_list); | 1701 | xfs_bmap_cancel(&free_list); |
1702 | if (committed) { | 1702 | if (committed) |
1703 | /* | 1703 | goto error_join; |
1704 | * If the passed in transaction committed | ||
1705 | * in xfs_bmap_finish(), then we want to | ||
1706 | * add the inode to this one before returning. | ||
1707 | * This keeps things simple for the higher | ||
1708 | * level code, because it always knows that | ||
1709 | * the inode is locked and held in the | ||
1710 | * transaction that returns to it whether | ||
1711 | * errors occur or not. We don't mark the | ||
1712 | * inode dirty so that this transaction can | ||
1713 | * be easily aborted if possible. | ||
1714 | */ | ||
1715 | xfs_trans_ijoin(ntp, ip, | ||
1716 | XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | ||
1717 | xfs_trans_ihold(ntp, ip); | ||
1718 | } | ||
1719 | return error; | 1704 | return error; |
1720 | } | 1705 | } |
1721 | 1706 | ||
1722 | if (committed) { | 1707 | if (committed) { |
1723 | /* | 1708 | /* |
1724 | * The first xact was committed, | 1709 | * The first xact was committed, so add the inode to |
1725 | * so add the inode to the new one. | 1710 | * the new one. Mark it dirty so it will be logged and |
1726 | * Mark it dirty so it will be logged | 1711 | * moved forward in the log as part of every commit. |
1727 | * and moved forward in the log as | ||
1728 | * part of every commit. | ||
1729 | */ | 1712 | */ |
1730 | xfs_trans_ijoin(ntp, ip, | 1713 | xfs_trans_ijoin(ntp, ip, |
1731 | XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | 1714 | XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); |
@@ -1733,19 +1716,16 @@ xfs_itruncate_finish( | |||
1733 | xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE); | 1716 | xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE); |
1734 | } | 1717 | } |
1735 | ntp = xfs_trans_dup(ntp); | 1718 | ntp = xfs_trans_dup(ntp); |
1736 | (void) xfs_trans_commit(*tp, 0); | 1719 | error = xfs_trans_commit(*tp, 0); |
1737 | *tp = ntp; | 1720 | *tp = ntp; |
1721 | if (error) | ||
1722 | goto error_join; | ||
1738 | error = xfs_trans_reserve(ntp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, | 1723 | error = xfs_trans_reserve(ntp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, |
1739 | XFS_TRANS_PERM_LOG_RES, | 1724 | XFS_TRANS_PERM_LOG_RES, |
1740 | XFS_ITRUNCATE_LOG_COUNT); | 1725 | XFS_ITRUNCATE_LOG_COUNT); |
1741 | /* | ||
1742 | * Add the inode being truncated to the next chained | ||
1743 | * transaction. | ||
1744 | */ | ||
1745 | xfs_trans_ijoin(ntp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | ||
1746 | xfs_trans_ihold(ntp, ip); | ||
1747 | if (error) | 1726 | if (error) |
1748 | return (error); | 1727 | goto error_join; |
1728 | |||
1749 | } | 1729 | } |
1750 | /* | 1730 | /* |
1751 | * Only update the size in the case of the data fork, but | 1731 | * Only update the size in the case of the data fork, but |
@@ -1777,6 +1757,18 @@ xfs_itruncate_finish( | |||
1777 | (ip->i_d.di_nextents == 0)); | 1757 | (ip->i_d.di_nextents == 0)); |
1778 | xfs_itrunc_trace(XFS_ITRUNC_FINISH2, ip, 0, new_size, 0, 0); | 1758 | xfs_itrunc_trace(XFS_ITRUNC_FINISH2, ip, 0, new_size, 0, 0); |
1779 | return 0; | 1759 | return 0; |
1760 | |||
1761 | error_join: | ||
1762 | /* | ||
1763 | * Add the inode being truncated to the next chained transaction. This | ||
1764 | * keeps things simple for the higher level code, because it always | ||
1765 | * knows that the inode is locked and held in the transaction that | ||
1766 | * returns to it whether errors occur or not. We don't mark the inode | ||
1767 | * dirty so that this transaction can be easily aborted if possible. | ||
1768 | */ | ||
1769 | xfs_trans_ijoin(ntp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | ||
1770 | xfs_trans_ihold(ntp, ip); | ||
1771 | return error; | ||
1780 | } | 1772 | } |
1781 | 1773 | ||
1782 | 1774 | ||
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 957b8caddf1e..418582b709eb 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -3017,7 +3017,7 @@ xlog_recover_process_efi( | |||
3017 | } | 3017 | } |
3018 | 3018 | ||
3019 | efip->efi_flags |= XFS_EFI_RECOVERED; | 3019 | efip->efi_flags |= XFS_EFI_RECOVERED; |
3020 | xfs_trans_commit(tp, 0); | 3020 | error = xfs_trans_commit(tp, 0); |
3021 | return error; | 3021 | return error; |
3022 | } | 3022 | } |
3023 | 3023 | ||
@@ -3131,16 +3131,13 @@ xlog_recover_clear_agi_bucket( | |||
3131 | error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, | 3131 | error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, |
3132 | XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), | 3132 | XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), |
3133 | XFS_FSS_TO_BB(mp, 1), 0, &agibp); | 3133 | XFS_FSS_TO_BB(mp, 1), 0, &agibp); |
3134 | if (error) { | 3134 | if (error) |
3135 | xfs_trans_cancel(tp, XFS_TRANS_ABORT); | 3135 | goto out_abort; |
3136 | return; | ||
3137 | } | ||
3138 | 3136 | ||
3137 | error = EINVAL; | ||
3139 | agi = XFS_BUF_TO_AGI(agibp); | 3138 | agi = XFS_BUF_TO_AGI(agibp); |
3140 | if (be32_to_cpu(agi->agi_magicnum) != XFS_AGI_MAGIC) { | 3139 | if (be32_to_cpu(agi->agi_magicnum) != XFS_AGI_MAGIC) |
3141 | xfs_trans_cancel(tp, XFS_TRANS_ABORT); | 3140 | goto out_abort; |
3142 | return; | ||
3143 | } | ||
3144 | 3141 | ||
3145 | agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO); | 3142 | agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO); |
3146 | offset = offsetof(xfs_agi_t, agi_unlinked) + | 3143 | offset = offsetof(xfs_agi_t, agi_unlinked) + |
@@ -3148,7 +3145,17 @@ xlog_recover_clear_agi_bucket( | |||
3148 | xfs_trans_log_buf(tp, agibp, offset, | 3145 | xfs_trans_log_buf(tp, agibp, offset, |
3149 | (offset + sizeof(xfs_agino_t) - 1)); | 3146 | (offset + sizeof(xfs_agino_t) - 1)); |
3150 | 3147 | ||
3151 | (void) xfs_trans_commit(tp, 0); | 3148 | error = xfs_trans_commit(tp, 0); |
3149 | if (error) | ||
3150 | goto out_error; | ||
3151 | return; | ||
3152 | |||
3153 | out_abort: | ||
3154 | xfs_trans_cancel(tp, XFS_TRANS_ABORT); | ||
3155 | out_error: | ||
3156 | xfs_fs_cmn_err(CE_WARN, mp, "xlog_recover_clear_agi_bucket: " | ||
3157 | "failed to clear agi %d. Continuing.", agno); | ||
3158 | return; | ||
3152 | } | 3159 | } |
3153 | 3160 | ||
3154 | /* | 3161 | /* |
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 244aa1b9f134..2d03fe194c2c 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -45,7 +45,7 @@ | |||
45 | #include "xfs_fsops.h" | 45 | #include "xfs_fsops.h" |
46 | #include "xfs_utils.h" | 46 | #include "xfs_utils.h" |
47 | 47 | ||
48 | STATIC void xfs_mount_log_sb(xfs_mount_t *, __int64_t); | 48 | STATIC int xfs_mount_log_sb(xfs_mount_t *, __int64_t); |
49 | STATIC int xfs_uuid_mount(xfs_mount_t *); | 49 | STATIC int xfs_uuid_mount(xfs_mount_t *); |
50 | STATIC void xfs_uuid_unmount(xfs_mount_t *mp); | 50 | STATIC void xfs_uuid_unmount(xfs_mount_t *mp); |
51 | STATIC void xfs_unmountfs_wait(xfs_mount_t *); | 51 | STATIC void xfs_unmountfs_wait(xfs_mount_t *); |
@@ -1189,8 +1189,13 @@ xfs_mountfs( | |||
1189 | /* | 1189 | /* |
1190 | * If fs is not mounted readonly, then update the superblock changes. | 1190 | * If fs is not mounted readonly, then update the superblock changes. |
1191 | */ | 1191 | */ |
1192 | if (update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) | 1192 | if (update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) { |
1193 | xfs_mount_log_sb(mp, update_flags); | 1193 | error = xfs_mount_log_sb(mp, update_flags); |
1194 | if (error) { | ||
1195 | cmn_err(CE_WARN, "XFS: failed to write sb changes"); | ||
1196 | goto error4; | ||
1197 | } | ||
1198 | } | ||
1194 | 1199 | ||
1195 | /* | 1200 | /* |
1196 | * Initialise the XFS quota management subsystem for this mount | 1201 | * Initialise the XFS quota management subsystem for this mount |
@@ -1320,8 +1325,10 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) | |||
1320 | cmn_err(CE_WARN, "XFS: Unable to free reserved block pool. " | 1325 | cmn_err(CE_WARN, "XFS: Unable to free reserved block pool. " |
1321 | "Freespace may not be correct on next mount."); | 1326 | "Freespace may not be correct on next mount."); |
1322 | 1327 | ||
1323 | 1328 | error = xfs_log_sbcount(mp, 1); | |
1324 | xfs_log_sbcount(mp, 1); | 1329 | if (error) |
1330 | cmn_err(CE_WARN, "XFS: Unable to update superblock counters. " | ||
1331 | "Freespace may not be correct on next mount."); | ||
1325 | xfs_unmountfs_writesb(mp); | 1332 | xfs_unmountfs_writesb(mp); |
1326 | xfs_unmountfs_wait(mp); /* wait for async bufs */ | 1333 | xfs_unmountfs_wait(mp); /* wait for async bufs */ |
1327 | xfs_log_unmount(mp); /* Done! No more fs ops. */ | 1334 | xfs_log_unmount(mp); /* Done! No more fs ops. */ |
@@ -1413,9 +1420,8 @@ xfs_log_sbcount( | |||
1413 | xfs_mod_sb(tp, XFS_SB_IFREE | XFS_SB_ICOUNT | XFS_SB_FDBLOCKS); | 1420 | xfs_mod_sb(tp, XFS_SB_IFREE | XFS_SB_ICOUNT | XFS_SB_FDBLOCKS); |
1414 | if (sync) | 1421 | if (sync) |
1415 | xfs_trans_set_sync(tp); | 1422 | xfs_trans_set_sync(tp); |
1416 | xfs_trans_commit(tp, 0); | 1423 | error = xfs_trans_commit(tp, 0); |
1417 | 1424 | return error; | |
1418 | return 0; | ||
1419 | } | 1425 | } |
1420 | 1426 | ||
1421 | STATIC void | 1427 | STATIC void |
@@ -1913,24 +1919,27 @@ xfs_uuid_unmount( | |||
1913 | * be altered by the mount options, as well as any potential sb_features2 | 1919 | * be altered by the mount options, as well as any potential sb_features2 |
1914 | * fixup. Only the first superblock is updated. | 1920 | * fixup. Only the first superblock is updated. |
1915 | */ | 1921 | */ |
1916 | STATIC void | 1922 | STATIC int |
1917 | xfs_mount_log_sb( | 1923 | xfs_mount_log_sb( |
1918 | xfs_mount_t *mp, | 1924 | xfs_mount_t *mp, |
1919 | __int64_t fields) | 1925 | __int64_t fields) |
1920 | { | 1926 | { |
1921 | xfs_trans_t *tp; | 1927 | xfs_trans_t *tp; |
1928 | int error; | ||
1922 | 1929 | ||
1923 | ASSERT(fields & (XFS_SB_UNIT | XFS_SB_WIDTH | XFS_SB_UUID | | 1930 | ASSERT(fields & (XFS_SB_UNIT | XFS_SB_WIDTH | XFS_SB_UUID | |
1924 | XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2)); | 1931 | XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2)); |
1925 | 1932 | ||
1926 | tp = xfs_trans_alloc(mp, XFS_TRANS_SB_UNIT); | 1933 | tp = xfs_trans_alloc(mp, XFS_TRANS_SB_UNIT); |
1927 | if (xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0, | 1934 | error = xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0, |
1928 | XFS_DEFAULT_LOG_COUNT)) { | 1935 | XFS_DEFAULT_LOG_COUNT); |
1936 | if (error) { | ||
1929 | xfs_trans_cancel(tp, 0); | 1937 | xfs_trans_cancel(tp, 0); |
1930 | return; | 1938 | return error; |
1931 | } | 1939 | } |
1932 | xfs_mod_sb(tp, fields); | 1940 | xfs_mod_sb(tp, fields); |
1933 | xfs_trans_commit(tp, 0); | 1941 | error = xfs_trans_commit(tp, 0); |
1942 | return error; | ||
1934 | } | 1943 | } |
1935 | 1944 | ||
1936 | 1945 | ||
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 9cd6471cd60f..a0dc6e5bc5b9 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c | |||
@@ -124,14 +124,14 @@ xfs_growfs_rt_alloc( | |||
124 | XFS_GROWRTALLOC_LOG_RES(mp), 0, | 124 | XFS_GROWRTALLOC_LOG_RES(mp), 0, |
125 | XFS_TRANS_PERM_LOG_RES, | 125 | XFS_TRANS_PERM_LOG_RES, |
126 | XFS_DEFAULT_PERM_LOG_COUNT))) | 126 | XFS_DEFAULT_PERM_LOG_COUNT))) |
127 | goto error_exit; | 127 | goto error_cancel; |
128 | cancelflags = XFS_TRANS_RELEASE_LOG_RES; | 128 | cancelflags = XFS_TRANS_RELEASE_LOG_RES; |
129 | /* | 129 | /* |
130 | * Lock the inode. | 130 | * Lock the inode. |
131 | */ | 131 | */ |
132 | if ((error = xfs_trans_iget(mp, tp, ino, 0, | 132 | if ((error = xfs_trans_iget(mp, tp, ino, 0, |
133 | XFS_ILOCK_EXCL, &ip))) | 133 | XFS_ILOCK_EXCL, &ip))) |
134 | goto error_exit; | 134 | goto error_cancel; |
135 | XFS_BMAP_INIT(&flist, &firstblock); | 135 | XFS_BMAP_INIT(&flist, &firstblock); |
136 | /* | 136 | /* |
137 | * Allocate blocks to the bitmap file. | 137 | * Allocate blocks to the bitmap file. |
@@ -144,14 +144,16 @@ xfs_growfs_rt_alloc( | |||
144 | if (!error && nmap < 1) | 144 | if (!error && nmap < 1) |
145 | error = XFS_ERROR(ENOSPC); | 145 | error = XFS_ERROR(ENOSPC); |
146 | if (error) | 146 | if (error) |
147 | goto error_exit; | 147 | goto error_cancel; |
148 | /* | 148 | /* |
149 | * Free any blocks freed up in the transaction, then commit. | 149 | * Free any blocks freed up in the transaction, then commit. |
150 | */ | 150 | */ |
151 | error = xfs_bmap_finish(&tp, &flist, &committed); | 151 | error = xfs_bmap_finish(&tp, &flist, &committed); |
152 | if (error) | 152 | if (error) |
153 | goto error_exit; | 153 | goto error_cancel; |
154 | xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | 154 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); |
155 | if (error) | ||
156 | goto error; | ||
155 | /* | 157 | /* |
156 | * Now we need to clear the allocated blocks. | 158 | * Now we need to clear the allocated blocks. |
157 | * Do this one block per transaction, to keep it simple. | 159 | * Do this one block per transaction, to keep it simple. |
@@ -166,13 +168,13 @@ xfs_growfs_rt_alloc( | |||
166 | */ | 168 | */ |
167 | if ((error = xfs_trans_reserve(tp, 0, | 169 | if ((error = xfs_trans_reserve(tp, 0, |
168 | XFS_GROWRTZERO_LOG_RES(mp), 0, 0, 0))) | 170 | XFS_GROWRTZERO_LOG_RES(mp), 0, 0, 0))) |
169 | goto error_exit; | 171 | goto error_cancel; |
170 | /* | 172 | /* |
171 | * Lock the bitmap inode. | 173 | * Lock the bitmap inode. |
172 | */ | 174 | */ |
173 | if ((error = xfs_trans_iget(mp, tp, ino, 0, | 175 | if ((error = xfs_trans_iget(mp, tp, ino, 0, |
174 | XFS_ILOCK_EXCL, &ip))) | 176 | XFS_ILOCK_EXCL, &ip))) |
175 | goto error_exit; | 177 | goto error_cancel; |
176 | /* | 178 | /* |
177 | * Get a buffer for the block. | 179 | * Get a buffer for the block. |
178 | */ | 180 | */ |
@@ -181,14 +183,16 @@ xfs_growfs_rt_alloc( | |||
181 | mp->m_bsize, 0); | 183 | mp->m_bsize, 0); |
182 | if (bp == NULL) { | 184 | if (bp == NULL) { |
183 | error = XFS_ERROR(EIO); | 185 | error = XFS_ERROR(EIO); |
184 | goto error_exit; | 186 | goto error_cancel; |
185 | } | 187 | } |
186 | memset(XFS_BUF_PTR(bp), 0, mp->m_sb.sb_blocksize); | 188 | memset(XFS_BUF_PTR(bp), 0, mp->m_sb.sb_blocksize); |
187 | xfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1); | 189 | xfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1); |
188 | /* | 190 | /* |
189 | * Commit the transaction. | 191 | * Commit the transaction. |
190 | */ | 192 | */ |
191 | xfs_trans_commit(tp, 0); | 193 | error = xfs_trans_commit(tp, 0); |
194 | if (error) | ||
195 | goto error; | ||
192 | } | 196 | } |
193 | /* | 197 | /* |
194 | * Go on to the next extent, if any. | 198 | * Go on to the next extent, if any. |
@@ -196,8 +200,9 @@ xfs_growfs_rt_alloc( | |||
196 | oblocks = map.br_startoff + map.br_blockcount; | 200 | oblocks = map.br_startoff + map.br_blockcount; |
197 | } | 201 | } |
198 | return 0; | 202 | return 0; |
199 | error_exit: | 203 | error_cancel: |
200 | xfs_trans_cancel(tp, cancelflags); | 204 | xfs_trans_cancel(tp, cancelflags); |
205 | error: | ||
201 | return error; | 206 | return error; |
202 | } | 207 | } |
203 | 208 | ||
@@ -1876,6 +1881,7 @@ xfs_growfs_rt( | |||
1876 | xfs_trans_t *tp; /* transaction pointer */ | 1881 | xfs_trans_t *tp; /* transaction pointer */ |
1877 | 1882 | ||
1878 | sbp = &mp->m_sb; | 1883 | sbp = &mp->m_sb; |
1884 | cancelflags = 0; | ||
1879 | /* | 1885 | /* |
1880 | * Initial error checking. | 1886 | * Initial error checking. |
1881 | */ | 1887 | */ |
@@ -2042,13 +2048,15 @@ xfs_growfs_rt( | |||
2042 | */ | 2048 | */ |
2043 | mp->m_rsumlevels = nrsumlevels; | 2049 | mp->m_rsumlevels = nrsumlevels; |
2044 | mp->m_rsumsize = nrsumsize; | 2050 | mp->m_rsumsize = nrsumsize; |
2045 | /* | 2051 | |
2046 | * Commit the transaction. | 2052 | error = xfs_trans_commit(tp, 0); |
2047 | */ | 2053 | if (error) { |
2048 | xfs_trans_commit(tp, 0); | 2054 | tp = NULL; |
2055 | break; | ||
2056 | } | ||
2049 | } | 2057 | } |
2050 | 2058 | ||
2051 | if (error) | 2059 | if (error && tp) |
2052 | xfs_trans_cancel(tp, cancelflags); | 2060 | xfs_trans_cancel(tp, cancelflags); |
2053 | 2061 | ||
2054 | /* | 2062 | /* |
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index 6351efb569c7..09e186d02c11 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c | |||
@@ -672,6 +672,8 @@ void | |||
672 | xfs_attr_quiesce( | 672 | xfs_attr_quiesce( |
673 | xfs_mount_t *mp) | 673 | xfs_mount_t *mp) |
674 | { | 674 | { |
675 | int error = 0; | ||
676 | |||
675 | /* wait for all modifications to complete */ | 677 | /* wait for all modifications to complete */ |
676 | while (atomic_read(&mp->m_active_trans) > 0) | 678 | while (atomic_read(&mp->m_active_trans) > 0) |
677 | delay(100); | 679 | delay(100); |
@@ -682,7 +684,11 @@ xfs_attr_quiesce( | |||
682 | ASSERT_ALWAYS(atomic_read(&mp->m_active_trans) == 0); | 684 | ASSERT_ALWAYS(atomic_read(&mp->m_active_trans) == 0); |
683 | 685 | ||
684 | /* Push the superblock and write an unmount record */ | 686 | /* Push the superblock and write an unmount record */ |
685 | xfs_log_sbcount(mp, 1); | 687 | error = xfs_log_sbcount(mp, 1); |
688 | if (error) | ||
689 | xfs_fs_cmn_err(CE_WARN, mp, | ||
690 | "xfs_attr_quiesce: failed to log sb changes. " | ||
691 | "Frozen image may not be consistent."); | ||
686 | xfs_log_unmount_write(mp); | 692 | xfs_log_unmount_write(mp); |
687 | xfs_unmountfs_writesb(mp); | 693 | xfs_unmountfs_writesb(mp); |
688 | } | 694 | } |
@@ -1316,8 +1322,11 @@ xfs_syncsub( | |||
1316 | * of sync if we crash or get a forced shutdown. We don't want to force | 1322 | * of sync if we crash or get a forced shutdown. We don't want to force |
1317 | * this to disk, just get a transaction into the iclogs.... | 1323 | * this to disk, just get a transaction into the iclogs.... |
1318 | */ | 1324 | */ |
1319 | if (flags & SYNC_SUPER) | 1325 | if (flags & SYNC_SUPER) { |
1320 | xfs_log_sbcount(mp, 0); | 1326 | error = xfs_log_sbcount(mp, 0); |
1327 | if (error) | ||
1328 | last_error = error; | ||
1329 | } | ||
1321 | 1330 | ||
1322 | /* | 1331 | /* |
1323 | * Now check to see if the log needs a "dummy" transaction. | 1332 | * Now check to see if the log needs a "dummy" transaction. |
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index d46f24c68498..bc0a4707189a 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -1447,28 +1447,22 @@ xfs_inactive_attrs( | |||
1447 | tp = *tpp; | 1447 | tp = *tpp; |
1448 | mp = ip->i_mount; | 1448 | mp = ip->i_mount; |
1449 | ASSERT(ip->i_d.di_forkoff != 0); | 1449 | ASSERT(ip->i_d.di_forkoff != 0); |
1450 | xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | 1450 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); |
1451 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 1451 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
1452 | if (error) | ||
1453 | goto error_unlock; | ||
1452 | 1454 | ||
1453 | error = xfs_attr_inactive(ip); | 1455 | error = xfs_attr_inactive(ip); |
1454 | if (error) { | 1456 | if (error) |
1455 | *tpp = NULL; | 1457 | goto error_unlock; |
1456 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
1457 | return error; /* goto out */ | ||
1458 | } | ||
1459 | 1458 | ||
1460 | tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); | 1459 | tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); |
1461 | error = xfs_trans_reserve(tp, 0, | 1460 | error = xfs_trans_reserve(tp, 0, |
1462 | XFS_IFREE_LOG_RES(mp), | 1461 | XFS_IFREE_LOG_RES(mp), |
1463 | 0, XFS_TRANS_PERM_LOG_RES, | 1462 | 0, XFS_TRANS_PERM_LOG_RES, |
1464 | XFS_INACTIVE_LOG_COUNT); | 1463 | XFS_INACTIVE_LOG_COUNT); |
1465 | if (error) { | 1464 | if (error) |
1466 | ASSERT(XFS_FORCED_SHUTDOWN(mp)); | 1465 | goto error_cancel; |
1467 | xfs_trans_cancel(tp, 0); | ||
1468 | *tpp = NULL; | ||
1469 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
1470 | return error; | ||
1471 | } | ||
1472 | 1466 | ||
1473 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 1467 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
1474 | xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); | 1468 | xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); |
@@ -1479,6 +1473,14 @@ xfs_inactive_attrs( | |||
1479 | 1473 | ||
1480 | *tpp = tp; | 1474 | *tpp = tp; |
1481 | return 0; | 1475 | return 0; |
1476 | |||
1477 | error_cancel: | ||
1478 | ASSERT(XFS_FORCED_SHUTDOWN(mp)); | ||
1479 | xfs_trans_cancel(tp, 0); | ||
1480 | error_unlock: | ||
1481 | *tpp = NULL; | ||
1482 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
1483 | return error; | ||
1482 | } | 1484 | } |
1483 | 1485 | ||
1484 | int | 1486 | int |