Lines Matching +full:nc +full:- +full:si

1 // SPDX-License-Identifier: GPL-2.0+
5 * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation.
22 * struct nilfs_sufile_info - on-memory private data of sufile
23 * @mi: on-memory private data of metadata file
43 return NILFS_MDT(sufile)->mi_entries_per_block; in nilfs_sufile_segment_usages_per_block()
49 __u64 t = segnum + NILFS_MDT(sufile)->mi_first_entry_offset; in nilfs_sufile_get_blkoff()
58 __u64 t = segnum + NILFS_MDT(sufile)->mi_first_entry_offset; in nilfs_sufile_get_offset()
68 nilfs_sufile_segment_usages_per_block(sufile) - in nilfs_sufile_segment_usages_in_block()
70 max - curr + 1); in nilfs_sufile_segment_usages_in_block()
74 * nilfs_sufile_segment_usage_offset - calculate the byte offset of a segment
86 return offset_in_folio(bh->b_folio, bh->b_data) + in nilfs_sufile_segment_usage_offset()
88 NILFS_MDT(sufile)->mi_entry_size; in nilfs_sufile_segment_usage_offset()
96 if (unlikely(err == -ENOENT)) { in nilfs_sufile_get_header_block()
97 nilfs_error(sufile->i_sb, in nilfs_sufile_get_header_block()
99 err = -EIO; in nilfs_sufile_get_header_block()
125 header = kmap_local_folio(header_bh->b_folio, 0); in nilfs_sufile_mod_counter()
126 le64_add_cpu(&header->sh_ncleansegs, ncleanadd); in nilfs_sufile_mod_counter()
127 le64_add_cpu(&header->sh_ndirtysegs, ndirtyadd); in nilfs_sufile_mod_counter()
134 * nilfs_sufile_get_ncleansegs - return the number of clean segments
141 return NILFS_SUI(sufile)->ncleansegs; in nilfs_sufile_get_ncleansegs()
145 * nilfs_sufile_updatev - modify multiple segment usages at a time
162 * * %-EINVAL - Invalid segment usage number
163 * * %-EIO - I/O error (including metadata corruption).
164 * * %-ENOENT - Given segment usage is in hole block (may be returned if
166 * * %-ENOMEM - Insufficient memory available.
183 down_write(&NILFS_MDT(sufile)->mi_sem); in nilfs_sufile_updatev()
186 nilfs_warn(sufile->i_sb, in nilfs_sufile_updatev()
193 ret = -EINVAL; in nilfs_sufile_updatev()
226 n = seg - segnumv; in nilfs_sufile_updatev()
229 up_write(&NILFS_MDT(sufile)->mi_sem); in nilfs_sufile_updatev()
245 nilfs_warn(sufile->i_sb, "%s: invalid segment number: %llu", in nilfs_sufile_update()
247 return -EINVAL; in nilfs_sufile_update()
249 down_write(&NILFS_MDT(sufile)->mi_sem); in nilfs_sufile_update()
263 up_write(&NILFS_MDT(sufile)->mi_sem); in nilfs_sufile_update()
268 * nilfs_sufile_set_alloc_range - limit range of segment to be allocated
273 * Return: 0 on success, or %-ERANGE if segment range is invalid.
279 int ret = -ERANGE; in nilfs_sufile_set_alloc_range()
281 down_write(&NILFS_MDT(sufile)->mi_sem); in nilfs_sufile_set_alloc_range()
285 sui->allocmin = start; in nilfs_sufile_set_alloc_range()
286 sui->allocmax = end; in nilfs_sufile_set_alloc_range()
289 up_write(&NILFS_MDT(sufile)->mi_sem); in nilfs_sufile_set_alloc_range()
294 * nilfs_sufile_alloc - allocate a segment
303 * * %-EIO - I/O error (including metadata corruption).
304 * * %-ENOMEM - Insufficient memory available.
305 * * %-ENOSPC - No clean segment left.
313 size_t susz = NILFS_MDT(sufile)->mi_entry_size; in nilfs_sufile_alloc()
320 down_write(&NILFS_MDT(sufile)->mi_sem); in nilfs_sufile_alloc()
325 header = kmap_local_folio(header_bh->b_folio, 0); in nilfs_sufile_alloc()
326 last_alloc = le64_to_cpu(header->sh_last_alloc); in nilfs_sufile_alloc()
330 maxsegnum = sui->allocmax; in nilfs_sufile_alloc()
332 if (segnum < sui->allocmin || segnum > sui->allocmax) in nilfs_sufile_alloc()
333 segnum = sui->allocmin; in nilfs_sufile_alloc()
337 if (cnt < sui->allocmax - sui->allocmin + 1) { in nilfs_sufile_alloc()
341 * sui->allocmin, this never happens. in nilfs_sufile_alloc()
343 segnum = sui->allocmin; in nilfs_sufile_alloc()
345 } else if (segnum > sui->allocmin && in nilfs_sufile_alloc()
346 sui->allocmax + 1 < nsegments) { in nilfs_sufile_alloc()
347 segnum = sui->allocmax + 1; in nilfs_sufile_alloc()
348 maxsegnum = nsegments - 1; in nilfs_sufile_alloc()
349 } else if (sui->allocmin > 0) { in nilfs_sufile_alloc()
351 maxsegnum = sui->allocmin - 1; in nilfs_sufile_alloc()
364 su = kaddr = kmap_local_folio(su_bh->b_folio, offset); in nilfs_sufile_alloc()
375 header = kmap_local_folio(header_bh->b_folio, 0); in nilfs_sufile_alloc()
376 le64_add_cpu(&header->sh_ncleansegs, -1); in nilfs_sufile_alloc()
377 le64_add_cpu(&header->sh_ndirtysegs, 1); in nilfs_sufile_alloc()
378 header->sh_last_alloc = cpu_to_le64(segnum); in nilfs_sufile_alloc()
381 sui->ncleansegs--; in nilfs_sufile_alloc()
398 ret = -ENOSPC; in nilfs_sufile_alloc()
404 up_write(&NILFS_MDT(sufile)->mi_sem); in nilfs_sufile_alloc()
416 su = kmap_local_folio(su_bh->b_folio, offset); in nilfs_sufile_do_cancel_free()
418 nilfs_warn(sufile->i_sb, "%s: segment %llu must be clean", in nilfs_sufile_do_cancel_free()
426 nilfs_sufile_mod_counter(header_bh, -1, 1); in nilfs_sufile_do_cancel_free()
427 NILFS_SUI(sufile)->ncleansegs--; in nilfs_sufile_do_cancel_free()
442 su = kmap_local_folio(su_bh->b_folio, offset); in nilfs_sufile_do_scrap()
443 if (su->su_flags == cpu_to_le32(BIT(NILFS_SEGMENT_USAGE_DIRTY)) && in nilfs_sufile_do_scrap()
444 su->su_nblocks == cpu_to_le32(0)) { in nilfs_sufile_do_scrap()
452 su->su_lastmod = cpu_to_le64(0); in nilfs_sufile_do_scrap()
453 su->su_nblocks = cpu_to_le32(0); in nilfs_sufile_do_scrap()
454 su->su_flags = cpu_to_le32(BIT(NILFS_SEGMENT_USAGE_DIRTY)); in nilfs_sufile_do_scrap()
457 nilfs_sufile_mod_counter(header_bh, clean ? (u64)-1 : 0, dirty ? 0 : 1); in nilfs_sufile_do_scrap()
458 NILFS_SUI(sufile)->ncleansegs -= clean; in nilfs_sufile_do_scrap()
473 su = kmap_local_folio(su_bh->b_folio, offset); in nilfs_sufile_do_free()
475 nilfs_warn(sufile->i_sb, "%s: segment %llu is already clean", in nilfs_sufile_do_free()
481 nilfs_warn(sufile->i_sb, "free segment %llu marked in error", in nilfs_sufile_do_free()
486 nilfs_warn(sufile->i_sb, "free unallocated segment %llu", in nilfs_sufile_do_free()
493 nilfs_sufile_mod_counter(header_bh, 1, sudirty ? (u64)-1 : 0); in nilfs_sufile_do_free()
494 NILFS_SUI(sufile)->ncleansegs++; in nilfs_sufile_do_free()
502 * nilfs_sufile_mark_dirty - mark the buffer having a segment usage dirty
515 down_write(&NILFS_MDT(sufile)->mi_sem); in nilfs_sufile_mark_dirty()
518 if (ret == -ENOENT) { in nilfs_sufile_mark_dirty()
519 nilfs_error(sufile->i_sb, in nilfs_sufile_mark_dirty()
522 ret = -EIO; in nilfs_sufile_mark_dirty()
528 su = kmap_local_folio(bh->b_folio, offset); in nilfs_sufile_mark_dirty()
530 struct the_nilfs *nilfs = sufile->i_sb->s_fs_info; in nilfs_sufile_mark_dirty()
535 nilfs_error(sufile->i_sb, in nilfs_sufile_mark_dirty()
547 ret = -EIO; in nilfs_sufile_mark_dirty()
556 up_write(&NILFS_MDT(sufile)->mi_sem); in nilfs_sufile_mark_dirty()
561 * nilfs_sufile_set_segment_usage - set usage of a segment
577 down_write(&NILFS_MDT(sufile)->mi_sem); in nilfs_sufile_set_segment_usage()
583 su = kmap_local_folio(bh->b_folio, offset); in nilfs_sufile_set_segment_usage()
590 su->su_lastmod = cpu_to_le64(modtime); in nilfs_sufile_set_segment_usage()
592 su->su_nblocks = cpu_to_le32(nblocks); in nilfs_sufile_set_segment_usage()
600 up_write(&NILFS_MDT(sufile)->mi_sem); in nilfs_sufile_set_segment_usage()
605 * nilfs_sufile_get_stat - get segment usage statistics
614 * * %-EIO - I/O error (including metadata corruption).
615 * * %-ENOMEM - Insufficient memory available.
621 struct the_nilfs *nilfs = sufile->i_sb->s_fs_info; in nilfs_sufile_get_stat()
624 down_read(&NILFS_MDT(sufile)->mi_sem); in nilfs_sufile_get_stat()
630 header = kmap_local_folio(header_bh->b_folio, 0); in nilfs_sufile_get_stat()
631 sustat->ss_nsegs = nilfs_sufile_get_nsegments(sufile); in nilfs_sufile_get_stat()
632 sustat->ss_ncleansegs = le64_to_cpu(header->sh_ncleansegs); in nilfs_sufile_get_stat()
633 sustat->ss_ndirtysegs = le64_to_cpu(header->sh_ndirtysegs); in nilfs_sufile_get_stat()
634 sustat->ss_ctime = nilfs->ns_ctime; in nilfs_sufile_get_stat()
635 sustat->ss_nongc_ctime = nilfs->ns_nongc_ctime; in nilfs_sufile_get_stat()
636 spin_lock(&nilfs->ns_last_segment_lock); in nilfs_sufile_get_stat()
637 sustat->ss_prot_seq = nilfs->ns_prot_seq; in nilfs_sufile_get_stat()
638 spin_unlock(&nilfs->ns_last_segment_lock); in nilfs_sufile_get_stat()
643 up_read(&NILFS_MDT(sufile)->mi_sem); in nilfs_sufile_get_stat()
656 su = kmap_local_folio(su_bh->b_folio, offset); in nilfs_sufile_do_set_error()
666 nilfs_sufile_mod_counter(header_bh, -1, 0); in nilfs_sufile_do_set_error()
667 NILFS_SUI(sufile)->ncleansegs--; in nilfs_sufile_do_set_error()
674 * nilfs_sufile_truncate_range - truncate range of segment array
681 * * %-EBUSY - Dirty or active segments are present in the range.
682 * * %-EINVAL - Invalid number of segments specified.
683 * * %-EIO - I/O error (including metadata corruption).
684 * * %-ENOMEM - Insufficient memory available.
689 struct the_nilfs *nilfs = sufile->i_sb->s_fs_info; in nilfs_sufile_truncate_range()
693 size_t susz = NILFS_MDT(sufile)->mi_entry_size; in nilfs_sufile_truncate_range()
698 ssize_t n, nc; in nilfs_sufile_truncate_range() local
704 ret = -EINVAL; in nilfs_sufile_truncate_range()
717 segusages_per_block - in nilfs_sufile_truncate_range()
719 end - segnum + 1); in nilfs_sufile_truncate_range()
723 if (ret != -ENOENT) in nilfs_sufile_truncate_range()
730 su = kmap_local_folio(su_bh->b_folio, offset); in nilfs_sufile_truncate_range()
733 if ((le32_to_cpu(su->su_flags) & in nilfs_sufile_truncate_range()
736 ret = -EBUSY; in nilfs_sufile_truncate_range()
742 nc = 0; in nilfs_sufile_truncate_range()
746 nc++; in nilfs_sufile_truncate_range()
750 if (nc > 0) { in nilfs_sufile_truncate_range()
752 ncleaned += nc; in nilfs_sufile_truncate_range()
765 NILFS_SUI(sufile)->ncleansegs += ncleaned; in nilfs_sufile_truncate_range()
775 * nilfs_sufile_resize - resize segment array
781 * * %-EBUSY - Dirty or active segments exist in the region to be truncated.
782 * * %-EIO - I/O error (including metadata corruption).
783 * * %-ENOMEM - Insufficient memory available.
784 * * %-ENOSPC - Enough free space is not left for shrinking.
788 struct the_nilfs *nilfs = sufile->i_sb->s_fs_info; in nilfs_sufile_resize()
795 down_write(&NILFS_MDT(sufile)->mi_sem); in nilfs_sufile_resize()
801 ret = -ENOSPC; in nilfs_sufile_resize()
803 if (newnsegs < nsegs && nsegs - newnsegs + nrsvsegs > sui->ncleansegs) in nilfs_sufile_resize()
811 sui->ncleansegs += newnsegs - nsegs; in nilfs_sufile_resize()
813 ret = nilfs_sufile_truncate_range(sufile, newnsegs, nsegs - 1); in nilfs_sufile_resize()
817 sui->ncleansegs -= nsegs - newnsegs; in nilfs_sufile_resize()
825 sui->allocmax = newnsegs - 1; in nilfs_sufile_resize()
826 sui->allocmin = 0; in nilfs_sufile_resize()
829 header = kmap_local_folio(header_bh->b_folio, 0); in nilfs_sufile_resize()
830 header->sh_ncleansegs = cpu_to_le64(sui->ncleansegs); in nilfs_sufile_resize()
840 up_write(&NILFS_MDT(sufile)->mi_sem); in nilfs_sufile_resize()
845 * nilfs_sufile_get_suinfo - get segment usage information
854 * * %-EIO - I/O error (including metadata corruption).
855 * * %-ENOMEM - Insufficient memory available.
862 struct nilfs_suinfo *si = buf; in nilfs_sufile_get_suinfo() local
863 size_t susz = NILFS_MDT(sufile)->mi_entry_size; in nilfs_sufile_get_suinfo()
864 struct the_nilfs *nilfs = sufile->i_sb->s_fs_info; in nilfs_sufile_get_suinfo()
871 down_read(&NILFS_MDT(sufile)->mi_sem); in nilfs_sufile_get_suinfo()
875 nilfs_sufile_get_nsegments(sufile) - segnum, in nilfs_sufile_get_suinfo()
879 segusages_per_block - in nilfs_sufile_get_suinfo()
881 nsegs - i); in nilfs_sufile_get_suinfo()
885 if (ret != -ENOENT) in nilfs_sufile_get_suinfo()
888 memset(si, 0, sisz * n); in nilfs_sufile_get_suinfo()
889 si = (void *)si + sisz * n; in nilfs_sufile_get_suinfo()
895 su = kaddr = kmap_local_folio(su_bh->b_folio, offset); in nilfs_sufile_get_suinfo()
897 j++, su = (void *)su + susz, si = (void *)si + sisz) { in nilfs_sufile_get_suinfo()
898 si->sui_lastmod = le64_to_cpu(su->su_lastmod); in nilfs_sufile_get_suinfo()
899 si->sui_nblocks = le32_to_cpu(su->su_nblocks); in nilfs_sufile_get_suinfo()
900 si->sui_flags = le32_to_cpu(su->su_flags) & in nilfs_sufile_get_suinfo()
903 si->sui_flags |= in nilfs_sufile_get_suinfo()
912 up_read(&NILFS_MDT(sufile)->mi_sem); in nilfs_sufile_get_suinfo()
917 * nilfs_sufile_set_suinfo - sets segment usage info
929 * * %-EINVAL - Invalid values in input (segment number, flags or nblocks).
930 * * %-EIO - I/O error (including metadata corruption).
931 * * %-ENOMEM - Insufficient memory available.
936 struct the_nilfs *nilfs = sufile->i_sb->s_fs_info; in nilfs_sufile_set_suinfo()
950 if (sup->sup_segnum >= nilfs->ns_nsegments in nilfs_sufile_set_suinfo()
951 || (sup->sup_flags & in nilfs_sufile_set_suinfo()
954 sup->sup_sui.sui_nblocks > in nilfs_sufile_set_suinfo()
955 nilfs->ns_blocks_per_segment)) in nilfs_sufile_set_suinfo()
956 return -EINVAL; in nilfs_sufile_set_suinfo()
959 down_write(&NILFS_MDT(sufile)->mi_sem); in nilfs_sufile_set_suinfo()
966 blkoff = nilfs_sufile_get_blkoff(sufile, sup->sup_segnum); in nilfs_sufile_set_suinfo()
973 sufile, sup->sup_segnum, bh); in nilfs_sufile_set_suinfo()
974 su = kmap_local_folio(bh->b_folio, offset); in nilfs_sufile_set_suinfo()
977 su->su_lastmod = cpu_to_le64(sup->sup_sui.sui_lastmod); in nilfs_sufile_set_suinfo()
980 su->su_nblocks = cpu_to_le32(sup->sup_sui.sui_nblocks); in nilfs_sufile_set_suinfo()
985 * nilfs kernel code - drop it not to write it to in nilfs_sufile_set_suinfo()
988 sup->sup_sui.sui_flags &= in nilfs_sufile_set_suinfo()
991 cleansi = nilfs_suinfo_clean(&sup->sup_sui); in nilfs_sufile_set_suinfo()
993 dirtysi = nilfs_suinfo_dirty(&sup->sup_sui); in nilfs_sufile_set_suinfo()
999 --ncleaned; in nilfs_sufile_set_suinfo()
1004 --ndirtied; in nilfs_sufile_set_suinfo()
1006 su->su_flags = cpu_to_le32(sup->sup_sui.sui_flags); in nilfs_sufile_set_suinfo()
1016 blkoff = nilfs_sufile_get_blkoff(sufile, sup->sup_segnum); in nilfs_sufile_set_suinfo()
1034 NILFS_SUI(sufile)->ncleansegs += ncleaned; in nilfs_sufile_set_suinfo()
1040 up_write(&NILFS_MDT(sufile)->mi_sem); in nilfs_sufile_set_suinfo()
1045 * nilfs_sufile_trim_fs() - trim ioctl handle function
1062 struct the_nilfs *nilfs = sufile->i_sb->s_fs_info; in nilfs_sufile_trim_fs()
1067 size_t n, i, susz = NILFS_MDT(sufile)->mi_entry_size; in nilfs_sufile_trim_fs()
1074 sects_per_block = (1 << nilfs->ns_blocksize_bits) / in nilfs_sufile_trim_fs()
1075 bdev_logical_block_size(nilfs->ns_bdev); in nilfs_sufile_trim_fs()
1076 len = range->len >> nilfs->ns_blocksize_bits; in nilfs_sufile_trim_fs()
1077 minlen = range->minlen >> nilfs->ns_blocksize_bits; in nilfs_sufile_trim_fs()
1078 max_blocks = ((u64)nilfs->ns_nsegments * nilfs->ns_blocks_per_segment); in nilfs_sufile_trim_fs()
1080 if (!len || range->start >= max_blocks << nilfs->ns_blocksize_bits) in nilfs_sufile_trim_fs()
1081 return -EINVAL; in nilfs_sufile_trim_fs()
1083 start_block = (range->start + nilfs->ns_blocksize - 1) >> in nilfs_sufile_trim_fs()
1084 nilfs->ns_blocksize_bits; in nilfs_sufile_trim_fs()
1087 * range->len can be very large (actually, it is set to in nilfs_sufile_trim_fs()
1088 * ULLONG_MAX by default) - truncate upper end of the range in nilfs_sufile_trim_fs()
1091 if (max_blocks - start_block < len) in nilfs_sufile_trim_fs()
1092 end_block = max_blocks - 1; in nilfs_sufile_trim_fs()
1094 end_block = start_block + len - 1; in nilfs_sufile_trim_fs()
1099 down_read(&NILFS_MDT(sufile)->mi_sem); in nilfs_sufile_trim_fs()
1108 if (ret != -ENOENT) in nilfs_sufile_trim_fs()
1117 su = kaddr = kmap_local_folio(su_bh->b_folio, offset); in nilfs_sufile_trim_fs()
1128 nblocks = seg_end - seg_start + 1; in nilfs_sufile_trim_fs()
1134 nblocks += seg_end - seg_start + 1; in nilfs_sufile_trim_fs()
1140 nblocks -= start_block - start; in nilfs_sufile_trim_fs()
1147 ret = blkdev_issue_discard(nilfs->ns_bdev, in nilfs_sufile_trim_fs()
1159 su = kaddr = kmap_local_folio(su_bh->b_folio, in nilfs_sufile_trim_fs()
1165 nblocks = seg_end - seg_start + 1; in nilfs_sufile_trim_fs()
1175 nblocks -= start_block - start; in nilfs_sufile_trim_fs()
1179 nblocks = end_block - start + 1; in nilfs_sufile_trim_fs()
1182 ret = blkdev_issue_discard(nilfs->ns_bdev, in nilfs_sufile_trim_fs()
1192 up_read(&NILFS_MDT(sufile)->mi_sem); in nilfs_sufile_trim_fs()
1194 range->len = ndiscarded << nilfs->ns_blocksize_bits; in nilfs_sufile_trim_fs()
1199 * nilfs_sufile_read - read or get sufile inode
1202 * @raw_inode: on-disk sufile inode
1216 if (susize > sb->s_blocksize) { in nilfs_sufile_read()
1219 return -EINVAL; in nilfs_sufile_read()
1223 return -EINVAL; in nilfs_sufile_read()
1228 return -ENOMEM; in nilfs_sufile_read()
1229 if (!(sufile->i_state & I_NEW)) in nilfs_sufile_read()
1245 if (err == -ENOENT) { in nilfs_sufile_read()
1248 err = -EINVAL; in nilfs_sufile_read()
1254 header = kmap_local_folio(header_bh->b_folio, 0); in nilfs_sufile_read()
1255 sui->ncleansegs = le64_to_cpu(header->sh_ncleansegs); in nilfs_sufile_read()
1259 sui->allocmax = nilfs_sufile_get_nsegments(sufile) - 1; in nilfs_sufile_read()
1260 sui->allocmin = 0; in nilfs_sufile_read()