Add safety to struct state_t

In addition to refcounting state_t objects, we also need to protect access
to the other objects it references.

First, each state_t now also holds it's own refcount to the cache entry and
export it belongs to.

Second, a mutex is added to protect the state_entry, state_export, and
state_owner fields.

Third, inline functions are provided to safely take a reference to each
of these objects. This guards against use of a state_t object just after
it has been removed from the stateid table (which also disconnects it from
all of these objects). By taking an independent reference under the
state_mutex, we guarantee those objects will live long enough for the
caller to do what it needs to do.

Fourth, we protect against multiple calls to state_del/state_del_locked. If
we are unable to remove the state_t from the stateid table, then it must
have already been destroyed.

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Make lock_entry_inc_ref static inline and lock_entry_dec_ref static

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Make sure state_nfs4_owner_unlock_all handles stale cache entry and export

And in general clean this up

Now, if we are unable to release all the owner's locks due to too many errors,
issue a LogFatal rather than having Ganesha continue with dangling pointers.

Also, just perform a single loop on lock owners belonging to the clientid.

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Make state_del only deal with unlocked case, and get LRU ref

If the entry is stale, then skip.

The one place that called state_del(state, true) could just call
state_del_locked(state).

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Replace release_lockstate with cleaned up/simplified release_lock_owner

Now that release_lockstate was only being used for the release lock owner
case, simplify it.

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Make sure release_openstate handles stale cache entry and export

Make sure everything is refcounted properly, also hold owner so_mutex
appropriately to protect looking at list of states belonging to owner.

Now, if we are unable to release all the owner's shares due to too many errors,
issue a LogFatal rather than having Ganesha continue with dangling pointers.

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Make sure state_export_unlock_all properly handles ref counting

state_export_unlock_all must protect the cache entry, owner, and state_t
(for NFS v4 locks) that it finds from the lock entry.

When tallying errors, we don't worry about stale cache inode entry errors
since such a cache inode entry will quickly have all it's locks removed,
so the export lock list WILL drain to empty despite the stale entry error.

We no longer take a reference on the lock entry itself since we only use it
while holding the export lock (which prevents the entry from becoming invalid)
to get references on the other objects in order to make a state_unlock
call to unlock the entire file (removing this lock entry and potentially
others if the owner had multiple locks on this file).

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Remove notion of lock type from state_lock.c functions except do_lock_op

All the higher level functions are ONLY called for POSIX_LOCKs.

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Replace lock_type_t with enum fsal_sle_type

This was kind of flakey with the lock_type_t being converted to an
enum fsal_sle_type with no validation that the values were the same.

Easier to just use enum fsal_sle_type in the first place.

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Make state_export_unshare_all consistent with state_export_unlock_all

The refcounting was fine, but handle errors the same way and other
cosmetic cleanup to make the code more consistent.

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Use cache_inode_lru_ref instead of cache_inode_get_protected

Now that cache_inode_lru_ref has provision to return CACHE_INODE_ESTALE
when the cache entry is about to die and not take an LRU reference, we
can dispense with cache_inode_get_protected.

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Remove cache_inode_get_protected now that it isn't necessary

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Use proper refcounting of state_t, state_owner_t, and export in layoutrecall.

Take a reference on each state_t in the recall list.

Take a reference to the state_owner_t to assure that is good also
before using it.

Use get_state_export_ref to properly reference state_export and handle
an export going stale.

Also, since the recall list is for a single cache inode entry, we don't
actually need to look at state_entry.

Also make some cosmetic changes to make the code easier to follow.

Also, fix a memory free ordering bug (free the handle FIRST, then the
cb_data that holds the layout recall that holds the pointer to the handle).

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Safely use state_entry, state_export, and state_owner in layout functions

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Cleanup state_lookup_layout_state and use safe check of state_owner

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Use proper refcounting of state_t, entry, and owner in state_export_release_nfs4_state

Also hold state_lock for call to state_share_remove.

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Use proper refcounting of state_t, entry, and owner in nfs4_Check_Stateid

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Use state_mutex in display_state_id_val

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Use proper refcounting of state_t, entry, and export in nfs4_op_layoutreturn

Signed-off-by: Frank S. Filz <ffilzlnx@mindspring.com>
Cleanup handle_recalls to use passed cache entry instead of state_entry

There is no need to use state_entry, the caller already was passed the
cache entry with a refcount.

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