1 /* $OpenBSD: ufs2.c,v 1.8 2019/08/03 15:22:17 deraadt Exp $ */
2
3 /*-
4 * Copyright (c) 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * The Mach Operating System project at Carnegie-Mellon University.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 *
35 * Copyright (c) 1990, 1991 Carnegie Mellon University
36 * All Rights Reserved.
37 *
38 * Author: David Golub
39 *
40 * Permission to use, copy, modify and distribute this software and its
41 * documentation is hereby granted, provided that both the copyright
42 * notice and this permission notice appear in all copies of the
43 * software, derivative works or modified versions, and any portions
44 * thereof, and that both notices appear in supporting documentation.
45 *
46 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
47 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
48 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
49 *
50 * Carnegie Mellon requests users of this software to return to
51 *
52 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
53 * School of Computer Science
54 * Carnegie Mellon University
55 * Pittsburgh PA 15213-3890
56 *
57 * any improvements or extensions that they make and grant Carnegie the
58 * rights to redistribute these changes.
59 */
60
61 /*
62 * Stand-alone file reading package.
63 */
64
65 #include <sys/param.h>
66 #include <sys/time.h>
67 #include <sys/stat.h>
68 #include <ufs/ffs/fs.h>
69 #include <ufs/ufs/dinode.h>
70 #include <ufs/ufs/dir.h>
71 #include <lib/libkern/libkern.h>
72
73 #include "stand.h"
74 #include "ufs2.h"
75
76 /*
77 * In-core open file.
78 */
79 struct file {
80 off_t f_seekp; /* seek pointer */
81 struct fs *f_fs; /* pointer to super-block */
82 struct ufs2_dinode f_di; /* copy of on-disk inode */
83 ufsino_t f_ino; /* our inode number */
84 int f_nindir[NIADDR];
85 /* number of blocks mapped by
86 indirect block at level i */
87 char *f_blk[NIADDR]; /* buffer for indirect block at
88 level i */
89 size_t f_blksize[NIADDR];
90 /* size of buffer */
91 daddr_t f_blkno[NIADDR];/* disk address of block in buffer */
92 char *f_buf; /* buffer for data block */
93 size_t f_buf_size; /* size of data block */
94 daddr_t f_buf_blkno; /* block number of data block */
95 };
96
97 static int read_inode(ufsino_t, struct open_file *);
98 static int chmod_inode(ufsino_t, struct open_file *, mode_t);
99 static int block_map(struct open_file *, daddr_t, daddr_t *);
100 static int buf_read_file(struct open_file *, char **, size_t *);
101 static int search_directory(char *, struct open_file *, ufsino_t *);
102 static int ufs2_close_internal(struct file *);
103 #ifdef COMPAT_UFS
104 static void ffs_oldfscompat(struct fs *);
105 #endif
106
107 /*
108 * Read a new inode into a file structure.
109 */
110 static int
read_inode(ufsino_t inumber,struct open_file * f)111 read_inode(ufsino_t inumber, struct open_file *f)
112 {
113 struct file *fp = (struct file *)f->f_fsdata;
114 struct fs *fs = fp->f_fs;
115 char *buf;
116 size_t rsize;
117 int rc;
118
119 /*
120 * Read inode and save it.
121 */
122 buf = alloc(fs->fs_bsize);
123 twiddle();
124 rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
125 fsbtodb(fs, ino_to_fsba(fs, inumber)), fs->fs_bsize, buf, &rsize);
126 if (rc)
127 goto out;
128 if (rsize != (size_t)fs->fs_bsize) {
129 rc = EIO;
130 goto out;
131 }
132
133 {
134 struct ufs2_dinode *dp;
135
136 dp = (struct ufs2_dinode *)buf;
137 fp->f_di = dp[ino_to_fsbo(fs, inumber)];
138 }
139
140 /*
141 * Clear out the old buffers
142 */
143 {
144 int level;
145
146 for (level = 0; level < NIADDR; level++)
147 fp->f_blkno[level] = -1;
148 fp->f_buf_blkno = -1;
149 fp->f_seekp = 0;
150 }
151 out:
152 free(buf, fs->fs_bsize);
153 return (rc);
154 }
155
156 /*
157 * Read a new inode into a file structure.
158 */
159 static int
chmod_inode(ufsino_t inumber,struct open_file * f,mode_t mode)160 chmod_inode(ufsino_t inumber, struct open_file *f, mode_t mode)
161 {
162 struct file *fp = (struct file *)f->f_fsdata;
163 struct fs *fs = fp->f_fs;
164 char *buf;
165 size_t rsize;
166 int rc;
167
168 /*
169 * Read inode and save it.
170 */
171 buf = alloc(fs->fs_bsize);
172 twiddle();
173 rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
174 fsbtodb(fs, ino_to_fsba(fs, inumber)), fs->fs_bsize, buf, &rsize);
175 if (rc)
176 goto out;
177 if (rsize != (size_t)fs->fs_bsize) {
178 rc = EIO;
179 goto out;
180 }
181
182 {
183 struct ufs2_dinode *dp;
184
185 dp = &((struct ufs2_dinode *)buf)[ino_to_fsbo(fs, inumber)];
186 dp->di_mode = mode;
187 }
188
189 twiddle();
190 rc = (f->f_dev->dv_strategy)(f->f_devdata, F_WRITE,
191 fsbtodb(fs, ino_to_fsba(fs, inumber)), fs->fs_bsize, buf, NULL);
192
193 out:
194 free(buf, fs->fs_bsize);
195 return (rc);
196 }
197
198 /*
199 * Given an offset in a file, find the disk block number that
200 * contains that block.
201 */
202 static int
block_map(struct open_file * f,daddr_t file_block,daddr_t * disk_block_p)203 block_map(struct open_file *f, daddr_t file_block, daddr_t *disk_block_p)
204 {
205 struct file *fp = (struct file *)f->f_fsdata;
206 daddr_t ind_block_num, *ind_p;
207 struct fs *fs = fp->f_fs;
208 int level, idx, rc;
209
210 /*
211 * Index structure of an inode:
212 *
213 * di_db[0..NDADDR-1] hold block numbers for blocks
214 * 0..NDADDR-1
215 *
216 * di_ib[0] index block 0 is the single indirect block
217 * holds block numbers for blocks
218 * NDADDR .. NDADDR + NINDIR(fs)-1
219 *
220 * di_ib[1] index block 1 is the double indirect block
221 * holds block numbers for INDEX blocks for blocks
222 * NDADDR + NINDIR(fs) ..
223 * NDADDR + NINDIR(fs) + NINDIR(fs)**2 - 1
224 *
225 * di_ib[2] index block 2 is the triple indirect block
226 * holds block numbers for double-indirect
227 * blocks for blocks
228 * NDADDR + NINDIR(fs) + NINDIR(fs)**2 ..
229 * NDADDR + NINDIR(fs) + NINDIR(fs)**2
230 * + NINDIR(fs)**3 - 1
231 */
232
233 if (file_block < NDADDR) {
234 /* Direct block. */
235 *disk_block_p = fp->f_di.di_db[file_block];
236 return (0);
237 }
238
239 file_block -= NDADDR;
240
241 /*
242 * nindir[0] = NINDIR
243 * nindir[1] = NINDIR**2
244 * nindir[2] = NINDIR**3
245 * etc
246 */
247 for (level = 0; level < NIADDR; level++) {
248 if (file_block < fp->f_nindir[level])
249 break;
250 file_block -= fp->f_nindir[level];
251 }
252 if (level == NIADDR) {
253 /* Block number too high */
254 return (EFBIG);
255 }
256
257 ind_block_num = fp->f_di.di_ib[level];
258
259 for (; level >= 0; level--) {
260 if (ind_block_num == 0) {
261 *disk_block_p = 0; /* missing */
262 return (0);
263 }
264
265 if (fp->f_blkno[level] != ind_block_num) {
266 if (fp->f_blk[level] == NULL)
267 fp->f_blk[level] =
268 alloc(fs->fs_bsize);
269 twiddle();
270 rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
271 fsbtodb(fp->f_fs, ind_block_num), fs->fs_bsize,
272 fp->f_blk[level], &fp->f_blksize[level]);
273 if (rc)
274 return (rc);
275 if (fp->f_blksize[level] != (size_t)fs->fs_bsize)
276 return (EIO);
277 fp->f_blkno[level] = ind_block_num;
278 }
279
280 ind_p = (daddr_t *)fp->f_blk[level];
281
282 if (level > 0) {
283 idx = file_block / fp->f_nindir[level - 1];
284 file_block %= fp->f_nindir[level - 1];
285 } else
286 idx = file_block;
287
288 ind_block_num = ind_p[idx];
289 }
290
291 *disk_block_p = ind_block_num;
292 return (0);
293 }
294
295 /*
296 * Read a portion of a file into an internal buffer. Return
297 * the location in the buffer and the amount in the buffer.
298 */
299 static int
buf_read_file(struct open_file * f,char ** buf_p,size_t * size_p)300 buf_read_file(struct open_file *f, char **buf_p, size_t *size_p)
301 {
302 struct file *fp = (struct file *)f->f_fsdata;
303 struct fs *fs = fp->f_fs;
304 daddr_t file_block, disk_block;
305 size_t block_size;
306 long off;
307 int rc;
308
309 off = blkoff(fs, fp->f_seekp);
310 file_block = lblkno(fs, fp->f_seekp);
311 block_size = dblksize(fs, &fp->f_di, (u_int64_t)file_block);
312
313 if (file_block != fp->f_buf_blkno) {
314 rc = block_map(f, file_block, &disk_block);
315 if (rc)
316 return (rc);
317
318 if (fp->f_buf == NULL)
319 fp->f_buf = alloc(fs->fs_bsize);
320
321 if (disk_block == 0) {
322 bzero(fp->f_buf, block_size);
323 fp->f_buf_size = block_size;
324 } else {
325 twiddle();
326 rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
327 fsbtodb(fs, disk_block),
328 block_size, fp->f_buf, &fp->f_buf_size);
329 if (rc)
330 return (rc);
331 }
332
333 fp->f_buf_blkno = file_block;
334 }
335
336 /*
337 * Return address of byte in buffer corresponding to
338 * offset, and size of remainder of buffer after that
339 * byte.
340 */
341 *buf_p = fp->f_buf + off;
342 *size_p = block_size - off;
343
344 /*
345 * But truncate buffer at end of file.
346 */
347 if (*size_p > fp->f_di.di_size - fp->f_seekp)
348 *size_p = fp->f_di.di_size - fp->f_seekp;
349
350 return (0);
351 }
352
353 /*
354 * Search a directory for a name and return its
355 * i_number.
356 */
357 static int
search_directory(char * name,struct open_file * f,ufsino_t * inumber_p)358 search_directory(char *name, struct open_file *f, ufsino_t *inumber_p)
359 {
360 struct file *fp = (struct file *)f->f_fsdata;
361 int namlen, length, rc;
362 struct direct *dp, *edp;
363 size_t buf_size;
364 char *buf;
365
366 length = strlen(name);
367
368 fp->f_seekp = 0;
369 while ((u_int64_t)fp->f_seekp < fp->f_di.di_size) {
370 rc = buf_read_file(f, &buf, &buf_size);
371 if (rc)
372 return (rc);
373
374 dp = (struct direct *)buf;
375 edp = (struct direct *)(buf + buf_size);
376 while (dp < edp) {
377 if (dp->d_ino == 0)
378 goto next;
379 #if BYTE_ORDER == LITTLE_ENDIAN
380 if (fp->f_fs->fs_maxsymlinklen <= 0)
381 namlen = dp->d_type;
382 else
383 #endif
384 namlen = dp->d_namlen;
385 if (namlen == length &&
386 !strcmp(name, dp->d_name)) {
387 /* found entry */
388 *inumber_p = dp->d_ino;
389 return (0);
390 }
391 next:
392 dp = (struct direct *)((char *)dp + dp->d_reclen);
393 }
394 fp->f_seekp += buf_size;
395 }
396 return (ENOENT);
397 }
398
399 /*
400 * Open a file.
401 */
402 int
ufs2_open(char * path,struct open_file * f)403 ufs2_open(char *path, struct open_file *f)
404 {
405 char namebuf[MAXPATHLEN+1], *cp, *ncp, *buf = NULL;
406 ufsino_t inumber, parent_inumber;
407 int rc, c, nlinks = 0;
408 struct file *fp;
409 size_t buf_size;
410 struct fs *fs;
411
412 /* allocate file system specific data structure */
413 fp = alloc(sizeof(struct file));
414 bzero(fp, sizeof(struct file));
415 f->f_fsdata = (void *)fp;
416
417 /* allocate space and read super block */
418 fs = alloc(SBSIZE);
419 fp->f_fs = fs;
420 twiddle();
421 rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
422 SBLOCK_UFS2 / DEV_BSIZE, SBSIZE, (char *)fs, &buf_size);
423 if (rc)
424 goto out;
425
426 if (buf_size != SBSIZE || fs->fs_magic != FS_UFS2_MAGIC ||
427 (u_int64_t)fs->fs_bsize > MAXBSIZE ||
428 (u_int64_t)fs->fs_bsize < sizeof(struct fs)) {
429 rc = EINVAL;
430 goto out;
431 }
432 #ifdef COMPAT_UFS
433 ffs_oldfscompat(fs);
434 #endif
435
436 /*
437 * Calculate indirect block levels.
438 */
439 {
440 int mult;
441 int level;
442
443 mult = 1;
444 for (level = 0; level < NIADDR; level++) {
445 mult *= NINDIR(fs);
446 fp->f_nindir[level] = mult;
447 }
448 }
449
450 inumber = ROOTINO;
451 if ((rc = read_inode(inumber, f)) != 0)
452 goto out;
453
454 cp = path;
455 while (*cp) {
456
457 /*
458 * Remove extra separators
459 */
460 while (*cp == '/')
461 cp++;
462 if (*cp == '\0')
463 break;
464
465 /*
466 * Check that current node is a directory.
467 */
468 if ((fp->f_di.di_mode & IFMT) != IFDIR) {
469 rc = ENOTDIR;
470 goto out;
471 }
472
473 /*
474 * Get next component of path name.
475 */
476 {
477 int len = 0;
478
479 ncp = cp;
480 while ((c = *cp) != '\0' && c != '/') {
481 if (++len > MAXNAMLEN) {
482 rc = ENOENT;
483 goto out;
484 }
485 cp++;
486 }
487 *cp = '\0';
488 }
489
490 /*
491 * Look up component in current directory.
492 * Save directory inumber in case we find a
493 * symbolic link.
494 */
495 parent_inumber = inumber;
496 rc = search_directory(ncp, f, &inumber);
497 *cp = c;
498 if (rc)
499 goto out;
500
501 /*
502 * Open next component.
503 */
504 if ((rc = read_inode(inumber, f)) != 0)
505 goto out;
506
507 /*
508 * Check for symbolic link.
509 */
510 if ((fp->f_di.di_mode & IFMT) == IFLNK) {
511 u_int64_t link_len = fp->f_di.di_size;
512 size_t len;
513
514 len = strlen(cp);
515
516 if (link_len + len > MAXPATHLEN ||
517 ++nlinks > MAXSYMLINKS) {
518 rc = ENOENT;
519 goto out;
520 }
521
522 bcopy(cp, &namebuf[link_len], len + 1);
523
524 if (link_len < (u_int64_t)fs->fs_maxsymlinklen) {
525 bcopy(fp->f_di.di_shortlink, namebuf, link_len);
526 } else {
527 /*
528 * Read file for symbolic link
529 */
530 daddr_t disk_block;
531 fs = fp->f_fs;
532
533 if (!buf)
534 buf = alloc(fs->fs_bsize);
535 rc = block_map(f, 0, &disk_block);
536 if (rc)
537 goto out;
538
539 twiddle();
540 rc = (f->f_dev->dv_strategy)(f->f_devdata,
541 F_READ, fsbtodb(fs, disk_block),
542 fs->fs_bsize, buf, &buf_size);
543 if (rc)
544 goto out;
545
546 bcopy(buf, namebuf, link_len);
547 }
548
549 /*
550 * If relative pathname, restart at parent directory.
551 * If absolute pathname, restart at root.
552 */
553 cp = namebuf;
554 if (*cp != '/')
555 inumber = parent_inumber;
556 else
557 inumber = ROOTINO;
558
559 if ((rc = read_inode(inumber, f)) != 0)
560 goto out;
561 }
562 }
563
564 /*
565 * Found terminal component.
566 */
567 fp->f_ino = inumber;
568 rc = 0;
569 out:
570 if (buf)
571 free(buf, fs->fs_bsize);
572 if (rc)
573 (void)ufs2_close_internal(fp);
574
575 return (rc);
576 }
577
578 int
ufs2_close(struct open_file * f)579 ufs2_close(struct open_file *f)
580 {
581 struct file *fp = (struct file *)f->f_fsdata;
582
583 f->f_fsdata = NULL;
584 if (fp == NULL)
585 return (0);
586
587 return (ufs2_close_internal(fp));
588 }
589
590 static int
ufs2_close_internal(struct file * fp)591 ufs2_close_internal(struct file *fp)
592 {
593 int level;
594
595 for (level = 0; level < NIADDR; level++) {
596 if (fp->f_blk[level])
597 free(fp->f_blk[level], fp->f_fs->fs_bsize);
598 }
599 if (fp->f_buf)
600 free(fp->f_buf, fp->f_fs->fs_bsize);
601 free(fp->f_fs, SBSIZE);
602 free(fp, sizeof(struct file));
603 return (0);
604 }
605
606 /*
607 * Copy a portion of a file into kernel memory.
608 * Cross block boundaries when necessary.
609 */
610 int
ufs2_read(struct open_file * f,void * start,size_t size,size_t * resid)611 ufs2_read(struct open_file *f, void *start, size_t size, size_t *resid)
612 {
613 struct file *fp = (struct file *)f->f_fsdata;
614 char *buf, *addr = start;
615 size_t csize, buf_size;
616 int rc = 0;
617
618 while (size != 0) {
619 if ((u_int64_t)fp->f_seekp >= fp->f_di.di_size)
620 break;
621
622 rc = buf_read_file(f, &buf, &buf_size);
623 if (rc)
624 break;
625
626 csize = size;
627 if (csize > buf_size)
628 csize = buf_size;
629
630 bcopy(buf, addr, csize);
631
632 fp->f_seekp += csize;
633 addr += csize;
634 size -= csize;
635 }
636 if (resid)
637 *resid = size;
638 return (rc);
639 }
640
641 /*
642 * Not implemented.
643 */
644 int
ufs2_write(struct open_file * f,void * start,size_t size,size_t * resid)645 ufs2_write(struct open_file *f, void *start, size_t size, size_t *resid)
646 {
647
648 return (EROFS);
649 }
650
651 off_t
ufs2_seek(struct open_file * f,off_t offset,int where)652 ufs2_seek(struct open_file *f, off_t offset, int where)
653 {
654 struct file *fp = (struct file *)f->f_fsdata;
655
656 switch (where) {
657 case SEEK_SET:
658 fp->f_seekp = offset;
659 break;
660 case SEEK_CUR:
661 fp->f_seekp += offset;
662 break;
663 case SEEK_END:
664 fp->f_seekp = fp->f_di.di_size - offset;
665 break;
666 default:
667 return (-1);
668 }
669 return (fp->f_seekp);
670 }
671
672 int
ufs2_stat(struct open_file * f,struct stat * sb)673 ufs2_stat(struct open_file *f, struct stat *sb)
674 {
675 struct file *fp = (struct file *)f->f_fsdata;
676
677 /* only important stuff */
678 sb->st_mode = fp->f_di.di_mode;
679 sb->st_uid = fp->f_di.di_uid;
680 sb->st_gid = fp->f_di.di_gid;
681 sb->st_size = fp->f_di.di_size;
682 return (0);
683 }
684
685 int
ufs2_fchmod(struct open_file * f,mode_t mode)686 ufs2_fchmod(struct open_file *f, mode_t mode)
687 {
688 struct file *fp = (struct file *)f->f_fsdata;
689
690 return chmod_inode(fp->f_ino, f, mode);
691 }
692
693 #ifndef NO_READDIR
694 int
ufs2_readdir(struct open_file * f,char * name)695 ufs2_readdir(struct open_file *f, char *name)
696 {
697 struct file *fp = (struct file *)f->f_fsdata;
698 struct direct *dp, *edp;
699 size_t buf_size;
700 int rc, namlen;
701 char *buf;
702
703 if (name == NULL)
704 fp->f_seekp = 0;
705 else {
706 /* end of dir */
707 if ((u_int64_t)fp->f_seekp >= fp->f_di.di_size) {
708 *name = '\0';
709 return -1;
710 }
711
712 do {
713 if ((rc = buf_read_file(f, &buf, &buf_size)) != 0)
714 return rc;
715
716 dp = (struct direct *)buf;
717 edp = (struct direct *)(buf + buf_size);
718 while (dp < edp && dp->d_ino == 0)
719 dp = (struct direct *)((char *)dp + dp->d_reclen);
720 fp->f_seekp += buf_size -
721 ((u_int8_t *)edp - (u_int8_t *)dp);
722 } while (dp >= edp);
723
724 #if BYTE_ORDER == LITTLE_ENDIAN
725 if (fp->f_fs->fs_maxsymlinklen <= 0)
726 namlen = dp->d_type;
727 else
728 #endif
729 namlen = dp->d_namlen;
730 strncpy(name, dp->d_name, namlen + 1);
731
732 fp->f_seekp += dp->d_reclen;
733 }
734
735 return 0;
736 }
737 #endif
738
739 #ifdef COMPAT_UFS
740 /*
741 * Sanity checks for old file systems.
742 *
743 * XXX - goes away some day.
744 */
745 static void
ffs_oldfscompat(struct fs * fs)746 ffs_oldfscompat(struct fs *fs)
747 {
748 int i;
749
750 fs->fs_npsect = max(fs->fs_npsect, fs->fs_nsect); /* XXX */
751 fs->fs_interleave = max(fs->fs_interleave, 1); /* XXX */
752 if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */
753 fs->fs_nrpos = 8; /* XXX */
754 if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */
755 quad_t sizepb = fs->fs_bsize; /* XXX */
756 /* XXX */
757 fs->fs_maxfilesize = fs->fs_bsize * NDADDR - 1; /* XXX */
758 for (i = 0; i < NIADDR; i++) { /* XXX */
759 sizepb *= NINDIR(fs); /* XXX */
760 fs->fs_maxfilesize += sizepb; /* XXX */
761 } /* XXX */
762 fs->fs_qbmask = ~fs->fs_bmask; /* XXX */
763 fs->fs_qfmask = ~fs->fs_fmask; /* XXX */
764 } /* XXX */
765 }
766 #endif
767