Skip to content

Commit

Permalink
nfs: Show original device name verbatim in /proc/*/mount{s,info}
Browse files Browse the repository at this point in the history
Since commit c7f404b ('vfs: new superblock methods to override
/proc/*/mount{s,info}'), nfs_path() is used to generate the mounted
device name reported back to userland.

nfs_path() always generates a trailing slash when the given dentry is
the root of an NFS mount, but userland may expect the original device
name to be returned verbatim (as it used to be).  Make this
canonicalisation optional and change the callers accordingly.

[jrnieder@gmail.com: use flag instead of bool argument]
Reported-and-tested-by: Chris Hiestand <chiestand@salk.edu>
Reference: http://bugs.debian.org/669314
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Cc: <stable@vger.kernel.org> # v2.6.39+
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
  • Loading branch information
Ben Hutchings authored and Trond Myklebust committed Oct 31, 2012
1 parent acce94e commit 97a5486
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 9 deletions.
5 changes: 3 additions & 2 deletions fs/nfs/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -353,8 +353,9 @@ extern void nfs_sb_active(struct super_block *sb);
extern void nfs_sb_deactive(struct super_block *sb);

/* namespace.c */
#define NFS_PATH_CANONICAL 1
extern char *nfs_path(char **p, struct dentry *dentry,
char *buffer, ssize_t buflen);
char *buffer, ssize_t buflen, unsigned flags);
extern struct vfsmount *nfs_d_automount(struct path *path);
struct vfsmount *nfs_submount(struct nfs_server *, struct dentry *,
struct nfs_fh *, struct nfs_fattr *);
Expand Down Expand Up @@ -498,7 +499,7 @@ static inline char *nfs_devname(struct dentry *dentry,
char *buffer, ssize_t buflen)
{
char *dummy;
return nfs_path(&dummy, dentry, buffer, buflen);
return nfs_path(&dummy, dentry, buffer, buflen, NFS_PATH_CANONICAL);
}

/*
Expand Down
19 changes: 14 additions & 5 deletions fs/nfs/namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,22 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ;
* @dentry - pointer to dentry
* @buffer - result buffer
* @buflen - length of buffer
* @flags - options (see below)
*
* Helper function for constructing the server pathname
* by arbitrary hashed dentry.
*
* This is mainly for use in figuring out the path on the
* server side when automounting on top of an existing partition
* and in generating /proc/mounts and friends.
*
* Supported flags:
* NFS_PATH_CANONICAL: ensure there is exactly one slash after
* the original device (export) name
* (if unset, the original name is returned verbatim)
*/
char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen)
char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen,
unsigned flags)
{
char *end;
int namelen;
Expand Down Expand Up @@ -74,7 +81,7 @@ char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen)
rcu_read_unlock();
goto rename_retry;
}
if (*end != '/') {
if ((flags & NFS_PATH_CANONICAL) && *end != '/') {
if (--buflen < 0) {
spin_unlock(&dentry->d_lock);
rcu_read_unlock();
Expand All @@ -91,9 +98,11 @@ char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen)
return end;
}
namelen = strlen(base);
/* Strip off excess slashes in base string */
while (namelen > 0 && base[namelen - 1] == '/')
namelen--;
if (flags & NFS_PATH_CANONICAL) {
/* Strip off excess slashes in base string */
while (namelen > 0 && base[namelen - 1] == '/')
namelen--;
}
buflen -= namelen;
if (buflen < 0) {
spin_unlock(&dentry->d_lock);
Expand Down
3 changes: 2 additions & 1 deletion fs/nfs/nfs4namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ static char *nfs_path_component(const char *nfspath, const char *end)
static char *nfs4_path(struct dentry *dentry, char *buffer, ssize_t buflen)
{
char *limit;
char *path = nfs_path(&limit, dentry, buffer, buflen);
char *path = nfs_path(&limit, dentry, buffer, buflen,
NFS_PATH_CANONICAL);
if (!IS_ERR(path)) {
char *path_component = nfs_path_component(path, limit);
if (path_component)
Expand Down
2 changes: 1 addition & 1 deletion fs/nfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -771,7 +771,7 @@ int nfs_show_devname(struct seq_file *m, struct dentry *root)
int err = 0;
if (!page)
return -ENOMEM;
devname = nfs_path(&dummy, root, page, PAGE_SIZE);
devname = nfs_path(&dummy, root, page, PAGE_SIZE, 0);
if (IS_ERR(devname))
err = PTR_ERR(devname);
else
Expand Down

0 comments on commit 97a5486

Please sign in to comment.