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

📄 symlink.c

📁 这是Linux系统下的对UDF文件系统新增的功能
💻 C
字号:
/* * symlink.c * * PURPOSE *	Symlink handling routines for the OSTA-UDF(tm) filesystem. * * CONTACTS *	E-mail regarding any portion of the Linux UDF file system should be *	directed to the development team mailing list (run by majordomo): *		linux_udf@hpesjro.fc.hp.com * * COPYRIGHT *	This file is distributed under the terms of the GNU General Public *	License (GPL). Copies of the GPL can be obtained from: *		ftp://prep.ai.mit.edu/pub/gnu/GPL *	Each contributing author retains all rights to their own work. * *  (C) 1998-2001 Ben Fennema *  (C) 1999 Stelias Computing Inc  * * HISTORY * *  04/16/99 blf  Created. * */#include "udfdecl.h"#include <asm/uaccess.h>#include <linux/errno.h>#include <linux/fs.h>#include <linux/udf_fs.h>#include <linux/sched.h>#include <linux/mm.h>#include <linux/stat.h>#include <linux/malloc.h>#include "udf_i.h"static void udf_pc_to_char(struct super_block *sb, char *from, int fromlen, char *to){	struct pathComponent *pc;	int elen = 0;	char *p = to;	while (elen < fromlen)	{		pc = (struct pathComponent *)(from + elen);		switch (pc->componentType)		{			case 1:				if (pc->lengthComponentIdent == 0)				{					p = to;					*p++ = '/';				}				break;			case 3:				memcpy(p, "../", 3);				p += 3;				break;			case 4:				memcpy(p, "./", 2);				p += 2;				/* that would be . - just ignore */				break;			case 5:				p += udf_get_filename(sb, pc->componentIdent, p, pc->lengthComponentIdent);				*p++ = '/';				break;		}		elen += sizeof(struct pathComponent) + pc->lengthComponentIdent;	}	if (p > to+1)		p[-1] = '\0';	else		p[0] = '\0';}static struct dentry * udf_follow_link(struct dentry * dentry,	struct dentry * base, unsigned int follow){	struct inode *inode = dentry->d_inode;	struct buffer_head *bh = NULL;	char *symlink, *tmpbuf;		if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)		symlink = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode);	else	{		bh = sb_bread(inode->i_sb, udf_bmap(inode, 0));		if (!bh)			return 0;		symlink = bh->b_data;	}	if ((tmpbuf = (char *)kmalloc(inode->i_size, GFP_KERNEL)))	{		udf_pc_to_char(inode->i_sb, symlink, inode->i_size, tmpbuf);		udf_release_data(bh);		base = lookup_dentry(tmpbuf, base, follow);		kfree(tmpbuf);		return base;	}	else	{		udf_release_data(bh);		return ERR_PTR(-ENOMEM);	}}static int udf_readlink(struct dentry * dentry, char * buffer, int buflen){	struct inode *inode = dentry->d_inode;	struct buffer_head *bh = NULL;	char *symlink, *tmpbuf;	int len;		if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)		symlink = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode);	else	{		bh = sb_bread(inode->i_sb, udf_bmap(inode, 0));		if (!bh)			return 0;		symlink = bh->b_data;	}	if ((tmpbuf = (char *)kmalloc(inode->i_size, GFP_KERNEL)))	{		udf_pc_to_char(inode->i_sb, symlink, inode->i_size, tmpbuf);		if ((len = strlen(tmpbuf)) > buflen)			len = buflen;		if (copy_to_user(buffer, tmpbuf, len))			len = -EFAULT;		kfree(tmpbuf);	}	else		len = -ENOMEM;	UPDATE_ATIME(inode);	udf_release_data(bh);	return len;}/* * symlinks can't do much... */struct inode_operations udf_symlink_inode_operations = {	NULL,			/* no file-operations */	NULL,			/* create */	NULL,			/* lookup */	NULL,			/* link */	NULL,			/* unlink */	NULL,			/* symlink */	NULL,			/* mkdir */	NULL,			/* rmdir */	NULL,			/* mknod */	NULL,			/* rename */	udf_readlink,	/* readlink */	udf_follow_link,/* follow_link */	NULL,			/* readpage */	NULL,			/* writepage */	NULL,			/* bmap */	NULL,			/* truncate */	NULL,			/* permission */	NULL,			/* smap */	NULL			/* revalidate */};

⌨️ 快捷键说明

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