2 #include <exec/types.h>
4 #include "adminspaces.h"
6 #include "bitmap_protos.h"
7 #include "cachebuffers_protos.h"
10 #include "transactions_protos.h"
11 #include "asmsupport.h"
12 #include "req_protos.h"
15 extern LONG
readcachebuffercheck(struct CacheBuffer
**,ULONG
,ULONG
);
17 LONG
allocadminspace(struct CacheBuffer
**returned_cb
) {
18 struct CacheBuffer
*cb
;
19 BLCK adminspaceblock
=globals
->block_adminspace
;
22 /* Returns a new, cleared CacheBuffer with blckno correctly
23 initialised. This function can only be called from
24 within an operation. *returned_cb is not destroyed
25 when there was an error. */
27 while((errorcode
=readcachebuffercheck(&cb
,adminspaceblock
,ADMINSPACECONTAINER_ID
))==0) {
28 struct fsAdminSpaceContainer
*asc
=cb
->data
;
29 struct fsAdminSpace
*as
=asc
->adminspace
;
30 LONG adminspaces
=(globals
->bytes_block
-sizeof(struct fsAdminSpaceContainer
))/sizeof(struct fsAdminSpace
);
32 while(adminspaces
-->0) {
35 if(as
->be_space
!=0 && (bitoffset
=bfffz(BE2L(as
->be_bits
),0)) < 32) {
36 BLCK emptyadminblock
=BE2L(as
->be_space
)+bitoffset
;
38 preparecachebuffer(cb
);
40 as
->be_bits
|=L2BE(1<<(31-bitoffset
));
42 if((errorcode
=storecachebuffer(cb
))!=0) {
46 if((cb
=newcachebuffer(emptyadminblock
))==0) {
47 return(ERROR_NO_FREE_STORE
);
57 if((adminspaceblock
=BE2L(asc
->be_next
))==0) {
60 /* If we get here it means current adminspace areas are all filled.
61 We would now need to find a new area and create a fsAdminSpace
62 structure in one of the AdminSpaceContainer blocks. If these
63 don't have any room left for new adminspace areas a new
64 AdminSpaceContainer would have to be created first which is
65 placed as the first block in the newly found admin area. */
67 adminspaceblock
=globals
->block_adminspace
;
69 if((errorcode
=findandmarkspace(32,&startblock
))==0) {
70 while((errorcode
=readcachebuffercheck(&cb
,adminspaceblock
,ADMINSPACECONTAINER_ID
))==0) {
71 struct fsAdminSpaceContainer
*asc
=cb
->data
;
72 struct fsAdminSpace
*as
=asc
->adminspace
;
73 LONG adminspaces
=(globals
->bytes_block
-sizeof(struct fsAdminSpaceContainer
))/sizeof(struct fsAdminSpace
);
75 while(adminspaces
-->0 && as
->be_space
!=0) {
80 /* Found a unused AdminSpace in this AdminSpaceContainer! */
82 preparecachebuffer(cb
);
84 as
->be_space
=L2BE(startblock
);
87 errorcode
=storecachebuffer(cb
);
91 if(BE2L(asc
->be_next
)==0) {
93 /* Oh-oh... we marked our new adminspace area in use, but we couldn't
94 find space to store a fsAdminSpace structure in the existing
95 fsAdminSpaceContainer blocks. This means we need to create and
96 link a new fsAdminSpaceContainer as the first block in our newly
99 preparecachebuffer(cb
);
101 asc
->be_next
=L2BE(startblock
);
103 if((errorcode
=storecachebuffer(cb
))!=0) {
107 /* Now preparing new AdminSpaceContainer */
109 if((cb
=newcachebuffer(startblock
))==0) {
110 return(ERROR_NO_FREE_STORE
);
115 asc
->bheader
.id
=ADMINSPACECONTAINER_ID
;
116 asc
->bheader
.be_ownblock
=L2BE(startblock
);
117 asc
->be_previous
=L2BE(adminspaceblock
);
119 asc
->adminspace
[0].be_space
=L2BE(startblock
);
120 asc
->adminspace
[0].be_bits
=L2BE(0x80000000);
123 if((errorcode
=storecachebuffer(cb
))!=0) {
127 adminspaceblock
=startblock
;
128 break; /* Breaks through to outer loop! */
131 adminspaceblock
=BE2L(asc
->be_next
);
146 LONG
freeadminspace(BLCK block
) {
147 struct CacheBuffer
*cb
;
148 BLCK adminspaceblock
=globals
->block_adminspace
;
151 _DEBUG(("freeadminspace: Entry -- freeing block %ld\n",block
));
153 while((errorcode
=readcachebuffercheck(&cb
,adminspaceblock
,ADMINSPACECONTAINER_ID
))==0) {
154 struct fsAdminSpaceContainer
*asc
=cb
->data
;
155 struct fsAdminSpace
*as
=asc
->adminspace
;
156 LONG adminspaces
=(globals
->bytes_block
-sizeof(struct fsAdminSpaceContainer
))/sizeof(struct fsAdminSpace
);
158 while(adminspaces
-->0) {
159 if(block
>=BE2L(as
->be_space
) && block
<BE2L(as
->be_space
)+32) {
160 WORD bitoffset
=block
-BE2L(as
->be_space
);
162 /* block to be freed has been located */
164 _DEBUG(("freeadminspace: Block to be freed is located in AdminSpaceContainer block at %ld\n",adminspaceblock
));
166 preparecachebuffer(cb
);
168 as
->be_bits
&=~(L2BE(1<<(31-bitoffset
)));
170 if((errorcode
=storecachebuffer(cb
))==0) {
171 errorcode
=addfreeoperation(block
);
174 /*** Extra code need to be added here to free the AdminSpace structure if it isn't
175 being used anymore. This could mean that the entire AdminSpaceBlock could no
176 longer be needed either.... */
184 if((adminspaceblock
=BE2L(asc
->be_next
))==0) {
190 /*** Strange. We have been looking for the block to free, but couldn't find it in any
191 of the AdminSpace containers... */
193 req("Unable to free an administration block.\nThe block cannot be found.", "Ok");
195 return(ERROR_OBJECT_NOT_FOUND
);