aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_attr.c30
-rw-r--r--fs/xfs/xfs_attr_leaf.c75
-rw-r--r--fs/xfs/xfs_attr_leaf.h2
-rw-r--r--fs/xfs/xfs_trans.c63
-rw-r--r--fs/xfs/xfs_trans.h1
5 files changed, 92 insertions, 79 deletions
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index ffa634d1c18c..f7cdc28aff41 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -400,7 +400,9 @@ xfs_attr_set_int(xfs_inode_t *dp, struct xfs_name *name,
400 * Commit the leaf transformation. We'll need another (linked) 400 * Commit the leaf transformation. We'll need another (linked)
401 * transaction to add the new attribute to the leaf. 401 * transaction to add the new attribute to the leaf.
402 */ 402 */
403 if ((error = xfs_attr_rolltrans(&args.trans, dp))) 403
404 error = xfs_trans_roll(&args.trans, dp);
405 if (error)
404 goto out; 406 goto out;
405 407
406 } 408 }
@@ -980,7 +982,8 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
980 * Commit the current trans (including the inode) and start 982 * Commit the current trans (including the inode) and start
981 * a new one. 983 * a new one.
982 */ 984 */
983 if ((error = xfs_attr_rolltrans(&args->trans, dp))) 985 error = xfs_trans_roll(&args->trans, dp);
986 if (error)
984 return (error); 987 return (error);
985 988
986 /* 989 /*
@@ -994,7 +997,8 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
994 * Commit the transaction that added the attr name so that 997 * Commit the transaction that added the attr name so that
995 * later routines can manage their own transactions. 998 * later routines can manage their own transactions.
996 */ 999 */
997 if ((error = xfs_attr_rolltrans(&args->trans, dp))) 1000 error = xfs_trans_roll(&args->trans, dp);
1001 if (error)
998 return (error); 1002 return (error);
999 1003
1000 /* 1004 /*
@@ -1083,7 +1087,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
1083 /* 1087 /*
1084 * Commit the remove and start the next trans in series. 1088 * Commit the remove and start the next trans in series.
1085 */ 1089 */
1086 error = xfs_attr_rolltrans(&args->trans, dp); 1090 error = xfs_trans_roll(&args->trans, dp);
1087 1091
1088 } else if (args->rmtblkno > 0) { 1092 } else if (args->rmtblkno > 0) {
1089 /* 1093 /*
@@ -1314,7 +1318,8 @@ restart:
1314 * Commit the node conversion and start the next 1318 * Commit the node conversion and start the next
1315 * trans in the chain. 1319 * trans in the chain.
1316 */ 1320 */
1317 if ((error = xfs_attr_rolltrans(&args->trans, dp))) 1321 error = xfs_trans_roll(&args->trans, dp);
1322 if (error)
1318 goto out; 1323 goto out;
1319 1324
1320 goto restart; 1325 goto restart;
@@ -1365,7 +1370,8 @@ restart:
1365 * Commit the leaf addition or btree split and start the next 1370 * Commit the leaf addition or btree split and start the next
1366 * trans in the chain. 1371 * trans in the chain.
1367 */ 1372 */
1368 if ((error = xfs_attr_rolltrans(&args->trans, dp))) 1373 error = xfs_trans_roll(&args->trans, dp);
1374 if (error)
1369 goto out; 1375 goto out;
1370 1376
1371 /* 1377 /*
@@ -1465,7 +1471,8 @@ restart:
1465 /* 1471 /*
1466 * Commit and start the next trans in the chain. 1472 * Commit and start the next trans in the chain.
1467 */ 1473 */
1468 if ((error = xfs_attr_rolltrans(&args->trans, dp))) 1474 error = xfs_trans_roll(&args->trans, dp);
1475 if (error)
1469 goto out; 1476 goto out;
1470 1477
1471 } else if (args->rmtblkno > 0) { 1478 } else if (args->rmtblkno > 0) {
@@ -1597,7 +1604,8 @@ xfs_attr_node_removename(xfs_da_args_t *args)
1597 /* 1604 /*
1598 * Commit the Btree join operation and start a new trans. 1605 * Commit the Btree join operation and start a new trans.
1599 */ 1606 */
1600 if ((error = xfs_attr_rolltrans(&args->trans, dp))) 1607 error = xfs_trans_roll(&args->trans, dp);
1608 if (error)
1601 goto out; 1609 goto out;
1602 } 1610 }
1603 1611
@@ -2098,7 +2106,8 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)
2098 /* 2106 /*
2099 * Start the next trans in the chain. 2107 * Start the next trans in the chain.
2100 */ 2108 */
2101 if ((error = xfs_attr_rolltrans(&args->trans, dp))) 2109 error = xfs_trans_roll(&args->trans, dp);
2110 if (error)
2102 return (error); 2111 return (error);
2103 } 2112 }
2104 2113
@@ -2248,7 +2257,8 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)
2248 /* 2257 /*
2249 * Close out trans and start the next one in the chain. 2258 * Close out trans and start the next one in the chain.
2250 */ 2259 */
2251 if ((error = xfs_attr_rolltrans(&args->trans, args->dp))) 2260 error = xfs_trans_roll(&args->trans, args->dp);
2261 if (error)
2252 return (error); 2262 return (error);
2253 } 2263 }
2254 return(0); 2264 return(0);
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 23ef5d7c87e1..79da6b2ea99e 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -2498,9 +2498,7 @@ xfs_attr_leaf_clearflag(xfs_da_args_t *args)
2498 /* 2498 /*
2499 * Commit the flag value change and start the next trans in series. 2499 * Commit the flag value change and start the next trans in series.
2500 */ 2500 */
2501 error = xfs_attr_rolltrans(&args->trans, args->dp); 2501 return xfs_trans_roll(&args->trans, args->dp);
2502
2503 return(error);
2504} 2502}
2505 2503
2506/* 2504/*
@@ -2547,9 +2545,7 @@ xfs_attr_leaf_setflag(xfs_da_args_t *args)
2547 /* 2545 /*
2548 * Commit the flag value change and start the next trans in series. 2546 * Commit the flag value change and start the next trans in series.
2549 */ 2547 */
2550 error = xfs_attr_rolltrans(&args->trans, args->dp); 2548 return xfs_trans_roll(&args->trans, args->dp);
2551
2552 return(error);
2553} 2549}
2554 2550
2555/* 2551/*
@@ -2665,7 +2661,7 @@ xfs_attr_leaf_flipflags(xfs_da_args_t *args)
2665 /* 2661 /*
2666 * Commit the flag value change and start the next trans in series. 2662 * Commit the flag value change and start the next trans in series.
2667 */ 2663 */
2668 error = xfs_attr_rolltrans(&args->trans, args->dp); 2664 error = xfs_trans_roll(&args->trans, args->dp);
2669 2665
2670 return(error); 2666 return(error);
2671} 2667}
@@ -2723,7 +2719,7 @@ xfs_attr_root_inactive(xfs_trans_t **trans, xfs_inode_t *dp)
2723 /* 2719 /*
2724 * Commit the invalidate and start the next transaction. 2720 * Commit the invalidate and start the next transaction.
2725 */ 2721 */
2726 error = xfs_attr_rolltrans(trans, dp); 2722 error = xfs_trans_roll(trans, dp);
2727 2723
2728 return (error); 2724 return (error);
2729} 2725}
@@ -2825,7 +2821,8 @@ xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp,
2825 /* 2821 /*
2826 * Atomically commit the whole invalidate stuff. 2822 * Atomically commit the whole invalidate stuff.
2827 */ 2823 */
2828 if ((error = xfs_attr_rolltrans(trans, dp))) 2824 error = xfs_trans_roll(trans, dp);
2825 if (error)
2829 return (error); 2826 return (error);
2830 } 2827 }
2831 2828
@@ -2964,7 +2961,8 @@ xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp,
2964 /* 2961 /*
2965 * Roll to next transaction. 2962 * Roll to next transaction.
2966 */ 2963 */
2967 if ((error = xfs_attr_rolltrans(trans, dp))) 2964 error = xfs_trans_roll(trans, dp);
2965 if (error)
2968 return (error); 2966 return (error);
2969 } 2967 }
2970 2968
@@ -2974,60 +2972,3 @@ xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp,
2974 2972
2975 return(0); 2973 return(0);
2976} 2974}
2977
2978
2979/*
2980 * Roll from one trans in the sequence of PERMANENT transactions to the next.
2981 */
2982int
2983xfs_attr_rolltrans(xfs_trans_t **transp, xfs_inode_t *dp)
2984{
2985 xfs_trans_t *trans;
2986 unsigned int logres, count;
2987 int error;
2988
2989 /*
2990 * Ensure that the inode is always logged.
2991 */
2992 trans = *transp;
2993 xfs_trans_log_inode(trans, dp, XFS_ILOG_CORE);
2994
2995 /*
2996 * Copy the critical parameters from one trans to the next.
2997 */
2998 logres = trans->t_log_res;
2999 count = trans->t_log_count;
3000 *transp = xfs_trans_dup(trans);
3001
3002 /*
3003 * Commit the current transaction.
3004 * If this commit failed, then it'd just unlock those items that
3005 * are not marked ihold. That also means that a filesystem shutdown
3006 * is in progress. The caller takes the responsibility to cancel
3007 * the duplicate transaction that gets returned.
3008 */
3009 if ((error = xfs_trans_commit(trans, 0)))
3010 return (error);
3011
3012 trans = *transp;
3013
3014 /*
3015 * Reserve space in the log for th next transaction.
3016 * This also pushes items in the "AIL", the list of logged items,
3017 * out to disk if they are taking up space at the tail of the log
3018 * that we want to use. This requires that either nothing be locked
3019 * across this call, or that anything that is locked be logged in
3020 * the prior and the next transactions.
3021 */
3022 error = xfs_trans_reserve(trans, 0, logres, 0,
3023 XFS_TRANS_PERM_LOG_RES, count);
3024 /*
3025 * Ensure that the inode is in the new transaction and locked.
3026 */
3027 if (!error) {
3028 xfs_trans_ijoin(trans, dp, XFS_ILOCK_EXCL);
3029 xfs_trans_ihold(trans, dp);
3030 }
3031 return (error);
3032
3033}
diff --git a/fs/xfs/xfs_attr_leaf.h b/fs/xfs/xfs_attr_leaf.h
index 5ecf437b7825..83e9af417ca2 100644
--- a/fs/xfs/xfs_attr_leaf.h
+++ b/fs/xfs/xfs_attr_leaf.h
@@ -274,6 +274,4 @@ int xfs_attr_leaf_order(struct xfs_dabuf *leaf1_bp,
274 struct xfs_dabuf *leaf2_bp); 274 struct xfs_dabuf *leaf2_bp);
275int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, 275int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize,
276 int *local); 276 int *local);
277int xfs_attr_rolltrans(struct xfs_trans **transp, struct xfs_inode *dp);
278
279#endif /* __XFS_ATTR_LEAF_H__ */ 277#endif /* __XFS_ATTR_LEAF_H__ */
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index e4ebddd3c500..d98758a09677 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
48STATIC void xfs_trans_apply_sb_deltas(xfs_trans_t *); 49STATIC void xfs_trans_apply_sb_deltas(xfs_trans_t *);
@@ -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 */
1227int
1228xfs_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().
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index 0804207c7391..9161e998f1a6 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -986,6 +986,7 @@ int _xfs_trans_commit(xfs_trans_t *,
986 int *); 986 int *);
987#define xfs_trans_commit(tp, flags) _xfs_trans_commit(tp, flags, NULL) 987#define xfs_trans_commit(tp, flags) _xfs_trans_commit(tp, flags, NULL)
988void xfs_trans_cancel(xfs_trans_t *, int); 988void xfs_trans_cancel(xfs_trans_t *, int);
989int xfs_trans_roll(struct xfs_trans **, struct xfs_inode *);
989int xfs_trans_ail_init(struct xfs_mount *); 990int xfs_trans_ail_init(struct xfs_mount *);
990void xfs_trans_ail_destroy(struct xfs_mount *); 991void xfs_trans_ail_destroy(struct xfs_mount *);
991void xfs_trans_push_ail(struct xfs_mount *, xfs_lsn_t); 992void xfs_trans_push_ail(struct xfs_mount *, xfs_lsn_t);