Re: [PATCH] Add getdents32t syscall

From: Linus Torvalds
Date: Thu Feb 26 2004 - 17:15:38 EST




On Thu, 26 Feb 2004, Jakub Jelinek wrote:
>
> glibc struct dirent has d_type field (similarly to struct dirent64).
> Because no 32-bit getdents syscall provides this field to userland,
> glibc needs to use getdents64 syscall even for 32-bit getdents
> (and readdir etc.) and convert dirent entries from struct dirent64
> to struct dirent. The code is quite complicated and as the former
> is bigger and the size of 64-bit dirents cannot be predicted accurately,
> it can happen that glibc reads too many entries and has to seek back
> on the dir etc.

Nooo..

Please just use the old "getdents()", and if you really really need this,
add the "type" char after the end of the name.

This is a two-liner change (yeah, and we'd need to add a flag saying we do
this).

In other words, what's wrong with this much simpler "extended getdents"
instead?

Linus

--- 1.23/fs/readdir.c Tue Feb 3 21:29:14 2004
+++ edited/fs/readdir.c Thu Feb 26 14:12:57 2004
@@ -139,7 +139,7 @@
{
struct linux_dirent __user * dirent;
struct getdents_callback * buf = (struct getdents_callback *) __buf;
- int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
+ int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2);

buf->error = -EINVAL; /* only used if we fail.. */
if (reclen > buf->count)
@@ -157,6 +157,8 @@
if (copy_to_user(dirent->d_name, name, namlen))
goto efault;
if (__put_user(0, dirent->d_name + namlen))
+ goto efault;
+ if (__put_user(d_type, dirent->d_name + namlen + 1))
goto efault;
buf->previous = dirent;
dirent = (void *)dirent + reclen;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/