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

📄 dir.c

📁 linux下的用户文件系统fuse-2.5.2
💻 C
📖 第 1 页 / 共 3 页
字号:
}#elsestatic int fuse_readlink(struct dentry *dentry, char __user *buffer,			 int buflen){	int ret;	char *link;	link = read_link(dentry);	ret = vfs_readlink(dentry, buffer, buflen, link);	free_link(link);	return ret;}static int fuse_follow_link(struct dentry *dentry, struct nameidata *nd){	int ret;	char *link;	link = read_link(dentry);	ret = vfs_follow_link(nd, link);	free_link(link);	return ret;}#endifstatic int fuse_dir_open(struct inode *inode, struct file *file){	return fuse_open_common(inode, file, 1);}static int fuse_dir_release(struct inode *inode, struct file *file){	return fuse_release_common(inode, file, 1);}static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync){	/* nfsd can call this with no file */	return file ? fuse_fsync_common(file, de, datasync, 1) : 0;}static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg){	unsigned ivalid = iattr->ia_valid;	if (ivalid & ATTR_MODE)		arg->valid |= FATTR_MODE,   arg->mode = iattr->ia_mode;	if (ivalid & ATTR_UID)		arg->valid |= FATTR_UID,    arg->uid = iattr->ia_uid;	if (ivalid & ATTR_GID)		arg->valid |= FATTR_GID,    arg->gid = iattr->ia_gid;	if (ivalid & ATTR_SIZE)		arg->valid |= FATTR_SIZE,   arg->size = iattr->ia_size;	/* You can only _set_ these together (they may change by themselves) */	if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) {		arg->valid |= FATTR_ATIME | FATTR_MTIME;#ifdef KERNEL_2_6		arg->atime = iattr->ia_atime.tv_sec;		arg->mtime = iattr->ia_mtime.tv_sec;#else		arg->atime = iattr->ia_atime;		arg->mtime = iattr->ia_mtime;#endif	}#ifdef ATTR_FILE	if (ivalid & ATTR_FILE) {		struct fuse_file *ff = iattr->ia_file->private_data;		arg->valid |= FATTR_FH;		arg->fh = ff->fh;	}#endif}/* * Set attributes, and at the same time refresh them. * * Truncation is slightly complicated, because the 'truncate' request * may fail, in which case we don't want to touch the mapping. * vmtruncate() doesn't allow for this case.  So do the rlimit * checking by hand and call vmtruncate() only after the file has * actually been truncated. */static int fuse_setattr(struct dentry *entry, struct iattr *attr){	struct inode *inode = entry->d_inode;	struct fuse_conn *fc = get_fuse_conn(inode);	struct fuse_inode *fi = get_fuse_inode(inode);	struct fuse_req *req;	struct fuse_setattr_in inarg;	struct fuse_attr_out outarg;	int err;	int is_truncate = 0;	if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {		err = inode_change_ok(inode, attr);		if (err)			return err;	}	if (attr->ia_valid & ATTR_SIZE) {		unsigned long limit;		is_truncate = 1;#ifdef KERNEL_2_6_10_PLUS		limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;#else		limit = current->rlim[RLIMIT_FSIZE].rlim_cur;#endif		if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) {			send_sig(SIGXFSZ, current, 0);			return -EFBIG;		}	}	req = fuse_get_request(fc);	if (!req)		return -EINTR;	memset(&inarg, 0, sizeof(inarg));	iattr_to_fattr(attr, &inarg);	req->in.h.opcode = FUSE_SETATTR;	req->in.h.nodeid = get_node_id(inode);	req->inode = inode;	req->in.numargs = 1;	req->in.args[0].size = sizeof(inarg);	req->in.args[0].value = &inarg;	req->out.numargs = 1;	req->out.args[0].size = sizeof(outarg);	req->out.args[0].value = &outarg;	request_send(fc, req);	err = req->out.h.error;	fuse_put_request(fc, req);	if (!err) {		if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {#ifndef KERNEL_2_6_12_PLUS			if (get_node_id(inode) != FUSE_ROOT_ID)				make_bad_inode(inode);#else			make_bad_inode(inode);#endif			err = -EIO;		} else {			if (is_truncate) {				loff_t origsize = i_size_read(inode);				i_size_write(inode, outarg.attr.size);				if (origsize > outarg.attr.size)					vmtruncate(inode, outarg.attr.size);			}			fuse_change_attributes(inode, &outarg.attr);			fi->i_time = time_to_jiffies(outarg.attr_valid,						     outarg.attr_valid_nsec);		}	} else if (err == -EINTR)		fuse_invalidate_attr(inode);	return err;}#ifdef KERNEL_2_6static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,			struct kstat *stat){	struct inode *inode = entry->d_inode;	int err = fuse_revalidate(entry);	if (!err)		generic_fillattr(inode, stat);	return err;}#else /* KERNEL_2_6 */static struct dentry *fuse_lookup_2_4(struct inode *dir, struct dentry *entry){	return fuse_lookup(dir, entry, NULL);}static int fuse_mknod_2_4(struct inode *dir, struct dentry *entry, int mode,			  int rdev){	return fuse_mknod(dir, entry, mode, rdev);}static int fuse_create_2_4(struct inode *dir, struct dentry *entry, int mode){	return fuse_create(dir, entry, mode, NULL);}static int fuse_permission_2_4(struct inode *inode, int mask){	return fuse_permission(inode, mask, NULL);}#endif /* KERNEL_2_6 */#ifdef HAVE_KERNEL_XATTR#ifdef KERNEL_2_6static int fuse_setxattr(struct dentry *entry, const char *name,			 const void *value, size_t size, int flags)#elsestatic int fuse_setxattr(struct dentry *entry, const char *name,			 void *value, size_t size, int flags)#endif{	struct inode *inode = entry->d_inode;	struct fuse_conn *fc = get_fuse_conn(inode);	struct fuse_req *req;	struct fuse_setxattr_in inarg;	int err;	if (fc->no_setxattr)		return -EOPNOTSUPP;	req = fuse_get_request(fc);	if (!req)		return -EINTR;	memset(&inarg, 0, sizeof(inarg));	inarg.size = size;	inarg.flags = flags;	req->in.h.opcode = FUSE_SETXATTR;	req->in.h.nodeid = get_node_id(inode);	req->inode = inode;	req->in.numargs = 3;	req->in.args[0].size = sizeof(inarg);	req->in.args[0].value = &inarg;	req->in.args[1].size = strlen(name) + 1;	req->in.args[1].value = name;	req->in.args[2].size = size;	req->in.args[2].value = value;	request_send(fc, req);	err = req->out.h.error;	fuse_put_request(fc, req);	if (err == -ENOSYS) {		fc->no_setxattr = 1;		err = -EOPNOTSUPP;	}	return err;}static ssize_t fuse_getxattr(struct dentry *entry, const char *name,			     void *value, size_t size){	struct inode *inode = entry->d_inode;	struct fuse_conn *fc = get_fuse_conn(inode);	struct fuse_req *req;	struct fuse_getxattr_in inarg;	struct fuse_getxattr_out outarg;	ssize_t ret;	if (fc->no_getxattr)		return -EOPNOTSUPP;	req = fuse_get_request(fc);	if (!req)		return -EINTR;	memset(&inarg, 0, sizeof(inarg));	inarg.size = size;	req->in.h.opcode = FUSE_GETXATTR;	req->in.h.nodeid = get_node_id(inode);	req->inode = inode;	req->in.numargs = 2;	req->in.args[0].size = sizeof(inarg);	req->in.args[0].value = &inarg;	req->in.args[1].size = strlen(name) + 1;	req->in.args[1].value = name;	/* This is really two different operations rolled into one */	req->out.numargs = 1;	if (size) {		req->out.argvar = 1;		req->out.args[0].size = size;		req->out.args[0].value = value;	} else {		req->out.args[0].size = sizeof(outarg);		req->out.args[0].value = &outarg;	}	request_send(fc, req);	ret = req->out.h.error;	if (!ret)		ret = size ? req->out.args[0].size : outarg.size;	else {		if (ret == -ENOSYS) {			fc->no_getxattr = 1;			ret = -EOPNOTSUPP;		}	}	fuse_put_request(fc, req);	return ret;}static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size){	struct inode *inode = entry->d_inode;	struct fuse_conn *fc = get_fuse_conn(inode);	struct fuse_req *req;	struct fuse_getxattr_in inarg;	struct fuse_getxattr_out outarg;	ssize_t ret;	if (fc->no_listxattr)		return -EOPNOTSUPP;	req = fuse_get_request(fc);	if (!req)		return -EINTR;	memset(&inarg, 0, sizeof(inarg));	inarg.size = size;	req->in.h.opcode = FUSE_LISTXATTR;	req->in.h.nodeid = get_node_id(inode);	req->inode = inode;	req->in.numargs = 1;	req->in.args[0].size = sizeof(inarg);	req->in.args[0].value = &inarg;	/* This is really two different operations rolled into one */	req->out.numargs = 1;	if (size) {		req->out.argvar = 1;		req->out.args[0].size = size;		req->out.args[0].value = list;	} else {		req->out.args[0].size = sizeof(outarg);		req->out.args[0].value = &outarg;	}	request_send(fc, req);	ret = req->out.h.error;	if (!ret)		ret = size ? req->out.args[0].size : outarg.size;	else {		if (ret == -ENOSYS) {			fc->no_listxattr = 1;			ret = -EOPNOTSUPP;		}	}	fuse_put_request(fc, req);	return ret;}static int fuse_removexattr(struct dentry *entry, const char *name){	struct inode *inode = entry->d_inode;	struct fuse_conn *fc = get_fuse_conn(inode);	struct fuse_req *req;	int err;	if (fc->no_removexattr)		return -EOPNOTSUPP;	req = fuse_get_request(fc);	if (!req)		return -EINTR;	req->in.h.opcode = FUSE_REMOVEXATTR;	req->in.h.nodeid = get_node_id(inode);	req->inode = inode;	req->in.numargs = 1;	req->in.args[0].size = strlen(name) + 1;	req->in.args[0].value = name;	request_send(fc, req);	err = req->out.h.error;	fuse_put_request(fc, req);	if (err == -ENOSYS) {		fc->no_removexattr = 1;		err = -EOPNOTSUPP;	}	return err;}#endifstatic struct inode_operations fuse_dir_inode_operations = {#ifdef KERNEL_2_6	.lookup		= fuse_lookup,#else	.lookup		= fuse_lookup_2_4,#endif	.mkdir		= fuse_mkdir,	.symlink	= fuse_symlink,	.unlink		= fuse_unlink,	.rmdir		= fuse_rmdir,	.rename		= fuse_rename,	.link		= fuse_link,	.setattr	= fuse_setattr,#ifdef KERNEL_2_6	.create		= fuse_create,	.mknod		= fuse_mknod,	.permission	= fuse_permission,	.getattr	= fuse_getattr,#else	.create		= fuse_create_2_4,	.mknod		= fuse_mknod_2_4,	.permission	= fuse_permission_2_4,	.revalidate	= fuse_revalidate,#endif#ifdef HAVE_KERNEL_XATTR	.setxattr	= fuse_setxattr,	.getxattr	= fuse_getxattr,	.listxattr	= fuse_listxattr,	.removexattr	= fuse_removexattr,#endif};static struct file_operations fuse_dir_operations = {	.llseek		= generic_file_llseek,	.read		= generic_read_dir,	.readdir	= fuse_readdir,	.open		= fuse_dir_open,	.release	= fuse_dir_release,	.fsync		= fuse_dir_fsync,};static struct inode_operations fuse_common_inode_operations = {	.setattr	= fuse_setattr,#ifdef KERNEL_2_6	.permission	= fuse_permission,	.getattr	= fuse_getattr,#else	.permission	= fuse_permission_2_4,	.revalidate	= fuse_revalidate,#endif#ifdef HAVE_KERNEL_XATTR	.setxattr	= fuse_setxattr,	.getxattr	= fuse_getxattr,	.listxattr	= fuse_listxattr,	.removexattr	= fuse_removexattr,#endif};static struct inode_operations fuse_symlink_inode_operations = {	.setattr	= fuse_setattr,	.follow_link	= fuse_follow_link,#ifdef KERNEL_2_6_8_PLUS	.put_link	= fuse_put_link,	.readlink	= generic_readlink,#else	.readlink	= fuse_readlink,#endif#ifdef KERNEL_2_6	.getattr	= fuse_getattr,#else	.revalidate	= fuse_revalidate,#endif#ifdef HAVE_KERNEL_XATTR	.setxattr	= fuse_setxattr,	.getxattr	= fuse_getxattr,	.listxattr	= fuse_listxattr,	.removexattr	= fuse_removexattr,#endif};void fuse_init_common(struct inode *inode){	inode->i_op = &fuse_common_inode_operations;}void fuse_init_dir(struct inode *inode){	inode->i_op = &fuse_dir_inode_operations;	inode->i_fop = &fuse_dir_operations;}void fuse_init_symlink(struct inode *inode){	inode->i_op = &fuse_symlink_inode_operations;}

⌨️ 快捷键说明

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