aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/quota/xfs_qm.c4
-rw-r--r--fs/xfs/quota/xfs_qm_syscalls.c4
-rw-r--r--fs/xfs/xfs_inode.c52
-rw-r--r--fs/xfs/xfs_log_recover.c27
-rw-r--r--fs/xfs/xfs_mount.c35
-rw-r--r--fs/xfs/xfs_rtalloc.c38
-rw-r--r--fs/xfs/xfs_vfsops.c15
-rw-r--r--fs/xfs/xfs_vnodeops.c28
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
745STATIC int 745STATIC 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
1761error_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
3153out_abort:
3154 xfs_trans_cancel(tp, XFS_TRANS_ABORT);
3155out_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
48STATIC void xfs_mount_log_sb(xfs_mount_t *, __int64_t); 48STATIC int xfs_mount_log_sb(xfs_mount_t *, __int64_t);
49STATIC int xfs_uuid_mount(xfs_mount_t *); 49STATIC int xfs_uuid_mount(xfs_mount_t *);
50STATIC void xfs_uuid_unmount(xfs_mount_t *mp); 50STATIC void xfs_uuid_unmount(xfs_mount_t *mp);
51STATIC void xfs_unmountfs_wait(xfs_mount_t *); 51STATIC 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
1421STATIC void 1427STATIC 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 */
1916STATIC void 1922STATIC int
1917xfs_mount_log_sb( 1923xfs_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;
199error_exit: 203error_cancel:
200 xfs_trans_cancel(tp, cancelflags); 204 xfs_trans_cancel(tp, cancelflags);
205error:
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
672xfs_attr_quiesce( 672xfs_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
1477error_cancel:
1478 ASSERT(XFS_FORCED_SHUTDOWN(mp));
1479 xfs_trans_cancel(tp, 0);
1480error_unlock:
1481 *tpp = NULL;
1482 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
1483 return error;
1482} 1484}
1483 1485
1484int 1486int