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

📄 inode.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
字号:
/* *  linux/fs/nfs/inode.c * *  Copyright (C) 1992  Rick Sladkey * *  nfs inode and superblock handling functions * *  Modularised by Alan Cox <Alan.Cox@linux.org>, while hacking some *  experimental NFS changes. Modularisation taken straight from SYS5 fs. * *  Change to nfs_read_super() to permit NFS mounts to multi-homed hosts. *  J.S.Peatfield@damtp.cam.ac.uk * */#include <linux/module.h>#include <linux/sched.h>#include <linux/nfs_fs.h>#include <linux/nfsiod.h>#include <linux/kernel.h>#include <linux/mm.h>#include <linux/string.h>#include <linux/stat.h>#include <linux/errno.h>#include <linux/locks.h>#include <linux/smp.h>#include <linux/smp_lock.h>#include <asm/system.h>#include <asm/segment.h>/* This is for kernel_thread */#define __KERNEL_SYSCALLS__#include <linux/unistd.h>extern int close_fp(struct file *filp);static int nfs_notify_change(struct inode *, struct iattr *);static void nfs_put_inode(struct inode *);static void nfs_put_super(struct super_block *);static void nfs_read_inode(struct inode *);static void nfs_statfs(struct super_block *, struct statfs *, int bufsiz);static struct super_operations nfs_sops = { 	nfs_read_inode,		/* read inode */	nfs_notify_change,	/* notify change */	NULL,			/* write inode */	nfs_put_inode,		/* put inode */	nfs_put_super,		/* put superblock */	NULL,			/* write superblock */	nfs_statfs,		/* stat filesystem */	NULL};/* * The "read_inode" function doesn't actually do anything: * the real data is filled in later in nfs_fhget. Here we * just mark the cache times invalid, and zero out i_mode * (the latter makes "nfs_refresh_inode" do the right thing * wrt pipe inodes) */static void nfs_read_inode(struct inode * inode){	int rsize = inode->i_sb->u.nfs_sb.s_server.rsize;	int size = inode->i_sb->u.nfs_sb.s_server.wsize;	if (rsize > size)		size = rsize;	inode->i_blksize = size;	inode->i_mode = 0;	inode->i_op = NULL;	NFS_CACHEINV(inode);}static void nfs_put_inode(struct inode * inode){	if (NFS_RENAMED_DIR(inode))		nfs_sillyrename_cleanup(inode);	if (inode->i_pipe)		clear_inode(inode);}void nfs_put_super(struct super_block *sb){	close_fp(sb->u.nfs_sb.s_server.file);	rpc_closesock(sb->u.nfs_sb.s_server.rsock);	lock_super(sb);	sb->s_dev = 0;	unlock_super(sb);	MOD_DEC_USE_COUNT;}/* * The way this works is that the mount process passes a structure * in the data argument which contains an open socket to the NFS * server and the root file handle obtained from the server's mount * daemon.  We stash these away in the private superblock fields. * Later we can add other mount parameters like caching values. */struct super_block *nfs_read_super(struct super_block *sb, void *raw_data,				   int silent){	struct nfs_mount_data *data = (struct nfs_mount_data *) raw_data;	struct nfs_server *server;	unsigned int fd;	struct file *filp;	kdev_t dev = sb->s_dev;	MOD_INC_USE_COUNT;	if (!data) {		printk("nfs_read_super: missing data argument\n");		sb->s_dev = 0;		MOD_DEC_USE_COUNT;		return NULL;	}	fd = data->fd;	if (data->version != NFS_MOUNT_VERSION) {		printk("nfs warning: mount version %s than kernel\n",			data->version < NFS_MOUNT_VERSION ? "older" : "newer");	}	if (fd >= NR_OPEN || !(filp = current->files->fd[fd])) {		printk("nfs_read_super: invalid file descriptor\n");		sb->s_dev = 0;		MOD_DEC_USE_COUNT;		return NULL;	}	if (!S_ISSOCK(filp->f_inode->i_mode)) {		printk("nfs_read_super: not a socket\n");		sb->s_dev = 0;		MOD_DEC_USE_COUNT;		return NULL;	}	filp->f_count++;	lock_super(sb);	sb->s_blocksize = 1024; /* XXX */	sb->s_blocksize_bits = 10;	sb->s_magic = NFS_SUPER_MAGIC;	sb->s_dev = dev;	sb->s_op = &nfs_sops;	server = &sb->u.nfs_sb.s_server;	server->file = filp;	server->lock = 0;	server->wait = NULL;	server->flags = data->flags;	server->rsize = data->rsize;	if (server->rsize <= 0)		server->rsize = NFS_DEF_FILE_IO_BUFFER_SIZE;	else if (server->rsize >= NFS_MAX_FILE_IO_BUFFER_SIZE)		server->rsize = NFS_MAX_FILE_IO_BUFFER_SIZE;	server->wsize = data->wsize;	if (server->wsize <= 0)		server->wsize = NFS_DEF_FILE_IO_BUFFER_SIZE;	else if (server->wsize >= NFS_MAX_FILE_IO_BUFFER_SIZE)		server->wsize = NFS_MAX_FILE_IO_BUFFER_SIZE;	server->timeo = data->timeo*HZ/10;	server->retrans = data->retrans;	server->acregmin = data->acregmin*HZ;	server->acregmax = data->acregmax*HZ;	server->acdirmin = data->acdirmin*HZ;	server->acdirmax = data->acdirmax*HZ;	strcpy(server->hostname, data->hostname);	/* Start of JSP NFS patch */	/* Check if passed address in data->addr */	if (data->addr.sin_addr.s_addr == INADDR_ANY) {  /* No address passed */	  if (((struct sockaddr_in *)(&server->toaddr))->sin_addr.s_addr == INADDR_ANY) {	    printk("NFS: Error passed unconnected socket and no address\n") ;	    MOD_DEC_USE_COUNT;	    return NULL ;	  } else {	    /* Need access to socket internals  JSP */	    struct socket *sock;	    int dummylen ;	 /*   printk("NFS: using socket address\n") ;*/	    sock = &((filp->f_inode)->u.socket_i);	    /* extract the other end of the socket into server->toaddr */	    sock->ops->getname(sock, &(server->toaddr), &dummylen, 1) ;	  }	} else {	/*  printk("NFS: copying passed addr to server->toaddr\n") ;*/	  memcpy((char *)&(server->toaddr),(char *)(&data->addr),sizeof(server->toaddr));	}	/* End of JSP NFS patch */	if ((server->rsock = rpc_makesock(filp)) == NULL) {		printk("NFS: cannot create RPC socket.\n");		MOD_DEC_USE_COUNT;		return NULL;	}	sb->u.nfs_sb.s_root = data->root;	unlock_super(sb);	if (!(sb->s_mounted = nfs_fhget(sb, &data->root, NULL))) {		sb->s_dev = 0;		printk("nfs_read_super: get root inode failed\n");		MOD_DEC_USE_COUNT;		return NULL;	}	return sb;}void nfs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz){	int error;	struct nfs_fsinfo res;	struct statfs tmp;	error = nfs_proc_statfs(&sb->u.nfs_sb.s_server, &sb->u.nfs_sb.s_root,		&res);	if (error) {		printk("nfs_statfs: statfs error = %d\n", -error);		res.bsize = res.blocks = res.bfree = res.bavail = 0;	}	tmp.f_type = NFS_SUPER_MAGIC;	tmp.f_bsize = res.bsize;	tmp.f_blocks = res.blocks;	tmp.f_bfree = res.bfree;	tmp.f_bavail = res.bavail;	tmp.f_files = 0;	tmp.f_ffree = 0;	tmp.f_namelen = NAME_MAX;	memcpy_tofs(buf, &tmp, bufsiz);}/* * This is our own version of iget that looks up inodes by file handle * instead of inode number.  We use this technique instead of using * the vfs read_inode function because there is no way to pass the * file handle or current attributes into the read_inode function. * We just have to be careful not to subvert iget's special handling * of mount points. */struct inode *nfs_fhget(struct super_block *sb, struct nfs_fh *fhandle,			struct nfs_fattr *fattr){	struct nfs_fattr newfattr;	int error;	struct inode *inode;	if (!sb) {		printk("nfs_fhget: super block is NULL\n");		return NULL;	}	if (!fattr) {		error = nfs_proc_getattr(&sb->u.nfs_sb.s_server, fhandle,			&newfattr);		if (error) {			printk("nfs_fhget: getattr error = %d\n", -error);			return NULL;		}		fattr = &newfattr;	}	if (!(inode = iget(sb, fattr->fileid))) {		printk("nfs_fhget: iget failed\n");		return NULL;	}	if (inode->i_dev == sb->s_dev) {		if (inode->i_ino != fattr->fileid) {			printk("nfs_fhget: unexpected inode from iget\n");			return inode;		}		*NFS_FH(inode) = *fhandle;		nfs_refresh_inode(inode, fattr);	}	return inode;}int nfs_notify_change(struct inode *inode, struct iattr *attr){	struct nfs_sattr sattr;	struct nfs_fattr fattr;	int error;	sattr.mode = (unsigned) -1;	if (attr->ia_valid & ATTR_MODE) 		sattr.mode = attr->ia_mode;	sattr.uid = (unsigned) -1;	if (attr->ia_valid & ATTR_UID)		sattr.uid = attr->ia_uid;	sattr.gid = (unsigned) -1;	if (attr->ia_valid & ATTR_GID)		sattr.gid = attr->ia_gid;	sattr.size = (unsigned) -1;	if (attr->ia_valid & ATTR_SIZE)		sattr.size = S_ISREG(inode->i_mode) ? attr->ia_size : -1;	sattr.mtime.seconds = sattr.mtime.useconds = (unsigned) -1;	if (attr->ia_valid & ATTR_MTIME) {		sattr.mtime.seconds = attr->ia_mtime;		sattr.mtime.useconds = 0;	}	sattr.atime.seconds = sattr.atime.useconds = (unsigned) -1;	if (attr->ia_valid & ATTR_ATIME) {		sattr.atime.seconds = attr->ia_atime;		sattr.atime.useconds = 0;	}	error = nfs_proc_setattr(NFS_SERVER(inode), NFS_FH(inode),		&sattr, &fattr);	if (!error)		nfs_refresh_inode(inode, &fattr);	inode->i_dirt = 0;	return error;}/* Every kernel module contains stuff like this. */static struct file_system_type nfs_fs_type = {	nfs_read_super, "nfs", 0, NULL};/* * Start up an nfsiod process. This is an awful hack, because when running * as a module, we will keep insmod's memory. Besides, the current->comm * hack won't work in this case * The best would be to have a syscall for nfs client control that (among * other things) forks biod's. * Alternatively, we might want to have the idle task spawn biod's on demand. */static int run_nfsiod(void *dummy){	int	ret;#ifdef __SMP__	lock_kernel();	syscall_count++;#endif	MOD_INC_USE_COUNT;	exit_mm(current);	current->session = 1;	current->pgrp = 1;	sprintf(current->comm, "nfsiod");	ret = nfsiod();	MOD_DEC_USE_COUNT;	return ret;}int init_nfs_fs(void){	/* Fork four biod's */#ifdef NO_MM	kernel_thread(run_nfsiod, NULL, CLONE_NO_WAIT);	kernel_thread(run_nfsiod, NULL, CLONE_NO_WAIT);	kernel_thread(run_nfsiod, NULL, CLONE_NO_WAIT);	kernel_thread(run_nfsiod, NULL, CLONE_NO_WAIT);#else	kernel_thread(run_nfsiod, NULL, 0);	kernel_thread(run_nfsiod, NULL, 0);	kernel_thread(run_nfsiod, NULL, 0);	kernel_thread(run_nfsiod, NULL, 0);#endif        return register_filesystem(&nfs_fs_type);}#ifdef MODULEint init_module(void){	int status;	if ((status = init_nfs_fs()) == 0)		register_symtab(0);	return status;}void cleanup_module(void){	unregister_filesystem(&nfs_fs_type);	nfs_kfree_cache();}#endif

⌨️ 快捷键说明

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