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