diff options
Diffstat (limited to 'fs/xfs/xfs_trans.c')
-rw-r--r-- | fs/xfs/xfs_trans.c | 810 |
1 files changed, 420 insertions, 390 deletions
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index f73e358bae8d..ce558efa2ea0 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
@@ -44,24 +44,14 @@ | |||
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 | #include "xfs_inode_item.h" |
47 | 47 | #include "xfs_trace.h" | |
48 | |||
49 | STATIC void xfs_trans_apply_sb_deltas(xfs_trans_t *); | ||
50 | STATIC uint xfs_trans_count_vecs(xfs_trans_t *); | ||
51 | STATIC void xfs_trans_fill_vecs(xfs_trans_t *, xfs_log_iovec_t *); | ||
52 | STATIC void xfs_trans_uncommit(xfs_trans_t *, uint); | ||
53 | STATIC void xfs_trans_committed(xfs_trans_t *, int); | ||
54 | STATIC void xfs_trans_chunk_committed(xfs_log_item_chunk_t *, xfs_lsn_t, int); | ||
55 | STATIC void xfs_trans_free(xfs_trans_t *); | ||
56 | 48 | ||
57 | kmem_zone_t *xfs_trans_zone; | 49 | kmem_zone_t *xfs_trans_zone; |
58 | 50 | ||
59 | |||
60 | /* | 51 | /* |
61 | * Reservation functions here avoid a huge stack in xfs_trans_init | 52 | * Reservation functions here avoid a huge stack in xfs_trans_init |
62 | * due to register overflow from temporaries in the calculations. | 53 | * due to register overflow from temporaries in the calculations. |
63 | */ | 54 | */ |
64 | |||
65 | STATIC uint | 55 | STATIC uint |
66 | xfs_calc_write_reservation(xfs_mount_t *mp) | 56 | xfs_calc_write_reservation(xfs_mount_t *mp) |
67 | { | 57 | { |
@@ -254,13 +244,30 @@ _xfs_trans_alloc( | |||
254 | tp->t_type = type; | 244 | tp->t_type = type; |
255 | tp->t_mountp = mp; | 245 | tp->t_mountp = mp; |
256 | tp->t_items_free = XFS_LIC_NUM_SLOTS; | 246 | tp->t_items_free = XFS_LIC_NUM_SLOTS; |
257 | tp->t_busy_free = XFS_LBC_NUM_SLOTS; | ||
258 | xfs_lic_init(&(tp->t_items)); | 247 | xfs_lic_init(&(tp->t_items)); |
259 | XFS_LBC_INIT(&(tp->t_busy)); | 248 | INIT_LIST_HEAD(&tp->t_busy); |
260 | return tp; | 249 | return tp; |
261 | } | 250 | } |
262 | 251 | ||
263 | /* | 252 | /* |
253 | * Free the transaction structure. If there is more clean up | ||
254 | * to do when the structure is freed, add it here. | ||
255 | */ | ||
256 | STATIC void | ||
257 | xfs_trans_free( | ||
258 | struct xfs_trans *tp) | ||
259 | { | ||
260 | struct xfs_busy_extent *busyp, *n; | ||
261 | |||
262 | list_for_each_entry_safe(busyp, n, &tp->t_busy, list) | ||
263 | xfs_alloc_busy_clear(tp->t_mountp, busyp); | ||
264 | |||
265 | atomic_dec(&tp->t_mountp->m_active_trans); | ||
266 | xfs_trans_free_dqinfo(tp); | ||
267 | kmem_zone_free(xfs_trans_zone, tp); | ||
268 | } | ||
269 | |||
270 | /* | ||
264 | * This is called to create a new transaction which will share the | 271 | * This is called to create a new transaction which will share the |
265 | * permanent log reservation of the given transaction. The remaining | 272 | * permanent log reservation of the given transaction. The remaining |
266 | * unused block and rt extent reservations are also inherited. This | 273 | * unused block and rt extent reservations are also inherited. This |
@@ -283,9 +290,8 @@ xfs_trans_dup( | |||
283 | ntp->t_type = tp->t_type; | 290 | ntp->t_type = tp->t_type; |
284 | ntp->t_mountp = tp->t_mountp; | 291 | ntp->t_mountp = tp->t_mountp; |
285 | ntp->t_items_free = XFS_LIC_NUM_SLOTS; | 292 | ntp->t_items_free = XFS_LIC_NUM_SLOTS; |
286 | ntp->t_busy_free = XFS_LBC_NUM_SLOTS; | ||
287 | xfs_lic_init(&(ntp->t_items)); | 293 | xfs_lic_init(&(ntp->t_items)); |
288 | XFS_LBC_INIT(&(ntp->t_busy)); | 294 | INIT_LIST_HEAD(&ntp->t_busy); |
289 | 295 | ||
290 | ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); | 296 | ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); |
291 | ASSERT(tp->t_ticket != NULL); | 297 | ASSERT(tp->t_ticket != NULL); |
@@ -421,7 +427,6 @@ undo_blocks: | |||
421 | return error; | 427 | return error; |
422 | } | 428 | } |
423 | 429 | ||
424 | |||
425 | /* | 430 | /* |
426 | * Record the indicated change to the given field for application | 431 | * Record the indicated change to the given field for application |
427 | * to the file system's superblock when the transaction commits. | 432 | * to the file system's superblock when the transaction commits. |
@@ -650,7 +655,7 @@ xfs_trans_apply_sb_deltas( | |||
650 | * XFS_TRANS_SB_DIRTY will not be set when the transaction is updated but we | 655 | * XFS_TRANS_SB_DIRTY will not be set when the transaction is updated but we |
651 | * still need to update the incore superblock with the changes. | 656 | * still need to update the incore superblock with the changes. |
652 | */ | 657 | */ |
653 | STATIC void | 658 | void |
654 | xfs_trans_unreserve_and_mod_sb( | 659 | xfs_trans_unreserve_and_mod_sb( |
655 | xfs_trans_t *tp) | 660 | xfs_trans_t *tp) |
656 | { | 661 | { |
@@ -764,94 +769,256 @@ xfs_trans_unreserve_and_mod_sb( | |||
764 | } | 769 | } |
765 | } | 770 | } |
766 | 771 | ||
772 | /* | ||
773 | * Total up the number of log iovecs needed to commit this | ||
774 | * transaction. The transaction itself needs one for the | ||
775 | * transaction header. Ask each dirty item in turn how many | ||
776 | * it needs to get the total. | ||
777 | */ | ||
778 | static uint | ||
779 | xfs_trans_count_vecs( | ||
780 | struct xfs_trans *tp) | ||
781 | { | ||
782 | int nvecs; | ||
783 | xfs_log_item_desc_t *lidp; | ||
784 | |||
785 | nvecs = 1; | ||
786 | lidp = xfs_trans_first_item(tp); | ||
787 | ASSERT(lidp != NULL); | ||
788 | |||
789 | /* In the non-debug case we need to start bailing out if we | ||
790 | * didn't find a log_item here, return zero and let trans_commit | ||
791 | * deal with it. | ||
792 | */ | ||
793 | if (lidp == NULL) | ||
794 | return 0; | ||
795 | |||
796 | while (lidp != NULL) { | ||
797 | /* | ||
798 | * Skip items which aren't dirty in this transaction. | ||
799 | */ | ||
800 | if (!(lidp->lid_flags & XFS_LID_DIRTY)) { | ||
801 | lidp = xfs_trans_next_item(tp, lidp); | ||
802 | continue; | ||
803 | } | ||
804 | lidp->lid_size = IOP_SIZE(lidp->lid_item); | ||
805 | nvecs += lidp->lid_size; | ||
806 | lidp = xfs_trans_next_item(tp, lidp); | ||
807 | } | ||
808 | |||
809 | return nvecs; | ||
810 | } | ||
767 | 811 | ||
768 | /* | 812 | /* |
769 | * xfs_trans_commit | 813 | * Fill in the vector with pointers to data to be logged |
814 | * by this transaction. The transaction header takes | ||
815 | * the first vector, and then each dirty item takes the | ||
816 | * number of vectors it indicated it needed in xfs_trans_count_vecs(). | ||
770 | * | 817 | * |
771 | * Commit the given transaction to the log a/synchronously. | 818 | * As each item fills in the entries it needs, also pin the item |
819 | * so that it cannot be flushed out until the log write completes. | ||
820 | */ | ||
821 | static void | ||
822 | xfs_trans_fill_vecs( | ||
823 | struct xfs_trans *tp, | ||
824 | struct xfs_log_iovec *log_vector) | ||
825 | { | ||
826 | xfs_log_item_desc_t *lidp; | ||
827 | struct xfs_log_iovec *vecp; | ||
828 | uint nitems; | ||
829 | |||
830 | /* | ||
831 | * Skip over the entry for the transaction header, we'll | ||
832 | * fill that in at the end. | ||
833 | */ | ||
834 | vecp = log_vector + 1; | ||
835 | |||
836 | nitems = 0; | ||
837 | lidp = xfs_trans_first_item(tp); | ||
838 | ASSERT(lidp); | ||
839 | while (lidp) { | ||
840 | /* Skip items which aren't dirty in this transaction. */ | ||
841 | if (!(lidp->lid_flags & XFS_LID_DIRTY)) { | ||
842 | lidp = xfs_trans_next_item(tp, lidp); | ||
843 | continue; | ||
844 | } | ||
845 | |||
846 | /* | ||
847 | * The item may be marked dirty but not log anything. This can | ||
848 | * be used to get called when a transaction is committed. | ||
849 | */ | ||
850 | if (lidp->lid_size) | ||
851 | nitems++; | ||
852 | IOP_FORMAT(lidp->lid_item, vecp); | ||
853 | vecp += lidp->lid_size; | ||
854 | IOP_PIN(lidp->lid_item); | ||
855 | lidp = xfs_trans_next_item(tp, lidp); | ||
856 | } | ||
857 | |||
858 | /* | ||
859 | * Now that we've counted the number of items in this transaction, fill | ||
860 | * in the transaction header. Note that the transaction header does not | ||
861 | * have a log item. | ||
862 | */ | ||
863 | tp->t_header.th_magic = XFS_TRANS_HEADER_MAGIC; | ||
864 | tp->t_header.th_type = tp->t_type; | ||
865 | tp->t_header.th_num_items = nitems; | ||
866 | log_vector->i_addr = (xfs_caddr_t)&tp->t_header; | ||
867 | log_vector->i_len = sizeof(xfs_trans_header_t); | ||
868 | log_vector->i_type = XLOG_REG_TYPE_TRANSHDR; | ||
869 | } | ||
870 | |||
871 | /* | ||
872 | * The committed item processing consists of calling the committed routine of | ||
873 | * each logged item, updating the item's position in the AIL if necessary, and | ||
874 | * unpinning each item. If the committed routine returns -1, then do nothing | ||
875 | * further with the item because it may have been freed. | ||
772 | * | 876 | * |
773 | * XFS disk error handling mechanism is not based on a typical | 877 | * Since items are unlocked when they are copied to the incore log, it is |
774 | * transaction abort mechanism. Logically after the filesystem | 878 | * possible for two transactions to be completing and manipulating the same |
775 | * gets marked 'SHUTDOWN', we can't let any new transactions | 879 | * item simultaneously. The AIL lock will protect the lsn field of each item. |
776 | * be durable - ie. committed to disk - because some metadata might | 880 | * The value of this field can never go backwards. |
777 | * be inconsistent. In such cases, this returns an error, and the | 881 | * |
778 | * caller may assume that all locked objects joined to the transaction | 882 | * We unpin the items after repositioning them in the AIL, because otherwise |
779 | * have already been unlocked as if the commit had succeeded. | 883 | * they could be immediately flushed and we'd have to race with the flusher |
780 | * Do not reference the transaction structure after this call. | 884 | * trying to pull the item from the AIL as we add it. |
781 | */ | 885 | */ |
782 | /*ARGSUSED*/ | 886 | void |
783 | int | 887 | xfs_trans_item_committed( |
784 | _xfs_trans_commit( | 888 | struct xfs_log_item *lip, |
785 | xfs_trans_t *tp, | 889 | xfs_lsn_t commit_lsn, |
786 | uint flags, | 890 | int aborted) |
787 | int *log_flushed) | ||
788 | { | 891 | { |
789 | xfs_log_iovec_t *log_vector; | 892 | xfs_lsn_t item_lsn; |
790 | int nvec; | 893 | struct xfs_ail *ailp; |
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 | 894 | ||
802 | commit_lsn = -1; | 895 | if (aborted) |
896 | lip->li_flags |= XFS_LI_ABORTED; | ||
897 | item_lsn = IOP_COMMITTED(lip, commit_lsn); | ||
898 | |||
899 | /* If the committed routine returns -1, item has been freed. */ | ||
900 | if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) | ||
901 | return; | ||
803 | 902 | ||
804 | /* | 903 | /* |
805 | * Determine whether this commit is releasing a permanent | 904 | * If the returned lsn is greater than what it contained before, update |
806 | * log reservation or not. | 905 | * the location of the item in the AIL. If it is not, then do nothing. |
906 | * Items can never move backwards in the AIL. | ||
907 | * | ||
908 | * While the new lsn should usually be greater, it is possible that a | ||
909 | * later transaction completing simultaneously with an earlier one | ||
910 | * using the same item could complete first with a higher lsn. This | ||
911 | * would cause the earlier transaction to fail the test below. | ||
807 | */ | 912 | */ |
808 | if (flags & XFS_TRANS_RELEASE_LOG_RES) { | 913 | ailp = lip->li_ailp; |
809 | ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); | 914 | spin_lock(&ailp->xa_lock); |
810 | log_flags = XFS_LOG_REL_PERM_RESERV; | 915 | if (XFS_LSN_CMP(item_lsn, lip->li_lsn) > 0) { |
916 | /* | ||
917 | * This will set the item's lsn to item_lsn and update the | ||
918 | * position of the item in the AIL. | ||
919 | * | ||
920 | * xfs_trans_ail_update() drops the AIL lock. | ||
921 | */ | ||
922 | xfs_trans_ail_update(ailp, lip, item_lsn); | ||
811 | } else { | 923 | } else { |
812 | log_flags = 0; | 924 | spin_unlock(&ailp->xa_lock); |
813 | } | 925 | } |
814 | mp = tp->t_mountp; | ||
815 | 926 | ||
816 | /* | 927 | /* |
817 | * If there is nothing to be logged by the transaction, | 928 | * Now that we've repositioned the item in the AIL, unpin it so it can |
818 | * then unlock all of the items associated with the | 929 | * be flushed. Pass information about buffer stale state down from the |
819 | * transaction and free the transaction structure. | 930 | * log item flags, if anyone else stales the buffer we do not want to |
820 | * Also make sure to return any reserved blocks to | 931 | * pay any attention to it. |
821 | * the free pool. | ||
822 | */ | 932 | */ |
823 | shut_us_down: | 933 | IOP_UNPIN(lip); |
824 | shutdown = XFS_FORCED_SHUTDOWN(mp) ? EIO : 0; | 934 | } |
825 | if (!(tp->t_flags & XFS_TRANS_DIRTY) || shutdown) { | 935 | |
826 | xfs_trans_unreserve_and_mod_sb(tp); | 936 | /* |
937 | * This is typically called by the LM when a transaction has been fully | ||
938 | * committed to disk. It needs to unpin the items which have | ||
939 | * been logged by the transaction and update their positions | ||
940 | * in the AIL if necessary. | ||
941 | * | ||
942 | * This also gets called when the transactions didn't get written out | ||
943 | * because of an I/O error. Abortflag & XFS_LI_ABORTED is set then. | ||
944 | */ | ||
945 | STATIC void | ||
946 | xfs_trans_committed( | ||
947 | struct xfs_trans *tp, | ||
948 | int abortflag) | ||
949 | { | ||
950 | xfs_log_item_desc_t *lidp; | ||
951 | xfs_log_item_chunk_t *licp; | ||
952 | xfs_log_item_chunk_t *next_licp; | ||
953 | |||
954 | /* Call the transaction's completion callback if there is one. */ | ||
955 | if (tp->t_callback != NULL) | ||
956 | tp->t_callback(tp, tp->t_callarg); | ||
957 | |||
958 | for (lidp = xfs_trans_first_item(tp); | ||
959 | lidp != NULL; | ||
960 | lidp = xfs_trans_next_item(tp, lidp)) { | ||
961 | xfs_trans_item_committed(lidp->lid_item, tp->t_lsn, abortflag); | ||
962 | } | ||
963 | |||
964 | /* free the item chunks, ignoring the embedded chunk */ | ||
965 | for (licp = tp->t_items.lic_next; licp != NULL; licp = next_licp) { | ||
966 | next_licp = licp->lic_next; | ||
967 | kmem_free(licp); | ||
968 | } | ||
969 | |||
970 | xfs_trans_free(tp); | ||
971 | } | ||
972 | |||
973 | /* | ||
974 | * Called from the trans_commit code when we notice that | ||
975 | * the filesystem is in the middle of a forced shutdown. | ||
976 | */ | ||
977 | STATIC void | ||
978 | xfs_trans_uncommit( | ||
979 | struct xfs_trans *tp, | ||
980 | uint flags) | ||
981 | { | ||
982 | xfs_log_item_desc_t *lidp; | ||
983 | |||
984 | for (lidp = xfs_trans_first_item(tp); | ||
985 | lidp != NULL; | ||
986 | lidp = xfs_trans_next_item(tp, lidp)) { | ||
827 | /* | 987 | /* |
828 | * It is indeed possible for the transaction to be | 988 | * Unpin all but those that aren't dirty. |
829 | * not dirty but the dqinfo portion to be. All that | ||
830 | * means is that we have some (non-persistent) quota | ||
831 | * reservations that need to be unreserved. | ||
832 | */ | 989 | */ |
833 | xfs_trans_unreserve_and_mod_dquots(tp); | 990 | if (lidp->lid_flags & XFS_LID_DIRTY) |
834 | if (tp->t_ticket) { | 991 | IOP_UNPIN_REMOVE(lidp->lid_item, tp); |
835 | commit_lsn = xfs_log_done(mp, tp->t_ticket, | ||
836 | NULL, log_flags); | ||
837 | if (commit_lsn == -1 && !shutdown) | ||
838 | shutdown = XFS_ERROR(EIO); | ||
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 | } | 992 | } |
847 | ASSERT(tp->t_ticket != NULL); | ||
848 | 993 | ||
849 | /* | 994 | xfs_trans_unreserve_and_mod_sb(tp); |
850 | * If we need to update the superblock, then do it now. | 995 | xfs_trans_unreserve_and_mod_dquots(tp); |
851 | */ | 996 | |
852 | if (tp->t_flags & XFS_TRANS_SB_DIRTY) | 997 | xfs_trans_free_items(tp, NULLCOMMITLSN, flags); |
853 | xfs_trans_apply_sb_deltas(tp); | 998 | xfs_trans_free(tp); |
854 | xfs_trans_apply_dquot_deltas(tp); | 999 | } |
1000 | |||
1001 | /* | ||
1002 | * Format the transaction direct to the iclog. This isolates the physical | ||
1003 | * transaction commit operation from the logical operation and hence allows | ||
1004 | * other methods to be introduced without affecting the existing commit path. | ||
1005 | */ | ||
1006 | static int | ||
1007 | xfs_trans_commit_iclog( | ||
1008 | struct xfs_mount *mp, | ||
1009 | struct xfs_trans *tp, | ||
1010 | xfs_lsn_t *commit_lsn, | ||
1011 | int flags) | ||
1012 | { | ||
1013 | int shutdown; | ||
1014 | int error; | ||
1015 | int log_flags = 0; | ||
1016 | struct xlog_in_core *commit_iclog; | ||
1017 | #define XFS_TRANS_LOGVEC_COUNT 16 | ||
1018 | struct xfs_log_iovec log_vector_fast[XFS_TRANS_LOGVEC_COUNT]; | ||
1019 | struct xfs_log_iovec *log_vector; | ||
1020 | uint nvec; | ||
1021 | |||
855 | 1022 | ||
856 | /* | 1023 | /* |
857 | * Ask each log item how many log_vector entries it will | 1024 | * Ask each log item how many log_vector entries it will |
@@ -861,8 +1028,7 @@ shut_us_down: | |||
861 | */ | 1028 | */ |
862 | nvec = xfs_trans_count_vecs(tp); | 1029 | nvec = xfs_trans_count_vecs(tp); |
863 | if (nvec == 0) { | 1030 | if (nvec == 0) { |
864 | xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR); | 1031 | return ENOMEM; /* triggers a shutdown! */ |
865 | goto shut_us_down; | ||
866 | } else if (nvec <= XFS_TRANS_LOGVEC_COUNT) { | 1032 | } else if (nvec <= XFS_TRANS_LOGVEC_COUNT) { |
867 | log_vector = log_vector_fast; | 1033 | log_vector = log_vector_fast; |
868 | } else { | 1034 | } else { |
@@ -877,6 +1043,9 @@ shut_us_down: | |||
877 | */ | 1043 | */ |
878 | xfs_trans_fill_vecs(tp, log_vector); | 1044 | xfs_trans_fill_vecs(tp, log_vector); |
879 | 1045 | ||
1046 | if (flags & XFS_TRANS_RELEASE_LOG_RES) | ||
1047 | log_flags = XFS_LOG_REL_PERM_RESERV; | ||
1048 | |||
880 | error = xfs_log_write(mp, log_vector, nvec, tp->t_ticket, &(tp->t_lsn)); | 1049 | error = xfs_log_write(mp, log_vector, nvec, tp->t_ticket, &(tp->t_lsn)); |
881 | 1050 | ||
882 | /* | 1051 | /* |
@@ -884,18 +1053,19 @@ shut_us_down: | |||
884 | * at any time after this call. However, all the items associated | 1053 | * at any time after this call. However, all the items associated |
885 | * with the transaction are still locked and pinned in memory. | 1054 | * with the transaction are still locked and pinned in memory. |
886 | */ | 1055 | */ |
887 | commit_lsn = xfs_log_done(mp, tp->t_ticket, &commit_iclog, log_flags); | 1056 | *commit_lsn = xfs_log_done(mp, tp->t_ticket, &commit_iclog, log_flags); |
888 | 1057 | ||
889 | tp->t_commit_lsn = commit_lsn; | 1058 | tp->t_commit_lsn = *commit_lsn; |
890 | if (nvec > XFS_TRANS_LOGVEC_COUNT) { | 1059 | trace_xfs_trans_commit_lsn(tp); |
1060 | |||
1061 | if (nvec > XFS_TRANS_LOGVEC_COUNT) | ||
891 | kmem_free(log_vector); | 1062 | kmem_free(log_vector); |
892 | } | ||
893 | 1063 | ||
894 | /* | 1064 | /* |
895 | * If we got a log write error. Unpin the logitems that we | 1065 | * If we got a log write error. Unpin the logitems that we |
896 | * had pinned, clean up, free trans structure, and return error. | 1066 | * had pinned, clean up, free trans structure, and return error. |
897 | */ | 1067 | */ |
898 | if (error || commit_lsn == -1) { | 1068 | if (error || *commit_lsn == -1) { |
899 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); | 1069 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); |
900 | xfs_trans_uncommit(tp, flags|XFS_TRANS_ABORT); | 1070 | xfs_trans_uncommit(tp, flags|XFS_TRANS_ABORT); |
901 | return XFS_ERROR(EIO); | 1071 | return XFS_ERROR(EIO); |
@@ -909,8 +1079,6 @@ shut_us_down: | |||
909 | */ | 1079 | */ |
910 | xfs_trans_unreserve_and_mod_sb(tp); | 1080 | xfs_trans_unreserve_and_mod_sb(tp); |
911 | 1081 | ||
912 | sync = tp->t_flags & XFS_TRANS_SYNC; | ||
913 | |||
914 | /* | 1082 | /* |
915 | * Tell the LM to call the transaction completion routine | 1083 | * Tell the LM to call the transaction completion routine |
916 | * when the log write with LSN commit_lsn completes (e.g. | 1084 | * when the log write with LSN commit_lsn completes (e.g. |
@@ -953,7 +1121,7 @@ shut_us_down: | |||
953 | * the commit lsn of this transaction for dependency tracking | 1121 | * the commit lsn of this transaction for dependency tracking |
954 | * purposes. | 1122 | * purposes. |
955 | */ | 1123 | */ |
956 | xfs_trans_unlock_items(tp, commit_lsn); | 1124 | xfs_trans_unlock_items(tp, *commit_lsn); |
957 | 1125 | ||
958 | /* | 1126 | /* |
959 | * If we detected a log error earlier, finish committing | 1127 | * If we detected a log error earlier, finish committing |
@@ -973,156 +1141,204 @@ shut_us_down: | |||
973 | * and the items are released we can finally allow the iclog to | 1141 | * and the items are released we can finally allow the iclog to |
974 | * go to disk. | 1142 | * go to disk. |
975 | */ | 1143 | */ |
976 | error = xfs_log_release_iclog(mp, commit_iclog); | 1144 | return xfs_log_release_iclog(mp, commit_iclog); |
977 | |||
978 | /* | ||
979 | * If the transaction needs to be synchronous, then force the | ||
980 | * log out now and wait for it. | ||
981 | */ | ||
982 | if (sync) { | ||
983 | if (!error) { | ||
984 | error = _xfs_log_force_lsn(mp, commit_lsn, | ||
985 | XFS_LOG_SYNC, log_flushed); | ||
986 | } | ||
987 | XFS_STATS_INC(xs_trans_sync); | ||
988 | } else { | ||
989 | XFS_STATS_INC(xs_trans_async); | ||
990 | } | ||
991 | |||
992 | return (error); | ||
993 | } | 1145 | } |
994 | 1146 | ||
995 | |||
996 | /* | 1147 | /* |
997 | * Total up the number of log iovecs needed to commit this | 1148 | * Walk the log items and allocate log vector structures for |
998 | * transaction. The transaction itself needs one for the | 1149 | * each item large enough to fit all the vectors they require. |
999 | * transaction header. Ask each dirty item in turn how many | 1150 | * Note that this format differs from the old log vector format in |
1000 | * it needs to get the total. | 1151 | * that there is no transaction header in these log vectors. |
1001 | */ | 1152 | */ |
1002 | STATIC uint | 1153 | STATIC struct xfs_log_vec * |
1003 | xfs_trans_count_vecs( | 1154 | xfs_trans_alloc_log_vecs( |
1004 | xfs_trans_t *tp) | 1155 | xfs_trans_t *tp) |
1005 | { | 1156 | { |
1006 | int nvecs; | ||
1007 | xfs_log_item_desc_t *lidp; | 1157 | xfs_log_item_desc_t *lidp; |
1158 | struct xfs_log_vec *lv = NULL; | ||
1159 | struct xfs_log_vec *ret_lv = NULL; | ||
1008 | 1160 | ||
1009 | nvecs = 1; | ||
1010 | lidp = xfs_trans_first_item(tp); | 1161 | lidp = xfs_trans_first_item(tp); |
1011 | ASSERT(lidp != NULL); | ||
1012 | 1162 | ||
1013 | /* In the non-debug case we need to start bailing out if we | 1163 | /* Bail out if we didn't find a log item. */ |
1014 | * didn't find a log_item here, return zero and let trans_commit | 1164 | if (!lidp) { |
1015 | * deal with it. | 1165 | ASSERT(0); |
1016 | */ | 1166 | return NULL; |
1017 | if (lidp == NULL) | 1167 | } |
1018 | return 0; | ||
1019 | 1168 | ||
1020 | while (lidp != NULL) { | 1169 | while (lidp != NULL) { |
1021 | /* | 1170 | struct xfs_log_vec *new_lv; |
1022 | * Skip items which aren't dirty in this transaction. | 1171 | |
1023 | */ | 1172 | /* Skip items which aren't dirty in this transaction. */ |
1024 | if (!(lidp->lid_flags & XFS_LID_DIRTY)) { | 1173 | if (!(lidp->lid_flags & XFS_LID_DIRTY)) { |
1025 | lidp = xfs_trans_next_item(tp, lidp); | 1174 | lidp = xfs_trans_next_item(tp, lidp); |
1026 | continue; | 1175 | continue; |
1027 | } | 1176 | } |
1177 | |||
1178 | /* Skip items that do not have any vectors for writing */ | ||
1028 | lidp->lid_size = IOP_SIZE(lidp->lid_item); | 1179 | lidp->lid_size = IOP_SIZE(lidp->lid_item); |
1029 | nvecs += lidp->lid_size; | 1180 | if (!lidp->lid_size) { |
1181 | lidp = xfs_trans_next_item(tp, lidp); | ||
1182 | continue; | ||
1183 | } | ||
1184 | |||
1185 | new_lv = kmem_zalloc(sizeof(*new_lv) + | ||
1186 | lidp->lid_size * sizeof(struct xfs_log_iovec), | ||
1187 | KM_SLEEP); | ||
1188 | |||
1189 | /* The allocated iovec region lies beyond the log vector. */ | ||
1190 | new_lv->lv_iovecp = (struct xfs_log_iovec *)&new_lv[1]; | ||
1191 | new_lv->lv_niovecs = lidp->lid_size; | ||
1192 | new_lv->lv_item = lidp->lid_item; | ||
1193 | if (!ret_lv) | ||
1194 | ret_lv = new_lv; | ||
1195 | else | ||
1196 | lv->lv_next = new_lv; | ||
1197 | lv = new_lv; | ||
1030 | lidp = xfs_trans_next_item(tp, lidp); | 1198 | lidp = xfs_trans_next_item(tp, lidp); |
1031 | } | 1199 | } |
1032 | 1200 | ||
1033 | return nvecs; | 1201 | return ret_lv; |
1034 | } | 1202 | } |
1035 | 1203 | ||
1036 | /* | 1204 | static int |
1037 | * Called from the trans_commit code when we notice that | 1205 | xfs_trans_commit_cil( |
1038 | * the filesystem is in the middle of a forced shutdown. | 1206 | struct xfs_mount *mp, |
1039 | */ | 1207 | struct xfs_trans *tp, |
1040 | STATIC void | 1208 | xfs_lsn_t *commit_lsn, |
1041 | xfs_trans_uncommit( | 1209 | int flags) |
1042 | xfs_trans_t *tp, | ||
1043 | uint flags) | ||
1044 | { | 1210 | { |
1045 | xfs_log_item_desc_t *lidp; | 1211 | struct xfs_log_vec *log_vector; |
1212 | int error; | ||
1046 | 1213 | ||
1047 | for (lidp = xfs_trans_first_item(tp); | 1214 | /* |
1048 | lidp != NULL; | 1215 | * Get each log item to allocate a vector structure for |
1049 | lidp = xfs_trans_next_item(tp, lidp)) { | 1216 | * the log item to to pass to the log write code. The |
1050 | /* | 1217 | * CIL commit code will format the vector and save it away. |
1051 | * Unpin all but those that aren't dirty. | 1218 | */ |
1052 | */ | 1219 | log_vector = xfs_trans_alloc_log_vecs(tp); |
1053 | if (lidp->lid_flags & XFS_LID_DIRTY) | 1220 | if (!log_vector) |
1054 | IOP_UNPIN_REMOVE(lidp->lid_item, tp); | 1221 | return ENOMEM; |
1055 | } | ||
1056 | 1222 | ||
1057 | xfs_trans_unreserve_and_mod_sb(tp); | 1223 | error = xfs_log_commit_cil(mp, tp, log_vector, commit_lsn, flags); |
1058 | xfs_trans_unreserve_and_mod_dquots(tp); | 1224 | if (error) |
1225 | return error; | ||
1059 | 1226 | ||
1060 | xfs_trans_free_items(tp, flags); | 1227 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); |
1061 | xfs_trans_free_busy(tp); | 1228 | |
1229 | /* xfs_trans_free_items() unlocks them first */ | ||
1230 | xfs_trans_free_items(tp, *commit_lsn, 0); | ||
1062 | xfs_trans_free(tp); | 1231 | xfs_trans_free(tp); |
1232 | return 0; | ||
1063 | } | 1233 | } |
1064 | 1234 | ||
1065 | /* | 1235 | /* |
1066 | * Fill in the vector with pointers to data to be logged | 1236 | * xfs_trans_commit |
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 | * | 1237 | * |
1071 | * As each item fills in the entries it needs, also pin the item | 1238 | * Commit the given transaction to the log a/synchronously. |
1072 | * so that it cannot be flushed out until the log write completes. | 1239 | * |
1240 | * XFS disk error handling mechanism is not based on a typical | ||
1241 | * transaction abort mechanism. Logically after the filesystem | ||
1242 | * gets marked 'SHUTDOWN', we can't let any new transactions | ||
1243 | * be durable - ie. committed to disk - because some metadata might | ||
1244 | * be inconsistent. In such cases, this returns an error, and the | ||
1245 | * caller may assume that all locked objects joined to the transaction | ||
1246 | * have already been unlocked as if the commit had succeeded. | ||
1247 | * Do not reference the transaction structure after this call. | ||
1073 | */ | 1248 | */ |
1074 | STATIC void | 1249 | int |
1075 | xfs_trans_fill_vecs( | 1250 | _xfs_trans_commit( |
1076 | xfs_trans_t *tp, | 1251 | struct xfs_trans *tp, |
1077 | xfs_log_iovec_t *log_vector) | 1252 | uint flags, |
1253 | int *log_flushed) | ||
1078 | { | 1254 | { |
1079 | xfs_log_item_desc_t *lidp; | 1255 | struct xfs_mount *mp = tp->t_mountp; |
1080 | xfs_log_iovec_t *vecp; | 1256 | xfs_lsn_t commit_lsn = -1; |
1081 | uint nitems; | 1257 | int error = 0; |
1258 | int log_flags = 0; | ||
1259 | int sync = tp->t_flags & XFS_TRANS_SYNC; | ||
1082 | 1260 | ||
1083 | /* | 1261 | /* |
1084 | * Skip over the entry for the transaction header, we'll | 1262 | * Determine whether this commit is releasing a permanent |
1085 | * fill that in at the end. | 1263 | * log reservation or not. |
1086 | */ | 1264 | */ |
1087 | vecp = log_vector + 1; /* pointer arithmetic */ | 1265 | if (flags & XFS_TRANS_RELEASE_LOG_RES) { |
1266 | ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); | ||
1267 | log_flags = XFS_LOG_REL_PERM_RESERV; | ||
1268 | } | ||
1088 | 1269 | ||
1089 | nitems = 0; | 1270 | /* |
1090 | lidp = xfs_trans_first_item(tp); | 1271 | * If there is nothing to be logged by the transaction, |
1091 | ASSERT(lidp != NULL); | 1272 | * then unlock all of the items associated with the |
1092 | while (lidp != NULL) { | 1273 | * transaction and free the transaction structure. |
1093 | /* | 1274 | * Also make sure to return any reserved blocks to |
1094 | * Skip items which aren't dirty in this transaction. | 1275 | * the free pool. |
1095 | */ | 1276 | */ |
1096 | if (!(lidp->lid_flags & XFS_LID_DIRTY)) { | 1277 | if (!(tp->t_flags & XFS_TRANS_DIRTY)) |
1097 | lidp = xfs_trans_next_item(tp, lidp); | 1278 | goto out_unreserve; |
1098 | continue; | 1279 | |
1099 | } | 1280 | if (XFS_FORCED_SHUTDOWN(mp)) { |
1100 | /* | 1281 | error = XFS_ERROR(EIO); |
1101 | * The item may be marked dirty but not log anything. | 1282 | goto out_unreserve; |
1102 | * This can be used to get called when a transaction | 1283 | } |
1103 | * is committed. | 1284 | |
1104 | */ | 1285 | ASSERT(tp->t_ticket != NULL); |
1105 | if (lidp->lid_size) { | 1286 | |
1106 | nitems++; | 1287 | /* |
1288 | * If we need to update the superblock, then do it now. | ||
1289 | */ | ||
1290 | if (tp->t_flags & XFS_TRANS_SB_DIRTY) | ||
1291 | xfs_trans_apply_sb_deltas(tp); | ||
1292 | xfs_trans_apply_dquot_deltas(tp); | ||
1293 | |||
1294 | if (mp->m_flags & XFS_MOUNT_DELAYLOG) | ||
1295 | error = xfs_trans_commit_cil(mp, tp, &commit_lsn, flags); | ||
1296 | else | ||
1297 | error = xfs_trans_commit_iclog(mp, tp, &commit_lsn, flags); | ||
1298 | |||
1299 | if (error == ENOMEM) { | ||
1300 | xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR); | ||
1301 | error = XFS_ERROR(EIO); | ||
1302 | goto out_unreserve; | ||
1303 | } | ||
1304 | |||
1305 | /* | ||
1306 | * If the transaction needs to be synchronous, then force the | ||
1307 | * log out now and wait for it. | ||
1308 | */ | ||
1309 | if (sync) { | ||
1310 | if (!error) { | ||
1311 | error = _xfs_log_force_lsn(mp, commit_lsn, | ||
1312 | XFS_LOG_SYNC, log_flushed); | ||
1107 | } | 1313 | } |
1108 | IOP_FORMAT(lidp->lid_item, vecp); | 1314 | XFS_STATS_INC(xs_trans_sync); |
1109 | vecp += lidp->lid_size; /* pointer arithmetic */ | 1315 | } else { |
1110 | IOP_PIN(lidp->lid_item); | 1316 | XFS_STATS_INC(xs_trans_async); |
1111 | lidp = xfs_trans_next_item(tp, lidp); | ||
1112 | } | 1317 | } |
1113 | 1318 | ||
1319 | return error; | ||
1320 | |||
1321 | out_unreserve: | ||
1322 | xfs_trans_unreserve_and_mod_sb(tp); | ||
1323 | |||
1114 | /* | 1324 | /* |
1115 | * Now that we've counted the number of items in this | 1325 | * It is indeed possible for the transaction to be not dirty but |
1116 | * transaction, fill in the transaction header. | 1326 | * the dqinfo portion to be. All that means is that we have some |
1327 | * (non-persistent) quota reservations that need to be unreserved. | ||
1117 | */ | 1328 | */ |
1118 | tp->t_header.th_magic = XFS_TRANS_HEADER_MAGIC; | 1329 | xfs_trans_unreserve_and_mod_dquots(tp); |
1119 | tp->t_header.th_type = tp->t_type; | 1330 | if (tp->t_ticket) { |
1120 | tp->t_header.th_num_items = nitems; | 1331 | commit_lsn = xfs_log_done(mp, tp->t_ticket, NULL, log_flags); |
1121 | log_vector->i_addr = (xfs_caddr_t)&tp->t_header; | 1332 | if (commit_lsn == -1 && !error) |
1122 | log_vector->i_len = sizeof(xfs_trans_header_t); | 1333 | error = XFS_ERROR(EIO); |
1123 | log_vector->i_type = XLOG_REG_TYPE_TRANSHDR; | 1334 | } |
1124 | } | 1335 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); |
1336 | xfs_trans_free_items(tp, NULLCOMMITLSN, error ? XFS_TRANS_ABORT : 0); | ||
1337 | xfs_trans_free(tp); | ||
1125 | 1338 | ||
1339 | XFS_STATS_INC(xs_trans_empty); | ||
1340 | return error; | ||
1341 | } | ||
1126 | 1342 | ||
1127 | /* | 1343 | /* |
1128 | * Unlock all of the transaction's items and free the transaction. | 1344 | * Unlock all of the transaction's items and free the transaction. |
@@ -1195,25 +1411,10 @@ xfs_trans_cancel( | |||
1195 | /* mark this thread as no longer being in a transaction */ | 1411 | /* mark this thread as no longer being in a transaction */ |
1196 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); | 1412 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); |
1197 | 1413 | ||
1198 | xfs_trans_free_items(tp, flags); | 1414 | xfs_trans_free_items(tp, NULLCOMMITLSN, flags); |
1199 | xfs_trans_free_busy(tp); | ||
1200 | xfs_trans_free(tp); | 1415 | xfs_trans_free(tp); |
1201 | } | 1416 | } |
1202 | 1417 | ||
1203 | |||
1204 | /* | ||
1205 | * Free the transaction structure. If there is more clean up | ||
1206 | * to do when the structure is freed, add it here. | ||
1207 | */ | ||
1208 | STATIC void | ||
1209 | xfs_trans_free( | ||
1210 | xfs_trans_t *tp) | ||
1211 | { | ||
1212 | atomic_dec(&tp->t_mountp->m_active_trans); | ||
1213 | xfs_trans_free_dqinfo(tp); | ||
1214 | kmem_zone_free(xfs_trans_zone, tp); | ||
1215 | } | ||
1216 | |||
1217 | /* | 1418 | /* |
1218 | * Roll from one trans in the sequence of PERMANENT transactions to | 1419 | * Roll from one trans in the sequence of PERMANENT transactions to |
1219 | * the next: permanent transactions are only flushed out when | 1420 | * the next: permanent transactions are only flushed out when |
@@ -1283,174 +1484,3 @@ xfs_trans_roll( | |||
1283 | xfs_trans_ihold(trans, dp); | 1484 | xfs_trans_ihold(trans, dp); |
1284 | return 0; | 1485 | return 0; |
1285 | } | 1486 | } |
1286 | |||
1287 | /* | ||
1288 | * THIS SHOULD BE REWRITTEN TO USE xfs_trans_next_item(). | ||
1289 | * | ||
1290 | * This is typically called by the LM when a transaction has been fully | ||
1291 | * committed to disk. It needs to unpin the items which have | ||
1292 | * been logged by the transaction and update their positions | ||
1293 | * in the AIL if necessary. | ||
1294 | * This also gets called when the transactions didn't get written out | ||
1295 | * because of an I/O error. Abortflag & XFS_LI_ABORTED is set then. | ||
1296 | * | ||
1297 | * Call xfs_trans_chunk_committed() to process the items in | ||
1298 | * each chunk. | ||
1299 | */ | ||
1300 | STATIC void | ||
1301 | xfs_trans_committed( | ||
1302 | xfs_trans_t *tp, | ||
1303 | int abortflag) | ||
1304 | { | ||
1305 | xfs_log_item_chunk_t *licp; | ||
1306 | xfs_log_item_chunk_t *next_licp; | ||
1307 | xfs_log_busy_chunk_t *lbcp; | ||
1308 | xfs_log_busy_slot_t *lbsp; | ||
1309 | int i; | ||
1310 | |||
1311 | /* | ||
1312 | * Call the transaction's completion callback if there | ||
1313 | * is one. | ||
1314 | */ | ||
1315 | if (tp->t_callback != NULL) { | ||
1316 | tp->t_callback(tp, tp->t_callarg); | ||
1317 | } | ||
1318 | |||
1319 | /* | ||
1320 | * Special case the chunk embedded in the transaction. | ||
1321 | */ | ||
1322 | licp = &(tp->t_items); | ||
1323 | if (!(xfs_lic_are_all_free(licp))) { | ||
1324 | xfs_trans_chunk_committed(licp, tp->t_lsn, abortflag); | ||
1325 | } | ||
1326 | |||
1327 | /* | ||
1328 | * Process the items in each chunk in turn. | ||
1329 | */ | ||
1330 | licp = licp->lic_next; | ||
1331 | while (licp != NULL) { | ||
1332 | ASSERT(!xfs_lic_are_all_free(licp)); | ||
1333 | xfs_trans_chunk_committed(licp, tp->t_lsn, abortflag); | ||
1334 | next_licp = licp->lic_next; | ||
1335 | kmem_free(licp); | ||
1336 | licp = next_licp; | ||
1337 | } | ||
1338 | |||
1339 | /* | ||
1340 | * Clear all the per-AG busy list items listed in this transaction | ||
1341 | */ | ||
1342 | lbcp = &tp->t_busy; | ||
1343 | while (lbcp != NULL) { | ||
1344 | for (i = 0, lbsp = lbcp->lbc_busy; i < lbcp->lbc_unused; i++, lbsp++) { | ||
1345 | if (!XFS_LBC_ISFREE(lbcp, i)) { | ||
1346 | xfs_alloc_clear_busy(tp, lbsp->lbc_ag, | ||
1347 | lbsp->lbc_idx); | ||
1348 | } | ||
1349 | } | ||
1350 | lbcp = lbcp->lbc_next; | ||
1351 | } | ||
1352 | xfs_trans_free_busy(tp); | ||
1353 | |||
1354 | /* | ||
1355 | * That's it for the transaction structure. Free it. | ||
1356 | */ | ||
1357 | xfs_trans_free(tp); | ||
1358 | } | ||
1359 | |||
1360 | /* | ||
1361 | * This is called to perform the commit processing for each | ||
1362 | * item described by the given chunk. | ||
1363 | * | ||
1364 | * The commit processing consists of unlocking items which were | ||
1365 | * held locked with the SYNC_UNLOCK attribute, calling the committed | ||
1366 | * routine of each logged item, updating the item's position in the AIL | ||
1367 | * if necessary, and unpinning each item. If the committed routine | ||
1368 | * returns -1, then do nothing further with the item because it | ||
1369 | * may have been freed. | ||
1370 | * | ||
1371 | * Since items are unlocked when they are copied to the incore | ||
1372 | * log, it is possible for two transactions to be completing | ||
1373 | * and manipulating the same item simultaneously. The AIL lock | ||
1374 | * will protect the lsn field of each item. The value of this | ||
1375 | * field can never go backwards. | ||
1376 | * | ||
1377 | * We unpin the items after repositioning them in the AIL, because | ||
1378 | * otherwise they could be immediately flushed and we'd have to race | ||
1379 | * with the flusher trying to pull the item from the AIL as we add it. | ||
1380 | */ | ||
1381 | STATIC void | ||
1382 | xfs_trans_chunk_committed( | ||
1383 | xfs_log_item_chunk_t *licp, | ||
1384 | xfs_lsn_t lsn, | ||
1385 | int aborted) | ||
1386 | { | ||
1387 | xfs_log_item_desc_t *lidp; | ||
1388 | xfs_log_item_t *lip; | ||
1389 | xfs_lsn_t item_lsn; | ||
1390 | int i; | ||
1391 | |||
1392 | lidp = licp->lic_descs; | ||
1393 | for (i = 0; i < licp->lic_unused; i++, lidp++) { | ||
1394 | struct xfs_ail *ailp; | ||
1395 | |||
1396 | if (xfs_lic_isfree(licp, i)) { | ||
1397 | continue; | ||
1398 | } | ||
1399 | |||
1400 | lip = lidp->lid_item; | ||
1401 | if (aborted) | ||
1402 | lip->li_flags |= XFS_LI_ABORTED; | ||
1403 | |||
1404 | /* | ||
1405 | * Send in the ABORTED flag to the COMMITTED routine | ||
1406 | * so that it knows whether the transaction was aborted | ||
1407 | * or not. | ||
1408 | */ | ||
1409 | item_lsn = IOP_COMMITTED(lip, lsn); | ||
1410 | |||
1411 | /* | ||
1412 | * If the committed routine returns -1, make | ||
1413 | * no more references to the item. | ||
1414 | */ | ||
1415 | if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) { | ||
1416 | continue; | ||
1417 | } | ||
1418 | |||
1419 | /* | ||
1420 | * If the returned lsn is greater than what it | ||
1421 | * contained before, update the location of the | ||
1422 | * item in the AIL. If it is not, then do nothing. | ||
1423 | * Items can never move backwards in the AIL. | ||
1424 | * | ||
1425 | * While the new lsn should usually be greater, it | ||
1426 | * is possible that a later transaction completing | ||
1427 | * simultaneously with an earlier one using the | ||
1428 | * same item could complete first with a higher lsn. | ||
1429 | * This would cause the earlier transaction to fail | ||
1430 | * the test below. | ||
1431 | */ | ||
1432 | ailp = lip->li_ailp; | ||
1433 | spin_lock(&ailp->xa_lock); | ||
1434 | if (XFS_LSN_CMP(item_lsn, lip->li_lsn) > 0) { | ||
1435 | /* | ||
1436 | * This will set the item's lsn to item_lsn | ||
1437 | * and update the position of the item in | ||
1438 | * the AIL. | ||
1439 | * | ||
1440 | * xfs_trans_ail_update() drops the AIL lock. | ||
1441 | */ | ||
1442 | xfs_trans_ail_update(ailp, lip, item_lsn); | ||
1443 | } else { | ||
1444 | spin_unlock(&ailp->xa_lock); | ||
1445 | } | ||
1446 | |||
1447 | /* | ||
1448 | * Now that we've repositioned the item in the AIL, | ||
1449 | * unpin it so it can be flushed. Pass information | ||
1450 | * about buffer stale state down from the log item | ||
1451 | * flags, if anyone else stales the buffer we do not | ||
1452 | * want to pay any attention to it. | ||
1453 | */ | ||
1454 | IOP_UNPIN(lip, lidp->lid_flags & XFS_LID_BUF_STALE); | ||
1455 | } | ||
1456 | } | ||