fs/xfs/xfs_icache.c

Source file repositories/reference/linux-study-clean/fs/xfs/xfs_icache.c

File Facts

System
Linux kernel
Corpus path
fs/xfs/xfs_icache.c
Extension
.c
Size
60455 bytes
Lines
2357
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 (VFS_I(ip)->i_mode != 0) {
			xfs_warn(ip->i_mount,
"Corruption detected! Free inode 0x%llx not marked free! (mode 0x%x)",
				I_INO(ip), VFS_I(ip)->i_mode);
			xfs_agno_mark_sick(ip->i_mount, XFS_INODE_TO_AGNO(ip),
					XFS_SICK_AG_INOBT);
			return -EFSCORRUPTED;
		}

		if (ip->i_nblocks != 0) {
			xfs_warn(ip->i_mount,
"Corruption detected! Free inode 0x%llx has blocks allocated!",
				I_INO(ip));
			xfs_agno_mark_sick(ip->i_mount, XFS_INODE_TO_AGNO(ip),
					XFS_SICK_AG_INOBT);
			return -EFSCORRUPTED;
		}
		return 0;
	}

	/* should be an allocated inode */
	if (VFS_I(ip)->i_mode == 0)
		return -ENOENT;

	return 0;
}

/* Make all pending inactivation work start immediately. */
static bool
xfs_inodegc_queue_all(
	struct xfs_mount	*mp)
{
	struct xfs_inodegc	*gc;
	int			cpu;
	bool			ret = false;

	for_each_cpu(cpu, &mp->m_inodegc_cpumask) {
		gc = per_cpu_ptr(mp->m_inodegc, cpu);
		if (!llist_empty(&gc->list)) {
			mod_delayed_work_on(cpu, mp->m_inodegc_wq, &gc->work, 0);
			ret = true;
		}
	}

	return ret;
}

/* Wait for all queued work and collect errors */
static int
xfs_inodegc_wait_all(
	struct xfs_mount	*mp)
{
	int			cpu;
	int			error = 0;

	flush_workqueue(mp->m_inodegc_wq);
	for_each_cpu(cpu, &mp->m_inodegc_cpumask) {
		struct xfs_inodegc	*gc;

		gc = per_cpu_ptr(mp->m_inodegc, cpu);
		if (gc->error && !error)
			error = gc->error;
		gc->error = 0;
	}

	return error;
}

/*
 * Check the validity of the inode we just found it the cache
 */
static int
xfs_iget_cache_hit(
	struct xfs_perag	*pag,
	struct xfs_inode	*ip,
	xfs_ino_t		ino,
	int			flags,
	int			lock_flags) __releases(RCU)
{
	struct inode		*inode = VFS_I(ip);
	struct xfs_mount	*mp = ip->i_mount;
	int			error;

	/*
	 * check for re-use of an inode within an RCU grace period due to the
	 * radix tree nodes not being updated yet. We monitor for this by
	 * setting the inode number to zero before freeing the inode structure.
	 * If the inode has been reallocated and set up, then the inode number
	 * will not match, so check for that, too.
	 */

Annotation

Implementation Notes