-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Bernhard Fischer wrote:
| On Wed, Mar 12, 2008 at 12:22:23AM -0700, Khem Raj wrote:
|> On Mar 11, 2008, at 11:56 PM, Basheer, Mansoor Ahamed wrote:
|>
|>>
|>> Robert Wrote [mailto:[EMAIL PROTECTED]
|>>> On Tue, 11 Mar 2008, Khem Raj wrote:
|>>>
|>>>> On Mar 11, 2008, at 11:03 PM, Basheer, Mansoor Ahamed wrote:
|>>>>
|>>>>> Hi,
|>>>>>
|>>>>> Current mknod implementation fails for major/minor number greater
|>> than
|>>> 255.
|>>>> is linux kernel supporting major/minor numbers greater than 255 ?
|>>> the *kernel* supports major/minor numbers of bit length (12,20).
|>>> it's
|>>> only userspace that restricts their values to (8,8).
|>>>
|>> Yes Robert you are right. For example USB endpoint devices use major
|>> 442
|>> (drivers/usb/core/endpoint.c).
|>>
|>> Also, __kernel_dev_t for ARM should be "unsigned int" and not
|>> "unsigned
|>> short".
|>>
|>> Signed-off-by: Mansoor Ahamed <[EMAIL PROTECTED]>
|>>
|>> --- libc/sysdeps/linux/common/mknod.c 2008-03-11 17:43:54.000000000
|>> +0530
|>> +++ libc/sysdeps/linux/common/mknod.c 2008-03-11 17:45:21.000000000
|>> +++ +0530
|>> @@ -20,9 +20,8 @@ static inline _syscall3(int, __syscall_m  int
|>> mknod(const char *path, mode_t mode, dev_t dev)  {
|>>        /* We must convert the dev_t value to a __kernel_dev_t */
|>> -       __kernel_dev_t k_dev;
|>> +       __kernel_dev_t k_dev = (__kernel_dev_t)dev;
|>>
|>> -       k_dev = ((major(dev) & 0xff) << 8) | (minor(dev) & 0xff);
|>>        return __syscall_mknod(path, mode, k_dev);  }
|>> libc_hidden_def(mknod)
|>
|> OK. the change looks ok. A testcase would be good to have.
|
| This change does definitely not look ok, given that it seems to only fix
| a fraction of affected arches, AFAICS?
|
| $ egrep "short.*kernel_dev_t" */bits/*.h
| arm/bits/kernel_types.h:typedef unsigned short          __kernel_dev_t;
| bfin/bits/kernel_types.h:typedef unsigned short __kernel_dev_t;
| cris/bits/kernel_types.h:typedef unsigned short __kernel_dev_t;
| e1/bits/kernel_types.h:typedef unsigned short   __kernel_dev_t;
| frv/bits/kernel_types.h:typedef unsigned short  __kernel_dev_t;
| h8300/bits/kernel_types.h:typedef unsigned short        __kernel_dev_t;
| i386/bits/kernel_types.h:typedef unsigned short __kernel_dev_t;
| m68k/bits/kernel_types.h:typedef unsigned short __kernel_dev_t;
| nios/bits/kernel_types.h:typedef unsigned short __kernel_dev_t;
| sh/bits/kernel_types.h:typedef unsigned short   __kernel_dev_t;
| sh64/bits/kernel_types.h:typedef unsigned short  __kernel_dev_t;
| sparc/bits/kernel_types.h:typedef unsigned short         __kernel_dev_t;
| vax/bits/kernel_types.h:typedef unsigned short  __kernel_dev_t;
|

Here is another patch that avoids using __kernel_dev_t. The above
updates are still not ruled out. But I did not see any other usage of
__kernel_dev_t in the sources.

Additionally we also need to fix ustat() to accept the major minor
versions larger than 255

OK ?

Thanks

- -Khem

- --
Khem Raj
MontaVista Software Inc.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFH616LUjbQJxVzeZQRAtU8AKCaYOxqvkaUt9Fn+OFReIgvo//8RACfVvyK
aTko5DCd+9dkl5/zW2555Qo=
=uywV
-----END PGP SIGNATURE-----
 libc/sysdeps/linux/common/mknod.c |   14 ++++++++++----
 libc/sysdeps/linux/common/ustat.c |   14 ++++++++++----
 2 files changed, 20 insertions(+), 8 deletions(-)

Signed-off-by: Khem Raj <[EMAIL PROTECTED]>

Allow mknod to create nodes with major/minor numbers > 255
Allow ustat to process nodes with have major/minor numbers >255

Index: uclibc-0.9.29/libc/sysdeps/linux/common/mknod.c
===================================================================
--- uclibc-0.9.29.orig/libc/sysdeps/linux/common/mknod.c
+++ uclibc-0.9.29/libc/sysdeps/linux/common/mknod.c
@@ -15,14 +15,20 @@ libc_hidden_proto(mknod)
 
 #define __NR___syscall_mknod __NR_mknod
 static inline _syscall3(int, __syscall_mknod, const char *, path,
-               __kernel_mode_t, mode, __kernel_dev_t, dev);
+               __kernel_mode_t, mode, unsigned int, dev);
 
 int mknod(const char *path, mode_t mode, dev_t dev)
 {
        /* We must convert the dev_t value to a __kernel_dev_t */
-       __kernel_dev_t k_dev;
+       unsigned long long int k_dev;
+       k_dev =  dev & ((1ULL << 32) - 1);
 
-       k_dev = ((major(dev) & 0xff) << 8) | (minor(dev) & 0xff);
-       return __syscall_mknod(path, mode, k_dev);
+       if (k_dev != dev)
+       {
+          __set_errno (EINVAL);
+          return -1;
+       }
+
+       return __syscall_mknod(path, mode, (unsigned int) k_dev);
 }
 libc_hidden_def(mknod)
Index: uclibc-0.9.29/libc/sysdeps/linux/common/ustat.c
===================================================================
--- uclibc-0.9.29.orig/libc/sysdeps/linux/common/ustat.c
+++ uclibc-0.9.29/libc/sysdeps/linux/common/ustat.c
@@ -13,13 +13,19 @@
 
 #define __NR___syscall_ustat __NR_ustat
 static inline _syscall2(int, __syscall_ustat,
-               unsigned short int, kdev_t, struct ustat *, ubuf);
+               unsigned int, kdev_t, struct ustat *, ubuf);
 
 int ustat(dev_t dev, struct ustat *ubuf)
 {
+       unsigned long long int k_dev;
        /* We must convert the dev_t value to a __kernel_dev_t */
-       __kernel_dev_t k_dev;
+       k_dev =  dev & ((1ULL << 32) - 1);
 
-       k_dev = ((major(dev) & 0xff) << 8) | (minor(dev) & 0xff);
-       return __syscall_ustat(k_dev, ubuf);
+       if (k_dev != dev)
+       {
+         __set_errno (EINVAL);
+         return -1;
+       }
+
+       return __syscall_ustat((unsigned int) k_dev, ubuf);
 }
_______________________________________________
uClibc mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/uclibc

Reply via email to