vfs: use __getname/__putname for getcwd() system call
It's a pathname. It should use the pathname allocators and deallocators, and PATH_MAX instead of PAGE_SIZE. Never mind that the two are commonly the same. With this, the allocations scale up nicely too, and I can do getcwd() system calls at a rate of about 300M/s, with no lock contention anywhere. Of course, nobody sane does that, especially since getcwd() is traditionally a very slow operation in Unix. But this was also the simplest way to benchmark the prepend_path() improvements by Waiman, and once I saw the profiles I couldn't leave it well enough alone. But apart from being an performance improvement (from using per-cpu slab allocators instead of the raw page allocator), it's actually a valid and real cleanup. Signed-off-by: Linus "OCD" Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
ff812d7242
commit
3272c544da
10
fs/dcache.c
10
fs/dcache.c
|
@ -3049,7 +3049,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
|
|||
{
|
||||
int error;
|
||||
struct path pwd, root;
|
||||
char *page = (char *) __get_free_page(GFP_USER);
|
||||
char *page = __getname();
|
||||
|
||||
if (!page)
|
||||
return -ENOMEM;
|
||||
|
@ -3061,8 +3061,8 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
|
|||
br_read_lock(&vfsmount_lock);
|
||||
if (!d_unlinked(pwd.dentry)) {
|
||||
unsigned long len;
|
||||
char *cwd = page + PAGE_SIZE;
|
||||
int buflen = PAGE_SIZE;
|
||||
char *cwd = page + PATH_MAX;
|
||||
int buflen = PATH_MAX;
|
||||
|
||||
prepend(&cwd, &buflen, "\0", 1);
|
||||
error = prepend_path(&pwd, &root, &cwd, &buflen);
|
||||
|
@ -3080,7 +3080,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
|
|||
}
|
||||
|
||||
error = -ERANGE;
|
||||
len = PAGE_SIZE + page - cwd;
|
||||
len = PATH_MAX + page - cwd;
|
||||
if (len <= size) {
|
||||
error = len;
|
||||
if (copy_to_user(buf, cwd, len))
|
||||
|
@ -3092,7 +3092,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
|
|||
}
|
||||
|
||||
out:
|
||||
free_page((unsigned long) page);
|
||||
__putname(page);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue