fs/ntfs3/index.c

Source file repositories/reference/linux-study-clean/fs/ntfs3/index.c

File Facts

System
Linux kernel
Corpus path
fs/ntfs3/index.c
Extension
.c
Size
58857 bytes
Lines
2753
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

struct bmp_buf {
	struct ATTRIB *b;
	struct mft_inode *mi;
	struct buffer_head *bh;
	ulong *buf;
	size_t bit;
	u32 nbits;
	u64 new_valid;
};

static int bmp_buf_get(struct ntfs_index *indx, struct ntfs_inode *ni,
		       size_t bit, struct bmp_buf *bbuf)
{
	struct ATTRIB *b;
	size_t data_size, valid_size, vbo, off = bit >> 3;
	struct ntfs_sb_info *sbi = ni->mi.sbi;
	CLST vcn = off >> sbi->cluster_bits;
	struct ATTR_LIST_ENTRY *le = NULL;
	struct buffer_head *bh;
	struct super_block *sb;
	u32 blocksize;
	const struct INDEX_NAMES *in = &s_index_names[indx->type];

	bbuf->bh = NULL;

	b = ni_find_attr(ni, NULL, &le, ATTR_BITMAP, in->name, in->name_len,
			 &vcn, &bbuf->mi);
	bbuf->b = b;
	if (!b)
		return -EINVAL;

	if (!b->non_res) {
		data_size = le32_to_cpu(b->res.data_size);

		if (off >= data_size)
			return -EINVAL;

		bbuf->buf = (ulong *)resident_data(b);
		bbuf->bit = 0;
		bbuf->nbits = data_size * 8;

		return 0;
	}

	data_size = le64_to_cpu(b->nres.data_size);
	if (WARN_ON(off >= data_size)) {
		/* Looks like filesystem error. */
		return -EINVAL;
	}

	valid_size = le64_to_cpu(b->nres.valid_size);

	bh = ntfs_bread_run(sbi, &indx->bitmap_run, off);
	if (!bh)
		return -EIO;

	if (IS_ERR(bh))
		return PTR_ERR(bh);

	bbuf->bh = bh;

	wait_on_buffer(bh);
	lock_buffer(bh);

	sb = sbi->sb;
	blocksize = sb->s_blocksize;

	vbo = off & ~(size_t)sbi->block_mask;

	bbuf->new_valid = vbo + blocksize;
	if (bbuf->new_valid <= valid_size)
		bbuf->new_valid = 0;
	else if (bbuf->new_valid > data_size)
		bbuf->new_valid = data_size;

	if (vbo >= valid_size) {
		memset(bh->b_data, 0, blocksize);
	} else if (vbo + blocksize > valid_size) {
		u32 voff = valid_size & sbi->block_mask;

		memset(bh->b_data + voff, 0, blocksize - voff);
	}

	bbuf->buf = (ulong *)bh->b_data;
	bbuf->bit = 8 * (off & ~(size_t)sbi->block_mask);
	bbuf->nbits = 8 * blocksize;

	return 0;
}

Annotation

Implementation Notes