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

📄 inode.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  inode.c * *  Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke *  Copyright (C) 1997 by Volker Lendecke * *  Please add a note about your changes to smbfs in the ChangeLog file. */#include <linux/config.h>#include <linux/module.h>#include <linux/sched.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/slab.h>#include <linux/init.h>#include <linux/file.h>#include <linux/dcache.h>#include <linux/smp_lock.h>#include <linux/nls.h>#include <linux/seq_file.h>#include <linux/smb_fs.h>#include <linux/smbno.h>#include <linux/smb_mount.h>#include <asm/system.h>#include <asm/uaccess.h>#include "smb_debug.h"#include "getopt.h"#include "proto.h"/* Always pick a default string */#ifdef CONFIG_SMB_NLS_REMOTE#define SMB_NLS_REMOTE CONFIG_SMB_NLS_REMOTE#else#define SMB_NLS_REMOTE ""#endif#define SMB_TTL_DEFAULT 1000static void smb_delete_inode(struct inode *);static void smb_put_super(struct super_block *);static int  smb_statfs(struct super_block *, struct statfs *);static int  smb_show_options(struct seq_file *, struct vfsmount *);static struct super_operations smb_sops ={	put_inode:	force_delete,	delete_inode:	smb_delete_inode,	put_super:	smb_put_super,	statfs:		smb_statfs,	show_options:	smb_show_options,};/* We are always generating a new inode here */struct inode *smb_iget(struct super_block *sb, struct smb_fattr *fattr){	struct inode *result;	DEBUG1("smb_iget: %p\n", fattr);	result = new_inode(sb);	if (!result)		return result;	result->i_ino = fattr->f_ino;	memset(&(result->u.smbfs_i), 0, sizeof(result->u.smbfs_i));	smb_set_inode_attr(result, fattr);	if (S_ISREG(result->i_mode)) {		result->i_op = &smb_file_inode_operations;		result->i_fop = &smb_file_operations;		result->i_data.a_ops = &smb_file_aops;	} else if (S_ISDIR(result->i_mode)) {		result->i_op = &smb_dir_inode_operations;		result->i_fop = &smb_dir_operations;	}	insert_inode_hash(result);	return result;}/* * Copy the inode data to a smb_fattr structure. */voidsmb_get_inode_attr(struct inode *inode, struct smb_fattr *fattr){	memset(fattr, 0, sizeof(struct smb_fattr));	fattr->f_mode	= inode->i_mode;	fattr->f_nlink	= inode->i_nlink;	fattr->f_ino	= inode->i_ino;	fattr->f_uid	= inode->i_uid;	fattr->f_gid	= inode->i_gid;	fattr->f_rdev	= inode->i_rdev;	fattr->f_size	= inode->i_size;	fattr->f_mtime	= inode->i_mtime;	fattr->f_ctime	= inode->i_ctime;	fattr->f_atime	= inode->i_atime;	fattr->f_blksize= inode->i_blksize;	fattr->f_blocks	= inode->i_blocks;	fattr->attr	= inode->u.smbfs_i.attr;	/*	 * Keep the attributes in sync with the inode permissions.	 */	if (fattr->f_mode & S_IWUSR)		fattr->attr &= ~aRONLY;	else		fattr->attr |= aRONLY;}/* * Update the inode, possibly causing it to invalidate its pages if mtime/size * is different from last time. */voidsmb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr){	/*	 * A size change should have a different mtime, or same mtime	 * but different size.	 */	time_t last_time = inode->i_mtime;	loff_t last_sz = inode->i_size;	inode->i_mode	= fattr->f_mode;	inode->i_nlink	= fattr->f_nlink;	inode->i_uid	= fattr->f_uid;	inode->i_gid	= fattr->f_gid;	inode->i_rdev	= fattr->f_rdev;	inode->i_ctime	= fattr->f_ctime;	inode->i_blksize= fattr->f_blksize;	inode->i_blocks = fattr->f_blocks;	inode->i_size	= fattr->f_size;	inode->i_mtime	= fattr->f_mtime;	inode->i_atime	= fattr->f_atime;	inode->u.smbfs_i.attr = fattr->attr;	/*	 * Update the "last time refreshed" field for revalidation.	 */	inode->u.smbfs_i.oldmtime = jiffies;	if (inode->i_mtime != last_time || inode->i_size != last_sz) {		VERBOSE("%ld changed, old=%ld, new=%ld, oz=%ld, nz=%ld\n",			inode->i_ino,			(long) last_time, (long) inode->i_mtime,			(long) last_sz, (long) inode->i_size);		if (!S_ISDIR(inode->i_mode))			invalidate_inode_pages(inode);	}}/* * This is called if the connection has gone bad ... * try to kill off all the current inodes. */voidsmb_invalidate_inodes(struct smb_sb_info *server){	VERBOSE("\n");	shrink_dcache_sb(SB_of(server));	invalidate_inodes(SB_of(server));}/* * This is called to update the inode attributes after * we've made changes to a file or directory. */static intsmb_refresh_inode(struct dentry *dentry){	struct inode *inode = dentry->d_inode;	int error;	struct smb_fattr fattr;	error = smb_proc_getattr(dentry, &fattr);	if (!error) {		smb_renew_times(dentry);		/*		 * Check whether the type part of the mode changed,		 * and don't update the attributes if it did.		 */		if ((inode->i_mode & S_IFMT) == (fattr.f_mode & S_IFMT)) {			smb_set_inode_attr(inode, &fattr);		} else {			/*			 * Big trouble! The inode has become a new object,			 * so any operations attempted on it are invalid.			 *			 * To limit damage, mark the inode as bad so that			 * subsequent lookup validations will fail.			 */			PARANOIA("%s/%s changed mode, %07o to %07o\n",				 DENTRY_PATH(dentry),				 inode->i_mode, fattr.f_mode);			fattr.f_mode = inode->i_mode; /* save mode */			make_bad_inode(inode);			inode->i_mode = fattr.f_mode; /* restore mode */			/*			 * No need to worry about unhashing the dentry: the			 * lookup validation will see that the inode is bad.			 * But we do want to invalidate the caches ...			 */			if (!S_ISDIR(inode->i_mode))				invalidate_inode_pages(inode);			else				smb_invalid_dir_cache(inode);			error = -EIO;		}	}	return error;}/* * This is called when we want to check whether the inode * has changed on the server.  If it has changed, we must * invalidate our local caches. */intsmb_revalidate_inode(struct dentry *dentry){	struct smb_sb_info *s = server_from_dentry(dentry);	struct inode *inode = dentry->d_inode;	int error = 0;	DEBUG1("smb_revalidate_inode\n");	lock_kernel();	/*	 * Check whether we've recently refreshed the inode.	 */	if (time_before(jiffies, inode->u.smbfs_i.oldmtime + SMB_MAX_AGE(s))) {		VERBOSE("up-to-date, ino=%ld, jiffies=%lu, oldtime=%lu\n",			inode->i_ino, jiffies, inode->u.smbfs_i.oldmtime);		goto out;	}	error = smb_refresh_inode(dentry);out:	unlock_kernel();	return error;}/* * This routine is called when i_nlink == 0 and i_count goes to 0. * All blocking cleanup operations need to go here to avoid races. */static voidsmb_delete_inode(struct inode *ino){	DEBUG1("ino=%ld\n", ino->i_ino);	lock_kernel();	if (smb_close(ino))		PARANOIA("could not close inode %ld\n", ino->i_ino);	unlock_kernel();	clear_inode(ino);}static struct option opts[] = {	{ "version",	0, 'v' },	{ "win95",	SMB_MOUNT_WIN95, 1 },	{ "oldattr",	SMB_MOUNT_OLDATTR, 1 },	{ "dirattr",	SMB_MOUNT_DIRATTR, 1 },	{ "case",	SMB_MOUNT_CASE, 1 },	{ "uid",	0, 'u' },	{ "gid",	0, 'g' },	{ "file_mode",	0, 'f' },	{ "dir_mode",	0, 'd' },	{ "iocharset",	0, 'i' },	{ "codepage",	0, 'c' },	{ "ttl",	0, 't' },	{ NULL,		0, 0}};static intparse_options(struct smb_mount_data_kernel *mnt, char *options){	int c;	unsigned long flags;	unsigned long value;	char *optarg;	char *optopt;	flags = 0;	while ( (c = smb_getopt("smbfs", &options, opts,				&optopt, &optarg, &flags, &value)) > 0) {		VERBOSE("'%s' -> '%s'\n", optopt, optarg ? optarg : "<none>");		switch (c) {		case 1:			/* got a "flag" option */			break;		case 'v':			if (value != SMB_MOUNT_VERSION) {			printk ("smbfs: Bad mount version %ld, expected %d\n",				value, SMB_MOUNT_VERSION);				return 0;			}			mnt->version = value;			break;		case 'u':			mnt->uid = value;			break;		case 'g':			mnt->gid = value;			break;		case 'f':			mnt->file_mode = (value & S_IRWXUGO) | S_IFREG;			break;		case 'd':			mnt->dir_mode = (value & S_IRWXUGO) | S_IFDIR;			break;		case 'i':			strncpy(mnt->codepage.local_name, optarg, 				SMB_NLS_MAXNAMELEN);			break;		case 'c':			strncpy(mnt->codepage.remote_name, optarg,				SMB_NLS_MAXNAMELEN);			break;		case 't':			mnt->ttl = value;			break;		default:			printk ("smbfs: Unrecognized mount option %s\n",				optopt);			return -1;		}	}	mnt->flags = flags;	return c;}/* * smb_show_options() is for displaying mount options in /proc/mounts.

⌨️ 快捷键说明

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