Re: Tracing the nfs file

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Fernando Santos <fernando.santos@xxxxxxxxxxxxxxxxxxxxx> wrote:

> Is there a way I can trace the original nfs file from the cache file?

The path can be decoded.  Note that for the purposes of this, the base64
encoding I used is as follows:

	"0123456789"			/* 0 - 9 */
	"abcdefghijklmnopqrstuvwxyz"	/* 10 - 35 */
	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"	/* 36 - 61 */
	"_-"				/* 62 - 63 */

not the traditional one as the traditional one includes the path separator
char '/' as one of the values.

> For example I have a cache file:
>
> /cache/fscache/cache/

We can ignore this.

> @4a/

256-bit hash/checksum of the index key.  This is rendered as hex.

> I03nfs/

The initial 'I' indicates this is an index object.  The remaining chars are:

 (1) a length rendered as two base64-encoded chars, followed by

 (2) the ASCII-encoded index key.  The index key may be divided up into a
     number of path segments if it would exceed 250 characters.  Each segment
     is a directory name.  Segments after the first have a name prefixed with
     a '+' character.

This is an entry in the first index and represents the network filesystem
name, in this case NFS.

> @6c/

256-bit hash...

> Jc000000000000Eg14Q40/

The initial 'J' indicates this is an index object that can't be represented as
straight ASCII.  The remaining chars are:

 (1) the base64-encoded index key.  There is no length and the key is
     zero-padded out to a multiple of 3 bytes (each group rendered as 4
     chars).  This may be split into names of 252 characters, with second and
     subsequent names prefixed with a '+'.

In this case, the NFS second-level index is laid out as this.

	struct nfs_server_key {
		uint16_t	nfsversion;
		uint16_t	family;
		uint16_t	port;
		union {
			struct in_addr	ipv4_addr;
			struct in6_addr ipv6_addr;
		} addr[0];
	};

Just remember, that the first three numbers are in host order.  So the first 8
chars represent the three uint16_t values.

> @c8/

256-bit hash...

> J1100000000000g-x2E10000000000000000M20300080000w000Kb000wFe000jt000oG3000000040000g000000000/

Another 'J' index object.

In this case, the NFS third-level index represents the superblock key:

struct nfs_fscache_key {
	...
	struct {
		struct {
			unsigned long	s_flags;
		} super;

		struct {
			struct nfs_fsid fsid;
			int		flags;
			unsigned int	rsize;
			unsigned int	wsize;
			unsigned int	acregmin;
			unsigned int	acregmax;
			unsigned int	acdirmin;
			unsigned int	acdirmax;
		} nfs_server;

		struct {
			rpc_authflavor_t au_flavor;
		} rpc_auth;

		u8 uniq_len;
		char uniquifier[0];
	} key;
};

The uniquifier at the end is optional and variable length.

> @97/

256-bit hash...


> Ew00g0000fBBvp1200000nYnCY_n3Ag-x2E1g0000fBBv0000

'D' and 'E' are data objects.  The 'D' object has its index key encoded as for
'I' and 'E' as for 'J'.

This starting with an 'E' is base64-encoded after the 'E'.

This being the NFS fourth-level index is the NFS inode key.  It encodes the
NFS inode file handle.  The above is 48 chars.  That would represent 48/4*3
or 36 bytes - or, more accurately, 34-36 bytes.

So you can recover the NFS FH from the above.  Chop the 'E' off of the front.
Decode each group of 4 chars to into 3 bytes.  Given that it's 36 bytes and
XDR likes 4-byte multiples, I would guess that the original handle was 36
bytes.

You may also need to decode the superblock key and extract the FSID.

David

--
Linux-cachefs mailing list
Linux-cachefs@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/linux-cachefs



[Index of Archives]     [LARTC]     [Bugtraq]     [Yosemite Forum]
  Powered by Linux