super.c (38465f5d1af932494d66b52d26bb3a02b837cdf8) super.c (f2aedb713c284429987dc66c7aaf38decfc8da2a)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * linux/fs/nfs/super.c
4 *
5 * Copyright (C) 1992 Rick Sladkey
6 *
7 * nfs superblock handling functions
8 *

--- 56 unchanged lines hidden (view full) ---

65#include "internal.h"
66#include "fscache.h"
67#include "nfs4session.h"
68#include "pnfs.h"
69#include "nfs.h"
70
71#define NFSDBG_FACILITY NFSDBG_VFS
72
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * linux/fs/nfs/super.c
4 *
5 * Copyright (C) 1992 Rick Sladkey
6 *
7 * nfs superblock handling functions
8 *

--- 56 unchanged lines hidden (view full) ---

65#include "internal.h"
66#include "fscache.h"
67#include "nfs4session.h"
68#include "pnfs.h"
69#include "nfs.h"
70
71#define NFSDBG_FACILITY NFSDBG_VFS
72
73static struct dentry *nfs_prepared_mount(struct file_system_type *fs_type,
74 int flags, const char *dev_name, void *raw_data);
75
76struct file_system_type nfs_fs_type = {
77 .owner = THIS_MODULE,
78 .name = "nfs",
79 .mount = nfs_fs_mount,
80 .kill_sb = nfs_kill_super,
81 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
82};
83MODULE_ALIAS_FS("nfs");
84EXPORT_SYMBOL_GPL(nfs_fs_type);
85
86struct file_system_type nfs_prepared_fs_type = {
87 .owner = THIS_MODULE,
88 .name = "nfs",
89 .mount = nfs_prepared_mount,
90 .kill_sb = nfs_kill_super,
91 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
92};
93EXPORT_SYMBOL_GPL(nfs_prepared_fs_type);
94
95const struct super_operations nfs_sops = {
96 .alloc_inode = nfs_alloc_inode,
97 .free_inode = nfs_free_inode,
98 .write_inode = nfs_write_inode,
99 .drop_inode = nfs_drop_inode,
100 .statfs = nfs_statfs,
101 .evict_inode = nfs_evict_inode,
102 .umount_begin = nfs_umount_begin,
103 .show_options = nfs_show_options,
104 .show_devname = nfs_show_devname,
105 .show_path = nfs_show_path,
106 .show_stats = nfs_show_stats,
73const struct super_operations nfs_sops = {
74 .alloc_inode = nfs_alloc_inode,
75 .free_inode = nfs_free_inode,
76 .write_inode = nfs_write_inode,
77 .drop_inode = nfs_drop_inode,
78 .statfs = nfs_statfs,
79 .evict_inode = nfs_evict_inode,
80 .umount_begin = nfs_umount_begin,
81 .show_options = nfs_show_options,
82 .show_devname = nfs_show_devname,
83 .show_path = nfs_show_path,
84 .show_stats = nfs_show_stats,
107 .remount_fs = nfs_remount,
108};
109EXPORT_SYMBOL_GPL(nfs_sops);
110
111#if IS_ENABLED(CONFIG_NFS_V4)
85};
86EXPORT_SYMBOL_GPL(nfs_sops);
87
88#if IS_ENABLED(CONFIG_NFS_V4)
112struct file_system_type nfs4_fs_type = {
113 .owner = THIS_MODULE,
114 .name = "nfs4",
115 .mount = nfs_fs_mount,
116 .kill_sb = nfs_kill_super,
117 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
118};
119MODULE_ALIAS_FS("nfs4");
120MODULE_ALIAS("nfs4");
121EXPORT_SYMBOL_GPL(nfs4_fs_type);
122
123static int __init register_nfs4_fs(void)
124{
125 return register_filesystem(&nfs4_fs_type);
126}
127
128static void unregister_nfs4_fs(void)
129{
130 unregister_filesystem(&nfs4_fs_type);

--- 775 unchanged lines hidden (view full) ---

906 return server;
907
908 /* Last chance! Try AUTH_UNIX */
909 dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", RPC_AUTH_UNIX);
910 ctx->selected_flavor = RPC_AUTH_UNIX;
911 return nfs_mod->rpc_ops->create_server(mount_info);
912}
913
89static int __init register_nfs4_fs(void)
90{
91 return register_filesystem(&nfs4_fs_type);
92}
93
94static void unregister_nfs4_fs(void)
95{
96 unregister_filesystem(&nfs4_fs_type);

--- 775 unchanged lines hidden (view full) ---

872 return server;
873
874 /* Last chance! Try AUTH_UNIX */
875 dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", RPC_AUTH_UNIX);
876 ctx->selected_flavor = RPC_AUTH_UNIX;
877 return nfs_mod->rpc_ops->create_server(mount_info);
878}
879
914static struct dentry *nfs_fs_mount_common(int, const char *, struct nfs_mount_info *);
915
916struct dentry *nfs_try_mount(int flags, const char *dev_name,
917 struct nfs_mount_info *mount_info)
880int nfs_try_get_tree(struct fs_context *fc)
918{
881{
919 struct nfs_subversion *nfs_mod = mount_info->nfs_mod;
920 if (mount_info->ctx->need_mount)
921 mount_info->server = nfs_try_mount_request(mount_info);
882 struct nfs_fs_context *ctx = nfs_fc2context(fc);
883
884 if (ctx->need_mount)
885 ctx->mount_info.server = nfs_try_mount_request(&ctx->mount_info);
922 else
886 else
923 mount_info->server = nfs_mod->rpc_ops->create_server(mount_info);
887 ctx->mount_info.server = ctx->mount_info.nfs_mod->rpc_ops->create_server(&ctx->mount_info);
924
888
925 return nfs_fs_mount_common(flags, dev_name, mount_info);
889 return nfs_get_tree_common(fc);
926}
890}
927EXPORT_SYMBOL_GPL(nfs_try_mount);
891EXPORT_SYMBOL_GPL(nfs_try_get_tree);
928
892
893
929#define NFS_REMOUNT_CMP_FLAGMASK ~(NFS_MOUNT_INTR \
930 | NFS_MOUNT_SECURE \
931 | NFS_MOUNT_TCP \
932 | NFS_MOUNT_VER3 \
933 | NFS_MOUNT_KERBEROS \
934 | NFS_MOUNT_NONLM \
935 | NFS_MOUNT_BROKEN_SUID \
936 | NFS_MOUNT_STRICTLOCK \

