| 1928 | |
| 1929 | |
| 1930 | bool set_diff_page(thread_db* tdbb, BufferDesc* bdb) |
| 1931 | { |
| 1932 | Database* const dbb = tdbb->getDatabase(); |
| 1933 | BackupManager* const bm = dbb->dbb_backup_manager; |
| 1934 | |
| 1935 | // Temporary pages don't write to delta and need no SCN |
| 1936 | PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(bdb->bdb_page.getPageSpaceID()); |
| 1937 | fb_assert(pageSpace); |
| 1938 | if (pageSpace->isTemporary()) |
| 1939 | return true; |
| 1940 | |
| 1941 | // Take backup state lock |
| 1942 | if (!(tdbb->tdbb_flags & TDBB_backup_write_locked)) |
| 1943 | { |
| 1944 | const AtomicCounter::counter_type oldFlags = bdb->bdb_flags.exchangeBitOr(BDB_nbak_state_lock); |
| 1945 | if (!(oldFlags & BDB_nbak_state_lock)) |
| 1946 | { |
| 1947 | NBAK_TRACE(("lock state for dirty page %d:%06d", |
| 1948 | bdb->bdb_page.getPageSpaceID(), bdb->bdb_page.getPageNum())); |
| 1949 | |
| 1950 | bm->lockStateRead(tdbb, LCK_WAIT); |
| 1951 | } |
| 1952 | } |
| 1953 | else |
| 1954 | fb_assert(bdb->bdb_page == HEADER_PAGE_NUMBER); |
| 1955 | |
| 1956 | if (bdb->bdb_page != HEADER_PAGE_NUMBER) |
| 1957 | { |
| 1958 | // SCN of header page is adjusted in nbak.cpp |
| 1959 | if (bdb->bdb_buffer->pag_scn != bm->getCurrentSCN()) |
| 1960 | { |
| 1961 | bdb->bdb_buffer->pag_scn = bm->getCurrentSCN(); // Set SCN for the page |
| 1962 | |
| 1963 | // At PAG_set_page_scn() below we could dirty SCN page and thus acquire |
| 1964 | // nbackup state lock recursively. Since RWLock allows it, we are safe. |
| 1965 | // Else we should release just taken state lock before call of |
| 1966 | // PAG_set_page_scn() and acquire it again. If current SCN changes meanwhile |
| 1967 | // we should repeat whole process again... |
| 1968 | |
| 1969 | win window(bdb->bdb_page); |
| 1970 | window.win_bdb = bdb; |
| 1971 | window.win_buffer = bdb->bdb_buffer; |
| 1972 | PAG_set_page_scn(tdbb, &window); |
| 1973 | } |
| 1974 | |
| 1975 | fb_assert(bdb->bdb_buffer->pag_scn == bm->getCurrentSCN()); |
| 1976 | } |
| 1977 | |
| 1978 | // Determine location of the page in difference file and write destination |
| 1979 | // so BufferDesc AST handlers and write_page routine can safely use this information |
| 1980 | |
| 1981 | const int backup_state = bm->getState(); |
| 1982 | |
| 1983 | if (backup_state == Ods::hdr_nbak_normal) |
| 1984 | return true; |
| 1985 | |
| 1986 | switch (backup_state) |
| 1987 | { |
no test coverage detected