2011-08-12 13:20:12 -04:00
|
|
|
/* Copyright (c) 2010, 2011
|
2010-10-11 14:59:26 -04:00
|
|
|
* The Regents of the University of Michigan
|
|
|
|
|
* All Rights Reserved
|
2011-08-12 13:20:12 -04:00
|
|
|
*
|
|
|
|
|
* Olga Kornievskaia <aglo@umich.edu>
|
|
|
|
|
* Casey Bodley <cbodley@umich.edu>
|
2010-10-11 14:59:26 -04:00
|
|
|
*
|
|
|
|
|
* 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,
|
|
|
|
|
};
|
|
|
|
|
|
2010-12-01 15:06:22 -05:00
|
|
|
enum pnfs_device_status {
|
|
|
|
|
/* GETDEVICEINFO was successful */
|
|
|
|
|
PNFS_DEVICE_GRANTED = 0x1,
|
|
|
|
|
/* a bulk recall or lease expiration led to device invalidation */
|
|
|
|
|
PNFS_DEVICE_REVOKED = 0x2,
|
|
|
|
|
};
|
|
|
|
|
|
2010-10-11 14:59:26 -04:00
|
|
|
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;
|
2010-12-01 15:06:22 -05:00
|
|
|
enum pnfs_device_status status;
|
|
|
|
|
uint32_t layout_count; /* layouts using this device */
|
|
|
|
|
CRITICAL_SECTION lock;
|
2010-10-11 14:59:26 -04:00
|
|
|
} 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;
|
2010-12-01 15:06:22 -05:00
|
|
|
struct pnfs_file_device_list *devices; /* -> nfs41_client.devices */
|
|
|
|
|
struct list_entry entry; /* position in devices */
|
2010-10-11 14:59:26 -04:00
|
|
|
} pnfs_file_device;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* layout */
|
2011-03-09 11:40:43 -05:00
|
|
|
typedef struct __pnfs_layout_state {
|
|
|
|
|
nfs41_fh meta_fh;
|
|
|
|
|
stateid4 stateid;
|
|
|
|
|
struct list_entry entry; /* position in nfs41_client.layouts */
|
|
|
|
|
struct __pnfs_file_layout *layout;
|
2010-10-11 14:59:26 -04:00
|
|
|
enum pnfs_layout_status status;
|
|
|
|
|
bool_t return_on_close;
|
2011-02-21 16:53:08 -08:00
|
|
|
LONG open_count; /* for return on last close */
|
2010-10-11 14:59:26 -04:00
|
|
|
uint32_t io_count; /* number of pending io operations */
|
2011-03-10 12:46:34 -05:00
|
|
|
bool_t pending; /* pending LAYOUTGET/LAYOUTRETURN */
|
2010-10-11 14:59:26 -04:00
|
|
|
SRWLOCK lock;
|
2011-03-10 12:46:34 -05:00
|
|
|
CONDITION_VARIABLE cond;
|
2011-03-09 11:40:43 -05:00
|
|
|
} 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;
|
2010-10-11 14:59:26 -04:00
|
|
|
} 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];
|
|
|
|
|
pnfs_file_device *device;
|
|
|
|
|
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 */
|
2011-03-10 12:37:28 -05:00
|
|
|
struct __stateid_arg;
|
2010-10-11 14:59:26 -04:00
|
|
|
typedef struct __pnfs_io_pattern {
|
|
|
|
|
struct __pnfs_io_thread *threads;
|
|
|
|
|
struct __nfs41_root *root;
|
2011-03-10 12:37:28 -05:00
|
|
|
nfs41_path_fh *meta_file;
|
|
|
|
|
const struct __stateid_arg *stateid;
|
|
|
|
|
pnfs_layout_state *state;
|
2010-10-11 14:59:26 -04:00
|
|
|
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 */
|
2011-03-09 11:40:43 -05:00
|
|
|
struct pnfs_layout_list;
|
2010-10-11 14:59:26 -04:00
|
|
|
struct cb_layoutrecall_args;
|
|
|
|
|
|
2011-03-09 11:40:43 -05:00
|
|
|
enum pnfs_status pnfs_layout_list_create(
|
|
|
|
|
OUT struct pnfs_layout_list **layouts_out);
|
2010-10-11 14:59:26 -04:00
|
|
|
|
2011-03-09 11:40:43 -05:00
|
|
|
void pnfs_layout_list_free(
|
|
|
|
|
IN struct pnfs_layout_list *layouts);
|
2010-10-11 14:59:26 -04:00
|
|
|
|
2011-03-09 13:54:35 -05:00
|
|
|
enum pnfs_status pnfs_layout_state_open(
|
2011-03-09 11:40:43 -05:00
|
|
|
IN struct pnfs_layout_list *layouts,
|
2010-10-11 14:59:26 -04:00
|
|
|
IN struct __nfs41_session *session,
|
|
|
|
|
IN struct __nfs41_open_state *state,
|
|
|
|
|
IN enum pnfs_iomode iomode,
|
|
|
|
|
IN uint64_t offset,
|
|
|
|
|
IN uint64_t length,
|
2011-03-09 13:54:35 -05:00
|
|
|
OUT pnfs_layout_state **layout_out);
|
2010-10-11 14:59:26 -04:00
|
|
|
|
2011-03-09 13:54:35 -05:00
|
|
|
void pnfs_layout_state_close(
|
2010-10-11 14:59:26 -04:00
|
|
|
IN struct __nfs41_session *session,
|
|
|
|
|
IN struct __nfs41_open_state *state,
|
|
|
|
|
IN bool_t remove);
|
|
|
|
|
|
|
|
|
|
enum pnfs_status pnfs_file_layout_recall(
|
2010-12-02 10:32:15 -05:00
|
|
|
IN struct __nfs41_client *client,
|
2010-10-11 14:59:26 -04:00
|
|
|
IN const struct cb_layoutrecall_args *recall);
|
|
|
|
|
|
|
|
|
|
enum pnfs_status pnfs_layout_io_start(
|
2011-03-09 13:54:35 -05:00
|
|
|
IN pnfs_layout_state *state);
|
2010-10-11 14:59:26 -04:00
|
|
|
|
|
|
|
|
void pnfs_layout_io_finished(
|
2011-03-09 13:54:35 -05:00
|
|
|
IN pnfs_layout_state *state);
|
2010-10-11 14:59:26 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
__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);
|
|
|
|
|
|
2010-12-02 10:32:15 -05:00
|
|
|
void pnfs_file_device_list_invalidate(
|
|
|
|
|
IN struct pnfs_file_device_list *devices);
|
|
|
|
|
|
2010-10-11 14:59:26 -04:00
|
|
|
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);
|
|
|
|
|
|
2010-12-01 15:06:22 -05:00
|
|
|
void pnfs_file_device_put(
|
|
|
|
|
IN pnfs_file_device *device);
|
|
|
|
|
|
2011-06-16 12:33:39 -04:00
|
|
|
struct notify_deviceid4; /* from nfs41_callback.h */
|
|
|
|
|
enum notify_deviceid_type4;
|
|
|
|
|
enum pnfs_status pnfs_file_device_notify(
|
|
|
|
|
IN struct pnfs_file_device_list *devices,
|
|
|
|
|
IN const struct notify_deviceid4 *change);
|
|
|
|
|
|
2010-10-11 14:59:26 -04:00
|
|
|
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)
|
|
|
|
|
{
|
2010-10-18 11:09:27 -04:00
|
|
|
return (uint32_t)((sui + layout->first_index) % stripe_count);
|
2010-10-11 14:59:26 -04:00
|
|
|
}
|
|
|
|
|
__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,
|
2011-03-10 12:37:28 -05:00
|
|
|
IN nfs41_path_fh *meta_file,
|
|
|
|
|
IN const struct __stateid_arg *stateid,
|
|
|
|
|
IN pnfs_layout_state *layout,
|
2010-10-11 14:59:26 -04:00
|
|
|
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,
|
2011-03-10 12:37:28 -05:00
|
|
|
IN nfs41_path_fh *meta_file,
|
|
|
|
|
IN const struct __stateid_arg *stateid,
|
|
|
|
|
IN pnfs_layout_state *layout,
|
2010-10-11 14:59:26 -04:00
|
|
|
IN uint64_t offset,
|
|
|
|
|
IN uint64_t length,
|
|
|
|
|
IN unsigned char *buffer,
|
|
|
|
|
OUT ULONG *len_out);
|
|
|
|
|
|
|
|
|
|
#endif /* !__PNFS_H__ */
|