fs/ext4/resize.c

Source file repositories/reference/linux-study-clean/fs/ext4/resize.c

File Facts

System
Linux kernel
Corpus path
fs/ext4/resize.c
Extension
.c
Size
65201 bytes
Lines
2193
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 ext4_rcu_ptr {
	struct rcu_head rcu;
	void *ptr;
};

static void ext4_rcu_ptr_callback(struct rcu_head *head)
{
	struct ext4_rcu_ptr *ptr;

	ptr = container_of(head, struct ext4_rcu_ptr, rcu);
	kvfree(ptr->ptr);
	kfree(ptr);
}

void ext4_kvfree_array_rcu(void *to_free)
{
	struct ext4_rcu_ptr *ptr = kzalloc_obj(*ptr);

	if (ptr) {
		ptr->ptr = to_free;
		call_rcu(&ptr->rcu, ext4_rcu_ptr_callback);
		return;
	}
	synchronize_rcu();
	kvfree(to_free);
}

int ext4_resize_begin(struct super_block *sb)
{
	struct ext4_sb_info *sbi = EXT4_SB(sb);
	int ret = 0;

	if (!capable(CAP_SYS_RESOURCE))
		return -EPERM;

	/*
	 * If the reserved GDT blocks is non-zero, the resize_inode feature
	 * should always be set.
	 */
	if (sbi->s_es->s_reserved_gdt_blocks &&
	    !ext4_has_feature_resize_inode(sb)) {
		ext4_error(sb, "resize_inode disabled but reserved GDT blocks non-zero");
		return -EFSCORRUPTED;
	}

	/*
	 * If we are not using the primary superblock/GDT copy don't resize,
         * because the user tools have no way of handling this.  Probably a
         * bad time to do it anyways.
         */
	if (EXT4_B2C(sbi, sbi->s_sbh->b_blocknr) !=
	    le32_to_cpu(sbi->s_es->s_first_data_block)) {
		ext4_warning(sb, "won't resize using backup superblock at %llu",
			(unsigned long long)sbi->s_sbh->b_blocknr);
		return -EPERM;
	}

	/*
	 * We are not allowed to do online-resizing on a filesystem mounted
	 * with error, because it can destroy the filesystem easily.
	 */
	if (sbi->s_mount_state & EXT4_ERROR_FS) {
		ext4_warning(sb, "There are errors in the filesystem, "
			     "so online resizing is not allowed");
		return -EPERM;
	}

	if (ext4_has_feature_sparse_super2(sb)) {
		ext4_msg(sb, KERN_ERR, "Online resizing not supported with sparse_super2");
		return -EOPNOTSUPP;
	}

	if (test_and_set_bit_lock(EXT4_FLAGS_RESIZING,
				  &sbi->s_ext4_flags))
		ret = -EBUSY;

	return ret;
}

int ext4_resize_end(struct super_block *sb, bool update_backups)
{
	clear_bit_unlock(EXT4_FLAGS_RESIZING, &EXT4_SB(sb)->s_ext4_flags);
	smp_mb__after_atomic();
	if (update_backups)
		return ext4_update_overhead(sb, true);
	return 0;
}

static ext4_grpblk_t ext4_group_overhead_blocks(struct super_block *sb,
						ext4_group_t group) {

Annotation

Implementation Notes