File: | ufs/ext2fs/ext2fs_balloc.c |
Warning: | line 110, column 2 Value stored to 'pref' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: ext2fs_balloc.c,v 1.27 2019/07/19 00:24:31 cheloha Exp $ */ |
2 | /* $NetBSD: ext2fs_balloc.c,v 1.10 2001/07/04 21:16:01 chs Exp $ */ |
3 | |
4 | /* |
5 | * Copyright (c) 1997 Manuel Bouyer. |
6 | * Copyright (c) 1982, 1986, 1989, 1993 |
7 | * The Regents of the University of California. All rights reserved. |
8 | * |
9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions |
11 | * are met: |
12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. |
14 | * 2. Redistributions in binary form must reproduce the above copyright |
15 | * notice, this list of conditions and the following disclaimer in the |
16 | * documentation and/or other materials provided with the distribution. |
17 | * 3. Neither the name of the University nor the names of its contributors |
18 | * may be used to endorse or promote products derived from this software |
19 | * without specific prior written permission. |
20 | * |
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
31 | * SUCH DAMAGE. |
32 | * |
33 | * @(#)ffs_balloc.c 8.4 (Berkeley) 9/23/93 |
34 | * Modified for ext2fs by Manuel Bouyer. |
35 | */ |
36 | |
37 | #include <sys/param.h> |
38 | #include <sys/systm.h> |
39 | #include <sys/buf.h> |
40 | #include <sys/vnode.h> |
41 | |
42 | #include <ufs/ufs/quota.h> |
43 | #include <ufs/ufs/inode.h> |
44 | #include <ufs/ufs/ufs_extern.h> |
45 | |
46 | #include <ufs/ext2fs/ext2fs.h> |
47 | #include <ufs/ext2fs/ext2fs_extern.h> |
48 | |
49 | /* |
50 | * Balloc defines the structure of file system storage |
51 | * by allocating the physical blocks on a device given |
52 | * the inode and the logical block number in a file. |
53 | */ |
54 | int |
55 | ext2fs_buf_alloc(struct inode *ip, u_int32_t bn, int size, struct ucred *cred, |
56 | struct buf **bpp, int flags) |
57 | { |
58 | struct m_ext2fs *fs; |
59 | struct buf *bp, *nbp; |
60 | struct vnode *vp = ITOV(ip)((ip)->i_vnode); |
61 | struct indir indirs[NIADDR3 + 2]; |
62 | u_int32_t nb, newb, *bap; |
63 | int num, i, error; |
64 | u_int deallocated; |
65 | u_int32_t *allocib, *blkp, *allocblk, allociblk[NIADDR3 + 1]; |
66 | int unwindidx = -1; |
67 | daddr_t lbn, pref; |
68 | |
69 | *bpp = NULL((void *)0); |
70 | fs = ip->i_e2fsinode_u.e2fs; |
71 | lbn = bn; |
72 | |
73 | /* |
74 | * The first NDADDR blocks are direct blocks |
75 | */ |
76 | if (bn < NDADDR12) { |
77 | nb = letoh32(ip->i_e2fs_blocks[bn])((__uint32_t)(ip->dinode_u.e2fs_din->e2di_blocks[bn])); |
78 | if (nb != 0) { |
79 | error = bread(vp, bn, fs->e2fs_bsize, &bp); |
80 | if (error) { |
81 | brelse(bp); |
82 | return (error); |
83 | } |
84 | *bpp = bp; |
85 | return (0); |
86 | } |
87 | |
88 | /* |
89 | * allocate a new direct block. |
90 | */ |
91 | error = ext2fs_alloc(ip, bn, |
92 | ext2fs_blkpref(ip, bn, (int)bn, &ip->i_e2fs_blocksdinode_u.e2fs_din->e2di_blocks[0]), |
93 | cred, &newb); |
94 | if (error) |
95 | return (error); |
96 | ip->i_e2fs_last_lblkinode_ext.e2fs.ext2fs_last_lblk = lbn; |
97 | ip->i_e2fs_last_blkinode_ext.e2fs.ext2fs_last_blk = newb; |
98 | ip->i_e2fs_blocksdinode_u.e2fs_din->e2di_blocks[bn] = htole32(newb)((__uint32_t)(newb)); |
99 | ip->i_flag |= IN_CHANGE0x0002 | IN_UPDATE0x0004; |
100 | bp = getblk(vp, bn, fs->e2fs_bsize, 0, INFSLP0xffffffffffffffffULL); |
101 | bp->b_blkno = fsbtodb(fs, newb)((newb) << (fs)->e2fs_fsbtodb); |
102 | if (flags & B_CLRBUF0x01) |
103 | clrbuf(bp){ __builtin_bzero(((bp)->b_data), ((bp)->b_bcount)); (bp )->b_resid = 0; }; |
104 | *bpp = bp; |
105 | return (0); |
106 | } |
107 | /* |
108 | * Determine the number of levels of indirection. |
109 | */ |
110 | pref = 0; |
Value stored to 'pref' is never read | |
111 | if ((error = ufs_getlbns(vp, bn, indirs, &num)) != 0) |
112 | return(error); |
113 | #ifdef DIAGNOSTIC1 |
114 | if (num < 1) |
115 | panic ("ext2fs_balloc: ufs_getlbns returned indirect block"); |
116 | #endif |
117 | /* |
118 | * Fetch the first indirect block allocating if necessary. |
119 | */ |
120 | --num; |
121 | nb = letoh32(ip->i_e2fs_blocks[NDADDR + indirs[0].in_off])((__uint32_t)(ip->dinode_u.e2fs_din->e2di_blocks[12 + indirs [0].in_off])); |
122 | allocib = NULL((void *)0); |
123 | allocblk = allociblk; |
124 | if (nb == 0) { |
125 | pref = ext2fs_blkpref(ip, lbn, 0, NULL((void *)0)); |
126 | error = ext2fs_alloc(ip, lbn, pref, cred, &newb); |
127 | if (error) |
128 | return (error); |
129 | nb = newb; |
130 | *allocblk++ = nb; |
131 | ip->i_e2fs_last_blkinode_ext.e2fs.ext2fs_last_blk = newb; |
132 | bp = getblk(vp, indirs[1].in_lbn, fs->e2fs_bsize, 0, INFSLP0xffffffffffffffffULL); |
133 | bp->b_blkno = fsbtodb(fs, newb)((newb) << (fs)->e2fs_fsbtodb); |
134 | clrbuf(bp){ __builtin_bzero(((bp)->b_data), ((bp)->b_bcount)); (bp )->b_resid = 0; }; |
135 | /* |
136 | * Write synchronously so that indirect blocks |
137 | * never point at garbage. |
138 | */ |
139 | if ((error = bwrite(bp)) != 0) |
140 | goto fail; |
141 | unwindidx = 0; |
142 | allocib = &ip->i_e2fs_blocksdinode_u.e2fs_din->e2di_blocks[NDADDR12 + indirs[0].in_off]; |
143 | *allocib = htole32(newb)((__uint32_t)(newb)); |
144 | ip->i_flag |= IN_CHANGE0x0002 | IN_UPDATE0x0004; |
145 | } |
146 | /* |
147 | * Fetch through the indirect blocks, allocating as necessary. |
148 | */ |
149 | for (i = 1;;) { |
150 | error = bread(vp, indirs[i].in_lbn, (int)fs->e2fs_bsize, &bp); |
151 | if (error) { |
152 | brelse(bp); |
153 | goto fail; |
154 | } |
155 | bap = (u_int32_t *)bp->b_data; |
156 | nb = letoh32(bap[indirs[i].in_off])((__uint32_t)(bap[indirs[i].in_off])); |
157 | if (i == num) |
158 | break; |
159 | i++; |
160 | if (nb != 0) { |
161 | brelse(bp); |
162 | continue; |
163 | } |
164 | pref = ext2fs_blkpref(ip, lbn, 0, NULL((void *)0)); |
165 | error = ext2fs_alloc(ip, lbn, pref, cred, &newb); |
166 | if (error) { |
167 | brelse(bp); |
168 | goto fail; |
169 | } |
170 | nb = newb; |
171 | *allocblk++ = nb; |
172 | ip->i_e2fs_last_blkinode_ext.e2fs.ext2fs_last_blk = newb; |
173 | nbp = getblk(vp, indirs[i].in_lbn, fs->e2fs_bsize, 0, INFSLP0xffffffffffffffffULL); |
174 | nbp->b_blkno = fsbtodb(fs, nb)((nb) << (fs)->e2fs_fsbtodb); |
175 | clrbuf(nbp){ __builtin_bzero(((nbp)->b_data), ((nbp)->b_bcount)); ( nbp)->b_resid = 0; }; |
176 | /* |
177 | * Write synchronously so that indirect blocks |
178 | * never point at garbage. |
179 | */ |
180 | if ((error = bwrite(nbp)) != 0) { |
181 | brelse(bp); |
182 | goto fail; |
183 | } |
184 | if (unwindidx < 0) |
185 | unwindidx = i - 1; |
186 | bap[indirs[i - 1].in_off] = htole32(nb)((__uint32_t)(nb)); |
187 | /* |
188 | * If required, write synchronously, otherwise use |
189 | * delayed write. |
190 | */ |
191 | if (flags & B_SYNC0x02) { |
192 | bwrite(bp); |
193 | } else { |
194 | bdwrite(bp); |
195 | } |
196 | } |
197 | /* |
198 | * Get the data block, allocating if necessary. |
199 | */ |
200 | if (nb == 0) { |
201 | pref = ext2fs_blkpref(ip, lbn, indirs[num].in_off, bap); |
202 | error = ext2fs_alloc(ip, lbn, pref, cred, &newb); |
203 | if (error) { |
204 | brelse(bp); |
205 | goto fail; |
206 | } |
207 | nb = newb; |
208 | *allocblk++ = nb; |
209 | ip->i_e2fs_last_lblkinode_ext.e2fs.ext2fs_last_lblk = lbn; |
210 | ip->i_e2fs_last_blkinode_ext.e2fs.ext2fs_last_blk = newb; |
211 | bap[indirs[num].in_off] = htole32(nb)((__uint32_t)(nb)); |
212 | /* |
213 | * If required, write synchronously, otherwise use |
214 | * delayed write. |
215 | */ |
216 | if (flags & B_SYNC0x02) { |
217 | bwrite(bp); |
218 | } else { |
219 | bdwrite(bp); |
220 | } |
221 | nbp = getblk(vp, lbn, fs->e2fs_bsize, 0, INFSLP0xffffffffffffffffULL); |
222 | nbp->b_blkno = fsbtodb(fs, nb)((nb) << (fs)->e2fs_fsbtodb); |
223 | if (flags & B_CLRBUF0x01) |
224 | clrbuf(nbp){ __builtin_bzero(((nbp)->b_data), ((nbp)->b_bcount)); ( nbp)->b_resid = 0; }; |
225 | *bpp = nbp; |
226 | return (0); |
227 | } |
228 | brelse(bp); |
229 | if (flags & B_CLRBUF0x01) { |
230 | error = bread(vp, lbn, (int)fs->e2fs_bsize, &nbp); |
231 | if (error) { |
232 | brelse(nbp); |
233 | goto fail; |
234 | } |
235 | } else { |
236 | nbp = getblk(vp, lbn, fs->e2fs_bsize, 0, INFSLP0xffffffffffffffffULL); |
237 | nbp->b_blkno = fsbtodb(fs, nb)((nb) << (fs)->e2fs_fsbtodb); |
238 | } |
239 | |
240 | *bpp = nbp; |
241 | return (0); |
242 | fail: |
243 | /* |
244 | * If we have failed part way through block allocation, we |
245 | * have to deallocate any indirect blocks that we have allocated. |
246 | */ |
247 | for (deallocated = 0, blkp = allociblk; blkp < allocblk; blkp++) { |
248 | ext2fs_blkfree(ip, *blkp); |
249 | deallocated += fs->e2fs_bsize; |
250 | } |
251 | if (unwindidx >= 0) { |
252 | if (unwindidx == 0) { |
253 | *allocib = 0; |
254 | } else { |
255 | int r; |
256 | |
257 | r = bread(vp, indirs[unwindidx].in_lbn, |
258 | (int)fs->e2fs_bsize, &bp); |
259 | if (r) { |
260 | panic("Could not unwind indirect block, error %d", r); |
261 | } else { |
262 | bap = (u_int32_t *)bp->b_data; |
263 | bap[indirs[unwindidx].in_off] = 0; |
264 | if (flags & B_SYNC0x02) |
265 | bwrite(bp); |
266 | else |
267 | bdwrite(bp); |
268 | } |
269 | } |
270 | for (i = unwindidx + 1; i <= num; i++) { |
271 | bp = getblk(vp, indirs[i].in_lbn, (int)fs->e2fs_bsize, |
272 | 0, INFSLP0xffffffffffffffffULL); |
273 | bp->b_flags |= B_INVAL0x00000800; |
274 | brelse(bp); |
275 | } |
276 | } |
277 | if (deallocated) { |
278 | ip->i_e2fs_nblockdinode_u.e2fs_din->e2di_nblock -= btodb(deallocated)((deallocated) >> 9); |
279 | ip->i_e2fs_flagsdinode_u.e2fs_din->e2di_flags |= IN_CHANGE0x0002 | IN_UPDATE0x0004; |
280 | } |
281 | return error; |
282 | } |