Fernando Santos <[email protected]> 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
[email protected]
https://www.redhat.com/mailman/listinfo/linux-cachefs

Reply via email to