fs/xfs/xfs_symlink.c

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

File Facts

System
Linux kernel
Corpus path
fs/xfs/xfs_symlink.c
Extension
.c
Size
8857 bytes
Lines
363
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

// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
 * Copyright (c) 2012-2013 Red Hat, Inc.
 * All rights reserved.
 */
#include "xfs_platform.h"
#include "xfs_shared.h"
#include "xfs_fs.h"
#include "xfs_format.h"
#include "xfs_log_format.h"
#include "xfs_trans_resv.h"
#include "xfs_bit.h"
#include "xfs_mount.h"
#include "xfs_dir2.h"
#include "xfs_inode.h"
#include "xfs_bmap.h"
#include "xfs_bmap_btree.h"
#include "xfs_quota.h"
#include "xfs_symlink.h"
#include "xfs_trans_space.h"
#include "xfs_trace.h"
#include "xfs_trans.h"
#include "xfs_ialloc.h"
#include "xfs_error.h"
#include "xfs_health.h"
#include "xfs_symlink_remote.h"
#include "xfs_parent.h"
#include "xfs_defer.h"

int
xfs_readlink(
	struct xfs_inode	*ip,
	char			*link)
{
	struct xfs_mount	*mp = ip->i_mount;
	xfs_fsize_t		pathlen;
	int			error;

	trace_xfs_readlink(ip);

	if (xfs_is_shutdown(mp))
		return -EIO;
	if (xfs_ifork_zapped(ip, XFS_DATA_FORK))
		return -EIO;

	xfs_ilock(ip, XFS_ILOCK_SHARED);

	pathlen = ip->i_disk_size;
	if (!pathlen)
		goto out_corrupt;

	if (pathlen < 0 || pathlen > XFS_SYMLINK_MAXLEN) {
		xfs_alert(mp, "%s: inode (%llu) bad symlink length (%lld)",
			 __func__, (unsigned long long)I_INO(ip),
			 (long long) pathlen);
		ASSERT(0);
		goto out_corrupt;
	}

	if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
		/*
		 * The VFS crashes on a NULL pointer, so return -EFSCORRUPTED
		 * if if_data is junk.
		 */
		if (XFS_IS_CORRUPT(ip->i_mount, !ip->i_df.if_data))
			goto out_corrupt;

		memcpy(link, ip->i_df.if_data, pathlen + 1);
		error = 0;
	} else {
		error = xfs_symlink_remote_read(ip, link);
	}

	xfs_iunlock(ip, XFS_ILOCK_SHARED);
	return error;
 out_corrupt:
	xfs_iunlock(ip, XFS_ILOCK_SHARED);
	xfs_inode_mark_sick(ip, XFS_SICK_INO_SYMLINK);
	return -EFSCORRUPTED;
}

int
xfs_symlink(
	struct mnt_idmap	*idmap,
	struct xfs_inode	*dp,
	struct xfs_name		*link_name,
	const char		*target_path,
	umode_t			mode,
	struct xfs_inode	**ipp)

Annotation

Implementation Notes