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

📄 inode.c

📁 介绍LINUX的文件系统,来自网络,是一篇阐述文件系统的好文章
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * ROMFS file system, Linux implementation * * Copyright (C) 1997-1999  Janos Farkas <chexum@shadow.banki.hu> * * Using parts of the minix filesystem * Copyright (C) 1991, 1992  Linus Torvalds * * and parts of the affs filesystem additionally * Copyright (C) 1993  Ray Burr * Copyright (C) 1996  Hans-Joachim Widmaier * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * * Changes *					Changed for 2.1.19 modules *	Jan 1997			Initial release *	Jun 1997			2.1.43+ changes *					Proper page locking in readpage *					Changed to work with 2.1.45+ fs *	Jul 1997			Fixed follow_link *			2.1.47 *					lookup shouldn't return -ENOENT *					from Horst von Brand: *					  fail on wrong checksum *					  double unlock_super was possible *					  correct namelen for statfs *					spotted by Bill Hawes: *					  readlink shouldn't iput() *	Jun 1998	2.1.106		from Avery Pennarun: glibc scandir() *					  exposed a problem in readdir *			2.1.107		code-freeze spellchecker run *	Aug 1998			2.1.118+ VFS changes *	Sep 1998	2.1.122		another VFS change (follow_link) *	Apr 1999	2.2.7		no more EBADF checking in *					  lookup/readdir, use ERR_PTR *	Jun 1999	2.3.6		d_alloc_root use changed *			2.3.9		clean up usage of ENOENT/negative *					  dentries in lookup *					clean up page flags setting *					  (error, uptodate, locking) in *					  in readpage *					use init_special_inode for *					  fifos/sockets (and streamline) in *					  read_inode, fix _ops table order *	Aug 1999	2.3.16		__initfunc() => __init change *	Oct 1999	2.3.24		page->owner hack obsoleted *	Nov 1999	2.3.27		2.3.25+ page->offset => index change *//* todo: *	- see Documentation/filesystems/romfs.txt *	- use allocated, not stack memory for file names? *	- considering write access... *	- network (tftp) files? *	- merge back some _op tables *//* * Sorry about some optimizations and for some goto's.  I just wanted * to squeeze some more bytes out of this code.. :) */#include <linux/module.h>#include <linux/types.h>#include <linux/errno.h>#include <linux/slab.h>#include <linux/romfs_fs.h>#include <linux/fs.h>#include <linux/locks.h>#include <linux/init.h>#include <linux/smp_lock.h>#include <asm/uaccess.h>static __s32romfs_checksum(void *data, int size){	__s32 sum, *ptr;	sum = 0; ptr = data;	size>>=2;	while (size>0) {		sum += ntohl(*ptr++);		size--;	}	return sum;}static struct super_operations romfs_ops;static struct super_block *romfs_read_super(struct super_block *s, void *data, int silent){	struct buffer_head *bh;	kdev_t dev = s->s_dev;	struct romfs_super_block *rsb;	int sz;	/* I would parse the options here, but there are none.. :) */	set_blocksize(dev, ROMBSIZE);	s->s_blocksize = ROMBSIZE;	s->s_blocksize_bits = ROMBSBITS;	s->u.generic_sbp = (void *) 0;	s->s_maxbytes = 0xFFFFFFFF;	bh = sb_bread(s, 0);	if (!bh) {		/* XXX merge with other printk? */                printk ("romfs: unable to read superblock\n");		goto outnobh;	}	rsb = (struct romfs_super_block *)bh->b_data;	sz = ntohl(rsb->size);	if (rsb->word0 != ROMSB_WORD0 || rsb->word1 != ROMSB_WORD1	   || sz < ROMFH_SIZE) {		if (!silent)			printk ("VFS: Can't find a romfs filesystem on dev "				"%s.\n", kdevname(dev));		goto out;	}	if (romfs_checksum(rsb, min_t(int, sz, 512))) {		printk ("romfs: bad initial checksum on dev "			"%s.\n", kdevname(dev));		goto out;	}	s->s_magic = ROMFS_MAGIC;	s->u.romfs_sb.s_maxsize = sz;	s->s_flags |= MS_RDONLY;	/* Find the start of the fs */	sz = (ROMFH_SIZE +	      strnlen(rsb->name, ROMFS_MAXFN) + 1 + ROMFH_PAD)	     & ROMFH_MASK;	brelse(bh);	s->s_op	= &romfs_ops;	s->s_root = d_alloc_root(iget(s, sz));	if (!s->s_root)		goto outnobh;	/* Ehrhm; sorry.. :)  And thanks to Hans-Joachim Widmaier  :) */	if (0) {out:		brelse(bh);outnobh:		s = NULL;	}	return s;}/* That's simple too. */static intromfs_statfs(struct super_block *sb, struct statfs *buf){	buf->f_type = ROMFS_MAGIC;	buf->f_bsize = ROMBSIZE;	buf->f_bfree = buf->f_bavail = buf->f_ffree;	buf->f_blocks = (sb->u.romfs_sb.s_maxsize+ROMBSIZE-1)>>ROMBSBITS;	buf->f_namelen = ROMFS_MAXFN;	return 0;}/* some helper routines */static intromfs_strnlen(struct inode *i, unsigned long offset, unsigned long count){	struct buffer_head *bh;	unsigned long avail, maxsize, res;	maxsize = i->i_sb->u.romfs_sb.s_maxsize;	if (offset >= maxsize)		return -1;	/* strnlen is almost always valid */	if (count > maxsize || offset+count > maxsize)		count = maxsize-offset;	bh = sb_bread(i->i_sb, offset>>ROMBSBITS);	if (!bh)		return -1;		/* error */	avail = ROMBSIZE - (offset & ROMBMASK);	maxsize = min_t(unsigned long, count, avail);	res = strnlen(((char *)bh->b_data)+(offset&ROMBMASK), maxsize);	brelse(bh);	if (res < maxsize)		return res;		/* found all of it */	while (res < count) {		offset += maxsize;		bh = sb_bread(i->i_sb, offset>>ROMBSBITS);		if (!bh)			return -1;		maxsize = min_t(unsigned long, count - res, ROMBSIZE);		avail = strnlen(bh->b_data, maxsize);		res += avail;		brelse(bh);		if (avail < maxsize)			return res;	}	return res;}static intromfs_copyfrom(struct inode *i, void *dest, unsigned long offset, unsigned long count){	struct buffer_head *bh;	unsigned long avail, maxsize, res;	maxsize = i->i_sb->u.romfs_sb.s_maxsize;	if (offset >= maxsize || count > maxsize || offset+count>maxsize)		return -1;	bh = sb_bread(i->i_sb, offset>>ROMBSBITS);	if (!bh)		return -1;		/* error */	avail = ROMBSIZE - (offset & ROMBMASK);	maxsize = min_t(unsigned long, count, avail);	memcpy(dest, ((char *)bh->b_data) + (offset & ROMBMASK), maxsize);	brelse(bh);	res = maxsize;			/* all of it */	while (res < count) {		offset += maxsize;		dest += maxsize;		bh = sb_bread(i->i_sb, offset>>ROMBSBITS);		if (!bh)			return -1;		maxsize = min_t(unsigned long, count - res, ROMBSIZE);		memcpy(dest, bh->b_data, maxsize);		brelse(bh);		res += maxsize;	}	return res;}static unsigned char romfs_dtype_table[] = {	DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_SOCK, DT_FIFO};static intromfs_readdir(struct file *filp, void *dirent, filldir_t filldir){	struct inode *i = filp->f_dentry->d_inode;	struct romfs_inode ri;	unsigned long offset, maxoff;	int j, ino, nextfh;	int stored = 0;	char fsname[ROMFS_MAXFN];	/* XXX dynamic? */	maxoff = i->i_sb->u.romfs_sb.s_maxsize;	offset = filp->f_pos;	if (!offset) {		offset = i->i_ino & ROMFH_MASK;		if (romfs_copyfrom(i, &ri, offset, ROMFH_SIZE) <= 0)			return stored;		offset = ntohl(ri.spec) & ROMFH_MASK;	}	/* Not really failsafe, but we are read-only... */	for(;;) {		if (!offset || offset >= maxoff) {			offset = maxoff;			filp->f_pos = offset;			return stored;		}		filp->f_pos = offset;		/* Fetch inode info */		if (romfs_copyfrom(i, &ri, offset, ROMFH_SIZE) <= 0)			return stored;		j = romfs_strnlen(i, offset+ROMFH_SIZE, sizeof(fsname)-1);		if (j < 0)			return stored;		fsname[j]=0;		romfs_copyfrom(i, fsname, offset+ROMFH_SIZE, j);		ino = offset;		nextfh = ntohl(ri.next);		if ((nextfh & ROMFH_TYPE) == ROMFH_HRD)			ino = ntohl(ri.spec);		if (filldir(dirent, fsname, j, offset, ino,			    romfs_dtype_table[nextfh & ROMFH_TYPE]) < 0) {			return stored;		}		stored++;		offset = nextfh & ROMFH_MASK;	}}static struct dentry *romfs_lookup(struct inode *dir, struct dentry *dentry){	unsigned long offset, maxoff;	int fslen, res;	struct inode *inode;	char fsname[ROMFS_MAXFN];	/* XXX dynamic? */	struct romfs_inode ri;

⌨️ 快捷键说明

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