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

📄 dir.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (a->len != b->len)		goto out;	for (i=0; i < a->len; i++) {		if (tolower(a->name[i]) != tolower(b->name[i]))			goto out;	}	result = 0;out:	return result;}/* * This is the callback from dput() when d_count is going to 0. * We use this to unhash dentries with bad inodes. */static intsmb_delete_dentry(struct dentry * dentry){	if (dentry->d_inode) {		if (is_bad_inode(dentry->d_inode)) {			PARANOIA("bad inode, unhashing %s/%s\n",				 DENTRY_PATH(dentry));			return 1;		}	} else {		/* N.B. Unhash negative dentries? */	}	return 0;}/* * Initialize a new dentry */voidsmb_new_dentry(struct dentry *dentry){	struct smb_sb_info *server = server_from_dentry(dentry);	if (server->mnt->flags & SMB_MOUNT_CASE)		dentry->d_op = &smbfs_dentry_operations_case;	else		dentry->d_op = &smbfs_dentry_operations;	dentry->d_time = jiffies;}/* * Whenever a lookup succeeds, we know the parent directories * are all valid, so we want to update the dentry timestamps. * N.B. Move this to dcache? */voidsmb_renew_times(struct dentry * dentry){	dget(dentry);	spin_lock(&dentry->d_lock);	for (;;) {		struct dentry *parent;		dentry->d_time = jiffies;		if (IS_ROOT(dentry))			break;		parent = dentry->d_parent;		dget(parent);		spin_unlock(&dentry->d_lock);		dput(dentry);		dentry = parent;		spin_lock(&dentry->d_lock);	}	spin_unlock(&dentry->d_lock);	dput(dentry);}static struct dentry *smb_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){	struct smb_fattr finfo;	struct inode *inode;	int error;	struct smb_sb_info *server;	error = -ENAMETOOLONG;	if (dentry->d_name.len > SMB_MAXNAMELEN)		goto out;	/* Do not allow lookup of names with backslashes in */	error = -EINVAL;	if (memchr(dentry->d_name.name, '\\', dentry->d_name.len))		goto out;	lock_kernel();	error = smb_proc_getattr(dentry, &finfo);#ifdef SMBFS_PARANOIA	if (error && error != -ENOENT)		PARANOIA("find %s/%s failed, error=%d\n",			 DENTRY_PATH(dentry), error);#endif	inode = NULL;	if (error == -ENOENT)		goto add_entry;	if (!error) {		error = -EACCES;		finfo.f_ino = iunique(dentry->d_sb, 2);		inode = smb_iget(dir->i_sb, &finfo);		if (inode) {	add_entry:			server = server_from_dentry(dentry);			if (server->mnt->flags & SMB_MOUNT_CASE)				dentry->d_op = &smbfs_dentry_operations_case;			else				dentry->d_op = &smbfs_dentry_operations;			d_add(dentry, inode);			smb_renew_times(dentry);			error = 0;		}	}	unlock_kernel();out:	return ERR_PTR(error);}/* * This code is common to all routines creating a new inode. */static intsmb_instantiate(struct dentry *dentry, __u16 fileid, int have_id){	struct smb_sb_info *server = server_from_dentry(dentry);	struct inode *inode;	int error;	struct smb_fattr fattr;	VERBOSE("file %s/%s, fileid=%u\n", DENTRY_PATH(dentry), fileid);	error = smb_proc_getattr(dentry, &fattr);	if (error)		goto out_close;	smb_renew_times(dentry);	fattr.f_ino = iunique(dentry->d_sb, 2);	inode = smb_iget(dentry->d_sb, &fattr);	if (!inode)		goto out_no_inode;	if (have_id) {		struct smb_inode_info *ei = SMB_I(inode);		ei->fileid = fileid;		ei->access = SMB_O_RDWR;		ei->open = server->generation;	}	d_instantiate(dentry, inode);out:	return error;out_no_inode:	error = -EACCES;out_close:	if (have_id) {		PARANOIA("%s/%s failed, error=%d, closing %u\n",			 DENTRY_PATH(dentry), error, fileid);		smb_close_fileid(dentry, fileid);	}	goto out;}/* N.B. How should the mode argument be used? */static intsmb_create(struct inode *dir, struct dentry *dentry, int mode,		struct nameidata *nd){	struct smb_sb_info *server = server_from_dentry(dentry);	__u16 fileid;	int error;	struct iattr attr;	VERBOSE("creating %s/%s, mode=%d\n", DENTRY_PATH(dentry), mode);	lock_kernel();	smb_invalid_dir_cache(dir);	error = smb_proc_create(dentry, 0, get_seconds(), &fileid);	if (!error) {		if (server->opt.capabilities & SMB_CAP_UNIX) {			/* Set attributes for new file */			attr.ia_valid = ATTR_MODE;			attr.ia_mode = mode;			error = smb_proc_setattr_unix(dentry, &attr, 0, 0);		}		error = smb_instantiate(dentry, fileid, 1);	} else {		PARANOIA("%s/%s failed, error=%d\n",			 DENTRY_PATH(dentry), error);	}	unlock_kernel();	return error;}/* N.B. How should the mode argument be used? */static intsmb_mkdir(struct inode *dir, struct dentry *dentry, int mode){	struct smb_sb_info *server = server_from_dentry(dentry);	int error;	struct iattr attr;	lock_kernel();	smb_invalid_dir_cache(dir);	error = smb_proc_mkdir(dentry);	if (!error) {		if (server->opt.capabilities & SMB_CAP_UNIX) {			/* Set attributes for new directory */			attr.ia_valid = ATTR_MODE;			attr.ia_mode = mode;			error = smb_proc_setattr_unix(dentry, &attr, 0, 0);		}		error = smb_instantiate(dentry, 0, 0);	}	unlock_kernel();	return error;}static intsmb_rmdir(struct inode *dir, struct dentry *dentry){	struct inode *inode = dentry->d_inode;	int error;	/*	 * Close the directory if it's open.	 */	lock_kernel();	smb_close(inode);	/*	 * Check that nobody else is using the directory..	 */	error = -EBUSY;	if (!d_unhashed(dentry))		goto out;	smb_invalid_dir_cache(dir);	error = smb_proc_rmdir(dentry);out:	unlock_kernel();	return error;}static intsmb_unlink(struct inode *dir, struct dentry *dentry){	int error;	/*	 * Close the file if it's open.	 */	lock_kernel();	smb_close(dentry->d_inode);	smb_invalid_dir_cache(dir);	error = smb_proc_unlink(dentry);	if (!error)		smb_renew_times(dentry);	unlock_kernel();	return error;}static intsmb_rename(struct inode *old_dir, struct dentry *old_dentry,	   struct inode *new_dir, struct dentry *new_dentry){	int error;	/*	 * Close any open files, and check whether to delete the	 * target before attempting the rename.	 */	lock_kernel();	if (old_dentry->d_inode)		smb_close(old_dentry->d_inode);	if (new_dentry->d_inode) {		smb_close(new_dentry->d_inode);		error = smb_proc_unlink(new_dentry);		if (error) {			VERBOSE("unlink %s/%s, error=%d\n",				DENTRY_PATH(new_dentry), error);			goto out;		}		/* FIXME */		d_delete(new_dentry);	}	smb_invalid_dir_cache(old_dir);	smb_invalid_dir_cache(new_dir);	error = smb_proc_mv(old_dentry, new_dentry);	if (!error) {		smb_renew_times(old_dentry);		smb_renew_times(new_dentry);	}out:	unlock_kernel();	return error;}/* * FIXME: samba servers won't let you create device nodes unless uid/gid * matches the connection credentials (and we don't know which those are ...) */static intsmb_make_node(struct inode *dir, struct dentry *dentry, int mode, dev_t dev){	int error;	struct iattr attr;	attr.ia_valid = ATTR_MODE | ATTR_UID | ATTR_GID;	attr.ia_mode = mode;	attr.ia_uid = current->euid;	attr.ia_gid = current->egid;	if (!new_valid_dev(dev))		return -EINVAL;	smb_invalid_dir_cache(dir);	error = smb_proc_setattr_unix(dentry, &attr, MAJOR(dev), MINOR(dev));	if (!error) {		error = smb_instantiate(dentry, 0, 0);	}	return error;}/* * dentry = existing file * new_dentry = new file */static intsmb_link(struct dentry *dentry, struct inode *dir, struct dentry *new_dentry){	int error;	DEBUG1("smb_link old=%s/%s new=%s/%s\n",	       DENTRY_PATH(dentry), DENTRY_PATH(new_dentry));	smb_invalid_dir_cache(dir);	error = smb_proc_link(server_from_dentry(dentry), dentry, new_dentry);	if (!error) {		smb_renew_times(dentry);		error = smb_instantiate(new_dentry, 0, 0);	}	return error;}

⌨️ 快捷键说明

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