diff options
| author | Ingo Molnar <mingo@elte.hu> | 2008-08-20 05:52:15 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-08-20 05:52:15 -0400 |
| commit | 7393423dd9b5790a3115873be355e9fc862bce8f (patch) | |
| tree | fc83214602c8ce41dc06d5c8e21deada679521f7 /fs/xfs/xfs_trans.c | |
| parent | 8df9676d6402563da91427e8d9f2da8a4598aede (diff) | |
| parent | 1fca25427482387689fa27594c992a961d98768f (diff) | |
Merge branch 'linus' into x86/cleanups
Diffstat (limited to 'fs/xfs/xfs_trans.c')
| -rw-r--r-- | fs/xfs/xfs_trans.c | 75 |
1 files changed, 69 insertions, 6 deletions
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index e4ebddd3c500..4e1c22a23be5 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
| @@ -43,6 +43,7 @@ | |||
| 43 | #include "xfs_quota.h" | 43 | #include "xfs_quota.h" |
| 44 | #include "xfs_trans_priv.h" | 44 | #include "xfs_trans_priv.h" |
| 45 | #include "xfs_trans_space.h" | 45 | #include "xfs_trans_space.h" |
| 46 | #include "xfs_inode_item.h" | ||
| 46 | 47 | ||
| 47 | 48 | ||
| 48 | STATIC void xfs_trans_apply_sb_deltas(xfs_trans_t *); | 49 | STATIC void xfs_trans_apply_sb_deltas(xfs_trans_t *); |
| @@ -253,7 +254,7 @@ _xfs_trans_alloc( | |||
| 253 | tp->t_mountp = mp; | 254 | tp->t_mountp = mp; |
| 254 | tp->t_items_free = XFS_LIC_NUM_SLOTS; | 255 | tp->t_items_free = XFS_LIC_NUM_SLOTS; |
| 255 | tp->t_busy_free = XFS_LBC_NUM_SLOTS; | 256 | tp->t_busy_free = XFS_LBC_NUM_SLOTS; |
| 256 | XFS_LIC_INIT(&(tp->t_items)); | 257 | xfs_lic_init(&(tp->t_items)); |
| 257 | XFS_LBC_INIT(&(tp->t_busy)); | 258 | XFS_LBC_INIT(&(tp->t_busy)); |
| 258 | return tp; | 259 | return tp; |
| 259 | } | 260 | } |
| @@ -282,7 +283,7 @@ xfs_trans_dup( | |||
| 282 | ntp->t_mountp = tp->t_mountp; | 283 | ntp->t_mountp = tp->t_mountp; |
| 283 | ntp->t_items_free = XFS_LIC_NUM_SLOTS; | 284 | ntp->t_items_free = XFS_LIC_NUM_SLOTS; |
| 284 | ntp->t_busy_free = XFS_LBC_NUM_SLOTS; | 285 | ntp->t_busy_free = XFS_LBC_NUM_SLOTS; |
| 285 | XFS_LIC_INIT(&(ntp->t_items)); | 286 | xfs_lic_init(&(ntp->t_items)); |
| 286 | XFS_LBC_INIT(&(ntp->t_busy)); | 287 | XFS_LBC_INIT(&(ntp->t_busy)); |
| 287 | 288 | ||
| 288 | ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); | 289 | ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); |
| @@ -1169,7 +1170,7 @@ xfs_trans_cancel( | |||
| 1169 | while (licp != NULL) { | 1170 | while (licp != NULL) { |
| 1170 | lidp = licp->lic_descs; | 1171 | lidp = licp->lic_descs; |
| 1171 | for (i = 0; i < licp->lic_unused; i++, lidp++) { | 1172 | for (i = 0; i < licp->lic_unused; i++, lidp++) { |
| 1172 | if (XFS_LIC_ISFREE(licp, i)) { | 1173 | if (xfs_lic_isfree(licp, i)) { |
| 1173 | continue; | 1174 | continue; |
| 1174 | } | 1175 | } |
| 1175 | 1176 | ||
| @@ -1216,6 +1217,68 @@ xfs_trans_free( | |||
| 1216 | kmem_zone_free(xfs_trans_zone, tp); | 1217 | kmem_zone_free(xfs_trans_zone, tp); |
| 1217 | } | 1218 | } |
| 1218 | 1219 | ||
| 1220 | /* | ||
| 1221 | * Roll from one trans in the sequence of PERMANENT transactions to | ||
| 1222 | * the next: permanent transactions are only flushed out when | ||
| 1223 | * committed with XFS_TRANS_RELEASE_LOG_RES, but we still want as soon | ||
| 1224 | * as possible to let chunks of it go to the log. So we commit the | ||
| 1225 | * chunk we've been working on and get a new transaction to continue. | ||
| 1226 | */ | ||
| 1227 | int | ||
| 1228 | xfs_trans_roll( | ||
| 1229 | struct xfs_trans **tpp, | ||
| 1230 | struct xfs_inode *dp) | ||
| 1231 | { | ||
| 1232 | struct xfs_trans *trans; | ||
| 1233 | unsigned int logres, count; | ||
| 1234 | int error; | ||
| 1235 | |||
| 1236 | /* | ||
| 1237 | * Ensure that the inode is always logged. | ||
| 1238 | */ | ||
| 1239 | trans = *tpp; | ||
| 1240 | xfs_trans_log_inode(trans, dp, XFS_ILOG_CORE); | ||
| 1241 | |||
| 1242 | /* | ||
| 1243 | * Copy the critical parameters from one trans to the next. | ||
| 1244 | */ | ||
| 1245 | logres = trans->t_log_res; | ||
| 1246 | count = trans->t_log_count; | ||
| 1247 | *tpp = xfs_trans_dup(trans); | ||
| 1248 | |||
| 1249 | /* | ||
| 1250 | * Commit the current transaction. | ||
| 1251 | * If this commit failed, then it'd just unlock those items that | ||
| 1252 | * are not marked ihold. That also means that a filesystem shutdown | ||
| 1253 | * is in progress. The caller takes the responsibility to cancel | ||
| 1254 | * the duplicate transaction that gets returned. | ||
| 1255 | */ | ||
| 1256 | error = xfs_trans_commit(trans, 0); | ||
| 1257 | if (error) | ||
| 1258 | return (error); | ||
| 1259 | |||
| 1260 | trans = *tpp; | ||
| 1261 | |||
| 1262 | /* | ||
| 1263 | * Reserve space in the log for th next transaction. | ||
| 1264 | * This also pushes items in the "AIL", the list of logged items, | ||
| 1265 | * out to disk if they are taking up space at the tail of the log | ||
| 1266 | * that we want to use. This requires that either nothing be locked | ||
| 1267 | * across this call, or that anything that is locked be logged in | ||
| 1268 | * the prior and the next transactions. | ||
| 1269 | */ | ||
| 1270 | error = xfs_trans_reserve(trans, 0, logres, 0, | ||
| 1271 | XFS_TRANS_PERM_LOG_RES, count); | ||
| 1272 | /* | ||
| 1273 | * Ensure that the inode is in the new transaction and locked. | ||
| 1274 | */ | ||
| 1275 | if (error) | ||
| 1276 | return error; | ||
| 1277 | |||
| 1278 | xfs_trans_ijoin(trans, dp, XFS_ILOCK_EXCL); | ||
| 1279 | xfs_trans_ihold(trans, dp); | ||
| 1280 | return 0; | ||
| 1281 | } | ||
| 1219 | 1282 | ||
| 1220 | /* | 1283 | /* |
| 1221 | * THIS SHOULD BE REWRITTEN TO USE xfs_trans_next_item(). | 1284 | * THIS SHOULD BE REWRITTEN TO USE xfs_trans_next_item(). |
| @@ -1253,7 +1316,7 @@ xfs_trans_committed( | |||
| 1253 | * Special case the chunk embedded in the transaction. | 1316 | * Special case the chunk embedded in the transaction. |
| 1254 | */ | 1317 | */ |
| 1255 | licp = &(tp->t_items); | 1318 | licp = &(tp->t_items); |
| 1256 | if (!(XFS_LIC_ARE_ALL_FREE(licp))) { | 1319 | if (!(xfs_lic_are_all_free(licp))) { |
| 1257 | xfs_trans_chunk_committed(licp, tp->t_lsn, abortflag); | 1320 | xfs_trans_chunk_committed(licp, tp->t_lsn, abortflag); |
| 1258 | } | 1321 | } |
| 1259 | 1322 | ||
| @@ -1262,7 +1325,7 @@ xfs_trans_committed( | |||
| 1262 | */ | 1325 | */ |
| 1263 | licp = licp->lic_next; | 1326 | licp = licp->lic_next; |
| 1264 | while (licp != NULL) { | 1327 | while (licp != NULL) { |
| 1265 | ASSERT(!XFS_LIC_ARE_ALL_FREE(licp)); | 1328 | ASSERT(!xfs_lic_are_all_free(licp)); |
| 1266 | xfs_trans_chunk_committed(licp, tp->t_lsn, abortflag); | 1329 | xfs_trans_chunk_committed(licp, tp->t_lsn, abortflag); |
| 1267 | next_licp = licp->lic_next; | 1330 | next_licp = licp->lic_next; |
| 1268 | kmem_free(licp); | 1331 | kmem_free(licp); |
| @@ -1325,7 +1388,7 @@ xfs_trans_chunk_committed( | |||
| 1325 | 1388 | ||
| 1326 | lidp = licp->lic_descs; | 1389 | lidp = licp->lic_descs; |
| 1327 | for (i = 0; i < licp->lic_unused; i++, lidp++) { | 1390 | for (i = 0; i < licp->lic_unused; i++, lidp++) { |
| 1328 | if (XFS_LIC_ISFREE(licp, i)) { | 1391 | if (xfs_lic_isfree(licp, i)) { |
| 1329 | continue; | 1392 | continue; |
| 1330 | } | 1393 | } |
| 1331 | 1394 | ||
