Lines Matching +full:last +full:- +full:level
1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
105 if ((ip->i_flag & IN_MODIFIED) == 0 && waitfor == 0) in ffs_update()
107 ip->i_flag &= ~(IN_LAZYACCESS | IN_LAZYMOD | IN_MODIFIED); in ffs_update()
123 * or fsyncdata() will be able to run before the on-disk inode in ffs_update()
127 ip->i_flag &= ~(IN_SIZEMOD | IN_IBLKDATA); in ffs_update()
129 if (fs->fs_ronly) in ffs_update()
146 bn = fsbtodb(fs, ino_to_fsba(fs, ip->i_number)); in ffs_update()
147 error = ffs_breadz(VFSTOUFS(vp->v_mount), ITODEVVP(ip), bn, bn, in ffs_update()
148 (int) fs->fs_bsize, NULL, NULL, 0, NOCRED, flags, NULL, &bp); in ffs_update()
187 else if (ip->i_effnlink != ip->i_nlink) in ffs_update()
190 *((struct ufs1_dinode *)bp->b_data + in ffs_update()
191 ino_to_fsbo(fs, ip->i_number)) = *ip->i_din1; in ffs_update()
196 random_harvest_queue(&(ip->i_din1), sizeof(ip->i_din1), RANDOM_FS_ATIME); in ffs_update()
198 ffs_update_dinode_ckhash(fs, ip->i_din2); in ffs_update()
199 *((struct ufs2_dinode *)bp->b_data + in ffs_update()
200 ino_to_fsbo(fs, ip->i_number)) = *ip->i_din2; in ffs_update()
205 random_harvest_queue(&(ip->i_din2), sizeof(ip->i_din2), RANDOM_FS_ATIME); in ffs_update()
209 if (ffs_fsfail_cleanup(VFSTOUFS(vp->v_mount), error)) in ffs_update()
215 if (bp->b_bufsize == fs->fs_bsize) in ffs_update()
216 bp->b_flags |= B_CLUSTEROK; in ffs_update()
249 int offset, size, level, nblocks; in ffs_truncate() local
255 ump = VFSTOUFS(vp->v_mount); in ffs_truncate()
256 fs = ump->um_fs; in ffs_truncate()
257 bo = &vp->v_bufobj; in ffs_truncate()
263 if (length > fs->fs_maxfilesize) in ffs_truncate()
281 * If we are truncating the extended-attributes, and cannot in ffs_truncate()
295 if (fs->fs_magic == FS_UFS2_MAGIC && ip->i_din2->di_extsize > 0) { in ffs_truncate()
296 extblocks = btodb(fragroundup(fs, ip->i_din2->di_extsize)); in ffs_truncate()
309 (void) chkdq(ip, -extblocks, NOCRED, FORCE); in ffs_truncate()
313 OFF_TO_IDX(lblktosize(fs, -extblocks)), 0); in ffs_truncate()
314 osize = ip->i_din2->di_extsize; in ffs_truncate()
315 ip->i_din2->di_blocks -= extblocks; in ffs_truncate()
316 ip->i_din2->di_extsize = 0; in ffs_truncate()
318 oldblks[i] = ip->i_din2->di_extb[i]; in ffs_truncate()
319 ip->i_din2->di_extb[i] = 0; in ffs_truncate()
328 sblksize(fs, osize, i), ip->i_number, in ffs_truncate()
329 vp->v_type, NULL, SINGLETON_KEY); in ffs_truncate()
335 if (vp->v_type == VLNK && ip->i_size < ump->um_maxsymlinklen) { in ffs_truncate()
340 bzero(DIP(ip, i_shortlink), (uint64_t)ip->i_size); in ffs_truncate()
341 ip->i_size = 0; in ffs_truncate()
348 if (ip->i_size == length) { in ffs_truncate()
354 if (fs->fs_ronly) in ffs_truncate()
355 panic("ffs_truncate: read-only filesystem"); in ffs_truncate()
358 cluster_init_vn(&ip->i_clusterw); in ffs_truncate()
359 osize = ip->i_size; in ffs_truncate()
362 * last byte of the file is allocated. Since the smallest in ffs_truncate()
368 error = UFS_BALLOC(vp, length - 1, 1, cred, flags, &bp); in ffs_truncate()
373 ip->i_size = length; in ffs_truncate()
375 if (bp->b_bufsize == fs->fs_bsize) in ffs_truncate()
376 bp->b_flags |= B_CLUSTEROK; in ffs_truncate()
383 * have no blocks, so return a blkno of -1. in ffs_truncate()
385 lbn = lblkno(fs, length - 1); in ffs_truncate()
387 blkno = -1; in ffs_truncate()
391 error = UFS_BALLOC(vp, lblktosize(fs, (off_t)lbn), fs->fs_bsize, in ffs_truncate()
395 indiroff = (lbn - UFS_NDADDR) % NINDIR(fs); in ffs_truncate()
397 blkno = ((ufs1_daddr_t *)(bp->b_data))[indiroff]; in ffs_truncate()
399 blkno = ((ufs2_daddr_t *)(bp->b_data))[indiroff]; in ffs_truncate()
401 * If the block number is non-zero, then the indirect block in ffs_truncate()
415 * then we must allocate it to ensure that the last block of in ffs_truncate()
451 * Shorten the size of the file. If the last block of the in ffs_truncate()
462 ip->i_size = length; in ffs_truncate()
466 if (vp->v_type == VDIR && ip->i_dirhash != NULL) in ffs_truncate()
472 error = UFS_BALLOC(vp, length - 1, 1, cred, flags, &bp); in ffs_truncate()
486 fragroundup(fs, blkoff(fs, length)) < fs->fs_bsize && in ffs_truncate()
490 error = UFS_BALLOC(vp, length - 1, 1, cred, flags, &bp); in ffs_truncate()
493 ip->i_size = length; in ffs_truncate()
496 if (vp->v_type == VDIR && ip->i_dirhash != NULL) in ffs_truncate()
500 if (vp->v_type != VDIR && offset != 0) in ffs_truncate()
501 bzero((char *)bp->b_data + offset, in ffs_truncate()
502 (uint64_t)(size - offset)); in ffs_truncate()
505 if (bp->b_bufsize == fs->fs_bsize) in ffs_truncate()
506 bp->b_flags |= B_CLUSTEROK; in ffs_truncate()
512 * last direct and indirect blocks (if any) in ffs_truncate()
513 * which we want to keep. Lastblock is -1 when in ffs_truncate()
516 lastblock = lblkno(fs, length + fs->fs_bsize - 1) - 1; in ffs_truncate()
517 lastiblock[SINGLE] = lastblock - UFS_NDADDR; in ffs_truncate()
518 lastiblock[DOUBLE] = lastiblock[SINGLE] - NINDIR(fs); in ffs_truncate()
519 lastiblock[TRIPLE] = lastiblock[DOUBLE] - NINDIR(fs) * NINDIR(fs); in ffs_truncate()
520 nblocks = btodb(fs->fs_bsize); in ffs_truncate()
525 * normalized to -1 for calls to ffs_indirtrunc below. in ffs_truncate()
527 for (level = TRIPLE; level >= SINGLE; level--) { in ffs_truncate()
528 oldblks[UFS_NDADDR + level] = DIP(ip, i_ib[level]); in ffs_truncate()
529 if (lastiblock[level] < 0) { in ffs_truncate()
530 DIP_SET(ip, i_ib[level], 0); in ffs_truncate()
531 lastiblock[level] = -1; in ffs_truncate()
560 ip->i_size = osize; in ffs_truncate()
564 error = vtruncbuf(vp, length, fs->fs_bsize); in ffs_truncate()
571 indir_lbn[SINGLE] = -UFS_NDADDR; in ffs_truncate()
572 indir_lbn[DOUBLE] = indir_lbn[SINGLE] - NINDIR(fs) - 1; in ffs_truncate()
573 indir_lbn[TRIPLE] = indir_lbn[DOUBLE] - NINDIR(fs) * NINDIR(fs) - 1; in ffs_truncate()
574 for (level = TRIPLE; level >= SINGLE; level--) { in ffs_truncate()
575 bn = DIP(ip, i_ib[level]); in ffs_truncate()
577 error = ffs_indirtrunc(ip, indir_lbn[level], in ffs_truncate()
578 fsbtodb(fs, bn), lastiblock[level], level, &count); in ffs_truncate()
582 if (lastiblock[level] < 0) { in ffs_truncate()
583 DIP_SET(ip, i_ib[level], 0); in ffs_truncate()
584 ffs_blkfree(ump, fs, ump->um_devvp, bn, in ffs_truncate()
585 fs->fs_bsize, ip->i_number, in ffs_truncate()
586 vp->v_type, NULL, SINGLETON_KEY); in ffs_truncate()
590 if (lastiblock[level] >= 0) in ffs_truncate()
597 key = ffs_blkrelease_start(ump, ump->um_devvp, ip->i_number); in ffs_truncate()
598 for (i = UFS_NDADDR - 1; i > lastblock; i--) { in ffs_truncate()
606 ffs_blkfree(ump, fs, ump->um_devvp, bn, bsize, ip->i_number, in ffs_truncate()
607 vp->v_type, NULL, key); in ffs_truncate()
616 * last direct block; release any frags. in ffs_truncate()
627 ip->i_size = length; in ffs_truncate()
633 if (oldspace - newspace > 0) { in ffs_truncate()
640 ffs_blkfree(ump, fs, ump->um_devvp, bn, in ffs_truncate()
641 oldspace - newspace, ip->i_number, vp->v_type, in ffs_truncate()
643 blocksreleased += btodb(oldspace - newspace); in ffs_truncate()
648 for (level = SINGLE; level <= TRIPLE; level++) in ffs_truncate()
649 if (newblks[UFS_NDADDR + level] != DIP(ip, i_ib[level])) in ffs_truncate()
650 panic("ffs_truncate1: level %d newblks %jd != i_ib %jd", in ffs_truncate()
651 level, (intmax_t)newblks[UFS_NDADDR + level], in ffs_truncate()
652 (intmax_t)DIP(ip, i_ib[level])); in ffs_truncate()
656 i, (intmax_t)newblks[UFS_NDADDR + level], in ffs_truncate()
657 (intmax_t)DIP(ip, i_ib[level])); in ffs_truncate()
660 (fs->fs_magic != FS_UFS2_MAGIC || ip->i_din2->di_extsize == 0) && in ffs_truncate()
661 (bo->bo_dirty.bv_cnt > 0 || bo->bo_clean.bv_cnt > 0)) in ffs_truncate()
663 vp, bo->bo_dirty.bv_cnt, bo->bo_clean.bv_cnt); in ffs_truncate()
669 ip->i_size = length; in ffs_truncate()
672 DIP_SET(ip, i_blocks, DIP(ip, i_blocks) - blocksreleased); in ffs_truncate()
677 (void) chkdq(ip, -blocksreleased, NOCRED, FORCE); in ffs_truncate()
692 * lastbn. If level is greater than SINGLE, the block is an indirect block
701 int level, in ffs_indirtrunc() argument
711 ufs2_daddr_t nb, nlbn, last; in ffs_indirtrunc() local
721 * Calculate index in current block of last in ffs_indirtrunc()
722 * block to be kept. -1 indicates the entire in ffs_indirtrunc()
725 factor = lbn_offset(fs, level); in ffs_indirtrunc()
726 last = lastbn; in ffs_indirtrunc()
728 last /= factor; in ffs_indirtrunc()
729 nblocks = btodb(fs->fs_bsize); in ffs_indirtrunc()
735 * have the on-disk address, so we just pass it to bread() instead in ffs_indirtrunc()
739 error = ffs_breadz(ump, vp, lbn, dbn, (int)fs->fs_bsize, NULL, NULL, 0, in ffs_indirtrunc()
747 bap1 = (ufs1_daddr_t *)bp->b_data; in ffs_indirtrunc()
749 bap2 = (ufs2_daddr_t *)bp->b_data; in ffs_indirtrunc()
750 if (lastbn != -1) { in ffs_indirtrunc()
751 copy = malloc(fs->fs_bsize, M_TEMP, M_WAITOK); in ffs_indirtrunc()
752 bcopy((caddr_t)bp->b_data, copy, (uint64_t)fs->fs_bsize); in ffs_indirtrunc()
753 for (i = last + 1; i < NINDIR(fs); i++) in ffs_indirtrunc()
774 key = ffs_blkrelease_start(ump, ITODEVVP(ip), ip->i_number); in ffs_indirtrunc()
775 for (i = NINDIR(fs) - 1, nlbn = lbn + 1 - i * factor; i > last; in ffs_indirtrunc()
776 i--, nlbn += factor) { in ffs_indirtrunc()
780 if (level > SINGLE) { in ffs_indirtrunc()
782 (ufs2_daddr_t)-1, level - 1, &blkcount)) != 0) in ffs_indirtrunc()
786 ffs_blkfree(ump, fs, ITODEVVP(ip), nb, fs->fs_bsize, in ffs_indirtrunc()
787 ip->i_number, vp->v_type, NULL, key); in ffs_indirtrunc()
793 * Recursively free last partial block. in ffs_indirtrunc()
795 if (level > SINGLE && lastbn >= 0) { in ffs_indirtrunc()
796 last = lastbn % factor; in ffs_indirtrunc()
800 last, level - 1, &blkcount); in ffs_indirtrunc()
809 bp->b_flags |= B_INVAL | B_NOCACHE; in ffs_indirtrunc()
821 return (ITOFS(ip)->fs_ronly != 0); in ffs_rdonly()