Re: [PATCH] new system call mknod64

H. Peter Anvin
2003-04-21T19:48:19Z

Followup to: <Pine.LNX.4.44.0304211153270.9109-100000@home.transmeta.com>
By author: Linus Torvalds <torvalds@transmeta.com>
In newsgroup: linux.dev.kernel
>
> But that _will_ force aliasing, unless you start doing some really funky
> things (make the dev_t look more like a UTF-8 unicode-like extension,
> which is obviously possible). In other words, there will be OTHER values
> for "dev_t" that will _also_ look like the tuple <3,1>.
>
> - other values of dev_t that also look like <3,1> had better act
> _identically_ to the legacy values. It _has_ to work this way, since
> otherwise you'd have a total maintenance nightmare, with "ls -l"
> showing two device files as being identical, yet having different
> behaviour.
>

Actually, the lessons learned from many things including UTF-8 (which
unfortunately does have aliasing) seems to indicate that the only
right answer is that noncanonical aliases are *illegal.* If we do
mapping on the syscall boundary, then the kernel will always report
canonical form, and we should just throw -EINVAL on receiving a
noncanonical device number if such a thing can exist at all.

FWIW, here is a completely alias-free encoding of dev_t which is also
backwards compatible and hole-free:

dev_t := major<31:8> . minor<31:8> . major<7:0> . minor<7:0>

where . is bitwise concatenation. One of the major advantages, other
that being alias-free, is that the resulting code is free from
conditionals.

typedef __u64 dev_t;

static inline __u32 MAJOR(dev_t __d)
{
return (__u32)(__d >> 32) & 0xffffff00 |
(__u32)(__d >> 8) & 0x000000ff;
}
static inline __u32 MINOR(dev_t __d)
{
return (__u32)(__d >> 8) & 0xffffff00 |
(__u32)__d & 0x000000ff;
}
static inline dev_t MKDEV(__u32 __ma, __u32 __mi)
{
return ((dev_t)(__ma & 0xffffff00) << 32) |
((dev_t)(__ma & 0x000000ff) << 8) |
((dev_t)(__mi & 0xffffff00) << 8) |
((dev_t)__mi & 0x000000ff);
}

In i386 assembly language, using regcall(%eax,%edx,%ecx):

MAJOR:
movb %ah,%dl
movl %edx,%eax
ret

MINOR:
movb %al,%ah
movb %dl,%al
rorl $8,%eax
ret

MKDEV:
movl %eax,%ecx
shll $8,%eax
movb %dl,%ah
movb %cl,%al
shrl $24,%ecx
movb %cl,%dl
ret
--
<hpa@transmeta.com> at work, <hpa@zytor.com> in private!
"Unix gives you enough rope to shoot yourself in the foot."
Architectures needed: ia64 m68k mips64 ppc ppc64 s390 s390x sh v850 x86-64