1 /* $NetBSD: inode.c,v 1.36 2013/06/23 07:28:36 dholland Exp $ */
4 * Copyright (c) 1980, 1986, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * Copyright (c) 1997 Manuel Bouyer.
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
38 * 1. Redistributions of source code must retain the above copyright
39 * notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright
41 * notice, this list of conditions and the following disclaimer in the
42 * documentation and/or other materials provided with the distribution.
44 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
45 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
46 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
47 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
48 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
49 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
53 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56 #include <sys/cdefs.h>
59 static char sccsid
[] = "@(#)inode.c 8.5 (Berkeley) 2/8/95";
61 __RCSID("$NetBSD: inode.c,v 1.36 2013/06/23 07:28:36 dholland Exp $");
65 #include <sys/param.h>
67 #include <ufs/ext2fs/ext2fs_dinode.h>
68 #include <ufs/ext2fs/ext2fs_dir.h>
69 #include <ufs/ext2fs/ext2fs.h>
71 #include <ufs/ufs/dinode.h> /* for IFMT & friends */
85 * CG is stored in fs byte order in memory, so we can't use ino_to_fsba
89 #define fsck_ino_to_fsba(fs, x) \
90 (fs2h32((fs)->e2fs_gd[ino_to_cg(fs, x)].ext2bgd_i_tables) + \
91 (((x)-1) % (fs)->e2fs.e2fs_ipg)/(fs)->e2fs_ipb)
94 static ino_t startinum
;
96 static int iblock(struct inodesc
*, long, u_int64_t
);
98 static int setlarge(void);
100 static int sethuge(void);
105 if (sblock
.e2fs
.e2fs_rev
< E2FS_REV1
) {
106 pfatal("LARGE FILES UNSUPPORTED ON REVISION 0 FILESYSTEMS");
109 if (!(sblock
.e2fs
.e2fs_features_rocompat
& EXT2F_ROCOMPAT_LARGEFILE
)) {
111 pwarn("SETTING LARGE FILE INDICATOR\n");
112 else if (!reply("SET LARGE FILE INDICATOR"))
114 sblock
.e2fs
.e2fs_features_rocompat
|= EXT2F_ROCOMPAT_LARGEFILE
;
123 if (sblock
.e2fs
.e2fs_rev
< E2FS_REV1
) {
124 pfatal("HUGE FILES UNSUPPORTED ON REVISION 0 FILESYSTEMS");
127 if (!(sblock
.e2fs
.e2fs_features_rocompat
& EXT2F_ROCOMPAT_HUGE_FILE
)) {
129 pwarn("SETTING HUGE FILE FEATURE\n");
130 else if (!reply("SET HUGE FILE FEATURE"))
132 sblock
.e2fs
.e2fs_features_rocompat
|= EXT2F_ROCOMPAT_HUGE_FILE
;
139 inosize(struct ext2fs_dinode
*dp
)
141 u_int64_t size
= fs2h32(dp
->e2di_size
);
143 if ((fs2h16(dp
->e2di_mode
) & IFMT
) == IFREG
)
144 size
|= (u_int64_t
)fs2h32(dp
->e2di_dacl
) << 32;
145 if (size
> INT32_MAX
)
151 inossize(struct ext2fs_dinode
*dp
, u_int64_t size
)
153 if ((fs2h16(dp
->e2di_mode
) & IFMT
) == IFREG
) {
154 dp
->e2di_dacl
= h2fs32(size
>> 32);
155 if (size
> INT32_MAX
)
158 } else if (size
> INT32_MAX
) {
159 pfatal("TRYING TO SET FILESIZE TO %llu ON MODE %x FILE\n",
160 (unsigned long long)size
, fs2h16(dp
->e2di_mode
) & IFMT
);
163 dp
->e2di_size
= h2fs32(size
);
167 ckinode(struct ext2fs_dinode
*dp
, struct inodesc
*idesc
)
171 struct ext2fs_dinode dino
;
172 u_int64_t remsize
, sizepb
;
174 char pathbuf
[MAXPATHLEN
+ 1];
176 if (idesc
->id_fix
!= IGNORE
)
177 idesc
->id_fix
= DONTKNOW
;
178 idesc
->id_entryno
= 0;
179 idesc
->id_filesize
= inosize(dp
);
180 mode
= fs2h16(dp
->e2di_mode
) & IFMT
;
181 if (mode
== IFBLK
|| mode
== IFCHR
|| mode
== IFIFO
||
182 (mode
== IFLNK
&& (inosize(dp
) < EXT2_MAXSYMLINKLEN
)))
185 ndb
= howmany(inosize(&dino
), sblock
.e2fs_bsize
);
186 for (ap
= &dino
.e2di_blocks
[0]; ap
< &dino
.e2di_blocks
[EXT2FS_NDADDR
];
188 idesc
->id_numfrags
= 1;
190 if (idesc
->id_type
== DATA
&& ndb
> 0) {
191 /* An empty block in a directory XXX */
192 getpathname(pathbuf
, sizeof(pathbuf
),
193 idesc
->id_number
, idesc
->id_number
);
194 pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS",
196 if (reply("ADJUST LENGTH") == 1) {
197 dp
= ginode(idesc
->id_number
);
199 (ap
- &dino
.e2di_blocks
[0]) *
202 "YOU MUST RERUN FSCK AFTERWARDS\n");
209 idesc
->id_blkno
= fs2h32(*ap
);
210 if (idesc
->id_type
== ADDR
)
211 ret
= (*idesc
->id_func
)(idesc
);
213 ret
= dirscan(idesc
);
217 idesc
->id_numfrags
= 1;
218 remsize
= inosize(&dino
) - sblock
.e2fs_bsize
* EXT2FS_NDADDR
;
219 sizepb
= sblock
.e2fs_bsize
;
220 for (ap
= &dino
.e2di_blocks
[EXT2FS_NDADDR
], n
= 1; n
<= EXT2FS_NIADDR
; ap
++, n
++) {
222 idesc
->id_blkno
= fs2h32(*ap
);
223 ret
= iblock(idesc
, n
, remsize
);
227 if (idesc
->id_type
== DATA
&& remsize
> 0) {
228 /* An empty block in a directory XXX */
229 getpathname(pathbuf
, sizeof(pathbuf
),
230 idesc
->id_number
, idesc
->id_number
);
231 pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS",
233 if (reply("ADJUST LENGTH") == 1) {
234 dp
= ginode(idesc
->id_number
);
235 inossize(dp
, inosize(dp
) - remsize
);
238 "YOU MUST RERUN FSCK AFTERWARDS\n");
245 sizepb
*= EXT2_NINDIR(&sblock
);
252 iblock(struct inodesc
*idesc
, long ilevel
, u_int64_t isize
)
258 int i
, n
, (*func
)(struct inodesc
*);
262 char pathbuf
[MAXPATHLEN
+ 1];
263 struct ext2fs_dinode
*dp
;
265 if (idesc
->id_type
== ADDR
) {
266 func
= idesc
->id_func
;
267 if (((n
= (*func
)(idesc
)) & KEEPON
) == 0)
271 if (chkrange(idesc
->id_blkno
, idesc
->id_numfrags
))
273 bp
= getdatablk(idesc
->id_blkno
, sblock
.e2fs_bsize
);
275 for (sizepb
= sblock
.e2fs_bsize
, i
= 0; i
< ilevel
; i
++)
276 sizepb
*= EXT2_NINDIR(&sblock
);
277 if (isize
> sizepb
* EXT2_NINDIR(&sblock
))
278 nif
= EXT2_NINDIR(&sblock
);
280 nif
= howmany(isize
, sizepb
);
281 if (idesc
->id_func
== pass1check
&&
282 nif
< EXT2_NINDIR(&sblock
)) {
283 aplim
= &bp
->b_un
.b_indir
[EXT2_NINDIR(&sblock
)];
284 for (ap
= &bp
->b_un
.b_indir
[nif
]; ap
< aplim
; ap
++) {
287 (void)snprintf(buf
, sizeof(buf
),
288 "PARTIALLY TRUNCATED INODE I=%llu",
289 (unsigned long long)idesc
->id_number
);
290 if (dofix(idesc
, buf
)) {
295 flush(fswritefd
, bp
);
297 aplim
= &bp
->b_un
.b_indir
[nif
];
298 for (ap
= bp
->b_un
.b_indir
; ap
< aplim
; ap
++) {
300 idesc
->id_blkno
= fs2h32(*ap
);
304 n
= iblock(idesc
, ilevel
, isize
);
306 bp
->b_flags
&= ~B_INUSE
;
310 if (idesc
->id_type
== DATA
&& isize
> 0) {
311 /* An empty block in a directory XXX */
312 getpathname(pathbuf
, sizeof(pathbuf
),
313 idesc
->id_number
, idesc
->id_number
);
314 pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS",
316 if (reply("ADJUST LENGTH") == 1) {
317 dp
= ginode(idesc
->id_number
);
318 inossize(dp
, inosize(dp
) - isize
);
321 "YOU MUST RERUN FSCK AFTERWARDS\n");
324 bp
->b_flags
&= ~B_INUSE
;
331 bp
->b_flags
&= ~B_INUSE
;
336 * Check that a block in a legal block number.
337 * Return 0 if in range, 1 if out of range.
340 chkrange(daddr_t blk
, int cnt
)
344 if ((unsigned int)(blk
+ cnt
) > maxfsblock
)
346 c
= dtog(&sblock
, blk
);
347 overh
= cgoverhead(c
);
348 if (blk
< sblock
.e2fs
.e2fs_bpg
* c
+ overh
+
349 sblock
.e2fs
.e2fs_first_dblock
) {
350 if ((blk
+ cnt
) > sblock
.e2fs
.e2fs_bpg
* c
+ overh
+
351 sblock
.e2fs
.e2fs_first_dblock
) {
353 printf("blk %lld < cgdmin %d;",
355 sblock
.e2fs
.e2fs_bpg
* c
+ overh
+
356 sblock
.e2fs
.e2fs_first_dblock
);
357 printf(" blk + cnt %lld > cgsbase %d\n",
358 (long long)(blk
+ cnt
),
359 sblock
.e2fs
.e2fs_bpg
* c
+
360 overh
+ sblock
.e2fs
.e2fs_first_dblock
);
365 if ((blk
+ cnt
) > sblock
.e2fs
.e2fs_bpg
* (c
+ 1) + overh
+
366 sblock
.e2fs
.e2fs_first_dblock
) {
368 printf("blk %lld >= cgdmin %d;",
370 sblock
.e2fs
.e2fs_bpg
* c
+ overh
+
371 sblock
.e2fs
.e2fs_first_dblock
);
372 printf(" blk + cnt %lld > cgdmax %d\n",
373 (long long)(blk
+cnt
),
374 sblock
.e2fs
.e2fs_bpg
* (c
+ 1) +
375 overh
+ sblock
.e2fs
.e2fs_first_dblock
);
384 * General purpose interface for reading inodes.
386 struct ext2fs_dinode
*
387 ginode(ino_t inumber
)
390 struct ext2fs_dinode
*dp
;
392 if ((inumber
< EXT2_FIRSTINO
&&
393 inumber
!= EXT2_ROOTINO
&&
394 !(inumber
== EXT2_RESIZEINO
&&
395 (sblock
.e2fs
.e2fs_features_compat
& EXT2F_COMPAT_RESIZE
) != 0))
397 errexit("bad inode number %llu to ginode",
398 (unsigned long long)inumber
);
399 if (startinum
== 0 ||
400 inumber
< startinum
|| inumber
>= startinum
+ sblock
.e2fs_ipb
) {
401 iblk
= fsck_ino_to_fsba(&sblock
, inumber
);
403 pbp
->b_flags
&= ~B_INUSE
;
404 pbp
= getdatablk(iblk
, sblock
.e2fs_bsize
);
406 ((inumber
- 1) / sblock
.e2fs_ipb
) * sblock
.e2fs_ipb
+ 1;
408 dp
= (struct ext2fs_dinode
*)(pbp
->b_un
.b_buf
+
409 EXT2_DINODE_SIZE(&sblock
) * ino_to_fsbo(&sblock
, inumber
));
415 * Special purpose version of ginode used to optimize first pass
416 * over all the inodes in numerical order.
418 ino_t nextino
, lastinum
;
419 long readcnt
, readpercg
, fullcnt
, inobufsize
, partialcnt
, partialsize
;
422 struct ext2fs_dinode
*
423 getnextinode(ino_t inumber
)
427 struct ext2fs_dinode
*dp
;
430 if (inumber
!= nextino
++ || inumber
> maxino
)
431 errexit("bad inode number %llu to nextinode",
432 (unsigned long long)inumber
);
433 if (inumber
>= lastinum
) {
435 dblk
= EXT2_FSBTODB(&sblock
, fsck_ino_to_fsba(&sblock
, lastinum
));
436 if (readcnt
% readpercg
== 0) {
438 lastinum
+= partialcnt
;
443 (void)bread(fsreadfd
, inodebuf
, dblk
, size
);
446 dp
= (struct ext2fs_dinode
*)bp
;
447 bp
+= EXT2_DINODE_SIZE(&sblock
);
460 inobufsize
= ext2_blkroundup(&sblock
, INOBUFSIZE
);
461 fullcnt
= inobufsize
/ EXT2_DINODE_SIZE(&sblock
);
462 readpercg
= sblock
.e2fs
.e2fs_ipg
/ fullcnt
;
463 partialcnt
= sblock
.e2fs
.e2fs_ipg
% fullcnt
;
464 partialsize
= partialcnt
* EXT2_DINODE_SIZE(&sblock
);
465 if (partialcnt
!= 0) {
468 partialcnt
= fullcnt
;
469 partialsize
= inobufsize
;
471 if (inodebuf
== NULL
&&
472 (inodebuf
= malloc((unsigned int)inobufsize
)) == NULL
)
473 errexit("Cannot allocate space for inode buffer");
474 while (nextino
< EXT2_ROOTINO
)
475 (void)getnextinode(nextino
);
482 if (inodebuf
!= NULL
)
488 * Routines to maintain information about directory inodes.
489 * This is built during the first pass and used during the
490 * second and third passes.
492 * Enter inodes into the cache.
495 cacheino(struct ext2fs_dinode
*dp
, ino_t inumber
)
498 struct inoinfo
**inpp
;
501 blks
= howmany(inosize(dp
), sblock
.e2fs_bsize
);
502 if (blks
> EXT2FS_NDADDR
)
503 blks
= EXT2FS_NDADDR
+ EXT2FS_NIADDR
;
505 inp
= malloc(sizeof(*inp
) + (blks
- 1) * sizeof(int32_t));
508 inpp
= &inphead
[inumber
% numdirs
];
509 inp
->i_nexthash
= *inpp
;
511 inp
->i_child
= inp
->i_sibling
= inp
->i_parentp
= 0;
512 if (inumber
== EXT2_ROOTINO
)
513 inp
->i_parent
= EXT2_ROOTINO
;
515 inp
->i_parent
= (ino_t
)0;
516 inp
->i_dotdot
= (ino_t
)0;
517 inp
->i_number
= inumber
;
518 inp
->i_isize
= inosize(dp
);
520 inp
->i_numblks
= blks
* sizeof(int32_t);
521 memcpy(&inp
->i_blks
[0], &dp
->e2di_blocks
[0], (size_t)inp
->i_numblks
);
522 if (inplast
== listmax
) {
524 inpsort
= (struct inoinfo
**)realloc((char *)inpsort
,
525 (unsigned int)listmax
* sizeof(struct inoinfo
*));
527 errexit("cannot increase directory list");
529 inpsort
[inplast
++] = inp
;
533 * Look up an inode cache structure.
536 getinoinfo(ino_t inumber
)
540 for (inp
= inphead
[inumber
% numdirs
]; inp
; inp
= inp
->i_nexthash
) {
541 if (inp
->i_number
!= inumber
)
545 errexit("cannot find inode %llu", (unsigned long long)inumber
);
546 return ((struct inoinfo
*)0);
550 * Clean up all the inode cache structure.
555 struct inoinfo
**inpp
;
559 for (inpp
= &inpsort
[inplast
- 1]; inpp
>= inpsort
; inpp
--)
563 inphead
= inpsort
= NULL
;
574 clri(struct inodesc
*idesc
, const char *type
, int flag
)
576 struct ext2fs_dinode
*dp
;
578 dp
= ginode(idesc
->id_number
);
581 (fs2h16(dp
->e2di_mode
) & IFMT
) == IFDIR
? "DIR" : "FILE");
582 pinode(idesc
->id_number
);
584 if (preen
|| reply("CLEAR") == 1) {
586 printf(" (CLEARED)\n");
588 (void)ckinode(dp
, idesc
);
590 statemap
[idesc
->id_number
] = USTATE
;
596 findname(struct inodesc
*idesc
)
598 struct ext2fs_direct
*dirp
= idesc
->id_dirp
;
599 u_int16_t namlen
= dirp
->e2d_namlen
;
600 /* from utilities.c namebuf[] variable */
601 char *buf
= __UNCONST(idesc
->id_name
);
602 if (namlen
> MAXPATHLEN
) {
603 /* XXX: Prevent overflow but don't fix */
607 if (fs2h32(dirp
->e2d_ino
) != idesc
->id_parent
)
609 (void)memcpy(buf
, dirp
->e2d_name
, (size_t)namlen
);
615 findino(struct inodesc
*idesc
)
617 struct ext2fs_direct
*dirp
= idesc
->id_dirp
;
618 u_int32_t ino
= fs2h32(dirp
->e2d_ino
);
622 if (strcmp(dirp
->e2d_name
, idesc
->id_name
) == 0 &&
623 (ino
== EXT2_ROOTINO
|| ino
>= EXT2_FIRSTINO
)
625 idesc
->id_parent
= ino
;
634 struct ext2fs_dinode
*dp
;
638 printf(" I=%llu ", (unsigned long long)ino
);
639 if ((ino
< EXT2_FIRSTINO
&& ino
!= EXT2_ROOTINO
) || ino
> maxino
)
642 uid
= fs2h16(dp
->e2di_uid
);
643 if (sblock
.e2fs
.e2fs_rev
> E2FS_REV0
)
644 uid
|= fs2h16(dp
->e2di_uid_high
) << 16;
647 if (Uflag
&& (pw
= getpwuid(uid
)) != 0)
648 printf("%s ", pw
->pw_name
);
651 printf("%u ", (unsigned int)uid
);
652 printf("MODE=%o\n", fs2h16(dp
->e2di_mode
));
654 printf("%s: ", cdevname());
655 printf("SIZE=%llu ", (long long)inosize(dp
));
656 printf("MTIME=%s ", print_mtime(fs2h32(dp
->e2di_mtime
)));
660 blkerror(ino_t ino
, const char *type
, daddr_t blk
)
663 pfatal("%lld %s I=%llu", (long long)blk
, type
, (unsigned long long)ino
);
665 switch (statemap
[ino
]) {
668 statemap
[ino
] = FCLEAR
;
672 statemap
[ino
] = DCLEAR
;
680 errexit("BAD STATE %d TO BLKERR", statemap
[ino
]);
686 * allocate an unused inode
689 allocino(ino_t request
, int type
)
692 struct ext2fs_dinode
*dp
;
696 request
= EXT2_ROOTINO
;
697 else if (statemap
[request
] != USTATE
)
699 for (ino
= request
; ino
< maxino
; ino
++) {
700 if ((ino
> EXT2_ROOTINO
) && (ino
< EXT2_FIRSTINO
))
702 if (statemap
[ino
] == USTATE
)
707 switch (type
& IFMT
) {
709 statemap
[ino
] = DSTATE
;
713 statemap
[ino
] = FSTATE
;
719 dp
->e2di_blocks
[0] = h2fs32(allocblk());
720 if (dp
->e2di_blocks
[0] == 0) {
721 statemap
[ino
] = USTATE
;
724 dp
->e2di_mode
= h2fs16(type
);
726 dp
->e2di_atime
= h2fs32(t
);
727 dp
->e2di_mtime
= dp
->e2di_ctime
= dp
->e2di_atime
;
729 inossize(dp
, sblock
.e2fs_bsize
);
730 inosnblock(dp
, btodb(sblock
.e2fs_bsize
));
733 typemap
[ino
] = E2IFTODT(type
);
738 * deallocate an inode
743 struct inodesc idesc
;
744 struct ext2fs_dinode
*dp
;
746 memset(&idesc
, 0, sizeof(struct inodesc
));
747 idesc
.id_type
= ADDR
;
748 idesc
.id_func
= pass4check
;
749 idesc
.id_number
= ino
;
751 (void)ckinode(dp
, &idesc
);
754 statemap
[ino
] = USTATE
;
759 inonblock(struct ext2fs_dinode
*dp
)
763 /* XXX check for EXT2_HUGE_FILE without EXT2F_ROCOMPAT_HUGE_FILE? */
765 nblock
= fs2h32(dp
->e2di_nblock
);
767 if ((sblock
.e2fs
.e2fs_features_rocompat
& EXT2F_ROCOMPAT_HUGE_FILE
)) {
768 nblock
|= (uint64_t)fs2h16(dp
->e2di_nblock_high
) << 32;
769 if (fs2h32(dp
->e2di_flags
) & EXT2_HUGE_FILE
) {
770 nblock
= EXT2_FSBTODB(&sblock
, nblock
);
778 inosnblock(struct ext2fs_dinode
*dp
, uint64_t nblock
)
782 flags
= fs2h32(dp
->e2di_flags
);
784 if (nblock
<= 0xffffffffULL
) {
785 flags
&= ~EXT2_HUGE_FILE
;
786 dp
->e2di_flags
= h2fs32(flags
);
787 dp
->e2di_nblock
= h2fs32(nblock
);
793 if (nblock
<= 0xffffffffffffULL
) {
794 flags
&= ~EXT2_HUGE_FILE
;
795 dp
->e2di_flags
= h2fs32(flags
);
796 dp
->e2di_nblock
= h2fs32(nblock
);
797 dp
->e2di_nblock_high
= h2fs16((nblock
>> 32));
801 if (EXT2_DBTOFSB(&sblock
, nblock
) <= 0xffffffffffffULL
) {
802 flags
|= EXT2_HUGE_FILE
;
803 dp
->e2di_flags
= h2fs32(flags
);
804 dp
->e2di_nblock
= h2fs32(EXT2_DBTOFSB(&sblock
, nblock
));
805 dp
->e2di_nblock_high
= h2fs16((EXT2_DBTOFSB(&sblock
, nblock
) >> 32));
809 pfatal("trying to set nblocks higher than representable");