pnfs: struct pnfs_layout_state to manage layout state

moved state data (stateid, flags, locks, and reference counts) out of struct pnfs_layout, which should represent a layout segment returned by LAYOUTGET
struct pnfs_layout_state now holds this state, along with a pointer to a single pnfs_file_layout
struct pnfs_file_layout_list is now a list of pnfs_layout_states, and was renamed to pnfs_layout_list

Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
This commit is contained in:
Casey Bodley 2011-03-09 11:40:43 -05:00 committed by unknown
parent d1683ac060
commit 248c14b6ae
4 changed files with 66 additions and 55 deletions

View file

@ -135,7 +135,7 @@ typedef struct __nfs41_client {
SRWLOCK session_lock; SRWLOCK session_lock;
nfs41_rpc_clnt *rpc; nfs41_rpc_clnt *rpc;
bool_t is_data; bool_t is_data;
struct pnfs_file_layout_list *layouts; struct pnfs_layout_list *layouts;
struct pnfs_file_device_list *devices; struct pnfs_file_device_list *devices;
struct list_entry root_entry; /* position in nfs41_root.clients */ struct list_entry root_entry; /* position in nfs41_root.clients */
struct __nfs41_root *root; struct __nfs41_root *root;

View file

@ -51,7 +51,7 @@ static int pnfs_client_init(
int status = NO_ERROR; int status = NO_ERROR;
/* initialize the pnfs layout and device lists for metadata clients */ /* initialize the pnfs layout and device lists for metadata clients */
pnfsstat = pnfs_file_layout_list_create(&client->layouts); pnfsstat = pnfs_layout_list_create(&client->layouts);
if (pnfsstat) { if (pnfsstat) {
status = ERROR_NOT_ENOUGH_MEMORY; status = ERROR_NOT_ENOUGH_MEMORY;
goto out; goto out;
@ -65,7 +65,7 @@ out:
return status; return status;
out_err_layouts: out_err_layouts:
pnfs_file_layout_list_free(client->layouts); pnfs_layout_list_free(client->layouts);
client->layouts = NULL; client->layouts = NULL;
goto out; goto out;
} }
@ -211,7 +211,7 @@ void nfs41_client_free(
if (client->session) nfs41_session_free(client->session); if (client->session) nfs41_session_free(client->session);
if (client->server) nfs41_server_deref(client->server); if (client->server) nfs41_server_deref(client->server);
nfs41_rpc_clnt_free(client->rpc); nfs41_rpc_clnt_free(client->rpc);
if (client->layouts) pnfs_file_layout_list_free(client->layouts); if (client->layouts) pnfs_layout_list_free(client->layouts);
if (client->devices) pnfs_file_device_list_free(client->devices); if (client->devices) pnfs_file_device_list_free(client->devices);
free(client); free(client);
} }

View file

@ -155,17 +155,24 @@ typedef struct __pnfs_file_device {
/* layout */ /* layout */
typedef struct __pnfs_layout { typedef struct __pnfs_layout_state {
stateid4 state; nfs41_fh meta_fh;
uint64_t offset; stateid4 stateid;
uint64_t length; struct list_entry entry; /* position in nfs41_client.layouts */
enum pnfs_layout_type type; struct __pnfs_file_layout *layout;
enum pnfs_iomode iomode;
enum pnfs_layout_status status; enum pnfs_layout_status status;
bool_t return_on_close; bool_t return_on_close;
LONG open_count; /* for return on last close */ LONG open_count; /* for return on last close */
uint32_t io_count; /* number of pending io operations */ uint32_t io_count; /* number of pending io operations */
SRWLOCK lock; SRWLOCK lock;
} pnfs_layout_state;
typedef struct __pnfs_layout {
struct list_entry entry;
uint64_t offset;
uint64_t length;
enum pnfs_iomode iomode;
enum pnfs_layout_type type;
} pnfs_layout; } pnfs_layout;
typedef struct __pnfs_file_layout_handles { typedef struct __pnfs_file_layout_handles {
@ -177,9 +184,7 @@ typedef struct __pnfs_file_layout {
pnfs_layout layout; pnfs_layout layout;
pnfs_file_layout_handles filehandles; pnfs_file_layout_handles filehandles;
unsigned char deviceid[PNFS_DEVICEID_SIZE]; unsigned char deviceid[PNFS_DEVICEID_SIZE];
struct list_entry entry; /* position in nfs41_client.layouts */
pnfs_file_device *device; pnfs_file_device *device;
nfs41_fh meta_fh;
uint64_t pattern_offset; uint64_t pattern_offset;
uint32_t first_index; uint32_t first_index;
uint32_t util; uint32_t util;
@ -235,17 +240,17 @@ typedef uint32_t (WINAPI *pnfs_io_thread_fn)(void*);
/* pnfs_layout.c */ /* pnfs_layout.c */
struct pnfs_file_layout_list; struct pnfs_layout_list;
struct cb_layoutrecall_args; struct cb_layoutrecall_args;
enum pnfs_status pnfs_file_layout_list_create( enum pnfs_status pnfs_layout_list_create(
OUT struct pnfs_file_layout_list **layouts_out); OUT struct pnfs_layout_list **layouts_out);
void pnfs_file_layout_list_free( void pnfs_layout_list_free(
IN struct pnfs_file_layout_list *layouts); IN struct pnfs_layout_list *layouts);
enum pnfs_status pnfs_open_state_layout( enum pnfs_status pnfs_open_state_layout(
IN struct pnfs_file_layout_list *layouts, IN struct pnfs_layout_list *layouts,
IN struct __nfs41_session *session, IN struct __nfs41_session *session,
IN struct __nfs41_open_state *state, IN struct __nfs41_open_state *state,
IN enum pnfs_iomode iomode, IN enum pnfs_iomode iomode,

View file

@ -32,37 +32,36 @@
#define FLLVL 2 /* dprintf level for file layout logging */ #define FLLVL 2 /* dprintf level for file layout logging */
/* pnfs_file_layout_list */ /* pnfs_layout_list */
struct pnfs_file_layout_list { struct pnfs_layout_list {
struct list_entry head; struct list_entry head;
CRITICAL_SECTION lock; CRITICAL_SECTION lock;
}; };
#define layout_entry(pos) list_container(pos, pnfs_file_layout, entry) #define state_entry(pos) list_container(pos, pnfs_layout_state, entry)
static enum pnfs_status layout_create( static enum pnfs_status layout_state_create(
IN const nfs41_fh *meta_fh, IN const nfs41_fh *meta_fh,
OUT pnfs_file_layout **layout_out) OUT pnfs_layout_state **layout_out)
{ {
pnfs_file_layout *layout; pnfs_layout_state *layout;
enum pnfs_status status = PNFS_SUCCESS; enum pnfs_status status = PNFS_SUCCESS;
layout = calloc(1, sizeof(pnfs_file_layout)); layout = calloc(1, sizeof(pnfs_layout_state));
if (layout == NULL) { if (layout == NULL) {
status = PNFSERR_RESOURCES; status = PNFSERR_RESOURCES;
goto out; goto out;
} }
layout->layout.type = PNFS_LAYOUTTYPE_FILE;
fh_copy(&layout->meta_fh, meta_fh); fh_copy(&layout->meta_fh, meta_fh);
InitializeSRWLock(&layout->layout.lock); InitializeSRWLock(&layout->lock);
*layout_out = layout; *layout_out = layout;
out: out:
return status; return status;
} }
static void layout_free( static void file_layout_free(
IN pnfs_file_layout *layout) IN pnfs_file_layout *layout)
{ {
if (layout->device) pnfs_file_device_put(layout->device); if (layout->device) pnfs_file_device_put(layout->device);
@ -70,11 +69,18 @@ static void layout_free(
free(layout); free(layout);
} }
static void layout_state_free(
IN pnfs_layout_state *state)
{
if (state->layout) file_layout_free(state->layout);
free(state);
}
static int layout_entry_compare( static int layout_entry_compare(
IN const struct list_entry *entry, IN const struct list_entry *entry,
IN const void *value) IN const void *value)
{ {
const pnfs_file_layout *layout = layout_entry(entry); const pnfs_layout_state *layout = state_entry(entry);
const nfs41_fh *meta_fh = (const nfs41_fh*)value; const nfs41_fh *meta_fh = (const nfs41_fh*)value;
const nfs41_fh *layout_fh = (const nfs41_fh*)&layout->meta_fh; const nfs41_fh *layout_fh = (const nfs41_fh*)&layout->meta_fh;
const uint32_t diff = layout_fh->len - meta_fh->len; const uint32_t diff = layout_fh->len - meta_fh->len;
@ -82,7 +88,7 @@ static int layout_entry_compare(
} }
static enum pnfs_status layout_entry_find( static enum pnfs_status layout_entry_find(
IN struct pnfs_file_layout_list *layouts, IN struct pnfs_layout_list *layouts,
IN const nfs41_fh *meta_fh, IN const nfs41_fh *meta_fh,
OUT struct list_entry **entry_out) OUT struct list_entry **entry_out)
{ {
@ -90,13 +96,13 @@ static enum pnfs_status layout_entry_find(
return *entry_out ? PNFS_SUCCESS : PNFSERR_NO_LAYOUT; return *entry_out ? PNFS_SUCCESS : PNFSERR_NO_LAYOUT;
} }
enum pnfs_status pnfs_file_layout_list_create( enum pnfs_status pnfs_layout_list_create(
OUT struct pnfs_file_layout_list **layouts_out) OUT struct pnfs_layout_list **layouts_out)
{ {
struct pnfs_file_layout_list *layouts; struct pnfs_layout_list *layouts;
enum pnfs_status status = PNFS_SUCCESS; enum pnfs_status status = PNFS_SUCCESS;
layouts = calloc(1, sizeof(struct pnfs_file_layout_list)); layouts = calloc(1, sizeof(struct pnfs_layout_list));
if (layouts == NULL) { if (layouts == NULL) {
status = PNFSERR_RESOURCES; status = PNFSERR_RESOURCES;
goto out; goto out;
@ -108,30 +114,30 @@ out:
return status; return status;
} }
void pnfs_file_layout_list_free( void pnfs_layout_list_free(
IN struct pnfs_file_layout_list *layouts) IN struct pnfs_layout_list *layouts)
{ {
struct list_entry *entry, *tmp; struct list_entry *entry, *tmp;
EnterCriticalSection(&layouts->lock); EnterCriticalSection(&layouts->lock);
list_for_each_tmp(entry, tmp, &layouts->head) list_for_each_tmp(entry, tmp, &layouts->head)
layout_free(layout_entry(entry)); layout_state_free(state_entry(entry));
LeaveCriticalSection(&layouts->lock); LeaveCriticalSection(&layouts->lock);
free(layouts); free(layouts);
} }
static enum pnfs_status file_layout_find_or_create( static enum pnfs_status layout_state_find_or_create(
IN struct pnfs_file_layout_list *layouts, IN struct pnfs_layout_list *layouts,
IN const nfs41_fh *meta_fh, IN const nfs41_fh *meta_fh,
OUT pnfs_file_layout **layout_out) OUT pnfs_layout_state **layout_out)
{ {
struct list_entry *entry; struct list_entry *entry;
enum pnfs_status status; enum pnfs_status status;
dprintf(FLLVL, "--> file_layout_find_or_create()\n"); dprintf(FLLVL, "--> layout_state_find_or_create()\n");
EnterCriticalSection(&layouts->lock); EnterCriticalSection(&layouts->lock);
@ -139,23 +145,23 @@ static enum pnfs_status file_layout_find_or_create(
status = layout_entry_find(layouts, meta_fh, &entry); status = layout_entry_find(layouts, meta_fh, &entry);
if (status) { if (status) {
/* create a new layout */ /* create a new layout */
pnfs_file_layout *layout; pnfs_layout_state *layout;
status = layout_create(meta_fh, &layout); status = layout_state_create(meta_fh, &layout);
if (status == PNFS_SUCCESS) { if (status == PNFS_SUCCESS) {
/* add it to the list */ /* add it to the list */
list_add_head(&layouts->head, &layout->entry); list_add_head(&layouts->head, &layout->entry);
*layout_out = layout; *layout_out = layout;
dprintf(FLLVL, "<-- file_layout_find_or_create() " dprintf(FLLVL, "<-- layout_state_find_or_create() "
"returning new layout %p\n", layout); "returning new layout %p\n", layout);
} else { } else {
dprintf(FLLVL, "<-- file_layout_find_or_create() " dprintf(FLLVL, "<-- layout_state_find_or_create() "
"returning %s\n", pnfs_error_string(status)); "returning %s\n", pnfs_error_string(status));
} }
} else { } else {
*layout_out = layout_entry(entry); *layout_out = state_entry(entry);
dprintf(FLLVL, "<-- file_layout_find_or_create() " dprintf(FLLVL, "<-- layout_state_find_or_create() "
"returning existing layout %p\n", *layout_out); "returning existing layout %p\n", *layout_out);
} }
@ -163,26 +169,26 @@ static enum pnfs_status file_layout_find_or_create(
return status; return status;
} }
static enum pnfs_status file_layout_find_and_delete( static enum pnfs_status layout_state_find_and_delete(
IN struct pnfs_file_layout_list *layouts, IN struct pnfs_layout_list *layouts,
IN const nfs41_fh *meta_fh) IN const nfs41_fh *meta_fh)
{ {
struct list_entry *entry; struct list_entry *entry;
enum pnfs_status status; enum pnfs_status status;
dprintf(FLLVL, "--> file_layout_find_and_delete()\n"); dprintf(FLLVL, "--> layout_state_find_and_delete()\n");
EnterCriticalSection(&layouts->lock); EnterCriticalSection(&layouts->lock);
status = layout_entry_find(layouts, meta_fh, &entry); status = layout_entry_find(layouts, meta_fh, &entry);
if (status == PNFS_SUCCESS) { if (status == PNFS_SUCCESS) {
list_remove(entry); list_remove(entry);
layout_free(layout_entry(entry)); layout_state_free(state_entry(entry));
} }
LeaveCriticalSection(&layouts->lock); LeaveCriticalSection(&layouts->lock);
dprintf(FLLVL, "<-- file_layout_find_and_delete() " dprintf(FLLVL, "<-- layout_state_find_and_delete() "
"returning %s\n", pnfs_error_string(status)); "returning %s\n", pnfs_error_string(status));
return status; return status;
} }
@ -505,7 +511,7 @@ static enum pnfs_status open_state_layout_cached(
} }
enum pnfs_status pnfs_open_state_layout( enum pnfs_status pnfs_open_state_layout(
IN struct pnfs_file_layout_list *layouts, IN struct pnfs_layout_list *layouts,
IN nfs41_session *session, IN nfs41_session *session,
IN nfs41_open_state *state, IN nfs41_open_state *state,
IN enum pnfs_iomode iomode, IN enum pnfs_iomode iomode,
@ -537,7 +543,7 @@ enum pnfs_status pnfs_open_state_layout(
status = open_state_layout_cached(state, iomode, offset, length, &layout); status = open_state_layout_cached(state, iomode, offset, length, &layout);
if (status) { if (status) {
status = file_layout_find_or_create(layouts, &state->file.fh, &layout); status = layout_state_find_or_create(layouts, &state->file.fh, &layout);
if (status == PNFS_SUCCESS) { if (status == PNFS_SUCCESS) {
LONG open_count = InterlockedIncrement(&layout->layout.open_count); LONG open_count = InterlockedIncrement(&layout->layout.open_count);
state->layout = layout; state->layout = layout;
@ -603,7 +609,7 @@ void pnfs_open_state_close(
if (remove && session->client->layouts) { if (remove && session->client->layouts) {
/* free the layout when the file is removed */ /* free the layout when the file is removed */
file_layout_find_and_delete(session->client->layouts, &state->file.fh); layout_state_find_and_delete(session->client->layouts, &state->file.fh);
} }
} }