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

📄 super.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (server->flags & NFS_MOUNT_UNSHARED)		compare_super = NULL;	/* Get a superblock - note that we may end up sharing one that already exists */	s = sget(&nfs_fs_type, compare_super, nfs_set_super, &sb_mntdata);	if (IS_ERR(s)) {		error = PTR_ERR(s);		goto out_err_nosb;	}	if (s->s_fs_info != server) {		nfs_free_server(server);		server = NULL;	}	if (!s->s_root) {		/* initial superblock/root creation */		nfs_clone_super(s, data->sb);	}	mntroot = nfs_get_root(s, data->fh);	if (IS_ERR(mntroot)) {		error = PTR_ERR(mntroot);		goto error_splat_super;	}	if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) {		dput(mntroot);		error = -ESTALE;		goto error_splat_super;	}	s->s_flags |= MS_ACTIVE;	mnt->mnt_sb = s;	mnt->mnt_root = mntroot;	dprintk("<-- nfs_xdev_get_sb() = 0\n");	return 0;out_err_nosb:	nfs_free_server(server);out_err_noserver:	dprintk("<-- nfs_xdev_get_sb() = %d [error]\n", error);	return error;error_splat_super:	up_write(&s->s_umount);	deactivate_super(s);	dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error);	return error;}#ifdef CONFIG_NFS_V4/* * Finish setting up a cloned NFS4 superblock */static void nfs4_clone_super(struct super_block *sb,			    const struct super_block *old_sb){	sb->s_blocksize_bits = old_sb->s_blocksize_bits;	sb->s_blocksize = old_sb->s_blocksize;	sb->s_maxbytes = old_sb->s_maxbytes;	sb->s_time_gran = 1;	sb->s_op = old_sb->s_op; 	nfs_initialise_sb(sb);}/* * Set up an NFS4 superblock */static void nfs4_fill_super(struct super_block *sb){	sb->s_time_gran = 1;	sb->s_op = &nfs4_sops;	nfs_initialise_sb(sb);}/* * Validate NFSv4 mount options */static int nfs4_validate_mount_data(void *options,				    struct nfs_parsed_mount_data *args,				    const char *dev_name){	struct nfs4_mount_data *data = (struct nfs4_mount_data *)options;	char *c;	memset(args, 0, sizeof(*args));	if (data == NULL)		goto out_no_data;	args->rsize		= NFS_MAX_FILE_IO_SIZE;	args->wsize		= NFS_MAX_FILE_IO_SIZE;	args->timeo		= 600;	args->retrans		= 2;	args->acregmin		= 3;	args->acregmax		= 60;	args->acdirmin		= 30;	args->acdirmax		= 60;	args->nfs_server.protocol = XPRT_TRANSPORT_TCP;	switch (data->version) {	case 1:		if (data->host_addrlen != sizeof(args->nfs_server.address))			goto out_no_address;		if (copy_from_user(&args->nfs_server.address,				   data->host_addr,				   sizeof(args->nfs_server.address)))			return -EFAULT;		if (args->nfs_server.address.sin_port == 0)			args->nfs_server.address.sin_port = htons(NFS_PORT);		if (!nfs_verify_server_address((struct sockaddr *)						&args->nfs_server.address))			goto out_no_address;		switch (data->auth_flavourlen) {		case 0:			args->auth_flavors[0] = RPC_AUTH_UNIX;			break;		case 1:			if (copy_from_user(&args->auth_flavors[0],					   data->auth_flavours,					   sizeof(args->auth_flavors[0])))				return -EFAULT;			break;		default:			goto out_inval_auth;		}		c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN);		if (IS_ERR(c))			return PTR_ERR(c);		args->nfs_server.hostname = c;		c = strndup_user(data->mnt_path.data, NFS4_MAXPATHLEN);		if (IS_ERR(c))			return PTR_ERR(c);		args->nfs_server.export_path = c;		dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", c);		c = strndup_user(data->client_addr.data, 16);		if (IS_ERR(c))			return PTR_ERR(c);		args->client_address = c;		/*		 * Translate to nfs_parsed_mount_data, which nfs4_fill_super		 * can deal with.		 */		args->flags	= data->flags & NFS4_MOUNT_FLAGMASK;		args->rsize	= data->rsize;		args->wsize	= data->wsize;		args->timeo	= data->timeo;		args->retrans	= data->retrans;		args->acregmin	= data->acregmin;		args->acregmax	= data->acregmax;		args->acdirmin	= data->acdirmin;		args->acdirmax	= data->acdirmax;		args->nfs_server.protocol = data->proto;		break;	default: {		unsigned int len;		if (nfs_parse_mount_options((char *)options, args) == 0)			return -EINVAL;		if (!nfs_verify_server_address((struct sockaddr *)						&args->nfs_server.address))			return -EINVAL;		switch (args->auth_flavor_len) {		case 0:			args->auth_flavors[0] = RPC_AUTH_UNIX;			break;		case 1:			break;		default:			goto out_inval_auth;		}		/*		 * Split "dev_name" into "hostname:mntpath".		 */		c = strchr(dev_name, ':');		if (c == NULL)			return -EINVAL;		/* while calculating len, pretend ':' is '\0' */		len = c - dev_name;		if (len > NFS4_MAXNAMLEN)			return -ENAMETOOLONG;		args->nfs_server.hostname = kzalloc(len, GFP_KERNEL);		if (args->nfs_server.hostname == NULL)			return -ENOMEM;		strncpy(args->nfs_server.hostname, dev_name, len - 1);		c++;			/* step over the ':' */		len = strlen(c);		if (len > NFS4_MAXPATHLEN)			return -ENAMETOOLONG;		args->nfs_server.export_path = kzalloc(len + 1, GFP_KERNEL);		if (args->nfs_server.export_path == NULL)			return -ENOMEM;		strncpy(args->nfs_server.export_path, c, len);		dprintk("MNTPATH: %s\n", args->nfs_server.export_path);		if (args->client_address == NULL)			goto out_no_client_address;		break;		}	}	return 0;out_no_data:	dfprintk(MOUNT, "NFS4: mount program didn't pass any mount data\n");	return -EINVAL;out_inval_auth:	dfprintk(MOUNT, "NFS4: Invalid number of RPC auth flavours %d\n",		 data->auth_flavourlen);	return -EINVAL;out_no_address:	dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n");	return -EINVAL;out_no_client_address:	dfprintk(MOUNT, "NFS4: mount program didn't pass callback address\n");	return -EINVAL;}/* * Get the superblock for an NFS4 mountpoint */static int nfs4_get_sb(struct file_system_type *fs_type,	int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt){	struct nfs_parsed_mount_data data;	struct super_block *s;	struct nfs_server *server;	struct nfs_fh mntfh;	struct dentry *mntroot;	int (*compare_super)(struct super_block *, void *) = nfs_compare_super;	struct nfs_sb_mountdata sb_mntdata = {		.mntflags = flags,	};	int error;	/* Validate the mount data */	error = nfs4_validate_mount_data(raw_data, &data, dev_name);	if (error < 0)		goto out;	/* Get a volume representation */	server = nfs4_create_server(&data, &mntfh);	if (IS_ERR(server)) {		error = PTR_ERR(server);		goto out;	}	sb_mntdata.server = server;	if (server->flags & NFS4_MOUNT_UNSHARED)		compare_super = NULL;	/* Get a superblock - note that we may end up sharing one that already exists */	s = sget(fs_type, compare_super, nfs_set_super, &sb_mntdata);	if (IS_ERR(s)) {		error = PTR_ERR(s);		goto out_free;	}	if (s->s_fs_info != server) {		nfs_free_server(server);		server = NULL;	}	if (!s->s_root) {		/* initial superblock/root creation */		nfs4_fill_super(s);	}	mntroot = nfs4_get_root(s, &mntfh);	if (IS_ERR(mntroot)) {		error = PTR_ERR(mntroot);		goto error_splat_super;	}	s->s_flags |= MS_ACTIVE;	mnt->mnt_sb = s;	mnt->mnt_root = mntroot;	error = 0;out:	kfree(data.client_address);	kfree(data.nfs_server.export_path);	kfree(data.nfs_server.hostname);	return error;out_free:	nfs_free_server(server);	goto out;error_splat_super:	up_write(&s->s_umount);	deactivate_super(s);	goto out;}static void nfs4_kill_super(struct super_block *sb){	struct nfs_server *server = NFS_SB(sb);	nfs_return_all_delegations(sb);	kill_anon_super(sb);	nfs4_renewd_prepare_shutdown(server);	nfs_free_server(server);}/* * Clone an NFS4 server record on xdev traversal (FSID-change) */static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags,			    const char *dev_name, void *raw_data,			    struct vfsmount *mnt){	struct nfs_clone_mount *data = raw_data;	struct super_block *s;	struct nfs_server *server;	struct dentry *mntroot;	int (*compare_super)(struct super_block *, void *) = nfs_compare_super;	struct nfs_sb_mountdata sb_mntdata = {		.mntflags = flags,	};	int error;	dprintk("--> nfs4_xdev_get_sb()\n");	/* create a new volume representation */	server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr);	if (IS_ERR(server)) {		error = PTR_ERR(server);		goto out_err_noserver;	}	sb_mntdata.server = server;	if (server->flags & NFS4_MOUNT_UNSHARED)		compare_super = NULL;	/* Get a superblock - note that we may end up sharing one that already exists */	s = sget(&nfs_fs_type, compare_super, nfs_set_super, &sb_mntdata);	if (IS_ERR(s)) {		error = PTR_ERR(s);		goto out_err_nosb;	}	if (s->s_fs_info != server) {		nfs_free_server(server);		server = NULL;	}	if (!s->s_root) {		/* initial superblock/root creation */		nfs4_clone_super(s, data->sb);	}	mntroot = nfs4_get_root(s, data->fh);	if (IS_ERR(mntroot)) {		error = PTR_ERR(mntroot);		goto error_splat_super;	}	if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) {		dput(mntroot);		error = -ESTALE;		goto error_splat_super;	}	s->s_flags |= MS_ACTIVE;	mnt->mnt_sb = s;	mnt->mnt_root = mntroot;	dprintk("<-- nfs4_xdev_get_sb() = 0\n");	return 0;out_err_nosb:	nfs_free_server(server);out_err_noserver:	dprintk("<-- nfs4_xdev_get_sb() = %d [error]\n", error);	return error;error_splat_super:	up_write(&s->s_umount);	deactivate_super(s);	dprintk("<-- nfs4_xdev_get_sb() = %d [splat]\n", error);	return error;}/* * Create an NFS4 server record on referral traversal */static int nfs4_referral_get_sb(struct file_system_type *fs_type, int flags,				const char *dev_name, void *raw_data,				struct vfsmount *mnt){	struct nfs_clone_mount *data = raw_data;	struct super_block *s;	struct nfs_server *server;	struct dentry *mntroot;	struct nfs_fh mntfh;	int (*compare_super)(struct super_block *, void *) = nfs_compare_super;	struct nfs_sb_mountdata sb_mntdata = {		.mntflags = flags,	};	int error;	dprintk("--> nfs4_referral_get_sb()\n");	/* create a new volume representation */	server = nfs4_create_referral_server(data, &mntfh);	if (IS_ERR(server)) {		error = PTR_ERR(server);		goto out_err_noserver;	}	sb_mntdata.server = server;	if (server->flags & NFS4_MOUNT_UNSHARED)		compare_super = NULL;	/* Get a superblock - note that we may end up sharing one that already exists */	s = sget(&nfs_fs_type, compare_super, nfs_set_super, &sb_mntdata);	if (IS_ERR(s)) {		error = PTR_ERR(s);		goto out_err_nosb;	}	if (s->s_fs_info != server) {		nfs_free_server(server);		server = NULL;	}	if (!s->s_root) {		/* initial superblock/root creation */		nfs4_fill_super(s);	}	mntroot = nfs4_get_root(s, &mntfh);	if (IS_ERR(mntroot)) {		error = PTR_ERR(mntroot);		goto error_splat_super;	}	if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) {		dput(mntroot);		error = -ESTALE;		goto error_splat_super;	}	s->s_flags |= MS_ACTIVE;	mnt->mnt_sb = s;	mnt->mnt_root = mntroot;	dprintk("<-- nfs4_referral_get_sb() = 0\n");	return 0;out_err_nosb:	nfs_free_server(server);out_err_noserver:	dprintk("<-- nfs4_referral_get_sb() = %d [error]\n", error);	return error;error_splat_super:	up_write(&s->s_umount);	deactivate_super(s);	dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error);	return error;}#endif /* CONFIG_NFS_V4 */

⌨️ 快捷键说明

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