1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_store.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include "storbios.hxx" 32*cdf0e10cSrcweir 33*cdf0e10cSrcweir #include "sal/types.h" 34*cdf0e10cSrcweir #include "sal/macros.h" 35*cdf0e10cSrcweir 36*cdf0e10cSrcweir #include "rtl/alloc.h" 37*cdf0e10cSrcweir #include "rtl/ref.hxx" 38*cdf0e10cSrcweir 39*cdf0e10cSrcweir #include "osl/diagnose.h" 40*cdf0e10cSrcweir #include "osl/mutex.hxx" 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir #include "store/types.h" 43*cdf0e10cSrcweir #include "object.hxx" 44*cdf0e10cSrcweir #include "lockbyte.hxx" 45*cdf0e10cSrcweir #include "storcach.hxx" 46*cdf0e10cSrcweir 47*cdf0e10cSrcweir using namespace store; 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir /*======================================================================== 50*cdf0e10cSrcweir * 51*cdf0e10cSrcweir * OStoreSuperBlock. 52*cdf0e10cSrcweir * 53*cdf0e10cSrcweir *======================================================================*/ 54*cdf0e10cSrcweir #define STORE_MAGIC_SUPERBLOCK sal_uInt32(0x484D5343) 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir struct OStoreSuperBlock 57*cdf0e10cSrcweir { 58*cdf0e10cSrcweir typedef OStorePageGuard G; 59*cdf0e10cSrcweir typedef OStorePageDescriptor D; 60*cdf0e10cSrcweir typedef OStorePageLink L; 61*cdf0e10cSrcweir 62*cdf0e10cSrcweir /** Representation. 63*cdf0e10cSrcweir */ 64*cdf0e10cSrcweir G m_aGuard; 65*cdf0e10cSrcweir D m_aDescr; 66*cdf0e10cSrcweir sal_uInt32 m_nMarked; 67*cdf0e10cSrcweir L m_aMarked; 68*cdf0e10cSrcweir sal_uInt32 m_nUnused; 69*cdf0e10cSrcweir L m_aUnused; 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir /** theSize. 72*cdf0e10cSrcweir */ 73*cdf0e10cSrcweir static const size_t theSize = sizeof(G) + sizeof(D) + 2 * (sizeof(L) + sizeof(sal_uInt32)); 74*cdf0e10cSrcweir 75*cdf0e10cSrcweir /** Construction. 76*cdf0e10cSrcweir */ 77*cdf0e10cSrcweir explicit OStoreSuperBlock (sal_uInt16 nPageSize) 78*cdf0e10cSrcweir : m_aGuard (STORE_MAGIC_SUPERBLOCK), 79*cdf0e10cSrcweir m_aDescr (nPageSize, nPageSize, STORE_MINIMUM_PAGESIZE), 80*cdf0e10cSrcweir m_nMarked (store::htonl(0)), 81*cdf0e10cSrcweir m_aMarked (0), 82*cdf0e10cSrcweir m_nUnused (store::htonl(0)), 83*cdf0e10cSrcweir m_aUnused (0) 84*cdf0e10cSrcweir {} 85*cdf0e10cSrcweir 86*cdf0e10cSrcweir OStoreSuperBlock (const OStoreSuperBlock & rhs) 87*cdf0e10cSrcweir : m_aGuard (rhs.m_aGuard), 88*cdf0e10cSrcweir m_aDescr (rhs.m_aDescr), 89*cdf0e10cSrcweir m_nMarked (rhs.m_nMarked), 90*cdf0e10cSrcweir m_aMarked (rhs.m_aMarked), 91*cdf0e10cSrcweir m_nUnused (rhs.m_nUnused), 92*cdf0e10cSrcweir m_aUnused (rhs.m_aUnused) 93*cdf0e10cSrcweir {} 94*cdf0e10cSrcweir 95*cdf0e10cSrcweir OStoreSuperBlock& operator= (const OStoreSuperBlock & rhs) 96*cdf0e10cSrcweir { 97*cdf0e10cSrcweir m_aGuard = rhs.m_aGuard; 98*cdf0e10cSrcweir m_aDescr = rhs.m_aDescr; 99*cdf0e10cSrcweir m_nMarked = rhs.m_nMarked; 100*cdf0e10cSrcweir m_aMarked = rhs.m_aMarked; 101*cdf0e10cSrcweir m_nUnused = rhs.m_nUnused; 102*cdf0e10cSrcweir m_aUnused = rhs.m_aUnused; 103*cdf0e10cSrcweir return *this; 104*cdf0e10cSrcweir } 105*cdf0e10cSrcweir 106*cdf0e10cSrcweir /** Comparison. 107*cdf0e10cSrcweir */ 108*cdf0e10cSrcweir sal_Bool operator== (const OStoreSuperBlock & rhs) const 109*cdf0e10cSrcweir { 110*cdf0e10cSrcweir return ((m_aGuard == rhs.m_aGuard ) && 111*cdf0e10cSrcweir (m_aDescr == rhs.m_aDescr ) && 112*cdf0e10cSrcweir (m_nMarked == rhs.m_nMarked) && 113*cdf0e10cSrcweir (m_aMarked == rhs.m_aMarked) && 114*cdf0e10cSrcweir (m_nUnused == rhs.m_nUnused) && 115*cdf0e10cSrcweir (m_aUnused == rhs.m_aUnused) ); 116*cdf0e10cSrcweir } 117*cdf0e10cSrcweir 118*cdf0e10cSrcweir /** unused(Count|Head|Insert|Remove|Reset). 119*cdf0e10cSrcweir */ 120*cdf0e10cSrcweir sal_uInt32 unusedCount (void) const 121*cdf0e10cSrcweir { 122*cdf0e10cSrcweir return store::ntohl(m_nUnused); 123*cdf0e10cSrcweir } 124*cdf0e10cSrcweir const L& unusedHead (void) const 125*cdf0e10cSrcweir { 126*cdf0e10cSrcweir return m_aUnused; 127*cdf0e10cSrcweir } 128*cdf0e10cSrcweir void unusedInsert (const L& rLink) 129*cdf0e10cSrcweir { 130*cdf0e10cSrcweir sal_uInt32 nUnused = unusedCount(); 131*cdf0e10cSrcweir m_nUnused = store::htonl(nUnused + 1); 132*cdf0e10cSrcweir m_aUnused = rLink; 133*cdf0e10cSrcweir } 134*cdf0e10cSrcweir void unusedRemove (const L& rLink) 135*cdf0e10cSrcweir { 136*cdf0e10cSrcweir sal_uInt32 nUnused = unusedCount(); 137*cdf0e10cSrcweir m_nUnused = store::htonl(nUnused - 1); 138*cdf0e10cSrcweir m_aUnused = rLink; 139*cdf0e10cSrcweir } 140*cdf0e10cSrcweir void unusedReset (void) 141*cdf0e10cSrcweir { 142*cdf0e10cSrcweir m_nUnused = store::htonl(0); 143*cdf0e10cSrcweir m_aUnused = L(0); 144*cdf0e10cSrcweir } 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir /** guard (external representation). 147*cdf0e10cSrcweir */ 148*cdf0e10cSrcweir void guard() 149*cdf0e10cSrcweir { 150*cdf0e10cSrcweir sal_uInt32 nCRC32 = 0; 151*cdf0e10cSrcweir nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); 152*cdf0e10cSrcweir nCRC32 = rtl_crc32 (nCRC32, &m_aDescr, theSize - sizeof(G)); 153*cdf0e10cSrcweir m_aGuard.m_nCRC32 = store::htonl(nCRC32); 154*cdf0e10cSrcweir } 155*cdf0e10cSrcweir 156*cdf0e10cSrcweir /** verify (external representation). 157*cdf0e10cSrcweir */ 158*cdf0e10cSrcweir storeError verify() const 159*cdf0e10cSrcweir { 160*cdf0e10cSrcweir sal_uInt32 nMagic = store::ntohl(m_aGuard.m_nMagic); 161*cdf0e10cSrcweir if (nMagic != STORE_MAGIC_SUPERBLOCK) 162*cdf0e10cSrcweir return store_E_WrongFormat; 163*cdf0e10cSrcweir 164*cdf0e10cSrcweir sal_uInt32 nCRC32 = 0; 165*cdf0e10cSrcweir nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); 166*cdf0e10cSrcweir nCRC32 = rtl_crc32 (nCRC32, &m_aDescr, theSize - sizeof(G)); 167*cdf0e10cSrcweir if (m_aGuard.m_nCRC32 != store::htonl(nCRC32)) 168*cdf0e10cSrcweir return store_E_InvalidChecksum; 169*cdf0e10cSrcweir else 170*cdf0e10cSrcweir return store_E_None; 171*cdf0e10cSrcweir } 172*cdf0e10cSrcweir }; 173*cdf0e10cSrcweir 174*cdf0e10cSrcweir /*======================================================================== 175*cdf0e10cSrcweir * 176*cdf0e10cSrcweir * SuperBlockPage interface. 177*cdf0e10cSrcweir * 178*cdf0e10cSrcweir *======================================================================*/ 179*cdf0e10cSrcweir namespace store 180*cdf0e10cSrcweir { 181*cdf0e10cSrcweir 182*cdf0e10cSrcweir struct SuperBlockPage 183*cdf0e10cSrcweir { 184*cdf0e10cSrcweir typedef OStoreSuperBlock SuperBlock; 185*cdf0e10cSrcweir 186*cdf0e10cSrcweir /** Representation. 187*cdf0e10cSrcweir */ 188*cdf0e10cSrcweir SuperBlock m_aSuperOne; 189*cdf0e10cSrcweir SuperBlock m_aSuperTwo; 190*cdf0e10cSrcweir 191*cdf0e10cSrcweir /** theSize. 192*cdf0e10cSrcweir */ 193*cdf0e10cSrcweir static const size_t theSize = 2 * SuperBlock::theSize; 194*cdf0e10cSrcweir static const sal_uInt16 thePageSize = theSize; 195*cdf0e10cSrcweir STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= thePageSize); 196*cdf0e10cSrcweir 197*cdf0e10cSrcweir /** Allocation. 198*cdf0e10cSrcweir */ 199*cdf0e10cSrcweir static void * operator new (size_t n) SAL_THROW(()) 200*cdf0e10cSrcweir { 201*cdf0e10cSrcweir return rtl_allocateMemory (sal::static_int_cast<sal_Size>(n)); 202*cdf0e10cSrcweir } 203*cdf0e10cSrcweir static void operator delete (void * p, size_t) SAL_THROW(()) 204*cdf0e10cSrcweir { 205*cdf0e10cSrcweir rtl_freeMemory (p); 206*cdf0e10cSrcweir } 207*cdf0e10cSrcweir 208*cdf0e10cSrcweir static void * operator new (size_t, sal_uInt16 nPageSize) SAL_THROW(()) 209*cdf0e10cSrcweir { 210*cdf0e10cSrcweir return rtl_allocateZeroMemory (sal::static_int_cast<sal_Size>(nPageSize)); 211*cdf0e10cSrcweir } 212*cdf0e10cSrcweir static void operator delete (void * p, sal_uInt16) SAL_THROW(()) 213*cdf0e10cSrcweir { 214*cdf0e10cSrcweir rtl_freeMemory (p); 215*cdf0e10cSrcweir } 216*cdf0e10cSrcweir 217*cdf0e10cSrcweir /** Construction. 218*cdf0e10cSrcweir */ 219*cdf0e10cSrcweir explicit SuperBlockPage (sal_uInt16 nPageSize = thePageSize) 220*cdf0e10cSrcweir : m_aSuperOne(nPageSize), 221*cdf0e10cSrcweir m_aSuperTwo(nPageSize) 222*cdf0e10cSrcweir {} 223*cdf0e10cSrcweir 224*cdf0e10cSrcweir /** save. 225*cdf0e10cSrcweir */ 226*cdf0e10cSrcweir storeError save (OStorePageBIOS & rBIOS, sal_uInt32 nSize = theSize) 227*cdf0e10cSrcweir { 228*cdf0e10cSrcweir m_aSuperOne.guard(); 229*cdf0e10cSrcweir m_aSuperTwo = m_aSuperOne; 230*cdf0e10cSrcweir return rBIOS.write (0, this, nSize); 231*cdf0e10cSrcweir } 232*cdf0e10cSrcweir 233*cdf0e10cSrcweir /** Page allocation. 234*cdf0e10cSrcweir */ 235*cdf0e10cSrcweir storeError unusedHead ( 236*cdf0e10cSrcweir OStorePageBIOS & rBIOS, 237*cdf0e10cSrcweir PageData & rPageHead); 238*cdf0e10cSrcweir 239*cdf0e10cSrcweir storeError unusedPop ( 240*cdf0e10cSrcweir OStorePageBIOS & rBIOS, 241*cdf0e10cSrcweir PageData const & rPageHead); 242*cdf0e10cSrcweir 243*cdf0e10cSrcweir storeError unusedPush ( 244*cdf0e10cSrcweir OStorePageBIOS & rBIOS, 245*cdf0e10cSrcweir sal_uInt32 nAddr); 246*cdf0e10cSrcweir 247*cdf0e10cSrcweir /** verify (with repair). 248*cdf0e10cSrcweir */ 249*cdf0e10cSrcweir storeError verify (OStorePageBIOS & rBIOS); 250*cdf0e10cSrcweir }; 251*cdf0e10cSrcweir 252*cdf0e10cSrcweir } // namespace store 253*cdf0e10cSrcweir 254*cdf0e10cSrcweir /*======================================================================== 255*cdf0e10cSrcweir * 256*cdf0e10cSrcweir * SuperBlockPage implementation. 257*cdf0e10cSrcweir * 258*cdf0e10cSrcweir *======================================================================*/ 259*cdf0e10cSrcweir /* 260*cdf0e10cSrcweir * unusedHead(): get freelist head (alloc page, step 1). 261*cdf0e10cSrcweir */ 262*cdf0e10cSrcweir storeError SuperBlockPage::unusedHead (OStorePageBIOS & rBIOS, PageData & rPageHead) 263*cdf0e10cSrcweir { 264*cdf0e10cSrcweir storeError eErrCode = verify (rBIOS); 265*cdf0e10cSrcweir if (eErrCode != store_E_None) 266*cdf0e10cSrcweir return eErrCode; 267*cdf0e10cSrcweir 268*cdf0e10cSrcweir // Check freelist head. 269*cdf0e10cSrcweir OStorePageLink const aListHead (m_aSuperOne.unusedHead()); 270*cdf0e10cSrcweir if (aListHead.location() == 0) 271*cdf0e10cSrcweir { 272*cdf0e10cSrcweir // Freelist empty, see SuperBlock::ctor(). 273*cdf0e10cSrcweir rPageHead.location (STORE_PAGE_NULL); 274*cdf0e10cSrcweir return store_E_None; 275*cdf0e10cSrcweir } 276*cdf0e10cSrcweir 277*cdf0e10cSrcweir // Load PageHead. 278*cdf0e10cSrcweir eErrCode = rBIOS.read (aListHead.location(), &rPageHead, PageData::theSize); 279*cdf0e10cSrcweir if (eErrCode != store_E_None) 280*cdf0e10cSrcweir return eErrCode; 281*cdf0e10cSrcweir 282*cdf0e10cSrcweir eErrCode = rPageHead.verify (aListHead.location()); 283*cdf0e10cSrcweir if (eErrCode != store_E_None) 284*cdf0e10cSrcweir return eErrCode; 285*cdf0e10cSrcweir 286*cdf0e10cSrcweir // Verify page is unused. 287*cdf0e10cSrcweir sal_uInt32 const nAddr = rPageHead.m_aUnused.location(); 288*cdf0e10cSrcweir OSL_POSTCOND(nAddr != STORE_PAGE_NULL, "store::SuperBlock::unusedHead(): page not free"); 289*cdf0e10cSrcweir if (nAddr == STORE_PAGE_NULL) 290*cdf0e10cSrcweir { 291*cdf0e10cSrcweir // Page in use. 292*cdf0e10cSrcweir rPageHead.location (STORE_PAGE_NULL); 293*cdf0e10cSrcweir 294*cdf0e10cSrcweir // Recovery: Reset freelist to empty. 295*cdf0e10cSrcweir m_aSuperOne.unusedReset(); 296*cdf0e10cSrcweir eErrCode = save (rBIOS); 297*cdf0e10cSrcweir } 298*cdf0e10cSrcweir return eErrCode; 299*cdf0e10cSrcweir } 300*cdf0e10cSrcweir 301*cdf0e10cSrcweir /* 302*cdf0e10cSrcweir * unusedPop(): pop freelist head (alloc page, step 2). 303*cdf0e10cSrcweir */ 304*cdf0e10cSrcweir storeError SuperBlockPage::unusedPop (OStorePageBIOS & rBIOS, PageData const & rPageHead) 305*cdf0e10cSrcweir { 306*cdf0e10cSrcweir sal_uInt32 const nAddr = rPageHead.m_aUnused.location(); 307*cdf0e10cSrcweir OSL_PRECOND(nAddr != STORE_PAGE_NULL, "store::SuperBlock::unusedPop(): page not free"); 308*cdf0e10cSrcweir if (nAddr == STORE_PAGE_NULL) 309*cdf0e10cSrcweir return store_E_CantSeek; 310*cdf0e10cSrcweir 311*cdf0e10cSrcweir // Pop from FreeList. 312*cdf0e10cSrcweir OStorePageLink const aListHead (nAddr); 313*cdf0e10cSrcweir m_aSuperOne.unusedRemove (aListHead); 314*cdf0e10cSrcweir return save (rBIOS); 315*cdf0e10cSrcweir } 316*cdf0e10cSrcweir 317*cdf0e10cSrcweir /* 318*cdf0e10cSrcweir * unusedPush(): push new freelist head. 319*cdf0e10cSrcweir */ 320*cdf0e10cSrcweir storeError SuperBlockPage::unusedPush (OStorePageBIOS & rBIOS, sal_uInt32 nAddr) 321*cdf0e10cSrcweir { 322*cdf0e10cSrcweir storeError eErrCode = verify (rBIOS); 323*cdf0e10cSrcweir if (eErrCode != store_E_None) 324*cdf0e10cSrcweir return eErrCode; 325*cdf0e10cSrcweir 326*cdf0e10cSrcweir PageData aPageHead; 327*cdf0e10cSrcweir eErrCode = rBIOS.read (nAddr, &aPageHead, PageData::theSize); 328*cdf0e10cSrcweir if (eErrCode != store_E_None) 329*cdf0e10cSrcweir return eErrCode; 330*cdf0e10cSrcweir 331*cdf0e10cSrcweir eErrCode = aPageHead.verify (nAddr); 332*cdf0e10cSrcweir if (eErrCode != store_E_None) 333*cdf0e10cSrcweir return eErrCode; 334*cdf0e10cSrcweir 335*cdf0e10cSrcweir aPageHead.m_aUnused = m_aSuperOne.unusedHead(); 336*cdf0e10cSrcweir aPageHead.guard (nAddr); 337*cdf0e10cSrcweir 338*cdf0e10cSrcweir eErrCode = rBIOS.write (nAddr, &aPageHead, PageData::theSize); 339*cdf0e10cSrcweir if (eErrCode != store_E_None) 340*cdf0e10cSrcweir return eErrCode; 341*cdf0e10cSrcweir 342*cdf0e10cSrcweir OStorePageLink const aListHead (nAddr); 343*cdf0e10cSrcweir m_aSuperOne.unusedInsert(aListHead); 344*cdf0e10cSrcweir return save (rBIOS); 345*cdf0e10cSrcweir } 346*cdf0e10cSrcweir 347*cdf0e10cSrcweir /* 348*cdf0e10cSrcweir * verify (with repair). 349*cdf0e10cSrcweir */ 350*cdf0e10cSrcweir storeError SuperBlockPage::verify (OStorePageBIOS & rBIOS) 351*cdf0e10cSrcweir { 352*cdf0e10cSrcweir // Verify 1st copy. 353*cdf0e10cSrcweir storeError eErrCode = m_aSuperOne.verify(); 354*cdf0e10cSrcweir if (eErrCode == store_E_None) 355*cdf0e10cSrcweir { 356*cdf0e10cSrcweir // Ok. Verify 2nd copy. 357*cdf0e10cSrcweir eErrCode = m_aSuperTwo.verify(); 358*cdf0e10cSrcweir if (eErrCode == store_E_None) 359*cdf0e10cSrcweir { 360*cdf0e10cSrcweir // Ok. Ensure identical copies (1st copy wins). 361*cdf0e10cSrcweir if (!(m_aSuperOne == m_aSuperTwo)) 362*cdf0e10cSrcweir { 363*cdf0e10cSrcweir // Different. Replace 2nd copy with 1st copy. 364*cdf0e10cSrcweir m_aSuperTwo = m_aSuperOne; 365*cdf0e10cSrcweir 366*cdf0e10cSrcweir // Write back. 367*cdf0e10cSrcweir if (rBIOS.isWriteable()) 368*cdf0e10cSrcweir eErrCode = rBIOS.write (0, this, theSize); 369*cdf0e10cSrcweir else 370*cdf0e10cSrcweir eErrCode = store_E_None; 371*cdf0e10cSrcweir } 372*cdf0e10cSrcweir } 373*cdf0e10cSrcweir else 374*cdf0e10cSrcweir { 375*cdf0e10cSrcweir // Failure. Replace 2nd copy with 1st copy. 376*cdf0e10cSrcweir m_aSuperTwo = m_aSuperOne; 377*cdf0e10cSrcweir 378*cdf0e10cSrcweir // Write back. 379*cdf0e10cSrcweir if (rBIOS.isWriteable()) 380*cdf0e10cSrcweir eErrCode = rBIOS.write (0, this, theSize); 381*cdf0e10cSrcweir else 382*cdf0e10cSrcweir eErrCode = store_E_None; 383*cdf0e10cSrcweir } 384*cdf0e10cSrcweir } 385*cdf0e10cSrcweir else 386*cdf0e10cSrcweir { 387*cdf0e10cSrcweir // Failure. Verify 2nd copy. 388*cdf0e10cSrcweir eErrCode = m_aSuperTwo.verify(); 389*cdf0e10cSrcweir if (eErrCode == store_E_None) 390*cdf0e10cSrcweir { 391*cdf0e10cSrcweir // Ok. Replace 1st copy with 2nd copy. 392*cdf0e10cSrcweir m_aSuperOne = m_aSuperTwo; 393*cdf0e10cSrcweir 394*cdf0e10cSrcweir // Write back. 395*cdf0e10cSrcweir if (rBIOS.isWriteable()) 396*cdf0e10cSrcweir eErrCode = rBIOS.write (0, this, theSize); 397*cdf0e10cSrcweir else 398*cdf0e10cSrcweir eErrCode = store_E_None; 399*cdf0e10cSrcweir } 400*cdf0e10cSrcweir else 401*cdf0e10cSrcweir { 402*cdf0e10cSrcweir // Double Failure. 403*cdf0e10cSrcweir OSL_TRACE("OStoreSuperBlockPage::verify(): double failure.\n"); 404*cdf0e10cSrcweir } 405*cdf0e10cSrcweir } 406*cdf0e10cSrcweir 407*cdf0e10cSrcweir // Done. 408*cdf0e10cSrcweir return eErrCode; 409*cdf0e10cSrcweir } 410*cdf0e10cSrcweir 411*cdf0e10cSrcweir /*======================================================================== 412*cdf0e10cSrcweir * 413*cdf0e10cSrcweir * OStorePageBIOS::Ace implementation. 414*cdf0e10cSrcweir * 415*cdf0e10cSrcweir *======================================================================*/ 416*cdf0e10cSrcweir OStorePageBIOS::Ace::Ace() 417*cdf0e10cSrcweir : m_next (this), m_prev (this), m_addr (STORE_PAGE_NULL), m_used (0) 418*cdf0e10cSrcweir {} 419*cdf0e10cSrcweir 420*cdf0e10cSrcweir OStorePageBIOS::Ace::~Ace() 421*cdf0e10cSrcweir { 422*cdf0e10cSrcweir m_next->m_prev = m_prev, m_prev->m_next = m_next; 423*cdf0e10cSrcweir } 424*cdf0e10cSrcweir 425*cdf0e10cSrcweir int 426*cdf0e10cSrcweir SAL_CALL OStorePageBIOS::Ace::constructor (void * obj, void * /* arg */) 427*cdf0e10cSrcweir { 428*cdf0e10cSrcweir Ace * ace = static_cast<Ace*>(obj); 429*cdf0e10cSrcweir ace->m_next = ace->m_prev = ace; 430*cdf0e10cSrcweir return 1; 431*cdf0e10cSrcweir } 432*cdf0e10cSrcweir 433*cdf0e10cSrcweir OStorePageBIOS::Ace * 434*cdf0e10cSrcweir OStorePageBIOS::Ace::find (OStorePageBIOS::Ace * head, sal_uInt32 addr) 435*cdf0e10cSrcweir { 436*cdf0e10cSrcweir OStorePageBIOS::Ace * entry; 437*cdf0e10cSrcweir for (entry = head->m_next; entry != head; entry = entry->m_next) 438*cdf0e10cSrcweir { 439*cdf0e10cSrcweir if (entry->m_addr >= addr) 440*cdf0e10cSrcweir return entry; 441*cdf0e10cSrcweir } 442*cdf0e10cSrcweir return head; 443*cdf0e10cSrcweir } 444*cdf0e10cSrcweir 445*cdf0e10cSrcweir void 446*cdf0e10cSrcweir OStorePageBIOS::Ace::insert (OStorePageBIOS::Ace * head, OStorePageBIOS::Ace * entry) 447*cdf0e10cSrcweir { 448*cdf0e10cSrcweir // insert entry at queue tail (before head). 449*cdf0e10cSrcweir entry->m_next = head; 450*cdf0e10cSrcweir entry->m_prev = head->m_prev; 451*cdf0e10cSrcweir head->m_prev = entry; 452*cdf0e10cSrcweir entry->m_prev->m_next = entry; 453*cdf0e10cSrcweir } 454*cdf0e10cSrcweir 455*cdf0e10cSrcweir /*======================================================================== 456*cdf0e10cSrcweir * 457*cdf0e10cSrcweir * OStorePageBIOS::AceCache interface. 458*cdf0e10cSrcweir * 459*cdf0e10cSrcweir *======================================================================*/ 460*cdf0e10cSrcweir namespace store 461*cdf0e10cSrcweir { 462*cdf0e10cSrcweir 463*cdf0e10cSrcweir class OStorePageBIOS::AceCache 464*cdf0e10cSrcweir { 465*cdf0e10cSrcweir rtl_cache_type * m_ace_cache; 466*cdf0e10cSrcweir 467*cdf0e10cSrcweir public: 468*cdf0e10cSrcweir static AceCache & get(); 469*cdf0e10cSrcweir 470*cdf0e10cSrcweir OStorePageBIOS::Ace * 471*cdf0e10cSrcweir create (sal_uInt32 addr, sal_uInt32 used = 1); 472*cdf0e10cSrcweir 473*cdf0e10cSrcweir void 474*cdf0e10cSrcweir destroy (OStorePageBIOS::Ace * ace); 475*cdf0e10cSrcweir 476*cdf0e10cSrcweir protected: 477*cdf0e10cSrcweir AceCache(); 478*cdf0e10cSrcweir ~AceCache(); 479*cdf0e10cSrcweir }; 480*cdf0e10cSrcweir 481*cdf0e10cSrcweir } // namespace store 482*cdf0e10cSrcweir 483*cdf0e10cSrcweir /*======================================================================== 484*cdf0e10cSrcweir * 485*cdf0e10cSrcweir * OStorePageBIOS::AceCache implementation. 486*cdf0e10cSrcweir * 487*cdf0e10cSrcweir *======================================================================*/ 488*cdf0e10cSrcweir extern "C" typedef int (SAL_CALL * ace_constructor_type)(void*,void*); 489*cdf0e10cSrcweir 490*cdf0e10cSrcweir OStorePageBIOS::AceCache & 491*cdf0e10cSrcweir OStorePageBIOS::AceCache::get() 492*cdf0e10cSrcweir { 493*cdf0e10cSrcweir static AceCache g_ace_cache; 494*cdf0e10cSrcweir return g_ace_cache; 495*cdf0e10cSrcweir } 496*cdf0e10cSrcweir 497*cdf0e10cSrcweir OStorePageBIOS::AceCache::AceCache() 498*cdf0e10cSrcweir { 499*cdf0e10cSrcweir m_ace_cache = rtl_cache_create ( 500*cdf0e10cSrcweir "store_ace_cache", 501*cdf0e10cSrcweir sizeof (OStorePageBIOS::Ace), 502*cdf0e10cSrcweir 0, // objalign 503*cdf0e10cSrcweir reinterpret_cast<ace_constructor_type>( OStorePageBIOS::Ace::constructor), 504*cdf0e10cSrcweir 0, // destructor, 505*cdf0e10cSrcweir 0, // reclaim, 506*cdf0e10cSrcweir 0, // userarg, 507*cdf0e10cSrcweir 0, // default source, 508*cdf0e10cSrcweir 0 // flags 509*cdf0e10cSrcweir ); 510*cdf0e10cSrcweir } 511*cdf0e10cSrcweir 512*cdf0e10cSrcweir OStorePageBIOS::AceCache::~AceCache() 513*cdf0e10cSrcweir { 514*cdf0e10cSrcweir rtl_cache_destroy (m_ace_cache), m_ace_cache = 0; 515*cdf0e10cSrcweir } 516*cdf0e10cSrcweir 517*cdf0e10cSrcweir OStorePageBIOS::Ace * 518*cdf0e10cSrcweir OStorePageBIOS::AceCache::create (sal_uInt32 addr, sal_uInt32 used) 519*cdf0e10cSrcweir { 520*cdf0e10cSrcweir Ace * ace = static_cast<Ace*>(rtl_cache_alloc (m_ace_cache)); 521*cdf0e10cSrcweir if (ace != 0) 522*cdf0e10cSrcweir { 523*cdf0e10cSrcweir // verify invariant state. 524*cdf0e10cSrcweir OSL_ASSERT((ace->m_next == ace) && (ace->m_prev == ace)); 525*cdf0e10cSrcweir 526*cdf0e10cSrcweir // initialize. 527*cdf0e10cSrcweir ace->m_addr = addr; 528*cdf0e10cSrcweir ace->m_used = used; 529*cdf0e10cSrcweir } 530*cdf0e10cSrcweir return ace; 531*cdf0e10cSrcweir } 532*cdf0e10cSrcweir 533*cdf0e10cSrcweir void 534*cdf0e10cSrcweir OStorePageBIOS::AceCache::destroy (OStorePageBIOS::Ace * ace) 535*cdf0e10cSrcweir { 536*cdf0e10cSrcweir if (ace != 0) 537*cdf0e10cSrcweir { 538*cdf0e10cSrcweir // remove from queue (if any). 539*cdf0e10cSrcweir ace->m_next->m_prev = ace->m_prev, ace->m_prev->m_next = ace->m_next; 540*cdf0e10cSrcweir 541*cdf0e10cSrcweir // restore invariant state. 542*cdf0e10cSrcweir ace->m_next = ace->m_prev = ace; 543*cdf0e10cSrcweir 544*cdf0e10cSrcweir // return to cache. 545*cdf0e10cSrcweir rtl_cache_free (m_ace_cache, ace); 546*cdf0e10cSrcweir } 547*cdf0e10cSrcweir } 548*cdf0e10cSrcweir 549*cdf0e10cSrcweir /*======================================================================== 550*cdf0e10cSrcweir * 551*cdf0e10cSrcweir * OStorePageBIOS implementation. 552*cdf0e10cSrcweir * 553*cdf0e10cSrcweir *======================================================================*/ 554*cdf0e10cSrcweir /* 555*cdf0e10cSrcweir * OStorePageBIOS. 556*cdf0e10cSrcweir */ 557*cdf0e10cSrcweir OStorePageBIOS::OStorePageBIOS (void) 558*cdf0e10cSrcweir : m_xLockBytes (NULL), 559*cdf0e10cSrcweir m_pSuper (NULL), 560*cdf0e10cSrcweir m_bWriteable (false) 561*cdf0e10cSrcweir { 562*cdf0e10cSrcweir } 563*cdf0e10cSrcweir 564*cdf0e10cSrcweir /* 565*cdf0e10cSrcweir * ~OStorePageBIOS. 566*cdf0e10cSrcweir */ 567*cdf0e10cSrcweir OStorePageBIOS::~OStorePageBIOS (void) 568*cdf0e10cSrcweir { 569*cdf0e10cSrcweir cleanup_Impl(); 570*cdf0e10cSrcweir } 571*cdf0e10cSrcweir 572*cdf0e10cSrcweir /* 573*cdf0e10cSrcweir * initialize. 574*cdf0e10cSrcweir * Precond: none. 575*cdf0e10cSrcweir */ 576*cdf0e10cSrcweir storeError OStorePageBIOS::initialize ( 577*cdf0e10cSrcweir ILockBytes * pLockBytes, 578*cdf0e10cSrcweir storeAccessMode eAccessMode, 579*cdf0e10cSrcweir sal_uInt16 & rnPageSize) 580*cdf0e10cSrcweir { 581*cdf0e10cSrcweir // Acquire exclusive access. 582*cdf0e10cSrcweir osl::MutexGuard aGuard (m_aMutex); 583*cdf0e10cSrcweir 584*cdf0e10cSrcweir // Initialize. 585*cdf0e10cSrcweir storeError eErrCode = initialize_Impl (pLockBytes, eAccessMode, rnPageSize); 586*cdf0e10cSrcweir if (eErrCode != store_E_None) 587*cdf0e10cSrcweir { 588*cdf0e10cSrcweir // Cleanup. 589*cdf0e10cSrcweir cleanup_Impl(); 590*cdf0e10cSrcweir } 591*cdf0e10cSrcweir return eErrCode; 592*cdf0e10cSrcweir } 593*cdf0e10cSrcweir 594*cdf0e10cSrcweir /* 595*cdf0e10cSrcweir * initialize_Impl. 596*cdf0e10cSrcweir * Internal: Precond: exclusive access. 597*cdf0e10cSrcweir */ 598*cdf0e10cSrcweir storeError OStorePageBIOS::initialize_Impl ( 599*cdf0e10cSrcweir ILockBytes * pLockBytes, 600*cdf0e10cSrcweir storeAccessMode eAccessMode, 601*cdf0e10cSrcweir sal_uInt16 & rnPageSize) 602*cdf0e10cSrcweir { 603*cdf0e10cSrcweir // Cleanup. 604*cdf0e10cSrcweir cleanup_Impl(); 605*cdf0e10cSrcweir 606*cdf0e10cSrcweir // Initialize. 607*cdf0e10cSrcweir m_xLockBytes = pLockBytes; 608*cdf0e10cSrcweir if (!m_xLockBytes.is()) 609*cdf0e10cSrcweir return store_E_InvalidParameter; 610*cdf0e10cSrcweir m_bWriteable = (eAccessMode != store_AccessReadOnly); 611*cdf0e10cSrcweir 612*cdf0e10cSrcweir // Check access mode. 613*cdf0e10cSrcweir storeError eErrCode = store_E_None; 614*cdf0e10cSrcweir if (eAccessMode != store_AccessCreate) 615*cdf0e10cSrcweir { 616*cdf0e10cSrcweir // Load SuperBlock page. 617*cdf0e10cSrcweir if ((m_pSuper = new SuperBlockPage()) == 0) 618*cdf0e10cSrcweir return store_E_OutOfMemory; 619*cdf0e10cSrcweir 620*cdf0e10cSrcweir eErrCode = read (0, m_pSuper, SuperBlockPage::theSize); 621*cdf0e10cSrcweir if (eErrCode == store_E_None) 622*cdf0e10cSrcweir { 623*cdf0e10cSrcweir // Verify SuperBlock page (with repair). 624*cdf0e10cSrcweir eErrCode = m_pSuper->verify (*this); 625*cdf0e10cSrcweir } 626*cdf0e10cSrcweir } 627*cdf0e10cSrcweir else 628*cdf0e10cSrcweir { 629*cdf0e10cSrcweir // Truncate to zero length. 630*cdf0e10cSrcweir eErrCode = m_xLockBytes->setSize(0); 631*cdf0e10cSrcweir if (eErrCode != store_E_None) 632*cdf0e10cSrcweir return eErrCode; 633*cdf0e10cSrcweir 634*cdf0e10cSrcweir // Mark as not existing. 635*cdf0e10cSrcweir eErrCode = store_E_NotExists; 636*cdf0e10cSrcweir } 637*cdf0e10cSrcweir 638*cdf0e10cSrcweir if (eErrCode != store_E_None) 639*cdf0e10cSrcweir { 640*cdf0e10cSrcweir // Check reason. 641*cdf0e10cSrcweir if (eErrCode != store_E_NotExists) 642*cdf0e10cSrcweir return eErrCode; 643*cdf0e10cSrcweir 644*cdf0e10cSrcweir // Check mode. 645*cdf0e10cSrcweir if (eAccessMode == store_AccessReadOnly) 646*cdf0e10cSrcweir return store_E_NotExists; 647*cdf0e10cSrcweir if (eAccessMode == store_AccessReadWrite) 648*cdf0e10cSrcweir return store_E_NotExists; 649*cdf0e10cSrcweir 650*cdf0e10cSrcweir // Check PageSize. 651*cdf0e10cSrcweir if ((STORE_MINIMUM_PAGESIZE > rnPageSize) || (rnPageSize > STORE_MAXIMUM_PAGESIZE)) 652*cdf0e10cSrcweir return store_E_InvalidParameter; 653*cdf0e10cSrcweir rnPageSize = ((rnPageSize + STORE_MINIMUM_PAGESIZE - 1) & ~(STORE_MINIMUM_PAGESIZE - 1)); 654*cdf0e10cSrcweir 655*cdf0e10cSrcweir // Create initial page (w/ SuperBlock). 656*cdf0e10cSrcweir if ((m_pSuper = new(rnPageSize) SuperBlockPage(rnPageSize)) == 0) 657*cdf0e10cSrcweir return store_E_OutOfMemory; 658*cdf0e10cSrcweir eErrCode = m_pSuper->save (*this, rnPageSize); 659*cdf0e10cSrcweir } 660*cdf0e10cSrcweir if (eErrCode == store_E_None) 661*cdf0e10cSrcweir { 662*cdf0e10cSrcweir // Obtain page size. 663*cdf0e10cSrcweir rnPageSize = store::ntohs(m_pSuper->m_aSuperOne.m_aDescr.m_nSize); 664*cdf0e10cSrcweir 665*cdf0e10cSrcweir // Create page allocator. 666*cdf0e10cSrcweir eErrCode = m_xLockBytes->initialize (m_xAllocator, rnPageSize); 667*cdf0e10cSrcweir if (eErrCode != store_E_None) 668*cdf0e10cSrcweir return eErrCode; 669*cdf0e10cSrcweir 670*cdf0e10cSrcweir // Create page cache. 671*cdf0e10cSrcweir eErrCode = PageCache_createInstance (m_xCache, rnPageSize); 672*cdf0e10cSrcweir } 673*cdf0e10cSrcweir return eErrCode; 674*cdf0e10cSrcweir } 675*cdf0e10cSrcweir 676*cdf0e10cSrcweir /* 677*cdf0e10cSrcweir * cleanup_Impl. 678*cdf0e10cSrcweir * Internal: Precond: exclusive access. 679*cdf0e10cSrcweir */ 680*cdf0e10cSrcweir void OStorePageBIOS::cleanup_Impl() 681*cdf0e10cSrcweir { 682*cdf0e10cSrcweir // Check referer count. 683*cdf0e10cSrcweir if (m_ace_head.m_used > 0) 684*cdf0e10cSrcweir { 685*cdf0e10cSrcweir // Report remaining referer count. 686*cdf0e10cSrcweir OSL_TRACE("store::PageBIOS::cleanup_Impl(): referer count: %d\n", m_ace_head.m_used); 687*cdf0e10cSrcweir for (Ace * ace = m_ace_head.m_next; ace != &m_ace_head; ace = m_ace_head.m_next) 688*cdf0e10cSrcweir { 689*cdf0e10cSrcweir m_ace_head.m_used -= ace->m_used; 690*cdf0e10cSrcweir AceCache::get().destroy (ace); 691*cdf0e10cSrcweir } 692*cdf0e10cSrcweir OSL_ENSURE(m_ace_head.m_used == 0, "store::PageBIOS::cleanup_Impl(): logic error"); 693*cdf0e10cSrcweir } 694*cdf0e10cSrcweir 695*cdf0e10cSrcweir // Release SuperBlock page. 696*cdf0e10cSrcweir delete m_pSuper, m_pSuper = 0; 697*cdf0e10cSrcweir 698*cdf0e10cSrcweir // Release PageCache. 699*cdf0e10cSrcweir m_xCache.clear(); 700*cdf0e10cSrcweir 701*cdf0e10cSrcweir // Release PageAllocator. 702*cdf0e10cSrcweir m_xAllocator.clear(); 703*cdf0e10cSrcweir 704*cdf0e10cSrcweir // Release LockBytes. 705*cdf0e10cSrcweir m_xLockBytes.clear(); 706*cdf0e10cSrcweir } 707*cdf0e10cSrcweir 708*cdf0e10cSrcweir /* 709*cdf0e10cSrcweir * read. 710*cdf0e10cSrcweir * Low Level: Precond: initialized, exclusive access. 711*cdf0e10cSrcweir */ 712*cdf0e10cSrcweir storeError OStorePageBIOS::read ( 713*cdf0e10cSrcweir sal_uInt32 nAddr, void *pData, sal_uInt32 nSize) 714*cdf0e10cSrcweir { 715*cdf0e10cSrcweir // Check precond. 716*cdf0e10cSrcweir if (!m_xLockBytes.is()) 717*cdf0e10cSrcweir return store_E_InvalidAccess; 718*cdf0e10cSrcweir 719*cdf0e10cSrcweir // Read Data. 720*cdf0e10cSrcweir return m_xLockBytes->readAt (nAddr, pData, nSize); 721*cdf0e10cSrcweir } 722*cdf0e10cSrcweir 723*cdf0e10cSrcweir /* 724*cdf0e10cSrcweir * write. 725*cdf0e10cSrcweir * Low Level: Precond: initialized, writeable, exclusive access. 726*cdf0e10cSrcweir */ 727*cdf0e10cSrcweir storeError OStorePageBIOS::write ( 728*cdf0e10cSrcweir sal_uInt32 nAddr, const void *pData, sal_uInt32 nSize) 729*cdf0e10cSrcweir { 730*cdf0e10cSrcweir // Check precond. 731*cdf0e10cSrcweir if (!m_xLockBytes.is()) 732*cdf0e10cSrcweir return store_E_InvalidAccess; 733*cdf0e10cSrcweir if (!m_bWriteable) 734*cdf0e10cSrcweir return store_E_AccessViolation; 735*cdf0e10cSrcweir 736*cdf0e10cSrcweir // Write Data. 737*cdf0e10cSrcweir return m_xLockBytes->writeAt (nAddr, pData, nSize); 738*cdf0e10cSrcweir } 739*cdf0e10cSrcweir 740*cdf0e10cSrcweir /* 741*cdf0e10cSrcweir * acquirePage. 742*cdf0e10cSrcweir * Precond: initialized. 743*cdf0e10cSrcweir */ 744*cdf0e10cSrcweir storeError OStorePageBIOS::acquirePage ( 745*cdf0e10cSrcweir const OStorePageDescriptor& rDescr, storeAccessMode eMode) 746*cdf0e10cSrcweir { 747*cdf0e10cSrcweir // Acquire exclusive access. 748*cdf0e10cSrcweir osl::MutexGuard aGuard (m_aMutex); 749*cdf0e10cSrcweir 750*cdf0e10cSrcweir // Check precond. 751*cdf0e10cSrcweir if (!m_xLockBytes.is()) 752*cdf0e10cSrcweir return store_E_InvalidAccess; 753*cdf0e10cSrcweir 754*cdf0e10cSrcweir // Check access mode. 755*cdf0e10cSrcweir if (!(m_bWriteable || (eMode == store_AccessReadOnly))) 756*cdf0e10cSrcweir return store_E_AccessViolation; 757*cdf0e10cSrcweir 758*cdf0e10cSrcweir // Find access control list entry. 759*cdf0e10cSrcweir Ace * ace = Ace::find (&m_ace_head, rDescr.m_nAddr); 760*cdf0e10cSrcweir if (ace->m_addr == rDescr.m_nAddr) 761*cdf0e10cSrcweir { 762*cdf0e10cSrcweir // Acquire existing entry (with ShareDenyWrite). 763*cdf0e10cSrcweir if (eMode == store_AccessReadOnly) 764*cdf0e10cSrcweir ace->m_used += 1; 765*cdf0e10cSrcweir else 766*cdf0e10cSrcweir return store_E_AccessViolation; 767*cdf0e10cSrcweir } 768*cdf0e10cSrcweir else 769*cdf0e10cSrcweir { 770*cdf0e10cSrcweir // Insert new entry. 771*cdf0e10cSrcweir Ace * entry = AceCache::get().create (rDescr.m_nAddr, 1); 772*cdf0e10cSrcweir if (!entry) 773*cdf0e10cSrcweir return store_E_OutOfMemory; 774*cdf0e10cSrcweir Ace::insert (ace, entry); 775*cdf0e10cSrcweir } 776*cdf0e10cSrcweir 777*cdf0e10cSrcweir // Increment total referer count and finish. 778*cdf0e10cSrcweir m_ace_head.m_used += 1; 779*cdf0e10cSrcweir return store_E_None; 780*cdf0e10cSrcweir } 781*cdf0e10cSrcweir 782*cdf0e10cSrcweir /* 783*cdf0e10cSrcweir * releasePage. 784*cdf0e10cSrcweir * Precond: initialized. 785*cdf0e10cSrcweir */ 786*cdf0e10cSrcweir storeError OStorePageBIOS::releasePage ( 787*cdf0e10cSrcweir const OStorePageDescriptor& rDescr, storeAccessMode /* eMode */) 788*cdf0e10cSrcweir { 789*cdf0e10cSrcweir // Acquire exclusive access. 790*cdf0e10cSrcweir osl::MutexGuard aGuard (m_aMutex); 791*cdf0e10cSrcweir 792*cdf0e10cSrcweir // Check precond. 793*cdf0e10cSrcweir if (!m_xLockBytes.is()) 794*cdf0e10cSrcweir return store_E_InvalidAccess; 795*cdf0e10cSrcweir 796*cdf0e10cSrcweir // Find access control list entry. 797*cdf0e10cSrcweir Ace * ace = Ace::find (&m_ace_head, rDescr.m_nAddr); 798*cdf0e10cSrcweir if (ace->m_addr != rDescr.m_nAddr) 799*cdf0e10cSrcweir return store_E_NotExists; 800*cdf0e10cSrcweir 801*cdf0e10cSrcweir // Release existing entry. 802*cdf0e10cSrcweir if (ace->m_used > 1) 803*cdf0e10cSrcweir ace->m_used -= 1; 804*cdf0e10cSrcweir else 805*cdf0e10cSrcweir AceCache::get().destroy (ace); 806*cdf0e10cSrcweir 807*cdf0e10cSrcweir // Decrement total referer count and finish. 808*cdf0e10cSrcweir m_ace_head.m_used -= 1; 809*cdf0e10cSrcweir return store_E_None; 810*cdf0e10cSrcweir } 811*cdf0e10cSrcweir 812*cdf0e10cSrcweir /* 813*cdf0e10cSrcweir * getRefererCount. 814*cdf0e10cSrcweir * Precond: none. 815*cdf0e10cSrcweir */ 816*cdf0e10cSrcweir sal_uInt32 OStorePageBIOS::getRefererCount (void) 817*cdf0e10cSrcweir { 818*cdf0e10cSrcweir // Acquire exclusive access. 819*cdf0e10cSrcweir osl::MutexGuard aGuard (m_aMutex); 820*cdf0e10cSrcweir 821*cdf0e10cSrcweir // Obtain total referer count. 822*cdf0e10cSrcweir return m_ace_head.m_used; 823*cdf0e10cSrcweir } 824*cdf0e10cSrcweir 825*cdf0e10cSrcweir /* 826*cdf0e10cSrcweir * allocate. 827*cdf0e10cSrcweir * Precond: initialized, writeable. 828*cdf0e10cSrcweir */ 829*cdf0e10cSrcweir storeError OStorePageBIOS::allocate ( 830*cdf0e10cSrcweir OStorePageObject& rPage, Allocation eAlloc) 831*cdf0e10cSrcweir { 832*cdf0e10cSrcweir // Acquire exclusive access. 833*cdf0e10cSrcweir osl::MutexGuard aGuard (m_aMutex); 834*cdf0e10cSrcweir 835*cdf0e10cSrcweir // Check precond. 836*cdf0e10cSrcweir if (!m_xLockBytes.is()) 837*cdf0e10cSrcweir return store_E_InvalidAccess; 838*cdf0e10cSrcweir if (!m_bWriteable) 839*cdf0e10cSrcweir return store_E_AccessViolation; 840*cdf0e10cSrcweir 841*cdf0e10cSrcweir // Check allocation type. 842*cdf0e10cSrcweir storeError eErrCode = store_E_None; 843*cdf0e10cSrcweir if (eAlloc != ALLOCATE_EOF) 844*cdf0e10cSrcweir { 845*cdf0e10cSrcweir // Try freelist head. 846*cdf0e10cSrcweir PageData aPageHead; 847*cdf0e10cSrcweir eErrCode = m_pSuper->unusedHead (*this, aPageHead); 848*cdf0e10cSrcweir if (eErrCode != store_E_None) 849*cdf0e10cSrcweir return eErrCode; 850*cdf0e10cSrcweir 851*cdf0e10cSrcweir sal_uInt32 const nAddr = aPageHead.location(); 852*cdf0e10cSrcweir if (nAddr != STORE_PAGE_NULL) 853*cdf0e10cSrcweir { 854*cdf0e10cSrcweir // Save page. 855*cdf0e10cSrcweir eErrCode = saveObjectAt_Impl (rPage, nAddr); 856*cdf0e10cSrcweir if (eErrCode != store_E_None) 857*cdf0e10cSrcweir return eErrCode; 858*cdf0e10cSrcweir 859*cdf0e10cSrcweir // Pop freelist head and finish. 860*cdf0e10cSrcweir return m_pSuper->unusedPop (*this, aPageHead); 861*cdf0e10cSrcweir } 862*cdf0e10cSrcweir } 863*cdf0e10cSrcweir 864*cdf0e10cSrcweir // Allocate from EOF. Determine current size. 865*cdf0e10cSrcweir sal_uInt32 nSize = STORE_PAGE_NULL; 866*cdf0e10cSrcweir eErrCode = m_xLockBytes->getSize (nSize); 867*cdf0e10cSrcweir if (eErrCode != store_E_None) 868*cdf0e10cSrcweir return eErrCode; 869*cdf0e10cSrcweir 870*cdf0e10cSrcweir // Save page at current EOF. 871*cdf0e10cSrcweir return saveObjectAt_Impl (rPage, nSize); 872*cdf0e10cSrcweir } 873*cdf0e10cSrcweir 874*cdf0e10cSrcweir /* 875*cdf0e10cSrcweir * free. 876*cdf0e10cSrcweir * Precond: initialized, writeable. 877*cdf0e10cSrcweir */ 878*cdf0e10cSrcweir storeError OStorePageBIOS::free (sal_uInt32 nAddr) 879*cdf0e10cSrcweir { 880*cdf0e10cSrcweir // Acquire exclusive access. 881*cdf0e10cSrcweir osl::MutexGuard aGuard (m_aMutex); 882*cdf0e10cSrcweir 883*cdf0e10cSrcweir // Check precond. 884*cdf0e10cSrcweir if (!m_xLockBytes.is()) 885*cdf0e10cSrcweir return store_E_InvalidAccess; 886*cdf0e10cSrcweir if (!m_bWriteable) 887*cdf0e10cSrcweir return store_E_AccessViolation; 888*cdf0e10cSrcweir 889*cdf0e10cSrcweir // Invalidate cache. 890*cdf0e10cSrcweir (void) m_xCache->removePageAt (nAddr); 891*cdf0e10cSrcweir 892*cdf0e10cSrcweir // Push onto freelist. 893*cdf0e10cSrcweir return m_pSuper->unusedPush (*this, nAddr); 894*cdf0e10cSrcweir } 895*cdf0e10cSrcweir 896*cdf0e10cSrcweir /* 897*cdf0e10cSrcweir * loadObjectAt. 898*cdf0e10cSrcweir * Precond: initialized, readable. 899*cdf0e10cSrcweir */ 900*cdf0e10cSrcweir storeError OStorePageBIOS::loadObjectAt (OStorePageObject & rPage, sal_uInt32 nAddr) 901*cdf0e10cSrcweir { 902*cdf0e10cSrcweir // Acquire exclusive access. 903*cdf0e10cSrcweir osl::MutexGuard aGuard (m_aMutex); 904*cdf0e10cSrcweir 905*cdf0e10cSrcweir // Check precond. 906*cdf0e10cSrcweir if (!m_xLockBytes.is()) 907*cdf0e10cSrcweir return store_E_InvalidAccess; 908*cdf0e10cSrcweir 909*cdf0e10cSrcweir return loadObjectAt_Impl (rPage, nAddr); 910*cdf0e10cSrcweir } 911*cdf0e10cSrcweir 912*cdf0e10cSrcweir /* 913*cdf0e10cSrcweir * loadObjectAt_Impl. 914*cdf0e10cSrcweir * Internal: Precond: initialized, readable, exclusive access. 915*cdf0e10cSrcweir */ 916*cdf0e10cSrcweir storeError OStorePageBIOS::loadObjectAt_Impl (OStorePageObject & rPage, sal_uInt32 nAddr) 917*cdf0e10cSrcweir { 918*cdf0e10cSrcweir storeError eErrCode = m_xCache->lookupPageAt (rPage.get(), nAddr); 919*cdf0e10cSrcweir if (eErrCode != store_E_NotExists) 920*cdf0e10cSrcweir return eErrCode; 921*cdf0e10cSrcweir 922*cdf0e10cSrcweir // Read page. 923*cdf0e10cSrcweir eErrCode = m_xLockBytes->readPageAt (rPage.get(), nAddr); 924*cdf0e10cSrcweir if (eErrCode != store_E_None) 925*cdf0e10cSrcweir return eErrCode; 926*cdf0e10cSrcweir 927*cdf0e10cSrcweir // Verify page. 928*cdf0e10cSrcweir eErrCode = rPage.verify (nAddr); 929*cdf0e10cSrcweir if (eErrCode != store_E_None) 930*cdf0e10cSrcweir return eErrCode; 931*cdf0e10cSrcweir 932*cdf0e10cSrcweir // Mark page as clean. 933*cdf0e10cSrcweir rPage.clean(); 934*cdf0e10cSrcweir 935*cdf0e10cSrcweir // Cache page. 936*cdf0e10cSrcweir return m_xCache->insertPageAt (rPage.get(), nAddr); 937*cdf0e10cSrcweir } 938*cdf0e10cSrcweir 939*cdf0e10cSrcweir /* 940*cdf0e10cSrcweir * saveObjectAt. 941*cdf0e10cSrcweir * Precond: initialized, writeable. 942*cdf0e10cSrcweir */ 943*cdf0e10cSrcweir storeError OStorePageBIOS::saveObjectAt (OStorePageObject & rPage, sal_uInt32 nAddr) 944*cdf0e10cSrcweir { 945*cdf0e10cSrcweir // Acquire exclusive access. 946*cdf0e10cSrcweir osl::MutexGuard aGuard (m_aMutex); 947*cdf0e10cSrcweir 948*cdf0e10cSrcweir // Check precond. 949*cdf0e10cSrcweir if (!m_xLockBytes.is()) 950*cdf0e10cSrcweir return store_E_InvalidAccess; 951*cdf0e10cSrcweir if (!m_bWriteable) 952*cdf0e10cSrcweir return store_E_AccessViolation; 953*cdf0e10cSrcweir 954*cdf0e10cSrcweir // Save Page. 955*cdf0e10cSrcweir return saveObjectAt_Impl (rPage, nAddr); 956*cdf0e10cSrcweir } 957*cdf0e10cSrcweir 958*cdf0e10cSrcweir /* 959*cdf0e10cSrcweir * saveObjectAt_Impl. 960*cdf0e10cSrcweir * Internal: Precond: initialized, writeable, exclusive access. 961*cdf0e10cSrcweir */ 962*cdf0e10cSrcweir storeError OStorePageBIOS::saveObjectAt_Impl (OStorePageObject & rPage, sal_uInt32 nAddr) 963*cdf0e10cSrcweir { 964*cdf0e10cSrcweir // Guard page (incl. set location). 965*cdf0e10cSrcweir storeError eErrCode = rPage.guard (nAddr); 966*cdf0e10cSrcweir if (eErrCode != store_E_None) 967*cdf0e10cSrcweir return eErrCode; 968*cdf0e10cSrcweir 969*cdf0e10cSrcweir // Write page. 970*cdf0e10cSrcweir eErrCode = m_xLockBytes->writePageAt(rPage.get(), nAddr); 971*cdf0e10cSrcweir if (eErrCode != store_E_None) 972*cdf0e10cSrcweir return eErrCode; 973*cdf0e10cSrcweir 974*cdf0e10cSrcweir // Mark page as clean. 975*cdf0e10cSrcweir rPage.clean(); 976*cdf0e10cSrcweir 977*cdf0e10cSrcweir // Cache page. 978*cdf0e10cSrcweir return m_xCache->updatePageAt (rPage.get(), nAddr); 979*cdf0e10cSrcweir } 980*cdf0e10cSrcweir 981*cdf0e10cSrcweir /* 982*cdf0e10cSrcweir * close. 983*cdf0e10cSrcweir * Precond: none. 984*cdf0e10cSrcweir */ 985*cdf0e10cSrcweir storeError OStorePageBIOS::close() 986*cdf0e10cSrcweir { 987*cdf0e10cSrcweir // Acquire exclusive access. 988*cdf0e10cSrcweir osl::MutexGuard aGuard (m_aMutex); 989*cdf0e10cSrcweir 990*cdf0e10cSrcweir // Cleanup. 991*cdf0e10cSrcweir cleanup_Impl(); 992*cdf0e10cSrcweir 993*cdf0e10cSrcweir // Done. 994*cdf0e10cSrcweir return store_E_None; 995*cdf0e10cSrcweir } 996*cdf0e10cSrcweir 997*cdf0e10cSrcweir /* 998*cdf0e10cSrcweir * flush. 999*cdf0e10cSrcweir * Precond: initialized. 1000*cdf0e10cSrcweir */ 1001*cdf0e10cSrcweir storeError OStorePageBIOS::flush (void) 1002*cdf0e10cSrcweir { 1003*cdf0e10cSrcweir // Acquire exclusive access. 1004*cdf0e10cSrcweir osl::MutexGuard aGuard (m_aMutex); 1005*cdf0e10cSrcweir 1006*cdf0e10cSrcweir // Check precond. 1007*cdf0e10cSrcweir if (!m_xLockBytes.is()) 1008*cdf0e10cSrcweir return store_E_InvalidAccess; 1009*cdf0e10cSrcweir 1010*cdf0e10cSrcweir // Flush LockBytes and finish. 1011*cdf0e10cSrcweir return m_xLockBytes->flush(); 1012*cdf0e10cSrcweir } 1013*cdf0e10cSrcweir 1014*cdf0e10cSrcweir /* 1015*cdf0e10cSrcweir * size. 1016*cdf0e10cSrcweir * Precond: initialized. 1017*cdf0e10cSrcweir */ 1018*cdf0e10cSrcweir storeError OStorePageBIOS::size (sal_uInt32 &rnSize) 1019*cdf0e10cSrcweir { 1020*cdf0e10cSrcweir // Acquire exclusive access. 1021*cdf0e10cSrcweir osl::MutexGuard aGuard (m_aMutex); 1022*cdf0e10cSrcweir 1023*cdf0e10cSrcweir // Initialize [out] param. 1024*cdf0e10cSrcweir rnSize = 0; 1025*cdf0e10cSrcweir 1026*cdf0e10cSrcweir // Check precond. 1027*cdf0e10cSrcweir if (!m_xLockBytes.is()) 1028*cdf0e10cSrcweir return store_E_InvalidAccess; 1029*cdf0e10cSrcweir 1030*cdf0e10cSrcweir // Obtain LockBytes size. 1031*cdf0e10cSrcweir return m_xLockBytes->getSize (rnSize); 1032*cdf0e10cSrcweir } 1033*cdf0e10cSrcweir 1034*cdf0e10cSrcweir /* 1035*cdf0e10cSrcweir * scanBegin. 1036*cdf0e10cSrcweir * Precond: initialized. 1037*cdf0e10cSrcweir */ 1038*cdf0e10cSrcweir storeError OStorePageBIOS::scanBegin ( 1039*cdf0e10cSrcweir ScanContext &rCtx, sal_uInt32 nMagic) 1040*cdf0e10cSrcweir { 1041*cdf0e10cSrcweir // Acquire exclusive access. 1042*cdf0e10cSrcweir osl::MutexGuard aGuard (m_aMutex); 1043*cdf0e10cSrcweir 1044*cdf0e10cSrcweir // Initialize [out] param. 1045*cdf0e10cSrcweir rCtx.m_aDescr = OStorePageDescriptor(0, 0, 0); 1046*cdf0e10cSrcweir rCtx.m_nSize = 0; 1047*cdf0e10cSrcweir rCtx.m_nMagic = nMagic; 1048*cdf0e10cSrcweir 1049*cdf0e10cSrcweir // Check precond. 1050*cdf0e10cSrcweir if (!m_xLockBytes.is()) 1051*cdf0e10cSrcweir return store_E_InvalidAccess; 1052*cdf0e10cSrcweir 1053*cdf0e10cSrcweir // Check SuperBlock page. 1054*cdf0e10cSrcweir storeError eErrCode = m_pSuper->verify (*this); 1055*cdf0e10cSrcweir if (eErrCode != store_E_None) 1056*cdf0e10cSrcweir { 1057*cdf0e10cSrcweir // Damaged. Determine page size (NYI). 1058*cdf0e10cSrcweir OSL_TRACE ("OStorePageBIOS::scanBegin(): damaged.\n"); 1059*cdf0e10cSrcweir return eErrCode; 1060*cdf0e10cSrcweir } 1061*cdf0e10cSrcweir 1062*cdf0e10cSrcweir // Setup Context descriptor. 1063*cdf0e10cSrcweir rCtx.m_aDescr = m_pSuper->m_aSuperOne.m_aDescr; 1064*cdf0e10cSrcweir rCtx.m_aDescr.m_nSize = store::ntohs(rCtx.m_aDescr.m_nSize); 1065*cdf0e10cSrcweir rCtx.m_aDescr.m_nAddr = rCtx.m_aDescr.m_nSize; 1066*cdf0e10cSrcweir 1067*cdf0e10cSrcweir // Setup Context size. 1068*cdf0e10cSrcweir eErrCode = size (rCtx.m_nSize); 1069*cdf0e10cSrcweir if (eErrCode != store_E_None) 1070*cdf0e10cSrcweir rCtx.m_nSize = ((sal_uInt32)(~0)); 1071*cdf0e10cSrcweir 1072*cdf0e10cSrcweir // Done. 1073*cdf0e10cSrcweir return store_E_None; 1074*cdf0e10cSrcweir } 1075*cdf0e10cSrcweir 1076*cdf0e10cSrcweir /* 1077*cdf0e10cSrcweir * scanNext. 1078*cdf0e10cSrcweir * Precond: initialized. 1079*cdf0e10cSrcweir */ 1080*cdf0e10cSrcweir storeError OStorePageBIOS::scanNext ( 1081*cdf0e10cSrcweir ScanContext &rCtx, OStorePageObject &rPage) 1082*cdf0e10cSrcweir { 1083*cdf0e10cSrcweir // Acquire exclusive access. 1084*cdf0e10cSrcweir osl::MutexGuard aGuard (m_aMutex); 1085*cdf0e10cSrcweir 1086*cdf0e10cSrcweir // Check precond. 1087*cdf0e10cSrcweir if (!m_xLockBytes.is()) 1088*cdf0e10cSrcweir return store_E_InvalidAccess; 1089*cdf0e10cSrcweir 1090*cdf0e10cSrcweir // Setup PageHead. 1091*cdf0e10cSrcweir PageData aPageHead; 1092*cdf0e10cSrcweir 1093*cdf0e10cSrcweir // Check context. 1094*cdf0e10cSrcweir while (rCtx.isValid()) 1095*cdf0e10cSrcweir { 1096*cdf0e10cSrcweir // Assign next location. 1097*cdf0e10cSrcweir sal_uInt32 nAddr = rCtx.m_aDescr.m_nAddr; 1098*cdf0e10cSrcweir rCtx.m_aDescr.m_nAddr += rCtx.m_aDescr.m_nSize; 1099*cdf0e10cSrcweir 1100*cdf0e10cSrcweir // Read PageHead. 1101*cdf0e10cSrcweir storeError eErrCode = read (nAddr, &aPageHead, PageData::theSize); 1102*cdf0e10cSrcweir if (eErrCode != store_E_None) 1103*cdf0e10cSrcweir continue; 1104*cdf0e10cSrcweir 1105*cdf0e10cSrcweir // Verify PageHead. 1106*cdf0e10cSrcweir eErrCode = aPageHead.verify (nAddr); 1107*cdf0e10cSrcweir if (eErrCode != store_E_None) 1108*cdf0e10cSrcweir continue; 1109*cdf0e10cSrcweir 1110*cdf0e10cSrcweir // Check PageHead Magic number. 1111*cdf0e10cSrcweir if (aPageHead.m_aGuard.m_nMagic != rCtx.m_nMagic) 1112*cdf0e10cSrcweir continue; 1113*cdf0e10cSrcweir 1114*cdf0e10cSrcweir // Check PageHead Unused link. 1115*cdf0e10cSrcweir if (aPageHead.m_aUnused.m_nAddr != STORE_PAGE_NULL) 1116*cdf0e10cSrcweir continue; 1117*cdf0e10cSrcweir 1118*cdf0e10cSrcweir // Load page. 1119*cdf0e10cSrcweir eErrCode = loadObjectAt_Impl (rPage, nAddr); 1120*cdf0e10cSrcweir if (eErrCode != store_E_None) 1121*cdf0e10cSrcweir continue; 1122*cdf0e10cSrcweir 1123*cdf0e10cSrcweir // Deliver page. 1124*cdf0e10cSrcweir return store_E_None; 1125*cdf0e10cSrcweir } 1126*cdf0e10cSrcweir 1127*cdf0e10cSrcweir // Done. 1128*cdf0e10cSrcweir return store_E_CantSeek; 1129*cdf0e10cSrcweir } 1130