LWN.net Logo

Re: [PATCH] new system call mknod64

From:  "H. Peter Anvin" <hpa@zytor.com>
To:  linux-kernel@vger.kernel.org
Subject:  Re: [PATCH] new system call mknod64
Date:  21 Apr 2003 12:59:13 -0700

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
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


(Log in to post comments)

Copyright © 2003, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds