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

📄 dir.c

📁 嵌入式linux下基于SRAM的内存文件系统
💻 C
字号:
/* * FILE NAME fs/pramfs/dir.c * * BRIEF DESCRIPTION * * File 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>/* *	Parent is locked. */int pram_add_link (struct dentry * dentry, struct inode * inode){	struct inode * dir = dentry->d_parent->d_inode;	struct pram_inode * pidir, * pi, * pitail = NULL;	pram_off_t tail_ino, prev_ino;	const char *name = dentry->d_name.name;	int namelen = dentry->d_name.len > PRAM_NAME_LEN ?		PRAM_NAME_LEN : dentry->d_name.len;	struct super_block * sb = dir->i_sb;	pidir = pram_get_inode(sb, dir->i_ino);	pi = pram_get_inode(sb, inode->i_ino);	dir->i_mtime = dir->i_ctime = CURRENT_TIME;	tail_ino = pidir->i_type.dir.tail;	if (tail_ino != 0) {		pitail = pram_get_inode(sb, tail_ino);		pram_lock_inode(sb, pitail);		pitail->i_d.d_next = inode->i_ino;		pram_unlock_inode(sb, pitail);		prev_ino = tail_ino;		pram_lock_inode(sb, pidir);		pidir->i_type.dir.tail = inode->i_ino;		pidir->i_mtime = dir->i_mtime.tv_sec;		pidir->i_ctime = dir->i_ctime.tv_sec;		pram_unlock_inode(sb, pidir);	} else {		// the directory is empty		prev_ino = 0;		pram_lock_inode(sb, pidir);		pidir->i_type.dir.head = pidir->i_type.dir.tail = inode->i_ino;		pidir->i_mtime = dir->i_mtime.tv_sec;		pidir->i_ctime = dir->i_ctime.tv_sec;		pram_unlock_inode(sb, pidir);	}	pram_lock_inode(sb, pi);	pi->i_d.d_prev = prev_ino;	pi->i_d.d_parent = dir->i_ino;	memcpy(pi->i_d.d_name, name, namelen);	pi->i_d.d_name[namelen] = '\0';	pram_unlock_inode(sb, pi);	return 0;}int pram_remove_link(struct inode * inode){	struct super_block * sb = inode->i_sb;	struct pram_inode * prev = NULL;	struct pram_inode * next = NULL;	struct pram_inode * pidir, * pi;	pi = pram_get_inode(sb, inode->i_ino);	pidir = pram_get_inode(sb, pi->i_d.d_parent);	if (!pidir)		return -EACCES;	if (inode->i_ino == pidir->i_type.dir.head) {		// first inode in directory		next = pram_get_inode(sb, pi->i_d.d_next);		if (next) {			pram_lock_inode(sb, next);			next->i_d.d_prev = 0;			pram_unlock_inode(sb, next);			pram_lock_inode(sb, pidir);			pidir->i_type.dir.head = pi->i_d.d_next;		} else {			pram_lock_inode(sb, pidir);			pidir->i_type.dir.head = pidir->i_type.dir.tail = 0;		}		pram_unlock_inode(sb, pidir);	} else if (inode->i_ino == pidir->i_type.dir.tail) {		// last inode in directory		prev = pram_get_inode(sb, pi->i_d.d_prev);		pram_lock_inode(sb, prev);		prev->i_d.d_next = 0;		pram_unlock_inode(sb, prev);		pram_lock_inode(sb, pidir);		pidir->i_type.dir.tail = pi->i_d.d_prev;		pram_unlock_inode(sb, pidir);	} else {		// somewhere in the middle		prev = pram_get_inode(sb, pi->i_d.d_prev);		next = pram_get_inode(sb, pi->i_d.d_next);		if (prev && next) {			pram_lock_inode(sb, prev);			prev->i_d.d_next = pi->i_d.d_next;			pram_unlock_inode(sb, prev);			pram_lock_inode(sb, next);			next->i_d.d_prev = pi->i_d.d_prev;			pram_unlock_inode(sb, next);		}	}	pram_lock_inode(sb, pi);	pi->i_d.d_next = pi->i_d.d_prev = pi->i_d.d_parent = 0;	pram_unlock_inode(sb, pi);	return 0;}#define S_SHIFT 12static unsigned int dtype_by_mode[S_IFMT >> S_SHIFT] = {        [S_IFREG >> S_SHIFT]  = DT_REG,        [S_IFDIR >> S_SHIFT]  = DT_DIR,        [S_IFCHR >> S_SHIFT]  = DT_CHR,        [S_IFBLK >> S_SHIFT]  = DT_BLK,        [S_IFIFO >> S_SHIFT]  = DT_FIFO,        [S_IFSOCK >> S_SHIFT] = DT_SOCK,        [S_IFLNK >> S_SHIFT]  = DT_LNK,};static intpram_readdir (struct file * filp, void * dirent, filldir_t filldir){	struct inode *inode = filp->f_dentry->d_inode;	struct super_block * sb = inode->i_sb;	struct pram_inode * pi;	int namelen, ret=0;	char *name;	ino_t ino;	if (filp->f_pos >> 32)		return 0;	pi = pram_get_inode(sb, inode->i_ino);	switch ((unsigned long)filp->f_pos) {	case 0:		ret = filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR);		filp->f_pos++;		return ret;	case 1:		ret = filldir(dirent, "..", 2, 1, pi->i_d.d_parent, DT_DIR);		ino = pi->i_type.dir.head;		filp->f_pos = ino ? ino : 2;		return ret;	case 2:		ino = pi->i_type.dir.head;		if (ino) {			filp->f_pos = ino;			pi = pram_get_inode(sb, ino);			break;		} else {			/* the directory is empty */			filp->f_pos = 2;			return 0;		}	case 3:		return 0;	default:		ino = filp->f_pos;		pi = pram_get_inode(sb, ino);		break;	}	while (pi && !pi->i_links_count) {		ino = filp->f_pos = pi->i_d.d_next;		pi = pram_get_inode(sb, ino);	}	if (pi) {		name = pi->i_d.d_name;		namelen = strlen(name);		ret = filldir(dirent, name, namelen,			      filp->f_pos, ino,			      dtype_by_mode[(pi->i_mode & S_IFMT)>>S_SHIFT]);		filp->f_pos = pi->i_d.d_next ? pi->i_d.d_next : 3;	} else		filp->f_pos = 3;	return ret;}const struct file_operations pram_dir_operations = {	.read		= generic_read_dir,	.readdir	= pram_readdir,	.ioctl		= pram_ioctl,	.fsync		= pram_sync_file,};

⌨️ 快捷键说明

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