exclusive locks are no longer held over LAYOUTGET, LAYOUTRETURN, or GETDEVICEINFO rpcs. this prevents a deadlock when CB_LAYOUTRECALL needs an exclusive lock while another operation is on the wire
introduced a 'pending' condition variable to protect access to state->layout while the layout's lock is not held
updated file_layout_recall() to compare the stateid sequence numbers to determine if the server has processed an outstanding LAYOUTGET or LAYOUTRETURN, where we're required to reply with NFS4ERR_DELAY
LAYOUTGET, LAYOUTRETURN, and GETDEVICEINFO can now be sent with try_recovery=TRUE because they no longer hold an exclusive lock. this makes it possible for recover_client_state() to recall all of the client's layouts without deadlocking
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
instead of ignoring errors from proc_cb_compound_args(), return NFS4ERR_BADXDR. note that we still need to allocate the cb_compound_res structure to return this error
added null checks to the end of handle_cb_compound(); if the cb_compound_res allocation fails, we'd crash trying to access res->status and res->resarray_count
also fixed some indenting
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
20.3. CB_LAYOUTRECALL
"LAYOUTRECALL4_FSID and LAYOUTRECALL4_ALL specify that all the storage device ID to storage device address mappings in the affected file system(s) are also recalled."
pnfs_file_layout_recall() now takes a nfs41_client instead of just the pnfs_file_layout_list, because both the layout list and device list are accessible from nfs41_client. for bulk recalls, calls new function pnfs_file_device_list_invalidate(). each device with layout_count=0 is removed and freed, and devices in use are flagged as REVOKED and freed when layout_count->0
layout_recall_return() now takes a pnfs_file_layout instead of pnfs_layout for access to pnfs_file_layout.device. pnfs_layout_io_start() and pnfs_layout_io_finish() do the same, because pnfs_layout_io_finish() calls layout_recall_return(). layout_recall_return() calls pnfs_file_device_put() to release its reference on the device
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
when we fork a thread to handle the callback, the arguments we got from
parsing the callback operations in the callback thread are on the stack.
we need to allocate memory for same-size data structure and copy them,
not just copy the pointer.