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

📄 namei.c

📁 嵌入式linux下基于SRAM的内存文件系统
💻 C
字号:
/* * FILE NAME fs/pramfs/namei.c * * BRIEF DESCRIPTION * * Inode operations for directories. * * Author: Steve Longerbeam <stevel@mvista.com, or source@mvista.com> * * Copyright 2003 Sony Corporation * Copyright 2003 Matsushita Electric Industrial Co., Ltd. * 2003-2004 (c) MontaVista Software, Inc. This file is licensed under * the terms of the GNU General Public License version 2. This program * is licensed "as is" without any warranty of any kind, whether express * or implied. */#include <linux/fs.h>#include <linux/pram_fs.h>#include <linux/pagemap.h>/* * Couple of helper functions - make the code slightly cleaner. */static inline void pram_inc_count(struct inode *inode){	inode->i_nlink++;	pram_write_inode_sync(inode);}static inline void pram_dec_count(struct inode *inode){	if (inode->i_nlink) {		inode->i_nlink--;		pram_write_inode_sync(inode);	}}static inline int pram_add_nondir(struct inode * dir,				   struct dentry * dentry,				   struct inode * inode){	int err = pram_add_link(dentry, inode);	if (!err) {		d_instantiate(dentry, inode);		return 0;	}	pram_dec_count(inode);	iput(inode);	return err;}/* * Methods themselves. */static ino_tpram_inode_by_name(struct inode * dir,		   struct dentry * dentry){	struct pram_inode * pi;	ino_t ino;	int namelen;	pi = pram_get_inode(dir->i_sb, dir->i_ino);	ino = pi->i_type.dir.head;	while (ino) {		pi = pram_get_inode(dir->i_sb, ino);		if (pi->i_links_count) {			namelen = strlen(pi->i_d.d_name);			if (namelen == dentry->d_name.len &&			    !memcmp(dentry->d_name.name,				    pi->i_d.d_name, namelen))				break;		}		ino = pi->i_d.d_next;	}	return ino;}static struct dentry *pram_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd){	struct inode * inode = NULL;	ino_t ino;	if (dentry->d_name.len > PRAM_NAME_LEN)		return ERR_PTR(-ENAMETOOLONG);	ino = pram_inode_by_name(dir, dentry);	if (ino) {		struct pram_inode * pi = pram_get_inode(dir->i_sb, ino);		inode = pram_fill_new_inode(dir->i_sb, pi);		if (!inode)			return ERR_PTR(-EACCES);	}	d_add(dentry, inode);	return NULL;}/* * By the time this is called, we already have created * the directory cache entry for the new file, but it * is so far negative - it has no inode. * * If the create succeeds, we fill in the inode information * with d_instantiate(). */static int pram_create (struct inode * dir, struct dentry * dentry,			int mode, struct nameidata *nd){	struct inode * inode;	int err;	pram_lock_failsafe(dir->i_sb, PRAM_FAILSAFE_OP_CREATE,			   dir->i_ino, mode, 0);	inode = pram_new_inode (dir, mode);	err = PTR_ERR(inode);	if (!IS_ERR(inode)) {		inode->i_op = &pram_file_inode_operations;		inode->i_fop = &pram_file_operations;		inode->i_mapping->a_ops = &pram_aops;		err = pram_add_nondir(dir, dentry, inode);	}	pram_unlock_failsafe(dir->i_sb);	return err;}static int pram_mknod (struct inode * dir, struct dentry *dentry, int mode,		       dev_t rdev){	struct inode * inode;	int err;	pram_lock_failsafe(dir->i_sb, PRAM_FAILSAFE_OP_MKNOD,			   dir->i_ino, mode, rdev);	inode = pram_new_inode (dir, mode);	err = PTR_ERR(inode);	if (!IS_ERR(inode)) {		init_special_inode(inode, mode, rdev);		pram_write_inode_sync(inode); /* update rdev */		err = pram_add_nondir(dir, dentry, inode);	}	pram_unlock_failsafe(dir->i_sb);	return err;}static int pram_symlink (struct inode * dir,			  struct dentry * dentry,			  const char * symname){	struct super_block * sb = dir->i_sb;	int err = -ENAMETOOLONG;	unsigned len = strlen(symname);	struct inode * inode;	pram_lock_failsafe(sb, PRAM_FAILSAFE_OP_SYMLINK, dir->i_ino, 0, 0);	if (len+1 > sb->s_blocksize)		goto out;	inode = pram_new_inode (dir, S_IFLNK | S_IRWXUGO);	err = PTR_ERR(inode);	if (IS_ERR(inode))		goto out;	inode->i_op = &pram_symlink_inode_operations;	inode->i_mapping->a_ops = &pram_aops;	err = pram_block_symlink(inode, symname, len);	if (err)		goto out_fail;	inode->i_size = len;	pram_write_inode_sync(inode);	err = pram_add_nondir(dir, dentry, inode);out:	pram_unlock_failsafe(sb);	return err;out_fail:	pram_dec_count(inode);	iput (inode);	goto out;}static int pram_link (struct dentry * dest_dentry,		       struct inode * dir,		       struct dentry * dentry){	pram_dbg ("hard links not supported\n");	return -ENOSYS;}static int pram_unlink(struct inode * dir, struct dentry *dentry){	struct inode * inode = dentry->d_inode;	inode->i_ctime = dir->i_ctime;	pram_lock_failsafe(dir->i_sb, PRAM_FAILSAFE_OP_UNLINK,			   inode->i_ino, dir->i_ino, 0);	pram_dec_count(inode);	pram_unlock_failsafe(dir->i_sb);	return 0;}static int pram_mkdir(struct inode * dir, struct dentry * dentry, int mode){	struct inode * inode;	struct pram_inode * pi;	int err = -EMLINK;	pram_lock_failsafe(dir->i_sb, PRAM_FAILSAFE_OP_MKDIR,			   dir->i_ino, mode, 0);	if (dir->i_nlink >= PRAM_LINK_MAX)		goto out;	pram_inc_count(dir);	inode = pram_new_inode (dir, S_IFDIR | mode);	err = PTR_ERR(inode);	if (IS_ERR(inode))		goto out_dir;	inode->i_op = &pram_dir_inode_operations;	inode->i_fop = &pram_dir_operations;	inode->i_mapping->a_ops = &pram_aops;	pram_inc_count(inode);	// make the new directory empty	pi = pram_get_inode(dir->i_sb, inode->i_ino);	pram_lock_inode(dir->i_sb, pi);	pi->i_type.dir.head = pi->i_type.dir.tail = 0;	pram_unlock_inode(dir->i_sb, pi);	err = pram_add_link(dentry, inode);	if (err)		goto out_fail;	d_instantiate(dentry, inode);out:	pram_unlock_failsafe(dir->i_sb);	return err;out_fail:	pram_dec_count(inode);	pram_dec_count(inode);	iput(inode);out_dir:	pram_dec_count(dir);	goto out;}static int pram_rmdir (struct inode * dir, struct dentry *dentry){	struct inode * inode = dentry->d_inode;	struct pram_inode * pi;	int err = -ENOTEMPTY;	if (!inode)		return -ENOENT;	pram_lock_failsafe(dir->i_sb, PRAM_FAILSAFE_OP_RMDIR,			   inode->i_ino, dir->i_ino, 0);	pi = pram_get_inode(dir->i_sb, inode->i_ino);	// directory to delete is empty?	if (pi->i_type.dir.tail == 0) {		inode->i_ctime = dir->i_ctime;		inode->i_size = 0;		inode->i_nlink = 0;		pram_write_inode_sync(inode);		pram_dec_count(dir);		err = 0;	} else {		pram_dbg("dir not empty\n");	}	pram_unlock_failsafe(dir->i_sb);	return err;}static int pram_rename (struct inode  * old_dir,			struct dentry * old_dentry,			struct inode  * new_dir,			struct dentry * new_dentry){	struct inode * old_inode = old_dentry->d_inode;	struct inode * new_inode = new_dentry->d_inode;	struct pram_inode * pi_new;	int err = -ENOENT;	pram_lock_failsafe(old_dir->i_sb, PRAM_FAILSAFE_OP_RENAME, 0, 0, 0);	if (new_inode) {		err = -ENOTEMPTY;		pi_new = pram_get_inode(new_dir->i_sb, new_inode->i_ino);		if (S_ISDIR(old_inode->i_mode)) {			if (pi_new->i_type.dir.tail != 0)				goto out;			if (new_inode->i_nlink)				new_inode->i_nlink--;		}		new_inode->i_ctime = CURRENT_TIME;		pram_dec_count(new_inode);	} else {		if (S_ISDIR(old_inode->i_mode)) {			err = -EMLINK;			if (new_dir->i_nlink >= PRAM_LINK_MAX)				goto out;			pram_dec_count(old_dir);			pram_inc_count(new_dir);		}	}	/* unlink the inode from the old directory ... */	if ((err = pram_remove_link(old_inode))) {		goto out;	}	/* and link it into the new directory. */	if ((err = pram_add_link(new_dentry, old_inode))) {		goto out;	}	err = 0; out:	pram_unlock_failsafe(old_dir->i_sb);	return err;}const struct inode_operations pram_dir_inode_operations = {	.create		= pram_create,	.lookup		= pram_lookup,	.link		= pram_link,	.unlink		= pram_unlink,	.symlink	= pram_symlink,	.mkdir		= pram_mkdir,	.rmdir		= pram_rmdir,	.mknod		= pram_mknod,	.rename		= pram_rename,};

⌨️ 快捷键说明

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