Branch data Line data Source code
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 : : *
9 : : * Modularised by Alan Cox <alan@lxorguk.ukuu.org.uk>, while hacking some
10 : : * experimental NFS changes. Modularisation taken straight from SYS5 fs.
11 : : *
12 : : * Change to nfs_read_super() to permit NFS mounts to multi-homed hosts.
13 : : * J.S.Peatfield@damtp.cam.ac.uk
14 : : *
15 : : * Split from inode.c by David Howells <dhowells@redhat.com>
16 : : *
17 : : * - superblocks are indexed on server only - all inodes, dentries, etc. associated with a
18 : : * particular server are held in the same superblock
19 : : * - NFS superblocks can have several effective roots to the dentry tree
20 : : * - directory type roots are spliced into the tree when a path from one root reaches the root
21 : : * of another (see nfs_lookup())
22 : : */
23 : :
24 : : #include <linux/module.h>
25 : : #include <linux/init.h>
26 : :
27 : : #include <linux/time.h>
28 : : #include <linux/kernel.h>
29 : : #include <linux/mm.h>
30 : : #include <linux/string.h>
31 : : #include <linux/stat.h>
32 : : #include <linux/errno.h>
33 : : #include <linux/unistd.h>
34 : : #include <linux/sunrpc/clnt.h>
35 : : #include <linux/sunrpc/addr.h>
36 : : #include <linux/sunrpc/stats.h>
37 : : #include <linux/sunrpc/metrics.h>
38 : : #include <linux/sunrpc/xprtsock.h>
39 : : #include <linux/sunrpc/xprtrdma.h>
40 : : #include <linux/nfs_fs.h>
41 : : #include <linux/nfs_mount.h>
42 : : #include <linux/nfs4_mount.h>
43 : : #include <linux/lockd/bind.h>
44 : : #include <linux/seq_file.h>
45 : : #include <linux/mount.h>
46 : : #include <linux/namei.h>
47 : : #include <linux/vfs.h>
48 : : #include <linux/inet.h>
49 : : #include <linux/in6.h>
50 : : #include <linux/slab.h>
51 : : #include <net/ipv6.h>
52 : : #include <linux/netdevice.h>
53 : : #include <linux/nfs_xdr.h>
54 : : #include <linux/magic.h>
55 : : #include <linux/parser.h>
56 : : #include <linux/nsproxy.h>
57 : : #include <linux/rcupdate.h>
58 : :
59 : : #include <linux/uaccess.h>
60 : :
61 : : #include "nfs4_fs.h"
62 : : #include "callback.h"
63 : : #include "delegation.h"
64 : : #include "iostat.h"
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 : :
73 : : const 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,
85 : : };
86 : : EXPORT_SYMBOL_GPL(nfs_sops);
87 : :
88 : : #if IS_ENABLED(CONFIG_NFS_V4)
89 : 11 : static int __init register_nfs4_fs(void)
90 : : {
91 : 11 : return register_filesystem(&nfs4_fs_type);
92 : : }
93 : :
94 : 0 : static void unregister_nfs4_fs(void)
95 : : {
96 : 0 : unregister_filesystem(&nfs4_fs_type);
97 : 0 : }
98 : : #else
99 : : static int __init register_nfs4_fs(void)
100 : : {
101 : : return 0;
102 : : }
103 : :
104 : : static void unregister_nfs4_fs(void)
105 : : {
106 : : }
107 : : #endif
108 : :
109 : : static struct shrinker acl_shrinker = {
110 : : .count_objects = nfs_access_cache_count,
111 : : .scan_objects = nfs_access_cache_scan,
112 : : .seeks = DEFAULT_SEEKS,
113 : : };
114 : :
115 : : /*
116 : : * Register the NFS filesystems
117 : : */
118 : 11 : int __init register_nfs_fs(void)
119 : : {
120 : 11 : int ret;
121 : :
122 : 11 : ret = register_filesystem(&nfs_fs_type);
123 [ - + ]: 11 : if (ret < 0)
124 : 0 : goto error_0;
125 : :
126 : 11 : ret = register_nfs4_fs();
127 [ - + ]: 11 : if (ret < 0)
128 : 0 : goto error_1;
129 : :
130 : 11 : ret = nfs_register_sysctl();
131 [ - + ]: 11 : if (ret < 0)
132 : 0 : goto error_2;
133 : 11 : ret = register_shrinker(&acl_shrinker);
134 [ - + ]: 11 : if (ret < 0)
135 : 0 : goto error_3;
136 : : return 0;
137 : : error_3:
138 : 0 : nfs_unregister_sysctl();
139 : 0 : error_2:
140 : 0 : unregister_nfs4_fs();
141 : 0 : error_1:
142 : 0 : unregister_filesystem(&nfs_fs_type);
143 : : error_0:
144 : : return ret;
145 : : }
146 : :
147 : : /*
148 : : * Unregister the NFS filesystems
149 : : */
150 : 0 : void __exit unregister_nfs_fs(void)
151 : : {
152 : 0 : unregister_shrinker(&acl_shrinker);
153 : 0 : nfs_unregister_sysctl();
154 : 0 : unregister_nfs4_fs();
155 : 0 : unregister_filesystem(&nfs_fs_type);
156 : 0 : }
157 : :
158 : 0 : bool nfs_sb_active(struct super_block *sb)
159 : : {
160 : 0 : struct nfs_server *server = NFS_SB(sb);
161 : :
162 [ # # ]: 0 : if (!atomic_inc_not_zero(&sb->s_active))
163 : : return false;
164 [ # # ]: 0 : if (atomic_inc_return(&server->active) != 1)
165 : 0 : atomic_dec(&sb->s_active);
166 : : return true;
167 : : }
168 : : EXPORT_SYMBOL_GPL(nfs_sb_active);
169 : :
170 : 0 : void nfs_sb_deactive(struct super_block *sb)
171 : : {
172 : 0 : struct nfs_server *server = NFS_SB(sb);
173 : :
174 [ # # ]: 0 : if (atomic_dec_and_test(&server->active))
175 : 0 : deactivate_super(sb);
176 : 0 : }
177 : : EXPORT_SYMBOL_GPL(nfs_sb_deactive);
178 : :
179 : : /*
180 : : * Deliver file system statistics to userspace
181 : : */
182 : 0 : int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
183 : : {
184 : 0 : struct nfs_server *server = NFS_SB(dentry->d_sb);
185 : 0 : unsigned char blockbits;
186 : 0 : unsigned long blockres;
187 : 0 : struct nfs_fh *fh = NFS_FH(d_inode(dentry));
188 : 0 : struct nfs_fsstat res;
189 : 0 : int error = -ENOMEM;
190 : :
191 : 0 : res.fattr = nfs_alloc_fattr();
192 [ # # ]: 0 : if (res.fattr == NULL)
193 : 0 : goto out_err;
194 : :
195 : 0 : error = server->nfs_client->rpc_ops->statfs(server, fh, &res);
196 [ # # ]: 0 : if (unlikely(error == -ESTALE)) {
197 : 0 : struct dentry *pd_dentry;
198 : :
199 : 0 : pd_dentry = dget_parent(dentry);
200 : 0 : nfs_zap_caches(d_inode(pd_dentry));
201 : 0 : dput(pd_dentry);
202 : : }
203 : 0 : nfs_free_fattr(res.fattr);
204 [ # # ]: 0 : if (error < 0)
205 : 0 : goto out_err;
206 : :
207 : 0 : buf->f_type = NFS_SUPER_MAGIC;
208 : :
209 : : /*
210 : : * Current versions of glibc do not correctly handle the
211 : : * case where f_frsize != f_bsize. Eventually we want to
212 : : * report the value of wtmult in this field.
213 : : */
214 : 0 : buf->f_frsize = dentry->d_sb->s_blocksize;
215 : :
216 : : /*
217 : : * On most *nix systems, f_blocks, f_bfree, and f_bavail
218 : : * are reported in units of f_frsize. Linux hasn't had
219 : : * an f_frsize field in its statfs struct until recently,
220 : : * thus historically Linux's sys_statfs reports these
221 : : * fields in units of f_bsize.
222 : : */
223 : 0 : buf->f_bsize = dentry->d_sb->s_blocksize;
224 : 0 : blockbits = dentry->d_sb->s_blocksize_bits;
225 : 0 : blockres = (1 << blockbits) - 1;
226 : 0 : buf->f_blocks = (res.tbytes + blockres) >> blockbits;
227 : 0 : buf->f_bfree = (res.fbytes + blockres) >> blockbits;
228 : 0 : buf->f_bavail = (res.abytes + blockres) >> blockbits;
229 : :
230 : 0 : buf->f_files = res.tfiles;
231 : 0 : buf->f_ffree = res.afiles;
232 : :
233 : 0 : buf->f_namelen = server->namelen;
234 : :
235 : 0 : return 0;
236 : :
237 : : out_err:
238 : : dprintk("%s: statfs error = %d\n", __func__, -error);
239 : : return error;
240 : : }
241 : : EXPORT_SYMBOL_GPL(nfs_statfs);
242 : :
243 : : /*
244 : : * Map the security flavour number to a name
245 : : */
246 : 0 : static const char *nfs_pseudoflavour_to_name(rpc_authflavor_t flavour)
247 : : {
248 : 0 : static const struct {
249 : : rpc_authflavor_t flavour;
250 : : const char *str;
251 : : } sec_flavours[NFS_AUTH_INFO_MAX_FLAVORS] = {
252 : : /* update NFS_AUTH_INFO_MAX_FLAVORS when this list changes! */
253 : : { RPC_AUTH_NULL, "null" },
254 : : { RPC_AUTH_UNIX, "sys" },
255 : : { RPC_AUTH_GSS_KRB5, "krb5" },
256 : : { RPC_AUTH_GSS_KRB5I, "krb5i" },
257 : : { RPC_AUTH_GSS_KRB5P, "krb5p" },
258 : : { RPC_AUTH_GSS_LKEY, "lkey" },
259 : : { RPC_AUTH_GSS_LKEYI, "lkeyi" },
260 : : { RPC_AUTH_GSS_LKEYP, "lkeyp" },
261 : : { RPC_AUTH_GSS_SPKM, "spkm" },
262 : : { RPC_AUTH_GSS_SPKMI, "spkmi" },
263 : : { RPC_AUTH_GSS_SPKMP, "spkmp" },
264 : : { UINT_MAX, "unknown" }
265 : : };
266 : 0 : int i;
267 : :
268 [ # # ]: 0 : for (i = 0; sec_flavours[i].flavour != UINT_MAX; i++) {
269 [ # # ]: 0 : if (sec_flavours[i].flavour == flavour)
270 : : break;
271 : : }
272 : 0 : return sec_flavours[i].str;
273 : : }
274 : :
275 : 0 : static void nfs_show_mountd_netid(struct seq_file *m, struct nfs_server *nfss,
276 : : int showdefaults)
277 : : {
278 : 0 : struct sockaddr *sap = (struct sockaddr *) &nfss->mountd_address;
279 : 0 : char *proto = NULL;
280 : :
281 [ # # # ]: 0 : switch (sap->sa_family) {
282 : 0 : case AF_INET:
283 [ # # # ]: 0 : switch (nfss->mountd_protocol) {
284 : 0 : case IPPROTO_UDP:
285 : 0 : proto = RPCBIND_NETID_UDP;
286 : 0 : break;
287 : 0 : case IPPROTO_TCP:
288 : 0 : proto = RPCBIND_NETID_TCP;
289 : 0 : break;
290 : : }
291 : : break;
292 : 0 : case AF_INET6:
293 [ # # # ]: 0 : switch (nfss->mountd_protocol) {
294 : 0 : case IPPROTO_UDP:
295 : 0 : proto = RPCBIND_NETID_UDP6;
296 : 0 : break;
297 : 0 : case IPPROTO_TCP:
298 : 0 : proto = RPCBIND_NETID_TCP6;
299 : 0 : break;
300 : : }
301 : : break;
302 : : }
303 [ # # ]: 0 : if (proto || showdefaults)
304 [ # # ]: 0 : seq_printf(m, ",mountproto=%s", proto ?: "auto");
305 : 0 : }
306 : :
307 : 0 : static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss,
308 : : int showdefaults)
309 : : {
310 : 0 : struct sockaddr *sap = (struct sockaddr *)&nfss->mountd_address;
311 : :
312 [ # # ]: 0 : if (nfss->flags & NFS_MOUNT_LEGACY_INTERFACE)
313 : : return;
314 : :
315 [ # # # ]: 0 : switch (sap->sa_family) {
316 : 0 : case AF_INET: {
317 : 0 : struct sockaddr_in *sin = (struct sockaddr_in *)sap;
318 : 0 : seq_printf(m, ",mountaddr=%pI4", &sin->sin_addr.s_addr);
319 : 0 : break;
320 : : }
321 : 0 : case AF_INET6: {
322 : 0 : struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
323 : 0 : seq_printf(m, ",mountaddr=%pI6c", &sin6->sin6_addr);
324 : 0 : break;
325 : : }
326 : 0 : default:
327 [ # # ]: 0 : if (showdefaults)
328 : 0 : seq_puts(m, ",mountaddr=unspecified");
329 : : }
330 : :
331 [ # # # # ]: 0 : if (nfss->mountd_version || showdefaults)
332 : 0 : seq_printf(m, ",mountvers=%u", nfss->mountd_version);
333 [ # # ]: 0 : if ((nfss->mountd_port &&
334 [ # # ]: 0 : nfss->mountd_port != (unsigned short)NFS_UNSPEC_PORT) ||
335 : : showdefaults)
336 : 0 : seq_printf(m, ",mountport=%u", nfss->mountd_port);
337 : :
338 : 0 : nfs_show_mountd_netid(m, nfss, showdefaults);
339 : : }
340 : :
341 : : #if IS_ENABLED(CONFIG_NFS_V4)
342 : 0 : static void nfs_show_nfsv4_options(struct seq_file *m, struct nfs_server *nfss,
343 : : int showdefaults)
344 : : {
345 : 0 : struct nfs_client *clp = nfss->nfs_client;
346 : :
347 : 0 : seq_printf(m, ",clientaddr=%s", clp->cl_ipaddr);
348 : 0 : }
349 : : #else
350 : : static void nfs_show_nfsv4_options(struct seq_file *m, struct nfs_server *nfss,
351 : : int showdefaults)
352 : : {
353 : : }
354 : : #endif
355 : :
356 : 0 : static void nfs_show_nfs_version(struct seq_file *m,
357 : : unsigned int version,
358 : : unsigned int minorversion)
359 : : {
360 : 0 : seq_printf(m, ",vers=%u", version);
361 [ # # ]: 0 : if (version == 4)
362 : 0 : seq_printf(m, ".%u", minorversion);
363 : 0 : }
364 : :
365 : : /*
366 : : * Describe the mount options in force on this server representation
367 : : */
368 : 0 : static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
369 : : int showdefaults)
370 : : {
371 : 0 : static const struct proc_nfs_info {
372 : : int flag;
373 : : const char *str;
374 : : const char *nostr;
375 : : } nfs_info[] = {
376 : : { NFS_MOUNT_SOFT, ",soft", "" },
377 : : { NFS_MOUNT_SOFTERR, ",softerr", "" },
378 : : { NFS_MOUNT_SOFTREVAL, ",softreval", "" },
379 : : { NFS_MOUNT_POSIX, ",posix", "" },
380 : : { NFS_MOUNT_NOCTO, ",nocto", "" },
381 : : { NFS_MOUNT_NOAC, ",noac", "" },
382 : : { NFS_MOUNT_NONLM, ",nolock", "" },
383 : : { NFS_MOUNT_NOACL, ",noacl", "" },
384 : : { NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" },
385 : : { NFS_MOUNT_UNSHARED, ",nosharecache", "" },
386 : : { NFS_MOUNT_NORESVPORT, ",noresvport", "" },
387 : : { 0, NULL, NULL }
388 : : };
389 : 0 : const struct proc_nfs_info *nfs_infop;
390 : 0 : struct nfs_client *clp = nfss->nfs_client;
391 : 0 : u32 version = clp->rpc_ops->version;
392 : 0 : int local_flock, local_fcntl;
393 : :
394 : 0 : nfs_show_nfs_version(m, version, clp->cl_minorversion);
395 : 0 : seq_printf(m, ",rsize=%u", nfss->rsize);
396 : 0 : seq_printf(m, ",wsize=%u", nfss->wsize);
397 [ # # ]: 0 : if (nfss->bsize != 0)
398 : 0 : seq_printf(m, ",bsize=%u", nfss->bsize);
399 : 0 : seq_printf(m, ",namlen=%u", nfss->namelen);
400 [ # # # # ]: 0 : if (nfss->acregmin != NFS_DEF_ACREGMIN*HZ || showdefaults)
401 : 0 : seq_printf(m, ",acregmin=%u", nfss->acregmin/HZ);
402 [ # # # # ]: 0 : if (nfss->acregmax != NFS_DEF_ACREGMAX*HZ || showdefaults)
403 : 0 : seq_printf(m, ",acregmax=%u", nfss->acregmax/HZ);
404 [ # # # # ]: 0 : if (nfss->acdirmin != NFS_DEF_ACDIRMIN*HZ || showdefaults)
405 : 0 : seq_printf(m, ",acdirmin=%u", nfss->acdirmin/HZ);
406 [ # # # # ]: 0 : if (nfss->acdirmax != NFS_DEF_ACDIRMAX*HZ || showdefaults)
407 : 0 : seq_printf(m, ",acdirmax=%u", nfss->acdirmax/HZ);
408 [ # # ]: 0 : if (!(nfss->flags & (NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR)))
409 : 0 : seq_puts(m, ",hard");
410 [ # # ]: 0 : for (nfs_infop = nfs_info; nfs_infop->flag; nfs_infop++) {
411 [ # # ]: 0 : if (nfss->flags & nfs_infop->flag)
412 : 0 : seq_puts(m, nfs_infop->str);
413 : : else
414 : 0 : seq_puts(m, nfs_infop->nostr);
415 : : }
416 : 0 : rcu_read_lock();
417 : 0 : seq_printf(m, ",proto=%s",
418 : : rpc_peeraddr2str(nfss->client, RPC_DISPLAY_NETID));
419 : 0 : rcu_read_unlock();
420 [ # # ]: 0 : if (clp->cl_nconnect > 0)
421 : 0 : seq_printf(m, ",nconnect=%u", clp->cl_nconnect);
422 [ # # ]: 0 : if (version == 4) {
423 [ # # ]: 0 : if (nfss->port != NFS_PORT)
424 : 0 : seq_printf(m, ",port=%u", nfss->port);
425 : : } else
426 [ # # ]: 0 : if (nfss->port)
427 : 0 : seq_printf(m, ",port=%u", nfss->port);
428 : :
429 : 0 : seq_printf(m, ",timeo=%lu", 10U * nfss->client->cl_timeout->to_initval / HZ);
430 : 0 : seq_printf(m, ",retrans=%u", nfss->client->cl_timeout->to_retries);
431 : 0 : seq_printf(m, ",sec=%s", nfs_pseudoflavour_to_name(nfss->client->cl_auth->au_flavor));
432 : :
433 [ # # ]: 0 : if (version != 4)
434 : 0 : nfs_show_mountd_options(m, nfss, showdefaults);
435 : : else
436 : 0 : nfs_show_nfsv4_options(m, nfss, showdefaults);
437 : :
438 [ # # ]: 0 : if (nfss->options & NFS_OPTION_FSCACHE)
439 : 0 : seq_puts(m, ",fsc");
440 : :
441 [ # # ]: 0 : if (nfss->options & NFS_OPTION_MIGRATION)
442 : 0 : seq_puts(m, ",migration");
443 : :
444 [ # # ]: 0 : if (nfss->flags & NFS_MOUNT_LOOKUP_CACHE_NONEG) {
445 [ # # ]: 0 : if (nfss->flags & NFS_MOUNT_LOOKUP_CACHE_NONE)
446 : 0 : seq_puts(m, ",lookupcache=none");
447 : : else
448 : 0 : seq_puts(m, ",lookupcache=pos");
449 : : }
450 : :
451 : 0 : local_flock = nfss->flags & NFS_MOUNT_LOCAL_FLOCK;
452 : 0 : local_fcntl = nfss->flags & NFS_MOUNT_LOCAL_FCNTL;
453 : :
454 [ # # ]: 0 : if (!local_flock && !local_fcntl)
455 : 0 : seq_puts(m, ",local_lock=none");
456 [ # # ]: 0 : else if (local_flock && local_fcntl)
457 : 0 : seq_puts(m, ",local_lock=all");
458 [ # # ]: 0 : else if (local_flock)
459 : 0 : seq_puts(m, ",local_lock=flock");
460 : : else
461 : 0 : seq_puts(m, ",local_lock=posix");
462 : 0 : }
463 : :
464 : : /*
465 : : * Describe the mount options on this VFS mountpoint
466 : : */
467 : 0 : int nfs_show_options(struct seq_file *m, struct dentry *root)
468 : : {
469 : 0 : struct nfs_server *nfss = NFS_SB(root->d_sb);
470 : :
471 : 0 : nfs_show_mount_options(m, nfss, 0);
472 : :
473 : 0 : rcu_read_lock();
474 : 0 : seq_printf(m, ",addr=%s",
475 : 0 : rpc_peeraddr2str(nfss->nfs_client->cl_rpcclient,
476 : : RPC_DISPLAY_ADDR));
477 : 0 : rcu_read_unlock();
478 : :
479 : 0 : return 0;
480 : : }
481 : : EXPORT_SYMBOL_GPL(nfs_show_options);
482 : :
483 : : #if IS_ENABLED(CONFIG_NFS_V4)
484 : : static void show_lease(struct seq_file *m, struct nfs_server *server)
485 : : {
486 : : struct nfs_client *clp = server->nfs_client;
487 : : unsigned long expire;
488 : :
489 : : seq_printf(m, ",lease_time=%ld", clp->cl_lease_time / HZ);
490 : : expire = clp->cl_last_renewal + clp->cl_lease_time;
491 : : seq_printf(m, ",lease_expired=%ld",
492 : : time_after(expire, jiffies) ? 0 : (jiffies - expire) / HZ);
493 : : }
494 : : #ifdef CONFIG_NFS_V4_1
495 : : static void show_sessions(struct seq_file *m, struct nfs_server *server)
496 : : {
497 : : if (nfs4_has_session(server->nfs_client))
498 : : seq_puts(m, ",sessions");
499 : : }
500 : : #else
501 : 0 : static void show_sessions(struct seq_file *m, struct nfs_server *server) {}
502 : : #endif
503 : : #endif
504 : :
505 : : #ifdef CONFIG_NFS_V4_1
506 : : static void show_pnfs(struct seq_file *m, struct nfs_server *server)
507 : : {
508 : : seq_printf(m, ",pnfs=");
509 : : if (server->pnfs_curr_ld)
510 : : seq_printf(m, "%s", server->pnfs_curr_ld->name);
511 : : else
512 : : seq_printf(m, "not configured");
513 : : }
514 : :
515 : : static void show_implementation_id(struct seq_file *m, struct nfs_server *nfss)
516 : : {
517 : : if (nfss->nfs_client && nfss->nfs_client->cl_implid) {
518 : : struct nfs41_impl_id *impl_id = nfss->nfs_client->cl_implid;
519 : : seq_printf(m, "\n\timpl_id:\tname='%s',domain='%s',"
520 : : "date='%llu,%u'",
521 : : impl_id->name, impl_id->domain,
522 : : impl_id->date.seconds, impl_id->date.nseconds);
523 : : }
524 : : }
525 : : #else
526 : : #if IS_ENABLED(CONFIG_NFS_V4)
527 : 0 : static void show_pnfs(struct seq_file *m, struct nfs_server *server)
528 : : {
529 : 0 : }
530 : : #endif
531 : 0 : static void show_implementation_id(struct seq_file *m, struct nfs_server *nfss)
532 : : {
533 : 0 : }
534 : : #endif
535 : :
536 : 0 : int nfs_show_devname(struct seq_file *m, struct dentry *root)
537 : : {
538 : 0 : char *page = (char *) __get_free_page(GFP_KERNEL);
539 : 0 : char *devname, *dummy;
540 : 0 : int err = 0;
541 [ # # ]: 0 : if (!page)
542 : : return -ENOMEM;
543 : 0 : devname = nfs_path(&dummy, root, page, PAGE_SIZE, 0);
544 [ # # ]: 0 : if (IS_ERR(devname))
545 : 0 : err = PTR_ERR(devname);
546 : : else
547 : 0 : seq_escape(m, devname, " \t\n\\");
548 : 0 : free_page((unsigned long)page);
549 : 0 : return err;
550 : : }
551 : : EXPORT_SYMBOL_GPL(nfs_show_devname);
552 : :
553 : 0 : int nfs_show_path(struct seq_file *m, struct dentry *dentry)
554 : : {
555 : 0 : seq_puts(m, "/");
556 : 0 : return 0;
557 : : }
558 : : EXPORT_SYMBOL_GPL(nfs_show_path);
559 : :
560 : : /*
561 : : * Present statistical information for this VFS mountpoint
562 : : */
563 : 0 : int nfs_show_stats(struct seq_file *m, struct dentry *root)
564 : : {
565 : 0 : int i, cpu;
566 : 0 : struct nfs_server *nfss = NFS_SB(root->d_sb);
567 : 0 : struct rpc_auth *auth = nfss->client->cl_auth;
568 : 0 : struct nfs_iostats totals = { };
569 : :
570 : 0 : seq_printf(m, "statvers=%s", NFS_IOSTAT_VERS);
571 : :
572 : : /*
573 : : * Display all mount option settings
574 : : */
575 : 0 : seq_puts(m, "\n\topts:\t");
576 [ # # ]: 0 : seq_puts(m, sb_rdonly(root->d_sb) ? "ro" : "rw");
577 [ # # ]: 0 : seq_puts(m, root->d_sb->s_flags & SB_SYNCHRONOUS ? ",sync" : "");
578 [ # # ]: 0 : seq_puts(m, root->d_sb->s_flags & SB_NOATIME ? ",noatime" : "");
579 [ # # ]: 0 : seq_puts(m, root->d_sb->s_flags & SB_NODIRATIME ? ",nodiratime" : "");
580 : 0 : nfs_show_mount_options(m, nfss, 1);
581 : :
582 : 0 : seq_printf(m, "\n\tage:\t%lu", (jiffies - nfss->mount_time) / HZ);
583 : :
584 : 0 : show_implementation_id(m, nfss);
585 : :
586 : 0 : seq_puts(m, "\n\tcaps:\t");
587 : 0 : seq_printf(m, "caps=0x%x", nfss->caps);
588 : 0 : seq_printf(m, ",wtmult=%u", nfss->wtmult);
589 : 0 : seq_printf(m, ",dtsize=%u", nfss->dtsize);
590 : 0 : seq_printf(m, ",bsize=%u", nfss->bsize);
591 : 0 : seq_printf(m, ",namlen=%u", nfss->namelen);
592 : :
593 : : #if IS_ENABLED(CONFIG_NFS_V4)
594 [ # # ]: 0 : if (nfss->nfs_client->rpc_ops->version == 4) {
595 : 0 : seq_puts(m, "\n\tnfsv4:\t");
596 : 0 : seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]);
597 : 0 : seq_printf(m, ",bm1=0x%x", nfss->attr_bitmask[1]);
598 : 0 : seq_printf(m, ",bm2=0x%x", nfss->attr_bitmask[2]);
599 : 0 : seq_printf(m, ",acl=0x%x", nfss->acl_bitmask);
600 : 0 : show_sessions(m, nfss);
601 : 0 : show_pnfs(m, nfss);
602 : 0 : show_lease(m, nfss);
603 : : }
604 : : #endif
605 : :
606 : : /*
607 : : * Display security flavor in effect for this mount
608 : : */
609 : 0 : seq_printf(m, "\n\tsec:\tflavor=%u", auth->au_ops->au_flavor);
610 [ # # ]: 0 : if (auth->au_flavor)
611 : 0 : seq_printf(m, ",pseudoflavor=%u", auth->au_flavor);
612 : :
613 : : /*
614 : : * Display superblock I/O counters
615 : : */
616 [ # # ]: 0 : for_each_possible_cpu(cpu) {
617 : 0 : struct nfs_iostats *stats;
618 : :
619 : 0 : preempt_disable();
620 : 0 : stats = per_cpu_ptr(nfss->io_stats, cpu);
621 : :
622 [ # # ]: 0 : for (i = 0; i < __NFSIOS_COUNTSMAX; i++)
623 : 0 : totals.events[i] += stats->events[i];
624 [ # # ]: 0 : for (i = 0; i < __NFSIOS_BYTESMAX; i++)
625 : 0 : totals.bytes[i] += stats->bytes[i];
626 : : #ifdef CONFIG_NFS_FSCACHE
627 : : for (i = 0; i < __NFSIOS_FSCACHEMAX; i++)
628 : : totals.fscache[i] += stats->fscache[i];
629 : : #endif
630 : :
631 : 0 : preempt_enable();
632 : : }
633 : :
634 : 0 : seq_puts(m, "\n\tevents:\t");
635 [ # # ]: 0 : for (i = 0; i < __NFSIOS_COUNTSMAX; i++)
636 : 0 : seq_printf(m, "%lu ", totals.events[i]);
637 : 0 : seq_puts(m, "\n\tbytes:\t");
638 [ # # ]: 0 : for (i = 0; i < __NFSIOS_BYTESMAX; i++)
639 : 0 : seq_printf(m, "%Lu ", totals.bytes[i]);
640 : : #ifdef CONFIG_NFS_FSCACHE
641 : : if (nfss->options & NFS_OPTION_FSCACHE) {
642 : : seq_puts(m, "\n\tfsc:\t");
643 : : for (i = 0; i < __NFSIOS_FSCACHEMAX; i++)
644 : : seq_printf(m, "%Lu ", totals.fscache[i]);
645 : : }
646 : : #endif
647 : 0 : seq_putc(m, '\n');
648 : :
649 : 0 : rpc_clnt_show_stats(m, nfss->client);
650 : :
651 : 0 : return 0;
652 : : }
653 : : EXPORT_SYMBOL_GPL(nfs_show_stats);
654 : :
655 : : /*
656 : : * Begin unmount by attempting to remove all automounted mountpoints we added
657 : : * in response to xdev traversals and referrals
658 : : */
659 : 0 : void nfs_umount_begin(struct super_block *sb)
660 : : {
661 : 0 : struct nfs_server *server;
662 : 0 : struct rpc_clnt *rpc;
663 : :
664 [ # # ]: 0 : server = NFS_SB(sb);
665 : : /* -EIO all pending I/O */
666 : 0 : rpc = server->client_acl;
667 [ # # ]: 0 : if (!IS_ERR(rpc))
668 : 0 : rpc_killall_tasks(rpc);
669 : 0 : rpc = server->client;
670 [ # # ]: 0 : if (!IS_ERR(rpc))
671 : 0 : rpc_killall_tasks(rpc);
672 : 0 : }
673 : : EXPORT_SYMBOL_GPL(nfs_umount_begin);
674 : :
675 : : /*
676 : : * Return true if 'match' is in auth_info or auth_info is empty.
677 : : * Return false otherwise.
678 : : */
679 : 0 : bool nfs_auth_info_match(const struct nfs_auth_info *auth_info,
680 : : rpc_authflavor_t match)
681 : : {
682 : 0 : int i;
683 : :
684 [ # # ]: 0 : if (!auth_info->flavor_len)
685 : : return true;
686 : :
687 [ # # # # : 0 : for (i = 0; i < auth_info->flavor_len; i++) {
# # ]
688 [ # # # # : 0 : if (auth_info->flavors[i] == match)
# # ]
689 : : return true;
690 : : }
691 : : return false;
692 : : }
693 : : EXPORT_SYMBOL_GPL(nfs_auth_info_match);
694 : :
695 : : /*
696 : : * Ensure that a specified authtype in ctx->auth_info is supported by
697 : : * the server. Returns 0 and sets ctx->selected_flavor if it's ok, and
698 : : * -EACCES if not.
699 : : */
700 : 0 : static int nfs_verify_authflavors(struct nfs_fs_context *ctx,
701 : : rpc_authflavor_t *server_authlist,
702 : : unsigned int count)
703 : : {
704 : 0 : rpc_authflavor_t flavor = RPC_AUTH_MAXFLAVOR;
705 : 0 : bool found_auth_null = false;
706 : 0 : unsigned int i;
707 : :
708 : : /*
709 : : * If the sec= mount option is used, the specified flavor or AUTH_NULL
710 : : * must be in the list returned by the server.
711 : : *
712 : : * AUTH_NULL has a special meaning when it's in the server list - it
713 : : * means that the server will ignore the rpc creds, so any flavor
714 : : * can be used but still use the sec= that was specified.
715 : : *
716 : : * Note also that the MNT procedure in MNTv1 does not return a list
717 : : * of supported security flavors. In this case, nfs_mount() fabricates
718 : : * a security flavor list containing just AUTH_NULL.
719 : : */
720 [ # # ]: 0 : for (i = 0; i < count; i++) {
721 : 0 : flavor = server_authlist[i];
722 : :
723 [ # # # # ]: 0 : if (nfs_auth_info_match(&ctx->auth_info, flavor))
724 : 0 : goto out;
725 : :
726 [ # # ]: 0 : if (flavor == RPC_AUTH_NULL)
727 : 0 : found_auth_null = true;
728 : : }
729 : :
730 [ # # ]: 0 : if (found_auth_null) {
731 : 0 : flavor = ctx->auth_info.flavors[0];
732 : 0 : goto out;
733 : : }
734 : :
735 : : dfprintk(MOUNT,
736 : : "NFS: specified auth flavors not supported by server\n");
737 : : return -EACCES;
738 : :
739 : 0 : out:
740 : 0 : ctx->selected_flavor = flavor;
741 : 0 : dfprintk(MOUNT, "NFS: using auth flavor %u\n", ctx->selected_flavor);
742 : 0 : return 0;
743 : : }
744 : :
745 : : /*
746 : : * Use the remote server's MOUNT service to request the NFS file handle
747 : : * corresponding to the provided path.
748 : : */
749 : 0 : static int nfs_request_mount(struct fs_context *fc,
750 : : struct nfs_fh *root_fh,
751 : : rpc_authflavor_t *server_authlist,
752 : : unsigned int *server_authlist_len)
753 : : {
754 [ # # ]: 0 : struct nfs_fs_context *ctx = nfs_fc2context(fc);
755 : 0 : struct nfs_mount_request request = {
756 : 0 : .sap = (struct sockaddr *)
757 : : &ctx->mount_server.address,
758 : 0 : .dirpath = ctx->nfs_server.export_path,
759 : 0 : .protocol = ctx->mount_server.protocol,
760 : : .fh = root_fh,
761 : 0 : .noresvport = ctx->flags & NFS_MOUNT_NORESVPORT,
762 : : .auth_flav_len = server_authlist_len,
763 : : .auth_flavs = server_authlist,
764 : 0 : .net = fc->net_ns,
765 : : };
766 : 0 : int status;
767 : :
768 [ # # ]: 0 : if (ctx->mount_server.version == 0) {
769 [ # # ]: 0 : switch (ctx->version) {
770 : 0 : default:
771 : 0 : ctx->mount_server.version = NFS_MNT3_VERSION;
772 : 0 : break;
773 : 0 : case 2:
774 : 0 : ctx->mount_server.version = NFS_MNT_VERSION;
775 : : }
776 : 0 : }
777 : 0 : request.version = ctx->mount_server.version;
778 : :
779 [ # # ]: 0 : if (ctx->mount_server.hostname)
780 : 0 : request.hostname = ctx->mount_server.hostname;
781 : : else
782 : 0 : request.hostname = ctx->nfs_server.hostname;
783 : :
784 : : /*
785 : : * Construct the mount server's address.
786 : : */
787 [ # # ]: 0 : if (ctx->mount_server.address.sa_family == AF_UNSPEC) {
788 : 0 : memcpy(request.sap, &ctx->nfs_server.address,
789 : : ctx->nfs_server.addrlen);
790 : 0 : ctx->mount_server.addrlen = ctx->nfs_server.addrlen;
791 : : }
792 : 0 : request.salen = ctx->mount_server.addrlen;
793 [ # # ]: 0 : nfs_set_port(request.sap, &ctx->mount_server.port, 0);
794 : :
795 : : /*
796 : : * Now ask the mount server to map our export path
797 : : * to a file handle.
798 : : */
799 : 0 : status = nfs_mount(&request);
800 [ # # ]: 0 : if (status != 0) {
801 : 0 : dfprintk(MOUNT, "NFS: unable to mount server %s, error %d\n",
802 : : request.hostname, status);
803 : 0 : return status;
804 : : }
805 : :
806 : : return 0;
807 : : }
808 : :
809 : 0 : static struct nfs_server *nfs_try_mount_request(struct fs_context *fc)
810 : : {
811 : 0 : struct nfs_fs_context *ctx = nfs_fc2context(fc);
812 : 0 : int status;
813 : 0 : unsigned int i;
814 : 0 : bool tried_auth_unix = false;
815 : 0 : bool auth_null_in_list = false;
816 : 0 : struct nfs_server *server = ERR_PTR(-EACCES);
817 : 0 : rpc_authflavor_t authlist[NFS_MAX_SECFLAVORS];
818 : 0 : unsigned int authlist_len = ARRAY_SIZE(authlist);
819 : :
820 : 0 : status = nfs_request_mount(fc, ctx->mntfh, authlist, &authlist_len);
821 [ # # ]: 0 : if (status)
822 : 0 : return ERR_PTR(status);
823 : :
824 : : /*
825 : : * Was a sec= authflavor specified in the options? First, verify
826 : : * whether the server supports it, and then just try to use it if so.
827 : : */
828 [ # # ]: 0 : if (ctx->auth_info.flavor_len > 0) {
829 : 0 : status = nfs_verify_authflavors(ctx, authlist, authlist_len);
830 : 0 : dfprintk(MOUNT, "NFS: using auth flavor %u\n",
831 : : ctx->selected_flavor);
832 [ # # ]: 0 : if (status)
833 : 0 : return ERR_PTR(status);
834 : 0 : return ctx->nfs_mod->rpc_ops->create_server(fc);
835 : : }
836 : :
837 : : /*
838 : : * No sec= option was provided. RFC 2623, section 2.7 suggests we
839 : : * SHOULD prefer the flavor listed first. However, some servers list
840 : : * AUTH_NULL first. Avoid ever choosing AUTH_NULL.
841 : : */
842 [ # # ]: 0 : for (i = 0; i < authlist_len; ++i) {
843 : 0 : rpc_authflavor_t flavor;
844 : 0 : struct rpcsec_gss_info info;
845 : :
846 : 0 : flavor = authlist[i];
847 [ # # # ]: 0 : switch (flavor) {
848 : : case RPC_AUTH_UNIX:
849 : : tried_auth_unix = true;
850 : : break;
851 : 0 : case RPC_AUTH_NULL:
852 : 0 : auth_null_in_list = true;
853 : 0 : continue;
854 : 0 : default:
855 [ # # ]: 0 : if (rpcauth_get_gssinfo(flavor, &info) != 0)
856 : 0 : continue;
857 : : /* Fallthrough */
858 : : }
859 : 0 : dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", flavor);
860 : 0 : ctx->selected_flavor = flavor;
861 : 0 : server = ctx->nfs_mod->rpc_ops->create_server(fc);
862 [ # # ]: 0 : if (!IS_ERR(server))
863 : 0 : return server;
864 : : }
865 : :
866 : : /*
867 : : * Nothing we tried so far worked. At this point, give up if we've
868 : : * already tried AUTH_UNIX or if the server's list doesn't contain
869 : : * AUTH_NULL
870 : : */
871 [ # # ]: 0 : if (tried_auth_unix || !auth_null_in_list)
872 : : return server;
873 : :
874 : : /* Last chance! Try AUTH_UNIX */
875 : 0 : dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", RPC_AUTH_UNIX);
876 : 0 : ctx->selected_flavor = RPC_AUTH_UNIX;
877 : 0 : return ctx->nfs_mod->rpc_ops->create_server(fc);
878 : : }
879 : :
880 : 0 : int nfs_try_get_tree(struct fs_context *fc)
881 : : {
882 [ # # ]: 0 : struct nfs_fs_context *ctx = nfs_fc2context(fc);
883 : :
884 [ # # ]: 0 : if (ctx->need_mount)
885 : 0 : ctx->server = nfs_try_mount_request(fc);
886 : : else
887 : 0 : ctx->server = ctx->nfs_mod->rpc_ops->create_server(fc);
888 : :
889 : 0 : return nfs_get_tree_common(fc);
890 : : }
891 : : EXPORT_SYMBOL_GPL(nfs_try_get_tree);
892 : :
893 : :
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 \
902 : : | NFS_MOUNT_LEGACY_INTERFACE)
903 : :
904 : : #define NFS_MOUNT_CMP_FLAGMASK (NFS_REMOUNT_CMP_FLAGMASK & \
905 : : ~(NFS_MOUNT_UNSHARED | NFS_MOUNT_NORESVPORT))
906 : :
907 : : static int
908 : 0 : nfs_compare_remount_data(struct nfs_server *nfss,
909 : : struct nfs_fs_context *ctx)
910 : : {
911 [ # # ]: 0 : if ((ctx->flags ^ nfss->flags) & NFS_REMOUNT_CMP_FLAGMASK ||
912 [ # # ]: 0 : ctx->rsize != nfss->rsize ||
913 [ # # ]: 0 : ctx->wsize != nfss->wsize ||
914 [ # # ]: 0 : ctx->version != nfss->nfs_client->rpc_ops->version ||
915 [ # # ]: 0 : ctx->minorversion != nfss->nfs_client->cl_minorversion ||
916 [ # # # # ]: 0 : ctx->retrans != nfss->client->cl_timeout->to_retries ||
917 [ # # ]: 0 : !nfs_auth_info_match(&ctx->auth_info, nfss->client->cl_auth->au_flavor) ||
918 [ # # ]: 0 : ctx->acregmin != nfss->acregmin / HZ ||
919 [ # # ]: 0 : ctx->acregmax != nfss->acregmax / HZ ||
920 [ # # ]: 0 : ctx->acdirmin != nfss->acdirmin / HZ ||
921 [ # # ]: 0 : ctx->acdirmax != nfss->acdirmax / HZ ||
922 [ # # ]: 0 : ctx->timeo != (10U * nfss->client->cl_timeout->to_initval / HZ) ||
923 [ # # ]: 0 : (ctx->options & NFS_OPTION_FSCACHE) != (nfss->options & NFS_OPTION_FSCACHE) ||
924 [ # # ]: 0 : ctx->nfs_server.port != nfss->port ||
925 [ # # # # ]: 0 : ctx->nfs_server.addrlen != nfss->nfs_client->cl_addrlen ||
926 : 0 : !rpc_cmp_addr((struct sockaddr *)&ctx->nfs_server.address,
927 : 0 : (struct sockaddr *)&nfss->nfs_client->cl_addr))
928 : 0 : return -EINVAL;
929 : :
930 : : return 0;
931 : : }
932 : :
933 : 0 : int nfs_reconfigure(struct fs_context *fc)
934 : : {
935 : 0 : struct nfs_fs_context *ctx = nfs_fc2context(fc);
936 : 0 : struct super_block *sb = fc->root->d_sb;
937 : 0 : struct nfs_server *nfss = sb->s_fs_info;
938 : :
939 : 0 : 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 : : */
947 [ # # ]: 0 : if (ctx->skip_reconfig_option_check)
948 : : return 0;
949 : :
950 : : /*
951 : : * noac is a special case. It implies -o sync, but that's not
952 : : * necessarily reflected in the mtab options. reconfigure_super
953 : : * will clear SB_SYNCHRONOUS if -o sync wasn't specified in the
954 : : * remount options, so we have to explicitly reset it.
955 : : */
956 [ # # ]: 0 : if (ctx->flags & NFS_MOUNT_NOAC) {
957 : 0 : fc->sb_flags |= SB_SYNCHRONOUS;
958 : 0 : fc->sb_flags_mask |= SB_SYNCHRONOUS;
959 : : }
960 : :
961 : : /* compare new mount options with old ones */
962 : 0 : return nfs_compare_remount_data(nfss, ctx);
963 : : }
964 : : EXPORT_SYMBOL_GPL(nfs_reconfigure);
965 : :
966 : : /*
967 : : * Finish setting up an NFS superblock
968 : : */
969 : 0 : static void nfs_fill_super(struct super_block *sb, struct nfs_fs_context *ctx)
970 : : {
971 [ # # ]: 0 : struct nfs_server *server = NFS_SB(sb);
972 : :
973 : 0 : sb->s_blocksize_bits = 0;
974 : 0 : sb->s_blocksize = 0;
975 : 0 : sb->s_xattr = server->nfs_client->cl_nfs_mod->xattr;
976 : 0 : sb->s_op = server->nfs_client->cl_nfs_mod->sops;
977 [ # # # # ]: 0 : if (ctx && ctx->bsize)
978 : 0 : sb->s_blocksize = nfs_block_size(ctx->bsize, &sb->s_blocksize_bits);
979 : :
980 [ # # ]: 0 : if (server->nfs_client->rpc_ops->version != 2) {
981 : : /* The VFS shouldn't apply the umask to mode bits. We will do
982 : : * so ourselves when necessary.
983 : : */
984 : 0 : sb->s_flags |= SB_POSIXACL;
985 : 0 : sb->s_time_gran = 1;
986 : 0 : sb->s_export_op = &nfs_export_ops;
987 : : } else
988 : 0 : sb->s_time_gran = 1000;
989 : :
990 [ # # ]: 0 : if (server->nfs_client->rpc_ops->version != 4) {
991 : 0 : sb->s_time_min = 0;
992 : 0 : sb->s_time_max = U32_MAX;
993 : : } else {
994 : 0 : sb->s_time_min = S64_MIN;
995 : 0 : sb->s_time_max = S64_MAX;
996 : : }
997 : :
998 : 0 : sb->s_magic = NFS_SUPER_MAGIC;
999 : :
1000 : : /* We probably want something more informative here */
1001 : 0 : snprintf(sb->s_id, sizeof(sb->s_id),
1002 : 0 : "%u:%u", MAJOR(sb->s_dev), MINOR(sb->s_dev));
1003 : :
1004 [ # # ]: 0 : if (sb->s_blocksize == 0)
1005 [ # # ]: 0 : sb->s_blocksize = nfs_block_bits(server->wsize,
1006 : : &sb->s_blocksize_bits);
1007 : :
1008 [ # # ]: 0 : nfs_super_set_maxbytes(sb, server->maxfilesize);
1009 : 0 : }
1010 : :
1011 : : static int nfs_compare_mount_options(const struct super_block *s, const struct nfs_server *b,
1012 : : const struct fs_context *fc)
1013 : : {
1014 : : const struct nfs_server *a = s->s_fs_info;
1015 : : const struct rpc_clnt *clnt_a = a->client;
1016 : : const struct rpc_clnt *clnt_b = b->client;
1017 : :
1018 : : if ((s->s_flags & NFS_SB_MASK) != (fc->sb_flags & NFS_SB_MASK))
1019 : : goto Ebusy;
1020 : : if (a->nfs_client != b->nfs_client)
1021 : : goto Ebusy;
1022 : : if ((a->flags ^ b->flags) & NFS_MOUNT_CMP_FLAGMASK)
1023 : : goto Ebusy;
1024 : : if (a->wsize != b->wsize)
1025 : : goto Ebusy;
1026 : : if (a->rsize != b->rsize)
1027 : : goto Ebusy;
1028 : : if (a->acregmin != b->acregmin)
1029 : : goto Ebusy;
1030 : : if (a->acregmax != b->acregmax)
1031 : : goto Ebusy;
1032 : : if (a->acdirmin != b->acdirmin)
1033 : : goto Ebusy;
1034 : : if (a->acdirmax != b->acdirmax)
1035 : : goto Ebusy;
1036 : : if (clnt_a->cl_auth->au_flavor != clnt_b->cl_auth->au_flavor)
1037 : : goto Ebusy;
1038 : : return 1;
1039 : : Ebusy:
1040 : : return 0;
1041 : : }
1042 : :
1043 : 0 : static int nfs_set_super(struct super_block *s, struct fs_context *fc)
1044 : : {
1045 : 0 : struct nfs_server *server = fc->s_fs_info;
1046 : 0 : int ret;
1047 : :
1048 : 0 : s->s_d_op = server->nfs_client->rpc_ops->dentry_ops;
1049 : 0 : ret = set_anon_super(s, server);
1050 [ # # ]: 0 : if (ret == 0)
1051 : 0 : server->s_dev = s->s_dev;
1052 : 0 : return ret;
1053 : : }
1054 : :
1055 : : static int nfs_compare_super_address(struct nfs_server *server1,
1056 : : struct nfs_server *server2)
1057 : : {
1058 : : struct sockaddr *sap1, *sap2;
1059 : : struct rpc_xprt *xprt1 = server1->client->cl_xprt;
1060 : : struct rpc_xprt *xprt2 = server2->client->cl_xprt;
1061 : :
1062 : : if (!net_eq(xprt1->xprt_net, xprt2->xprt_net))
1063 : : return 0;
1064 : :
1065 : : sap1 = (struct sockaddr *)&server1->nfs_client->cl_addr;
1066 : : sap2 = (struct sockaddr *)&server2->nfs_client->cl_addr;
1067 : :
1068 : : if (sap1->sa_family != sap2->sa_family)
1069 : : return 0;
1070 : :
1071 : : switch (sap1->sa_family) {
1072 : : case AF_INET: {
1073 : : struct sockaddr_in *sin1 = (struct sockaddr_in *)sap1;
1074 : : struct sockaddr_in *sin2 = (struct sockaddr_in *)sap2;
1075 : : if (sin1->sin_addr.s_addr != sin2->sin_addr.s_addr)
1076 : : return 0;
1077 : : if (sin1->sin_port != sin2->sin_port)
1078 : : return 0;
1079 : : break;
1080 : : }
1081 : : case AF_INET6: {
1082 : : struct sockaddr_in6 *sin1 = (struct sockaddr_in6 *)sap1;
1083 : : struct sockaddr_in6 *sin2 = (struct sockaddr_in6 *)sap2;
1084 : : if (!ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr))
1085 : : return 0;
1086 : : if (sin1->sin6_port != sin2->sin6_port)
1087 : : return 0;
1088 : : break;
1089 : : }
1090 : : default:
1091 : : return 0;
1092 : : }
1093 : :
1094 : : return 1;
1095 : : }
1096 : :
1097 : 0 : static int nfs_compare_userns(const struct nfs_server *old,
1098 : : const struct nfs_server *new)
1099 : : {
1100 : 0 : const struct user_namespace *oldns = &init_user_ns;
1101 : 0 : const struct user_namespace *newns = &init_user_ns;
1102 : :
1103 [ # # ]: 0 : if (old->client && old->client->cl_cred)
1104 : 0 : oldns = old->client->cl_cred->user_ns;
1105 [ # # # # ]: 0 : if (new->client && new->client->cl_cred)
1106 : 0 : newns = new->client->cl_cred->user_ns;
1107 [ # # ]: 0 : if (oldns != newns)
1108 : : return 0;
1109 : : return 1;
1110 : : }
1111 : :
1112 : 0 : static int nfs_compare_super(struct super_block *sb, struct fs_context *fc)
1113 : : {
1114 [ # # ]: 0 : struct nfs_server *server = fc->s_fs_info, *old = NFS_SB(sb);
1115 : :
1116 [ # # ]: 0 : if (!nfs_compare_super_address(old, server))
1117 : : return 0;
1118 : : /* Note: NFS_MOUNT_UNSHARED == NFS4_MOUNT_UNSHARED */
1119 [ # # ]: 0 : if (old->flags & NFS_MOUNT_UNSHARED)
1120 : : return 0;
1121 [ # # ]: 0 : if (memcmp(&old->fsid, &server->fsid, sizeof(old->fsid)) != 0)
1122 : : return 0;
1123 [ # # ]: 0 : if (!nfs_compare_userns(old, server))
1124 : : return 0;
1125 : 0 : return nfs_compare_mount_options(sb, server, fc);
1126 : : }
1127 : :
1128 : : #ifdef CONFIG_NFS_FSCACHE
1129 : : static void nfs_get_cache_cookie(struct super_block *sb,
1130 : : struct nfs_fs_context *ctx)
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 : :
1139 : : if (!ctx)
1140 : : return;
1141 : :
1142 : : if (ctx->clone_data.sb) {
1143 : : struct nfs_server *mnt_s = NFS_SB(ctx->clone_data.sb);
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 : : }
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 : : }
1157 : : return;
1158 : : }
1159 : :
1160 : : nfs_fscache_get_super_cookie(sb, uniq, ulen);
1161 : : }
1162 : : #else
1163 : : static void nfs_get_cache_cookie(struct super_block *sb,
1164 : : struct nfs_fs_context *ctx)
1165 : : {
1166 : : }
1167 : : #endif
1168 : :
1169 : 0 : static void nfs_set_readahead(struct backing_dev_info *bdi,
1170 : : unsigned long iomax_pages)
1171 : : {
1172 : 0 : bdi->ra_pages = VM_READAHEAD_PAGES;
1173 : 0 : bdi->io_pages = iomax_pages;
1174 : : }
1175 : :
1176 : 0 : int nfs_get_tree_common(struct fs_context *fc)
1177 : : {
1178 [ # # ]: 0 : struct nfs_fs_context *ctx = nfs_fc2context(fc);
1179 : 0 : struct super_block *s;
1180 : 0 : int (*compare_super)(struct super_block *, struct fs_context *) = nfs_compare_super;
1181 : 0 : struct nfs_server *server = ctx->server;
1182 : 0 : unsigned long kflags = 0, kflags_out = 0;
1183 : 0 : int error;
1184 : :
1185 : 0 : ctx->server = NULL;
1186 [ # # ]: 0 : if (IS_ERR(server))
1187 : 0 : return PTR_ERR(server);
1188 : :
1189 [ # # ]: 0 : if (server->flags & NFS_MOUNT_UNSHARED)
1190 : 0 : compare_super = NULL;
1191 : :
1192 : : /* -o noac implies -o sync */
1193 [ # # ]: 0 : if (server->flags & NFS_MOUNT_NOAC)
1194 : 0 : fc->sb_flags |= SB_SYNCHRONOUS;
1195 : :
1196 [ # # ]: 0 : if (ctx->clone_data.sb)
1197 [ # # ]: 0 : if (ctx->clone_data.sb->s_flags & SB_SYNCHRONOUS)
1198 : 0 : fc->sb_flags |= SB_SYNCHRONOUS;
1199 : :
1200 [ # # ]: 0 : if (server->caps & NFS_CAP_SECURITY_LABEL)
1201 : 0 : fc->lsm_flags |= SECURITY_LSM_NATIVE_LABELS;
1202 : :
1203 : : /* Get a superblock - note that we may end up sharing one that already exists */
1204 : 0 : fc->s_fs_info = server;
1205 : 0 : s = sget_fc(fc, compare_super, nfs_set_super);
1206 : 0 : fc->s_fs_info = NULL;
1207 [ # # ]: 0 : if (IS_ERR(s)) {
1208 : 0 : error = PTR_ERR(s);
1209 : 0 : nfs_errorf(fc, "NFS: Couldn't get superblock");
1210 : 0 : goto out_err_nosb;
1211 : : }
1212 : :
1213 [ # # ]: 0 : if (s->s_fs_info != server) {
1214 : 0 : nfs_free_server(server);
1215 : 0 : server = NULL;
1216 : : } else {
1217 : 0 : error = super_setup_bdi_name(s, "%u:%u", MAJOR(server->s_dev),
1218 : 0 : MINOR(server->s_dev));
1219 [ # # ]: 0 : if (error)
1220 : 0 : goto error_splat_super;
1221 : 0 : nfs_set_readahead(s->s_bdi, server->rpages);
1222 : 0 : server->super = s;
1223 : : }
1224 : :
1225 [ # # ]: 0 : if (!s->s_root) {
1226 : 0 : unsigned bsize = ctx->clone_data.inherited_bsize;
1227 : : /* initial superblock/root creation */
1228 : 0 : nfs_fill_super(s, ctx);
1229 [ # # ]: 0 : if (bsize) {
1230 : 0 : s->s_blocksize_bits = bsize;
1231 : 0 : s->s_blocksize = 1U << bsize;
1232 : : }
1233 : : nfs_get_cache_cookie(s, ctx);
1234 : : }
1235 : :
1236 : 0 : error = nfs_get_root(s, fc);
1237 [ # # ]: 0 : if (error < 0) {
1238 : 0 : nfs_errorf(fc, "NFS: Couldn't get root dentry");
1239 : 0 : goto error_splat_super;
1240 : : }
1241 : :
1242 [ # # ]: 0 : if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL)
1243 : 0 : kflags |= SECURITY_LSM_NATIVE_LABELS;
1244 [ # # ]: 0 : if (ctx->clone_data.sb) {
1245 [ # # ]: 0 : if (d_inode(fc->root)->i_fop != &nfs_dir_operations) {
1246 : 0 : error = -ESTALE;
1247 : 0 : goto error_splat_root;
1248 : : }
1249 : : /* clone any lsm security options from the parent to the new sb */
1250 : 0 : error = security_sb_clone_mnt_opts(ctx->clone_data.sb, s, kflags,
1251 : : &kflags_out);
1252 : : } else {
1253 : 0 : error = security_sb_set_mnt_opts(s, fc->security,
1254 : : kflags, &kflags_out);
1255 : : }
1256 [ # # ]: 0 : if (error)
1257 : 0 : goto error_splat_root;
1258 [ # # ]: 0 : if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL &&
1259 [ # # ]: 0 : !(kflags_out & SECURITY_LSM_NATIVE_LABELS))
1260 : 0 : NFS_SB(s)->caps &= ~NFS_CAP_SECURITY_LABEL;
1261 : :
1262 : 0 : s->s_flags |= SB_ACTIVE;
1263 : 0 : error = 0;
1264 : :
1265 : : out:
1266 : : return error;
1267 : :
1268 : : out_err_nosb:
1269 : 0 : nfs_free_server(server);
1270 : 0 : goto out;
1271 : :
1272 : 0 : error_splat_root:
1273 : 0 : dput(fc->root);
1274 : 0 : fc->root = NULL;
1275 : 0 : error_splat_super:
1276 : 0 : deactivate_locked_super(s);
1277 : 0 : goto out;
1278 : : }
1279 : :
1280 : : /*
1281 : : * Destroy an NFS2/3 superblock
1282 : : */
1283 : 0 : void nfs_kill_super(struct super_block *s)
1284 : : {
1285 : 0 : struct nfs_server *server = NFS_SB(s);
1286 : 0 : dev_t dev = s->s_dev;
1287 : :
1288 : 0 : generic_shutdown_super(s);
1289 : :
1290 : 0 : nfs_fscache_release_super_cookie(s);
1291 : :
1292 : 0 : nfs_free_server(server);
1293 : 0 : free_anon_bdev(dev);
1294 : 0 : }
1295 : : EXPORT_SYMBOL_GPL(nfs_kill_super);
1296 : :
1297 : : #if IS_ENABLED(CONFIG_NFS_V4)
1298 : :
1299 : : /*
1300 : : * NFS v4 module parameters need to stay in the
1301 : : * NFS client for backwards compatibility
1302 : : */
1303 : : unsigned int nfs_callback_set_tcpport;
1304 : : unsigned short nfs_callback_nr_threads;
1305 : : /* Default cache timeout is 10 minutes */
1306 : : unsigned int nfs_idmap_cache_timeout = 600;
1307 : : /* Turn off NFSv4 uid/gid mapping when using AUTH_SYS */
1308 : : bool nfs4_disable_idmapping = true;
1309 : : unsigned short max_session_slots = NFS4_DEF_SLOT_TABLE_SIZE;
1310 : : unsigned short max_session_cb_slots = NFS4_DEF_CB_SLOT_TABLE_SIZE;
1311 : : unsigned short send_implementation_id = 1;
1312 : : char nfs4_client_id_uniquifier[NFS4_CLIENT_ID_UNIQ_LEN] = "";
1313 : : bool recover_lost_locks = false;
1314 : :
1315 : : EXPORT_SYMBOL_GPL(nfs_callback_nr_threads);
1316 : : EXPORT_SYMBOL_GPL(nfs_callback_set_tcpport);
1317 : : EXPORT_SYMBOL_GPL(nfs_idmap_cache_timeout);
1318 : : EXPORT_SYMBOL_GPL(nfs4_disable_idmapping);
1319 : : EXPORT_SYMBOL_GPL(max_session_slots);
1320 : : EXPORT_SYMBOL_GPL(max_session_cb_slots);
1321 : : EXPORT_SYMBOL_GPL(send_implementation_id);
1322 : : EXPORT_SYMBOL_GPL(nfs4_client_id_uniquifier);
1323 : : EXPORT_SYMBOL_GPL(recover_lost_locks);
1324 : :
1325 : : #define NFS_CALLBACK_MAXPORTNR (65535U)
1326 : :
1327 : 0 : static int param_set_portnr(const char *val, const struct kernel_param *kp)
1328 : : {
1329 : 0 : unsigned long num;
1330 : 0 : int ret;
1331 : :
1332 [ # # ]: 0 : if (!val)
1333 : : return -EINVAL;
1334 : 0 : ret = kstrtoul(val, 0, &num);
1335 [ # # # # ]: 0 : if (ret || num > NFS_CALLBACK_MAXPORTNR)
1336 : : return -EINVAL;
1337 : 0 : *((unsigned int *)kp->arg) = num;
1338 : 0 : return 0;
1339 : : }
1340 : : static const struct kernel_param_ops param_ops_portnr = {
1341 : : .set = param_set_portnr,
1342 : : .get = param_get_uint,
1343 : : };
1344 : : #define param_check_portnr(name, p) __param_check(name, p, unsigned int);
1345 : :
1346 : : module_param_named(callback_tcpport, nfs_callback_set_tcpport, portnr, 0644);
1347 : : module_param_named(callback_nr_threads, nfs_callback_nr_threads, ushort, 0644);
1348 : : MODULE_PARM_DESC(callback_nr_threads, "Number of threads that will be "
1349 : : "assigned to the NFSv4 callback channels.");
1350 : : module_param(nfs_idmap_cache_timeout, int, 0644);
1351 : : module_param(nfs4_disable_idmapping, bool, 0644);
1352 : : module_param_string(nfs4_unique_id, nfs4_client_id_uniquifier,
1353 : : NFS4_CLIENT_ID_UNIQ_LEN, 0600);
1354 : : MODULE_PARM_DESC(nfs4_disable_idmapping,
1355 : : "Turn off NFSv4 idmapping when using 'sec=sys'");
1356 : : module_param(max_session_slots, ushort, 0644);
1357 : : MODULE_PARM_DESC(max_session_slots, "Maximum number of outstanding NFSv4.1 "
1358 : : "requests the client will negotiate");
1359 : : module_param(max_session_cb_slots, ushort, 0644);
1360 : : MODULE_PARM_DESC(max_session_cb_slots, "Maximum number of parallel NFSv4.1 "
1361 : : "callbacks the client will process for a given server");
1362 : : module_param(send_implementation_id, ushort, 0644);
1363 : : MODULE_PARM_DESC(send_implementation_id,
1364 : : "Send implementation ID with NFSv4.1 exchange_id");
1365 : : MODULE_PARM_DESC(nfs4_unique_id, "nfs_client_id4 uniquifier string");
1366 : :
1367 : : module_param(recover_lost_locks, bool, 0644);
1368 : : MODULE_PARM_DESC(recover_lost_locks,
1369 : : "If the server reports that a lock might be lost, "
1370 : : "try to recover it risking data corruption.");
1371 : :
1372 : :
1373 : : #endif /* CONFIG_NFS_V4 */
|