Subject: a faq on broken aliass (was Re: Fixed file ID's)

From: a sun <[email-masked]>
Date: Tue, 18 Jan 2000 01:35:36 -0800

[another question on broken aliases and fixed file id's ...]

if somebody could enter this as a faq, that would be great. there
seems to be some confusion on why aliases don't work. here's the
answer:
	1) macos pre-8.6 used a path composed of fileid/directory id's
	   to lookup aliases. 
	2) in afpd, file id's are fixed, but directory id's are
	   variable. 

as a result, macos pre-8.6 will just fail with aliases that refer to
files that are more than one directory level deep. with macos 8.6 or
higher, the alias manager will attempt to resolve those by
pathname. as long as a directory doesn't get assigned the same
directory id as one in the alias, things should be all right. for
files, this algorithm should be good enough as file id's are not
likely to be duplicated on a system. for directory aliases, however,
this can fail because directory ids can get re-assigned between
connections.

anyways, i'm going to stick in a workaround that should handle things
until we get proper catalogue database support. currently, this is how
file id's are assigned:
	16 bits: device
	16 bits: inode

i'll change the id assignment to look like the following:
         1 bit:  directory/file identifier (set == it's a file)
        13 bits: device
        18 bits: inode 

18 bits allows for 262144 files on the same device while 13 bits for
devices should still be reasonably unique. oh yeah, i'll use lstat as
well so that symbolic links have their own numbers as well. 

there. is everybody happy now? i'll release something right after i
finish up some codepage work.

-a

---

From: "Robert B. Bell" <[email-masked]>
Date: Tue, 18 Jan 2000 10:44:20 -0800

>there. is everybody happy now?

And there was much rejoicing!

---

From: "Robert B. Bell" <[email-masked]>
Date: Tue, 01 Feb 2000 12:11:13 -0800

>finish up some codepage work.

I am having problems with the same "16 bit" inode numbers
in the SAME directory.
I am using Red Hat 6.0 i386 with netatalk-1.4b2+asun2.1.4-37b.
I have four share volumes (each on its own ext2 file system).
The largest of these 4 volumes is 4 GB.
When I did the mkfs, I did not specify the number of inodes,
and it created on the 4 GB drive 1048576 inodes
which means it is a 20 bit inode number.

Therefore, I believe I created the code to do what Adrian wanted,
but with the following changes:
   1 bit:  directory/file identifier (set == it's a file)
  11 bits: device
  20 bits: inode 

Here is my diff, I have compiled it, but not tested it.
I have not setup a test bed yet.
I only have my production system with 14 people using it
via netatalk at the moment.

So I was wondering,
is this the right patch to do what Adrian was planning to do?

diff -rc netatalk-1.4b2+asun2.1.4/etc/afpd/file.c
netatalk-1.4b2+asun2.1.4.new/etc/afpd/file.c
*** netatalk-1.4b2+asun2.1.4/etc/afpd/file.c	Sun Jan  2 22:45:09 2000
--- netatalk-1.4b2+asun2.1.4.new/etc/afpd/file.c	Tue Feb  1 11:43:12 2000
***************
*** 199,205 ****
  #ifdef AFS
  	      aint = htonl(st->st_ino);
  #else AFS
! 	      aint = htonl(( st->st_dev << 16 ) | (st->st_ino & 0x0000ffff));
  #endif AFS
  #if AD_VERSION > AD_VERSION1
  	    }
--- 199,207 ----
  #ifdef AFS
  	      aint = htonl(st->st_ino);
  #else AFS
! 	      aint = htonl(( S_ISREG( st->st_mode ) ? 0x10000000 : 0 )
! 			   | (( st->st_dev << 20 )  & 0x7ff00000 )
! 			   | (st->st_ino            & 0x000fffff));
  #endif AFS
  #if AD_VERSION > AD_VERSION1
  	    }
diff -rc netatalk-1.4b2+asun2.1.4/etc/afpd/fork.c
netatalk-1.4b2+asun2.1.4.new/etc/afpd/fork.c
*** netatalk-1.4b2+asun2.1.4/etc/afpd/fork.c	Mon Dec 13 22:29:26 1999
--- netatalk-1.4b2+asun2.1.4.new/etc/afpd/fork.c	Tue Feb  1 11:43:54 2000
***************
*** 180,186 ****
  #ifdef AFS
  	      aint = st.st_ino;
  #else AFS
! 	      aint = ( st.st_dev << 16 ) | ( st.st_ino & 0x0000ffff );
  #endif AFS
  #if AD_VERSION > AD_VERSION1
  	    }
--- 180,188 ----
  #ifdef AFS
  	      aint = st.st_ino;
  #else AFS
! 	      aint = ( S_ISREG( st.st_mode ) ? 0x10000000 : 0 )
! 		   | (( st.st_dev << 20 )    & 0x7ff00000 )
! 		   | (st.st_ino              & 0x000fffff);
  #endif AFS
  #if AD_VERSION > AD_VERSION1
  	    }

Thank you,
  Robert Bell.

---

From: "Markus Pallo" <[email-masked]>
Date: Wed, 2 Feb 2000 11:32:26 +0100

Hello,

our filesystem is bigger than 4 GB (approx. 60 GB :-) ). Are 11 bits for the
device really necessary ? I have now idea for what it is used for ?

Thank you for answering........

Markus Pallo

---

From: "Robert B. Bell" <[email-masked]>
Date: Wed, 02 Feb 2000 12:48:04 -0800

The device field is unique for each disk drive you have.
The combination of device number and inode number
is unique on your system.

The device field (st_dev in fstat() or stat() is of type dev_t 
which is a long long = 64 bits on my linux box).
(The inode field is long = 32 bits.)
So by shortening it, it could cause problems,
but the bottom 11 bits are unique for the 5 disk drives
I have connected to it.
Under linux 2.2, the device number field is the 
the disk drive's device major number 
shifted left 8 bits ORed with the minor number.
For example, one of my SCSI drives, /dev/sdb1 
has major number 8 and minor number 17.
Thus the st_dev field would be 2065. or 0x811
/dev/sbc1 has same major number, and the minor number is 33 (0x821).
/dev/sbd1 has minor = 49 (0x831).
/dev/sbe1 has minor = 65 (0x841).
Which are all still unique when masked 
to a 11 bit values on my system.

The problem I have is the inode numbers are not unique with 16 bits
which is what netatalk+asun currently has.

I think one of the causes of dancing icons 
may be the result of two or more files 
in the same directory/folder having 
the same number when using only the bottom 16 bits of the inode number.

Does that help :)
  Robert.

---

From: a sun <[email-masked]>
Date: Mon, 7 Feb 2000 11:09:15 -0800

fyi,

here's how i'm currently using device/inode bits:

       1 bit  = file/directory identifier    
       4 bits = major device #
       3 bits = minor device #
      24 bits = inode

-a