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:
parent
d1683ac060
commit
248c14b6ae
4 changed files with 66 additions and 55 deletions
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue