2 * Copyright (c) 2003 Juli Mallett. All rights reserved.
4 * This software was written by Juli Mallett <jmallett@FreeBSD.org> for the
5 * FreeBSD project. Redistribution and use in source and binary forms, with
6 * or without modification, are permitted provided that the following
9 * 1. Redistribution of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 * 2. Redistribution in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
31 #include <sys/param.h>
32 #include <sys/mount.h>
33 #include <sys/disklabel.h>
36 #include <ufs/ufs/ufsmount.h>
37 #include <ufs/ufs/dinode.h>
38 #include <ufs/ffs/fs.h>
50 cgballoc(struct uufsd
*disk
)
59 blksfree
= cg_blksfree(cgp
);
60 for (bno
= 0; bno
< fs
->fs_fpg
/ fs
->fs_frag
; bno
++)
61 if (ffs_isblock(fs
, blksfree
, bno
))
65 fs
->fs_cs(fs
, cgp
->cg_cgx
).cs_nbfree
--;
66 ffs_clrblock(fs
, blksfree
, (long)bno
);
67 ffs_clusteracct(fs
, cgp
, bno
, -1);
68 cgp
->cg_cs
.cs_nbfree
--;
69 fs
->fs_cstotal
.cs_nbfree
--;
71 return (cgbase(fs
, cgp
->cg_cgx
) + blkstofrags(fs
, bno
));
75 cgbfree(struct uufsd
*disk
, ufs2_daddr_t bno
, long size
)
80 ufs1_daddr_t fragno
, cgbno
;
81 int i
, cg
, blk
, frags
, bbase
;
85 if (cgread1(disk
, cg
) != 1)
88 cgbno
= dtogd(fs
, bno
);
89 blksfree
= cg_blksfree(cgp
);
90 if (size
== fs
->fs_bsize
) {
91 fragno
= fragstoblks(fs
, cgbno
);
92 ffs_setblock(fs
, blksfree
, fragno
);
93 ffs_clusteracct(fs
, cgp
, fragno
, 1);
94 cgp
->cg_cs
.cs_nbfree
++;
95 fs
->fs_cstotal
.cs_nbfree
++;
96 fs
->fs_cs(fs
, cg
).cs_nbfree
++;
98 bbase
= cgbno
- fragnum(fs
, cgbno
);
100 * decrement the counts associated with the old frags
102 blk
= blkmap(fs
, blksfree
, bbase
);
103 ffs_fragacct(fs
, blk
, cgp
->cg_frsum
, -1);
105 * deallocate the fragment
107 frags
= numfrags(fs
, size
);
108 for (i
= 0; i
< frags
; i
++)
109 setbit(blksfree
, cgbno
+ i
);
110 cgp
->cg_cs
.cs_nffree
+= i
;
111 fs
->fs_cstotal
.cs_nffree
+= i
;
112 fs
->fs_cs(fs
, cg
).cs_nffree
+= i
;
114 * add back in counts associated with the new frags
116 blk
= blkmap(fs
, blksfree
, bbase
);
117 ffs_fragacct(fs
, blk
, cgp
->cg_frsum
, 1);
119 * if a complete block has been reassembled, account for it
121 fragno
= fragstoblks(fs
, bbase
);
122 if (ffs_isblock(fs
, blksfree
, fragno
)) {
123 cgp
->cg_cs
.cs_nffree
-= fs
->fs_frag
;
124 fs
->fs_cstotal
.cs_nffree
-= fs
->fs_frag
;
125 fs
->fs_cs(fs
, cg
).cs_nffree
-= fs
->fs_frag
;
126 ffs_clusteracct(fs
, cgp
, fragno
, 1);
127 cgp
->cg_cs
.cs_nbfree
++;
128 fs
->fs_cstotal
.cs_nbfree
++;
129 fs
->fs_cs(fs
, cg
).cs_nbfree
++;
132 return cgwrite(disk
);
136 cgialloc(struct uufsd
*disk
)
138 struct ufs2_dinode
*dp2
;
147 inosused
= cg_inosused(cgp
);
148 for (ino
= 0; ino
< fs
->fs_ipg
; ino
++)
149 if (isclr(inosused
, ino
))
153 if (fs
->fs_magic
== FS_UFS2_MAGIC
&&
154 ino
+ INOPB(fs
) > cgp
->cg_initediblk
&&
155 cgp
->cg_initediblk
< cgp
->cg_niblk
) {
156 char block
[MAXBSIZE
];
157 bzero(block
, (int)fs
->fs_bsize
);
158 dp2
= (struct ufs2_dinode
*)&block
;
159 for (i
= 0; i
< INOPB(fs
); i
++) {
160 dp2
->di_gen
= arc4random();
163 if (bwrite(disk
, ino_to_fsba(fs
,
164 cgp
->cg_cgx
* fs
->fs_ipg
+ cgp
->cg_initediblk
),
165 block
, fs
->fs_bsize
))
167 cgp
->cg_initediblk
+= INOPB(fs
);
170 setbit(inosused
, ino
);
171 cgp
->cg_irotor
= ino
;
172 cgp
->cg_cs
.cs_nifree
--;
173 fs
->fs_cstotal
.cs_nifree
--;
174 fs
->fs_cs(fs
, cgp
->cg_cgx
).cs_nifree
--;
177 return (ino
+ (cgp
->cg_cgx
* fs
->fs_ipg
));
181 cgread(struct uufsd
*disk
)
183 return (cgread1(disk
, disk
->d_ccg
++));
187 cgread1(struct uufsd
*disk
, int c
)
193 if ((unsigned)c
>= fs
->fs_ncg
) {
196 if (bread(disk
, fsbtodb(fs
, cgtod(fs
, c
)), disk
->d_cgunion
.d_buf
,
197 fs
->fs_bsize
) == -1) {
198 ERROR(disk
, "unable to read cylinder group");
206 cgwrite(struct uufsd
*disk
)
208 return (cgwrite1(disk
, disk
->d_lcg
));
212 cgwrite1(struct uufsd
*disk
, int c
)
217 if (bwrite(disk
, fsbtodb(fs
, cgtod(fs
, c
)),
218 disk
->d_cgunion
.d_buf
, fs
->fs_bsize
) == -1) {
219 ERROR(disk
, "unable to write cylinder group");