aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jfs/jfs_txnmgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jfs/jfs_txnmgr.c')
-rw-r--r--fs/jfs/jfs_txnmgr.c89
1 files changed, 40 insertions, 49 deletions
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index 98e16d93e146..bbc9c1407b55 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -227,6 +227,7 @@ static lid_t txLockAlloc(void)
227 227
228static void txLockFree(lid_t lid) 228static void txLockFree(lid_t lid)
229{ 229{
230 TxLock[lid].tid = 0;
230 TxLock[lid].next = TxAnchor.freelock; 231 TxLock[lid].next = TxAnchor.freelock;
231 TxAnchor.freelock = lid; 232 TxAnchor.freelock = lid;
232 TxAnchor.tlocksInUse--; 233 TxAnchor.tlocksInUse--;
@@ -633,8 +634,10 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
633 634
634 /* is page locked by the requester transaction ? */ 635 /* is page locked by the requester transaction ? */
635 tlck = lid_to_tlock(lid); 636 tlck = lid_to_tlock(lid);
636 if ((xtid = tlck->tid) == tid) 637 if ((xtid = tlck->tid) == tid) {
638 TXN_UNLOCK();
637 goto grantLock; 639 goto grantLock;
640 }
638 641
639 /* 642 /*
640 * is page locked by anonymous transaction/lock ? 643 * is page locked by anonymous transaction/lock ?
@@ -649,6 +652,7 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
649 */ 652 */
650 if (xtid == 0) { 653 if (xtid == 0) {
651 tlck->tid = tid; 654 tlck->tid = tid;
655 TXN_UNLOCK();
652 tblk = tid_to_tblock(tid); 656 tblk = tid_to_tblock(tid);
653 /* 657 /*
654 * The order of the tlocks in the transaction is important 658 * The order of the tlocks in the transaction is important
@@ -706,17 +710,18 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
706 */ 710 */
707 tlck->tid = tid; 711 tlck->tid = tid;
708 712
713 TXN_UNLOCK();
714
709 /* mark tlock for meta-data page */ 715 /* mark tlock for meta-data page */
710 if (mp->xflag & COMMIT_PAGE) { 716 if (mp->xflag & COMMIT_PAGE) {
711 717
712 tlck->flag = tlckPAGELOCK; 718 tlck->flag = tlckPAGELOCK;
713 719
714 /* mark the page dirty and nohomeok */ 720 /* mark the page dirty and nohomeok */
715 mark_metapage_dirty(mp); 721 metapage_nohomeok(mp);
716 atomic_inc(&mp->nohomeok);
717 722
718 jfs_info("locking mp = 0x%p, nohomeok = %d tid = %d tlck = 0x%p", 723 jfs_info("locking mp = 0x%p, nohomeok = %d tid = %d tlck = 0x%p",
719 mp, atomic_read(&mp->nohomeok), tid, tlck); 724 mp, mp->nohomeok, tid, tlck);
720 725
721 /* if anonymous transaction, and buffer is on the group 726 /* if anonymous transaction, and buffer is on the group
722 * commit synclist, mark inode to show this. This will 727 * commit synclist, mark inode to show this. This will
@@ -762,8 +767,10 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
762 if (tlck->next == 0) { 767 if (tlck->next == 0) {
763 /* This inode's first anonymous transaction */ 768 /* This inode's first anonymous transaction */
764 jfs_ip->atltail = lid; 769 jfs_ip->atltail = lid;
770 TXN_LOCK();
765 list_add_tail(&jfs_ip->anon_inode_list, 771 list_add_tail(&jfs_ip->anon_inode_list,
766 &TxAnchor.anon_list); 772 &TxAnchor.anon_list);
773 TXN_UNLOCK();
767 } 774 }
768 } 775 }
769 776
@@ -821,8 +828,6 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
821 grantLock: 828 grantLock:
822 tlck->type |= type; 829 tlck->type |= type;
823 830
824 TXN_UNLOCK();
825
826 return tlck; 831 return tlck;
827 832
828 /* 833 /*
@@ -841,11 +846,19 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
841 BUG(); 846 BUG();
842 } 847 }
843 INCREMENT(stattx.waitlock); /* statistics */ 848 INCREMENT(stattx.waitlock); /* statistics */
849 TXN_UNLOCK();
844 release_metapage(mp); 850 release_metapage(mp);
851 TXN_LOCK();
852 xtid = tlck->tid; /* reaquire after dropping TXN_LOCK */
845 853
846 jfs_info("txLock: in waitLock, tid = %d, xtid = %d, lid = %d", 854 jfs_info("txLock: in waitLock, tid = %d, xtid = %d, lid = %d",
847 tid, xtid, lid); 855 tid, xtid, lid);
848 TXN_SLEEP_DROP_LOCK(&tid_to_tblock(xtid)->waitor); 856
857 /* Recheck everything since dropping TXN_LOCK */
858 if (xtid && (tlck->mp == mp) && (mp->lid == lid))
859 TXN_SLEEP_DROP_LOCK(&tid_to_tblock(xtid)->waitor);
860 else
861 TXN_UNLOCK();
849 jfs_info("txLock: awakened tid = %d, lid = %d", tid, lid); 862 jfs_info("txLock: awakened tid = %d, lid = %d", tid, lid);
850 863
851 return NULL; 864 return NULL;
@@ -906,6 +919,7 @@ static void txUnlock(struct tblock * tblk)
906 struct metapage *mp; 919 struct metapage *mp;
907 struct jfs_log *log; 920 struct jfs_log *log;
908 int difft, diffp; 921 int difft, diffp;
922 unsigned long flags;
909 923
910 jfs_info("txUnlock: tblk = 0x%p", tblk); 924 jfs_info("txUnlock: tblk = 0x%p", tblk);
911 log = JFS_SBI(tblk->sb)->log; 925 log = JFS_SBI(tblk->sb)->log;
@@ -925,19 +939,14 @@ static void txUnlock(struct tblock * tblk)
925 assert(mp->xflag & COMMIT_PAGE); 939 assert(mp->xflag & COMMIT_PAGE);
926 940
927 /* hold buffer 941 /* hold buffer
928 *
929 * It's possible that someone else has the metapage.
930 * The only things were changing are nohomeok, which
931 * is handled atomically, and clsn which is protected
932 * by the LOGSYNC_LOCK.
933 */ 942 */
934 hold_metapage(mp, 1); 943 hold_metapage(mp);
935 944
936 assert(atomic_read(&mp->nohomeok) > 0); 945 assert(mp->nohomeok > 0);
937 atomic_dec(&mp->nohomeok); 946 _metapage_homeok(mp);
938 947
939 /* inherit younger/larger clsn */ 948 /* inherit younger/larger clsn */
940 LOGSYNC_LOCK(log); 949 LOGSYNC_LOCK(log, flags);
941 if (mp->clsn) { 950 if (mp->clsn) {
942 logdiff(difft, tblk->clsn, log); 951 logdiff(difft, tblk->clsn, log);
943 logdiff(diffp, mp->clsn, log); 952 logdiff(diffp, mp->clsn, log);
@@ -945,16 +954,11 @@ static void txUnlock(struct tblock * tblk)
945 mp->clsn = tblk->clsn; 954 mp->clsn = tblk->clsn;
946 } else 955 } else
947 mp->clsn = tblk->clsn; 956 mp->clsn = tblk->clsn;
948 LOGSYNC_UNLOCK(log); 957 LOGSYNC_UNLOCK(log, flags);
949 958
950 assert(!(tlck->flag & tlckFREEPAGE)); 959 assert(!(tlck->flag & tlckFREEPAGE));
951 960
952 if (tlck->flag & tlckWRITEPAGE) { 961 put_metapage(mp);
953 write_metapage(mp);
954 } else {
955 /* release page which has been forced */
956 release_metapage(mp);
957 }
958 } 962 }
959 963
960 /* insert tlock, and linelock(s) of the tlock if any, 964 /* insert tlock, and linelock(s) of the tlock if any,
@@ -981,10 +985,10 @@ static void txUnlock(struct tblock * tblk)
981 * has been inserted in logsync list at txUpdateMap()) 985 * has been inserted in logsync list at txUpdateMap())
982 */ 986 */
983 if (tblk->lsn) { 987 if (tblk->lsn) {
984 LOGSYNC_LOCK(log); 988 LOGSYNC_LOCK(log, flags);
985 log->count--; 989 log->count--;
986 list_del(&tblk->synclist); 990 list_del(&tblk->synclist);
987 LOGSYNC_UNLOCK(log); 991 LOGSYNC_UNLOCK(log, flags);
988 } 992 }
989} 993}
990 994
@@ -1573,8 +1577,8 @@ static int dataLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1573 * the last entry, so don't bother logging this 1577 * the last entry, so don't bother logging this
1574 */ 1578 */
1575 mp->lid = 0; 1579 mp->lid = 0;
1576 hold_metapage(mp, 0); 1580 grab_metapage(mp);
1577 atomic_dec(&mp->nohomeok); 1581 metapage_homeok(mp);
1578 discard_metapage(mp); 1582 discard_metapage(mp);
1579 tlck->mp = NULL; 1583 tlck->mp = NULL;
1580 return 0; 1584 return 0;
@@ -2270,7 +2274,8 @@ void txForce(struct tblock * tblk)
2270 tlck->flag &= ~tlckWRITEPAGE; 2274 tlck->flag &= ~tlckWRITEPAGE;
2271 2275
2272 /* do not release page to freelist */ 2276 /* do not release page to freelist */
2273 2277 force_metapage(mp);
2278#if 0
2274 /* 2279 /*
2275 * The "right" thing to do here is to 2280 * The "right" thing to do here is to
2276 * synchronously write the metadata. 2281 * synchronously write the metadata.
@@ -2282,9 +2287,10 @@ void txForce(struct tblock * tblk)
2282 * we can get by with synchronously writing 2287 * we can get by with synchronously writing
2283 * the pages when they are released. 2288 * the pages when they are released.
2284 */ 2289 */
2285 assert(atomic_read(&mp->nohomeok)); 2290 assert(mp->nohomeok);
2286 set_bit(META_dirty, &mp->flag); 2291 set_bit(META_dirty, &mp->flag);
2287 set_bit(META_sync, &mp->flag); 2292 set_bit(META_sync, &mp->flag);
2293#endif
2288 } 2294 }
2289 } 2295 }
2290 } 2296 }
@@ -2344,7 +2350,7 @@ static void txUpdateMap(struct tblock * tblk)
2344 */ 2350 */
2345 mp = tlck->mp; 2351 mp = tlck->mp;
2346 ASSERT(mp->xflag & COMMIT_PAGE); 2352 ASSERT(mp->xflag & COMMIT_PAGE);
2347 hold_metapage(mp, 0); 2353 grab_metapage(mp);
2348 } 2354 }
2349 2355
2350 /* 2356 /*
@@ -2394,8 +2400,8 @@ static void txUpdateMap(struct tblock * tblk)
2394 ASSERT(mp->lid == lid); 2400 ASSERT(mp->lid == lid);
2395 tlck->mp->lid = 0; 2401 tlck->mp->lid = 0;
2396 } 2402 }
2397 assert(atomic_read(&mp->nohomeok) == 1); 2403 assert(mp->nohomeok == 1);
2398 atomic_dec(&mp->nohomeok); 2404 metapage_homeok(mp);
2399 discard_metapage(mp); 2405 discard_metapage(mp);
2400 tlck->mp = NULL; 2406 tlck->mp = NULL;
2401 } 2407 }
@@ -2861,24 +2867,9 @@ static void LogSyncRelease(struct metapage * mp)
2861{ 2867{
2862 struct jfs_log *log = mp->log; 2868 struct jfs_log *log = mp->log;
2863 2869
2864 assert(atomic_read(&mp->nohomeok)); 2870 assert(mp->nohomeok);
2865 assert(log); 2871 assert(log);
2866 atomic_dec(&mp->nohomeok); 2872 metapage_homeok(mp);
2867
2868 if (atomic_read(&mp->nohomeok))
2869 return;
2870
2871 hold_metapage(mp, 0);
2872
2873 LOGSYNC_LOCK(log);
2874 mp->log = NULL;
2875 mp->lsn = 0;
2876 mp->clsn = 0;
2877 log->count--;
2878 list_del_init(&mp->synclist);
2879 LOGSYNC_UNLOCK(log);
2880
2881 release_metapage(mp);
2882} 2873}
2883 2874
2884/* 2875/*