1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski *
3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file
5*b1cdbd2cSJim Jagielski * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file
7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski *
11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski *
13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the
17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski * under the License.
19*b1cdbd2cSJim Jagielski *
20*b1cdbd2cSJim Jagielski *************************************************************/
21*b1cdbd2cSJim Jagielski
22*b1cdbd2cSJim Jagielski
23*b1cdbd2cSJim Jagielski
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_store.hxx"
26*b1cdbd2cSJim Jagielski
27*b1cdbd2cSJim Jagielski #include "stordata.hxx"
28*b1cdbd2cSJim Jagielski
29*b1cdbd2cSJim Jagielski #include "sal/types.h"
30*b1cdbd2cSJim Jagielski #include "osl/diagnose.h"
31*b1cdbd2cSJim Jagielski
32*b1cdbd2cSJim Jagielski #include "store/types.h"
33*b1cdbd2cSJim Jagielski #include "storbase.hxx"
34*b1cdbd2cSJim Jagielski #include "storbios.hxx"
35*b1cdbd2cSJim Jagielski
36*b1cdbd2cSJim Jagielski using namespace store;
37*b1cdbd2cSJim Jagielski
38*b1cdbd2cSJim Jagielski /*========================================================================
39*b1cdbd2cSJim Jagielski *
40*b1cdbd2cSJim Jagielski * OStoreDataPageObject implementation.
41*b1cdbd2cSJim Jagielski *
42*b1cdbd2cSJim Jagielski *======================================================================*/
43*b1cdbd2cSJim Jagielski /*
44*b1cdbd2cSJim Jagielski * guard.
45*b1cdbd2cSJim Jagielski */
guard(sal_uInt32 nAddr)46*b1cdbd2cSJim Jagielski storeError OStoreDataPageObject::guard (sal_uInt32 nAddr)
47*b1cdbd2cSJim Jagielski {
48*b1cdbd2cSJim Jagielski return PageHolderObject< page >::guard (m_xPage, nAddr);
49*b1cdbd2cSJim Jagielski }
50*b1cdbd2cSJim Jagielski
51*b1cdbd2cSJim Jagielski /*
52*b1cdbd2cSJim Jagielski * verify.
53*b1cdbd2cSJim Jagielski */
verify(sal_uInt32 nAddr) const54*b1cdbd2cSJim Jagielski storeError OStoreDataPageObject::verify (sal_uInt32 nAddr) const
55*b1cdbd2cSJim Jagielski {
56*b1cdbd2cSJim Jagielski return PageHolderObject< page >::verify (m_xPage, nAddr);
57*b1cdbd2cSJim Jagielski }
58*b1cdbd2cSJim Jagielski
59*b1cdbd2cSJim Jagielski /*========================================================================
60*b1cdbd2cSJim Jagielski *
61*b1cdbd2cSJim Jagielski * OStoreIndirectionPageObject implementation.
62*b1cdbd2cSJim Jagielski *
63*b1cdbd2cSJim Jagielski *======================================================================*/
64*b1cdbd2cSJim Jagielski /*
65*b1cdbd2cSJim Jagielski * store_truncate_Impl (single indirect page).
66*b1cdbd2cSJim Jagielski */
store_truncate_Impl(sal_uInt32 nAddr,sal_uInt16 nSingle,OStorePageBIOS & rBIOS)67*b1cdbd2cSJim Jagielski static storeError store_truncate_Impl (
68*b1cdbd2cSJim Jagielski sal_uInt32 nAddr,
69*b1cdbd2cSJim Jagielski sal_uInt16 nSingle,
70*b1cdbd2cSJim Jagielski OStorePageBIOS &rBIOS)
71*b1cdbd2cSJim Jagielski {
72*b1cdbd2cSJim Jagielski if (nAddr != STORE_PAGE_NULL)
73*b1cdbd2cSJim Jagielski {
74*b1cdbd2cSJim Jagielski // Load single indirect page.
75*b1cdbd2cSJim Jagielski OStoreIndirectionPageObject aSingle;
76*b1cdbd2cSJim Jagielski storeError eErrCode = rBIOS.loadObjectAt (aSingle, nAddr);
77*b1cdbd2cSJim Jagielski if (eErrCode == store_E_None)
78*b1cdbd2cSJim Jagielski {
79*b1cdbd2cSJim Jagielski // Truncate to 'nSingle' direct pages.
80*b1cdbd2cSJim Jagielski eErrCode = aSingle.truncate (nSingle, rBIOS);
81*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
82*b1cdbd2cSJim Jagielski return eErrCode;
83*b1cdbd2cSJim Jagielski }
84*b1cdbd2cSJim Jagielski else
85*b1cdbd2cSJim Jagielski {
86*b1cdbd2cSJim Jagielski if (eErrCode != store_E_InvalidChecksum)
87*b1cdbd2cSJim Jagielski return eErrCode;
88*b1cdbd2cSJim Jagielski }
89*b1cdbd2cSJim Jagielski
90*b1cdbd2cSJim Jagielski // Check for complete truncation.
91*b1cdbd2cSJim Jagielski if (nSingle == 0)
92*b1cdbd2cSJim Jagielski {
93*b1cdbd2cSJim Jagielski // Free single indirect page.
94*b1cdbd2cSJim Jagielski eErrCode = rBIOS.free (nAddr);
95*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
96*b1cdbd2cSJim Jagielski return eErrCode;
97*b1cdbd2cSJim Jagielski }
98*b1cdbd2cSJim Jagielski }
99*b1cdbd2cSJim Jagielski return store_E_None;
100*b1cdbd2cSJim Jagielski }
101*b1cdbd2cSJim Jagielski
102*b1cdbd2cSJim Jagielski /*
103*b1cdbd2cSJim Jagielski * store_truncate_Impl (double indirect page).
104*b1cdbd2cSJim Jagielski */
store_truncate_Impl(sal_uInt32 nAddr,sal_uInt16 nDouble,sal_uInt16 nSingle,OStorePageBIOS & rBIOS)105*b1cdbd2cSJim Jagielski static storeError store_truncate_Impl (
106*b1cdbd2cSJim Jagielski sal_uInt32 nAddr,
107*b1cdbd2cSJim Jagielski sal_uInt16 nDouble,
108*b1cdbd2cSJim Jagielski sal_uInt16 nSingle,
109*b1cdbd2cSJim Jagielski OStorePageBIOS &rBIOS)
110*b1cdbd2cSJim Jagielski {
111*b1cdbd2cSJim Jagielski if (nAddr != STORE_PAGE_NULL)
112*b1cdbd2cSJim Jagielski {
113*b1cdbd2cSJim Jagielski // Load double indirect page.
114*b1cdbd2cSJim Jagielski OStoreIndirectionPageObject aDouble;
115*b1cdbd2cSJim Jagielski storeError eErrCode = rBIOS.loadObjectAt (aDouble, nAddr);
116*b1cdbd2cSJim Jagielski if (eErrCode == store_E_None)
117*b1cdbd2cSJim Jagielski {
118*b1cdbd2cSJim Jagielski // Truncate to 'nDouble', 'nSingle' pages.
119*b1cdbd2cSJim Jagielski eErrCode = aDouble.truncate (nDouble, nSingle, rBIOS);
120*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
121*b1cdbd2cSJim Jagielski return eErrCode;
122*b1cdbd2cSJim Jagielski }
123*b1cdbd2cSJim Jagielski else
124*b1cdbd2cSJim Jagielski {
125*b1cdbd2cSJim Jagielski if (eErrCode != store_E_InvalidChecksum)
126*b1cdbd2cSJim Jagielski return eErrCode;
127*b1cdbd2cSJim Jagielski }
128*b1cdbd2cSJim Jagielski
129*b1cdbd2cSJim Jagielski // Check for complete truncation.
130*b1cdbd2cSJim Jagielski if ((nDouble + nSingle) == 0)
131*b1cdbd2cSJim Jagielski {
132*b1cdbd2cSJim Jagielski // Free double indirect page.
133*b1cdbd2cSJim Jagielski eErrCode = rBIOS.free (nAddr);
134*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
135*b1cdbd2cSJim Jagielski return eErrCode;
136*b1cdbd2cSJim Jagielski }
137*b1cdbd2cSJim Jagielski }
138*b1cdbd2cSJim Jagielski return store_E_None;
139*b1cdbd2cSJim Jagielski }
140*b1cdbd2cSJim Jagielski
141*b1cdbd2cSJim Jagielski /*
142*b1cdbd2cSJim Jagielski * store_truncate_Impl (triple indirect page).
143*b1cdbd2cSJim Jagielski */
store_truncate_Impl(sal_uInt32 nAddr,sal_uInt16 nTriple,sal_uInt16 nDouble,sal_uInt16 nSingle,OStorePageBIOS & rBIOS)144*b1cdbd2cSJim Jagielski static storeError store_truncate_Impl (
145*b1cdbd2cSJim Jagielski sal_uInt32 nAddr,
146*b1cdbd2cSJim Jagielski sal_uInt16 nTriple,
147*b1cdbd2cSJim Jagielski sal_uInt16 nDouble,
148*b1cdbd2cSJim Jagielski sal_uInt16 nSingle,
149*b1cdbd2cSJim Jagielski OStorePageBIOS &rBIOS)
150*b1cdbd2cSJim Jagielski {
151*b1cdbd2cSJim Jagielski if (nAddr != STORE_PAGE_NULL)
152*b1cdbd2cSJim Jagielski {
153*b1cdbd2cSJim Jagielski // Load triple indirect page.
154*b1cdbd2cSJim Jagielski OStoreIndirectionPageObject aTriple;
155*b1cdbd2cSJim Jagielski storeError eErrCode = rBIOS.loadObjectAt (aTriple, nAddr);
156*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
157*b1cdbd2cSJim Jagielski return eErrCode;
158*b1cdbd2cSJim Jagielski
159*b1cdbd2cSJim Jagielski // Truncate to 'nTriple', 'nDouble', 'nSingle' pages.
160*b1cdbd2cSJim Jagielski eErrCode = aTriple.truncate (nTriple, nDouble, nSingle, rBIOS);
161*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
162*b1cdbd2cSJim Jagielski return eErrCode;
163*b1cdbd2cSJim Jagielski
164*b1cdbd2cSJim Jagielski // Check for complete truncation.
165*b1cdbd2cSJim Jagielski if ((nTriple + nDouble + nSingle) == 0)
166*b1cdbd2cSJim Jagielski {
167*b1cdbd2cSJim Jagielski // Free triple indirect page.
168*b1cdbd2cSJim Jagielski eErrCode = rBIOS.free (nAddr);
169*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
170*b1cdbd2cSJim Jagielski return eErrCode;
171*b1cdbd2cSJim Jagielski }
172*b1cdbd2cSJim Jagielski }
173*b1cdbd2cSJim Jagielski return store_E_None;
174*b1cdbd2cSJim Jagielski }
175*b1cdbd2cSJim Jagielski
176*b1cdbd2cSJim Jagielski /*
177*b1cdbd2cSJim Jagielski * loadOrCreate.
178*b1cdbd2cSJim Jagielski */
loadOrCreate(sal_uInt32 nAddr,OStorePageBIOS & rBIOS)179*b1cdbd2cSJim Jagielski storeError OStoreIndirectionPageObject::loadOrCreate (
180*b1cdbd2cSJim Jagielski sal_uInt32 nAddr,
181*b1cdbd2cSJim Jagielski OStorePageBIOS & rBIOS)
182*b1cdbd2cSJim Jagielski {
183*b1cdbd2cSJim Jagielski if (nAddr == STORE_PAGE_NULL)
184*b1cdbd2cSJim Jagielski {
185*b1cdbd2cSJim Jagielski storeError eErrCode = construct<page>(rBIOS.allocator());
186*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
187*b1cdbd2cSJim Jagielski return eErrCode;
188*b1cdbd2cSJim Jagielski
189*b1cdbd2cSJim Jagielski eErrCode = rBIOS.allocate (*this);
190*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
191*b1cdbd2cSJim Jagielski return eErrCode;
192*b1cdbd2cSJim Jagielski
193*b1cdbd2cSJim Jagielski // Save location pending at caller.
194*b1cdbd2cSJim Jagielski return store_E_Pending;
195*b1cdbd2cSJim Jagielski }
196*b1cdbd2cSJim Jagielski return rBIOS.loadObjectAt (*this, nAddr);
197*b1cdbd2cSJim Jagielski }
198*b1cdbd2cSJim Jagielski
199*b1cdbd2cSJim Jagielski /*
200*b1cdbd2cSJim Jagielski * guard.
201*b1cdbd2cSJim Jagielski */
guard(sal_uInt32 nAddr)202*b1cdbd2cSJim Jagielski storeError OStoreIndirectionPageObject::guard (sal_uInt32 nAddr)
203*b1cdbd2cSJim Jagielski {
204*b1cdbd2cSJim Jagielski return PageHolderObject< page >::guard (m_xPage, nAddr);
205*b1cdbd2cSJim Jagielski }
206*b1cdbd2cSJim Jagielski
207*b1cdbd2cSJim Jagielski /*
208*b1cdbd2cSJim Jagielski * verify.
209*b1cdbd2cSJim Jagielski */
verify(sal_uInt32 nAddr) const210*b1cdbd2cSJim Jagielski storeError OStoreIndirectionPageObject::verify (sal_uInt32 nAddr) const
211*b1cdbd2cSJim Jagielski {
212*b1cdbd2cSJim Jagielski return PageHolderObject< page >::verify (m_xPage, nAddr);
213*b1cdbd2cSJim Jagielski }
214*b1cdbd2cSJim Jagielski
215*b1cdbd2cSJim Jagielski /*
216*b1cdbd2cSJim Jagielski * read (single indirect).
217*b1cdbd2cSJim Jagielski */
read(sal_uInt16 nSingle,OStoreDataPageObject & rData,OStorePageBIOS & rBIOS)218*b1cdbd2cSJim Jagielski storeError OStoreIndirectionPageObject::read (
219*b1cdbd2cSJim Jagielski sal_uInt16 nSingle,
220*b1cdbd2cSJim Jagielski OStoreDataPageObject &rData,
221*b1cdbd2cSJim Jagielski OStorePageBIOS &rBIOS)
222*b1cdbd2cSJim Jagielski {
223*b1cdbd2cSJim Jagielski PageHolderObject< page > xImpl (m_xPage);
224*b1cdbd2cSJim Jagielski page const & rPage = (*xImpl);
225*b1cdbd2cSJim Jagielski
226*b1cdbd2cSJim Jagielski // Check arguments.
227*b1cdbd2cSJim Jagielski sal_uInt16 const nLimit = rPage.capacityCount();
228*b1cdbd2cSJim Jagielski if (!(nSingle < nLimit))
229*b1cdbd2cSJim Jagielski return store_E_InvalidAccess;
230*b1cdbd2cSJim Jagielski
231*b1cdbd2cSJim Jagielski // Obtain data page location.
232*b1cdbd2cSJim Jagielski sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[nSingle]);
233*b1cdbd2cSJim Jagielski if (nAddr == STORE_PAGE_NULL)
234*b1cdbd2cSJim Jagielski return store_E_NotExists;
235*b1cdbd2cSJim Jagielski
236*b1cdbd2cSJim Jagielski // Load data page and leave.
237*b1cdbd2cSJim Jagielski return rBIOS.loadObjectAt (rData, nAddr);
238*b1cdbd2cSJim Jagielski }
239*b1cdbd2cSJim Jagielski
240*b1cdbd2cSJim Jagielski /*
241*b1cdbd2cSJim Jagielski * read (double indirect).
242*b1cdbd2cSJim Jagielski */
read(sal_uInt16 nDouble,sal_uInt16 nSingle,OStoreDataPageObject & rData,OStorePageBIOS & rBIOS)243*b1cdbd2cSJim Jagielski storeError OStoreIndirectionPageObject::read (
244*b1cdbd2cSJim Jagielski sal_uInt16 nDouble,
245*b1cdbd2cSJim Jagielski sal_uInt16 nSingle,
246*b1cdbd2cSJim Jagielski OStoreDataPageObject &rData,
247*b1cdbd2cSJim Jagielski OStorePageBIOS &rBIOS)
248*b1cdbd2cSJim Jagielski {
249*b1cdbd2cSJim Jagielski PageHolderObject< page > xImpl (m_xPage);
250*b1cdbd2cSJim Jagielski page const & rPage = (*xImpl);
251*b1cdbd2cSJim Jagielski
252*b1cdbd2cSJim Jagielski // Check arguments.
253*b1cdbd2cSJim Jagielski sal_uInt16 const nLimit = rPage.capacityCount();
254*b1cdbd2cSJim Jagielski if (!((nDouble < nLimit) && (nSingle < nLimit)))
255*b1cdbd2cSJim Jagielski return store_E_InvalidAccess;
256*b1cdbd2cSJim Jagielski
257*b1cdbd2cSJim Jagielski // Check single indirect page location.
258*b1cdbd2cSJim Jagielski sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[nDouble]);
259*b1cdbd2cSJim Jagielski if (nAddr == STORE_PAGE_NULL)
260*b1cdbd2cSJim Jagielski return store_E_NotExists;
261*b1cdbd2cSJim Jagielski
262*b1cdbd2cSJim Jagielski // Load single indirect page.
263*b1cdbd2cSJim Jagielski OStoreIndirectionPageObject aSingle;
264*b1cdbd2cSJim Jagielski storeError eErrCode = rBIOS.loadObjectAt (aSingle, nAddr);
265*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
266*b1cdbd2cSJim Jagielski return eErrCode;
267*b1cdbd2cSJim Jagielski
268*b1cdbd2cSJim Jagielski // Read single indirect and leave.
269*b1cdbd2cSJim Jagielski return aSingle.read (nSingle, rData, rBIOS);
270*b1cdbd2cSJim Jagielski }
271*b1cdbd2cSJim Jagielski
272*b1cdbd2cSJim Jagielski /*
273*b1cdbd2cSJim Jagielski * read (triple indirect).
274*b1cdbd2cSJim Jagielski */
read(sal_uInt16 nTriple,sal_uInt16 nDouble,sal_uInt16 nSingle,OStoreDataPageObject & rData,OStorePageBIOS & rBIOS)275*b1cdbd2cSJim Jagielski storeError OStoreIndirectionPageObject::read (
276*b1cdbd2cSJim Jagielski sal_uInt16 nTriple,
277*b1cdbd2cSJim Jagielski sal_uInt16 nDouble,
278*b1cdbd2cSJim Jagielski sal_uInt16 nSingle,
279*b1cdbd2cSJim Jagielski OStoreDataPageObject &rData,
280*b1cdbd2cSJim Jagielski OStorePageBIOS &rBIOS)
281*b1cdbd2cSJim Jagielski {
282*b1cdbd2cSJim Jagielski PageHolderObject< page > xImpl (m_xPage);
283*b1cdbd2cSJim Jagielski page const & rPage = (*xImpl);
284*b1cdbd2cSJim Jagielski
285*b1cdbd2cSJim Jagielski // Check arguments.
286*b1cdbd2cSJim Jagielski sal_uInt16 const nLimit = rPage.capacityCount();
287*b1cdbd2cSJim Jagielski if (!((nTriple < nLimit) && (nDouble < nLimit) && (nSingle < nLimit)))
288*b1cdbd2cSJim Jagielski return store_E_InvalidAccess;
289*b1cdbd2cSJim Jagielski
290*b1cdbd2cSJim Jagielski // Check double indirect page location.
291*b1cdbd2cSJim Jagielski sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[nTriple]);
292*b1cdbd2cSJim Jagielski if (nAddr == STORE_PAGE_NULL)
293*b1cdbd2cSJim Jagielski return store_E_NotExists;
294*b1cdbd2cSJim Jagielski
295*b1cdbd2cSJim Jagielski // Load double indirect page.
296*b1cdbd2cSJim Jagielski OStoreIndirectionPageObject aDouble;
297*b1cdbd2cSJim Jagielski storeError eErrCode = rBIOS.loadObjectAt (aDouble, nAddr);
298*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
299*b1cdbd2cSJim Jagielski return eErrCode;
300*b1cdbd2cSJim Jagielski
301*b1cdbd2cSJim Jagielski // Read double indirect and leave.
302*b1cdbd2cSJim Jagielski return aDouble.read (nDouble, nSingle, rData, rBIOS);
303*b1cdbd2cSJim Jagielski }
304*b1cdbd2cSJim Jagielski
305*b1cdbd2cSJim Jagielski /*
306*b1cdbd2cSJim Jagielski * write (single indirect).
307*b1cdbd2cSJim Jagielski */
write(sal_uInt16 nSingle,OStoreDataPageObject & rData,OStorePageBIOS & rBIOS)308*b1cdbd2cSJim Jagielski storeError OStoreIndirectionPageObject::write (
309*b1cdbd2cSJim Jagielski sal_uInt16 nSingle,
310*b1cdbd2cSJim Jagielski OStoreDataPageObject &rData,
311*b1cdbd2cSJim Jagielski OStorePageBIOS &rBIOS)
312*b1cdbd2cSJim Jagielski {
313*b1cdbd2cSJim Jagielski PageHolderObject< page > xImpl (m_xPage);
314*b1cdbd2cSJim Jagielski page & rPage = (*xImpl);
315*b1cdbd2cSJim Jagielski
316*b1cdbd2cSJim Jagielski // Check arguments.
317*b1cdbd2cSJim Jagielski sal_uInt16 const nLimit = rPage.capacityCount();
318*b1cdbd2cSJim Jagielski if (!(nSingle < nLimit))
319*b1cdbd2cSJim Jagielski return store_E_InvalidAccess;
320*b1cdbd2cSJim Jagielski
321*b1cdbd2cSJim Jagielski // Obtain data page location.
322*b1cdbd2cSJim Jagielski sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[nSingle]);
323*b1cdbd2cSJim Jagielski if (nAddr == STORE_PAGE_NULL)
324*b1cdbd2cSJim Jagielski {
325*b1cdbd2cSJim Jagielski // Allocate data page.
326*b1cdbd2cSJim Jagielski storeError eErrCode = rBIOS.allocate (rData);
327*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
328*b1cdbd2cSJim Jagielski return eErrCode;
329*b1cdbd2cSJim Jagielski
330*b1cdbd2cSJim Jagielski // Store data page location.
331*b1cdbd2cSJim Jagielski rPage.m_pData[nSingle] = store::htonl(rData.location());
332*b1cdbd2cSJim Jagielski
333*b1cdbd2cSJim Jagielski // Save this page.
334*b1cdbd2cSJim Jagielski return rBIOS.saveObjectAt (*this, location());
335*b1cdbd2cSJim Jagielski }
336*b1cdbd2cSJim Jagielski else
337*b1cdbd2cSJim Jagielski {
338*b1cdbd2cSJim Jagielski // Save data page.
339*b1cdbd2cSJim Jagielski return rBIOS.saveObjectAt (rData, nAddr);
340*b1cdbd2cSJim Jagielski }
341*b1cdbd2cSJim Jagielski }
342*b1cdbd2cSJim Jagielski
343*b1cdbd2cSJim Jagielski /*
344*b1cdbd2cSJim Jagielski * write (double indirect).
345*b1cdbd2cSJim Jagielski */
write(sal_uInt16 nDouble,sal_uInt16 nSingle,OStoreDataPageObject & rData,OStorePageBIOS & rBIOS)346*b1cdbd2cSJim Jagielski storeError OStoreIndirectionPageObject::write (
347*b1cdbd2cSJim Jagielski sal_uInt16 nDouble,
348*b1cdbd2cSJim Jagielski sal_uInt16 nSingle,
349*b1cdbd2cSJim Jagielski OStoreDataPageObject &rData,
350*b1cdbd2cSJim Jagielski OStorePageBIOS &rBIOS)
351*b1cdbd2cSJim Jagielski {
352*b1cdbd2cSJim Jagielski PageHolderObject< page > xImpl (m_xPage);
353*b1cdbd2cSJim Jagielski page & rPage = (*xImpl);
354*b1cdbd2cSJim Jagielski
355*b1cdbd2cSJim Jagielski // Check arguments.
356*b1cdbd2cSJim Jagielski sal_uInt16 const nLimit = rPage.capacityCount();
357*b1cdbd2cSJim Jagielski if (!((nDouble < nLimit) && (nSingle < nLimit)))
358*b1cdbd2cSJim Jagielski return store_E_InvalidAccess;
359*b1cdbd2cSJim Jagielski
360*b1cdbd2cSJim Jagielski // Load or create single indirect page.
361*b1cdbd2cSJim Jagielski OStoreIndirectionPageObject aSingle;
362*b1cdbd2cSJim Jagielski storeError eErrCode = aSingle.loadOrCreate (store::ntohl(rPage.m_pData[nDouble]), rBIOS);
363*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
364*b1cdbd2cSJim Jagielski {
365*b1cdbd2cSJim Jagielski if (eErrCode != store_E_Pending)
366*b1cdbd2cSJim Jagielski return eErrCode;
367*b1cdbd2cSJim Jagielski rPage.m_pData[nDouble] = store::htonl(aSingle.location());
368*b1cdbd2cSJim Jagielski
369*b1cdbd2cSJim Jagielski eErrCode = rBIOS.saveObjectAt (*this, location());
370*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
371*b1cdbd2cSJim Jagielski return eErrCode;
372*b1cdbd2cSJim Jagielski }
373*b1cdbd2cSJim Jagielski
374*b1cdbd2cSJim Jagielski // Write single indirect and leave.
375*b1cdbd2cSJim Jagielski return aSingle.write (nSingle, rData, rBIOS);
376*b1cdbd2cSJim Jagielski }
377*b1cdbd2cSJim Jagielski
378*b1cdbd2cSJim Jagielski /*
379*b1cdbd2cSJim Jagielski * write (triple indirect).
380*b1cdbd2cSJim Jagielski */
write(sal_uInt16 nTriple,sal_uInt16 nDouble,sal_uInt16 nSingle,OStoreDataPageObject & rData,OStorePageBIOS & rBIOS)381*b1cdbd2cSJim Jagielski storeError OStoreIndirectionPageObject::write (
382*b1cdbd2cSJim Jagielski sal_uInt16 nTriple,
383*b1cdbd2cSJim Jagielski sal_uInt16 nDouble,
384*b1cdbd2cSJim Jagielski sal_uInt16 nSingle,
385*b1cdbd2cSJim Jagielski OStoreDataPageObject &rData,
386*b1cdbd2cSJim Jagielski OStorePageBIOS &rBIOS)
387*b1cdbd2cSJim Jagielski {
388*b1cdbd2cSJim Jagielski PageHolderObject< page > xImpl (m_xPage);
389*b1cdbd2cSJim Jagielski page & rPage = (*xImpl);
390*b1cdbd2cSJim Jagielski
391*b1cdbd2cSJim Jagielski // Check arguments.
392*b1cdbd2cSJim Jagielski sal_uInt16 const nLimit = rPage.capacityCount();
393*b1cdbd2cSJim Jagielski if (!((nTriple < nLimit) && (nDouble < nLimit) && (nSingle < nLimit)))
394*b1cdbd2cSJim Jagielski return store_E_InvalidAccess;
395*b1cdbd2cSJim Jagielski
396*b1cdbd2cSJim Jagielski // Load or create double indirect page.
397*b1cdbd2cSJim Jagielski OStoreIndirectionPageObject aDouble;
398*b1cdbd2cSJim Jagielski storeError eErrCode = aDouble.loadOrCreate (store::ntohl(rPage.m_pData[nTriple]), rBIOS);
399*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
400*b1cdbd2cSJim Jagielski {
401*b1cdbd2cSJim Jagielski if (eErrCode != store_E_Pending)
402*b1cdbd2cSJim Jagielski return eErrCode;
403*b1cdbd2cSJim Jagielski rPage.m_pData[nTriple] = store::htonl(aDouble.location());
404*b1cdbd2cSJim Jagielski
405*b1cdbd2cSJim Jagielski eErrCode = rBIOS.saveObjectAt (*this, location());
406*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
407*b1cdbd2cSJim Jagielski return eErrCode;
408*b1cdbd2cSJim Jagielski }
409*b1cdbd2cSJim Jagielski
410*b1cdbd2cSJim Jagielski // Write double indirect and leave.
411*b1cdbd2cSJim Jagielski return aDouble.write (nDouble, nSingle, rData, rBIOS);
412*b1cdbd2cSJim Jagielski }
413*b1cdbd2cSJim Jagielski
414*b1cdbd2cSJim Jagielski /*
415*b1cdbd2cSJim Jagielski * truncate (single indirect).
416*b1cdbd2cSJim Jagielski */
truncate(sal_uInt16 nSingle,OStorePageBIOS & rBIOS)417*b1cdbd2cSJim Jagielski storeError OStoreIndirectionPageObject::truncate (
418*b1cdbd2cSJim Jagielski sal_uInt16 nSingle,
419*b1cdbd2cSJim Jagielski OStorePageBIOS & rBIOS)
420*b1cdbd2cSJim Jagielski {
421*b1cdbd2cSJim Jagielski PageHolderObject< page > xImpl (m_xPage);
422*b1cdbd2cSJim Jagielski page & rPage = (*xImpl);
423*b1cdbd2cSJim Jagielski
424*b1cdbd2cSJim Jagielski // Check arguments.
425*b1cdbd2cSJim Jagielski sal_uInt16 const nLimit = rPage.capacityCount();
426*b1cdbd2cSJim Jagielski if (!(nSingle < nLimit))
427*b1cdbd2cSJim Jagielski return store_E_InvalidAccess;
428*b1cdbd2cSJim Jagielski
429*b1cdbd2cSJim Jagielski // Truncate.
430*b1cdbd2cSJim Jagielski storeError eErrCode = store_E_None;
431*b1cdbd2cSJim Jagielski for (sal_uInt16 i = nLimit; i > nSingle; i--)
432*b1cdbd2cSJim Jagielski {
433*b1cdbd2cSJim Jagielski // Obtain data page location.
434*b1cdbd2cSJim Jagielski sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[i - 1]);
435*b1cdbd2cSJim Jagielski if (nAddr != STORE_PAGE_NULL)
436*b1cdbd2cSJim Jagielski {
437*b1cdbd2cSJim Jagielski // Free data page.
438*b1cdbd2cSJim Jagielski eErrCode = rBIOS.free (nAddr);
439*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
440*b1cdbd2cSJim Jagielski return eErrCode;
441*b1cdbd2cSJim Jagielski
442*b1cdbd2cSJim Jagielski // Clear pointer to data page.
443*b1cdbd2cSJim Jagielski rPage.m_pData[i - 1] = STORE_PAGE_NULL;
444*b1cdbd2cSJim Jagielski touch();
445*b1cdbd2cSJim Jagielski }
446*b1cdbd2cSJim Jagielski }
447*b1cdbd2cSJim Jagielski
448*b1cdbd2cSJim Jagielski // Check for modified page.
449*b1cdbd2cSJim Jagielski if (dirty())
450*b1cdbd2cSJim Jagielski {
451*b1cdbd2cSJim Jagielski // Save this page.
452*b1cdbd2cSJim Jagielski eErrCode = rBIOS.saveObjectAt (*this, location());
453*b1cdbd2cSJim Jagielski }
454*b1cdbd2cSJim Jagielski
455*b1cdbd2cSJim Jagielski // Done.
456*b1cdbd2cSJim Jagielski return eErrCode;
457*b1cdbd2cSJim Jagielski }
458*b1cdbd2cSJim Jagielski
459*b1cdbd2cSJim Jagielski /*
460*b1cdbd2cSJim Jagielski * truncate (double indirect).
461*b1cdbd2cSJim Jagielski */
truncate(sal_uInt16 nDouble,sal_uInt16 nSingle,OStorePageBIOS & rBIOS)462*b1cdbd2cSJim Jagielski storeError OStoreIndirectionPageObject::truncate (
463*b1cdbd2cSJim Jagielski sal_uInt16 nDouble,
464*b1cdbd2cSJim Jagielski sal_uInt16 nSingle,
465*b1cdbd2cSJim Jagielski OStorePageBIOS &rBIOS)
466*b1cdbd2cSJim Jagielski {
467*b1cdbd2cSJim Jagielski PageHolderObject< page > xImpl (m_xPage);
468*b1cdbd2cSJim Jagielski page & rPage = (*xImpl);
469*b1cdbd2cSJim Jagielski
470*b1cdbd2cSJim Jagielski // Check arguments.
471*b1cdbd2cSJim Jagielski sal_uInt16 const nLimit = rPage.capacityCount();
472*b1cdbd2cSJim Jagielski if (!((nDouble < nLimit) && (nSingle < nLimit)))
473*b1cdbd2cSJim Jagielski return store_E_InvalidAccess;
474*b1cdbd2cSJim Jagielski
475*b1cdbd2cSJim Jagielski // Truncate.
476*b1cdbd2cSJim Jagielski storeError eErrCode = store_E_None;
477*b1cdbd2cSJim Jagielski for (sal_uInt16 i = nLimit; i > nDouble + 1; i--)
478*b1cdbd2cSJim Jagielski {
479*b1cdbd2cSJim Jagielski // Truncate single indirect page to zero direct pages.
480*b1cdbd2cSJim Jagielski eErrCode = store_truncate_Impl (store::ntohl(rPage.m_pData[i - 1]), 0, rBIOS);
481*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
482*b1cdbd2cSJim Jagielski return eErrCode;
483*b1cdbd2cSJim Jagielski
484*b1cdbd2cSJim Jagielski // Clear pointer to single indirect page.
485*b1cdbd2cSJim Jagielski rPage.m_pData[i - 1] = STORE_PAGE_NULL;
486*b1cdbd2cSJim Jagielski touch();
487*b1cdbd2cSJim Jagielski }
488*b1cdbd2cSJim Jagielski
489*b1cdbd2cSJim Jagielski // Truncate last single indirect page to 'nSingle' direct pages.
490*b1cdbd2cSJim Jagielski eErrCode = store_truncate_Impl (store::ntohl(rPage.m_pData[nDouble]), nSingle, rBIOS);
491*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
492*b1cdbd2cSJim Jagielski return eErrCode;
493*b1cdbd2cSJim Jagielski
494*b1cdbd2cSJim Jagielski // Check for complete truncation.
495*b1cdbd2cSJim Jagielski if (nSingle == 0)
496*b1cdbd2cSJim Jagielski {
497*b1cdbd2cSJim Jagielski // Clear pointer to last single indirect page.
498*b1cdbd2cSJim Jagielski rPage.m_pData[nDouble] = STORE_PAGE_NULL;
499*b1cdbd2cSJim Jagielski touch();
500*b1cdbd2cSJim Jagielski }
501*b1cdbd2cSJim Jagielski
502*b1cdbd2cSJim Jagielski // Check for modified page.
503*b1cdbd2cSJim Jagielski if (dirty())
504*b1cdbd2cSJim Jagielski {
505*b1cdbd2cSJim Jagielski // Save this page.
506*b1cdbd2cSJim Jagielski eErrCode = rBIOS.saveObjectAt (*this, location());
507*b1cdbd2cSJim Jagielski }
508*b1cdbd2cSJim Jagielski
509*b1cdbd2cSJim Jagielski // Done.
510*b1cdbd2cSJim Jagielski return eErrCode;
511*b1cdbd2cSJim Jagielski }
512*b1cdbd2cSJim Jagielski
513*b1cdbd2cSJim Jagielski /*
514*b1cdbd2cSJim Jagielski * truncate (triple indirect).
515*b1cdbd2cSJim Jagielski */
truncate(sal_uInt16 nTriple,sal_uInt16 nDouble,sal_uInt16 nSingle,OStorePageBIOS & rBIOS)516*b1cdbd2cSJim Jagielski storeError OStoreIndirectionPageObject::truncate (
517*b1cdbd2cSJim Jagielski sal_uInt16 nTriple,
518*b1cdbd2cSJim Jagielski sal_uInt16 nDouble,
519*b1cdbd2cSJim Jagielski sal_uInt16 nSingle,
520*b1cdbd2cSJim Jagielski OStorePageBIOS &rBIOS)
521*b1cdbd2cSJim Jagielski {
522*b1cdbd2cSJim Jagielski PageHolderObject< page > xImpl (m_xPage);
523*b1cdbd2cSJim Jagielski page & rPage = (*xImpl);
524*b1cdbd2cSJim Jagielski
525*b1cdbd2cSJim Jagielski // Check arguments.
526*b1cdbd2cSJim Jagielski sal_uInt16 const nLimit = rPage.capacityCount();
527*b1cdbd2cSJim Jagielski if (!((nTriple < nLimit) && (nDouble < nLimit) && (nSingle < nLimit)))
528*b1cdbd2cSJim Jagielski return store_E_InvalidAccess;
529*b1cdbd2cSJim Jagielski
530*b1cdbd2cSJim Jagielski // Truncate.
531*b1cdbd2cSJim Jagielski storeError eErrCode = store_E_None;
532*b1cdbd2cSJim Jagielski for (sal_uInt16 i = nLimit; i > nTriple + 1; i--)
533*b1cdbd2cSJim Jagielski {
534*b1cdbd2cSJim Jagielski // Truncate double indirect page to zero single indirect pages.
535*b1cdbd2cSJim Jagielski eErrCode = store_truncate_Impl (store::ntohl(rPage.m_pData[i - 1]), 0, 0, rBIOS);
536*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
537*b1cdbd2cSJim Jagielski return eErrCode;
538*b1cdbd2cSJim Jagielski
539*b1cdbd2cSJim Jagielski // Clear pointer to double indirect page.
540*b1cdbd2cSJim Jagielski rPage.m_pData[i - 1] = STORE_PAGE_NULL;
541*b1cdbd2cSJim Jagielski touch();
542*b1cdbd2cSJim Jagielski }
543*b1cdbd2cSJim Jagielski
544*b1cdbd2cSJim Jagielski // Truncate last double indirect page to 'nDouble', 'nSingle' pages.
545*b1cdbd2cSJim Jagielski eErrCode = store_truncate_Impl (store::ntohl(rPage.m_pData[nTriple]), nDouble, nSingle, rBIOS);
546*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
547*b1cdbd2cSJim Jagielski return eErrCode;
548*b1cdbd2cSJim Jagielski
549*b1cdbd2cSJim Jagielski // Check for complete truncation.
550*b1cdbd2cSJim Jagielski if ((nDouble + nSingle) == 0)
551*b1cdbd2cSJim Jagielski {
552*b1cdbd2cSJim Jagielski // Clear pointer to last double indirect page.
553*b1cdbd2cSJim Jagielski rPage.m_pData[nTriple] = STORE_PAGE_NULL;
554*b1cdbd2cSJim Jagielski touch();
555*b1cdbd2cSJim Jagielski }
556*b1cdbd2cSJim Jagielski
557*b1cdbd2cSJim Jagielski // Check for modified page.
558*b1cdbd2cSJim Jagielski if (dirty())
559*b1cdbd2cSJim Jagielski {
560*b1cdbd2cSJim Jagielski // Save this page.
561*b1cdbd2cSJim Jagielski eErrCode = rBIOS.saveObjectAt (*this, location());
562*b1cdbd2cSJim Jagielski }
563*b1cdbd2cSJim Jagielski
564*b1cdbd2cSJim Jagielski // Done.
565*b1cdbd2cSJim Jagielski return eErrCode;
566*b1cdbd2cSJim Jagielski }
567*b1cdbd2cSJim Jagielski
568*b1cdbd2cSJim Jagielski /*========================================================================
569*b1cdbd2cSJim Jagielski *
570*b1cdbd2cSJim Jagielski * OStoreDirectoryPageObject implementation.
571*b1cdbd2cSJim Jagielski *
572*b1cdbd2cSJim Jagielski *======================================================================*/
573*b1cdbd2cSJim Jagielski /*
574*b1cdbd2cSJim Jagielski * guard.
575*b1cdbd2cSJim Jagielski */
guard(sal_uInt32 nAddr)576*b1cdbd2cSJim Jagielski storeError OStoreDirectoryPageObject::guard (sal_uInt32 nAddr)
577*b1cdbd2cSJim Jagielski {
578*b1cdbd2cSJim Jagielski return PageHolderObject< page >::guard (m_xPage, nAddr);
579*b1cdbd2cSJim Jagielski }
580*b1cdbd2cSJim Jagielski
581*b1cdbd2cSJim Jagielski /*
582*b1cdbd2cSJim Jagielski * verify.
583*b1cdbd2cSJim Jagielski */
verify(sal_uInt32 nAddr) const584*b1cdbd2cSJim Jagielski storeError OStoreDirectoryPageObject::verify (sal_uInt32 nAddr) const
585*b1cdbd2cSJim Jagielski {
586*b1cdbd2cSJim Jagielski return PageHolderObject< page >::verify (m_xPage, nAddr);
587*b1cdbd2cSJim Jagielski // OLD: m_rPage.verifyVersion (STORE_MAGIC_DIRECTORYPAGE);
588*b1cdbd2cSJim Jagielski }
589*b1cdbd2cSJim Jagielski
590*b1cdbd2cSJim Jagielski /*
591*b1cdbd2cSJim Jagielski * scope (external data page; private).
592*b1cdbd2cSJim Jagielski */
593*b1cdbd2cSJim Jagielski OStoreDirectoryPageData::ChunkScope
scope(sal_uInt32 nPage,page::DataBlock::LinkDescriptor & rDescr) const594*b1cdbd2cSJim Jagielski OStoreDirectoryPageObject::scope (
595*b1cdbd2cSJim Jagielski sal_uInt32 nPage,
596*b1cdbd2cSJim Jagielski page::DataBlock::LinkDescriptor &rDescr) const
597*b1cdbd2cSJim Jagielski {
598*b1cdbd2cSJim Jagielski page const & rPage = PAGE();
599*b1cdbd2cSJim Jagielski OStoreDirectoryDataBlock const & rDataBlock = rPage.m_aDataBlock;
600*b1cdbd2cSJim Jagielski
601*b1cdbd2cSJim Jagielski sal_uInt32 index0, index1, index2, index3;
602*b1cdbd2cSJim Jagielski
603*b1cdbd2cSJim Jagielski // direct.
604*b1cdbd2cSJim Jagielski sal_uInt32 nCount = rDataBlock.directCount();
605*b1cdbd2cSJim Jagielski sal_uInt32 nLimit = nCount;
606*b1cdbd2cSJim Jagielski if (nPage < nLimit)
607*b1cdbd2cSJim Jagielski {
608*b1cdbd2cSJim Jagielski // Page to index reduction.
609*b1cdbd2cSJim Jagielski index0 = nPage;
610*b1cdbd2cSJim Jagielski
611*b1cdbd2cSJim Jagielski // Setup LinkDescriptor indices.
612*b1cdbd2cSJim Jagielski rDescr.m_nIndex0 = (sal_uInt16)(index0 & 0xffff);
613*b1cdbd2cSJim Jagielski
614*b1cdbd2cSJim Jagielski // Done.
615*b1cdbd2cSJim Jagielski return page::SCOPE_DIRECT;
616*b1cdbd2cSJim Jagielski }
617*b1cdbd2cSJim Jagielski nPage -= nLimit;
618*b1cdbd2cSJim Jagielski
619*b1cdbd2cSJim Jagielski // single indirect.
620*b1cdbd2cSJim Jagielski sal_uInt32 const nCapacity = indirect::capacityCount(rPage.m_aDescr);
621*b1cdbd2cSJim Jagielski nCount = rDataBlock.singleCount();
622*b1cdbd2cSJim Jagielski nLimit = nCount * nCapacity;
623*b1cdbd2cSJim Jagielski if (nPage < nLimit)
624*b1cdbd2cSJim Jagielski {
625*b1cdbd2cSJim Jagielski // Page to index reduction.
626*b1cdbd2cSJim Jagielski sal_uInt32 n = nPage;
627*b1cdbd2cSJim Jagielski
628*b1cdbd2cSJim Jagielski // Reduce to single indirect i(1), direct n = i(0).
629*b1cdbd2cSJim Jagielski index1 = n / nCapacity;
630*b1cdbd2cSJim Jagielski index0 = n % nCapacity;
631*b1cdbd2cSJim Jagielski
632*b1cdbd2cSJim Jagielski // Verify reduction.
633*b1cdbd2cSJim Jagielski n = index1 * nCapacity + index0;
634*b1cdbd2cSJim Jagielski OSL_POSTCOND(n == nPage, "wrong math on indirect indices");
635*b1cdbd2cSJim Jagielski if (n != nPage)
636*b1cdbd2cSJim Jagielski return page::SCOPE_UNKNOWN;
637*b1cdbd2cSJim Jagielski
638*b1cdbd2cSJim Jagielski // Setup LinkDescriptor indices.
639*b1cdbd2cSJim Jagielski rDescr.m_nIndex0 = (sal_uInt16)(index0 & 0xffff);
640*b1cdbd2cSJim Jagielski rDescr.m_nIndex1 = (sal_uInt16)(index1 & 0xffff);
641*b1cdbd2cSJim Jagielski
642*b1cdbd2cSJim Jagielski // Done.
643*b1cdbd2cSJim Jagielski return page::SCOPE_SINGLE;
644*b1cdbd2cSJim Jagielski }
645*b1cdbd2cSJim Jagielski nPage -= nLimit;
646*b1cdbd2cSJim Jagielski
647*b1cdbd2cSJim Jagielski // double indirect.
648*b1cdbd2cSJim Jagielski nCount = rDataBlock.doubleCount();
649*b1cdbd2cSJim Jagielski nLimit = nCount * nCapacity * nCapacity;
650*b1cdbd2cSJim Jagielski if (nPage < nLimit)
651*b1cdbd2cSJim Jagielski {
652*b1cdbd2cSJim Jagielski // Page to index reduction.
653*b1cdbd2cSJim Jagielski sal_uInt32 n = nPage;
654*b1cdbd2cSJim Jagielski
655*b1cdbd2cSJim Jagielski // Reduce to double indirect i(2), single indirect n = i(0).
656*b1cdbd2cSJim Jagielski index2 = n / (nCapacity * nCapacity);
657*b1cdbd2cSJim Jagielski n = n % (nCapacity * nCapacity);
658*b1cdbd2cSJim Jagielski
659*b1cdbd2cSJim Jagielski // Reduce to single indirect i(1), direct n = i(0).
660*b1cdbd2cSJim Jagielski index1 = n / nCapacity;
661*b1cdbd2cSJim Jagielski index0 = n % nCapacity;
662*b1cdbd2cSJim Jagielski
663*b1cdbd2cSJim Jagielski // Verify reduction.
664*b1cdbd2cSJim Jagielski n = index2 * nCapacity * nCapacity +
665*b1cdbd2cSJim Jagielski index1 * nCapacity + index0;
666*b1cdbd2cSJim Jagielski OSL_POSTCOND(n == nPage, "wrong math on double indirect indices");
667*b1cdbd2cSJim Jagielski if (n != nPage)
668*b1cdbd2cSJim Jagielski return page::SCOPE_UNKNOWN;
669*b1cdbd2cSJim Jagielski
670*b1cdbd2cSJim Jagielski // Setup LinkDescriptor indices.
671*b1cdbd2cSJim Jagielski rDescr.m_nIndex0 = (sal_uInt16)(index0 & 0xffff);
672*b1cdbd2cSJim Jagielski rDescr.m_nIndex1 = (sal_uInt16)(index1 & 0xffff);
673*b1cdbd2cSJim Jagielski rDescr.m_nIndex2 = (sal_uInt16)(index2 & 0xffff);
674*b1cdbd2cSJim Jagielski
675*b1cdbd2cSJim Jagielski // Done.
676*b1cdbd2cSJim Jagielski return page::SCOPE_DOUBLE;
677*b1cdbd2cSJim Jagielski }
678*b1cdbd2cSJim Jagielski nPage -= nLimit;
679*b1cdbd2cSJim Jagielski
680*b1cdbd2cSJim Jagielski // triple indirect.
681*b1cdbd2cSJim Jagielski nCount = rDataBlock.tripleCount();
682*b1cdbd2cSJim Jagielski nLimit = nCount * nCapacity * nCapacity * nCapacity;
683*b1cdbd2cSJim Jagielski if (nPage < nLimit)
684*b1cdbd2cSJim Jagielski {
685*b1cdbd2cSJim Jagielski // Page to index reduction.
686*b1cdbd2cSJim Jagielski sal_uInt32 n = nPage;
687*b1cdbd2cSJim Jagielski
688*b1cdbd2cSJim Jagielski // Reduce to triple indirect i(3), double indirect n.
689*b1cdbd2cSJim Jagielski index3 = n / (nCapacity * nCapacity * nCapacity);
690*b1cdbd2cSJim Jagielski n = n % (nCapacity * nCapacity * nCapacity);
691*b1cdbd2cSJim Jagielski
692*b1cdbd2cSJim Jagielski // Reduce to double indirect i(2), single indirect n.
693*b1cdbd2cSJim Jagielski index2 = n / (nCapacity * nCapacity);
694*b1cdbd2cSJim Jagielski n = n % (nCapacity * nCapacity);
695*b1cdbd2cSJim Jagielski
696*b1cdbd2cSJim Jagielski // Reduce to single indirect i(1), direct n = i(0).
697*b1cdbd2cSJim Jagielski index1 = n / nCapacity;
698*b1cdbd2cSJim Jagielski index0 = n % nCapacity;
699*b1cdbd2cSJim Jagielski
700*b1cdbd2cSJim Jagielski // Verify reduction.
701*b1cdbd2cSJim Jagielski n = index3 * nCapacity * nCapacity * nCapacity +
702*b1cdbd2cSJim Jagielski index2 * nCapacity * nCapacity +
703*b1cdbd2cSJim Jagielski index1 * nCapacity + index0;
704*b1cdbd2cSJim Jagielski OSL_POSTCOND(n == nPage, "wrong math on triple indirect indices");
705*b1cdbd2cSJim Jagielski if (n != nPage)
706*b1cdbd2cSJim Jagielski return page::SCOPE_UNKNOWN;
707*b1cdbd2cSJim Jagielski
708*b1cdbd2cSJim Jagielski // Setup LinkDescriptor indices.
709*b1cdbd2cSJim Jagielski rDescr.m_nIndex0 = (sal_uInt16)(index0 & 0xffff);
710*b1cdbd2cSJim Jagielski rDescr.m_nIndex1 = (sal_uInt16)(index1 & 0xffff);
711*b1cdbd2cSJim Jagielski rDescr.m_nIndex2 = (sal_uInt16)(index2 & 0xffff);
712*b1cdbd2cSJim Jagielski rDescr.m_nIndex3 = (sal_uInt16)(index3 & 0xffff);
713*b1cdbd2cSJim Jagielski
714*b1cdbd2cSJim Jagielski // Done.
715*b1cdbd2cSJim Jagielski return page::SCOPE_TRIPLE;
716*b1cdbd2cSJim Jagielski }
717*b1cdbd2cSJim Jagielski
718*b1cdbd2cSJim Jagielski // Unreachable (more than triple indirect).
719*b1cdbd2cSJim Jagielski return page::SCOPE_UNREACHABLE;
720*b1cdbd2cSJim Jagielski }
721*b1cdbd2cSJim Jagielski
722*b1cdbd2cSJim Jagielski #if 0 /* NYI */
723*b1cdbd2cSJim Jagielski /*
724*b1cdbd2cSJim Jagielski * chunk (external data page).
725*b1cdbd2cSJim Jagielski */
726*b1cdbd2cSJim Jagielski inode::ChunkDescriptor OStoreDirectoryPageObject::chunk (sal_uInt32 nOffset)
727*b1cdbd2cSJim Jagielski {
728*b1cdbd2cSJim Jagielski // @@@ INSUFFICIENT: NEED SCOPE AS WELL @@@
729*b1cdbd2cSJim Jagielski sal_uInt32 nCapacity = m_rPage.capacity();
730*b1cdbd2cSJim Jagielski if (nOffset < nCapacity)
731*b1cdbd2cSJim Jagielski // Internal scope (inode page).
732*b1cdbd2cSJim Jagielski return inode::ChunkDescriptor (nOffset, nCapacity);
733*b1cdbd2cSJim Jagielski else
734*b1cdbd2cSJim Jagielski // External scope (data page).
735*b1cdbd2cSJim Jagielski return inode::ChunkDescriptor (nOffset - nCapacity, data::capacity(m_rPage.m_aDescr));
736*b1cdbd2cSJim Jagielski
737*b1cdbd2cSJim Jagielski inode::ChunkScope eScope = m_rPage.scope(nOffset);
738*b1cdbd2cSJim Jagielski if (eScope == inode::SCOPE_INTERNAL)
739*b1cdbd2cSJim Jagielski // Inode page (internal scope).
740*b1cdbd2cSJim Jagielski return inode::ChunkDescriptor (nOffset, m_rPage.capacity());
741*b1cdbd2cSJim Jagielski else
742*b1cdbd2cSJim Jagielski // Data page (external scope).
743*b1cdbd2cSJim Jagielski return inode::ChunkDescriptor (nOffset - m_rPage.capacity(), data::capacity(m_rPage.m_aDescr));
744*b1cdbd2cSJim Jagielski }
745*b1cdbd2cSJim Jagielski #endif /* NYI */
746*b1cdbd2cSJim Jagielski
747*b1cdbd2cSJim Jagielski /*
748*b1cdbd2cSJim Jagielski * read (external data page).
749*b1cdbd2cSJim Jagielski */
read(sal_uInt32 nPage,OStoreDataPageObject & rData,OStorePageBIOS & rBIOS)750*b1cdbd2cSJim Jagielski storeError OStoreDirectoryPageObject::read (
751*b1cdbd2cSJim Jagielski sal_uInt32 nPage,
752*b1cdbd2cSJim Jagielski OStoreDataPageObject &rData,
753*b1cdbd2cSJim Jagielski OStorePageBIOS &rBIOS)
754*b1cdbd2cSJim Jagielski {
755*b1cdbd2cSJim Jagielski // Determine scope and link indices.
756*b1cdbd2cSJim Jagielski page::DataBlock::LinkDescriptor aLink;
757*b1cdbd2cSJim Jagielski page::ChunkScope eScope = scope (nPage, aLink);
758*b1cdbd2cSJim Jagielski
759*b1cdbd2cSJim Jagielski storeError eErrCode = store_E_None;
760*b1cdbd2cSJim Jagielski if (eScope == page::SCOPE_DIRECT)
761*b1cdbd2cSJim Jagielski {
762*b1cdbd2cSJim Jagielski sal_uInt32 const nAddr = directLink (aLink.m_nIndex0);
763*b1cdbd2cSJim Jagielski if (nAddr == STORE_PAGE_NULL)
764*b1cdbd2cSJim Jagielski return store_E_NotExists;
765*b1cdbd2cSJim Jagielski
766*b1cdbd2cSJim Jagielski eErrCode = rBIOS.loadObjectAt (rData, nAddr);
767*b1cdbd2cSJim Jagielski }
768*b1cdbd2cSJim Jagielski else if (eScope == page::SCOPE_SINGLE)
769*b1cdbd2cSJim Jagielski {
770*b1cdbd2cSJim Jagielski sal_uInt32 const nAddr = singleLink (aLink.m_nIndex1);
771*b1cdbd2cSJim Jagielski if (nAddr == STORE_PAGE_NULL)
772*b1cdbd2cSJim Jagielski return store_E_NotExists;
773*b1cdbd2cSJim Jagielski
774*b1cdbd2cSJim Jagielski OStoreIndirectionPageObject aSingle;
775*b1cdbd2cSJim Jagielski eErrCode = rBIOS.loadObjectAt (aSingle, nAddr);
776*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
777*b1cdbd2cSJim Jagielski return eErrCode;
778*b1cdbd2cSJim Jagielski
779*b1cdbd2cSJim Jagielski eErrCode = aSingle.read (aLink.m_nIndex0, rData, rBIOS);
780*b1cdbd2cSJim Jagielski }
781*b1cdbd2cSJim Jagielski else if (eScope == page::SCOPE_DOUBLE)
782*b1cdbd2cSJim Jagielski {
783*b1cdbd2cSJim Jagielski sal_uInt32 const nAddr = doubleLink (aLink.m_nIndex2);
784*b1cdbd2cSJim Jagielski if (nAddr == STORE_PAGE_NULL)
785*b1cdbd2cSJim Jagielski return store_E_NotExists;
786*b1cdbd2cSJim Jagielski
787*b1cdbd2cSJim Jagielski OStoreIndirectionPageObject aDouble;
788*b1cdbd2cSJim Jagielski eErrCode = rBIOS.loadObjectAt (aDouble, nAddr);
789*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
790*b1cdbd2cSJim Jagielski return eErrCode;
791*b1cdbd2cSJim Jagielski
792*b1cdbd2cSJim Jagielski eErrCode = aDouble.read (aLink.m_nIndex1, aLink.m_nIndex0, rData, rBIOS);
793*b1cdbd2cSJim Jagielski }
794*b1cdbd2cSJim Jagielski else if (eScope == page::SCOPE_TRIPLE)
795*b1cdbd2cSJim Jagielski {
796*b1cdbd2cSJim Jagielski sal_uInt32 const nAddr = tripleLink (aLink.m_nIndex3);
797*b1cdbd2cSJim Jagielski if (nAddr == STORE_PAGE_NULL)
798*b1cdbd2cSJim Jagielski return store_E_NotExists;
799*b1cdbd2cSJim Jagielski
800*b1cdbd2cSJim Jagielski OStoreIndirectionPageObject aTriple;
801*b1cdbd2cSJim Jagielski eErrCode = rBIOS.loadObjectAt (aTriple, nAddr);
802*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
803*b1cdbd2cSJim Jagielski return eErrCode;
804*b1cdbd2cSJim Jagielski
805*b1cdbd2cSJim Jagielski eErrCode = aTriple.read (aLink.m_nIndex2, aLink.m_nIndex1, aLink.m_nIndex0, rData, rBIOS);
806*b1cdbd2cSJim Jagielski }
807*b1cdbd2cSJim Jagielski else if (eScope == page::SCOPE_UNREACHABLE)
808*b1cdbd2cSJim Jagielski {
809*b1cdbd2cSJim Jagielski // Out of scope.
810*b1cdbd2cSJim Jagielski eErrCode = store_E_CantSeek;
811*b1cdbd2cSJim Jagielski }
812*b1cdbd2cSJim Jagielski else
813*b1cdbd2cSJim Jagielski {
814*b1cdbd2cSJim Jagielski // Unknown scope.
815*b1cdbd2cSJim Jagielski OSL_TRACE("OStoreDirectoryPageObject::get(): scope failed");
816*b1cdbd2cSJim Jagielski eErrCode = store_E_Unknown;
817*b1cdbd2cSJim Jagielski }
818*b1cdbd2cSJim Jagielski
819*b1cdbd2cSJim Jagielski // Leave.
820*b1cdbd2cSJim Jagielski return eErrCode;
821*b1cdbd2cSJim Jagielski }
822*b1cdbd2cSJim Jagielski
823*b1cdbd2cSJim Jagielski /*
824*b1cdbd2cSJim Jagielski * write (external data page).
825*b1cdbd2cSJim Jagielski */
write(sal_uInt32 nPage,OStoreDataPageObject & rData,OStorePageBIOS & rBIOS)826*b1cdbd2cSJim Jagielski storeError OStoreDirectoryPageObject::write (
827*b1cdbd2cSJim Jagielski sal_uInt32 nPage,
828*b1cdbd2cSJim Jagielski OStoreDataPageObject &rData,
829*b1cdbd2cSJim Jagielski OStorePageBIOS &rBIOS)
830*b1cdbd2cSJim Jagielski {
831*b1cdbd2cSJim Jagielski // Determine scope and link indices.
832*b1cdbd2cSJim Jagielski page::DataBlock::LinkDescriptor aLink;
833*b1cdbd2cSJim Jagielski page::ChunkScope eScope = scope (nPage, aLink);
834*b1cdbd2cSJim Jagielski
835*b1cdbd2cSJim Jagielski storeError eErrCode = store_E_None;
836*b1cdbd2cSJim Jagielski if (eScope == page::SCOPE_DIRECT)
837*b1cdbd2cSJim Jagielski {
838*b1cdbd2cSJim Jagielski sal_uInt32 const nAddr = directLink (aLink.m_nIndex0);
839*b1cdbd2cSJim Jagielski if (nAddr == STORE_PAGE_NULL)
840*b1cdbd2cSJim Jagielski {
841*b1cdbd2cSJim Jagielski // Allocate data page.
842*b1cdbd2cSJim Jagielski eErrCode = rBIOS.allocate (rData);
843*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
844*b1cdbd2cSJim Jagielski return eErrCode;
845*b1cdbd2cSJim Jagielski
846*b1cdbd2cSJim Jagielski // Store data page location.
847*b1cdbd2cSJim Jagielski directLink (aLink.m_nIndex0, rData.location());
848*b1cdbd2cSJim Jagielski }
849*b1cdbd2cSJim Jagielski else
850*b1cdbd2cSJim Jagielski {
851*b1cdbd2cSJim Jagielski // Save data page.
852*b1cdbd2cSJim Jagielski eErrCode = rBIOS.saveObjectAt (rData, nAddr);
853*b1cdbd2cSJim Jagielski }
854*b1cdbd2cSJim Jagielski }
855*b1cdbd2cSJim Jagielski else if (eScope == page::SCOPE_SINGLE)
856*b1cdbd2cSJim Jagielski {
857*b1cdbd2cSJim Jagielski OStoreIndirectionPageObject aSingle;
858*b1cdbd2cSJim Jagielski eErrCode = aSingle.loadOrCreate (singleLink (aLink.m_nIndex1), rBIOS);
859*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
860*b1cdbd2cSJim Jagielski {
861*b1cdbd2cSJim Jagielski if (eErrCode != store_E_Pending)
862*b1cdbd2cSJim Jagielski return eErrCode;
863*b1cdbd2cSJim Jagielski singleLink (aLink.m_nIndex1, aSingle.location());
864*b1cdbd2cSJim Jagielski }
865*b1cdbd2cSJim Jagielski
866*b1cdbd2cSJim Jagielski eErrCode = aSingle.write (aLink.m_nIndex0, rData, rBIOS);
867*b1cdbd2cSJim Jagielski }
868*b1cdbd2cSJim Jagielski else if (eScope == page::SCOPE_DOUBLE)
869*b1cdbd2cSJim Jagielski {
870*b1cdbd2cSJim Jagielski OStoreIndirectionPageObject aDouble;
871*b1cdbd2cSJim Jagielski eErrCode = aDouble.loadOrCreate (doubleLink (aLink.m_nIndex2), rBIOS);
872*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
873*b1cdbd2cSJim Jagielski {
874*b1cdbd2cSJim Jagielski if (eErrCode != store_E_Pending)
875*b1cdbd2cSJim Jagielski return eErrCode;
876*b1cdbd2cSJim Jagielski doubleLink (aLink.m_nIndex2, aDouble.location());
877*b1cdbd2cSJim Jagielski }
878*b1cdbd2cSJim Jagielski
879*b1cdbd2cSJim Jagielski eErrCode = aDouble.write (aLink.m_nIndex1, aLink.m_nIndex0, rData, rBIOS);
880*b1cdbd2cSJim Jagielski }
881*b1cdbd2cSJim Jagielski else if (eScope == page::SCOPE_TRIPLE)
882*b1cdbd2cSJim Jagielski {
883*b1cdbd2cSJim Jagielski OStoreIndirectionPageObject aTriple;
884*b1cdbd2cSJim Jagielski eErrCode = aTriple.loadOrCreate (tripleLink (aLink.m_nIndex3), rBIOS);
885*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
886*b1cdbd2cSJim Jagielski {
887*b1cdbd2cSJim Jagielski if (eErrCode != store_E_Pending)
888*b1cdbd2cSJim Jagielski return eErrCode;
889*b1cdbd2cSJim Jagielski tripleLink (aLink.m_nIndex3, aTriple.location());
890*b1cdbd2cSJim Jagielski }
891*b1cdbd2cSJim Jagielski
892*b1cdbd2cSJim Jagielski eErrCode = aTriple.write (aLink.m_nIndex2, aLink.m_nIndex1, aLink.m_nIndex0, rData, rBIOS);
893*b1cdbd2cSJim Jagielski }
894*b1cdbd2cSJim Jagielski else if (eScope == page::SCOPE_UNREACHABLE)
895*b1cdbd2cSJim Jagielski {
896*b1cdbd2cSJim Jagielski // Out of scope.
897*b1cdbd2cSJim Jagielski eErrCode = store_E_CantSeek;
898*b1cdbd2cSJim Jagielski }
899*b1cdbd2cSJim Jagielski else
900*b1cdbd2cSJim Jagielski {
901*b1cdbd2cSJim Jagielski // Unknown scope.
902*b1cdbd2cSJim Jagielski OSL_TRACE("OStoreDirectoryPageObject::put(): scope failed");
903*b1cdbd2cSJim Jagielski eErrCode = store_E_Unknown;
904*b1cdbd2cSJim Jagielski }
905*b1cdbd2cSJim Jagielski
906*b1cdbd2cSJim Jagielski // Leave.
907*b1cdbd2cSJim Jagielski return eErrCode;
908*b1cdbd2cSJim Jagielski }
909*b1cdbd2cSJim Jagielski
910*b1cdbd2cSJim Jagielski /*
911*b1cdbd2cSJim Jagielski * truncate (external data page).
912*b1cdbd2cSJim Jagielski */
truncate(sal_uInt32 nPage,OStorePageBIOS & rBIOS)913*b1cdbd2cSJim Jagielski storeError OStoreDirectoryPageObject::truncate (
914*b1cdbd2cSJim Jagielski sal_uInt32 nPage,
915*b1cdbd2cSJim Jagielski OStorePageBIOS &rBIOS)
916*b1cdbd2cSJim Jagielski {
917*b1cdbd2cSJim Jagielski // Determine scope and link indices.
918*b1cdbd2cSJim Jagielski page::DataBlock::LinkDescriptor aLink;
919*b1cdbd2cSJim Jagielski page::ChunkScope eScope = scope (nPage, aLink);
920*b1cdbd2cSJim Jagielski
921*b1cdbd2cSJim Jagielski storeError eErrCode = store_E_None;
922*b1cdbd2cSJim Jagielski if (eScope == page::SCOPE_DIRECT)
923*b1cdbd2cSJim Jagielski {
924*b1cdbd2cSJim Jagielski // Truncate all triple indirect pages.
925*b1cdbd2cSJim Jagielski eErrCode = truncate (page::SCOPE_TRIPLE, 0, rBIOS);
926*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
927*b1cdbd2cSJim Jagielski return eErrCode;
928*b1cdbd2cSJim Jagielski
929*b1cdbd2cSJim Jagielski // Truncate all double indirect pages.
930*b1cdbd2cSJim Jagielski eErrCode = truncate (page::SCOPE_DOUBLE, 0, rBIOS);
931*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
932*b1cdbd2cSJim Jagielski return eErrCode;
933*b1cdbd2cSJim Jagielski
934*b1cdbd2cSJim Jagielski // Truncate all single indirect pages.
935*b1cdbd2cSJim Jagielski eErrCode = truncate (page::SCOPE_SINGLE, 0, rBIOS);
936*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
937*b1cdbd2cSJim Jagielski return eErrCode;
938*b1cdbd2cSJim Jagielski
939*b1cdbd2cSJim Jagielski // Truncate direct pages, including 'aLink.m_nIndex0'.
940*b1cdbd2cSJim Jagielski eErrCode = truncate (eScope, aLink.m_nIndex0, rBIOS);
941*b1cdbd2cSJim Jagielski }
942*b1cdbd2cSJim Jagielski else if (eScope == page::SCOPE_SINGLE)
943*b1cdbd2cSJim Jagielski {
944*b1cdbd2cSJim Jagielski // Truncate all triple indirect pages.
945*b1cdbd2cSJim Jagielski eErrCode = truncate (page::SCOPE_TRIPLE, 0, rBIOS);
946*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
947*b1cdbd2cSJim Jagielski return eErrCode;
948*b1cdbd2cSJim Jagielski
949*b1cdbd2cSJim Jagielski // Truncate all double indirect pages.
950*b1cdbd2cSJim Jagielski eErrCode = truncate (page::SCOPE_DOUBLE, 0, rBIOS);
951*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
952*b1cdbd2cSJim Jagielski return eErrCode;
953*b1cdbd2cSJim Jagielski
954*b1cdbd2cSJim Jagielski // Truncate single indirect pages, downto 'aLink.m_nIndex1'.
955*b1cdbd2cSJim Jagielski eErrCode = truncate (eScope, aLink.m_nIndex1 + 1, rBIOS);
956*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
957*b1cdbd2cSJim Jagielski return eErrCode;
958*b1cdbd2cSJim Jagielski
959*b1cdbd2cSJim Jagielski // Truncate last single indirect page to ... pages.
960*b1cdbd2cSJim Jagielski eErrCode = store_truncate_Impl (singleLink (aLink.m_nIndex1), aLink.m_nIndex0, rBIOS);
961*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
962*b1cdbd2cSJim Jagielski return eErrCode;
963*b1cdbd2cSJim Jagielski
964*b1cdbd2cSJim Jagielski // Check for complete truncation.
965*b1cdbd2cSJim Jagielski if (aLink.m_nIndex0 == 0)
966*b1cdbd2cSJim Jagielski {
967*b1cdbd2cSJim Jagielski // Clear pointer to last single indirect page.
968*b1cdbd2cSJim Jagielski singleLink (aLink.m_nIndex1, STORE_PAGE_NULL);
969*b1cdbd2cSJim Jagielski }
970*b1cdbd2cSJim Jagielski }
971*b1cdbd2cSJim Jagielski else if (eScope == page::SCOPE_DOUBLE)
972*b1cdbd2cSJim Jagielski {
973*b1cdbd2cSJim Jagielski // Truncate all triple indirect pages.
974*b1cdbd2cSJim Jagielski eErrCode = truncate (page::SCOPE_TRIPLE, 0, rBIOS);
975*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
976*b1cdbd2cSJim Jagielski return eErrCode;
977*b1cdbd2cSJim Jagielski
978*b1cdbd2cSJim Jagielski // Truncate double indirect pages, downto 'aLink.m_nIndex2'.
979*b1cdbd2cSJim Jagielski eErrCode = truncate (eScope, aLink.m_nIndex2 + 1, rBIOS);
980*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
981*b1cdbd2cSJim Jagielski return eErrCode;
982*b1cdbd2cSJim Jagielski
983*b1cdbd2cSJim Jagielski // Truncate last double indirect page to ... pages.
984*b1cdbd2cSJim Jagielski eErrCode = store_truncate_Impl (
985*b1cdbd2cSJim Jagielski doubleLink (aLink.m_nIndex2), aLink.m_nIndex1, aLink.m_nIndex0, rBIOS);
986*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
987*b1cdbd2cSJim Jagielski return eErrCode;
988*b1cdbd2cSJim Jagielski
989*b1cdbd2cSJim Jagielski // Check for complete truncation.
990*b1cdbd2cSJim Jagielski if ((aLink.m_nIndex1 + aLink.m_nIndex0) == 0)
991*b1cdbd2cSJim Jagielski {
992*b1cdbd2cSJim Jagielski // Clear pointer to last double indirect page.
993*b1cdbd2cSJim Jagielski doubleLink (aLink.m_nIndex2, STORE_PAGE_NULL);
994*b1cdbd2cSJim Jagielski }
995*b1cdbd2cSJim Jagielski }
996*b1cdbd2cSJim Jagielski else if (eScope == page::SCOPE_TRIPLE)
997*b1cdbd2cSJim Jagielski {
998*b1cdbd2cSJim Jagielski // Truncate triple indirect pages, downto 'aLink.m_nIndex3'.
999*b1cdbd2cSJim Jagielski eErrCode = truncate (eScope, aLink.m_nIndex3 + 1, rBIOS);
1000*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
1001*b1cdbd2cSJim Jagielski return eErrCode;
1002*b1cdbd2cSJim Jagielski
1003*b1cdbd2cSJim Jagielski // Truncate last triple indirect page to ... pages.
1004*b1cdbd2cSJim Jagielski eErrCode = store_truncate_Impl (
1005*b1cdbd2cSJim Jagielski tripleLink (aLink.m_nIndex3), aLink.m_nIndex2, aLink.m_nIndex1, aLink.m_nIndex0, rBIOS);
1006*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
1007*b1cdbd2cSJim Jagielski return eErrCode;
1008*b1cdbd2cSJim Jagielski
1009*b1cdbd2cSJim Jagielski // Check for complete truncation.
1010*b1cdbd2cSJim Jagielski if ((aLink.m_nIndex2 + aLink.m_nIndex1 + aLink.m_nIndex0) == 0)
1011*b1cdbd2cSJim Jagielski {
1012*b1cdbd2cSJim Jagielski // Clear pointer to last triple indirect page.
1013*b1cdbd2cSJim Jagielski tripleLink (aLink.m_nIndex3, STORE_PAGE_NULL);
1014*b1cdbd2cSJim Jagielski }
1015*b1cdbd2cSJim Jagielski }
1016*b1cdbd2cSJim Jagielski else if (eScope == page::SCOPE_UNREACHABLE)
1017*b1cdbd2cSJim Jagielski {
1018*b1cdbd2cSJim Jagielski // Out of scope.
1019*b1cdbd2cSJim Jagielski eErrCode = store_E_CantSeek;
1020*b1cdbd2cSJim Jagielski }
1021*b1cdbd2cSJim Jagielski else
1022*b1cdbd2cSJim Jagielski {
1023*b1cdbd2cSJim Jagielski // Unknown scope.
1024*b1cdbd2cSJim Jagielski OSL_TRACE("OStoreDirectoryPageObject::put(): scope failed");
1025*b1cdbd2cSJim Jagielski eErrCode = store_E_Unknown;
1026*b1cdbd2cSJim Jagielski }
1027*b1cdbd2cSJim Jagielski
1028*b1cdbd2cSJim Jagielski // Leave.
1029*b1cdbd2cSJim Jagielski return eErrCode;
1030*b1cdbd2cSJim Jagielski }
1031*b1cdbd2cSJim Jagielski
1032*b1cdbd2cSJim Jagielski /*
1033*b1cdbd2cSJim Jagielski * truncate (external data page scope; private).
1034*b1cdbd2cSJim Jagielski */
truncate(page::ChunkScope eScope,sal_uInt16 nRemain,OStorePageBIOS & rBIOS)1035*b1cdbd2cSJim Jagielski storeError OStoreDirectoryPageObject::truncate (
1036*b1cdbd2cSJim Jagielski page::ChunkScope eScope,
1037*b1cdbd2cSJim Jagielski sal_uInt16 nRemain,
1038*b1cdbd2cSJim Jagielski OStorePageBIOS &rBIOS)
1039*b1cdbd2cSJim Jagielski {
1040*b1cdbd2cSJim Jagielski OStoreDirectoryDataBlock const & rDataBlock = PAGE().m_aDataBlock;
1041*b1cdbd2cSJim Jagielski
1042*b1cdbd2cSJim Jagielski // Enter.
1043*b1cdbd2cSJim Jagielski storeError eErrCode = store_E_None;
1044*b1cdbd2cSJim Jagielski if (eScope == page::SCOPE_DIRECT)
1045*b1cdbd2cSJim Jagielski {
1046*b1cdbd2cSJim Jagielski // Truncate direct data pages.
1047*b1cdbd2cSJim Jagielski sal_uInt16 i, n = rDataBlock.directCount();
1048*b1cdbd2cSJim Jagielski for (i = n; i > nRemain; i--)
1049*b1cdbd2cSJim Jagielski {
1050*b1cdbd2cSJim Jagielski // Obtain data page location.
1051*b1cdbd2cSJim Jagielski sal_uInt32 nAddr = directLink (i - 1);
1052*b1cdbd2cSJim Jagielski if (nAddr == STORE_PAGE_NULL) continue;
1053*b1cdbd2cSJim Jagielski
1054*b1cdbd2cSJim Jagielski // Free data page.
1055*b1cdbd2cSJim Jagielski eErrCode = rBIOS.free (nAddr);
1056*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
1057*b1cdbd2cSJim Jagielski break;
1058*b1cdbd2cSJim Jagielski
1059*b1cdbd2cSJim Jagielski // Clear pointer to data page.
1060*b1cdbd2cSJim Jagielski directLink (i - 1, STORE_PAGE_NULL);
1061*b1cdbd2cSJim Jagielski }
1062*b1cdbd2cSJim Jagielski
1063*b1cdbd2cSJim Jagielski // Done.
1064*b1cdbd2cSJim Jagielski return eErrCode;
1065*b1cdbd2cSJim Jagielski }
1066*b1cdbd2cSJim Jagielski
1067*b1cdbd2cSJim Jagielski if (eScope == page::SCOPE_SINGLE)
1068*b1cdbd2cSJim Jagielski {
1069*b1cdbd2cSJim Jagielski // Truncate single indirect pages.
1070*b1cdbd2cSJim Jagielski sal_uInt16 i, n = rDataBlock.singleCount();
1071*b1cdbd2cSJim Jagielski for (i = n; i > nRemain; i--)
1072*b1cdbd2cSJim Jagielski {
1073*b1cdbd2cSJim Jagielski // Truncate single indirect page to zero data pages.
1074*b1cdbd2cSJim Jagielski eErrCode = store_truncate_Impl (singleLink (i - 1), 0, rBIOS);
1075*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
1076*b1cdbd2cSJim Jagielski break;
1077*b1cdbd2cSJim Jagielski
1078*b1cdbd2cSJim Jagielski // Clear pointer to single indirect page.
1079*b1cdbd2cSJim Jagielski singleLink (i - 1, STORE_PAGE_NULL);
1080*b1cdbd2cSJim Jagielski }
1081*b1cdbd2cSJim Jagielski
1082*b1cdbd2cSJim Jagielski // Done.
1083*b1cdbd2cSJim Jagielski return eErrCode;
1084*b1cdbd2cSJim Jagielski }
1085*b1cdbd2cSJim Jagielski
1086*b1cdbd2cSJim Jagielski if (eScope == page::SCOPE_DOUBLE)
1087*b1cdbd2cSJim Jagielski {
1088*b1cdbd2cSJim Jagielski // Truncate double indirect pages.
1089*b1cdbd2cSJim Jagielski sal_uInt16 i, n = rDataBlock.doubleCount();
1090*b1cdbd2cSJim Jagielski for (i = n; i > nRemain; i--)
1091*b1cdbd2cSJim Jagielski {
1092*b1cdbd2cSJim Jagielski // Truncate double indirect page to zero single indirect pages.
1093*b1cdbd2cSJim Jagielski eErrCode = store_truncate_Impl (doubleLink (i - 1), 0, 0, rBIOS);
1094*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
1095*b1cdbd2cSJim Jagielski break;
1096*b1cdbd2cSJim Jagielski
1097*b1cdbd2cSJim Jagielski // Clear pointer to double indirect page.
1098*b1cdbd2cSJim Jagielski doubleLink (i - 1, STORE_PAGE_NULL);
1099*b1cdbd2cSJim Jagielski }
1100*b1cdbd2cSJim Jagielski
1101*b1cdbd2cSJim Jagielski // Done.
1102*b1cdbd2cSJim Jagielski return eErrCode;
1103*b1cdbd2cSJim Jagielski }
1104*b1cdbd2cSJim Jagielski
1105*b1cdbd2cSJim Jagielski if (eScope == page::SCOPE_TRIPLE)
1106*b1cdbd2cSJim Jagielski {
1107*b1cdbd2cSJim Jagielski // Truncate triple indirect pages.
1108*b1cdbd2cSJim Jagielski sal_uInt16 i, n = rDataBlock.tripleCount();
1109*b1cdbd2cSJim Jagielski for (i = n; i > nRemain; i--)
1110*b1cdbd2cSJim Jagielski {
1111*b1cdbd2cSJim Jagielski // Truncate to zero double indirect pages.
1112*b1cdbd2cSJim Jagielski eErrCode = store_truncate_Impl (tripleLink (i - 1), 0, 0, 0, rBIOS);
1113*b1cdbd2cSJim Jagielski if (eErrCode != store_E_None)
1114*b1cdbd2cSJim Jagielski break;
1115*b1cdbd2cSJim Jagielski
1116*b1cdbd2cSJim Jagielski // Clear pointer to triple indirect page.
1117*b1cdbd2cSJim Jagielski tripleLink (i - 1, STORE_PAGE_NULL);
1118*b1cdbd2cSJim Jagielski }
1119*b1cdbd2cSJim Jagielski
1120*b1cdbd2cSJim Jagielski // Done.
1121*b1cdbd2cSJim Jagielski return eErrCode;
1122*b1cdbd2cSJim Jagielski }
1123*b1cdbd2cSJim Jagielski
1124*b1cdbd2cSJim Jagielski // Invalid scope.
1125*b1cdbd2cSJim Jagielski return store_E_InvalidAccess;
1126*b1cdbd2cSJim Jagielski }
1127