diff options
author | David Chinner <dgc@sgi.com> | 2008-04-09 22:21:18 -0400 |
---|---|---|
committer | Lachlan McIlroy <lachlan@redback.melbourne.sgi.com> | 2008-04-17 21:58:17 -0400 |
commit | e5720eec0548c08943d759e39db0388d8fe59287 (patch) | |
tree | e38b474f0dbac30aee7141878953223a2a588c69 /fs/xfs/xfs_mount.c | |
parent | 3c1e2bbe5bcdcd435510a05eb121fa74b848e24f (diff) |
[XFS] Propagate errors from xfs_trans_commit().
xfs_trans_commit() can return errors when there are problems in the
transaction subsystem. They are indicative that the entire transaction may
be incomplete, and hence the error should be propagated as there is a good
possibility that there is something fatally wrong in the filesystem. Catch
and propagate or warn about commit errors in the places where they are
currently ignored.
SGI-PV: 980084
SGI-Modid: xfs-linux-melb:xfs-kern:30795a
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Niv Sardi <xaiki@sgi.com>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_mount.c')
-rw-r--r-- | fs/xfs/xfs_mount.c | 35 |
1 files changed, 22 insertions, 13 deletions
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 | ||