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

📄 readdir.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
字号:
/* *  linux/fs/readdir.c * *  Copyright (C) 1995  Linus Torvalds */#include <linux/types.h>#include <linux/errno.h>#include <linux/stat.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/mm.h>#include <asm/segment.h>/* * Traditional linux readdir() handling.. * * "count=1" is a special case, meaning that the buffer is one * dirent-structure in size and that the code can't handle more * anyway. Thus the special "fillonedir()" function for that * case (the low-level handlers don't need to care about this). */#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))#define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1))struct old_linux_dirent {	unsigned long	d_ino;	unsigned long	d_offset;	unsigned short	d_namlen;	char		d_name[1];};struct readdir_callback {	struct old_linux_dirent * dirent;	int count;};static int fillonedir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino){	struct readdir_callback * buf = (struct readdir_callback *) __buf;	struct old_linux_dirent * dirent;	if (buf->count)		return -EINVAL;	buf->count++;	dirent = buf->dirent;	put_user(ino, &dirent->d_ino);	put_user(offset, &dirent->d_offset);	put_user(namlen, &dirent->d_namlen);	memcpy_tofs(dirent->d_name, name, namlen);	put_user(0, dirent->d_name + namlen);	return 0;}asmlinkage int old_readdir(unsigned int fd, void * dirent, unsigned int count){	int error;	struct file * file;	struct readdir_callback buf;	if (fd >= NR_OPEN || !(file = current->files->fd[fd]))		return -EBADF;	if (!file->f_op || !file->f_op->readdir)		return -ENOTDIR;	error = verify_area(VERIFY_WRITE, dirent, sizeof(struct old_linux_dirent));	if (error)		return error;	buf.count = 0;	buf.dirent = dirent;	error = file->f_op->readdir(file->f_inode, file, &buf, fillonedir);	if (error < 0)		return error;	return buf.count;}/* * New, all-improved, singing, dancing, iBCS2-compliant getdents() * interface.  */struct linux_dirent {	unsigned long	d_ino;	unsigned long	d_off;	unsigned short	d_reclen;	char		d_name[1];};struct getdents_callback {	struct linux_dirent * current_dir;	struct linux_dirent * previous;	int count;	int error;};static int filldir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino){	struct linux_dirent * dirent;	struct getdents_callback * buf = (struct getdents_callback *) __buf;	int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);	buf->error = -EINVAL;	/* only used if we fail.. */	if (reclen > buf->count)		return -EINVAL;	dirent = buf->previous;	if (dirent)		put_user(offset, &dirent->d_off);	dirent = buf->current_dir;	buf->previous = dirent;	put_user(ino, &dirent->d_ino);	put_user(reclen, &dirent->d_reclen);	memcpy_tofs(dirent->d_name, name, namlen);	put_user(0, dirent->d_name + namlen);	((char *) dirent) += reclen;	buf->current_dir = dirent;	buf->count -= reclen;	return 0;}asmlinkage int sys_getdents(unsigned int fd, void * dirent, unsigned int count){	struct file * file;	struct linux_dirent * lastdirent;	struct getdents_callback buf;	int error;	if (fd >= NR_OPEN || !(file = current->files->fd[fd]))		return -EBADF;	if (!file->f_op || !file->f_op->readdir)		return -ENOTDIR;	error = verify_area(VERIFY_WRITE, dirent, count);	if (error)		return error;	buf.current_dir = (struct linux_dirent *) dirent;	buf.previous = NULL;	buf.count = count;	buf.error = 0;	error = file->f_op->readdir(file->f_inode, file, &buf, filldir);	if (error < 0)		return error;	lastdirent = buf.previous;	if (!lastdirent)		return buf.error;	put_user(file->f_pos, &lastdirent->d_off);	return count - buf.count;}

⌨️ 快捷键说明

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