1 // SPDX-License-Identifier: GPL-2.0-only
3 * linux/fs/nfs/namespace.c
5 * Copyright (C) 2005 Trond Myklebust <Trond.Myklebust@netapp.com>
6 * - Modified by David Howells <dhowells@redhat.com>
11 #include <linux/module.h>
12 #include <linux/dcache.h>
13 #include <linux/gfp.h>
14 #include <linux/mount.h>
15 #include <linux/namei.h>
16 #include <linux/nfs_fs.h>
17 #include <linux/string.h>
18 #include <linux/sunrpc/clnt.h>
19 #include <linux/vfs.h>
20 #include <linux/sunrpc/gss_api.h>
24 #define NFSDBG_FACILITY NFSDBG_VFS
26 static void nfs_expire_automounts(struct work_struct
*work
);
28 static LIST_HEAD(nfs_automount_list
);
29 static DECLARE_DELAYED_WORK(nfs_automount_task
, nfs_expire_automounts
);
30 int nfs_mountpoint_expiry_timeout
= 500 * HZ
;
33 * nfs_path - reconstruct the path given an arbitrary dentry
34 * @base - used to return pointer to the end of devname part of path
35 * @dentry_in - pointer to dentry
36 * @buffer - result buffer
37 * @buflen_in - length of buffer
38 * @flags - options (see below)
40 * Helper function for constructing the server pathname
41 * by arbitrary hashed dentry.
43 * This is mainly for use in figuring out the path on the
44 * server side when automounting on top of an existing partition
45 * and in generating /proc/mounts and friends.
48 * NFS_PATH_CANONICAL: ensure there is exactly one slash after
49 * the original device (export) name
50 * (if unset, the original name is returned verbatim)
52 char *nfs_path(char **p
, struct dentry
*dentry_in
, char *buffer
,
53 ssize_t buflen_in
, unsigned flags
)
59 struct dentry
*dentry
;
69 seq
= read_seqbegin(&rename_lock
);
72 spin_lock(&dentry
->d_lock
);
75 namelen
= dentry
->d_name
.len
;
76 buflen
-= namelen
+ 1;
80 memcpy(end
, dentry
->d_name
.name
, namelen
);
82 spin_unlock(&dentry
->d_lock
);
83 dentry
= dentry
->d_parent
;
85 if (read_seqretry(&rename_lock
, seq
)) {
86 spin_unlock(&dentry
->d_lock
);
90 if ((flags
& NFS_PATH_CANONICAL
) && *end
!= '/') {
92 spin_unlock(&dentry
->d_lock
);
99 base
= dentry
->d_fsdata
;
101 spin_unlock(&dentry
->d_lock
);
106 namelen
= strlen(base
);
108 /* Strip off excess slashes in base string */
109 while (namelen
> 0 && base
[namelen
- 1] == '/')
114 spin_unlock(&dentry
->d_lock
);
119 memcpy(end
, base
, namelen
);
120 spin_unlock(&dentry
->d_lock
);
124 spin_unlock(&dentry
->d_lock
);
126 if (read_seqretry(&rename_lock
, seq
))
129 return ERR_PTR(-ENAMETOOLONG
);
131 EXPORT_SYMBOL_GPL(nfs_path
);
134 * nfs_d_automount - Handle crossing a mountpoint on the server
135 * @path - The mountpoint
137 * When we encounter a mountpoint on the server, we want to set up
138 * a mountpoint on the client too, to prevent inode numbers from
139 * colliding, and to allow "df" to work properly.
140 * On NFSv4, we also want to allow for the fact that different
141 * filesystems may be migrated to different servers in a failover
142 * situation, and that different filesystems may want to use
143 * different security flavours.
145 struct vfsmount
*nfs_d_automount(struct path
*path
)
147 struct nfs_fs_context
*ctx
;
148 struct fs_context
*fc
;
149 struct vfsmount
*mnt
= ERR_PTR(-ENOMEM
);
150 struct nfs_server
*server
= NFS_SERVER(d_inode(path
->dentry
));
151 struct nfs_client
*client
= server
->nfs_client
;
152 int timeout
= READ_ONCE(nfs_mountpoint_expiry_timeout
);
155 if (IS_ROOT(path
->dentry
))
156 return ERR_PTR(-ESTALE
);
158 /* Open a new filesystem context, transferring parameters from the
159 * parent superblock, including the network namespace.
161 fc
= fs_context_for_submount(path
->mnt
->mnt_sb
->s_type
, path
->dentry
);
165 ctx
= nfs_fc2context(fc
);
166 ctx
->clone_data
.dentry
= path
->dentry
;
167 ctx
->clone_data
.sb
= path
->dentry
->d_sb
;
168 ctx
->clone_data
.fattr
= nfs_alloc_fattr();
169 if (!ctx
->clone_data
.fattr
)
172 if (fc
->net_ns
!= client
->cl_net
) {
174 fc
->net_ns
= get_net(client
->cl_net
);
177 /* for submounts we want the same server; referrals will reassign */
178 memcpy(&ctx
->nfs_server
.address
, &client
->cl_addr
, client
->cl_addrlen
);
179 ctx
->nfs_server
.addrlen
= client
->cl_addrlen
;
180 ctx
->nfs_server
.port
= server
->port
;
182 ctx
->version
= client
->rpc_ops
->version
;
183 ctx
->minorversion
= client
->cl_minorversion
;
184 ctx
->nfs_mod
= client
->cl_nfs_mod
;
185 __module_get(ctx
->nfs_mod
->owner
);
187 ret
= client
->rpc_ops
->submount(fc
, server
);
193 up_write(&fc
->root
->d_sb
->s_umount
);
194 mnt
= vfs_create_mount(fc
);
198 mntget(mnt
); /* prevent immediate expiration */
202 mnt_set_expiry(mnt
, &nfs_automount_list
);
203 schedule_delayed_work(&nfs_automount_task
, timeout
);
211 nfs_namespace_getattr(const struct path
*path
, struct kstat
*stat
,
212 u32 request_mask
, unsigned int query_flags
)
214 if (NFS_FH(d_inode(path
->dentry
))->size
!= 0)
215 return nfs_getattr(path
, stat
, request_mask
, query_flags
);
216 generic_fillattr(d_inode(path
->dentry
), stat
);
221 nfs_namespace_setattr(struct dentry
*dentry
, struct iattr
*attr
)
223 if (NFS_FH(d_inode(dentry
))->size
!= 0)
224 return nfs_setattr(dentry
, attr
);
228 const struct inode_operations nfs_mountpoint_inode_operations
= {
229 .getattr
= nfs_getattr
,
230 .setattr
= nfs_setattr
,
233 const struct inode_operations nfs_referral_inode_operations
= {
234 .getattr
= nfs_namespace_getattr
,
235 .setattr
= nfs_namespace_setattr
,
238 static void nfs_expire_automounts(struct work_struct
*work
)
240 struct list_head
*list
= &nfs_automount_list
;
241 int timeout
= READ_ONCE(nfs_mountpoint_expiry_timeout
);
243 mark_mounts_for_expiry(list
);
244 if (!list_empty(list
) && timeout
> 0)
245 schedule_delayed_work(&nfs_automount_task
, timeout
);
248 void nfs_release_automount_timer(void)
250 if (list_empty(&nfs_automount_list
))
251 cancel_delayed_work(&nfs_automount_task
);
255 * nfs_do_submount - set up mountpoint when crossing a filesystem boundary
256 * @fc: pointer to struct nfs_fs_context
259 int nfs_do_submount(struct fs_context
*fc
)
261 struct nfs_fs_context
*ctx
= nfs_fc2context(fc
);
262 struct dentry
*dentry
= ctx
->clone_data
.dentry
;
263 struct nfs_server
*server
;
267 /* create a new volume representation */
268 server
= ctx
->nfs_mod
->rpc_ops
->clone_server(NFS_SB(ctx
->clone_data
.sb
),
270 ctx
->clone_data
.fattr
,
271 ctx
->selected_flavor
);
274 return PTR_ERR(server
);
276 ctx
->server
= server
;
278 buffer
= kmalloc(4096, GFP_USER
);
282 ctx
->internal
= true;
283 ctx
->clone_data
.inherited_bsize
= ctx
->clone_data
.sb
->s_blocksize_bits
;
285 p
= nfs_devname(dentry
, buffer
, 4096);
287 nfs_errorf(fc
, "NFS: Couldn't determine submount pathname");
290 ret
= vfs_parse_fs_string(fc
, "source", p
, buffer
+ 4096 - p
);
292 ret
= vfs_get_tree(fc
);
297 EXPORT_SYMBOL_GPL(nfs_do_submount
);
299 int nfs_submount(struct fs_context
*fc
, struct nfs_server
*server
)
301 struct nfs_fs_context
*ctx
= nfs_fc2context(fc
);
302 struct dentry
*dentry
= ctx
->clone_data
.dentry
;
303 struct dentry
*parent
= dget_parent(dentry
);
306 /* Look it up again to get its attributes */
307 err
= server
->nfs_client
->rpc_ops
->lookup(d_inode(parent
), dentry
,
308 ctx
->mntfh
, ctx
->clone_data
.fattr
,
314 ctx
->selected_flavor
= server
->client
->cl_auth
->au_flavor
;
315 return nfs_do_submount(fc
);
317 EXPORT_SYMBOL_GPL(nfs_submount
);
319 static int param_set_nfs_timeout(const char *val
, const struct kernel_param
*kp
)
326 ret
= kstrtol(val
, 0, &num
);
330 if (num
>= INT_MAX
/ HZ
)
334 *((int *)kp
->arg
) = num
;
335 if (!list_empty(&nfs_automount_list
))
336 mod_delayed_work(system_wq
, &nfs_automount_task
, num
);
338 *((int *)kp
->arg
) = -1*HZ
;
339 cancel_delayed_work(&nfs_automount_task
);
344 static int param_get_nfs_timeout(char *buffer
, const struct kernel_param
*kp
)
346 long num
= *((int *)kp
->arg
);
349 if (num
>= INT_MAX
- (HZ
- 1))
352 num
= (num
+ (HZ
- 1)) / HZ
;
355 return scnprintf(buffer
, PAGE_SIZE
, "%li\n", num
);
358 static const struct kernel_param_ops param_ops_nfs_timeout
= {
359 .set
= param_set_nfs_timeout
,
360 .get
= param_get_nfs_timeout
,
362 #define param_check_nfs_timeout(name, p) __param_check(name, p, int);
364 module_param(nfs_mountpoint_expiry_timeout
, nfs_timeout
, 0644);
365 MODULE_PARM_DESC(nfs_mountpoint_expiry_timeout
,
366 "Set the NFS automounted mountpoint timeout value (seconds)."
367 "Values <= 0 turn expiration off.");