Add some more debug to cache_inode_readdir.c

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Add fsal_private to req_op_context

This is a void * that allows the FSAL to attach private data to the current
request.

This is useful when the FSAL calls back to cache_inode and is then
subsequently called again.

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Add FSAL_PSEUDO

FSAL_PSEUDO will be used to implement the PseudoFS segments.

It will support multiple PseudoFS segments (file systems).

For a PseudoFS segment at "/", it will generate the same handles that
Ganesha 1.5 and 2.0 generate for PseudoFS.

This FSAL does not support any files other than directories.

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Convert FSAL_PSEUDO to avl representation.

As in the dirent package, pseudofs entries are in two avl
trees, one ordered by name, the other by index.

Removes linear searches, in exchange for sorted inserts
and rotations, as usual.

Bug with empty directory fixed by FSF.

Signed-off-by: Matt Benjamin <matt@linuxbox.com>
Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Add lookup parent to FSAL_PSEUDO

To handle cache_inode_lookupp we need to be able to handle lookup
parent in the FSAL.

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Add inline function to take a reference on a gsh_export

Any place we are just taking a reference on an already found gsh_export
we just need to increment the refcount.

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Refactoring in nfs4_op_readdir.c

Do some refactoring to make the code easier to read and set up
to add junction processing.

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Fix return code in nfs_export_get_root_entry

If cache_inode_new_entry returned CACHE_INODE_ENTRY_EXISTS,
nfs_export_get_root_entry would pass that on to it's caller,
which is not right, all it cares is that the entry was found
and usable.

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Make nfs_export_get_root_entry return a reference to the cache inode entry

Since nfs_export_get_root_entry "looks up" a cache inode entry, it
should return a reference to that entry that the caller is responsible
for calling cache_inode_put for when done with it.

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Add some junction support to cache_inode

The big addition is that cache_inode_getattr must be able to cross a
junction at the request of the call back routine. The way this will work
is that the call back routine will return CACHE_INODE_CROSS_JUNCTION
which will signal cache_inode_getattr to cross the junction and make a
new callback with the node on the other side of the junction.

The callback routine is responsible for any tracking it must do to
know it has been called back with the node across the junction. The
callback routine is also responsible for handling any export permission
considerations of the junction crossing.

This capability is simply a helper and is to allow enforcing of proper
use of the attribute lock. We don't want to acquire the lock for the
node accross the junction while holding the lock for the junction node.
This can especially be an issue with a mid-filesystem junction where
there the junction node and the root node are one and the same.

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Add new junction support for NFS v4 LOOKUPP

LOOKUPP will have to handle export changes on reverse junction crossing.
To accomplish this, we also need some "parent" information in the export
so when we take the reverse junction out of the root of the export, we
know where to go.

Also make sure all our references are correct.

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Add new junction support to NFS v4 LOOKUP

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Add new junction support to NFS v4 READDIR

This is all handled inside the callback. When called back on a junction
node, we cross the junction, doing export permission checking and
generating new creds.

If the new export is not available to the particular client because of
export permissions, the entry is completely hidden from that client.

If the client is not using the right authentication flavor, but is just
requesting FATTR4_MOUNTED_ON_FILEID, then we allow the operation to
proceed (AIX clients depend on this).

Otherwise, if the authentication is not right, we report the
NFS4ERR_WRONGSEC in the FATTR4_RDATTR_ERROR field (if present, otherwise
the whole READDIR operation must fail).

Otherwise, the junction is crossed, and we signal cache_inode_getattr to
callback with the node across the junction. We process it.

In all cases, the export and credentials are restored.

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Allow for EXPORT config of export_id = 0

This doesn't hook it up to anything yet. It just allows the existence of
a config for export_id = 0 while still using the old Pseudo FS.

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Remove BuildDefaultExport (dead code)

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Add export for export_id = 0 if wasn't configured

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Make export iterators return false if any callback returns false

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Fix get_gsh_export_by_path and get_gsh_export_by_pseudo

These routines have to distinguish requirement for exact match and
partial match. Export config processing needs exact match to detect
duplicates, while mounting requires partial match since the mount
path might be a sub-directoru of an export.

Also fix up some bits in export parsing.

Also add locked versions for use when called from iterators.

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Don't lookup export in cache_inode_get_keyed

We actually have the export in the req_ctx. This eliminates the need to
acquire the export_by_id.lock lock here, which would be bad because while
constructing the Pseudo FS, we hold that lock, and could end up calling
cache_inode_get_keyed.

Put an assert in to catch us if the assumption is actually wrong.

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Add routines to mount an export in the new Pseudo FS

This is the big building block for creating a new Pseudo FS on top of
cache_inode and FSAL_PSEUDO.

pseudo_mount_export() will take a defined export, and use it's Pseudo
Path to find the export it would be mounted on, and then assure that
said export has the directory tree to support the mounted export. If a
directory is missing, it will be created.

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>