fs/afs/dir_edit.c

Source file repositories/reference/linux-study-clean/fs/afs/dir_edit.c

File Facts

System
Linux kernel
Corpus path
fs/afs/dir_edit.c
Extension
.c
Size
18074 bytes
Lines
649
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 ((bitmap & mask) == 0) {
			if (bit > 64 - nr_slots)
				return -1;
			return bit;
		}

		n = __ffs(bitmap);
		bitmap >>= n;
		bit += n;
	} while (bitmap);

	return -1;
}

/*
 * Set a number of contiguous bits in the directory block bitmap.
 */
static void afs_set_contig_bits(union afs_xdr_dir_block *block,
				int bit, unsigned int nr_slots)
{
	u64 mask;

	mask = (1 << nr_slots) - 1;
	mask <<= bit;

	block->hdr.bitmap[0] |= (u8)(mask >> 0 * 8);
	block->hdr.bitmap[1] |= (u8)(mask >> 1 * 8);
	block->hdr.bitmap[2] |= (u8)(mask >> 2 * 8);
	block->hdr.bitmap[3] |= (u8)(mask >> 3 * 8);
	block->hdr.bitmap[4] |= (u8)(mask >> 4 * 8);
	block->hdr.bitmap[5] |= (u8)(mask >> 5 * 8);
	block->hdr.bitmap[6] |= (u8)(mask >> 6 * 8);
	block->hdr.bitmap[7] |= (u8)(mask >> 7 * 8);
}

/*
 * Clear a number of contiguous bits in the directory block bitmap.
 */
static void afs_clear_contig_bits(union afs_xdr_dir_block *block,
				  int bit, unsigned int nr_slots)
{
	u64 mask;

	mask = (1 << nr_slots) - 1;
	mask <<= bit;

	block->hdr.bitmap[0] &= ~(u8)(mask >> 0 * 8);
	block->hdr.bitmap[1] &= ~(u8)(mask >> 1 * 8);
	block->hdr.bitmap[2] &= ~(u8)(mask >> 2 * 8);
	block->hdr.bitmap[3] &= ~(u8)(mask >> 3 * 8);
	block->hdr.bitmap[4] &= ~(u8)(mask >> 4 * 8);
	block->hdr.bitmap[5] &= ~(u8)(mask >> 5 * 8);
	block->hdr.bitmap[6] &= ~(u8)(mask >> 6 * 8);
	block->hdr.bitmap[7] &= ~(u8)(mask >> 7 * 8);
}

/*
 * Get a specific block, extending the directory storage to cover it as needed.
 */
static union afs_xdr_dir_block *afs_dir_get_block(struct afs_dir_iter *iter, size_t block)
{
	struct folio_queue *fq;
	struct afs_vnode *dvnode = iter->dvnode;
	struct folio *folio;
	size_t blpos = block * AFS_DIR_BLOCK_SIZE;
	size_t blend = (block + 1) * AFS_DIR_BLOCK_SIZE, fpos = iter->fpos;
	int ret;

	if (dvnode->directory_size < blend) {
		size_t cur_size = dvnode->directory_size;

		ret = netfs_alloc_folioq_buffer(
			NULL, &dvnode->directory, &cur_size, blend,
			mapping_gfp_mask(dvnode->netfs.inode.i_mapping));
		dvnode->directory_size = cur_size;
		if (ret < 0)
			goto fail;
	}

	fq = iter->fq;
	if (!fq)
		fq = dvnode->directory;

	/* Search the folio queue for the folio containing the block... */
	for (; fq; fq = fq->next) {
		for (int s = iter->fq_slot; s < folioq_count(fq); s++) {
			size_t fsize = folioq_folio_size(fq, s);

			if (blend <= fpos + fsize) {
				/* ... and then return the mapped block. */

Annotation

Implementation Notes