diff options
Diffstat (limited to 'fs/xfs/xfs_mount.c')
-rw-r--r-- | fs/xfs/xfs_mount.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 39cf6f3267c3..31453ca0f3dd 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -725,7 +725,7 @@ xfs_mountfs( | |||
725 | bhv_vnode_t *rvp = NULL; | 725 | bhv_vnode_t *rvp = NULL; |
726 | int readio_log, writeio_log; | 726 | int readio_log, writeio_log; |
727 | xfs_daddr_t d; | 727 | xfs_daddr_t d; |
728 | __uint64_t ret64; | 728 | __uint64_t resblks; |
729 | __int64_t update_flags; | 729 | __int64_t update_flags; |
730 | uint quotamount, quotaflags; | 730 | uint quotamount, quotaflags; |
731 | int agno; | 731 | int agno; |
@@ -842,6 +842,7 @@ xfs_mountfs( | |||
842 | */ | 842 | */ |
843 | if ((mfsi_flags & XFS_MFSI_SECOND) == 0 && | 843 | if ((mfsi_flags & XFS_MFSI_SECOND) == 0 && |
844 | (mp->m_flags & XFS_MOUNT_NOUUID) == 0) { | 844 | (mp->m_flags & XFS_MOUNT_NOUUID) == 0) { |
845 | __uint64_t ret64; | ||
845 | if (xfs_uuid_mount(mp)) { | 846 | if (xfs_uuid_mount(mp)) { |
846 | error = XFS_ERROR(EINVAL); | 847 | error = XFS_ERROR(EINVAL); |
847 | goto error1; | 848 | goto error1; |
@@ -1135,13 +1136,27 @@ xfs_mountfs( | |||
1135 | goto error4; | 1136 | goto error4; |
1136 | } | 1137 | } |
1137 | 1138 | ||
1138 | |||
1139 | /* | 1139 | /* |
1140 | * Complete the quota initialisation, post-log-replay component. | 1140 | * Complete the quota initialisation, post-log-replay component. |
1141 | */ | 1141 | */ |
1142 | if ((error = XFS_QM_MOUNT(mp, quotamount, quotaflags, mfsi_flags))) | 1142 | if ((error = XFS_QM_MOUNT(mp, quotamount, quotaflags, mfsi_flags))) |
1143 | goto error4; | 1143 | goto error4; |
1144 | 1144 | ||
1145 | /* | ||
1146 | * Now we are mounted, reserve a small amount of unused space for | ||
1147 | * privileged transactions. This is needed so that transaction | ||
1148 | * space required for critical operations can dip into this pool | ||
1149 | * when at ENOSPC. This is needed for operations like create with | ||
1150 | * attr, unwritten extent conversion at ENOSPC, etc. Data allocations | ||
1151 | * are not allowed to use this reserved space. | ||
1152 | * | ||
1153 | * We default to 5% or 1024 fsbs of space reserved, whichever is smaller. | ||
1154 | * This may drive us straight to ENOSPC on mount, but that implies | ||
1155 | * we were already there on the last unmount. | ||
1156 | */ | ||
1157 | resblks = min_t(__uint64_t, mp->m_sb.sb_dblocks / 20, 1024); | ||
1158 | xfs_reserve_blocks(mp, &resblks, NULL); | ||
1159 | |||
1145 | return 0; | 1160 | return 0; |
1146 | 1161 | ||
1147 | error4: | 1162 | error4: |
@@ -1181,6 +1196,7 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) | |||
1181 | #if defined(DEBUG) || defined(INDUCE_IO_ERROR) | 1196 | #if defined(DEBUG) || defined(INDUCE_IO_ERROR) |
1182 | int64_t fsid; | 1197 | int64_t fsid; |
1183 | #endif | 1198 | #endif |
1199 | __uint64_t resblks; | ||
1184 | 1200 | ||
1185 | /* | 1201 | /* |
1186 | * We can potentially deadlock here if we have an inode cluster | 1202 | * We can potentially deadlock here if we have an inode cluster |
@@ -1209,6 +1225,23 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) | |||
1209 | xfs_binval(mp->m_rtdev_targp); | 1225 | xfs_binval(mp->m_rtdev_targp); |
1210 | } | 1226 | } |
1211 | 1227 | ||
1228 | /* | ||
1229 | * Unreserve any blocks we have so that when we unmount we don't account | ||
1230 | * the reserved free space as used. This is really only necessary for | ||
1231 | * lazy superblock counting because it trusts the incore superblock | ||
1232 | * counters to be aboslutely correct on clean unmount. | ||
1233 | * | ||
1234 | * We don't bother correcting this elsewhere for lazy superblock | ||
1235 | * counting because on mount of an unclean filesystem we reconstruct the | ||
1236 | * correct counter value and this is irrelevant. | ||
1237 | * | ||
1238 | * For non-lazy counter filesystems, this doesn't matter at all because | ||
1239 | * we only every apply deltas to the superblock and hence the incore | ||
1240 | * value does not matter.... | ||
1241 | */ | ||
1242 | resblks = 0; | ||
1243 | xfs_reserve_blocks(mp, &resblks, NULL); | ||
1244 | |||
1212 | xfs_log_sbcount(mp, 1); | 1245 | xfs_log_sbcount(mp, 1); |
1213 | xfs_unmountfs_writesb(mp); | 1246 | xfs_unmountfs_writesb(mp); |
1214 | xfs_unmountfs_wait(mp); /* wait for async bufs */ | 1247 | xfs_unmountfs_wait(mp); /* wait for async bufs */ |