pnfs: handle partial layout recalls

layout status flags for PNFS_LAYOUT_RECALLED and PNFS_LAYOUT_CHANGED are removed, and replaced by a list of recalled ranges.  recalls during io are added to the list and processed on pnfs_layout_io_finished().  recalls outside of io are processed immediately

new function layout_recall_range() loops through all existing layout segments, and removes ranges that intersect with the range recalled.  deals with 4 cases per segment:
-only the beginning of the segment is recalled
-only the end of the segment is recalled
-the entire segment is recalled
-only a middle part of the segment is recalled

new function pnfs_layout_recall_status() is called before each unit of io, allowing io threads to bail out early if a recall is detected.  takes a layout segment as an argument, and only returns an error if that segment intersects a recalled range

new function pnfs_layout_recall_fenced() is called when map_ds_error() in pnfs_io.c detects fencing.  also takes a layout segment as an argument, and appends a recall matching the range of the segment

pnfs_layout_state_prepare() now checks the given range against the list of recalled ranges

Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
This commit is contained in:
Casey Bodley 2012-01-30 13:49:40 -05:00 committed by unknown
parent d0ff37a195
commit db7caebe28
3 changed files with 277 additions and 71 deletions

View file

@ -84,13 +84,6 @@ enum pnfs_iomode {
};
enum pnfs_layout_status {
/* CB_LAYOUTRECALL indicated that the server has recalled this layout,
* and it should be returned on completion of any pending io */
PNFS_LAYOUT_RECALLED = 0x04,
/* CB_LAYOUTRECALL indicated that the layout is changing, and "the client
* SHOULD NOT write and commit modified data to the storage devices!" */
PNFS_LAYOUT_CHANGED = 0x08,
/* a LAYOUTGET error indicated that this layout will never be granted */
PNFS_LAYOUT_UNAVAILABLE = 0x10,
/* LAYOUTGET returned BADIOMODE, so a RW layout will never be granted */
@ -158,6 +151,7 @@ typedef struct __pnfs_layout_state {
stateid4 stateid;
struct list_entry entry; /* position in nfs41_client.layouts */
struct list_entry layouts; /* list of pnfs_file_layouts */
struct list_entry recalls; /* list of pnfs_layouts */
enum pnfs_layout_status status;
bool_t return_on_close;
LONG open_count; /* for return on last close */
@ -190,21 +184,6 @@ typedef struct __pnfs_file_layout {
uint32_t util;
} pnfs_file_layout;
typedef struct __pnfs_layout_recall {
enum pnfs_layout_type type;
enum pnfs_iomode iomode;
bool_t changed;
enum pnfs_return_type recall;
union {
struct {
nfs41_fh fh;
stateid4 stateid;
} file;
nfs41_fsid fsid;
} args;
} pnfs_layout_recall;
/* pnfs_layout.c */
struct pnfs_layout_list;
@ -239,6 +218,15 @@ enum pnfs_status pnfs_file_layout_recall(
IN struct __nfs41_client *client,
IN const struct cb_layoutrecall_args *recall);
/* expects caller to hold a shared lock on pnfs_layout_state */
enum pnfs_status pnfs_layout_recall_status(
IN const pnfs_layout_state *state,
IN const pnfs_layout *layout);
void pnfs_layout_recall_fenced(
IN pnfs_layout_state *state,
IN const pnfs_layout *layout);
/* expects caller to hold an exclusive lock on pnfs_layout_state */
void pnfs_layout_io_start(
IN pnfs_layout_state *state);