struct stat - was: Re: Divergences ...

Andries.Brouwer@cwi.nl
Wed, 6 Mar 1996 03:21:08 +0100


: From dholland@hcs.harvard.edu Wed Mar 6 01:32:57 1996

: > My point was that it is necessary, absolutely necessary,
: > to have well-defined include files. That consequently it is
: > a bad mistake to include unknown and varying kernel sources.

: You can't avoid it. How do you propose to make sure, then, that libc
: and the kernel have the same notion of what struct stat is? (Just for
: example.)

The idea is not that the libc include files never change.
The idea is that they change once in three months, namely
when one installs a new libc version. Not when one does a
new "make config" in /usr/src/linux.

Since you are the third to mention stat to me - this is what
is in my kernel (linux/fs/stat.c). My new libc works with
old kernels, my new kernel works with old libc's, but only
a new kernel together with a new libc can handle 64-bit
device numbers.

static struct {
unsigned int statbuf_size;
void (*cp_stat)(struct inode *, void *);
} stat_versions[] = {
{ sizeof(struct old_stat), cp_old_stat },
{ sizeof(struct new_stat), cp_new_stat },
{ sizeof(struct longdev_stat), cp_longdev_stat }
};
#define SIZE(a) (sizeof(a) / sizeof((a)[0]))

asmlinkage int sys_versioned_stat(unsigned int version,
char * filename, void * statbuf)
{
struct inode * inode;
int error;

if (version >= SIZE(stat_versions))
return -EINVAL;
error = verify_area(VERIFY_WRITE, statbuf,
stat_versions[version].statbuf_size);
if (error)
return error;
error = namei(filename,&inode);
if (error)
return error;
(* stat_versions[version].cp_stat)(inode,statbuf);
iput(inode);
return 0;
}

asmlinkage int sys_stat(char * filename, struct old_stat * statbuf)
{
return sys_versioned_stat(0, filename, statbuf);
}

asmlinkage int sys_newstat(char * filename, struct new_stat * statbuf)
{
return sys_versioned_stat(1, filename, statbuf);
}

I may, or may not, submit code for a kdev_t type that is a pointer,
to Linus. It is really a pleasure to be able to change

blocksize = BLOCK_SIZE;
if (blksize_size[MAJOR(dev)] && blksize_size[MAJOR(dev)][MINOR(dev)])
blocksize = blksize_size[MAJOR(dev)][MINOR(dev)];
i = blocksize;
blocksize_bits = 0;
while(i != 1) {
blocksize_bits++;
i >>= 1;
}

into

blocksize = dev->blksize;
blocksize_bits = dev->blksize_bits;

but it is a big change, maybe inappropriate in these code freeze times.
Of course the stat and kdev_t changes can be done independently of
each other. But I digress.

Andries