Re: [PATCH 4/4] eCryptfs: ino_t to u64 for filldir

From: David Howells
Date: Fri Aug 25 2006 - 18:56:38 EST


Michael Halcrow <mhalcrow@xxxxxxxxxx> wrote:

> > > filldir()'s inode number is now type u64 instead of ino_t.
> >
> > Btw, in ecryptfs_interpose(), you have:
> >
> > inode = iget(sb, lower_inode->i_ino);
> >
> > But you have to be *very* *very* careful doing that. i_ino may be
> > ambiguous. My suggestions to make i_ino bigger were turned down by
> > Al Viro; and even it were bigger, it might still not be unique.
>
> Is this the case as long as we stay under the same mountpoint?

Yes.

Imagine, for a moment, that you are running on a 32-bit system, and that you
are using, say, XFS, and that XFS has 64-bit inode numbers. i_ino is 32-bits,
so clearly XFS can't place its full inode number in there.

What XFS can do is:

(1) Use iget5 to do its own inode search and set, disregarding i_ino for that
purpose.

(2) Place just the lower 32-bits of the inode number in i_ino.

(3) Return the 64-bit inode number directly through the getattr() and
readdir() ops, without recourse to i_ino.

(4) Ignore i_ino entirely, except for spicing up printk()'s.


Now, consider, say, NFS. NFS now puts some or all of 64-bit inode numbers in
the i_ino field, but it actually differentiates inodes using iget5 and
comparing file handles - which it really can't represent in i_ino.

It doesn't actually check that the server hasn't given it two fileids the same,
so even with a 64-bit i_ino, you just have to hope that you can get unique
values.

And, in fact, imagine the following scenario:

(1) An NFS inode with fileid N is in the client's icache, and this corresponds
to some remote file on the server.

(2) The remote file is then deleted (but the client isn't told).

(3) A new remote file is created that would has the same fileid (N), but a
different file handle.

(4) The client looks up the new remote file under a different name (so
different dentry), and sets up a client inode for it with the new
filehandle.

(5) The client will now have two NFS inodes from the server with the same
fileid, but with different filehandles. As far as the NFS client
filesystem is concerned, they are _different_ files, but as far as
eCryptFS is concerned, they are the _same_ because is passed the lower
i_ino to iget().


I think what you need to do is actually simple. Use iget5 to look up your
inode, using the _pointer_ to the lower inode as the key. Then just fill in
i_ino from the lower inode. The lower inode can't escape whilst you have it
pinned, so the pointer is, in effect, invariant whilst you are using it.

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