aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/internal.h5
-rw-r--r--fs/nfs/namespace.c19
-rw-r--r--fs/nfs/nfs4namespace.c3
-rw-r--r--fs/nfs/super.c2
4 files changed, 20 insertions, 9 deletions
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 59b133c5d65..a54fe51c1df 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -353,8 +353,9 @@ extern void nfs_sb_active(struct super_block *sb);
353extern void nfs_sb_deactive(struct super_block *sb); 353extern void nfs_sb_deactive(struct super_block *sb);
354 354
355/* namespace.c */ 355/* namespace.c */
356#define NFS_PATH_CANONICAL 1
356extern char *nfs_path(char **p, struct dentry *dentry, 357extern char *nfs_path(char **p, struct dentry *dentry,
357 char *buffer, ssize_t buflen); 358 char *buffer, ssize_t buflen, unsigned flags);
358extern struct vfsmount *nfs_d_automount(struct path *path); 359extern struct vfsmount *nfs_d_automount(struct path *path);
359struct vfsmount *nfs_submount(struct nfs_server *, struct dentry *, 360struct vfsmount *nfs_submount(struct nfs_server *, struct dentry *,
360 struct nfs_fh *, struct nfs_fattr *); 361 struct nfs_fh *, struct nfs_fattr *);
@@ -498,7 +499,7 @@ static inline char *nfs_devname(struct dentry *dentry,
498 char *buffer, ssize_t buflen) 499 char *buffer, ssize_t buflen)
499{ 500{
500 char *dummy; 501 char *dummy;
501 return nfs_path(&dummy, dentry, buffer, buflen); 502 return nfs_path(&dummy, dentry, buffer, buflen, NFS_PATH_CANONICAL);
502} 503}
503 504
504/* 505/*
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index 655925373b9..dd057bc6b65 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -33,6 +33,7 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ;
33 * @dentry - pointer to dentry 33 * @dentry - pointer to dentry
34 * @buffer - result buffer 34 * @buffer - result buffer
35 * @buflen - length of buffer 35 * @buflen - length of buffer
36 * @flags - options (see below)
36 * 37 *
37 * Helper function for constructing the server pathname 38 * Helper function for constructing the server pathname
38 * by arbitrary hashed dentry. 39 * by arbitrary hashed dentry.
@@ -40,8 +41,14 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ;
40 * This is mainly for use in figuring out the path on the 41 * This is mainly for use in figuring out the path on the
41 * server side when automounting on top of an existing partition 42 * server side when automounting on top of an existing partition
42 * and in generating /proc/mounts and friends. 43 * and in generating /proc/mounts and friends.
44 *
45 * Supported flags:
46 * NFS_PATH_CANONICAL: ensure there is exactly one slash after
47 * the original device (export) name
48 * (if unset, the original name is returned verbatim)
43 */ 49 */
44char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen) 50char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen,
51 unsigned flags)
45{ 52{
46 char *end; 53 char *end;
47 int namelen; 54 int namelen;
@@ -74,7 +81,7 @@ rename_retry:
74 rcu_read_unlock(); 81 rcu_read_unlock();
75 goto rename_retry; 82 goto rename_retry;
76 } 83 }
77 if (*end != '/') { 84 if ((flags & NFS_PATH_CANONICAL) && *end != '/') {
78 if (--buflen < 0) { 85 if (--buflen < 0) {
79 spin_unlock(&dentry->d_lock); 86 spin_unlock(&dentry->d_lock);
80 rcu_read_unlock(); 87 rcu_read_unlock();
@@ -91,9 +98,11 @@ rename_retry:
91 return end; 98 return end;
92 } 99 }
93 namelen = strlen(base); 100 namelen = strlen(base);
94 /* Strip off excess slashes in base string */ 101 if (flags & NFS_PATH_CANONICAL) {
95 while (namelen > 0 && base[namelen - 1] == '/') 102 /* Strip off excess slashes in base string */
96 namelen--; 103 while (namelen > 0 && base[namelen - 1] == '/')
104 namelen--;
105 }
97 buflen -= namelen; 106 buflen -= namelen;
98 if (buflen < 0) { 107 if (buflen < 0) {
99 spin_unlock(&dentry->d_lock); 108 spin_unlock(&dentry->d_lock);
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index 79fbb61ce20..1e09eb78543 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -81,7 +81,8 @@ static char *nfs_path_component(const char *nfspath, const char *end)
81static char *nfs4_path(struct dentry *dentry, char *buffer, ssize_t buflen) 81static char *nfs4_path(struct dentry *dentry, char *buffer, ssize_t buflen)
82{ 82{
83 char *limit; 83 char *limit;
84 char *path = nfs_path(&limit, dentry, buffer, buflen); 84 char *path = nfs_path(&limit, dentry, buffer, buflen,
85 NFS_PATH_CANONICAL);
85 if (!IS_ERR(path)) { 86 if (!IS_ERR(path)) {
86 char *path_component = nfs_path_component(path, limit); 87 char *path_component = nfs_path_component(path, limit);
87 if (path_component) 88 if (path_component)
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index e831bce4976..13c2a5be476 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -771,7 +771,7 @@ int nfs_show_devname(struct seq_file *m, struct dentry *root)
771 int err = 0; 771 int err = 0;
772 if (!page) 772 if (!page)
773 return -ENOMEM; 773 return -ENOMEM;
774 devname = nfs_path(&dummy, root, page, PAGE_SIZE); 774 devname = nfs_path(&dummy, root, page, PAGE_SIZE, 0);
775 if (IS_ERR(devname)) 775 if (IS_ERR(devname))
776 err = PTR_ERR(devname); 776 err = PTR_ERR(devname);
777 else 777 else