| From 118b23022512eb2f41ce42db70dc0568d00be4ba Mon Sep 17 00:00:00 2001 |
| From: Al Viro <viro@zeniv.linux.org.uk> |
| Date: Sat, 24 Aug 2013 12:08:17 -0400 |
| Subject: cope with potentially long ->d_dname() output for |
| shmem/hugetlb |
| |
| From: Al Viro <viro@zeniv.linux.org.uk> |
| |
| commit 118b23022512eb2f41ce42db70dc0568d00be4ba upstream. |
| |
| dynamic_dname() is both too much and too little for those - the |
| output may be well in excess of 64 bytes dynamic_dname() assumes |
| to be enough (thanks to ashmem feeding really long names to |
| shmem_file_setup()) and vsnprintf() is an overkill for those |
| guys. |
| |
| Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> |
| Cc: Colin Cross <ccross@google.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| fs/dcache.c | 11 +++++++++++ |
| fs/hugetlbfs/inode.c | 8 +------- |
| include/linux/dcache.h | 1 + |
| mm/shmem.c | 8 +------- |
| 4 files changed, 14 insertions(+), 14 deletions(-) |
| |
| --- a/fs/dcache.c |
| +++ b/fs/dcache.c |
| @@ -2724,6 +2724,17 @@ char *dynamic_dname(struct dentry *dentr |
| return memcpy(buffer, temp, sz); |
| } |
| |
| +char *simple_dname(struct dentry *dentry, char *buffer, int buflen) |
| +{ |
| + char *end = buffer + buflen; |
| + /* these dentries are never renamed, so d_lock is not needed */ |
| + if (prepend(&end, &buflen, " (deleted)", 11) || |
| + prepend_name(&end, &buflen, &dentry->d_name) || |
| + prepend(&end, &buflen, "/", 1)) |
| + end = ERR_PTR(-ENAMETOOLONG); |
| + return end; |
| +} |
| + |
| /* |
| * Write full pathname from the root of the filesystem into the buffer. |
| */ |
| --- a/fs/hugetlbfs/inode.c |
| +++ b/fs/hugetlbfs/inode.c |
| @@ -916,14 +916,8 @@ static int get_hstate_idx(int page_size_ |
| return h - hstates; |
| } |
| |
| -static char *hugetlb_dname(struct dentry *dentry, char *buffer, int buflen) |
| -{ |
| - return dynamic_dname(dentry, buffer, buflen, "/%s (deleted)", |
| - dentry->d_name.name); |
| -} |
| - |
| static struct dentry_operations anon_ops = { |
| - .d_dname = hugetlb_dname |
| + .d_dname = simple_dname |
| }; |
| |
| /* |
| --- a/include/linux/dcache.h |
| +++ b/include/linux/dcache.h |
| @@ -332,6 +332,7 @@ extern int d_validate(struct dentry *, s |
| * helper function for dentry_operations.d_dname() members |
| */ |
| extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...); |
| +extern char *simple_dname(struct dentry *, char *, int); |
| |
| extern char *__d_path(const struct path *, const struct path *, char *, int); |
| extern char *d_absolute_path(const struct path *, char *, int); |
| --- a/mm/shmem.c |
| +++ b/mm/shmem.c |
| @@ -2879,14 +2879,8 @@ EXPORT_SYMBOL_GPL(shmem_truncate_range); |
| |
| /* common code */ |
| |
| -static char *shmem_dname(struct dentry *dentry, char *buffer, int buflen) |
| -{ |
| - return dynamic_dname(dentry, buffer, buflen, "/%s (deleted)", |
| - dentry->d_name.name); |
| -} |
| - |
| static struct dentry_operations anon_ops = { |
| - .d_dname = shmem_dname |
| + .d_dname = simple_dname |
| }; |
| |
| /** |