fs/ntfs/bitmap.c

Source file repositories/reference/linux-study-clean/fs/ntfs/bitmap.c

File Facts

System
Linux kernel
Corpus path
fs/ntfs/bitmap.c
Extension
.c
Size
7631 bytes
Lines
291
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if (IS_ERR(folio)) {
			ret = PTR_ERR(folio);
			goto out_free;
		}

		kaddr = kmap_local_folio(folio, 0);
		bitmap = (unsigned long *)kaddr;

		start_buf = max_t(u64, index * buf_clusters, start_cluster);
		end_buf = min_t(u64, (index + 1) * buf_clusters, end_cluster);

		end = start_buf;
		while (end < end_buf) {
			u64 aligned_start, aligned_count;
			u64 start = find_next_zero_bit(bitmap, end_buf - start_buf,
					end - start_buf) + start_buf;
			if (start >= end_buf)
				break;

			end = find_next_bit(bitmap, end_buf - start_buf,
					start - start_buf) + start_buf;

			aligned_start = ALIGN(ntfs_cluster_to_bytes(vol, start), dq);
			aligned_count =
				ALIGN_DOWN(ntfs_cluster_to_bytes(vol, end - start), dq);
			if (aligned_count >= range->minlen) {
				ret = blkdev_issue_discard(vol->sb->s_bdev, aligned_start >> 9,
						aligned_count >> 9, GFP_NOFS);
				if (ret)
					goto out_unmap;
				trimmed += aligned_count;
			}
		}

out_unmap:
		kunmap_local(kaddr);
		folio_unlock(folio);
		folio_put(folio);

		if (ret)
			goto out_free;
	}

	range->len = trimmed;

out_free:
	kfree(ra);
	return ret;
}

/*
 * __ntfs_bitmap_set_bits_in_run - set a run of bits in a bitmap to a value
 * @vi:			vfs inode describing the bitmap
 * @start_bit:		first bit to set
 * @count:		number of bits to set
 * @value:		value to set the bits to (i.e. 0 or 1)
 * @is_rollback:	if 'true' this is a rollback operation
 *
 * Set @count bits starting at bit @start_bit in the bitmap described by the
 * vfs inode @vi to @value, where @value is either 0 or 1.
 *
 * @is_rollback should always be 'false', it is for internal use to rollback
 * errors.  You probably want to use ntfs_bitmap_set_bits_in_run() instead.
 *
 * Return 0 on success and -errno on error.
 */
int __ntfs_bitmap_set_bits_in_run(struct inode *vi, const s64 start_bit,
		const s64 count, const u8 value, const bool is_rollback)
{
	s64 cnt = count;
	pgoff_t index, end_index;
	struct address_space *mapping;
	struct folio *folio;
	u8 *kaddr;
	int pos, len, err;
	u8 bit;
	struct ntfs_inode *ni = NTFS_I(vi);
	struct ntfs_volume *vol = ni->vol;

	ntfs_debug("Entering for i_ino 0x%llx, start_bit 0x%llx, count 0x%llx, value %u.%s",
			ni->mft_no, (unsigned long long)start_bit,
			(unsigned long long)cnt, (unsigned int)value,
			is_rollback ? " (rollback)" : "");

	if (start_bit < 0 || cnt < 0 || value > 1)
		return -EINVAL;

	/*
	 * Calculate the indices for the pages containing the first and last
	 * bits, i.e. @start_bit and @start_bit + @cnt - 1, respectively.

Annotation

Implementation Notes