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

📄 inode.c

📁 嵌入式系统设计与实验教材二源码linux内核移植与编译
💻 C
📖 第 1 页 / 共 3 页
字号:
		rpc_shutdown_client(server->client);		goto nfsv3_try_again;	}	if (!root_inode)		goto out_no_root;	sb->s_root = d_alloc_root(root_inode);	if (!sb->s_root)		goto out_no_root;	sb->s_root->d_op = &nfs_dentry_operations;	/* Get some general file system info */        if (server->rpc_ops->statfs(server, root, &fsinfo) >= 0) {		if (server->namelen == 0)			server->namelen = fsinfo.namelen;	} else {		printk(KERN_NOTICE "NFS: cannot retrieve file system info.\n");		goto out_no_root;        }	/* Work out a lot of parameters */	if (data->rsize == 0)		server->rsize = nfs_block_size(fsinfo.rtpref, NULL);	if (data->wsize == 0)		server->wsize = nfs_block_size(fsinfo.wtpref, NULL);	/* NFSv3: we don't have bsize, but rather rtmult and wtmult... */	if (!fsinfo.bsize)		fsinfo.bsize = (fsinfo.rtmult>fsinfo.wtmult) ? fsinfo.rtmult : fsinfo.wtmult;	/* Also make sure we don't go below rsize/wsize since	 * RPC calls are expensive */	if (fsinfo.bsize < server->rsize)		fsinfo.bsize = server->rsize;	if (fsinfo.bsize < server->wsize)		fsinfo.bsize = server->wsize;	if (data->bsize == 0)		sb->s_blocksize = nfs_block_bits(fsinfo.bsize, &sb->s_blocksize_bits);	if (server->rsize > fsinfo.rtmax)		server->rsize = fsinfo.rtmax;	if (server->wsize > fsinfo.wtmax)		server->wsize = fsinfo.wtmax;	server->rpages = (server->rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;	if (server->rpages > NFS_READ_MAXIOV) {		server->rpages = NFS_READ_MAXIOV;		server->rsize = server->rpages << PAGE_CACHE_SHIFT;	}	server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;        if (server->wpages > NFS_WRITE_MAXIOV) {		server->wpages = NFS_WRITE_MAXIOV;                server->wsize = server->wpages << PAGE_CACHE_SHIFT;	}	server->dtsize = nfs_block_size(fsinfo.dtpref, NULL);	if (server->dtsize > PAGE_CACHE_SIZE)		server->dtsize = PAGE_CACHE_SIZE;	if (server->dtsize > server->rsize)		server->dtsize = server->rsize;        maxlen = (version == 2) ? NFS2_MAXNAMLEN : NFS3_MAXNAMLEN;        if (server->namelen == 0 || server->namelen > maxlen)                server->namelen = maxlen;	sb->s_maxbytes = fsinfo.maxfilesize;	/* Fire up the writeback cache */	if (nfs_reqlist_alloc(server) < 0) {		printk(KERN_NOTICE "NFS: cannot initialize writeback cache.\n");		goto failure_kill_reqlist;	}	/* We're airborne */	/* Check whether to start the lockd process */	if (!(server->flags & NFS_MOUNT_NONLM))		lockd_up();	return sb;	/* Yargs. It didn't work out. */ failure_kill_reqlist:	nfs_reqlist_exit(server);out_no_root:	printk("nfs_read_super: get root inode failed\n");	iput(root_inode);	rpciod_down();	goto out_shutdown;out_no_iod:	printk(KERN_WARNING "NFS: couldn't start rpciod!\n");out_shutdown:	rpc_shutdown_client(server->client);	goto out_free_host;out_no_client:	printk(KERN_WARNING "NFS: cannot create RPC client.\n");	xprt_destroy(xprt);	goto out_free_host;out_no_xprt:	printk(KERN_WARNING "NFS: cannot create RPC transport.\n");out_free_host:	nfs_reqlist_free(server);	kfree(server->hostname);out_unlock:	goto out_fail;out_no_remote:	printk("NFS: mount program didn't pass remote address!\n");	goto out_fail;out_miss_args:	printk("nfs_read_super: missing data argument\n");out_fail:	return NULL;}static intnfs_statfs(struct super_block *sb, struct statfs *buf){	struct nfs_server *server = &sb->u.nfs_sb.s_server;	unsigned char blockbits;	unsigned long blockres;	struct nfs_fsinfo res;	int error;	error = server->rpc_ops->statfs(server, NFS_FH(sb->s_root->d_inode), &res);	buf->f_type = NFS_SUPER_MAGIC;	if (error < 0)		goto out_err;	if (res.bsize == 0)		res.bsize = sb->s_blocksize;	buf->f_bsize = nfs_block_bits(res.bsize, &blockbits);	blockres = (1 << blockbits) - 1;	buf->f_blocks = (res.tbytes + blockres) >> blockbits;	buf->f_bfree = (res.fbytes + blockres) >> blockbits;	buf->f_bavail = (res.abytes + blockres) >> blockbits;	buf->f_files = res.tfiles;	buf->f_ffree = res.afiles;	if (res.namelen == 0 || res.namelen > server->namelen)		res.namelen = server->namelen;	buf->f_namelen = res.namelen;	return 0; out_err:	printk("nfs_statfs: statfs error = %d\n", -error);	buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1;	return 0;}static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt){	static struct proc_nfs_info {		int flag;		char *str;		char *nostr;	} nfs_info[] = {		{ NFS_MOUNT_SOFT, ",soft", ",hard" },		{ NFS_MOUNT_INTR, ",intr", "" },		{ NFS_MOUNT_POSIX, ",posix", "" },		{ NFS_MOUNT_TCP, ",tcp", ",udp" },		{ NFS_MOUNT_NOCTO, ",nocto", "" },		{ NFS_MOUNT_NOAC, ",noac", "" },		{ NFS_MOUNT_NONLM, ",nolock", ",lock" },		{ NFS_MOUNT_BROKEN_SUID, ",broken_suid", "" },		{ 0, NULL, NULL }	};	struct proc_nfs_info *nfs_infop;	struct nfs_server *nfss = &mnt->mnt_sb->u.nfs_sb.s_server;	seq_printf(m, ",v%d", nfss->rpc_ops->version);	seq_printf(m, ",rsize=%d", nfss->rsize);	seq_printf(m, ",wsize=%d", nfss->wsize);	if (nfss->acregmin != 3*HZ)		seq_printf(m, ",acregmin=%d", nfss->acregmin/HZ);	if (nfss->acregmax != 60*HZ)		seq_printf(m, ",acregmax=%d", nfss->acregmax/HZ);	if (nfss->acdirmin != 30*HZ)		seq_printf(m, ",acdirmin=%d", nfss->acdirmin/HZ);	if (nfss->acdirmax != 60*HZ)		seq_printf(m, ",acdirmax=%d", nfss->acdirmax/HZ);	for (nfs_infop = nfs_info; nfs_infop->flag; nfs_infop++) {		if (nfss->flags & nfs_infop->flag)			seq_puts(m, nfs_infop->str);		else			seq_puts(m, nfs_infop->nostr);	}	seq_puts(m, ",addr=");	seq_escape(m, nfss->hostname, " \t\n\\");	return 0;}/* * Invalidate the local caches */voidnfs_zap_caches(struct inode *inode){	NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode);	NFS_ATTRTIMEO_UPDATE(inode) = jiffies;	invalidate_inode_pages(inode);	memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode)));	NFS_CACHEINV(inode);}/* * Invalidate, but do not unhash, the inode */static voidnfs_invalidate_inode(struct inode *inode){	umode_t save_mode = inode->i_mode;	make_bad_inode(inode);	inode->i_mode = save_mode;	nfs_zap_caches(inode);}/* * Fill in inode information from the fattr. */static voidnfs_fill_inode(struct inode *inode, struct nfs_fh *fh, struct nfs_fattr *fattr){	/*	 * Check whether the mode has been set, as we only want to	 * do this once. (We don't allow inodes to change types.)	 */	if (inode->i_mode == 0) {		NFS_FILEID(inode) = fattr->fileid;		NFS_FSID(inode) = fattr->fsid;		inode->i_mode = fattr->mode;		/* Why so? Because we want revalidate for devices/FIFOs, and		 * that's precisely what we have in nfs_file_inode_operations.		 */		inode->i_op = &nfs_file_inode_operations;		if (S_ISREG(inode->i_mode)) {			inode->i_fop = &nfs_file_operations;			inode->i_data.a_ops = &nfs_file_aops;		} else if (S_ISDIR(inode->i_mode)) {			inode->i_op = &nfs_dir_inode_operations;			inode->i_fop = &nfs_dir_operations;		} else if (S_ISLNK(inode->i_mode))			inode->i_op = &nfs_symlink_inode_operations;		else			init_special_inode(inode, inode->i_mode, fattr->rdev);		memcpy(&inode->u.nfs_i.fh, fh, sizeof(inode->u.nfs_i.fh));	}	nfs_refresh_inode(inode, fattr);}struct nfs_find_desc {	struct nfs_fh		*fh;	struct nfs_fattr	*fattr;};/* * In NFSv3 we can have 64bit inode numbers. In order to support * this, and re-exported directories (also seen in NFSv2) * we are forced to allow 2 different inodes to have the same * i_ino. */static intnfs_find_actor(struct inode *inode, unsigned long ino, void *opaque){	struct nfs_find_desc	*desc = (struct nfs_find_desc *)opaque;	struct nfs_fh		*fh = desc->fh;	struct nfs_fattr	*fattr = desc->fattr;	if (NFS_FSID(inode) != fattr->fsid)		return 0;	if (NFS_FILEID(inode) != fattr->fileid)		return 0;	if (memcmp(&inode->u.nfs_i.fh, fh, sizeof(inode->u.nfs_i.fh)) != 0)		return 0;	/* Force an attribute cache update if inode->i_count == 0 */	if (!atomic_read(&inode->i_count))		NFS_CACHEINV(inode);	return 1;}intnfs_inode_is_stale(struct inode *inode, struct nfs_fh *fh, struct nfs_fattr *fattr){	/* Empty inodes are not stale */	if (!inode->i_mode)		return 0;	if ((fattr->mode & S_IFMT) != (inode->i_mode & S_IFMT))		return 1;	if (is_bad_inode(inode) || NFS_STALE(inode))		return 1;	/* Has the filehandle changed? If so is the old one stale? */	if (memcmp(&inode->u.nfs_i.fh, fh, sizeof(inode->u.nfs_i.fh)) != 0 &&	    __nfs_revalidate_inode(NFS_SERVER(inode),inode) == -ESTALE)		return 1;	return 0;}/* * 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. * */struct inode *nfs_fhget(struct dentry *dentry, struct nfs_fh *fhandle,				 struct nfs_fattr *fattr){	struct super_block *sb = dentry->d_sb;	dprintk("NFS: nfs_fhget(%s/%s fileid=%Ld)\n",		dentry->d_parent->d_name.name, dentry->d_name.name,		(long long)fattr->fileid);	return __nfs_fhget(sb, fhandle, fattr);}/* * Look up the inode by super block and fattr->fileid. */static struct inode *__nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr){	struct nfs_find_desc desc = { fh, fattr };	struct inode *inode = NULL;	unsigned long ino;	if ((fattr->valid & NFS_ATTR_FATTR) == 0)		goto out_no_inode;	if (!fattr->nlink) {		printk("NFS: Buggy server - nlink == 0!\n");		goto out_no_inode;	}	ino = nfs_fattr_to_ino_t(fattr);	if (!(inode = iget4(sb, ino, nfs_find_actor, &desc)))		goto out_no_inode;	nfs_fill_inode(inode, fh, fattr);	dprintk("NFS: __nfs_fhget(%x/%Ld ct=%d)\n",		inode->i_dev, (long long)NFS_FILEID(inode),		atomic_read(&inode->i_count));out:	return inode;out_no_inode:	printk("__nfs_fhget: iget failed\n");	goto out;}intnfs_notify_change(struct dentry *dentry, struct iattr *attr){	struct inode *inode = dentry->d_inode;	struct nfs_fattr fattr;	int error;	/*	 * Make sure the inode is up-to-date.	 */	error = nfs_revalidate(dentry);	if (error) {#ifdef NFS_PARANOIAprintk("nfs_notify_change: revalidate failed, error=%d\n", error);#endif		goto out;	}	if (!S_ISREG(inode->i_mode))		attr->ia_valid &= ~ATTR_SIZE;	filemap_fdatasync(inode->i_mapping);	error = nfs_wb_all(inode);	filemap_fdatawait(inode->i_mapping);	if (error)		goto out;	error = NFS_PROTO(inode)->setattr(inode, &fattr, attr);	if (error)		goto out;	/*	 * If we changed the size or mtime, update the inode	 * now to avoid invalidating the page cache.	 */	if (attr->ia_valid & ATTR_SIZE) {

⌨️ 快捷键说明

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