aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_trans.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2010-03-07 19:28:28 -0500
committerAlex Elder <aelder@sgi.com>2010-05-19 10:58:08 -0400
commit0924378a689ccb05f6d60875742dc28f69bf0129 (patch)
tree8d6933bff18ac9f4670395673e38dad94fedd998 /fs/xfs/xfs_trans.c
parent713bf88bba55b8dd91a18e8a59b0f97bf9b0f5de (diff)
xfs: split out iclog writing from xfs_trans_commit()
Split the the part of xfs_trans_commit() that deals with writing the transaction into the iclog into a separate function. This isolates the physical commit process from the logical commit operation and makes it easier to insert different transaction commit paths without affecting the existing algorithm adversely. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/xfs/xfs_trans.c')
-rw-r--r--fs/xfs/xfs_trans.c387
1 files changed, 199 insertions, 188 deletions
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 6962f2bd3da3..e07b3290b3bf 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -47,8 +47,6 @@
47 47
48 48
49STATIC void xfs_trans_apply_sb_deltas(xfs_trans_t *); 49STATIC void xfs_trans_apply_sb_deltas(xfs_trans_t *);
50STATIC uint xfs_trans_count_vecs(xfs_trans_t *);
51STATIC void xfs_trans_fill_vecs(xfs_trans_t *, xfs_log_iovec_t *);
52STATIC void xfs_trans_uncommit(xfs_trans_t *, uint); 50STATIC void xfs_trans_uncommit(xfs_trans_t *, uint);
53STATIC void xfs_trans_committed(xfs_trans_t *, int); 51STATIC void xfs_trans_committed(xfs_trans_t *, int);
54STATIC void xfs_trans_chunk_committed(xfs_log_item_chunk_t *, xfs_lsn_t, int); 52STATIC void xfs_trans_chunk_committed(xfs_log_item_chunk_t *, xfs_lsn_t, int);
@@ -764,94 +762,126 @@ xfs_trans_unreserve_and_mod_sb(
764 } 762 }
765} 763}
766 764
767
768/* 765/*
769 * xfs_trans_commit 766 * Total up the number of log iovecs needed to commit this
770 * 767 * transaction. The transaction itself needs one for the
771 * Commit the given transaction to the log a/synchronously. 768 * transaction header. Ask each dirty item in turn how many
772 * 769 * it needs to get the total.
773 * XFS disk error handling mechanism is not based on a typical
774 * transaction abort mechanism. Logically after the filesystem
775 * gets marked 'SHUTDOWN', we can't let any new transactions
776 * be durable - ie. committed to disk - because some metadata might
777 * be inconsistent. In such cases, this returns an error, and the
778 * caller may assume that all locked objects joined to the transaction
779 * have already been unlocked as if the commit had succeeded.
780 * Do not reference the transaction structure after this call.
781 */ 770 */
782 /*ARGSUSED*/ 771static uint
783int 772xfs_trans_count_vecs(
784_xfs_trans_commit( 773 xfs_trans_t *tp)
785 xfs_trans_t *tp,
786 uint flags,
787 int *log_flushed)
788{ 774{
789 xfs_log_iovec_t *log_vector; 775 int nvecs;
790 int nvec; 776 xfs_log_item_desc_t *lidp;
791 xfs_mount_t *mp;
792 xfs_lsn_t commit_lsn;
793 /* REFERENCED */
794 int error;
795 int log_flags;
796 int sync;
797#define XFS_TRANS_LOGVEC_COUNT 16
798 xfs_log_iovec_t log_vector_fast[XFS_TRANS_LOGVEC_COUNT];
799 struct xlog_in_core *commit_iclog;
800 int shutdown;
801 777
802 commit_lsn = -1; 778 nvecs = 1;
779 lidp = xfs_trans_first_item(tp);
780 ASSERT(lidp != NULL);
803 781
804 /* 782 /* In the non-debug case we need to start bailing out if we
805 * Determine whether this commit is releasing a permanent 783 * didn't find a log_item here, return zero and let trans_commit
806 * log reservation or not. 784 * deal with it.
807 */ 785 */
808 if (flags & XFS_TRANS_RELEASE_LOG_RES) { 786 if (lidp == NULL)
809 ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); 787 return 0;
810 log_flags = XFS_LOG_REL_PERM_RESERV; 788
811 } else { 789 while (lidp != NULL) {
812 log_flags = 0; 790 /*
791 * Skip items which aren't dirty in this transaction.
792 */
793 if (!(lidp->lid_flags & XFS_LID_DIRTY)) {
794 lidp = xfs_trans_next_item(tp, lidp);
795 continue;
796 }
797 lidp->lid_size = IOP_SIZE(lidp->lid_item);
798 nvecs += lidp->lid_size;
799 lidp = xfs_trans_next_item(tp, lidp);
813 } 800 }
814 mp = tp->t_mountp; 801
802 return nvecs;
803}
804
805/*
806 * Fill in the vector with pointers to data to be logged
807 * by this transaction. The transaction header takes
808 * the first vector, and then each dirty item takes the
809 * number of vectors it indicated it needed in xfs_trans_count_vecs().
810 *
811 * As each item fills in the entries it needs, also pin the item
812 * so that it cannot be flushed out until the log write completes.
813 */
814static void
815xfs_trans_fill_vecs(
816 struct xfs_trans *tp,
817 struct xfs_log_iovec *log_vector)
818{
819 xfs_log_item_desc_t *lidp;
820 struct xfs_log_iovec *vecp;
821 uint nitems;
815 822
816 /* 823 /*
817 * If there is nothing to be logged by the transaction, 824 * Skip over the entry for the transaction header, we'll
818 * then unlock all of the items associated with the 825 * fill that in at the end.
819 * transaction and free the transaction structure.
820 * Also make sure to return any reserved blocks to
821 * the free pool.
822 */ 826 */
823shut_us_down: 827 vecp = log_vector + 1;
824 shutdown = XFS_FORCED_SHUTDOWN(mp) ? EIO : 0; 828
825 if (!(tp->t_flags & XFS_TRANS_DIRTY) || shutdown) { 829 nitems = 0;
826 xfs_trans_unreserve_and_mod_sb(tp); 830 lidp = xfs_trans_first_item(tp);
831 ASSERT(lidp);
832 while (lidp) {
833 /* Skip items which aren't dirty in this transaction. */
834 if (!(lidp->lid_flags & XFS_LID_DIRTY)) {
835 lidp = xfs_trans_next_item(tp, lidp);
836 continue;
837 }
838
827 /* 839 /*
828 * It is indeed possible for the transaction to be 840 * The item may be marked dirty but not log anything. This can
829 * not dirty but the dqinfo portion to be. All that 841 * be used to get called when a transaction is committed.
830 * means is that we have some (non-persistent) quota
831 * reservations that need to be unreserved.
832 */ 842 */
833 xfs_trans_unreserve_and_mod_dquots(tp); 843 if (lidp->lid_size)
834 if (tp->t_ticket) { 844 nitems++;
835 commit_lsn = xfs_log_done(mp, tp->t_ticket, 845 IOP_FORMAT(lidp->lid_item, vecp);
836 NULL, log_flags); 846 vecp += lidp->lid_size;
837 if (commit_lsn == -1 && !shutdown) 847 IOP_PIN(lidp->lid_item);
838 shutdown = XFS_ERROR(EIO); 848 lidp = xfs_trans_next_item(tp, lidp);
839 }
840 current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
841 xfs_trans_free_items(tp, shutdown? XFS_TRANS_ABORT : 0);
842 xfs_trans_free_busy(tp);
843 xfs_trans_free(tp);
844 XFS_STATS_INC(xs_trans_empty);
845 return (shutdown);
846 } 849 }
847 ASSERT(tp->t_ticket != NULL);
848 850
849 /* 851 /*
850 * If we need to update the superblock, then do it now. 852 * Now that we've counted the number of items in this transaction, fill
853 * in the transaction header. Note that the transaction header does not
854 * have a log item.
851 */ 855 */
852 if (tp->t_flags & XFS_TRANS_SB_DIRTY) 856 tp->t_header.th_magic = XFS_TRANS_HEADER_MAGIC;
853 xfs_trans_apply_sb_deltas(tp); 857 tp->t_header.th_type = tp->t_type;
854 xfs_trans_apply_dquot_deltas(tp); 858 tp->t_header.th_num_items = nitems;
859 log_vector->i_addr = (xfs_caddr_t)&tp->t_header;
860 log_vector->i_len = sizeof(xfs_trans_header_t);
861 log_vector->i_type = XLOG_REG_TYPE_TRANSHDR;
862}
863
864/*
865 * Format the transaction direct to the iclog. This isolates the physical
866 * transaction commit operation from the logical operation and hence allows
867 * other methods to be introduced without affecting the existing commit path.
868 */
869static int
870xfs_trans_commit_iclog(
871 struct xfs_mount *mp,
872 struct xfs_trans *tp,
873 xfs_lsn_t *commit_lsn,
874 int flags)
875{
876 int shutdown;
877 int error;
878 int log_flags = 0;
879 struct xlog_in_core *commit_iclog;
880#define XFS_TRANS_LOGVEC_COUNT 16
881 struct xfs_log_iovec log_vector_fast[XFS_TRANS_LOGVEC_COUNT];
882 struct xfs_log_iovec *log_vector;
883 uint nvec;
884
855 885
856 /* 886 /*
857 * Ask each log item how many log_vector entries it will 887 * Ask each log item how many log_vector entries it will
@@ -861,8 +891,7 @@ shut_us_down:
861 */ 891 */
862 nvec = xfs_trans_count_vecs(tp); 892 nvec = xfs_trans_count_vecs(tp);
863 if (nvec == 0) { 893 if (nvec == 0) {
864 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR); 894 return ENOMEM; /* triggers a shutdown! */
865 goto shut_us_down;
866 } else if (nvec <= XFS_TRANS_LOGVEC_COUNT) { 895 } else if (nvec <= XFS_TRANS_LOGVEC_COUNT) {
867 log_vector = log_vector_fast; 896 log_vector = log_vector_fast;
868 } else { 897 } else {
@@ -877,6 +906,9 @@ shut_us_down:
877 */ 906 */
878 xfs_trans_fill_vecs(tp, log_vector); 907 xfs_trans_fill_vecs(tp, log_vector);
879 908
909 if (flags & XFS_TRANS_RELEASE_LOG_RES)
910 log_flags = XFS_LOG_REL_PERM_RESERV;
911
880 error = xfs_log_write(mp, log_vector, nvec, tp->t_ticket, &(tp->t_lsn)); 912 error = xfs_log_write(mp, log_vector, nvec, tp->t_ticket, &(tp->t_lsn));
881 913
882 /* 914 /*
@@ -884,18 +916,17 @@ shut_us_down:
884 * at any time after this call. However, all the items associated 916 * at any time after this call. However, all the items associated
885 * with the transaction are still locked and pinned in memory. 917 * with the transaction are still locked and pinned in memory.
886 */ 918 */
887 commit_lsn = xfs_log_done(mp, tp->t_ticket, &commit_iclog, log_flags); 919 *commit_lsn = xfs_log_done(mp, tp->t_ticket, &commit_iclog, log_flags);
888 920
889 tp->t_commit_lsn = commit_lsn; 921 tp->t_commit_lsn = *commit_lsn;
890 if (nvec > XFS_TRANS_LOGVEC_COUNT) { 922 if (nvec > XFS_TRANS_LOGVEC_COUNT)
891 kmem_free(log_vector); 923 kmem_free(log_vector);
892 }
893 924
894 /* 925 /*
895 * If we got a log write error. Unpin the logitems that we 926 * If we got a log write error. Unpin the logitems that we
896 * had pinned, clean up, free trans structure, and return error. 927 * had pinned, clean up, free trans structure, and return error.
897 */ 928 */
898 if (error || commit_lsn == -1) { 929 if (error || *commit_lsn == -1) {
899 current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); 930 current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
900 xfs_trans_uncommit(tp, flags|XFS_TRANS_ABORT); 931 xfs_trans_uncommit(tp, flags|XFS_TRANS_ABORT);
901 return XFS_ERROR(EIO); 932 return XFS_ERROR(EIO);
@@ -909,8 +940,6 @@ shut_us_down:
909 */ 940 */
910 xfs_trans_unreserve_and_mod_sb(tp); 941 xfs_trans_unreserve_and_mod_sb(tp);
911 942
912 sync = tp->t_flags & XFS_TRANS_SYNC;
913
914 /* 943 /*
915 * Tell the LM to call the transaction completion routine 944 * Tell the LM to call the transaction completion routine
916 * when the log write with LSN commit_lsn completes (e.g. 945 * when the log write with LSN commit_lsn completes (e.g.
@@ -953,7 +982,7 @@ shut_us_down:
953 * the commit lsn of this transaction for dependency tracking 982 * the commit lsn of this transaction for dependency tracking
954 * purposes. 983 * purposes.
955 */ 984 */
956 xfs_trans_unlock_items(tp, commit_lsn); 985 xfs_trans_unlock_items(tp, *commit_lsn);
957 986
958 /* 987 /*
959 * If we detected a log error earlier, finish committing 988 * If we detected a log error earlier, finish committing
@@ -973,7 +1002,92 @@ shut_us_down:
973 * and the items are released we can finally allow the iclog to 1002 * and the items are released we can finally allow the iclog to
974 * go to disk. 1003 * go to disk.
975 */ 1004 */
976 error = xfs_log_release_iclog(mp, commit_iclog); 1005 return xfs_log_release_iclog(mp, commit_iclog);
1006}
1007
1008
1009/*
1010 * xfs_trans_commit
1011 *
1012 * Commit the given transaction to the log a/synchronously.
1013 *
1014 * XFS disk error handling mechanism is not based on a typical
1015 * transaction abort mechanism. Logically after the filesystem
1016 * gets marked 'SHUTDOWN', we can't let any new transactions
1017 * be durable - ie. committed to disk - because some metadata might
1018 * be inconsistent. In such cases, this returns an error, and the
1019 * caller may assume that all locked objects joined to the transaction
1020 * have already been unlocked as if the commit had succeeded.
1021 * Do not reference the transaction structure after this call.
1022 */
1023 /*ARGSUSED*/
1024int
1025_xfs_trans_commit(
1026 xfs_trans_t *tp,
1027 uint flags,
1028 int *log_flushed)
1029{
1030 xfs_mount_t *mp = tp->t_mountp;
1031 xfs_lsn_t commit_lsn = -1;
1032 int error;
1033 int log_flags = 0;
1034 int sync = tp->t_flags & XFS_TRANS_SYNC;
1035 int shutdown;
1036
1037 /*
1038 * Determine whether this commit is releasing a permanent
1039 * log reservation or not.
1040 */
1041 if (flags & XFS_TRANS_RELEASE_LOG_RES) {
1042 ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES);
1043 log_flags = XFS_LOG_REL_PERM_RESERV;
1044 }
1045
1046 /*
1047 * If there is nothing to be logged by the transaction,
1048 * then unlock all of the items associated with the
1049 * transaction and free the transaction structure.
1050 * Also make sure to return any reserved blocks to
1051 * the free pool.
1052 */
1053shut_us_down:
1054 shutdown = XFS_FORCED_SHUTDOWN(mp) ? EIO : 0;
1055 if (!(tp->t_flags & XFS_TRANS_DIRTY) || shutdown) {
1056 xfs_trans_unreserve_and_mod_sb(tp);
1057 /*
1058 * It is indeed possible for the transaction to be
1059 * not dirty but the dqinfo portion to be. All that
1060 * means is that we have some (non-persistent) quota
1061 * reservations that need to be unreserved.
1062 */
1063 xfs_trans_unreserve_and_mod_dquots(tp);
1064 if (tp->t_ticket) {
1065 commit_lsn = xfs_log_done(mp, tp->t_ticket,
1066 NULL, log_flags);
1067 if (commit_lsn == -1 && !shutdown)
1068 shutdown = XFS_ERROR(EIO);
1069 }
1070 current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
1071 xfs_trans_free_items(tp, shutdown? XFS_TRANS_ABORT : 0);
1072 xfs_trans_free_busy(tp);
1073 xfs_trans_free(tp);
1074 XFS_STATS_INC(xs_trans_empty);
1075 return (shutdown);
1076 }
1077 ASSERT(tp->t_ticket != NULL);
1078
1079 /*
1080 * If we need to update the superblock, then do it now.
1081 */
1082 if (tp->t_flags & XFS_TRANS_SB_DIRTY)
1083 xfs_trans_apply_sb_deltas(tp);
1084 xfs_trans_apply_dquot_deltas(tp);
1085
1086 error = xfs_trans_commit_iclog(mp, tp, &commit_lsn, flags);
1087 if (error == ENOMEM) {
1088 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
1089 goto shut_us_down;
1090 }
977 1091
978 /* 1092 /*
979 * If the transaction needs to be synchronous, then force the 1093 * If the transaction needs to be synchronous, then force the
@@ -992,47 +1106,6 @@ shut_us_down:
992 return (error); 1106 return (error);
993} 1107}
994 1108
995
996/*
997 * Total up the number of log iovecs needed to commit this
998 * transaction. The transaction itself needs one for the
999 * transaction header. Ask each dirty item in turn how many
1000 * it needs to get the total.
1001 */
1002STATIC uint
1003xfs_trans_count_vecs(
1004 xfs_trans_t *tp)
1005{
1006 int nvecs;
1007 xfs_log_item_desc_t *lidp;
1008
1009 nvecs = 1;
1010 lidp = xfs_trans_first_item(tp);
1011 ASSERT(lidp != NULL);
1012
1013 /* In the non-debug case we need to start bailing out if we
1014 * didn't find a log_item here, return zero and let trans_commit
1015 * deal with it.
1016 */
1017 if (lidp == NULL)
1018 return 0;
1019
1020 while (lidp != NULL) {
1021 /*
1022 * Skip items which aren't dirty in this transaction.
1023 */
1024 if (!(lidp->lid_flags & XFS_LID_DIRTY)) {
1025 lidp = xfs_trans_next_item(tp, lidp);
1026 continue;
1027 }
1028 lidp->lid_size = IOP_SIZE(lidp->lid_item);
1029 nvecs += lidp->lid_size;
1030 lidp = xfs_trans_next_item(tp, lidp);
1031 }
1032
1033 return nvecs;
1034}
1035
1036/* 1109/*
1037 * Called from the trans_commit code when we notice that 1110 * Called from the trans_commit code when we notice that
1038 * the filesystem is in the middle of a forced shutdown. 1111 * the filesystem is in the middle of a forced shutdown.
@@ -1063,68 +1136,6 @@ xfs_trans_uncommit(
1063} 1136}
1064 1137
1065/* 1138/*
1066 * Fill in the vector with pointers to data to be logged
1067 * by this transaction. The transaction header takes
1068 * the first vector, and then each dirty item takes the
1069 * number of vectors it indicated it needed in xfs_trans_count_vecs().
1070 *
1071 * As each item fills in the entries it needs, also pin the item
1072 * so that it cannot be flushed out until the log write completes.
1073 */
1074STATIC void
1075xfs_trans_fill_vecs(
1076 xfs_trans_t *tp,
1077 xfs_log_iovec_t *log_vector)
1078{
1079 xfs_log_item_desc_t *lidp;
1080 xfs_log_iovec_t *vecp;
1081 uint nitems;
1082
1083 /*
1084 * Skip over the entry for the transaction header, we'll
1085 * fill that in at the end.
1086 */
1087 vecp = log_vector + 1; /* pointer arithmetic */
1088
1089 nitems = 0;
1090 lidp = xfs_trans_first_item(tp);
1091 ASSERT(lidp != NULL);
1092 while (lidp != NULL) {
1093 /*
1094 * Skip items which aren't dirty in this transaction.
1095 */
1096 if (!(lidp->lid_flags & XFS_LID_DIRTY)) {
1097 lidp = xfs_trans_next_item(tp, lidp);
1098 continue;
1099 }
1100 /*
1101 * The item may be marked dirty but not log anything.
1102 * This can be used to get called when a transaction
1103 * is committed.
1104 */
1105 if (lidp->lid_size) {
1106 nitems++;
1107 }
1108 IOP_FORMAT(lidp->lid_item, vecp);
1109 vecp += lidp->lid_size; /* pointer arithmetic */
1110 IOP_PIN(lidp->lid_item);
1111 lidp = xfs_trans_next_item(tp, lidp);
1112 }
1113
1114 /*
1115 * Now that we've counted the number of items in this
1116 * transaction, fill in the transaction header.
1117 */
1118 tp->t_header.th_magic = XFS_TRANS_HEADER_MAGIC;
1119 tp->t_header.th_type = tp->t_type;
1120 tp->t_header.th_num_items = nitems;
1121 log_vector->i_addr = (xfs_caddr_t)&tp->t_header;
1122 log_vector->i_len = sizeof(xfs_trans_header_t);
1123 log_vector->i_type = XLOG_REG_TYPE_TRANSHDR;
1124}
1125
1126
1127/*
1128 * Unlock all of the transaction's items and free the transaction. 1139 * Unlock all of the transaction's items and free the transaction.
1129 * The transaction must not have modified any of its items, because 1140 * The transaction must not have modified any of its items, because
1130 * there is no way to restore them to their previous state. 1141 * there is no way to restore them to their previous state.