⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 symlink.c

📁 linux 内核源代码
💻 C
字号:
/* * fs/sysfs/symlink.c - sysfs symlink implementation * * Copyright (c) 2001-3 Patrick Mochel * Copyright (c) 2007 SUSE Linux Products GmbH * Copyright (c) 2007 Tejun Heo <teheo@suse.de> * * This file is released under the GPLv2. * * Please see Documentation/filesystems/sysfs.txt for more information. */#include <linux/fs.h>#include <linux/mount.h>#include <linux/module.h>#include <linux/kobject.h>#include <linux/namei.h>#include <linux/mutex.h>#include "sysfs.h"static int object_depth(struct sysfs_dirent *sd){	int depth = 0;	for (; sd->s_parent; sd = sd->s_parent)		depth++;	return depth;}static int object_path_length(struct sysfs_dirent * sd){	int length = 1;	for (; sd->s_parent; sd = sd->s_parent)		length += strlen(sd->s_name) + 1;	return length;}static void fill_object_path(struct sysfs_dirent *sd, char *buffer, int length){	--length;	for (; sd->s_parent; sd = sd->s_parent) {		int cur = strlen(sd->s_name);		/* back up enough to print this bus id with '/' */		length -= cur;		strncpy(buffer + length, sd->s_name, cur);		*(buffer + --length) = '/';	}}/** *	sysfs_create_link - create symlink between two objects. *	@kobj:	object whose directory we're creating the link in. *	@target:	object we're pointing to. *	@name:		name of the symlink. */int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name){	struct sysfs_dirent *parent_sd = NULL;	struct sysfs_dirent *target_sd = NULL;	struct sysfs_dirent *sd = NULL;	struct sysfs_addrm_cxt acxt;	int error;	BUG_ON(!name);	if (!kobj)		parent_sd = &sysfs_root;	else		parent_sd = kobj->sd;	error = -EFAULT;	if (!parent_sd)		goto out_put;	/* target->sd can go away beneath us but is protected with	 * sysfs_assoc_lock.  Fetch target_sd from it.	 */	spin_lock(&sysfs_assoc_lock);	if (target->sd)		target_sd = sysfs_get(target->sd);	spin_unlock(&sysfs_assoc_lock);	error = -ENOENT;	if (!target_sd)		goto out_put;	error = -ENOMEM;	sd = sysfs_new_dirent(name, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK);	if (!sd)		goto out_put;	sd->s_symlink.target_sd = target_sd;	target_sd = NULL;	/* reference is now owned by the symlink */	sysfs_addrm_start(&acxt, parent_sd);	error = sysfs_add_one(&acxt, sd);	sysfs_addrm_finish(&acxt);	if (error)		goto out_put;	return 0; out_put:	sysfs_put(target_sd);	sysfs_put(sd);	return error;}/** *	sysfs_remove_link - remove symlink in object's directory. *	@kobj:	object we're acting for. *	@name:	name of the symlink to remove. */void sysfs_remove_link(struct kobject * kobj, const char * name){	sysfs_hash_and_remove(kobj->sd, name);}static int sysfs_get_target_path(struct sysfs_dirent * parent_sd,				 struct sysfs_dirent * target_sd, char *path){	char * s;	int depth, size;	depth = object_depth(parent_sd);	size = object_path_length(target_sd) + depth * 3 - 1;	if (size > PATH_MAX)		return -ENAMETOOLONG;	pr_debug("%s: depth = %d, size = %d\n", __FUNCTION__, depth, size);	for (s = path; depth--; s += 3)		strcpy(s,"../");	fill_object_path(target_sd, path, size);	pr_debug("%s: path = '%s'\n", __FUNCTION__, path);	return 0;}static int sysfs_getlink(struct dentry *dentry, char * path){	struct sysfs_dirent *sd = dentry->d_fsdata;	struct sysfs_dirent *parent_sd = sd->s_parent;	struct sysfs_dirent *target_sd = sd->s_symlink.target_sd;	int error;	mutex_lock(&sysfs_mutex);	error = sysfs_get_target_path(parent_sd, target_sd, path);	mutex_unlock(&sysfs_mutex);	return error;}static void *sysfs_follow_link(struct dentry *dentry, struct nameidata *nd){	int error = -ENOMEM;	unsigned long page = get_zeroed_page(GFP_KERNEL);	if (page)		error = sysfs_getlink(dentry, (char *) page); 	nd_set_link(nd, error ? ERR_PTR(error) : (char *)page);	return NULL;}static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie){	char *page = nd_get_link(nd);	if (!IS_ERR(page))		free_page((unsigned long)page);}const struct inode_operations sysfs_symlink_inode_operations = {	.readlink = generic_readlink,	.follow_link = sysfs_follow_link,	.put_link = sysfs_put_link,};EXPORT_SYMBOL_GPL(sysfs_create_link);EXPORT_SYMBOL_GPL(sysfs_remove_link);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -