ufs_dir.c

来自「elinux jffs初始版本 具体了解JFFS的文件系统!」· C语言 代码 · 共 190 行

C
190
字号
/* *  linux/fs/ufs/ufs_dir.c * * Copyright (C) 1996 * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu) * Laboratory for Computer Science Research Computing Facility * Rutgers, The State University of New Jersey * * $Id: ufs_dir.c,v 1.1.1.1 1998/07/10 11:59:02 bjornw Exp $ * */#include <linux/fs.h>/* XXX */extern int ufs_lookup (struct inode *, const char *, int, struct inode **);extern int ufs_bmap (struct inode *, int);extern void ufs_print_inode (struct inode *);/* * This is blatantly stolen from ext2fs */static intufs_readdir (struct inode * inode, struct file * filp, void * dirent,	     filldir_t filldir){	int error = 0;	unsigned long offset, lblk, blk;	int i, stored;	struct buffer_head * bh;	struct ufs_direct * de;	struct super_block * sb;	if (!inode || !S_ISDIR(inode->i_mode))		return -EBADF;	sb = inode->i_sb;	if (inode->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) {	        printk("ufs_readdir: ino %lu  f_pos %lu\n",	               inode->i_ino, (unsigned long) filp->f_pos);	        ufs_print_inode(inode);	}	stored = 0;	bh = NULL;	offset = filp->f_pos & (sb->s_blocksize - 1);	while (!error && !stored && filp->f_pos < inode->i_size) {		lblk = (filp->f_pos) >> sb->s_blocksize_bits;	        blk = ufs_bmap(inode, lblk);	        /* XXX - ufs_bmap() call needs error checking */	        blk = ufs_bmap(inode, lblk);		bh = bread (sb->s_dev, blk, sb->s_blocksize);		if (!bh) {	                /* XXX - error - skip to the next block */	                printk("ufs_readdir: dir inode %lu has a hole at offset %lu\n",	                       inode->i_ino, (unsigned long int)filp->f_pos);			filp->f_pos += sb->s_blocksize - offset;			continue;		}revalidate:		/* If the dir block has changed since the last call to		 * readdir(2), then we might be pointing to an invalid		 * dirent right now.  Scan from the start of the block		 * to make sure. */		if (filp->f_version != inode->i_version) {			for (i = 0; i < sb->s_blocksize && i < offset; ) {				de = (struct ufs_direct *) 					(bh->b_data + i);				/* It's too expensive to do a full				 * dirent test each time round this				 * loop, but we do have to test at				 * least that it is non-zero.  A				 * failure will be detected in the				 * dirent test below. */				if (de->d_reclen < 1)					break;				i += de->d_reclen;			}			offset = i;			filp->f_pos = (filp->f_pos & ~(sb->s_blocksize - 1))				| offset;			filp->f_version = inode->i_version;		}				while (!error && filp->f_pos < inode->i_size 		       && offset < sb->s_blocksize) {			de = (struct ufs_direct *) (bh->b_data + offset);	                /* XXX - put in a real ufs_check_dir_entry() */	                if ((de->d_reclen == 0) || (de->d_namlen == 0)) {	                        filp->f_pos = (filp->f_pos & (sb->s_blocksize - 1)) + sb->s_blocksize;	                        brelse(bh);	                        return stored;	                }#if 0			if (!ext2_check_dir_entry ("ext2_readdir", inode, de,						   bh, offset)) {				/* On error, skip the f_pos to the	                           next block. */				filp->f_pos = (filp->f_pos & (sb->s_blocksize - 1))					      + sb->s_blocksize;				brelse (bh);				return stored;			}#endif /* XXX */			offset += de->d_reclen;			if (de->d_ino) {				/* We might block in the next section				 * if the data destination is				 * currently swapped out.  So, use a				 * version stamp to detect whether or				 * not the directory has been modified				 * during the copy operation. */				unsigned long version;				dcache_add(inode, de->d_name, de->d_namlen,	                                   de->d_ino);				version = inode->i_version;	                        if (inode->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) {	                                printk("ufs_readdir: filldir(%s,%u)\n",	                                       de->d_name, de->d_ino);	                        }				error = filldir(dirent, de->d_name, de->d_namlen, filp->f_pos, de->d_ino);				if (error)					break;				if (version != inode->i_version)					goto revalidate;				stored ++;			}			filp->f_pos += de->d_reclen;		}		offset = 0;		brelse (bh);	}#if 0 /* XXX */	if (!IS_RDONLY(inode)) {		inode->i_atime = CURRENT_TIME;		inode->i_dirt = 1;	}#endif /* XXX */	return 0;}static struct file_operations ufs_dir_operations = {	NULL,			/* lseek */	NULL,			/* read */	NULL,			/* write */	ufs_readdir,		/* readdir */	NULL,			/* select */	NULL,			/* ioctl */	NULL,			/* mmap */	NULL,			/* open */	NULL,			/* release */	file_fsync,		/* fsync */	NULL,			/* fasync */	NULL,			/* check_media_change */	NULL,			/* revalidate */};struct inode_operations ufs_dir_inode_operations = {	&ufs_dir_operations,	/* default directory file operations */	NULL,			/* create */	ufs_lookup,		/* lookup */	NULL,			/* link */	NULL,			/* unlink */	NULL,			/* symlink */	NULL,			/* mkdir */	NULL,			/* rmdir */	NULL,			/* mknod */	NULL,			/* rename */	NULL,			/* readlink */	NULL,			/* follow_link */	NULL,			/* readpage */	NULL,			/* writepage */	NULL,			/* bmap */	NULL,			/* truncate */	NULL,			/* permission */	NULL,			/* smap */};/* * Local Variables: *** * c-indent-level: 8 *** * c-continued-statement-offset: 8 *** * c-brace-offset: -8 *** * c-argdecl-indent: 0 *** * c-label-offset: -8 *** * End: *** */

⌨️ 快捷键说明

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