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 "storpage.hxx" 32*cdf0e10cSrcweir 33*cdf0e10cSrcweir #include "sal/types.h" 34*cdf0e10cSrcweir #include "rtl/string.h" 35*cdf0e10cSrcweir #include "rtl/ref.hxx" 36*cdf0e10cSrcweir #include "osl/diagnose.h" 37*cdf0e10cSrcweir #include "osl/mutex.hxx" 38*cdf0e10cSrcweir 39*cdf0e10cSrcweir #include "store/types.h" 40*cdf0e10cSrcweir 41*cdf0e10cSrcweir #include "object.hxx" 42*cdf0e10cSrcweir #include "lockbyte.hxx" 43*cdf0e10cSrcweir 44*cdf0e10cSrcweir #include "storbase.hxx" 45*cdf0e10cSrcweir #include "stordata.hxx" 46*cdf0e10cSrcweir #include "stortree.hxx" 47*cdf0e10cSrcweir 48*cdf0e10cSrcweir using namespace store; 49*cdf0e10cSrcweir 50*cdf0e10cSrcweir /*======================================================================== 51*cdf0e10cSrcweir * 52*cdf0e10cSrcweir * OStorePageManager implementation. 53*cdf0e10cSrcweir * 54*cdf0e10cSrcweir *======================================================================*/ 55*cdf0e10cSrcweir const sal_uInt32 OStorePageManager::m_nTypeId = sal_uInt32(0x62190120); 56*cdf0e10cSrcweir 57*cdf0e10cSrcweir /* 58*cdf0e10cSrcweir * OStorePageManager. 59*cdf0e10cSrcweir */ 60*cdf0e10cSrcweir OStorePageManager::OStorePageManager (void) 61*cdf0e10cSrcweir { 62*cdf0e10cSrcweir } 63*cdf0e10cSrcweir 64*cdf0e10cSrcweir /* 65*cdf0e10cSrcweir * ~OStorePageManager. 66*cdf0e10cSrcweir */ 67*cdf0e10cSrcweir OStorePageManager::~OStorePageManager (void) 68*cdf0e10cSrcweir { 69*cdf0e10cSrcweir } 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir /* 72*cdf0e10cSrcweir * isKindOf. 73*cdf0e10cSrcweir */ 74*cdf0e10cSrcweir sal_Bool SAL_CALL OStorePageManager::isKindOf (sal_uInt32 nTypeId) 75*cdf0e10cSrcweir { 76*cdf0e10cSrcweir return (nTypeId == m_nTypeId); 77*cdf0e10cSrcweir } 78*cdf0e10cSrcweir 79*cdf0e10cSrcweir /* 80*cdf0e10cSrcweir * initialize (two-phase construction). 81*cdf0e10cSrcweir * Precond: none. 82*cdf0e10cSrcweir */ 83*cdf0e10cSrcweir storeError OStorePageManager::initialize ( 84*cdf0e10cSrcweir ILockBytes * pLockBytes, 85*cdf0e10cSrcweir storeAccessMode eAccessMode, 86*cdf0e10cSrcweir sal_uInt16 & rnPageSize) 87*cdf0e10cSrcweir { 88*cdf0e10cSrcweir // Acquire exclusive access. 89*cdf0e10cSrcweir osl::MutexGuard aGuard(*this); 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir // Check arguments. 92*cdf0e10cSrcweir if (!pLockBytes) 93*cdf0e10cSrcweir return store_E_InvalidParameter; 94*cdf0e10cSrcweir 95*cdf0e10cSrcweir // Initialize base. 96*cdf0e10cSrcweir storeError eErrCode = base::initialize (pLockBytes, eAccessMode, rnPageSize); 97*cdf0e10cSrcweir if (eErrCode != store_E_None) 98*cdf0e10cSrcweir return eErrCode; 99*cdf0e10cSrcweir 100*cdf0e10cSrcweir // Check for (not) writeable. 101*cdf0e10cSrcweir if (!base::isWriteable()) 102*cdf0e10cSrcweir { 103*cdf0e10cSrcweir // Readonly. Load RootNode. 104*cdf0e10cSrcweir return base::loadObjectAt (m_aRoot, rnPageSize); 105*cdf0e10cSrcweir } 106*cdf0e10cSrcweir 107*cdf0e10cSrcweir // Writeable. Load or Create RootNode. 108*cdf0e10cSrcweir eErrCode = m_aRoot.loadOrCreate (rnPageSize, *this); 109*cdf0e10cSrcweir if (eErrCode == store_E_Pending) 110*cdf0e10cSrcweir { 111*cdf0e10cSrcweir // Creation notification. 112*cdf0e10cSrcweir PageHolderObject< page > xRoot (m_aRoot.get()); 113*cdf0e10cSrcweir 114*cdf0e10cSrcweir // Pre-allocate left most entry (ugly, but we can't insert to left). 115*cdf0e10cSrcweir OStorePageKey aKey (rtl_crc32 (0, "/", 1), 0); 116*cdf0e10cSrcweir xRoot->insert (0, entry(aKey)); 117*cdf0e10cSrcweir 118*cdf0e10cSrcweir // Save RootNode. 119*cdf0e10cSrcweir eErrCode = base::saveObjectAt (m_aRoot, rnPageSize); 120*cdf0e10cSrcweir } 121*cdf0e10cSrcweir 122*cdf0e10cSrcweir // Done. 123*cdf0e10cSrcweir return eErrCode; 124*cdf0e10cSrcweir } 125*cdf0e10cSrcweir 126*cdf0e10cSrcweir /* 127*cdf0e10cSrcweir * find_lookup (w/o split()). 128*cdf0e10cSrcweir * Internal: Precond: initialized, readable, exclusive access. 129*cdf0e10cSrcweir */ 130*cdf0e10cSrcweir storeError OStorePageManager::find_lookup ( 131*cdf0e10cSrcweir OStoreBTreeNodeObject & rNode, 132*cdf0e10cSrcweir sal_uInt16 & rIndex, 133*cdf0e10cSrcweir OStorePageKey const & rKey) 134*cdf0e10cSrcweir { 135*cdf0e10cSrcweir // Find Node and Index. 136*cdf0e10cSrcweir storeError eErrCode = m_aRoot.find_lookup (rNode, rIndex, rKey, *this); 137*cdf0e10cSrcweir if (eErrCode != store_E_None) 138*cdf0e10cSrcweir return eErrCode; 139*cdf0e10cSrcweir 140*cdf0e10cSrcweir // Greater or Equal. 141*cdf0e10cSrcweir PageHolderObject< page > xPage (rNode.get()); 142*cdf0e10cSrcweir OSL_POSTCOND(rIndex < xPage->usageCount(), "store::PageManager::find_lookup(): logic error"); 143*cdf0e10cSrcweir entry e (xPage->m_pData[rIndex]); 144*cdf0e10cSrcweir 145*cdf0e10cSrcweir // Check for exact match. 146*cdf0e10cSrcweir if (e.compare(entry(rKey)) != entry::COMPARE_EQUAL) 147*cdf0e10cSrcweir { 148*cdf0e10cSrcweir // Page not present. 149*cdf0e10cSrcweir return store_E_NotExists; 150*cdf0e10cSrcweir } 151*cdf0e10cSrcweir 152*cdf0e10cSrcweir // Check address. 153*cdf0e10cSrcweir if (e.m_aLink.location() == STORE_PAGE_NULL) 154*cdf0e10cSrcweir { 155*cdf0e10cSrcweir // Page not present. 156*cdf0e10cSrcweir return store_E_NotExists; 157*cdf0e10cSrcweir } 158*cdf0e10cSrcweir 159*cdf0e10cSrcweir return store_E_None; 160*cdf0e10cSrcweir } 161*cdf0e10cSrcweir 162*cdf0e10cSrcweir /* 163*cdf0e10cSrcweir * remove_Impl (possibly down from root). 164*cdf0e10cSrcweir * Internal: Precond: initialized, writeable, exclusive access. 165*cdf0e10cSrcweir */ 166*cdf0e10cSrcweir #if 0 /* EXP */ 167*cdf0e10cSrcweir storeError OStorePageManager::remove_Impl (entry & rEntry) 168*cdf0e10cSrcweir { 169*cdf0e10cSrcweir // Find Node and Index. 170*cdf0e10cSrcweir OStoreBTreeNodeObject aNode; 171*cdf0e10cSrcweir sal_uInt16 nIndex = 0; 172*cdf0e10cSrcweir eErrCode = m_aRoot.find_lookup (aNode, nIndex, entry::CompareGreater(rEntry), *this); 173*cdf0e10cSrcweir 174*cdf0e10cSrcweir // @@@ 175*cdf0e10cSrcweir 176*cdf0e10cSrcweir PageHolderObject< page > xPage (aNode.get()); 177*cdf0e10cSrcweir page & rPage = (*xPage); 178*cdf0e10cSrcweir 179*cdf0e10cSrcweir // Check current page index. 180*cdf0e10cSrcweir sal_uInt16 i = rPage.find (rEntry), n = rPage.usageCount(); 181*cdf0e10cSrcweir if (!(i < n)) 182*cdf0e10cSrcweir { 183*cdf0e10cSrcweir // Path to entry not exists (Must not happen(?)). 184*cdf0e10cSrcweir return store_E_NotExists; 185*cdf0e10cSrcweir } 186*cdf0e10cSrcweir 187*cdf0e10cSrcweir // Compare entry. 188*cdf0e10cSrcweir entry::CompareResult result = rEntry.compare (rPage.m_pData[i]); 189*cdf0e10cSrcweir 190*cdf0e10cSrcweir for (; result == entry::COMPARE_GREATER && xPage->depth() > 0; ) 191*cdf0e10cSrcweir { 192*cdf0e10cSrcweir // Check next node address. 193*cdf0e10cSrcweir sal_uInt32 const nAddr = rPage.m_pData[i].m_aLink.location(); 194*cdf0e10cSrcweir if (nAddr == STORE_PAGE_NULL) 195*cdf0e10cSrcweir { 196*cdf0e10cSrcweir // Path to entry not exists (Must not happen(?)). 197*cdf0e10cSrcweir return store_E_NotExists; 198*cdf0e10cSrcweir } 199*cdf0e10cSrcweir 200*cdf0e10cSrcweir // Load next node page. 201*cdf0e10cSrcweir eErrCode = loadObjectAt (aNode, nAddr); 202*cdf0e10cSrcweir 203*cdf0e10cSrcweir PageHolderObject< page > xNext (aNode.get()); 204*cdf0e10cSrcweir xNext.swap (xPage); 205*cdf0e10cSrcweir } 206*cdf0e10cSrcweir 207*cdf0e10cSrcweir aNode.remove (nIndex, rEntry, *this); 208*cdf0e10cSrcweir 209*cdf0e10cSrcweir 210*cdf0e10cSrcweir do 211*cdf0e10cSrcweir { 212*cdf0e10cSrcweir // Load next node page. 213*cdf0e10cSrcweir eErrCode = loadObjectAt (aNode, nAddr); 214*cdf0e10cSrcweir 215*cdf0e10cSrcweir page const & rPage = (*xPage); 216*cdf0e10cSrcweir 217*cdf0e10cSrcweir // Check current page index. 218*cdf0e10cSrcweir sal_uInt16 i = rPage.find (rEntry), n = rPage.usageCount(); 219*cdf0e10cSrcweir if (!(i < n)) 220*cdf0e10cSrcweir { 221*cdf0e10cSrcweir // Path to entry not exists (Must not happen(?)). 222*cdf0e10cSrcweir return store_E_NotExists; 223*cdf0e10cSrcweir } 224*cdf0e10cSrcweir 225*cdf0e10cSrcweir // Compare entry. 226*cdf0e10cSrcweir result = rEntry.compare (rPage.m_pData[i]); 227*cdf0e10cSrcweir 228*cdf0e10cSrcweir } while (result == entry::COMPATE_GREATER); 229*cdf0e10cSrcweir } 230*cdf0e10cSrcweir #endif /* EXP */ 231*cdf0e10cSrcweir 232*cdf0e10cSrcweir storeError OStorePageManager::remove_Impl (entry & rEntry) 233*cdf0e10cSrcweir { 234*cdf0e10cSrcweir OStoreBTreeNodeObject aNode (m_aRoot.get()); 235*cdf0e10cSrcweir 236*cdf0e10cSrcweir // Check current page index. 237*cdf0e10cSrcweir PageHolderObject< page > xPage (aNode.get()); 238*cdf0e10cSrcweir sal_uInt16 i = xPage->find (rEntry), n = xPage->usageCount(); 239*cdf0e10cSrcweir if (!(i < n)) 240*cdf0e10cSrcweir { 241*cdf0e10cSrcweir // Path to entry not exists (Must not happen(?)). 242*cdf0e10cSrcweir return store_E_NotExists; 243*cdf0e10cSrcweir } 244*cdf0e10cSrcweir 245*cdf0e10cSrcweir // Compare entry. 246*cdf0e10cSrcweir entry::CompareResult result = rEntry.compare (xPage->m_pData[i]); 247*cdf0e10cSrcweir 248*cdf0e10cSrcweir // Iterate down until equal match. 249*cdf0e10cSrcweir while ((result == entry::COMPARE_GREATER) && (xPage->depth() > 0)) 250*cdf0e10cSrcweir { 251*cdf0e10cSrcweir // Check link address. 252*cdf0e10cSrcweir sal_uInt32 const nAddr = xPage->m_pData[i].m_aLink.location(); 253*cdf0e10cSrcweir if (nAddr == STORE_PAGE_NULL) 254*cdf0e10cSrcweir { 255*cdf0e10cSrcweir // Path to entry not exists (Must not happen(?)). 256*cdf0e10cSrcweir return store_E_NotExists; 257*cdf0e10cSrcweir } 258*cdf0e10cSrcweir 259*cdf0e10cSrcweir // Load link page. 260*cdf0e10cSrcweir storeError eErrCode = loadObjectAt (aNode, nAddr); 261*cdf0e10cSrcweir if (eErrCode != store_E_None) 262*cdf0e10cSrcweir return eErrCode; 263*cdf0e10cSrcweir 264*cdf0e10cSrcweir PageHolderObject< page > xNext (aNode.get()); 265*cdf0e10cSrcweir xNext.swap (xPage); 266*cdf0e10cSrcweir 267*cdf0e10cSrcweir // Check index. 268*cdf0e10cSrcweir i = xPage->find (rEntry), n = xPage->usageCount(); 269*cdf0e10cSrcweir if (!(i < n)) 270*cdf0e10cSrcweir { 271*cdf0e10cSrcweir // Path to entry not exists (Must not happen(?)). 272*cdf0e10cSrcweir return store_E_NotExists; 273*cdf0e10cSrcweir } 274*cdf0e10cSrcweir 275*cdf0e10cSrcweir // Compare entry. 276*cdf0e10cSrcweir result = rEntry.compare (xPage->m_pData[i]); 277*cdf0e10cSrcweir } 278*cdf0e10cSrcweir 279*cdf0e10cSrcweir OSL_POSTCOND( 280*cdf0e10cSrcweir result != entry::COMPARE_LESS, 281*cdf0e10cSrcweir "OStorePageManager::remove(): find failed"); 282*cdf0e10cSrcweir 283*cdf0e10cSrcweir // Check entry comparison. 284*cdf0e10cSrcweir if (result == entry::COMPARE_LESS) 285*cdf0e10cSrcweir { 286*cdf0e10cSrcweir // Must not happen. 287*cdf0e10cSrcweir return store_E_Unknown; 288*cdf0e10cSrcweir } 289*cdf0e10cSrcweir 290*cdf0e10cSrcweir // Remove down from current page (recursive). 291*cdf0e10cSrcweir return aNode.remove (i, rEntry, *this); 292*cdf0e10cSrcweir } 293*cdf0e10cSrcweir 294*cdf0e10cSrcweir /* 295*cdf0e10cSrcweir * namei. 296*cdf0e10cSrcweir * Precond: none (static). 297*cdf0e10cSrcweir */ 298*cdf0e10cSrcweir storeError OStorePageManager::namei ( 299*cdf0e10cSrcweir const rtl_String *pPath, const rtl_String *pName, OStorePageKey &rKey) 300*cdf0e10cSrcweir { 301*cdf0e10cSrcweir // Check parameter. 302*cdf0e10cSrcweir if (!(pPath && pName)) 303*cdf0e10cSrcweir return store_E_InvalidParameter; 304*cdf0e10cSrcweir 305*cdf0e10cSrcweir // Check name length. 306*cdf0e10cSrcweir if (!(pName->length < STORE_MAXIMUM_NAMESIZE)) 307*cdf0e10cSrcweir return store_E_NameTooLong; 308*cdf0e10cSrcweir 309*cdf0e10cSrcweir // Transform pathname into key. 310*cdf0e10cSrcweir rKey.m_nLow = store::htonl(rtl_crc32 (0, pName->buffer, pName->length)); 311*cdf0e10cSrcweir rKey.m_nHigh = store::htonl(rtl_crc32 (0, pPath->buffer, pPath->length)); 312*cdf0e10cSrcweir 313*cdf0e10cSrcweir // Done. 314*cdf0e10cSrcweir return store_E_None; 315*cdf0e10cSrcweir } 316*cdf0e10cSrcweir 317*cdf0e10cSrcweir /* 318*cdf0e10cSrcweir * iget. 319*cdf0e10cSrcweir * Precond: initialized. 320*cdf0e10cSrcweir */ 321*cdf0e10cSrcweir storeError OStorePageManager::iget ( 322*cdf0e10cSrcweir OStoreDirectoryPageObject & rPage, 323*cdf0e10cSrcweir sal_uInt32 nAttrib, 324*cdf0e10cSrcweir const rtl_String * pPath, 325*cdf0e10cSrcweir const rtl_String * pName, 326*cdf0e10cSrcweir storeAccessMode eMode) 327*cdf0e10cSrcweir { 328*cdf0e10cSrcweir // Acquire exclusive access. 329*cdf0e10cSrcweir osl::MutexGuard aGuard(*this); 330*cdf0e10cSrcweir 331*cdf0e10cSrcweir // Check precond. 332*cdf0e10cSrcweir if (!self::isValid()) 333*cdf0e10cSrcweir return store_E_InvalidAccess; 334*cdf0e10cSrcweir 335*cdf0e10cSrcweir // Setup inode page key. 336*cdf0e10cSrcweir OStorePageKey aKey; 337*cdf0e10cSrcweir storeError eErrCode = namei (pPath, pName, aKey); 338*cdf0e10cSrcweir if (eErrCode != store_E_None) 339*cdf0e10cSrcweir return eErrCode; 340*cdf0e10cSrcweir 341*cdf0e10cSrcweir // Check for directory. 342*cdf0e10cSrcweir if (nAttrib & STORE_ATTRIB_ISDIR) 343*cdf0e10cSrcweir { 344*cdf0e10cSrcweir // Ugly, but necessary (backward compatibility). 345*cdf0e10cSrcweir aKey.m_nLow = store::htonl(rtl_crc32 (store::ntohl(aKey.m_nLow), "/", 1)); 346*cdf0e10cSrcweir } 347*cdf0e10cSrcweir 348*cdf0e10cSrcweir // Load inode page. 349*cdf0e10cSrcweir eErrCode = load_dirpage_Impl (aKey, rPage); 350*cdf0e10cSrcweir if (eErrCode != store_E_None) 351*cdf0e10cSrcweir { 352*cdf0e10cSrcweir // Check mode and reason. 353*cdf0e10cSrcweir if (eErrCode != store_E_NotExists) 354*cdf0e10cSrcweir return eErrCode; 355*cdf0e10cSrcweir 356*cdf0e10cSrcweir if (eMode == store_AccessReadWrite) 357*cdf0e10cSrcweir return store_E_NotExists; 358*cdf0e10cSrcweir if (eMode == store_AccessReadOnly) 359*cdf0e10cSrcweir return store_E_NotExists; 360*cdf0e10cSrcweir 361*cdf0e10cSrcweir if (!base::isWriteable()) 362*cdf0e10cSrcweir return store_E_AccessViolation; 363*cdf0e10cSrcweir 364*cdf0e10cSrcweir // Create inode page. 365*cdf0e10cSrcweir eErrCode = rPage.construct< inode >(base::allocator()); 366*cdf0e10cSrcweir if (eErrCode != store_E_None) 367*cdf0e10cSrcweir return eErrCode; 368*cdf0e10cSrcweir 369*cdf0e10cSrcweir // Setup inode nameblock. 370*cdf0e10cSrcweir PageHolderObject< inode > xPage (rPage.get()); 371*cdf0e10cSrcweir 372*cdf0e10cSrcweir rPage.key (aKey); 373*cdf0e10cSrcweir rPage.attrib (nAttrib); 374*cdf0e10cSrcweir 375*cdf0e10cSrcweir memcpy ( 376*cdf0e10cSrcweir &(xPage->m_aNameBlock.m_pData[0]), 377*cdf0e10cSrcweir pName->buffer, pName->length); 378*cdf0e10cSrcweir 379*cdf0e10cSrcweir // Save inode page. 380*cdf0e10cSrcweir eErrCode = save_dirpage_Impl (aKey, rPage); 381*cdf0e10cSrcweir if (eErrCode != store_E_None) 382*cdf0e10cSrcweir return eErrCode; 383*cdf0e10cSrcweir } 384*cdf0e10cSrcweir 385*cdf0e10cSrcweir // Check for symbolic link. 386*cdf0e10cSrcweir if (rPage.attrib() & STORE_ATTRIB_ISLINK) 387*cdf0e10cSrcweir { 388*cdf0e10cSrcweir // Obtain 'Destination' page key. 389*cdf0e10cSrcweir PageHolderObject< inode > xPage (rPage.get()); 390*cdf0e10cSrcweir OStorePageKey aDstKey; 391*cdf0e10cSrcweir memcpy (&aDstKey, &(xPage->m_pData[0]), sizeof(aDstKey)); 392*cdf0e10cSrcweir 393*cdf0e10cSrcweir // Load 'Destination' inode. 394*cdf0e10cSrcweir eErrCode = load_dirpage_Impl (aDstKey, rPage); 395*cdf0e10cSrcweir if (eErrCode != store_E_None) 396*cdf0e10cSrcweir return eErrCode; 397*cdf0e10cSrcweir } 398*cdf0e10cSrcweir 399*cdf0e10cSrcweir // Done. 400*cdf0e10cSrcweir return store_E_None; 401*cdf0e10cSrcweir } 402*cdf0e10cSrcweir 403*cdf0e10cSrcweir /* 404*cdf0e10cSrcweir * iterate. 405*cdf0e10cSrcweir * Precond: initialized. 406*cdf0e10cSrcweir * ToDo: skip hardlink entries. 407*cdf0e10cSrcweir */ 408*cdf0e10cSrcweir storeError OStorePageManager::iterate ( 409*cdf0e10cSrcweir OStorePageKey & rKey, 410*cdf0e10cSrcweir OStorePageLink & rLink, 411*cdf0e10cSrcweir sal_uInt32 & rAttrib) 412*cdf0e10cSrcweir { 413*cdf0e10cSrcweir // Acquire exclusive access. 414*cdf0e10cSrcweir osl::MutexGuard aGuard(*this); 415*cdf0e10cSrcweir 416*cdf0e10cSrcweir // Check precond. 417*cdf0e10cSrcweir if (!self::isValid()) 418*cdf0e10cSrcweir return store_E_InvalidAccess; 419*cdf0e10cSrcweir 420*cdf0e10cSrcweir // Find NodePage and Index. 421*cdf0e10cSrcweir OStoreBTreeNodeObject aNode; 422*cdf0e10cSrcweir sal_uInt16 i = 0; 423*cdf0e10cSrcweir storeError eErrCode = m_aRoot.find_lookup (aNode, i, rKey, *this); 424*cdf0e10cSrcweir if (eErrCode != store_E_None) 425*cdf0e10cSrcweir return eErrCode; 426*cdf0e10cSrcweir 427*cdf0e10cSrcweir // GreaterEqual. Found next entry. 428*cdf0e10cSrcweir PageHolderObject< page > xNode (aNode.get()); 429*cdf0e10cSrcweir entry e (xNode->m_pData[i]); 430*cdf0e10cSrcweir 431*cdf0e10cSrcweir // Setup result. 432*cdf0e10cSrcweir rKey = e.m_aKey; 433*cdf0e10cSrcweir rLink = e.m_aLink; 434*cdf0e10cSrcweir rAttrib = store::ntohl(e.m_nAttrib); 435*cdf0e10cSrcweir 436*cdf0e10cSrcweir // Done. 437*cdf0e10cSrcweir return store_E_None; 438*cdf0e10cSrcweir } 439*cdf0e10cSrcweir 440*cdf0e10cSrcweir /* 441*cdf0e10cSrcweir * load => private: iget() @@@ 442*cdf0e10cSrcweir * Internal: Precond: initialized, exclusive access. 443*cdf0e10cSrcweir */ 444*cdf0e10cSrcweir storeError OStorePageManager::load_dirpage_Impl ( 445*cdf0e10cSrcweir const OStorePageKey &rKey, 446*cdf0e10cSrcweir OStoreDirectoryPageObject &rPage) 447*cdf0e10cSrcweir { 448*cdf0e10cSrcweir // Find Node and Index. 449*cdf0e10cSrcweir OStoreBTreeNodeObject aNode; 450*cdf0e10cSrcweir sal_uInt16 i = 0; 451*cdf0e10cSrcweir storeError eErrCode = find_lookup (aNode, i, rKey); 452*cdf0e10cSrcweir if (eErrCode != store_E_None) 453*cdf0e10cSrcweir return eErrCode; 454*cdf0e10cSrcweir 455*cdf0e10cSrcweir // Existing entry. Load page. 456*cdf0e10cSrcweir PageHolderObject< page > xNode (aNode.get()); 457*cdf0e10cSrcweir entry e (xNode->m_pData[i]); 458*cdf0e10cSrcweir return loadObjectAt (rPage, e.m_aLink.location()); 459*cdf0e10cSrcweir } 460*cdf0e10cSrcweir 461*cdf0e10cSrcweir /* 462*cdf0e10cSrcweir * save => private: iget(), rebuild() @@@ 463*cdf0e10cSrcweir * Internal: Precond: initialized, writeable, exclusive access. 464*cdf0e10cSrcweir */ 465*cdf0e10cSrcweir storeError OStorePageManager::save_dirpage_Impl ( 466*cdf0e10cSrcweir const OStorePageKey &rKey, 467*cdf0e10cSrcweir OStoreDirectoryPageObject &rPage) 468*cdf0e10cSrcweir { 469*cdf0e10cSrcweir // Find NodePage and Index. 470*cdf0e10cSrcweir node aNode; 471*cdf0e10cSrcweir sal_uInt16 i = 0; 472*cdf0e10cSrcweir 473*cdf0e10cSrcweir storeError eErrCode = m_aRoot.find_insert (aNode, i, rKey, *this); 474*cdf0e10cSrcweir PageHolderObject< page > xNode (aNode.get()); 475*cdf0e10cSrcweir if (eErrCode != store_E_None) 476*cdf0e10cSrcweir { 477*cdf0e10cSrcweir if (eErrCode != store_E_AlreadyExists) 478*cdf0e10cSrcweir return eErrCode; 479*cdf0e10cSrcweir 480*cdf0e10cSrcweir // Existing entry. 481*cdf0e10cSrcweir entry e (xNode->m_pData[i]); 482*cdf0e10cSrcweir if (e.m_aLink.location() != STORE_PAGE_NULL) 483*cdf0e10cSrcweir { 484*cdf0e10cSrcweir // Save page to existing location. 485*cdf0e10cSrcweir return saveObjectAt (rPage, e.m_aLink.location()); 486*cdf0e10cSrcweir } 487*cdf0e10cSrcweir 488*cdf0e10cSrcweir // Allocate page. 489*cdf0e10cSrcweir eErrCode = base::allocate (rPage); 490*cdf0e10cSrcweir if (eErrCode != store_E_None) 491*cdf0e10cSrcweir return eErrCode; 492*cdf0e10cSrcweir 493*cdf0e10cSrcweir // Update page location. 494*cdf0e10cSrcweir xNode->m_pData[i].m_aLink = rPage.location(); 495*cdf0e10cSrcweir 496*cdf0e10cSrcweir // Save modified NodePage. 497*cdf0e10cSrcweir return saveObjectAt (aNode, aNode.location()); 498*cdf0e10cSrcweir } 499*cdf0e10cSrcweir 500*cdf0e10cSrcweir // Allocate page. 501*cdf0e10cSrcweir eErrCode = base::allocate (rPage); 502*cdf0e10cSrcweir if (eErrCode != store_E_None) 503*cdf0e10cSrcweir return eErrCode; 504*cdf0e10cSrcweir 505*cdf0e10cSrcweir // Insert. 506*cdf0e10cSrcweir OStorePageLink aLink (rPage.location()); 507*cdf0e10cSrcweir xNode->insert (i + 1, entry (rKey, aLink)); 508*cdf0e10cSrcweir 509*cdf0e10cSrcweir // Save modified NodePage. 510*cdf0e10cSrcweir return saveObjectAt (aNode, aNode.location()); 511*cdf0e10cSrcweir } 512*cdf0e10cSrcweir 513*cdf0e10cSrcweir /* 514*cdf0e10cSrcweir * attrib [nAttrib = ((nAttrib & ~nMask1) | nMask2)]. 515*cdf0e10cSrcweir * Precond: initialized. 516*cdf0e10cSrcweir */ 517*cdf0e10cSrcweir storeError OStorePageManager::attrib ( 518*cdf0e10cSrcweir const OStorePageKey &rKey, 519*cdf0e10cSrcweir sal_uInt32 nMask1, 520*cdf0e10cSrcweir sal_uInt32 nMask2, 521*cdf0e10cSrcweir sal_uInt32 &rAttrib) 522*cdf0e10cSrcweir { 523*cdf0e10cSrcweir // Acquire exclusive access. 524*cdf0e10cSrcweir osl::MutexGuard aGuard(*this); 525*cdf0e10cSrcweir 526*cdf0e10cSrcweir // Check precond. 527*cdf0e10cSrcweir if (!self::isValid()) 528*cdf0e10cSrcweir return store_E_InvalidAccess; 529*cdf0e10cSrcweir 530*cdf0e10cSrcweir // Find NodePage and index. 531*cdf0e10cSrcweir OStoreBTreeNodeObject aNode; 532*cdf0e10cSrcweir sal_uInt16 i = 0; 533*cdf0e10cSrcweir storeError eErrCode = find_lookup (aNode, i, rKey); 534*cdf0e10cSrcweir if (eErrCode != store_E_None) 535*cdf0e10cSrcweir return eErrCode; 536*cdf0e10cSrcweir 537*cdf0e10cSrcweir // Existing entry. 538*cdf0e10cSrcweir PageHolderObject< page > xNode (aNode.get()); 539*cdf0e10cSrcweir entry e (xNode->m_pData[i]); 540*cdf0e10cSrcweir if (nMask1 != nMask2) 541*cdf0e10cSrcweir { 542*cdf0e10cSrcweir // Evaluate new attributes. 543*cdf0e10cSrcweir sal_uInt32 nAttrib = store::ntohl(e.m_nAttrib); 544*cdf0e10cSrcweir 545*cdf0e10cSrcweir nAttrib &= ~nMask1; 546*cdf0e10cSrcweir nAttrib |= nMask2; 547*cdf0e10cSrcweir 548*cdf0e10cSrcweir if (store::htonl(nAttrib) != e.m_nAttrib) 549*cdf0e10cSrcweir { 550*cdf0e10cSrcweir // Check access mode. 551*cdf0e10cSrcweir if (base::isWriteable()) 552*cdf0e10cSrcweir { 553*cdf0e10cSrcweir // Set new attributes. 554*cdf0e10cSrcweir e.m_nAttrib = store::htonl(nAttrib); 555*cdf0e10cSrcweir xNode->m_pData[i] = e; 556*cdf0e10cSrcweir 557*cdf0e10cSrcweir // Save modified NodePage. 558*cdf0e10cSrcweir eErrCode = saveObjectAt (aNode, aNode.location()); 559*cdf0e10cSrcweir } 560*cdf0e10cSrcweir else 561*cdf0e10cSrcweir { 562*cdf0e10cSrcweir // Access denied. 563*cdf0e10cSrcweir eErrCode = store_E_AccessViolation; 564*cdf0e10cSrcweir } 565*cdf0e10cSrcweir } 566*cdf0e10cSrcweir } 567*cdf0e10cSrcweir 568*cdf0e10cSrcweir // Obtain current attributes. 569*cdf0e10cSrcweir rAttrib = store::ntohl(e.m_nAttrib); 570*cdf0e10cSrcweir return eErrCode; 571*cdf0e10cSrcweir } 572*cdf0e10cSrcweir 573*cdf0e10cSrcweir /* 574*cdf0e10cSrcweir * link (insert 'Source' as hardlink to 'Destination'). 575*cdf0e10cSrcweir * Precond: initialized, writeable. 576*cdf0e10cSrcweir */ 577*cdf0e10cSrcweir storeError OStorePageManager::link ( 578*cdf0e10cSrcweir const OStorePageKey &rSrcKey, 579*cdf0e10cSrcweir const OStorePageKey &rDstKey) 580*cdf0e10cSrcweir { 581*cdf0e10cSrcweir // Acquire exclusive access. 582*cdf0e10cSrcweir osl::MutexGuard aGuard(*this); 583*cdf0e10cSrcweir 584*cdf0e10cSrcweir // Check precond. 585*cdf0e10cSrcweir if (!self::isValid()) 586*cdf0e10cSrcweir return store_E_InvalidAccess; 587*cdf0e10cSrcweir 588*cdf0e10cSrcweir if (!base::isWriteable()) 589*cdf0e10cSrcweir return store_E_AccessViolation; 590*cdf0e10cSrcweir 591*cdf0e10cSrcweir // Find 'Destination' NodePage and Index. 592*cdf0e10cSrcweir OStoreBTreeNodeObject aDstNode; 593*cdf0e10cSrcweir sal_uInt16 i = 0; 594*cdf0e10cSrcweir storeError eErrCode = find_lookup (aDstNode, i, rDstKey); 595*cdf0e10cSrcweir if (eErrCode != store_E_None) 596*cdf0e10cSrcweir return eErrCode; 597*cdf0e10cSrcweir 598*cdf0e10cSrcweir // Existing 'Destination' entry. 599*cdf0e10cSrcweir PageHolderObject< page > xDstNode (aDstNode.get()); 600*cdf0e10cSrcweir entry e (xDstNode->m_pData[i]); 601*cdf0e10cSrcweir OStorePageLink aDstLink (e.m_aLink); 602*cdf0e10cSrcweir 603*cdf0e10cSrcweir // Find 'Source' NodePage and Index. 604*cdf0e10cSrcweir OStoreBTreeNodeObject aSrcNode; 605*cdf0e10cSrcweir eErrCode = m_aRoot.find_insert (aSrcNode, i, rSrcKey, *this); 606*cdf0e10cSrcweir if (eErrCode != store_E_None) 607*cdf0e10cSrcweir return eErrCode; 608*cdf0e10cSrcweir 609*cdf0e10cSrcweir // Insert 'Source' entry. 610*cdf0e10cSrcweir PageHolderObject< page > xSrcNode (aSrcNode.get()); 611*cdf0e10cSrcweir xSrcNode->insert (i + 1, entry (rSrcKey, aDstLink, STORE_ATTRIB_ISLINK)); 612*cdf0e10cSrcweir return saveObjectAt (aSrcNode, aSrcNode.location()); 613*cdf0e10cSrcweir } 614*cdf0e10cSrcweir 615*cdf0e10cSrcweir /* 616*cdf0e10cSrcweir * symlink (insert 'Source' DirectoryPage as symlink to 'Destination'). 617*cdf0e10cSrcweir * Precond: initialized, writeable. 618*cdf0e10cSrcweir */ 619*cdf0e10cSrcweir storeError OStorePageManager::symlink ( 620*cdf0e10cSrcweir const rtl_String *pSrcPath, 621*cdf0e10cSrcweir const rtl_String *pSrcName, 622*cdf0e10cSrcweir const OStorePageKey &rDstKey) 623*cdf0e10cSrcweir { 624*cdf0e10cSrcweir // Acquire exclusive access. 625*cdf0e10cSrcweir osl::MutexGuard aGuard(*this); 626*cdf0e10cSrcweir 627*cdf0e10cSrcweir // Check precond. 628*cdf0e10cSrcweir if (!self::isValid()) 629*cdf0e10cSrcweir return store_E_InvalidAccess; 630*cdf0e10cSrcweir 631*cdf0e10cSrcweir if (!base::isWriteable()) 632*cdf0e10cSrcweir return store_E_AccessViolation; 633*cdf0e10cSrcweir 634*cdf0e10cSrcweir // Check 'Source' parameter. 635*cdf0e10cSrcweir storeError eErrCode = store_E_InvalidParameter; 636*cdf0e10cSrcweir if (!(pSrcPath && pSrcName)) 637*cdf0e10cSrcweir return eErrCode; 638*cdf0e10cSrcweir 639*cdf0e10cSrcweir // Setup 'Source' page key. 640*cdf0e10cSrcweir OStorePageKey aSrcKey; 641*cdf0e10cSrcweir eErrCode = namei (pSrcPath, pSrcName, aSrcKey); 642*cdf0e10cSrcweir if (eErrCode != store_E_None) 643*cdf0e10cSrcweir return eErrCode; 644*cdf0e10cSrcweir 645*cdf0e10cSrcweir // Find 'Source' NodePage and Index. 646*cdf0e10cSrcweir OStoreBTreeNodeObject aSrcNode; 647*cdf0e10cSrcweir sal_uInt16 i = 0; 648*cdf0e10cSrcweir eErrCode = m_aRoot.find_insert (aSrcNode, i, aSrcKey, *this); 649*cdf0e10cSrcweir if (eErrCode != store_E_None) 650*cdf0e10cSrcweir return eErrCode; 651*cdf0e10cSrcweir 652*cdf0e10cSrcweir // Initialize directory page. 653*cdf0e10cSrcweir OStoreDirectoryPageObject aPage; 654*cdf0e10cSrcweir eErrCode = aPage.construct< inode >(base::allocator()); 655*cdf0e10cSrcweir if (eErrCode != store_E_None) 656*cdf0e10cSrcweir return eErrCode; 657*cdf0e10cSrcweir 658*cdf0e10cSrcweir // Setup as 'Source' directory page. 659*cdf0e10cSrcweir inode_holder_type xNode (aPage.get()); 660*cdf0e10cSrcweir aPage.key (aSrcKey); 661*cdf0e10cSrcweir memcpy ( 662*cdf0e10cSrcweir &(xNode->m_aNameBlock.m_pData[0]), 663*cdf0e10cSrcweir pSrcName->buffer, pSrcName->length); 664*cdf0e10cSrcweir 665*cdf0e10cSrcweir // Store 'Destination' page key. 666*cdf0e10cSrcweir OStorePageKey aDstKey (rDstKey); 667*cdf0e10cSrcweir memcpy (&(xNode->m_pData[0]), &aDstKey, sizeof(aDstKey)); 668*cdf0e10cSrcweir 669*cdf0e10cSrcweir // Mark 'Source' as symbolic link to 'Destination'. 670*cdf0e10cSrcweir aPage.attrib (STORE_ATTRIB_ISLINK); 671*cdf0e10cSrcweir aPage.dataLength (sal_uInt32(sizeof(aDstKey))); 672*cdf0e10cSrcweir 673*cdf0e10cSrcweir // Allocate and save 'Source' directory page. 674*cdf0e10cSrcweir eErrCode = base::allocate (aPage); 675*cdf0e10cSrcweir if (eErrCode != store_E_None) 676*cdf0e10cSrcweir return eErrCode; 677*cdf0e10cSrcweir 678*cdf0e10cSrcweir // Insert 'Source' entry. 679*cdf0e10cSrcweir PageHolderObject< page > xSrcNode (aSrcNode.get()); 680*cdf0e10cSrcweir OStorePageLink aSrcLink (aPage.location()); 681*cdf0e10cSrcweir xSrcNode->insert (i + 1, entry(aSrcKey, aSrcLink)); 682*cdf0e10cSrcweir 683*cdf0e10cSrcweir // Save modified NodePage. 684*cdf0e10cSrcweir return saveObjectAt (aSrcNode, aSrcNode.location()); 685*cdf0e10cSrcweir } 686*cdf0e10cSrcweir 687*cdf0e10cSrcweir /* 688*cdf0e10cSrcweir * rename. 689*cdf0e10cSrcweir * Precond: initialized, writeable. 690*cdf0e10cSrcweir */ 691*cdf0e10cSrcweir storeError OStorePageManager::rename ( 692*cdf0e10cSrcweir const OStorePageKey &rSrcKey, 693*cdf0e10cSrcweir const rtl_String *pDstPath, 694*cdf0e10cSrcweir const rtl_String *pDstName) 695*cdf0e10cSrcweir { 696*cdf0e10cSrcweir // Acquire exclusive access. 697*cdf0e10cSrcweir osl::MutexGuard aGuard(*this); 698*cdf0e10cSrcweir 699*cdf0e10cSrcweir // Check precond. 700*cdf0e10cSrcweir if (!self::isValid()) 701*cdf0e10cSrcweir return store_E_InvalidAccess; 702*cdf0e10cSrcweir 703*cdf0e10cSrcweir if (!base::isWriteable()) 704*cdf0e10cSrcweir return store_E_AccessViolation; 705*cdf0e10cSrcweir 706*cdf0e10cSrcweir // Check 'Destination' parameter. 707*cdf0e10cSrcweir storeError eErrCode = store_E_InvalidParameter; 708*cdf0e10cSrcweir if (!(pDstPath && pDstName)) 709*cdf0e10cSrcweir return eErrCode; 710*cdf0e10cSrcweir 711*cdf0e10cSrcweir // Setup 'Destination' page key. 712*cdf0e10cSrcweir OStorePageKey aDstKey; 713*cdf0e10cSrcweir eErrCode = namei (pDstPath, pDstName, aDstKey); 714*cdf0e10cSrcweir if (eErrCode != store_E_None) 715*cdf0e10cSrcweir return eErrCode; 716*cdf0e10cSrcweir 717*cdf0e10cSrcweir // Find 'Source' NodePage and Index. 718*cdf0e10cSrcweir OStoreBTreeNodeObject aSrcNode; 719*cdf0e10cSrcweir sal_uInt16 i = 0; 720*cdf0e10cSrcweir eErrCode = find_lookup (aSrcNode, i, rSrcKey); 721*cdf0e10cSrcweir if (eErrCode != store_E_None) 722*cdf0e10cSrcweir return eErrCode; 723*cdf0e10cSrcweir 724*cdf0e10cSrcweir // Existing 'Source' entry. 725*cdf0e10cSrcweir PageHolderObject< page > xSrcNode (aSrcNode.get()); 726*cdf0e10cSrcweir entry e (xSrcNode->m_pData[i]); 727*cdf0e10cSrcweir 728*cdf0e10cSrcweir // Check for (not a) hardlink. 729*cdf0e10cSrcweir OStoreDirectoryPageObject aPage; 730*cdf0e10cSrcweir if (!(store::ntohl(e.m_nAttrib) & STORE_ATTRIB_ISLINK)) 731*cdf0e10cSrcweir { 732*cdf0e10cSrcweir // Load directory page. 733*cdf0e10cSrcweir eErrCode = base::loadObjectAt (aPage, e.m_aLink.location()); 734*cdf0e10cSrcweir if (eErrCode != store_E_None) 735*cdf0e10cSrcweir return eErrCode; 736*cdf0e10cSrcweir 737*cdf0e10cSrcweir // Check for directory. 738*cdf0e10cSrcweir if (aPage.attrib() & STORE_ATTRIB_ISDIR) 739*cdf0e10cSrcweir { 740*cdf0e10cSrcweir // Ugly, but necessary (backward compatibility). 741*cdf0e10cSrcweir aDstKey.m_nLow = store::htonl(rtl_crc32 (store::ntohl(aDstKey.m_nLow), "/", 1)); 742*cdf0e10cSrcweir } 743*cdf0e10cSrcweir } 744*cdf0e10cSrcweir 745*cdf0e10cSrcweir // Let 'Source' entry be 'Destination' entry. 746*cdf0e10cSrcweir e.m_aKey = aDstKey; 747*cdf0e10cSrcweir 748*cdf0e10cSrcweir // Find 'Destination' NodePage and Index. 749*cdf0e10cSrcweir OStoreBTreeNodeObject aDstNode; 750*cdf0e10cSrcweir eErrCode = m_aRoot.find_insert (aDstNode, i, e.m_aKey, *this); 751*cdf0e10cSrcweir if (eErrCode != store_E_None) 752*cdf0e10cSrcweir return eErrCode; 753*cdf0e10cSrcweir 754*cdf0e10cSrcweir // Insert 'Destination' entry. 755*cdf0e10cSrcweir PageHolderObject< page > xDstNode (aDstNode.get()); 756*cdf0e10cSrcweir xDstNode->insert (i + 1, e); 757*cdf0e10cSrcweir 758*cdf0e10cSrcweir eErrCode = saveObjectAt (aDstNode, aDstNode.location()); 759*cdf0e10cSrcweir if (eErrCode != store_E_None) 760*cdf0e10cSrcweir return eErrCode; 761*cdf0e10cSrcweir 762*cdf0e10cSrcweir // Check for (not a) hardlink. 763*cdf0e10cSrcweir if (!(store::ntohl(e.m_nAttrib) & STORE_ATTRIB_ISLINK)) 764*cdf0e10cSrcweir { 765*cdf0e10cSrcweir // Modify 'Source' directory page. 766*cdf0e10cSrcweir inode_holder_type xNode (aPage.get()); 767*cdf0e10cSrcweir 768*cdf0e10cSrcweir // Setup 'Destination' NameBlock. 769*cdf0e10cSrcweir sal_Int32 nDstLen = pDstName->length; 770*cdf0e10cSrcweir memcpy ( 771*cdf0e10cSrcweir &(xNode->m_aNameBlock.m_pData[0]), 772*cdf0e10cSrcweir pDstName->buffer, pDstName->length); 773*cdf0e10cSrcweir memset ( 774*cdf0e10cSrcweir &(xNode->m_aNameBlock.m_pData[nDstLen]), 775*cdf0e10cSrcweir 0, STORE_MAXIMUM_NAMESIZE - nDstLen); 776*cdf0e10cSrcweir aPage.key (e.m_aKey); 777*cdf0e10cSrcweir 778*cdf0e10cSrcweir // Save directory page. 779*cdf0e10cSrcweir eErrCode = base::saveObjectAt (aPage, e.m_aLink.location()); 780*cdf0e10cSrcweir if (eErrCode != store_E_None) 781*cdf0e10cSrcweir return eErrCode; 782*cdf0e10cSrcweir } 783*cdf0e10cSrcweir 784*cdf0e10cSrcweir // Remove 'Source' entry. 785*cdf0e10cSrcweir e.m_aKey = rSrcKey; 786*cdf0e10cSrcweir return remove_Impl (e); 787*cdf0e10cSrcweir } 788*cdf0e10cSrcweir 789*cdf0e10cSrcweir /* 790*cdf0e10cSrcweir * remove. 791*cdf0e10cSrcweir * Precond: initialized, writeable. 792*cdf0e10cSrcweir */ 793*cdf0e10cSrcweir storeError OStorePageManager::remove (const OStorePageKey &rKey) 794*cdf0e10cSrcweir { 795*cdf0e10cSrcweir // Acquire exclusive access. 796*cdf0e10cSrcweir osl::MutexGuard aGuard(*this); 797*cdf0e10cSrcweir 798*cdf0e10cSrcweir // Check precond. 799*cdf0e10cSrcweir if (!self::isValid()) 800*cdf0e10cSrcweir return store_E_InvalidAccess; 801*cdf0e10cSrcweir 802*cdf0e10cSrcweir if (!base::isWriteable()) 803*cdf0e10cSrcweir return store_E_AccessViolation; 804*cdf0e10cSrcweir 805*cdf0e10cSrcweir // Find NodePage and index. 806*cdf0e10cSrcweir OStoreBTreeNodeObject aNodePage; 807*cdf0e10cSrcweir sal_uInt16 i = 0; 808*cdf0e10cSrcweir storeError eErrCode = find_lookup (aNodePage, i, rKey); 809*cdf0e10cSrcweir if (eErrCode != store_E_None) 810*cdf0e10cSrcweir return eErrCode; 811*cdf0e10cSrcweir 812*cdf0e10cSrcweir // Existing entry. 813*cdf0e10cSrcweir PageHolderObject< page > xNodePage (aNodePage.get()); 814*cdf0e10cSrcweir entry e (xNodePage->m_pData[i]); 815*cdf0e10cSrcweir 816*cdf0e10cSrcweir // Check for (not a) hardlink. 817*cdf0e10cSrcweir if (!(store::ntohl(e.m_nAttrib) & STORE_ATTRIB_ISLINK)) 818*cdf0e10cSrcweir { 819*cdf0e10cSrcweir // Load directory page. 820*cdf0e10cSrcweir OStoreDirectoryPageObject aPage; 821*cdf0e10cSrcweir eErrCode = base::loadObjectAt (aPage, e.m_aLink.location()); 822*cdf0e10cSrcweir if (eErrCode != store_E_None) 823*cdf0e10cSrcweir return eErrCode; 824*cdf0e10cSrcweir 825*cdf0e10cSrcweir inode_holder_type xNode (aPage.get()); 826*cdf0e10cSrcweir 827*cdf0e10cSrcweir // Acquire page write access. 828*cdf0e10cSrcweir OStorePageDescriptor aDescr (xNode->m_aDescr); 829*cdf0e10cSrcweir eErrCode = base::acquirePage (aDescr, store_AccessReadWrite); 830*cdf0e10cSrcweir if (eErrCode != store_E_None) 831*cdf0e10cSrcweir return eErrCode; 832*cdf0e10cSrcweir 833*cdf0e10cSrcweir // Check for symbolic link. 834*cdf0e10cSrcweir if (!(aPage.attrib() & STORE_ATTRIB_ISLINK)) 835*cdf0e10cSrcweir { 836*cdf0e10cSrcweir // Ordinary inode. Determine 'Data' scope. 837*cdf0e10cSrcweir inode::ChunkScope eScope = xNode->scope (aPage.dataLength()); 838*cdf0e10cSrcweir if (eScope == inode::SCOPE_EXTERNAL) 839*cdf0e10cSrcweir { 840*cdf0e10cSrcweir // External 'Data' scope. Truncate all external data pages. 841*cdf0e10cSrcweir eErrCode = aPage.truncate (0, *this); 842*cdf0e10cSrcweir if (eErrCode != store_E_None) 843*cdf0e10cSrcweir return eErrCode; 844*cdf0e10cSrcweir } 845*cdf0e10cSrcweir 846*cdf0e10cSrcweir // Truncate internal data page. 847*cdf0e10cSrcweir memset (&(xNode->m_pData[0]), 0, xNode->capacity()); 848*cdf0e10cSrcweir aPage.dataLength (0); 849*cdf0e10cSrcweir } 850*cdf0e10cSrcweir 851*cdf0e10cSrcweir // Release page write access. 852*cdf0e10cSrcweir eErrCode = base::releasePage (aDescr, store_AccessReadWrite); 853*cdf0e10cSrcweir 854*cdf0e10cSrcweir // Release and free directory page. 855*cdf0e10cSrcweir eErrCode = base::free (aPage.location()); 856*cdf0e10cSrcweir } 857*cdf0e10cSrcweir 858*cdf0e10cSrcweir // Remove entry. 859*cdf0e10cSrcweir return remove_Impl (e); 860*cdf0e10cSrcweir } 861*cdf0e10cSrcweir 862*cdf0e10cSrcweir /* 863*cdf0e10cSrcweir * RebuildContext. 864*cdf0e10cSrcweir */ 865*cdf0e10cSrcweir struct RebuildContext 866*cdf0e10cSrcweir { 867*cdf0e10cSrcweir /** Representation. 868*cdf0e10cSrcweir */ 869*cdf0e10cSrcweir rtl::Reference<OStorePageBIOS> m_xBIOS; 870*cdf0e10cSrcweir OStorePageBIOS::ScanContext m_aCtx; 871*cdf0e10cSrcweir sal_uInt16 m_nPageSize; 872*cdf0e10cSrcweir 873*cdf0e10cSrcweir /** Construction. 874*cdf0e10cSrcweir */ 875*cdf0e10cSrcweir RebuildContext (void) 876*cdf0e10cSrcweir : m_xBIOS (new OStorePageBIOS()), 877*cdf0e10cSrcweir m_nPageSize (0) 878*cdf0e10cSrcweir {} 879*cdf0e10cSrcweir 880*cdf0e10cSrcweir /** initialize (PageBIOS and ScanContext). 881*cdf0e10cSrcweir */ 882*cdf0e10cSrcweir storeError initialize (ILockBytes *pLockBytes, sal_uInt32 nMagic = 0) 883*cdf0e10cSrcweir { 884*cdf0e10cSrcweir storeError eErrCode = store_E_InvalidParameter; 885*cdf0e10cSrcweir if (pLockBytes) 886*cdf0e10cSrcweir { 887*cdf0e10cSrcweir m_xBIOS->initialize (pLockBytes, store_AccessReadOnly, m_nPageSize); 888*cdf0e10cSrcweir eErrCode = m_xBIOS->scanBegin (m_aCtx, nMagic); 889*cdf0e10cSrcweir } 890*cdf0e10cSrcweir return eErrCode; 891*cdf0e10cSrcweir } 892*cdf0e10cSrcweir 893*cdf0e10cSrcweir /** initialize (ScanContext). 894*cdf0e10cSrcweir */ 895*cdf0e10cSrcweir storeError initialize (sal_uInt32 nMagic = 0) 896*cdf0e10cSrcweir { 897*cdf0e10cSrcweir return m_xBIOS->scanBegin (m_aCtx, nMagic); 898*cdf0e10cSrcweir } 899*cdf0e10cSrcweir 900*cdf0e10cSrcweir /** load (next ScanContext matching page). 901*cdf0e10cSrcweir */ 902*cdf0e10cSrcweir storeError load (OStorePageObject &rPage) 903*cdf0e10cSrcweir { 904*cdf0e10cSrcweir if (m_aCtx.isValid()) 905*cdf0e10cSrcweir return m_xBIOS->scanNext (m_aCtx, rPage); 906*cdf0e10cSrcweir else 907*cdf0e10cSrcweir return store_E_CantSeek; 908*cdf0e10cSrcweir } 909*cdf0e10cSrcweir }; 910*cdf0e10cSrcweir 911*cdf0e10cSrcweir /* 912*cdf0e10cSrcweir * rebuild. 913*cdf0e10cSrcweir * Precond: none. 914*cdf0e10cSrcweir */ 915*cdf0e10cSrcweir storeError OStorePageManager::rebuild ( 916*cdf0e10cSrcweir ILockBytes *pSrcLB, ILockBytes *pDstLB) 917*cdf0e10cSrcweir { 918*cdf0e10cSrcweir // Acquire exclusive access. 919*cdf0e10cSrcweir osl::MutexGuard aGuard(*this); 920*cdf0e10cSrcweir 921*cdf0e10cSrcweir // Check arguments. 922*cdf0e10cSrcweir storeError eErrCode = store_E_InvalidParameter; 923*cdf0e10cSrcweir if (!(pSrcLB && pDstLB)) 924*cdf0e10cSrcweir return eErrCode; 925*cdf0e10cSrcweir 926*cdf0e10cSrcweir // Initialize 'Source' rebuild context. 927*cdf0e10cSrcweir RebuildContext aCtx; 928*cdf0e10cSrcweir eErrCode = aCtx.initialize (pSrcLB, STORE_MAGIC_DIRECTORYPAGE); 929*cdf0e10cSrcweir if (eErrCode != store_E_None) 930*cdf0e10cSrcweir return eErrCode; 931*cdf0e10cSrcweir rtl::Reference<OStorePageBIOS> xSrcBIOS (aCtx.m_xBIOS); 932*cdf0e10cSrcweir 933*cdf0e10cSrcweir // Initialize as 'Destination' with 'Source' page size. 934*cdf0e10cSrcweir eErrCode = self::initialize (pDstLB, store_AccessCreate, aCtx.m_nPageSize); 935*cdf0e10cSrcweir if (eErrCode != store_E_None) 936*cdf0e10cSrcweir return eErrCode; 937*cdf0e10cSrcweir 938*cdf0e10cSrcweir // Pass One: Scan 'Source' directory pages. 939*cdf0e10cSrcweir { 940*cdf0e10cSrcweir // Scan 'Source' directory pages. 941*cdf0e10cSrcweir OStoreDirectoryPageObject aSrcPage; 942*cdf0e10cSrcweir while ((eErrCode = aCtx.load(aSrcPage)) == store_E_None) 943*cdf0e10cSrcweir { 944*cdf0e10cSrcweir OStoreDirectoryPageObject aDstPage; 945*cdf0e10cSrcweir eErrCode = aDstPage.construct< inode >(base::allocator()); 946*cdf0e10cSrcweir if (eErrCode != store_E_None) 947*cdf0e10cSrcweir break; 948*cdf0e10cSrcweir 949*cdf0e10cSrcweir inode_holder_type xSrcDir (aSrcPage.get()); 950*cdf0e10cSrcweir inode_holder_type xDstDir (aDstPage.get()); 951*cdf0e10cSrcweir 952*cdf0e10cSrcweir // Copy NameBlock @@@ OLD @@@ 953*cdf0e10cSrcweir memcpy (&(xDstDir->m_aNameBlock), &(xSrcDir->m_aNameBlock), sizeof(xSrcDir->m_aNameBlock)); 954*cdf0e10cSrcweir 955*cdf0e10cSrcweir // Obtain 'Source' data length. 956*cdf0e10cSrcweir sal_uInt32 nDataLen = aSrcPage.dataLength(); 957*cdf0e10cSrcweir if (nDataLen > 0) 958*cdf0e10cSrcweir { 959*cdf0e10cSrcweir // Copy internal data area @@@ OLD @@@ 960*cdf0e10cSrcweir memcpy (&(xDstDir->m_pData[0]), &(xSrcDir->m_pData[0]), xSrcDir->capacity()); 961*cdf0e10cSrcweir } 962*cdf0e10cSrcweir 963*cdf0e10cSrcweir // Insert 'Destination' directory page. 964*cdf0e10cSrcweir eErrCode = save_dirpage_Impl (aDstPage.key(), aDstPage); 965*cdf0e10cSrcweir if (eErrCode != store_E_None) 966*cdf0e10cSrcweir break; 967*cdf0e10cSrcweir 968*cdf0e10cSrcweir // Check for external data page scope. 969*cdf0e10cSrcweir if (xSrcDir->scope(nDataLen) != inode::SCOPE_INTERNAL) 970*cdf0e10cSrcweir { 971*cdf0e10cSrcweir // Initialize 'Destination' data page. 972*cdf0e10cSrcweir typedef OStoreDataPageData data; 973*cdf0e10cSrcweir PageHolderObject< data > xData; 974*cdf0e10cSrcweir if (!xData.construct(base::allocator())) 975*cdf0e10cSrcweir return store_E_OutOfMemory; 976*cdf0e10cSrcweir 977*cdf0e10cSrcweir // Determine data page count. 978*cdf0e10cSrcweir inode::ChunkDescriptor aDescr ( 979*cdf0e10cSrcweir nDataLen - xDstDir->capacity(), xData->capacity()); 980*cdf0e10cSrcweir 981*cdf0e10cSrcweir sal_uInt32 i, n = aDescr.m_nPage; 982*cdf0e10cSrcweir if (aDescr.m_nOffset) n += 1; 983*cdf0e10cSrcweir 984*cdf0e10cSrcweir // Copy data pages. 985*cdf0e10cSrcweir OStoreDataPageObject aData; 986*cdf0e10cSrcweir for (i = 0; i < n; i++) 987*cdf0e10cSrcweir { 988*cdf0e10cSrcweir // Read 'Source' data page. 989*cdf0e10cSrcweir osl::MutexGuard aSrcGuard (*xSrcBIOS); 990*cdf0e10cSrcweir 991*cdf0e10cSrcweir eErrCode = aSrcPage.read (i, aData, *xSrcBIOS); 992*cdf0e10cSrcweir if (eErrCode != store_E_None) 993*cdf0e10cSrcweir continue; 994*cdf0e10cSrcweir 995*cdf0e10cSrcweir // Write 'Destination' data page. @@@ READONLY @@@ 996*cdf0e10cSrcweir eErrCode = aDstPage.write (i, aData, *this); 997*cdf0e10cSrcweir } 998*cdf0e10cSrcweir } 999*cdf0e10cSrcweir 1000*cdf0e10cSrcweir // Update 'Destination' directory page. 1001*cdf0e10cSrcweir aDstPage.dataLength (nDataLen); 1002*cdf0e10cSrcweir eErrCode = base::saveObjectAt (aDstPage, aDstPage.location()); 1003*cdf0e10cSrcweir } 1004*cdf0e10cSrcweir 1005*cdf0e10cSrcweir // Save directory scan results. 1006*cdf0e10cSrcweir flush(); 1007*cdf0e10cSrcweir } 1008*cdf0e10cSrcweir 1009*cdf0e10cSrcweir // Pass Two: Scan 'Source' BTree nodes. 1010*cdf0e10cSrcweir { 1011*cdf0e10cSrcweir // Re-start 'Source' rebuild context. 1012*cdf0e10cSrcweir aCtx.initialize (STORE_MAGIC_BTREENODE); 1013*cdf0e10cSrcweir 1014*cdf0e10cSrcweir // Scan 'Source' BTree nodes. 1015*cdf0e10cSrcweir OStoreBTreeNodeObject aNode; 1016*cdf0e10cSrcweir while ((eErrCode = aCtx.load(aNode)) == store_E_None) 1017*cdf0e10cSrcweir { 1018*cdf0e10cSrcweir // Check for leaf node. 1019*cdf0e10cSrcweir PageHolderObject< page > xNode (aNode.get()); 1020*cdf0e10cSrcweir if (xNode->depth() == 0) 1021*cdf0e10cSrcweir { 1022*cdf0e10cSrcweir sal_uInt16 i, n = xNode->usageCount(); 1023*cdf0e10cSrcweir for (i = 0; i < n; i++) 1024*cdf0e10cSrcweir { 1025*cdf0e10cSrcweir entry e (xNode->m_pData[i]); 1026*cdf0e10cSrcweir 1027*cdf0e10cSrcweir // Check for Hard link. 1028*cdf0e10cSrcweir if (e.m_nAttrib & STORE_ATTRIB_ISLINK) 1029*cdf0e10cSrcweir { 1030*cdf0e10cSrcweir // Load the hard link destination. 1031*cdf0e10cSrcweir OStoreDirectoryPageObject aSrcPage; 1032*cdf0e10cSrcweir eErrCode = xSrcBIOS->loadObjectAt (aSrcPage, e.m_aLink.location()); 1033*cdf0e10cSrcweir if (eErrCode == store_E_None) 1034*cdf0e10cSrcweir { 1035*cdf0e10cSrcweir OStorePageKey aDstKey (aSrcPage.key()); 1036*cdf0e10cSrcweir eErrCode = link (e.m_aKey, aDstKey); 1037*cdf0e10cSrcweir } 1038*cdf0e10cSrcweir e.m_nAttrib &= ~STORE_ATTRIB_ISLINK; 1039*cdf0e10cSrcweir } 1040*cdf0e10cSrcweir 1041*cdf0e10cSrcweir if (e.m_nAttrib) 1042*cdf0e10cSrcweir { 1043*cdf0e10cSrcweir // Ordinary attributes. 1044*cdf0e10cSrcweir sal_uInt32 nAttrib = 0; 1045*cdf0e10cSrcweir eErrCode = attrib (e.m_aKey, 0, e.m_nAttrib, nAttrib); 1046*cdf0e10cSrcweir } 1047*cdf0e10cSrcweir } 1048*cdf0e10cSrcweir } 1049*cdf0e10cSrcweir } 1050*cdf0e10cSrcweir 1051*cdf0e10cSrcweir // Save BTree node scan results. 1052*cdf0e10cSrcweir flush(); 1053*cdf0e10cSrcweir } 1054*cdf0e10cSrcweir 1055*cdf0e10cSrcweir // Done. 1056*cdf0e10cSrcweir return store_E_None; 1057*cdf0e10cSrcweir } 1058