--- 23 unchanged lines hidden (view full) ---

960 ctx->nfs_server.addrlen != nfss->nfs_client->cl_addrlen ||
961 !rpc_cmp_addr((struct sockaddr *)&ctx->nfs_server.address,
962 (struct sockaddr *)&nfss->nfs_client->cl_addr))
963 return -EINVAL;
964
965 return 0;
966}
967
894#define NFS_REMOUNT_CMP_FLAGMASK ~(NFS_MOUNT_INTR \
895 | NFS_MOUNT_SECURE \
896 | NFS_MOUNT_TCP \
897 | NFS_MOUNT_VER3 \
898 | NFS_MOUNT_KERBEROS \
899 | NFS_MOUNT_NONLM \
900 | NFS_MOUNT_BROKEN_SUID \
901 | NFS_MOUNT_STRICTLOCK \

--- 23 unchanged lines hidden (view full) ---

925 ctx->nfs_server.addrlen != nfss->nfs_client->cl_addrlen ||
926 !rpc_cmp_addr((struct sockaddr *)&ctx->nfs_server.address,
927 (struct sockaddr *)&nfss->nfs_client->cl_addr))
928 return -EINVAL;
929
930 return 0;
931}
932
968int
969nfs_remount(struct super_block *sb, int *flags, char *raw_data)
933int nfs_reconfigure(struct fs_context *fc)
970{
934{
971 int error;
935 struct nfs_fs_context *ctx = nfs_fc2context(fc);
936 struct super_block *sb = fc->root->d_sb;
972 struct nfs_server *nfss = sb->s_fs_info;
937 struct nfs_server *nfss = sb->s_fs_info;
973 struct nfs_fs_context *ctx;
974 struct nfs_mount_data *options = (struct nfs_mount_data *)raw_data;
975 struct nfs4_mount_data *options4 = (struct nfs4_mount_data *)raw_data;
976 u32 nfsvers = nfss->nfs_client->rpc_ops->version;
977
978 sync_filesystem(sb);
979
980 /*
981 * Userspace mount programs that send binary options generally send
982 * them populated with default values. We have no way to know which
983 * ones were explicitly specified. Fall back to legacy behavior and
984 * just return success.
985 */
938
939 sync_filesystem(sb);
940
941 /*
942 * Userspace mount programs that send binary options generally send
943 * them populated with default values. We have no way to know which
944 * ones were explicitly specified. Fall back to legacy behavior and
945 * just return success.
946 */
986 if ((nfsvers == 4 && (!options4 || options4->version == 1)) ||
987 (nfsvers <= 3 && (!options || (options->version >= 1 &&
988 options->version <= 6))))
947 if (ctx->skip_reconfig_option_check)
989 return 0;
990
948 return 0;
949
991 ctx = nfs_alloc_parsed_mount_data();
992 if (ctx == NULL)
993 return -ENOMEM;
994
995 /* fill out struct with values from existing mount */
996 ctx->flags = nfss->flags;
997 ctx->rsize = nfss->rsize;
998 ctx->wsize = nfss->wsize;
999 ctx->retrans = nfss->client->cl_timeout->to_retries;
1000 ctx->selected_flavor = nfss->client->cl_auth->au_flavor;
1001 ctx->acregmin = nfss->acregmin / HZ;
1002 ctx->acregmax = nfss->acregmax / HZ;
1003 ctx->acdirmin = nfss->acdirmin / HZ;
1004 ctx->acdirmax = nfss->acdirmax / HZ;
1005 ctx->timeo = 10U * nfss->client->cl_timeout->to_initval / HZ;
1006 ctx->nfs_server.port = nfss->port;
1007 ctx->nfs_server.addrlen = nfss->nfs_client->cl_addrlen;
1008 ctx->version = nfsvers;
1009 ctx->minorversion = nfss->nfs_client->cl_minorversion;
1010 ctx->net = current->nsproxy->net_ns;
1011 memcpy(&ctx->nfs_server.address, &nfss->nfs_client->cl_addr,
1012 ctx->nfs_server.addrlen);
1013
1014 /* overwrite those values with any that were specified */
1015 error = -EINVAL;
1016 if (!nfs_parse_mount_options((char *)options, ctx))
1017 goto out;
1018
1019 /*
1020 * noac is a special case. It implies -o sync, but that's not
950 /*
951 * noac is a special case. It implies -o sync, but that's not
1021 * necessarily reflected in the mtab options. do_remount_sb
952 * necessarily reflected in the mtab options. reconfigure_super
1022 * will clear SB_SYNCHRONOUS if -o sync wasn't specified in the
1023 * remount options, so we have to explicitly reset it.
1024 */
953 * will clear SB_SYNCHRONOUS if -o sync wasn't specified in the
954 * remount options, so we have to explicitly reset it.
955 */
1025 if (ctx->flags & NFS_MOUNT_NOAC)
1026 *flags |= SB_SYNCHRONOUS;
956 if (ctx->flags & NFS_MOUNT_NOAC) {
957 fc->sb_flags |= SB_SYNCHRONOUS;
958 fc->sb_flags_mask |= SB_SYNCHRONOUS;
959 }
1027
1028 /* compare new mount options with old ones */
960
961 /* compare new mount options with old ones */
1029 error = nfs_compare_remount_data(nfss, ctx);
1030 if (!error)
1031 error = security_sb_remount(sb, ctx->lsm_opts);
1032out:
1033 nfs_free_parsed_mount_data(ctx);
1034 return error;
962 return nfs_compare_remount_data(nfss, ctx);
1035}
963}
1036EXPORT_SYMBOL_GPL(nfs_remount);
964EXPORT_SYMBOL_GPL(nfs_reconfigure);
1037
1038/*
1039 * Finish setting up an NFS superblock
1040 */
1041static void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info)
1042{
1043 struct nfs_fs_context *ctx = mount_info->ctx;
1044 struct nfs_server *server = NFS_SB(sb);

--- 62 unchanged lines hidden (view full) ---

1107 goto Ebusy;
1108 if (clnt_a->cl_auth->au_flavor != clnt_b->cl_auth->au_flavor)
1109 goto Ebusy;
1110 return 1;
1111Ebusy:
1112 return 0;
1113}
1114
965
966/*
967 * Finish setting up an NFS superblock
968 */
969static void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info)
970{
971 struct nfs_fs_context *ctx = mount_info->ctx;
972 struct nfs_server *server = NFS_SB(sb);

--- 62 unchanged lines hidden (view full) ---

1035 goto Ebusy;
1036 if (clnt_a->cl_auth->au_flavor != clnt_b->cl_auth->au_flavor)
1037 goto Ebusy;
1038 return 1;
1039Ebusy:
1040 return 0;
1041}
1042
1115struct nfs_sb_mountdata {
1116 struct nfs_server *server;
1117 int mntflags;
1118};
1119
1120static int nfs_set_super(struct super_block *s, void *data)
1043static int nfs_set_super(struct super_block *s, struct fs_context *fc)
1121{
1044{
1122 struct nfs_sb_mountdata *sb_mntdata = data;
1123 struct nfs_server *server = sb_mntdata->server;
1045 struct nfs_server *server = fc->s_fs_info;
1124 int ret;
1125
1046 int ret;
1047
1126 s->s_flags = sb_mntdata->mntflags;
1127 s->s_fs_info = server;
1128 s->s_d_op = server->nfs_client->rpc_ops->dentry_ops;
1129 ret = set_anon_super(s, server);
1130 if (ret == 0)
1131 server->s_dev = s->s_dev;
1132 return ret;
1133}
1134
1135static int nfs_compare_super_address(struct nfs_server *server1,

--- 48 unchanged lines hidden (view full) ---

1184 oldns = old->client->cl_cred->user_ns;
1185 if (new->client && new->client->cl_cred)
1186 newns = new->client->cl_cred->user_ns;
1187 if (oldns != newns)
1188 return 0;
1189 return 1;
1190}
1191
1048 s->s_d_op = server->nfs_client->rpc_ops->dentry_ops;
1049 ret = set_anon_super(s, server);
1050 if (ret == 0)
1051 server->s_dev = s->s_dev;
1052 return ret;
1053}
1054
1055static int nfs_compare_super_address(struct nfs_server *server1,

--- 48 unchanged lines hidden (view full) ---

1104 oldns = old->client->cl_cred->user_ns;
1105 if (new->client && new->client->cl_cred)
1106 newns = new->client->cl_cred->user_ns;
1107 if (oldns != newns)
1108 return 0;
1109 return 1;
1110}
1111
1192static int nfs_compare_super(struct super_block *sb, void *data)
1112static int nfs_compare_super(struct super_block *sb, struct fs_context *fc)
1193{
1113{
1194 struct nfs_sb_mountdata *sb_mntdata = data;
1195 struct nfs_server *server = sb_mntdata->server, *old = NFS_SB(sb);
1196 int mntflags = sb_mntdata->mntflags;
1114 struct nfs_server *server = fc->s_fs_info, *old = NFS_SB(sb);
1197
1198 if (!nfs_compare_super_address(old, server))
1199 return 0;
1200 /* Note: NFS_MOUNT_UNSHARED == NFS4_MOUNT_UNSHARED */
1201 if (old->flags & NFS_MOUNT_UNSHARED)
1202 return 0;
1203 if (memcmp(&old->fsid, &server->fsid, sizeof(old->fsid)) != 0)
1204 return 0;
1205 if (!nfs_compare_userns(old, server))
1206 return 0;
1115
1116 if (!nfs_compare_super_address(old, server))
1117 return 0;
1118 /* Note: NFS_MOUNT_UNSHARED == NFS4_MOUNT_UNSHARED */
1119 if (old->flags & NFS_MOUNT_UNSHARED)
1120 return 0;
1121 if (memcmp(&old->fsid, &server->fsid, sizeof(old->fsid)) != 0)
1122 return 0;
1123 if (!nfs_compare_userns(old, server))
1124 return 0;
1207 return nfs_compare_mount_options(sb, server, mntflags);
1125 return nfs_compare_mount_options(sb, server, fc->sb_flags);
1208}
1209
1210#ifdef CONFIG_NFS_FSCACHE
1211static void nfs_get_cache_cookie(struct super_block *sb,
1126}
1127
1128#ifdef CONFIG_NFS_FSCACHE
1129static void nfs_get_cache_cookie(struct super_block *sb,
1212 struct nfs_fs_context *ctx,
1213 struct nfs_clone_mount *cloned)
1130 struct nfs_fs_context *ctx)
1214{
1215 struct nfs_server *nfss = NFS_SB(sb);
1216 char *uniq = NULL;
1217 int ulen = 0;
1218
1219 nfss->fscache_key = NULL;
1220 nfss->fscache = NULL;
1221
1131{
1132 struct nfs_server *nfss = NFS_SB(sb);
1133 char *uniq = NULL;
1134 int ulen = 0;
1135
1136 nfss->fscache_key = NULL;
1137 nfss->fscache = NULL;
1138
1222 if (ctx) {
1223 if (!(ctx->options & NFS_OPTION_FSCACHE))
1224 return;
1225 if (ctx->fscache_uniq) {
1226 uniq = ctx->fscache_uniq;
1227 ulen = strlen(ctx->fscache_uniq);
1228 }
1229 } else if (cloned) {
1230 struct nfs_server *mnt_s = NFS_SB(cloned->sb);
1139 if (!ctx)
1140 return;
1141
1142 if (ctx->clone_data.sb) {
1143 struct nfs_server *mnt_s = NFS_SB(ctx->clone_data.sb);
1231 if (!(mnt_s->options & NFS_OPTION_FSCACHE))
1232 return;
1233 if (mnt_s->fscache_key) {
1234 uniq = mnt_s->fscache_key->key.uniquifier;
1235 ulen = mnt_s->fscache_key->key.uniq_len;
1236 }
1144 if (!(mnt_s->options & NFS_OPTION_FSCACHE))
1145 return;
1146 if (mnt_s->fscache_key) {
1147 uniq = mnt_s->fscache_key->key.uniquifier;
1148 ulen = mnt_s->fscache_key->key.uniq_len;
1149 }
1237 } else
1150 } else {
1151 if (!(ctx->options & NFS_OPTION_FSCACHE))
1152 return;
1153 if (ctx->fscache_uniq) {
1154 uniq = ctx->fscache_uniq;
1155 ulen = strlen(ctx->fscache_uniq);
1156 }
1238 return;
1157 return;
1158 }
1239
1240 nfs_fscache_get_super_cookie(sb, uniq, ulen);
1241}
1242#else
1243static void nfs_get_cache_cookie(struct super_block *sb,
1159
1160 nfs_fscache_get_super_cookie(sb, uniq, ulen);
1161}
1162#else
1163static void nfs_get_cache_cookie(struct super_block *sb,
1244 struct nfs_fs_context *parsed,
1245 struct nfs_clone_mount *cloned)
1164 struct nfs_fs_context *ctx)
1246{
1247}
1248#endif
1249
1250static void nfs_set_readahead(struct backing_dev_info *bdi,
1251 unsigned long iomax_pages)
1252{
1253 bdi->ra_pages = VM_READAHEAD_PAGES;
1254 bdi->io_pages = iomax_pages;
1255}
1256
1165{
1166}
1167#endif
1168
1169static void nfs_set_readahead(struct backing_dev_info *bdi,
1170 unsigned long iomax_pages)
1171{
1172 bdi->ra_pages = VM_READAHEAD_PAGES;
1173 bdi->io_pages = iomax_pages;
1174}
1175
1257static struct dentry *nfs_fs_mount_common(int flags, const char *dev_name,
1258 struct nfs_mount_info *mount_info)
1176int nfs_get_tree_common(struct fs_context *fc)
1259{
1177{
1178 struct nfs_fs_context *ctx = nfs_fc2context(fc);
1260 struct super_block *s;
1261 struct dentry *mntroot = ERR_PTR(-ENOMEM);
1179 struct super_block *s;
1180 struct dentry *mntroot = ERR_PTR(-ENOMEM);
1262 int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
1263 struct nfs_server *server = mount_info->server;
1181 int (*compare_super)(struct super_block *, struct fs_context *) = nfs_compare_super;
1182 struct nfs_server *server = ctx->mount_info.server;
1264 unsigned long kflags = 0, kflags_out = 0;
1183 unsigned long kflags = 0, kflags_out = 0;
1265 struct nfs_sb_mountdata sb_mntdata = {
1266 .mntflags = flags,
1267 .server = server,
1268 };
1269 int error;
1270
1184 int error;
1185
1271 mount_info->server = NULL;
1186 ctx->mount_info.server = NULL;
1272 if (IS_ERR(server))
1187 if (IS_ERR(server))
1273 return ERR_CAST(server);
1188 return PTR_ERR(server);
1274
1275 if (server->flags & NFS_MOUNT_UNSHARED)
1276 compare_super = NULL;
1277
1278 /* -o noac implies -o sync */
1279 if (server->flags & NFS_MOUNT_NOAC)
1189
1190 if (server->flags & NFS_MOUNT_UNSHARED)
1191 compare_super = NULL;
1192
1193 /* -o noac implies -o sync */
1194 if (server->flags & NFS_MOUNT_NOAC)
1280 sb_mntdata.mntflags |= SB_SYNCHRONOUS;
1195 fc->sb_flags |= SB_SYNCHRONOUS;
1281
1196
1282 if (mount_info->cloned != NULL && mount_info->cloned->sb != NULL)
1283 if (mount_info->cloned->sb->s_flags & SB_SYNCHRONOUS)
1284 sb_mntdata.mntflags |= SB_SYNCHRONOUS;
1197 if (ctx->clone_data.sb)
1198 if (ctx->clone_data.sb->s_flags & SB_SYNCHRONOUS)
1199 fc->sb_flags |= SB_SYNCHRONOUS;
1285
1200
1201 if (server->caps & NFS_CAP_SECURITY_LABEL)
1202 fc->lsm_flags |= SECURITY_LSM_NATIVE_LABELS;
1203
1286 /* Get a superblock - note that we may end up sharing one that already exists */
1204 /* Get a superblock - note that we may end up sharing one that already exists */
1287 s = sget(mount_info->nfs_mod->nfs_fs, compare_super, nfs_set_super,
1288 flags, &sb_mntdata);
1205 fc->s_fs_info = server;
1206 s = sget_fc(fc, compare_super, nfs_set_super);
1207 fc->s_fs_info = NULL;
1289 if (IS_ERR(s)) {
1208 if (IS_ERR(s)) {
1290 mntroot = ERR_CAST(s);
1209 error = PTR_ERR(s);
1210 dfprintk(MOUNT, "NFS: Couldn't get superblock\n");
1291 goto out_err_nosb;
1292 }
1293
1294 if (s->s_fs_info != server) {
1295 nfs_free_server(server);
1296 server = NULL;
1297 } else {
1298 error = super_setup_bdi_name(s, "%u:%u", MAJOR(server->s_dev),
1299 MINOR(server->s_dev));
1211 goto out_err_nosb;
1212 }
1213
1214 if (s->s_fs_info != server) {
1215 nfs_free_server(server);
1216 server = NULL;
1217 } else {
1218 error = super_setup_bdi_name(s, "%u:%u", MAJOR(server->s_dev),
1219 MINOR(server->s_dev));
1300 if (error) {
1301 mntroot = ERR_PTR(error);
1220 if (error)
1302 goto error_splat_super;
1221 goto error_splat_super;
1303 }
1304 nfs_set_readahead(s->s_bdi, server->rpages);
1305 server->super = s;
1306 }
1307
1308 if (!s->s_root) {
1222 nfs_set_readahead(s->s_bdi, server->rpages);
1223 server->super = s;
1224 }
1225
1226 if (!s->s_root) {
1309 unsigned bsize = mount_info->inherited_bsize;
1227 unsigned bsize = ctx->mount_info.inherited_bsize;
1310 /* initial superblock/root creation */
1228 /* initial superblock/root creation */
1311 nfs_fill_super(s, mount_info);
1229 nfs_fill_super(s, &ctx->mount_info);
1312 if (bsize) {
1313 s->s_blocksize_bits = bsize;
1314 s->s_blocksize = 1U << bsize;
1315 }
1230 if (bsize) {
1231 s->s_blocksize_bits = bsize;
1232 s->s_blocksize = 1U << bsize;
1233 }
1316 nfs_get_cache_cookie(s, mount_info->ctx, mount_info->cloned);
1317 if (!(server->flags & NFS_MOUNT_UNSHARED))
1318 s->s_iflags |= SB_I_MULTIROOT;
1234 nfs_get_cache_cookie(s, ctx);
1319 }
1320
1235 }
1236
1321 mntroot = nfs_get_root(s, mount_info->mntfh, dev_name);
1322 if (IS_ERR(mntroot))
1237 mntroot = nfs_get_root(s, ctx->mount_info.mntfh, fc->source);
1238 if (IS_ERR(mntroot)) {
1239 error = PTR_ERR(mntroot);
1240 dfprintk(MOUNT, "NFS: Couldn't get root dentry\n");
1323 goto error_splat_super;
1241 goto error_splat_super;
1242 }
1243 fc->root = mntroot;
1324
1244
1325
1326 if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL)
1327 kflags |= SECURITY_LSM_NATIVE_LABELS;
1245 if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL)
1246 kflags |= SECURITY_LSM_NATIVE_LABELS;
1328 if (mount_info->cloned) {
1329 if (d_inode(mntroot)->i_fop != &nfs_dir_operations) {
1247 if (ctx->clone_data.sb) {
1248 if (d_inode(fc->root)->i_fop != &nfs_dir_operations) {
1330 error = -ESTALE;
1331 goto error_splat_root;
1332 }
1333 /* clone any lsm security options from the parent to the new sb */
1249 error = -ESTALE;
1250 goto error_splat_root;
1251 }
1252 /* clone any lsm security options from the parent to the new sb */
1334 error = security_sb_clone_mnt_opts(mount_info->cloned->sb, s, kflags,
1253 error = security_sb_clone_mnt_opts(ctx->clone_data.sb, s, kflags,
1335 &kflags_out);
1336 } else {
1254 &kflags_out);
1255 } else {
1337 error = security_sb_set_mnt_opts(s, mount_info->ctx->lsm_opts,
1256 error = security_sb_set_mnt_opts(s, fc->security,
1338 kflags, &kflags_out);
1339 }
1340 if (error)
1341 goto error_splat_root;
1342 if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL &&
1343 !(kflags_out & SECURITY_LSM_NATIVE_LABELS))
1344 NFS_SB(s)->caps &= ~NFS_CAP_SECURITY_LABEL;
1257 kflags, &kflags_out);
1258 }
1259 if (error)
1260 goto error_splat_root;
1261 if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL &&
1262 !(kflags_out & SECURITY_LSM_NATIVE_LABELS))
1263 NFS_SB(s)->caps &= ~NFS_CAP_SECURITY_LABEL;
1345 if (error)
1346 goto error_splat_root;
1347
1348 s->s_flags |= SB_ACTIVE;
1264
1265 s->s_flags |= SB_ACTIVE;
1266 error = 0;
1349
1350out:
1267
1268out:
1351 return mntroot;
1269 return error;
1352
1353out_err_nosb:
1354 nfs_free_server(server);
1355 goto out;
1356
1357error_splat_root:
1270
1271out_err_nosb:
1272 nfs_free_server(server);
1273 goto out;
1274
1275error_splat_root:
1358 dput(mntroot);
1359 mntroot = ERR_PTR(error);
1276 dput(fc->root);
1277 fc->root = NULL;
1360error_splat_super:
1361 deactivate_locked_super(s);
1362 goto out;
1363}
1364
1278error_splat_super:
1279 deactivate_locked_super(s);
1280 goto out;
1281}
1282
1365struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
1366 int flags, const char *dev_name, void *raw_data)
1367{
1368 struct nfs_mount_info mount_info = {
1369 };
1370 struct dentry *mntroot = ERR_PTR(-ENOMEM);
1371 struct nfs_subversion *nfs_mod;
1372 int error;
1373
1374 mount_info.ctx = nfs_alloc_parsed_mount_data();
1375 mount_info.mntfh = nfs_alloc_fhandle();
1376 if (mount_info.ctx == NULL || mount_info.mntfh == NULL)
1377 goto out;
1378
1379 /* Validate the mount data */
1380 error = nfs_validate_mount_data(fs_type, raw_data, mount_info.ctx, mount_info.mntfh, dev_name);
1381 if (error == NFS_TEXT_DATA)
1382 error = nfs_validate_text_mount_data(raw_data,
1383 mount_info.ctx, dev_name);
1384 if (error < 0) {
1385 mntroot = ERR_PTR(error);
1386 goto out;
1387 }
1388
1389 nfs_mod = get_nfs_version(mount_info.ctx->version);
1390 if (IS_ERR(nfs_mod)) {
1391 mntroot = ERR_CAST(nfs_mod);
1392 goto out;
1393 }
1394 mount_info.nfs_mod = nfs_mod;
1395
1396 mntroot = nfs_mod->rpc_ops->try_mount(flags, dev_name, &mount_info);
1397
1398 put_nfs_version(nfs_mod);
1399out:
1400 nfs_free_parsed_mount_data(mount_info.ctx);
1401 nfs_free_fhandle(mount_info.mntfh);
1402 return mntroot;
1403}
1404EXPORT_SYMBOL_GPL(nfs_fs_mount);
1405
1406/*
1407 * Destroy an NFS2/3 superblock
1408 */
1409void nfs_kill_super(struct super_block *s)
1410{
1411 struct nfs_server *server = NFS_SB(s);
1412 dev_t dev = s->s_dev;
1413
1414 generic_shutdown_super(s);
1415
1416 nfs_fscache_release_super_cookie(s);
1417
1418 nfs_free_server(server);
1419 free_anon_bdev(dev);
1420}
1421EXPORT_SYMBOL_GPL(nfs_kill_super);
1422
1283/*
1284 * Destroy an NFS2/3 superblock
1285 */
1286void nfs_kill_super(struct super_block *s)
1287{
1288 struct nfs_server *server = NFS_SB(s);
1289 dev_t dev = s->s_dev;
1290
1291 generic_shutdown_super(s);
1292
1293 nfs_fscache_release_super_cookie(s);
1294
1295 nfs_free_server(server);
1296 free_anon_bdev(dev);
1297}
1298EXPORT_SYMBOL_GPL(nfs_kill_super);
1299
1423/*
1424 * Internal use only: mount_info is already set up by caller.
1425 * Used for mountpoint crossings and for nfs4 root.
1426 */
1427static struct dentry *
1428nfs_prepared_mount(struct file_system_type *fs_type, int flags,
1429 const char *dev_name, void *raw_data)
1430{
1431 return nfs_fs_mount_common(flags, dev_name, raw_data);
1432}
1433
1434#if IS_ENABLED(CONFIG_NFS_V4)
1435
1436/*
1437 * NFS v4 module parameters need to stay in the
1438 * NFS client for backwards compatibility
1439 */
1440unsigned int nfs_callback_set_tcpport;
1441unsigned short nfs_callback_nr_threads;

--- 69 unchanged lines hidden ---
1300#if IS_ENABLED(CONFIG_NFS_V4)
1301
1302/*
1303 * NFS v4 module parameters need to stay in the
1304 * NFS client for backwards compatibility
1305 */
1306unsigned int nfs_callback_set_tcpport;
1307unsigned short nfs_callback_nr_threads;

--- 69 unchanged lines hidden ---