Print this page
NEX-16819 loader UEFI support
Includes work by Toomas Soome <tsoome@me.com>
Upstream commits:
loader: pxe receive cleanup
9475 libefi: Do not return only if ReceiveFilter
installboot: should support efi system partition
8931 boot1.efi: scan all display modes rather than
loader: spinconsole updates
loader: gfx experiment to try GOP Blt() function.
sha1 build test
loader: add sha1 hash calculation
common/sha1: update for loader build
loader: biosdisk rework
uts: 32-bit kernel FB needs mapping in low memory
uts: add diag-device
uts: boot console mirror with diag-device
uts: enable very early console on ttya
kmdb: add diag-device as input/output device
uts: test VGA memory exclusion from mapping
uts: clear boot mapping and protect boot pages test
uts: add dboot map debug printf
uts: need to release FB pages in release_bootstrap()
uts: add screenmap ioctl
uts: update sys/queue.h
loader: add illumos uts/common to include path
loader: tem/gfx font cleanup
loader: vbe checks
uts: gfx_private set KD_TEXT when KD_RESETTEXT is
uts: gfx 8-bit update
loader: gfx 8-bit fix
loader: always set media size from partition.
uts: MB2 support for 32-bit kernel
loader: x86 should have tem 80x25
uts: x86 should have tem 80x25
uts: font update
loader: font update
uts: tem attributes
loader: tem.c comment added
uts: use font module
loader: add font module
loader: build rules for new font setup
uts: gfx_private update for new font structure
uts: early boot update for new font structure
uts: font update
uts: font build rules update for new fonts
uts: tem update to new font structure
loader: module.c needs to include tem_impl.h
uts: gfx_private 8x16 font rework
uts: make font_lookup public
loader: font rework
uts: font rework
9259 libefi: efi_alloc_and_read should check for PMBR
uts: tem utf-8 support
loader: implement tem utf-8 support
loader: tem should be able to display UTF-8
7784 uts: console input should support utf-8
7796 uts: ldterm default to utf-8
uts: do not reset serial console
uts: set up colors even if tem is not console
uts: add type for early boot properties
uts: gfx_private experiment with drm and vga
uts: gfx_private should use setmode drm callback.
uts: identify FB types and set up gfx_private based
loader: replace gop and vesa with framebuffer
uts: boot needs simple tem to support mdb
uts: boot_keyboard should emit esc sequences for
uts: gfx_private FB showuld be written by line
kmdb: set terminal window size
uts: gfx_private needs to keep track of early boot FB
pnglite: move pnglite to usr/src/common
loader: gfx_fb
ficl-sys: add gfx primitives
loader: add illumos.png logo
ficl: add fb-putimage
loader: add png support
loader: add alpha blending for gfx_fb
loader: use term-drawrect for menu frame
ficl: add simple gfx words
uts: provide fb_info via fbgattr dev_specific array.
uts: gfx_private add alpha blending
uts: update sys/ascii.h
uts: tem OSC support (incomplete)
uts: implement env module support and use data from
uts: tem get colors from early boot data
loader: use crc32 from libstand (libz)
loader: optimize for size
loader: pass tem info to the environment
loader: import tem for loader console
loader: UEFI loader needs to set ISADIR based on
loader: need UEFI32 support
8918 loader.efi: add vesa edid support
uts: tem_safe_pix_clear_prom_output() should only
uts: tem_safe_pix_clear_entire_screen() should use
uts: tem_safe_check_first_time() should query cursor
uts: tem implement cls callback & visual_io v4
uts: gfx_vgatext use block cursor for vgatext
uts: gfx_private implement cls callback & visual_io
uts: gfx_private bitmap framebuffer implementation
uts: early start frame buffer console support
uts: font functions should check the input char
uts: font rendering should support 16/24/32bit depths
uts: use smallest font as fallback default.
uts: update terminal dimensions based on selected
7834 uts: vgatext should use gfx_private
uts: add spacing property to 8859-1.bdf
terminfo: add underline for sun-color
terminfo: sun-color has 16 colors
uts: add font load callback type
loader: do not repeat int13 calls with error 0x20 and
8905 loader: add skein/edonr support
8904 common/crypto: make skein and edonr loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Revert "NEX-16819 loader UEFI support"
This reverts commit ec06b9fc617b99234e538bf2e7e4d02a24993e0c.
Reverting due to failures in the zfs-tests and the sharefs-tests
NEX-16819 loader UEFI support
Includes work by Toomas Soome <tsoome@me.com>
Upstream commits:
loader: pxe receive cleanup
9475 libefi: Do not return only if ReceiveFilter
installboot: should support efi system partition
8931 boot1.efi: scan all display modes rather than
loader: spinconsole updates
loader: gfx experiment to try GOP Blt() function.
sha1 build test
loader: add sha1 hash calculation
common/sha1: update for loader build
loader: biosdisk rework
uts: 32-bit kernel FB needs mapping in low memory
uts: add diag-device
uts: boot console mirror with diag-device
uts: enable very early console on ttya
kmdb: add diag-device as input/output device
uts: test VGA memory exclusion from mapping
uts: clear boot mapping and protect boot pages test
uts: add dboot map debug printf
uts: need to release FB pages in release_bootstrap()
uts: add screenmap ioctl
uts: update sys/queue.h
loader: add illumos uts/common to include path
loader: tem/gfx font cleanup
loader: vbe checks
uts: gfx_private set KD_TEXT when KD_RESETTEXT is
uts: gfx 8-bit update
loader: gfx 8-bit fix
loader: always set media size from partition.
uts: MB2 support for 32-bit kernel
loader: x86 should have tem 80x25
uts: x86 should have tem 80x25
uts: font update
loader: font update
uts: tem attributes
loader: tem.c comment added
uts: use font module
loader: add font module
loader: build rules for new font setup
uts: gfx_private update for new font structure
uts: early boot update for new font structure
uts: font update
uts: font build rules update for new fonts
uts: tem update to new font structure
loader: module.c needs to include tem_impl.h
uts: gfx_private 8x16 font rework
uts: make font_lookup public
loader: font rework
uts: font rework
libefi: efi_alloc_and_read should check for PMBR
uts: tem utf-8 support
loader: implement tem utf-8 support
loader: tem should be able to display UTF-8
7784 uts: console input should support utf-8
7796 uts: ldterm default to utf-8
uts: do not reset serial console
uts: set up colors even if tem is not console
uts: add type for early boot properties
uts: gfx_private experiment with drm and vga
uts: gfx_private should use setmode drm callback.
uts: identify FB types and set up gfx_private based
loader: replace gop and vesa with framebuffer
uts: boot needs simple tem to support mdb
uts: boot_keyboard should emit esc sequences for
uts: gfx_private FB showuld be written by line
kmdb: set terminal window size
uts: gfx_private needs to keep track of early boot FB
pnglite: move pnglite to usr/src/common
loader: gfx_fb
ficl-sys: add gfx primitives
loader: add illumos.png logo
ficl: add fb-putimage
loader: add png support
loader: add alpha blending for gfx_fb
loader: use term-drawrect for menu frame
ficl: add simple gfx words
uts: provide fb_info via fbgattr dev_specific array.
uts: gfx_private add alpha blending
uts: update sys/ascii.h
uts: tem OSC support (incomplete)
uts: implement env module support and use data from
uts: tem get colors from early boot data
loader: use crc32 from libstand (libz)
loader: optimize for size
loader: pass tem info to the environment
loader: import tem for loader console
loader: UEFI loader needs to set ISADIR based on
loader: need UEFI32 support
8918 loader.efi: add vesa edid support
uts: tem_safe_pix_clear_prom_output() should only
uts: tem_safe_pix_clear_entire_screen() should use
uts: tem_safe_check_first_time() should query cursor
uts: tem implement cls callback & visual_io v4
uts: gfx_vgatext use block cursor for vgatext
uts: gfx_private implement cls callback & visual_io
uts: gfx_private bitmap framebuffer implementation
uts: early start frame buffer console support
uts: font functions should check the input char
uts: font rendering should support 16/24/32bit depths
uts: use smallest font as fallback default.
uts: update terminal dimensions based on selected
7834 uts: vgatext should use gfx_private
uts: add spacing property to 8859-1.bdf
terminfo: add underline for sun-color
terminfo: sun-color has 16 colors
uts: add font load callback type
loader: do not repeat int13 calls with error 0x20 and
8905 loader: add skein/edonr support
8904 common/crypto: make skein and edonr loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/boot/lib/libstand/ufs.c
+++ new/usr/src/boot/lib/libstand/ufs.c
1 1 /* $NetBSD: ufs.c,v 1.20 1998/03/01 07:15:39 ross Exp $ */
2 2
3 -/*-
3 +/*
4 4 * Copyright (c) 2002 Networks Associates Technology, Inc.
5 5 * All rights reserved.
6 6 *
7 7 * This software was developed for the FreeBSD Project by Marshall
8 8 * Kirk McKusick and Network Associates Laboratories, the Security
9 9 * Research Division of Network Associates, Inc. under DARPA/SPAWAR
10 10 * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS
11 11 * research program
12 12 *
13 13 * Copyright (c) 1982, 1989, 1993
14 14 * The Regents of the University of California. All rights reserved.
15 15 *
16 16 * This code is derived from software contributed to Berkeley by
17 17 * The Mach Operating System project at Carnegie-Mellon University.
18 18 *
19 19 * Redistribution and use in source and binary forms, with or without
20 20 * modification, are permitted provided that the following conditions
21 21 * are met:
22 22 * 1. Redistributions of source code must retain the above copyright
23 23 * notice, this list of conditions and the following disclaimer.
24 24 * 2. Redistributions in binary form must reproduce the above copyright
25 25 * notice, this list of conditions and the following disclaimer in the
26 26 * documentation and/or other materials provided with the distribution.
27 27 * 3. Neither the name of the University nor the names of its contributors
28 28 * may be used to endorse or promote products derived from this software
29 29 * without specific prior written permission.
30 30 *
31 31 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
32 32 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33 33 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 34 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
35 35 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
39 39 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
40 40 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41 41 * SUCH DAMAGE.
42 42 *
43 43 *
44 44 * Copyright (c) 1990, 1991 Carnegie Mellon University
45 45 * All Rights Reserved.
46 46 *
47 47 * Author: David Golub
48 48 *
49 49 * Permission to use, copy, modify and distribute this software and its
50 50 * documentation is hereby granted, provided that both the copyright
51 51 * notice and this permission notice appear in all copies of the
52 52 * software, derivative works or modified versions, and any portions
53 53 * thereof, and that both notices appear in supporting documentation.
54 54 *
55 55 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
56 56 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
57 57 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
58 58 *
59 59 * Carnegie Mellon requests users of this software to return to
60 60 *
61 61 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
62 62 * School of Computer Science
63 63 * Carnegie Mellon University
64 64 * Pittsburgh PA 15213-3890
65 65 *
66 66 * any improvements or extensions that they make and grant Carnegie the
67 67 * rights to redistribute these changes.
68 68 */
69 69
70 70 #include <sys/cdefs.h>
71 71
72 72 /*
73 73 * Stand-alone file reading package.
74 74 */
75 75
|
↓ open down ↓ |
62 lines elided |
↑ open up ↑ |
76 76 #include <sys/param.h>
77 77 #include <sys/disklabel.h>
78 78 #include <sys/time.h>
79 79 #include <ufs/ufs/dinode.h>
80 80 #include <ufs/ufs/dir.h>
81 81 #include <ufs/ffs/fs.h>
82 82 #include "stand.h"
83 83 #include "string.h"
84 84
85 85 static int ufs_open(const char *path, struct open_file *f);
86 -static int ufs_write(struct open_file *f, void *buf, size_t size, size_t *resid);
86 +static int ufs_write(struct open_file *f, const void *buf, size_t size,
87 + size_t *resid);
87 88 static int ufs_close(struct open_file *f);
88 89 static int ufs_read(struct open_file *f, void *buf, size_t size, size_t *resid);
89 90 static off_t ufs_seek(struct open_file *f, off_t offset, int where);
90 91 static int ufs_stat(struct open_file *f, struct stat *sb);
91 92 static int ufs_readdir(struct open_file *f, struct dirent *d);
92 93
93 94 struct fs_ops ufs_fsops = {
94 95 "ufs",
95 96 ufs_open,
96 97 ufs_close,
97 98 ufs_read,
98 99 ufs_write,
99 100 ufs_seek,
100 101 ufs_stat,
101 102 ufs_readdir
102 103 };
103 104
104 105 /*
105 106 * In-core open file.
106 107 */
107 108 struct file {
108 109 off_t f_seekp; /* seek pointer */
109 110 struct fs *f_fs; /* pointer to super-block */
110 111 union dinode {
111 112 struct ufs1_dinode di1;
112 113 struct ufs2_dinode di2;
113 114 } f_di; /* copy of on-disk inode */
114 115 int f_nindir[NIADDR];
115 116 /* number of blocks mapped by
116 117 indirect block at level i */
117 118 char *f_blk[NIADDR]; /* buffer for indirect block at
118 119 level i */
119 120 size_t f_blksize[NIADDR];
120 121 /* size of buffer */
121 122 ufs2_daddr_t f_blkno[NIADDR];/* disk address of block in buffer */
122 123 ufs2_daddr_t f_buf_blkno; /* block number of data block */
|
↓ open down ↓ |
26 lines elided |
↑ open up ↑ |
123 124 char *f_buf; /* buffer for data block */
124 125 size_t f_buf_size; /* size of data block */
125 126 };
126 127 #define DIP(fp, field) \
127 128 ((fp)->f_fs->fs_magic == FS_UFS1_MAGIC ? \
128 129 (fp)->f_di.di1.field : (fp)->f_di.di2.field)
129 130
130 131 static int read_inode(ino_t, struct open_file *);
131 132 static int block_map(struct open_file *, ufs2_daddr_t, ufs2_daddr_t *);
132 133 static int buf_read_file(struct open_file *, char **, size_t *);
133 -static int buf_write_file(struct open_file *, char *, size_t *);
134 +static int buf_write_file(struct open_file *, const char *, size_t *);
134 135 static int search_directory(char *, struct open_file *, ino_t *);
135 136
136 137 /*
137 138 * Read a new inode into a file structure.
138 139 */
139 140 static int
140 141 read_inode(inumber, f)
141 142 ino_t inumber;
142 143 struct open_file *f;
143 144 {
144 145 struct file *fp = (struct file *)f->f_fsdata;
145 146 struct fs *fs = fp->f_fs;
146 147 char *buf;
147 148 size_t rsize;
148 149 int rc;
149 150
150 151 if (fs == NULL)
151 152 panic("fs == NULL");
152 153
153 154 /*
154 155 * Read inode and save it.
155 156 */
156 157 buf = malloc(fs->fs_bsize);
157 158 twiddle(1);
158 159 rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
159 160 fsbtodb(fs, ino_to_fsba(fs, inumber)), fs->fs_bsize,
160 161 buf, &rsize);
161 162 if (rc)
162 163 goto out;
163 164 if (rsize != fs->fs_bsize) {
164 165 rc = EIO;
165 166 goto out;
166 167 }
167 168
168 169 if (fp->f_fs->fs_magic == FS_UFS1_MAGIC)
169 170 fp->f_di.di1 = ((struct ufs1_dinode *)buf)
170 171 [ino_to_fsbo(fs, inumber)];
171 172 else
172 173 fp->f_di.di2 = ((struct ufs2_dinode *)buf)
173 174 [ino_to_fsbo(fs, inumber)];
174 175
175 176 /*
176 177 * Clear out the old buffers
177 178 */
178 179 {
179 180 int level;
180 181
181 182 for (level = 0; level < NIADDR; level++)
182 183 fp->f_blkno[level] = -1;
183 184 fp->f_buf_blkno = -1;
184 185 }
185 186 fp->f_seekp = 0;
186 187 out:
187 188 free(buf);
188 189 return (rc);
189 190 }
190 191
191 192 /*
192 193 * Given an offset in a file, find the disk block number that
193 194 * contains that block.
194 195 */
195 196 static int
196 197 block_map(f, file_block, disk_block_p)
197 198 struct open_file *f;
198 199 ufs2_daddr_t file_block;
199 200 ufs2_daddr_t *disk_block_p; /* out */
200 201 {
201 202 struct file *fp = (struct file *)f->f_fsdata;
202 203 struct fs *fs = fp->f_fs;
203 204 int level;
204 205 int idx;
205 206 ufs2_daddr_t ind_block_num;
206 207 int rc;
207 208
208 209 /*
209 210 * Index structure of an inode:
210 211 *
211 212 * di_db[0..NDADDR-1] hold block numbers for blocks
212 213 * 0..NDADDR-1
213 214 *
214 215 * di_ib[0] index block 0 is the single indirect block
215 216 * holds block numbers for blocks
216 217 * NDADDR .. NDADDR + NINDIR(fs)-1
217 218 *
218 219 * di_ib[1] index block 1 is the double indirect block
219 220 * holds block numbers for INDEX blocks for blocks
220 221 * NDADDR + NINDIR(fs) ..
221 222 * NDADDR + NINDIR(fs) + NINDIR(fs)**2 - 1
222 223 *
223 224 * di_ib[2] index block 2 is the triple indirect block
224 225 * holds block numbers for double-indirect
225 226 * blocks for blocks
226 227 * NDADDR + NINDIR(fs) + NINDIR(fs)**2 ..
227 228 * NDADDR + NINDIR(fs) + NINDIR(fs)**2
228 229 * + NINDIR(fs)**3 - 1
229 230 */
230 231
231 232 if (file_block < NDADDR) {
232 233 /* Direct block. */
233 234 *disk_block_p = DIP(fp, di_db[file_block]);
234 235 return (0);
235 236 }
236 237
237 238 file_block -= NDADDR;
238 239
239 240 /*
240 241 * nindir[0] = NINDIR
241 242 * nindir[1] = NINDIR**2
242 243 * nindir[2] = NINDIR**3
243 244 * etc
244 245 */
245 246 for (level = 0; level < NIADDR; level++) {
246 247 if (file_block < fp->f_nindir[level])
247 248 break;
248 249 file_block -= fp->f_nindir[level];
249 250 }
250 251 if (level == NIADDR) {
251 252 /* Block number too high */
252 253 return (EFBIG);
253 254 }
254 255
255 256 ind_block_num = DIP(fp, di_ib[level]);
256 257
257 258 for (; level >= 0; level--) {
258 259 if (ind_block_num == 0) {
259 260 *disk_block_p = 0; /* missing */
260 261 return (0);
261 262 }
262 263
263 264 if (fp->f_blkno[level] != ind_block_num) {
264 265 if (fp->f_blk[level] == (char *)0)
265 266 fp->f_blk[level] =
266 267 malloc(fs->fs_bsize);
267 268 twiddle(1);
268 269 rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
269 270 fsbtodb(fp->f_fs, ind_block_num),
270 271 fs->fs_bsize,
271 272 fp->f_blk[level],
272 273 &fp->f_blksize[level]);
273 274 if (rc)
274 275 return (rc);
275 276 if (fp->f_blksize[level] != fs->fs_bsize)
276 277 return (EIO);
277 278 fp->f_blkno[level] = ind_block_num;
278 279 }
279 280
280 281 if (level > 0) {
281 282 idx = file_block / fp->f_nindir[level - 1];
282 283 file_block %= fp->f_nindir[level - 1];
283 284 } else
284 285 idx = file_block;
285 286
286 287 if (fp->f_fs->fs_magic == FS_UFS1_MAGIC)
287 288 ind_block_num = ((ufs1_daddr_t *)fp->f_blk[level])[idx];
288 289 else
289 290 ind_block_num = ((ufs2_daddr_t *)fp->f_blk[level])[idx];
290 291 }
291 292
292 293 *disk_block_p = ind_block_num;
|
↓ open down ↓ |
149 lines elided |
↑ open up ↑ |
293 294
294 295 return (0);
295 296 }
296 297
297 298 /*
298 299 * Write a portion of a file from an internal buffer.
299 300 */
300 301 static int
301 302 buf_write_file(f, buf_p, size_p)
302 303 struct open_file *f;
303 - char *buf_p;
304 + const char *buf_p;
304 305 size_t *size_p; /* out */
305 306 {
306 307 struct file *fp = (struct file *)f->f_fsdata;
307 308 struct fs *fs = fp->f_fs;
308 309 long off;
309 310 ufs_lbn_t file_block;
310 311 ufs2_daddr_t disk_block;
311 312 size_t block_size;
312 313 int rc;
313 314
314 315 /*
315 316 * Calculate the starting block address and offset.
316 317 */
317 318 off = blkoff(fs, fp->f_seekp);
318 319 file_block = lblkno(fs, fp->f_seekp);
319 320 block_size = sblksize(fs, DIP(fp, di_size), file_block);
320 321
321 322 rc = block_map(f, file_block, &disk_block);
322 323 if (rc)
323 324 return (rc);
324 325
325 326 if (disk_block == 0)
326 327 /* Because we can't allocate space on the drive */
327 328 return (EFBIG);
328 329
329 330 /*
330 331 * Truncate buffer at end of file, and at the end of
331 332 * this block.
332 333 */
333 334 if (*size_p > DIP(fp, di_size) - fp->f_seekp)
334 335 *size_p = DIP(fp, di_size) - fp->f_seekp;
335 336 if (*size_p > block_size - off)
336 337 *size_p = block_size - off;
337 338
338 339 /*
339 340 * If we don't entirely occlude the block and it's not
340 341 * in memory already, read it in first.
341 342 */
342 343 if (((off > 0) || (*size_p + off < block_size)) &&
343 344 (file_block != fp->f_buf_blkno)) {
344 345
345 346 if (fp->f_buf == (char *)0)
346 347 fp->f_buf = malloc(fs->fs_bsize);
347 348
348 349 twiddle(8);
349 350 rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
350 351 fsbtodb(fs, disk_block),
351 352 block_size, fp->f_buf, &fp->f_buf_size);
352 353 if (rc)
353 354 return (rc);
354 355
355 356 fp->f_buf_blkno = file_block;
356 357 }
357 358
358 359 /*
359 360 * Copy the user data into the cached block.
360 361 */
361 362 bcopy(buf_p, fp->f_buf + off, *size_p);
362 363
363 364 /*
364 365 * Write the block out to storage.
365 366 */
366 367
367 368 twiddle(4);
368 369 rc = (f->f_dev->dv_strategy)(f->f_devdata, F_WRITE,
369 370 fsbtodb(fs, disk_block),
370 371 block_size, fp->f_buf, &fp->f_buf_size);
371 372 return (rc);
372 373 }
373 374
374 375 /*
375 376 * Read a portion of a file into an internal buffer. Return
376 377 * the location in the buffer and the amount in the buffer.
377 378 */
378 379 static int
379 380 buf_read_file(f, buf_p, size_p)
380 381 struct open_file *f;
381 382 char **buf_p; /* out */
382 383 size_t *size_p; /* out */
383 384 {
384 385 struct file *fp = (struct file *)f->f_fsdata;
385 386 struct fs *fs = fp->f_fs;
386 387 long off;
387 388 ufs_lbn_t file_block;
388 389 ufs2_daddr_t disk_block;
389 390 size_t block_size;
390 391 int rc;
391 392
392 393 off = blkoff(fs, fp->f_seekp);
393 394 file_block = lblkno(fs, fp->f_seekp);
394 395 block_size = sblksize(fs, DIP(fp, di_size), file_block);
395 396
396 397 if (file_block != fp->f_buf_blkno) {
397 398 if (fp->f_buf == (char *)0)
398 399 fp->f_buf = malloc(fs->fs_bsize);
399 400
400 401 rc = block_map(f, file_block, &disk_block);
401 402 if (rc)
402 403 return (rc);
403 404
404 405 if (disk_block == 0) {
405 406 bzero(fp->f_buf, block_size);
406 407 fp->f_buf_size = block_size;
407 408 } else {
408 409 twiddle(4);
409 410 rc = (f->f_dev->dv_strategy)(f->f_devdata,
410 411 F_READ, fsbtodb(fs, disk_block),
411 412 block_size, fp->f_buf, &fp->f_buf_size);
412 413 if (rc)
413 414 return (rc);
414 415 }
415 416
416 417 fp->f_buf_blkno = file_block;
417 418 }
418 419
419 420 /*
420 421 * Return address of byte in buffer corresponding to
421 422 * offset, and size of remainder of buffer after that
422 423 * byte.
423 424 */
424 425 *buf_p = fp->f_buf + off;
425 426 *size_p = block_size - off;
426 427
427 428 /*
428 429 * But truncate buffer at end of file.
429 430 */
430 431 if (*size_p > DIP(fp, di_size) - fp->f_seekp)
431 432 *size_p = DIP(fp, di_size) - fp->f_seekp;
432 433
433 434 return (0);
434 435 }
435 436
436 437 /*
437 438 * Search a directory for a name and return its
438 439 * i_number.
439 440 */
440 441 static int
441 442 search_directory(name, f, inumber_p)
442 443 char *name;
443 444 struct open_file *f;
444 445 ino_t *inumber_p; /* out */
445 446 {
446 447 struct file *fp = (struct file *)f->f_fsdata;
447 448 struct direct *dp;
448 449 struct direct *edp;
449 450 char *buf;
450 451 size_t buf_size;
451 452 int namlen, length;
452 453 int rc;
453 454
454 455 length = strlen(name);
455 456
456 457 fp->f_seekp = 0;
457 458 while (fp->f_seekp < DIP(fp, di_size)) {
458 459 rc = buf_read_file(f, &buf, &buf_size);
459 460 if (rc)
460 461 return (rc);
461 462
462 463 dp = (struct direct *)buf;
463 464 edp = (struct direct *)(buf + buf_size);
464 465 while (dp < edp) {
465 466 if (dp->d_ino == (ino_t)0)
466 467 goto next;
467 468 namlen = dp->d_namlen;
468 469 if (namlen == length &&
469 470 !strcmp(name, dp->d_name)) {
470 471 /* found entry */
471 472 *inumber_p = dp->d_ino;
472 473 return (0);
473 474 }
474 475 next:
475 476 dp = (struct direct *)((char *)dp + dp->d_reclen);
476 477 }
477 478 fp->f_seekp += buf_size;
478 479 }
479 480 return (ENOENT);
480 481 }
481 482
482 483 static int sblock_try[] = SBLOCKSEARCH;
483 484
484 485 /*
485 486 * Open a file.
486 487 */
487 488 static int
488 489 ufs_open(upath, f)
489 490 const char *upath;
490 491 struct open_file *f;
491 492 {
492 493 char *cp, *ncp;
493 494 int c;
494 495 ino_t inumber, parent_inumber;
495 496 struct file *fp;
496 497 struct fs *fs;
497 498 int i, rc;
498 499 size_t buf_size;
499 500 int nlinks = 0;
500 501 char namebuf[MAXPATHLEN+1];
501 502 char *buf = NULL;
502 503 char *path = NULL;
503 504
504 505 /* allocate file system specific data structure */
505 506 fp = malloc(sizeof(struct file));
506 507 bzero(fp, sizeof(struct file));
507 508 f->f_fsdata = (void *)fp;
508 509
509 510 /* allocate space and read super block */
510 511 fs = malloc(SBLOCKSIZE);
511 512 fp->f_fs = fs;
512 513 twiddle(1);
513 514 /*
514 515 * Try reading the superblock in each of its possible locations.
515 516 */
516 517 for (i = 0; sblock_try[i] != -1; i++) {
517 518 rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
518 519 sblock_try[i] / DEV_BSIZE, SBLOCKSIZE,
519 520 (char *)fs, &buf_size);
520 521 if (rc)
521 522 goto out;
522 523 if ((fs->fs_magic == FS_UFS1_MAGIC ||
523 524 (fs->fs_magic == FS_UFS2_MAGIC &&
524 525 fs->fs_sblockloc == sblock_try[i])) &&
525 526 buf_size == SBLOCKSIZE &&
526 527 fs->fs_bsize <= MAXBSIZE &&
527 528 fs->fs_bsize >= sizeof(struct fs))
528 529 break;
529 530 }
530 531 if (sblock_try[i] == -1) {
531 532 rc = EINVAL;
532 533 goto out;
533 534 }
534 535 /*
535 536 * Calculate indirect block levels.
536 537 */
537 538 {
538 539 ufs2_daddr_t mult;
539 540 int level;
540 541
541 542 mult = 1;
542 543 for (level = 0; level < NIADDR; level++) {
543 544 mult *= NINDIR(fs);
544 545 fp->f_nindir[level] = mult;
545 546 }
546 547 }
547 548
548 549 inumber = ROOTINO;
549 550 if ((rc = read_inode(inumber, f)) != 0)
550 551 goto out;
551 552
552 553 cp = path = strdup(upath);
553 554 if (path == NULL) {
554 555 rc = ENOMEM;
555 556 goto out;
556 557 }
557 558 while (*cp) {
558 559
559 560 /*
560 561 * Remove extra separators
561 562 */
562 563 while (*cp == '/')
563 564 cp++;
564 565 if (*cp == '\0')
565 566 break;
566 567
567 568 /*
568 569 * Check that current node is a directory.
569 570 */
570 571 if ((DIP(fp, di_mode) & IFMT) != IFDIR) {
571 572 rc = ENOTDIR;
572 573 goto out;
573 574 }
574 575
575 576 /*
576 577 * Get next component of path name.
577 578 */
578 579 {
579 580 int len = 0;
580 581
581 582 ncp = cp;
582 583 while ((c = *cp) != '\0' && c != '/') {
583 584 if (++len > UFS_MAXNAMLEN) {
584 585 rc = ENOENT;
585 586 goto out;
586 587 }
587 588 cp++;
588 589 }
589 590 *cp = '\0';
590 591 }
591 592
592 593 /*
593 594 * Look up component in current directory.
594 595 * Save directory inumber in case we find a
595 596 * symbolic link.
596 597 */
597 598 parent_inumber = inumber;
598 599 rc = search_directory(ncp, f, &inumber);
599 600 *cp = c;
600 601 if (rc)
601 602 goto out;
602 603
603 604 /*
604 605 * Open next component.
605 606 */
606 607 if ((rc = read_inode(inumber, f)) != 0)
607 608 goto out;
608 609
609 610 /*
610 611 * Check for symbolic link.
611 612 */
612 613 if ((DIP(fp, di_mode) & IFMT) == IFLNK) {
613 614 int link_len = DIP(fp, di_size);
614 615 int len;
615 616
616 617 len = strlen(cp);
617 618
618 619 if (link_len + len > MAXPATHLEN ||
619 620 ++nlinks > MAXSYMLINKS) {
620 621 rc = ENOENT;
621 622 goto out;
622 623 }
623 624
624 625 bcopy(cp, &namebuf[link_len], len + 1);
625 626
626 627 if (link_len < fs->fs_maxsymlinklen) {
627 628 if (fp->f_fs->fs_magic == FS_UFS1_MAGIC)
628 629 cp = (caddr_t)(fp->f_di.di1.di_db);
629 630 else
630 631 cp = (caddr_t)(fp->f_di.di2.di_db);
631 632 bcopy(cp, namebuf, (unsigned) link_len);
632 633 } else {
633 634 /*
634 635 * Read file for symbolic link
635 636 */
636 637 size_t buf_size;
637 638 ufs2_daddr_t disk_block;
638 639 struct fs *fs = fp->f_fs;
639 640
640 641 if (!buf)
641 642 buf = malloc(fs->fs_bsize);
642 643 rc = block_map(f, (ufs2_daddr_t)0, &disk_block);
643 644 if (rc)
644 645 goto out;
645 646
646 647 twiddle(1);
647 648 rc = (f->f_dev->dv_strategy)(f->f_devdata,
648 649 F_READ, fsbtodb(fs, disk_block),
649 650 fs->fs_bsize, buf, &buf_size);
650 651 if (rc)
651 652 goto out;
652 653
653 654 bcopy((char *)buf, namebuf, (unsigned)link_len);
654 655 }
655 656
656 657 /*
657 658 * If relative pathname, restart at parent directory.
658 659 * If absolute pathname, restart at root.
659 660 */
660 661 cp = namebuf;
661 662 if (*cp != '/')
662 663 inumber = parent_inumber;
663 664 else
664 665 inumber = (ino_t)ROOTINO;
665 666
666 667 if ((rc = read_inode(inumber, f)) != 0)
667 668 goto out;
668 669 }
669 670 }
670 671
671 672 /*
672 673 * Found terminal component.
673 674 */
674 675 rc = 0;
675 676 fp->f_seekp = 0;
676 677 out:
677 678 if (buf)
678 679 free(buf);
679 680 if (path)
680 681 free(path);
681 682 if (rc) {
682 683 if (fp->f_buf)
683 684 free(fp->f_buf);
684 685 free(fp->f_fs);
685 686 free(fp);
686 687 }
687 688 return (rc);
688 689 }
689 690
690 691 static int
691 692 ufs_close(f)
692 693 struct open_file *f;
693 694 {
694 695 struct file *fp = (struct file *)f->f_fsdata;
695 696 int level;
696 697
697 698 f->f_fsdata = (void *)0;
698 699 if (fp == (struct file *)0)
699 700 return (0);
700 701
701 702 for (level = 0; level < NIADDR; level++) {
702 703 if (fp->f_blk[level])
703 704 free(fp->f_blk[level]);
704 705 }
705 706 if (fp->f_buf)
706 707 free(fp->f_buf);
707 708 free(fp->f_fs);
708 709 free(fp);
709 710 return (0);
710 711 }
711 712
712 713 /*
713 714 * Copy a portion of a file into kernel memory.
714 715 * Cross block boundaries when necessary.
715 716 */
716 717 static int
717 718 ufs_read(f, start, size, resid)
718 719 struct open_file *f;
719 720 void *start;
720 721 size_t size;
721 722 size_t *resid; /* out */
722 723 {
723 724 struct file *fp = (struct file *)f->f_fsdata;
724 725 size_t csize;
725 726 char *buf;
726 727 size_t buf_size;
727 728 int rc = 0;
728 729 char *addr = start;
729 730
730 731 while (size != 0) {
731 732 if (fp->f_seekp >= DIP(fp, di_size))
732 733 break;
733 734
734 735 rc = buf_read_file(f, &buf, &buf_size);
735 736 if (rc)
736 737 break;
737 738
738 739 csize = size;
739 740 if (csize > buf_size)
740 741 csize = buf_size;
741 742
742 743 bcopy(buf, addr, csize);
743 744
744 745 fp->f_seekp += csize;
745 746 addr += csize;
746 747 size -= csize;
747 748 }
748 749 if (resid)
749 750 *resid = size;
750 751 return (rc);
|
↓ open down ↓ |
437 lines elided |
↑ open up ↑ |
751 752 }
752 753
753 754 /*
754 755 * Write to a portion of an already allocated file.
755 756 * Cross block boundaries when necessary. Can not
756 757 * extend the file.
757 758 */
758 759 static int
759 760 ufs_write(f, start, size, resid)
760 761 struct open_file *f;
761 - void *start;
762 + const void *start;
762 763 size_t size;
763 764 size_t *resid; /* out */
764 765 {
765 766 struct file *fp = (struct file *)f->f_fsdata;
766 767 size_t csize;
767 768 int rc = 0;
768 - char *addr = start;
769 + const char *addr = start;
769 770
770 771 csize = size;
771 772 while ((size != 0) && (csize != 0)) {
772 773 if (fp->f_seekp >= DIP(fp, di_size))
773 774 break;
774 775
775 776 if (csize >= 512) csize = 512; /* XXX */
776 777
777 778 rc = buf_write_file(f, addr, &csize);
778 779 if (rc)
779 780 break;
780 781
781 782 fp->f_seekp += csize;
782 783 addr += csize;
783 784 size -= csize;
784 785 }
785 786 if (resid)
786 787 *resid = size;
787 788 return (rc);
788 789 }
789 790
790 791 static off_t
791 792 ufs_seek(f, offset, where)
792 793 struct open_file *f;
793 794 off_t offset;
794 795 int where;
795 796 {
796 797 struct file *fp = (struct file *)f->f_fsdata;
797 798
798 799 switch (where) {
799 800 case SEEK_SET:
800 801 fp->f_seekp = offset;
801 802 break;
802 803 case SEEK_CUR:
803 804 fp->f_seekp += offset;
804 805 break;
805 806 case SEEK_END:
806 807 fp->f_seekp = DIP(fp, di_size) - offset;
807 808 break;
808 809 default:
809 810 errno = EINVAL;
810 811 return (-1);
811 812 }
812 813 return (fp->f_seekp);
813 814 }
814 815
815 816 static int
816 817 ufs_stat(f, sb)
817 818 struct open_file *f;
818 819 struct stat *sb;
819 820 {
820 821 struct file *fp = (struct file *)f->f_fsdata;
821 822
822 823 /* only important stuff */
823 824 sb->st_mode = DIP(fp, di_mode);
824 825 sb->st_uid = DIP(fp, di_uid);
825 826 sb->st_gid = DIP(fp, di_gid);
826 827 sb->st_size = DIP(fp, di_size);
827 828 return (0);
828 829 }
829 830
830 831 static int
831 832 ufs_readdir(struct open_file *f, struct dirent *d)
832 833 {
833 834 struct file *fp = (struct file *)f->f_fsdata;
834 835 struct direct *dp;
835 836 char *buf;
836 837 size_t buf_size;
837 838 int error;
838 839
839 840 /*
840 841 * assume that a directory entry will not be split across blocks
841 842 */
842 843 again:
843 844 if (fp->f_seekp >= DIP(fp, di_size))
844 845 return (ENOENT);
845 846 error = buf_read_file(f, &buf, &buf_size);
846 847 if (error)
847 848 return (error);
848 849 dp = (struct direct *)buf;
849 850 fp->f_seekp += dp->d_reclen;
850 851 if (dp->d_ino == (ino_t)0)
851 852 goto again;
852 853
853 854 d->d_type = 0; /* illumos ufs does not have type in direct */
854 855 strcpy(d->d_name, dp->d_name);
855 856 return (0);
856 857 }
|
↓ open down ↓ |
78 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX