Skip to content
This repository has been archived by the owner on Feb 11, 2024. It is now read-only.

Commit

Permalink
mm: Eliminate d_path_outlen() and further speed up show_map_vma()
Browse files Browse the repository at this point in the history
d_path_outlen() isn't needed because we know that d_path() always
populates the given buffer backwards starting from the last byte; with
this, we can easily calculate the length of the generated string by
using the returned pointer from d_path() and the size of the buffer
given to d_path(). This eliminates the need for d_path_outlen() and
removes the bizarre strlen() usage, which makes things simpler and
faster. We also now avoid a memmove() when d_path() completely uses up
its provided buffer.

Signed-off-by: Sultan Alsawaf <[email protected]>
Change-Id: Ia52d062e7e12d9075a092f334ae49d9085fef03f
  • Loading branch information
kerneltoast authored and YumeMichi committed Dec 30, 2023
1 parent 1b5a371 commit 016a204
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 18 deletions.
13 changes: 4 additions & 9 deletions fs/d_path.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,9 +249,9 @@ static void get_fs_root_rcu(struct fs_struct *fs, struct path *root)
*
* "buflen" should be positive.
*/
char *d_path_outlen(const struct path *path, char *buf, int *buflen)
char *d_path(const struct path *path, char *buf, int buflen)
{
char *res = buf + *buflen;
char *res = buf + buflen;
struct path root;
int error;

Expand All @@ -268,22 +268,17 @@ char *d_path_outlen(const struct path *path, char *buf, int *buflen)
*/
if (path->dentry->d_op && path->dentry->d_op->d_dname &&
(!IS_ROOT(path->dentry) || path->dentry != path->mnt->mnt_root))
return path->dentry->d_op->d_dname(path->dentry, buf, *buflen);
return path->dentry->d_op->d_dname(path->dentry, buf, buflen);

rcu_read_lock();
get_fs_root_rcu(current->fs, &root);
error = path_with_deleted(path, &root, &res, buflen);
error = path_with_deleted(path, &root, &res, &buflen);
rcu_read_unlock();

if (error < 0)
res = ERR_PTR(error);
return res;
}

char *d_path(const struct path *path, char *buf, int buflen)
{
return d_path_outlen(path, buf, &buflen);
}
EXPORT_SYMBOL(d_path);

/*
Expand Down
13 changes: 5 additions & 8 deletions fs/proc/task_mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -528,19 +528,16 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
* program uses newlines in its paths then it can kick rocks.
*/
if (size > 1) {
const int inlen = size - 1;
int outlen = inlen;
char *p;

p = d_path_outlen(&file->f_path, buf, &outlen);
p = d_path(&file->f_path, buf, size);
if (!IS_ERR(p)) {
size_t len;

if (outlen != inlen)
len = inlen - outlen - 1;
else
len = strlen(p);
memmove(buf, p, len);
/* Minus one to exclude the NUL character */
len = size - (p - buf) - 1;
if (likely(p > buf))
memmove(buf, p, len);
buf[len] = '\n';
seq_commit(m, len + 1);
return;
Expand Down
1 change: 0 additions & 1 deletion include/linux/dcache.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,6 @@ 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);
extern char *d_path(const struct path *, char *, int);
extern char *d_path_outlen(const struct path *, char *, int *);
extern char *dentry_path_raw(struct dentry *, char *, int);
extern char *dentry_path(struct dentry *, char *, int);

Expand Down

0 comments on commit 016a204

Please sign in to comment.