fs/exfat/fatent.c

Source file repositories/reference/linux-study-clean/fs/exfat/fatent.c

File Facts

System
Linux kernel
Corpus path
fs/exfat/fatent.c
Extension
.c
Size
13425 bytes
Lines
586
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 (clu == last_cluster || cur_cmap_i != next_cmap_i) {
				sync = true;
				cur_cmap_i = next_cmap_i;
			}

			err = exfat_clear_bitmap(sb, clu, (sync && IS_DIRSYNC(inode)));
			if (err)
				break;
			clu++;
			num_clusters++;
		} while (num_clusters < p_chain->size);

		if (sbi->options.discard)
			exfat_discard_cluster(sb, p_chain->dir, p_chain->size);
	} else {
		unsigned int nr_clu = 1;

		do {
			bool sync = false;
			unsigned int n_clu = clu;
			int err = exfat_get_next_cluster(sb, &n_clu);

			if (err || n_clu == EXFAT_EOF_CLUSTER)
				sync = true;
			else
				next_cmap_i =
				  BITMAP_OFFSET_SECTOR_INDEX(sb, CLUSTER_TO_BITMAP_ENT(n_clu));

			if (cur_cmap_i != next_cmap_i) {
				sync = true;
				cur_cmap_i = next_cmap_i;
			}

			if (exfat_clear_bitmap(sb, clu, (sync && IS_DIRSYNC(inode))))
				break;

			if (sbi->options.discard) {
				if (n_clu == clu + 1)
					nr_clu++;
				else {
					exfat_discard_cluster(sb, clu - nr_clu + 1, nr_clu);
					nr_clu = 1;
				}
			}

			clu = n_clu;
			num_clusters++;

			if (err)
				break;

			if (num_clusters >= sbi->num_clusters - EXFAT_FIRST_CLUSTER) {
				/*
				 * The cluster chain includes a loop, scan the
				 * bitmap to get the number of used clusters.
				 */
				exfat_count_used_clusters(sb, &sbi->used_clusters);

				return 0;
			}
		} while (clu != EXFAT_EOF_CLUSTER);
	}

	sbi->used_clusters -= num_clusters;
	return 0;
}

int exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain)
{
	int ret = 0;

	mutex_lock(&EXFAT_SB(inode->i_sb)->bitmap_lock);
	ret = __exfat_free_cluster(inode, p_chain);
	mutex_unlock(&EXFAT_SB(inode->i_sb)->bitmap_lock);

	return ret;
}

int exfat_find_last_cluster(struct super_block *sb, struct exfat_chain *p_chain,
		unsigned int *ret_clu)
{
	struct buffer_head *bh = NULL;
	unsigned int clu, next;
	unsigned int count = 0;

	next = p_chain->dir;
	if (p_chain->flags == ALLOC_NO_FAT_CHAIN) {
		*ret_clu = next + p_chain->size - 1;
		return 0;
	}

Annotation

Implementation Notes