ms-nfs41-client/daemon/pnfs.h
Casey Bodley 3ecd38e414 recovery: operations take stateid_arg instead of stateid4
operations that require a stateid now take stateid_arg for recovery information.  these operations include close, setattr, lock/unlock, layoutget, and read/write (including pnfs)

nfs41_open_stateid_arg() locks nfs41_open_state and copies its stateid into a stateid_arg
nfs41_lock_stateid_arg() locks nfs41_open_state.last_lock and copies its stateid into a stateid_arg; if there is no lock state, it falls back to nfs41_open_stateid_arg()

pnfs_read/write() now take nfs41_open_state so they can generate stateid_args

Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
2010-12-06 14:21:28 -05:00

349 lines
10 KiB
C

/* Copyright (c) 2010
* The Regents of the University of Michigan
* All Rights Reserved
*
* Permission is granted to use, copy and redistribute this software
* for noncommercial education and research purposes, so long as no
* fee is charged, and so long as the name of the University of Michigan
* is not used in any advertising or publicity pertaining to the use
* or distribution of this software without specific, written prior
* authorization. Permission to modify or otherwise create derivative
* works of this software is not granted.
*
* This software is provided as is, without representation or warranty
* of any kind either express or implied, including without limitation
* the implied warranties of merchantability, fitness for a particular
* purpose, or noninfringement. The Regents of the University of
* Michigan shall not be liable for any damages, including special,
* indirect, incidental, or consequential damages, with respect to any
* claim arising out of or in connection with the use of the software,
* even if it has been or is hereafter advised of the possibility of
* such damages.
*/
#ifndef __PNFS_H__
#define __PNFS_H__
#include "nfs41_types.h"
#include "list.h"
/* preprocessor options */
#ifndef PNFS_DISABLE
# ifndef PNFS_DISABLE_READ
# define PNFS_ENABLE_READ
# endif
# ifndef PNFS_DISABLE_WRITE
# define PNFS_ENABLE_WRITE
# endif
# define PNFS_THREADING
# define PNFS_THREAD_BY_SERVER
#endif
/* forward declarations from nfs41.h */
struct __nfs41_client;
struct __nfs41_session;
struct __nfs41_open_state;
struct __nfs41_root;
/* pnfs error values, in order of increasing severity */
enum pnfs_status {
PNFS_SUCCESS = 0,
PNFS_PENDING,
PNFS_READ_EOF,
PNFSERR_NOT_SUPPORTED,
PNFSERR_NOT_CONNECTED,
PNFSERR_IO,
PNFSERR_NO_DEVICE,
PNFSERR_NO_LAYOUT,
PNFSERR_INVALID_FH_LIST,
PNFSERR_INVALID_DS_INDEX,
PNFSERR_RESOURCES,
PNFSERR_LAYOUT_RECALLED,
PNFSERR_LAYOUT_CHANGED,
};
enum pnfs_layout_type {
PNFS_LAYOUTTYPE_FILE = 1,
PNFS_LAYOUTTYPE_OBJECT = 2,
PNFS_LAYOUTTYPE_BLOCK = 3
};
enum pnfs_iomode {
PNFS_IOMODE_READ = 0x1,
PNFS_IOMODE_RW = 0x2,
PNFS_IOMODE_ANY = PNFS_IOMODE_READ | PNFS_IOMODE_RW
};
enum pnfs_layout_status {
/* LAYOUTGET was successful, and the layout has not been returned or
* otherwise revoked by the server */
PNFS_LAYOUT_GRANTED = 0x01,
/* GETDEVICEINFO was successful, and we have a valid 'device' pointer */
PNFS_LAYOUT_HAS_DEVICE = 0x02,
/* 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 */
PNFS_LAYOUT_NOT_RW = 0x20,
};
enum pnfs_return_type {
PNFS_RETURN_FILE = 1,
PNFS_RETURN_FSID = 2,
PNFS_RETURN_ALL = 3
};
#define NFL4_UFLG_MASK 0x0000003F
#define NFL4_UFLG_DENSE 0x00000001
#define NFL4_UFLG_COMMIT_THRU_MDS 0x00000002
#define NFL4_UFLG_STRIPE_UNIT_SIZE_MASK 0xFFFFFFC0
#define PNFS_DEVICEID_SIZE 16
/* device */
typedef struct __pnfs_device {
unsigned char deviceid[PNFS_DEVICEID_SIZE];
enum pnfs_layout_type type;
} pnfs_device;
typedef struct __pnfs_stripe_indices {
uint32_t count;
uint32_t *arr;
} pnfs_stripe_indices;
typedef struct __pnfs_data_server {
struct __nfs41_client *client;
multi_addr4 addrs;
SRWLOCK lock;
} pnfs_data_server;
typedef struct __pnfs_data_server_list {
uint32_t count;
pnfs_data_server *arr;
} pnfs_data_server_list;
typedef struct __pnfs_file_device {
pnfs_device device;
pnfs_stripe_indices stripes;
pnfs_data_server_list servers;
struct list_entry entry; /* position in nfs41_client.devices */
SRWLOCK lock;
} pnfs_file_device;
/* layout */
typedef struct __pnfs_layout {
stateid4 state;
uint64_t offset;
uint64_t length;
enum pnfs_layout_type type;
enum pnfs_iomode iomode;
enum pnfs_layout_status status;
bool_t return_on_close;
uint32_t io_count; /* number of pending io operations */
SRWLOCK lock;
} pnfs_layout;
typedef struct __pnfs_file_layout_handles {
uint32_t count;
nfs41_path_fh *arr;
} pnfs_file_layout_handles;
typedef struct __pnfs_file_layout {
pnfs_layout layout;
pnfs_file_layout_handles filehandles;
unsigned char deviceid[PNFS_DEVICEID_SIZE];
struct list_entry entry; /* position in nfs41_client.layouts */
pnfs_file_device *device;
nfs41_fh meta_fh;
uint64_t pattern_offset;
uint32_t first_index;
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;
/* io */
typedef struct __pnfs_io_pattern {
struct __pnfs_io_thread *threads;
struct __nfs41_root *root;
struct __nfs41_open_state *state;
pnfs_file_layout *layout;
unsigned char *buffer;
uint64_t offset_start;
uint64_t offset_end;
uint32_t count;
uint32_t default_lease;
} pnfs_io_pattern;
typedef struct __pnfs_io_thread {
pnfs_io_pattern *pattern;
uint64_t offset;
uint64_t offset_end;
uint32_t id;
enum stable_how4 stable;
} pnfs_io_thread;
typedef struct __pnfs_io_unit {
nfs41_path_fh *file;
unsigned char *buffer;
uint64_t offset;
uint64_t length;
uint32_t stripeid;
uint32_t serverid;
} pnfs_io_unit;
typedef uint32_t (WINAPI *pnfs_io_thread_fn)(void*);
/* pnfs_layout.c */
struct pnfs_file_layout_list;
struct cb_layoutrecall_args;
enum pnfs_status pnfs_file_layout_list_create(
OUT struct pnfs_file_layout_list **layouts_out);
void pnfs_file_layout_list_free(
IN struct pnfs_file_layout_list *layouts);
enum pnfs_status pnfs_open_state_layout(
IN struct pnfs_file_layout_list *layouts,
IN struct __nfs41_session *session,
IN struct __nfs41_open_state *state,
IN enum pnfs_iomode iomode,
IN uint64_t offset,
IN uint64_t length,
OUT pnfs_file_layout **layout_out);
void pnfs_open_state_close(
IN struct __nfs41_session *session,
IN struct __nfs41_open_state *state,
IN bool_t remove);
enum pnfs_status pnfs_file_layout_recall(
IN struct pnfs_file_layout_list *layouts,
IN const struct cb_layoutrecall_args *recall);
enum pnfs_status pnfs_layout_io_start(
IN pnfs_layout *layout);
void pnfs_layout_io_finished(
IN pnfs_layout *layout);
__inline int is_dense(
IN const pnfs_file_layout *layout)
{
return (layout->util & NFL4_UFLG_DENSE) != 0;
}
__inline int should_commit_to_mds(
IN const pnfs_file_layout *layout)
{
return (layout->util & NFL4_UFLG_COMMIT_THRU_MDS) != 0;
}
__inline uint32_t layout_unit_size(
IN const pnfs_file_layout *layout)
{
return layout->util & NFL4_UFLG_STRIPE_UNIT_SIZE_MASK;
}
/* pnfs_device.c */
struct pnfs_file_device_list;
enum pnfs_status pnfs_file_device_list_create(
OUT struct pnfs_file_device_list **devices_out);
void pnfs_file_device_list_free(
IN struct pnfs_file_device_list *devices);
enum pnfs_status pnfs_file_device_get(
IN struct __nfs41_session *session,
IN struct pnfs_file_device_list *devices,
IN unsigned char *deviceid,
OUT pnfs_file_device **device_out);
enum pnfs_status pnfs_data_server_client(
IN struct __nfs41_root *root,
IN pnfs_data_server *server,
IN uint32_t default_lease,
OUT struct __nfs41_client **client_out);
enum pnfs_status pnfs_file_device_io_unit(
IN pnfs_io_pattern *pattern,
IN uint64_t offset,
OUT pnfs_io_unit *io);
__inline uint64_t stripe_unit_number(
IN pnfs_file_layout *layout,
IN uint64_t offset,
IN uint32_t unit_size)
{
const uint64_t relative_offset = offset - layout->pattern_offset;
return relative_offset / unit_size;
}
__inline uint32_t stripe_index(
IN pnfs_file_layout *layout,
IN uint64_t sui,
IN uint32_t stripe_count)
{
return (uint32_t)((sui + layout->first_index) % stripe_count);
}
__inline uint32_t data_server_index(
IN pnfs_file_device *device,
IN uint32_t stripeid)
{
return device->stripes.arr[stripeid];
}
/* pnfs_io.c */
enum pnfs_status pnfs_read(
IN struct __nfs41_root *root,
IN struct __nfs41_session *session,
IN struct __nfs41_open_state *state,
IN pnfs_file_layout *layout,
IN uint64_t offset,
IN uint64_t length,
OUT unsigned char *buffer_out,
OUT ULONG *len_out);
enum pnfs_status pnfs_write(
IN struct __nfs41_root *root,
IN struct __nfs41_session *session,
IN struct __nfs41_open_state *state,
IN pnfs_file_layout *layout,
IN uint64_t offset,
IN uint64_t length,
IN unsigned char *buffer,
OUT ULONG *len_out);
#endif /* !__PNFS_H__ */