ReactOS  0.4.11-dev-946-g431643b
pnfs_io.c File Reference
#include <stdio.h>
#include <process.h>
#include "nfs41_ops.h"
#include "util.h"
#include "daemon_debug.h"
Include dependency graph for pnfs_io.c:

Go to the source code of this file.

Classes

struct  __pnfs_io_pattern
 
struct  __pnfs_io_thread
 
struct  __pnfs_io_unit
 

Macros

#define IOLVL   2 /* dprintf level for pnfs io logging */
 
#define file_layout_entry(pos)   list_container(pos, pnfs_file_layout, layout.entry)
 

Typedefs

typedef struct __pnfs_io_pattern pnfs_io_pattern
 
typedef struct __pnfs_io_thread pnfs_io_thread
 
typedef struct __pnfs_io_unit pnfs_io_unit
 
typedef uint32_t(WINAPIpnfs_io_thread_fn) (void *)
 

Functions

static enum pnfs_status stripe_next_unit (IN const pnfs_file_layout *layout, IN uint32_t stripeid, IN uint64_t *position, IN uint64_t offset_end, OUT pnfs_io_unit *io)
 
static enum pnfs_status get_sparse_fh (IN pnfs_file_layout *layout, IN nfs41_path_fh *meta_file, IN uint32_t stripeid, OUT nfs41_path_fh **file_out)
 
static enum pnfs_status get_dense_fh (IN pnfs_file_layout *layout, IN uint32_t stripeid, OUT nfs41_path_fh **file_out)
 
static __inline bool_t layout_compatible (IN const pnfs_layout *layout, IN enum pnfs_iomode iomode, IN uint64_t position)
 
static uint32_t thread_count (IN pnfs_layout_state *state, IN enum pnfs_iomode iomode, IN uint64_t offset, IN uint64_t length)
 
static enum pnfs_status thread_init (IN pnfs_io_pattern *pattern, IN pnfs_io_thread *thread, IN pnfs_file_layout *layout, IN uint32_t stripeid, IN uint64_t offset)
 
static enum pnfs_status pattern_threads_init (IN pnfs_io_pattern *pattern, IN enum pnfs_iomode iomode, IN uint64_t offset, IN uint64_t length)
 
static enum pnfs_status pattern_init (IN pnfs_io_pattern *pattern, IN nfs41_root *root, IN nfs41_path_fh *meta_file, IN const stateid_arg *stateid, IN pnfs_layout_state *state, IN unsigned char *buffer, IN enum pnfs_iomode iomode, IN uint64_t offset, IN uint64_t length, IN uint32_t default_lease)
 
static void pattern_free (IN pnfs_io_pattern *pattern)
 
static __inline uint64_t positive_remainder (IN uint64_t dividend, IN uint32_t divisor)
 
static enum pnfs_status thread_next_unit (IN pnfs_io_thread *thread, OUT pnfs_io_unit *io)
 
static enum pnfs_status thread_data_server (IN pnfs_io_thread *thread, OUT pnfs_data_server **server_out)
 
static enum pnfs_status pattern_join (IN HANDLE *threads, IN DWORD count)
 
static enum pnfs_status pattern_fork (IN pnfs_io_pattern *pattern, IN pnfs_io_thread_fn thread_fn)
 
static uint64_t pattern_bytes_transferred (IN pnfs_io_pattern *pattern, OUT OPTIONAL enum stable_how4 *stable)
 
static enum pnfs_status map_ds_error (IN enum nfsstat4 nfsstat, IN pnfs_layout_state *state, IN const pnfs_file_layout *layout)
 
static uint32_t WINAPI file_layout_read_thread (void *args)
 
static uint32_t WINAPI file_layout_write_thread (void *args)
 
enum pnfs_status pnfs_read (IN nfs41_root *root, IN nfs41_open_state *state, IN stateid_arg *stateid, IN pnfs_layout_state *layout, IN uint64_t offset, IN uint64_t length, OUT unsigned char *buffer_out, OUT ULONG *len_out)
 
static enum pnfs_status mds_commit (IN nfs41_open_state *state, IN uint64_t offset, IN uint32_t length, IN const pnfs_io_pattern *pattern, OUT nfs41_file_info *info)
 
static enum pnfs_status layout_commit (IN nfs41_open_state *state, IN pnfs_layout_state *layout, IN uint64_t offset, IN uint64_t length, OUT nfs41_file_info *info)
 
enum pnfs_status pnfs_write (IN nfs41_root *root, IN nfs41_open_state *state, IN stateid_arg *stateid, IN pnfs_layout_state *layout, IN uint64_t offset, IN uint64_t length, IN unsigned char *buffer, OUT ULONG *len_out, OUT nfs41_file_info *info)
 

Macro Definition Documentation

◆ file_layout_entry

#define file_layout_entry (   pos)    list_container(pos, pnfs_file_layout, layout.entry)

Definition at line 32 of file pnfs_io.c.

Referenced by pattern_threads_init(), and thread_count().

◆ IOLVL

#define IOLVL   2 /* dprintf level for pnfs io logging */

Typedef Documentation

◆ pnfs_io_pattern

◆ pnfs_io_thread

◆ pnfs_io_thread_fn

typedef uint32_t(WINAPI * pnfs_io_thread_fn) (void *)

Definition at line 65 of file pnfs_io.c.

◆ pnfs_io_unit

Function Documentation

◆ file_layout_read_thread()

static uint32_t WINAPI file_layout_read_thread ( void args)
static

Definition at line 487 of file pnfs_io.c.

Referenced by pnfs_read().

488 {
490  stateid_arg stateid;
492  pnfs_io_pattern *pattern = thread->pattern;
495  uint32_t maxreadsize, bytes_read, total_read;
496  enum pnfs_status status;
497  enum nfsstat4 nfsstat;
498  bool_t eof;
499 
500  dprintf(IOLVL, "--> file_layout_read_thread(%u)\n", thread->id);
501 
502  /* get the data server for this thread */
503  status = thread_data_server(thread, &server);
504  if (status) {
505  eprintf("thread_data_server() failed with %s\n",
506  pnfs_error_string(status));
507  goto out;
508  }
509  /* find or establish a client for this data server */
510  status = pnfs_data_server_client(pattern->root,
511  server, pattern->default_lease, &client);
512  if (status) {
513  eprintf("pnfs_data_server_client() failed with %s\n",
514  pnfs_error_string(status));
515  goto out;
516  }
517 
518  memcpy(&stateid, pattern->stateid, sizeof(stateid));
519  stateid.stateid.seqid = 0;
520 
521  total_read = 0;
522  while (thread_next_unit(thread, &io) == PNFS_PENDING) {
523  maxreadsize = max_read_size(client->session, &thread->file->fh);
524  if (io.length > maxreadsize)
525  io.length = maxreadsize;
526 
527  nfsstat = nfs41_read(client->session, thread->file, &stateid,
528  io.offset, (uint32_t)io.length, io.buffer, &bytes_read, &eof);
529  if (nfsstat) {
530  eprintf("nfs41_read() failed with %s\n",
531  nfs_error_string(nfsstat));
532  status = map_ds_error(nfsstat, pattern->state, thread->layout);
533  break;
534  }
535 
536  total_read += bytes_read;
537  thread->offset += bytes_read;
538 
539  if (eof) {
540  dprintf(IOLVL, "read thread %u reached eof: offset %llu\n",
541  thread->id, thread->offset);
542  status = total_read ? PNFS_SUCCESS : PNFS_READ_EOF;
543  break;
544  }
545  }
546 out:
547  dprintf(IOLVL, "<-- file_layout_read_thread(%u) returning %s\n",
548  thread->id, pnfs_error_string(status));
549  return status;
550 }
pnfs_status
Definition: pnfs.h:58
uint32_t default_lease
Definition: pnfs_io.c:44
static rfbScreenInfoPtr server
Definition: vnc.c:74
uint64_t length
Definition: pnfs_io.c:60
int32_t bool_t
Definition: types.h:101
nfs41_root * root
Definition: pnfs_io.c:36
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
static enum pnfs_status map_ds_error(IN enum nfsstat4 nfsstat, IN pnfs_layout_state *state, IN const pnfs_file_layout *layout)
Definition: pnfs_io.c:459
uint32_t seqid
Definition: nfs41_types.h:144
static enum pnfs_status thread_next_unit(IN pnfs_io_thread *thread, OUT pnfs_io_unit *io)
Definition: pnfs_io.c:330
uint32_t max_read_size(IN const nfs41_session *session, IN const nfs41_fh *fh)
Definition: util.c:84
#define dprintf
Definition: regdump.c:33
uint32_t id
Definition: pnfs_io.c:53
const char * pnfs_error_string(enum pnfs_status status)
Definition: pnfs_debug.c:28
const stateid_arg * stateid
Definition: pnfs_io.c:38
pnfs_io_pattern * pattern
Definition: pnfs_io.c:49
nfs41_path_fh * file
Definition: pnfs_io.c:51
#define IOLVL
Definition: pnfs_io.c:30
static FILE * client
Definition: client.c:41
static FILE * out
Definition: regtests2xml.c:44
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
uint64_t offset
Definition: pnfs_io.c:59
static enum pnfs_status thread_data_server(IN pnfs_io_thread *thread, OUT pnfs_data_server **server_out)
Definition: pnfs_io.c:355
int nfs41_read(IN nfs41_session *session, IN nfs41_path_fh *file, IN stateid_arg *stateid, IN uint64_t offset, IN uint32_t count, OUT unsigned char *data_out, OUT uint32_t *data_len_out, OUT bool_t *eof_out)
Definition: nfs41_ops.c:774
static HANDLE thread
Definition: service.c:33
nfsstat4
Definition: nfs41_const.h:86
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
_Check_return_ _CRTIMP int __cdecl __cdecl eof(_In_ int _FileHandle)
pnfs_file_layout * layout
Definition: pnfs_io.c:50
stateid4 stateid
Definition: nfs41_ops.h:284
unsigned char * buffer
Definition: pnfs_io.c:58
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)
UINT32 uint32_t
Definition: types.h:75
pnfs_layout_state * state
Definition: pnfs_io.c:39
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK io
Definition: file.c:100
static SERVICE_STATUS status
Definition: service.c:31
struct __nfs41_session * session
Definition: nfs41.h:199
GLubyte * pattern
Definition: glext.h:7787
uint64_t offset
Definition: pnfs_io.c:52

◆ file_layout_write_thread()

static uint32_t WINAPI file_layout_write_thread ( void args)
static

Definition at line 552 of file pnfs_io.c.

Referenced by pnfs_write().

553 {
555  stateid_arg stateid;
557  pnfs_io_pattern *pattern = thread->pattern;
560  const uint64_t offset_start = thread->offset;
561  uint64_t commit_min, commit_max;
562  uint32_t maxwritesize, bytes_written, total_written;
563  enum pnfs_status status;
564  enum nfsstat4 nfsstat;
565 
566  dprintf(IOLVL, "--> file_layout_write_thread(%u)\n", thread->id);
567 
568  /* get the data server for this thread */
569  status = thread_data_server(thread, &server);
570  if (status) {
571  eprintf("thread_data_server() failed with %s\n",
572  pnfs_error_string(status));
573  goto out;
574  }
575  /* find or establish a client for this data server */
576  status = pnfs_data_server_client(pattern->root,
577  server, pattern->default_lease, &client);
578  if (status) {
579  eprintf("pnfs_data_server_client() failed with %s\n",
580  pnfs_error_string(status));
581  goto out;
582  }
583 
584  memcpy(&stateid, pattern->stateid, sizeof(stateid));
585  stateid.stateid.seqid = 0;
586 
587  maxwritesize = max_write_size(client->session, &thread->file->fh);
588 
589 retry_write:
590  thread->offset = offset_start;
591  thread->stable = FILE_SYNC4;
592  commit_min = NFS4_UINT64_MAX;
593  commit_max = 0;
594  total_written = 0;
595 
596  while (thread_next_unit(thread, &io) == PNFS_PENDING) {
597  if (io.length > maxwritesize)
598  io.length = maxwritesize;
599 
600  nfsstat = nfs41_write(client->session, thread->file, &stateid,
601  io.buffer, (uint32_t)io.length, io.offset, UNSTABLE4,
602  &bytes_written, &thread->verf, NULL);
603  if (nfsstat) {
604  eprintf("nfs41_write() failed with %s\n",
605  nfs_error_string(nfsstat));
606  status = map_ds_error(nfsstat, pattern->state, thread->layout);
607  break;
608  }
609  if (!verify_write(&thread->verf, &thread->stable))
610  goto retry_write;
611 
612  total_written += bytes_written;
613  thread->offset += bytes_written;
614 
615  /* track the range for commit */
616  if (commit_min > io.offset)
617  commit_min = io.offset;
618  if (commit_max < io.offset + io.length)
619  commit_max = io.offset + io.length;
620  }
621 
622  /* nothing to commit */
623  if (commit_max <= commit_min)
624  goto out;
625  /* layout changed; redo all io against metadata server */
626  if (status == PNFSERR_LAYOUT_CHANGED)
627  goto out;
628  /* the data is already in stable storage */
629  if (thread->stable != UNSTABLE4)
630  goto out;
631  /* the metadata server expects us to commit there instead */
632  if (should_commit_to_mds(thread->layout))
633  goto out;
634 
635  dprintf(1, "sending COMMIT to data server for offset=%lld len=%lld\n",
636  commit_min, commit_max - commit_min);
637  nfsstat = nfs41_commit(client->session, thread->file,
638  commit_min, (uint32_t)(commit_max - commit_min), 0, &thread->verf, NULL);
639 
640  if (nfsstat)
641  status = map_ds_error(nfsstat, pattern->state, thread->layout);
642  else if (!verify_commit(&thread->verf)) {
643  /* resend the writes unless the layout was recalled */
644  if (status != PNFSERR_LAYOUT_RECALLED)
645  goto retry_write;
646  status = PNFSERR_IO;
647  } else {
648  /* on successful commit, leave pnfs_status unchanged; if the
649  * layout was recalled, we still want to return the error */
650  thread->stable = DATA_SYNC4;
651  }
652 out:
653  dprintf(IOLVL, "<-- file_layout_write_thread(%u) returning %s\n",
654  thread->id, pnfs_error_string(status));
655  return status;
656 }
pnfs_status
Definition: pnfs.h:58
uint32_t default_lease
Definition: pnfs_io.c:44
static rfbScreenInfoPtr server
Definition: vnc.c:74
uint64_t length
Definition: pnfs_io.c:60
int nfs41_write(IN nfs41_session *session, IN nfs41_path_fh *file, IN stateid_arg *stateid, IN unsigned char *data, IN uint32_t data_len, IN uint64_t offset, IN enum stable_how4 stable, OUT uint32_t *bytes_written, OUT nfs41_write_verf *verf, OUT nfs41_file_info *cinfo)
Definition: nfs41_ops.c:685
nfs41_write_verf verf
Definition: pnfs_io.c:48
enum stable_how4 stable
Definition: pnfs_io.c:54
nfs41_root * root
Definition: pnfs_io.c:36
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
static enum pnfs_status map_ds_error(IN enum nfsstat4 nfsstat, IN pnfs_layout_state *state, IN const pnfs_file_layout *layout)
Definition: pnfs_io.c:459
uint32_t seqid
Definition: nfs41_types.h:144
static enum pnfs_status thread_next_unit(IN pnfs_io_thread *thread, OUT pnfs_io_unit *io)
Definition: pnfs_io.c:330
#define dprintf
Definition: regdump.c:33
uint32_t id
Definition: pnfs_io.c:53
smooth NULL
Definition: ftsmooth.c:416
const char * pnfs_error_string(enum pnfs_status status)
Definition: pnfs_debug.c:28
static const uint64_t NFS4_UINT64_MAX
Definition: nfs41_types.h:32
int nfs41_commit(IN nfs41_session *session, IN nfs41_path_fh *file, IN uint64_t offset, IN uint32_t count, IN bool_t do_getattr, OUT nfs41_write_verf *verf, OUT nfs41_file_info *cinfo)
Definition: nfs41_ops.c:833
const stateid_arg * stateid
Definition: pnfs_io.c:38
pnfs_io_pattern * pattern
Definition: pnfs_io.c:49
__inline int should_commit_to_mds(IN const pnfs_file_layout *layout)
Definition: pnfs.h:306
nfs41_path_fh * file
Definition: pnfs_io.c:51
#define IOLVL
Definition: pnfs_io.c:30
bool_t verify_commit(IN nfs41_write_verf *verf)
Definition: util.c:126
static FILE * client
Definition: client.c:41
static FILE * out
Definition: regtests2xml.c:44
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
uint64_t offset
Definition: pnfs_io.c:59
static enum pnfs_status thread_data_server(IN pnfs_io_thread *thread, OUT pnfs_data_server **server_out)
Definition: pnfs_io.c:355
static HANDLE thread
Definition: service.c:33
nfsstat4
Definition: nfs41_const.h:86
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
UINT64 uint64_t
Definition: types.h:77
pnfs_file_layout * layout
Definition: pnfs_io.c:50
stateid4 stateid
Definition: nfs41_ops.h:284
unsigned char * buffer
Definition: pnfs_io.c:58
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)
UINT32 uint32_t
Definition: types.h:75
pnfs_layout_state * state
Definition: pnfs_io.c:39
bool_t verify_write(IN nfs41_write_verf *verf, IN OUT enum stable_how4 *stable)
Definition: util.c:100
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK io
Definition: file.c:100
static SERVICE_STATUS status
Definition: service.c:31
uint32_t max_write_size(IN const nfs41_session *session, IN const nfs41_fh *fh)
Definition: util.c:92
struct __nfs41_session * session
Definition: nfs41.h:199
GLubyte * pattern
Definition: glext.h:7787
uint64_t offset
Definition: pnfs_io.c:52

◆ get_dense_fh()

static enum pnfs_status get_dense_fh ( IN pnfs_file_layout layout,
IN uint32_t  stripeid,
OUT nfs41_path_fh **  file_out 
)
static

Definition at line 106 of file pnfs_io.c.

Referenced by thread_init().

110 {
111  const uint32_t filehandle_count = layout->filehandles.count;
112  const uint32_t stripe_count = layout->device->stripes.count;
114 
115  if (filehandle_count == stripe_count) {
116  *file_out = &layout->filehandles.arr[stripeid];
117  } else {
118  eprintf("invalid dense layout! has %u file handles "
119  "and %u stripes\n", filehandle_count, stripe_count);
120  status = PNFSERR_INVALID_FH_LIST;
121  }
122  return status;
123 }
pnfs_status
Definition: pnfs.h:58
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
static DWORD layout
Definition: bitmap.c:46
UINT32 uint32_t
Definition: types.h:75
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ get_sparse_fh()

static enum pnfs_status get_sparse_fh ( IN pnfs_file_layout layout,
IN nfs41_path_fh meta_file,
IN uint32_t  stripeid,
OUT nfs41_path_fh **  file_out 
)
static

Definition at line 78 of file pnfs_io.c.

Referenced by thread_init().

83 {
84  const uint32_t filehandle_count = layout->filehandles.count;
85  const uint32_t server_count = layout->device->servers.count;
87 
88  if (filehandle_count == server_count) {
89  const uint32_t serverid = data_server_index(layout->device, stripeid);
90  *file_out = &layout->filehandles.arr[serverid];
91  } else if (filehandle_count == 1) {
92  *file_out = &layout->filehandles.arr[0];
93  } else if (filehandle_count == 0) {
94  *file_out = meta_file;
95  } else {
96  eprintf("invalid sparse layout! has %u file handles "
97  "and %u servers\n", filehandle_count, server_count);
98  status = PNFSERR_INVALID_FH_LIST;
99  }
100  return status;
101 }
pnfs_status
Definition: pnfs.h:58
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
static DWORD layout
Definition: bitmap.c:46
UINT32 uint32_t
Definition: types.h:75
static SERVICE_STATUS status
Definition: service.c:31
__inline uint32_t data_server_index(IN const pnfs_file_device *device, IN uint32_t stripeid)
Definition: pnfs.h:358
Definition: ps.c:97

◆ layout_commit()

static enum pnfs_status layout_commit ( IN nfs41_open_state state,
IN pnfs_layout_state layout,
IN uint64_t  offset,
IN uint64_t  length,
OUT nfs41_file_info info 
)
static

Definition at line 762 of file pnfs_io.c.

Referenced by pnfs_write().

768 {
769  stateid4 layout_stateid;
770  uint64_t last_offset = offset + length - 1;
771  uint64_t *new_last_offset = NULL;
772  enum nfsstat4 nfsstat;
774 
776  /* if this is past the current eof, update the open state's
777  * last offset, and pass a pointer to LAYOUTCOMMIT */
778  if (state->pnfs_last_offset < last_offset ||
779  (state->pnfs_last_offset == 0 && last_offset == 0)) {
780  state->pnfs_last_offset = last_offset;
781  new_last_offset = &last_offset;
782  }
784 
786  memcpy(&layout_stateid, &layout->stateid, sizeof(layout_stateid));
788 
789  dprintf(1, "LAYOUTCOMMIT for offset=%lld len=%lld new_last_offset=%u\n",
790  offset, length, new_last_offset ? 1 : 0);
791  nfsstat = pnfs_rpc_layoutcommit(state->session, &state->file,
792  &layout_stateid, offset, length, new_last_offset, NULL, info);
793  if (nfsstat) {
794  dprintf(IOLVL, "pnfs_rpc_layoutcommit() failed with %s\n",
795  nfs_error_string(nfsstat));
796  status = PNFSERR_IO;
797  }
798  return status;
799 }
pnfs_status
Definition: pnfs.h:58
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
GLintptr offset
Definition: glext.h:5920
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define IOLVL
Definition: pnfs_io.c:30
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
enum nfsstat4 pnfs_rpc_layoutcommit(IN nfs41_session *session, IN nfs41_path_fh *file, IN stateid4 *stateid, IN uint64_t offset, IN uint64_t length, IN OPTIONAL uint64_t *new_last_offset, IN OPTIONAL nfstime4 *new_time_modify, OUT nfs41_file_info *info)
Definition: nfs41_ops.c:1999
nfsstat4
Definition: nfs41_const.h:86
static int state
Definition: maze.c:121
static DWORD layout
Definition: bitmap.c:46
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
UINT64 uint64_t
Definition: types.h:77
static SERVICE_STATUS status
Definition: service.c:31
VOID WINAPI AcquireSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:61
VOID WINAPI ReleaseSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:89
Definition: ps.c:97

◆ layout_compatible()

static __inline bool_t layout_compatible ( IN const pnfs_layout layout,
IN enum pnfs_iomode  iomode,
IN uint64_t  position 
)
static

Definition at line 125 of file pnfs_io.c.

Referenced by pattern_threads_init(), and thread_count().

129 {
130  return layout->iomode >= iomode
131  && layout->offset <= position
132  && position < layout->offset + layout->length;
133 }
static DWORD layout
Definition: bitmap.c:46

◆ map_ds_error()

static enum pnfs_status map_ds_error ( IN enum nfsstat4  nfsstat,
IN pnfs_layout_state state,
IN const pnfs_file_layout layout 
)
static

Definition at line 459 of file pnfs_io.c.

Referenced by file_layout_read_thread(), and file_layout_write_thread().

463 {
464  switch (nfsstat) {
465  case NO_ERROR:
466  return PNFS_SUCCESS;
467 
468  /* 13.11 Layout Revocation and Fencing
469  * http://tools.ietf.org/html/rfc5661#section-13.11
470  * if we've been fenced, we'll either get ERR_STALE when we PUTFH
471  * something in layout.filehandles, or ERR_PNFS_NO_LAYOUT when
472  * attempting to READ or WRITE */
473  case NFS4ERR_STALE:
475  dprintf(IOLVL, "data server fencing detected!\n");
476 
478 
479  /* return CHANGED to prevent any further use of the layout */
480  return PNFSERR_LAYOUT_CHANGED;
481 
482  default:
483  return PNFSERR_IO;
484  }
485 }
#define NO_ERROR
Definition: dderror.h:5
#define dprintf
Definition: regdump.c:33
#define IOLVL
Definition: pnfs_io.c:30
void pnfs_layout_recall_fenced(IN pnfs_layout_state *state, IN const pnfs_layout *layout)
Definition: pnfs_layout.c:1233
static int state
Definition: maze.c:121
static DWORD layout
Definition: bitmap.c:46

◆ mds_commit()

static enum pnfs_status mds_commit ( IN nfs41_open_state state,
IN uint64_t  offset,
IN uint32_t  length,
IN const pnfs_io_pattern pattern,
OUT nfs41_file_info info 
)
static

Definition at line 714 of file pnfs_io.c.

Referenced by pnfs_write().

720 {
721  nfs41_write_verf verf;
722  enum nfsstat4 nfsstat;
724  uint32_t i;
725 
726  nfsstat = nfs41_commit(state->session,
727  &state->file, offset, length, 1, &verf, info);
728  if (nfsstat) {
729  eprintf("nfs41_commit() to mds failed with %s\n",
730  nfs_error_string(nfsstat));
731  status = PNFSERR_IO;
732  goto out;
733  }
734 
735  /* 13.7. COMMIT through Metadata Server:
736  * If nfl_util & NFL4_UFLG_COMMIT_THRU_MDS is TRUE, then in order to
737  * maintain the current NFSv4.1 commit and recovery model, the data
738  * servers MUST return a common writeverf verifier in all WRITE
739  * responses for a given file layout, and the metadata server's
740  * COMMIT implementation must return the same writeverf. */
741  for (i = 0; i < pattern->count; i++) {
742  const pnfs_io_thread *thread = &pattern->threads[i];
743  if (thread->stable != UNSTABLE4) /* already committed */
744  continue;
745 
746  if (!should_commit_to_mds(thread->layout)) {
747  /* commit to mds is not allowed on this layout */
748  eprintf("mds commit: failed to commit to data server\n");
749  status = PNFSERR_IO;
750  break;
751  }
752  if (memcmp(verf.verf, thread->verf.verf, NFS4_VERIFIER_SIZE) != 0) {
753  eprintf("mds commit verifier doesn't match ds write verifiers\n");
754  status = PNFSERR_IO;
755  break;
756  }
757  }
758 out:
759  return status;
760 }
pnfs_status
Definition: pnfs.h:58
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
nfs41_write_verf verf
Definition: pnfs_io.c:48
enum stable_how4 stable
Definition: pnfs_io.c:54
GLintptr offset
Definition: glext.h:5920
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
#define NFS4_VERIFIER_SIZE
Definition: nfs41_const.h:30
GLenum GLclampf GLint i
Definition: glfuncs.h:14
unsigned char verf[NFS4_VERIFIER_SIZE]
Definition: nfs41_types.h:76
int nfs41_commit(IN nfs41_session *session, IN nfs41_path_fh *file, IN uint64_t offset, IN uint32_t count, IN bool_t do_getattr, OUT nfs41_write_verf *verf, OUT nfs41_file_info *cinfo)
Definition: nfs41_ops.c:833
__inline int should_commit_to_mds(IN const pnfs_file_layout *layout)
Definition: pnfs.h:306
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static FILE * out
Definition: regtests2xml.c:44
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
static HANDLE thread
Definition: service.c:33
nfsstat4
Definition: nfs41_const.h:86
static int state
Definition: maze.c:121
pnfs_file_layout * layout
Definition: pnfs_io.c:50
UINT32 uint32_t
Definition: types.h:75
static SERVICE_STATUS status
Definition: service.c:31
GLubyte * pattern
Definition: glext.h:7787
Definition: ps.c:97

◆ pattern_bytes_transferred()

static uint64_t pattern_bytes_transferred ( IN pnfs_io_pattern pattern,
OUT OPTIONAL enum stable_how4 stable 
)
static

Definition at line 442 of file pnfs_io.c.

Referenced by pnfs_read(), and pnfs_write().

445 {
446  uint64_t lowest_offset = pattern->offset_end;
447  uint32_t i;
448 
449  if (stable) *stable = FILE_SYNC4;
450 
451  for (i = 0; i < pattern->count; i++) {
452  lowest_offset = min(lowest_offset, pattern->threads[i].offset);
453  if (stable) *stable = min(*stable, pattern->threads[i].stable);
454  }
455  return lowest_offset - pattern->offset_start;
456 }
GLenum GLclampf GLint i
Definition: glfuncs.h:14
UINT64 uint64_t
Definition: types.h:77
#define min(a, b)
Definition: monoChain.cc:55
UINT32 uint32_t
Definition: types.h:75
GLubyte * pattern
Definition: glext.h:7787

◆ pattern_fork()

static enum pnfs_status pattern_fork ( IN pnfs_io_pattern pattern,
IN pnfs_io_thread_fn  thread_fn 
)
static

Definition at line 387 of file pnfs_io.c.

Referenced by pnfs_read(), and pnfs_write().

390 {
391  HANDLE *threads;
392  uint32_t i;
394 
395  if (pattern->count == 0)
396  goto out;
397 
398  if (pattern->count == 1) {
399  /* no need to fork if there's only 1 thread */
400  status = (enum pnfs_status)thread_fn(pattern->threads);
401  goto out;
402  }
403 
404  /* create a thread for each unit that has actual io */
405  threads = calloc(pattern->count, sizeof(HANDLE));
406  if (threads == NULL) {
407  status = PNFSERR_RESOURCES;
408  goto out;
409  }
410 
411  for (i = 0; i < pattern->count; i++) {
412  threads[i] = (HANDLE)_beginthreadex(NULL, 0,
413  thread_fn, &pattern->threads[i], 0, NULL);
414  if (threads[i] == NULL) {
415  eprintf("_beginthreadex() failed with %d\n", GetLastError());
416  pattern->count = i; /* join any threads already started */
417  break;
418  }
419  }
420 
421  /* wait on all threads to finish */
422  status = pattern_join(threads, pattern->count);
423  if (status) {
424  eprintf("pattern_join() failed with %s\n", pnfs_error_string(status));
425  goto out;
426  }
427 
428  for (i = 0; i < pattern->count; i++) {
429  /* keep track of the most severe error returned by a thread */
430  DWORD exitcode;
431  if (GetExitCodeThread(threads[i], &exitcode))
432  status = max(status, (enum pnfs_status)exitcode);
433 
434  CloseHandle(threads[i]);
435  }
436 
437  free(threads);
438 out:
439  return status;
440 }
pnfs_status
Definition: pnfs.h:58
#define max(a, b)
Definition: svc.c:63
#define CloseHandle
Definition: compat.h:398
#define free
Definition: debug_ros.c:5
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
_CRTIMP uintptr_t __cdecl _beginthreadex(_In_opt_ void *_Security, _In_ unsigned _StackSize, _In_ unsigned(__stdcall *_StartAddress)(void *), _In_opt_ void *_ArgList, _In_ unsigned _InitFlag, _Out_opt_ unsigned *_ThrdAddr)
BOOL WINAPI GetExitCodeThread(IN HANDLE hThread, OUT LPDWORD lpExitCode)
Definition: thread.c:503
GLenum GLclampf GLint i
Definition: glfuncs.h:14
static enum pnfs_status pattern_join(IN HANDLE *threads, IN DWORD count)
Definition: pnfs_io.c:369
smooth NULL
Definition: ftsmooth.c:416
const char * pnfs_error_string(enum pnfs_status status)
Definition: pnfs_debug.c:28
static FILE * out
Definition: regtests2xml.c:44
unsigned long DWORD
Definition: ntddk_ex.h:95
PVOID HANDLE
Definition: typedefs.h:71
static HANDLE ULONG_PTR DWORD threads
Definition: process.c:81
UINT32 uint32_t
Definition: types.h:75
#define calloc
Definition: rosglue.h:14
static SERVICE_STATUS status
Definition: service.c:31
GLubyte * pattern
Definition: glext.h:7787
Definition: ps.c:97

◆ pattern_free()

static void pattern_free ( IN pnfs_io_pattern pattern)
static

Definition at line 274 of file pnfs_io.c.

Referenced by pnfs_read(), and pnfs_write().

276 {
277  /* inform the layout that our io is finished */
279  free(pattern->threads);
280 }
#define free
Definition: debug_ros.c:5
void pnfs_layout_io_finished(IN pnfs_layout_state *state)
Definition: pnfs_layout.c:1267
GLubyte * pattern
Definition: glext.h:7787

◆ pattern_init()

static enum pnfs_status pattern_init ( IN pnfs_io_pattern pattern,
IN nfs41_root root,
IN nfs41_path_fh meta_file,
IN const stateid_arg stateid,
IN pnfs_layout_state state,
IN unsigned char buffer,
IN enum pnfs_iomode  iomode,
IN uint64_t  offset,
IN uint64_t  length,
IN uint32_t  default_lease 
)
static

Definition at line 226 of file pnfs_io.c.

Referenced by pnfs_read(), and pnfs_write().

237 {
238  enum pnfs_status status;
239 
240  /* calculate an upper bound on the number of threads to allocate */
241  pattern->count = thread_count(state, iomode, offset, length);
242  pattern->threads = calloc(pattern->count, sizeof(pnfs_io_thread));
243  if (pattern->threads == NULL) {
244  status = PNFSERR_RESOURCES;
245  goto out;
246  }
247 
248  /* information shared between threads */
249  pattern->root = root;
250  pattern->meta_file = meta_file;
251  pattern->stateid = stateid;
252  pattern->state = state;
253  pattern->buffer = buffer;
254  pattern->offset_start = offset;
255  pattern->offset_end = offset + length;
256  pattern->default_lease = default_lease;
257 
258  /* initialize a thread for every stripe necessary to cover the range */
259  status = pattern_threads_init(pattern, iomode, offset, length);
260  if (status)
261  goto out_err_free;
262 
263  /* take a reference on the layout so we don't return it during io */
265 out:
266  return status;
267 
268 out_err_free:
269  free(pattern->threads);
270  pattern->threads = NULL;
271  goto out;
272 }
pnfs_status
Definition: pnfs.h:58
#define free
Definition: debug_ros.c:5
struct _root root
GLintptr offset
Definition: glext.h:5920
GLuint buffer
Definition: glext.h:5915
static enum pnfs_status pattern_threads_init(IN pnfs_io_pattern *pattern, IN enum pnfs_iomode iomode, IN uint64_t offset, IN uint64_t length)
Definition: pnfs_io.c:176
smooth NULL
Definition: ftsmooth.c:416
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static FILE * out
Definition: regtests2xml.c:44
void pnfs_layout_io_start(IN pnfs_layout_state *state)
Definition: pnfs_layout.c:1257
static int state
Definition: maze.c:121
static uint32_t thread_count(IN pnfs_layout_state *state, IN enum pnfs_iomode iomode, IN uint64_t offset, IN uint64_t length)
Definition: pnfs_io.c:137
#define calloc
Definition: rosglue.h:14
static SERVICE_STATUS status
Definition: service.c:31
GLubyte * pattern
Definition: glext.h:7787

◆ pattern_join()

static enum pnfs_status pattern_join ( IN HANDLE threads,
IN DWORD  count 
)
static

Definition at line 369 of file pnfs_io.c.

Referenced by pattern_fork().

372 {
373  DWORD status;
374  /* WaitForMultipleObjects() supports a maximum of 64 objects */
375  while (count) {
378  if (status != WAIT_OBJECT_0)
379  return PNFSERR_RESOURCES;
380 
381  count -= n;
382  threads += n;
383  }
384  return PNFS_SUCCESS;
385 }
#define TRUE
Definition: types.h:120
#define MAXIMUM_WAIT_OBJECTS
Definition: winbase.h:385
GLuint GLuint GLsizei count
Definition: gl.h:1545
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
GLuint n
Definition: s_context.h:57
#define WAIT_OBJECT_0
Definition: winbase.h:387
unsigned long DWORD
Definition: ntddk_ex.h:95
static HANDLE ULONG_PTR DWORD threads
Definition: process.c:81
#define min(a, b)
Definition: monoChain.cc:55
#define INFINITE
Definition: serial.h:102
static SERVICE_STATUS status
Definition: service.c:31

◆ pattern_threads_init()

static enum pnfs_status pattern_threads_init ( IN pnfs_io_pattern pattern,
IN enum pnfs_iomode  iomode,
IN uint64_t  offset,
IN uint64_t  length 
)
static

Definition at line 176 of file pnfs_io.c.

Referenced by pattern_init().

181 {
183  uint64_t position = offset;
184  struct list_entry *entry;
185  uint32_t s, t = 0;
187 
188  list_for_each(entry, &pattern->state->layouts) {
190 
191  if (!layout_compatible(&layout->layout, iomode, position))
192  continue;
193 
194  for (s = 0; s < layout->device->stripes.count; s++) {
195  uint64_t off = position;
196 
197  /* does the range contain this stripe? */
198  status = stripe_next_unit(layout, s, &off, offset + length, &io);
199  if (status != PNFS_PENDING)
200  continue;
201 
202  if (t >= pattern->count) { /* miscounted threads needed? */
203  status = PNFSERR_NO_LAYOUT;
204  goto out;
205  }
206 
207  status = thread_init(pattern, &pattern->threads[t++], layout, s, off);
208  if (status)
209  goto out;
210  }
211  position = layout->layout.offset + layout->layout.length;
212  }
213 
214  if (position < offset + length) {
215  /* unable to satisfy the entire range */
216  status = PNFSERR_NO_LAYOUT;
217  goto out;
218  }
219 
220  /* update the pattern with the actual number of threads used */
221  pattern->count = t;
222 out:
223  return status;
224 }
pnfs_status
Definition: pnfs.h:58
uint64_t offset
Definition: pnfs.h:166
uint8_t entry
Definition: isohybrid.c:63
GLintptr offset
Definition: glext.h:5920
GLdouble GLdouble t
Definition: gl.h:2047
pnfs_file_device * device
Definition: pnfs.h:181
uint32_t count
Definition: pnfs.h:124
pnfs_stripe_indices stripes
Definition: pnfs.h:141
#define list_for_each(entry, head)
Definition: list.h:36
static enum pnfs_status stripe_next_unit(IN const pnfs_file_layout *layout, IN uint32_t stripeid, IN uint64_t *position, IN uint64_t offset_end, OUT pnfs_io_unit *io)
Definition: pnfs_io.c:291
uint64_t length
Definition: pnfs.h:167
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static __inline bool_t layout_compatible(IN const pnfs_layout *layout, IN enum pnfs_iomode iomode, IN uint64_t position)
Definition: pnfs_io.c:125
static FILE * out
Definition: regtests2xml.c:44
static DWORD layout
Definition: bitmap.c:46
GLdouble s
Definition: gl.h:2039
static enum pnfs_status thread_init(IN pnfs_io_pattern *pattern, IN pnfs_io_thread *thread, IN pnfs_file_layout *layout, IN uint32_t stripeid, IN uint64_t offset)
Definition: pnfs_io.c:159
UINT64 uint64_t
Definition: types.h:77
Definition: list.h:27
UINT32 uint32_t
Definition: types.h:75
pnfs_layout layout
Definition: pnfs.h:178
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK io
Definition: file.c:100
static SERVICE_STATUS status
Definition: service.c:31
GLubyte * pattern
Definition: glext.h:7787
#define file_layout_entry(pos)
Definition: pnfs_io.c:32
off
Definition: i386-dis.c:3909
Definition: ps.c:97

◆ pnfs_read()

enum pnfs_status pnfs_read ( IN nfs41_root root,
IN nfs41_open_state state,
IN stateid_arg stateid,
IN pnfs_layout_state layout,
IN uint64_t  offset,
IN uint64_t  length,
OUT unsigned char buffer_out,
OUT ULONG len_out 
)

Definition at line 659 of file pnfs_io.c.

668 {
670  enum pnfs_status status;
671 
672  dprintf(IOLVL, "--> pnfs_read(%llu, %llu)\n", offset, length);
673 
674  *len_out = 0;
675 
677 
678  /* get layouts/devices for the entire range; PNFS_PENDING means we
679  * dropped the lock to send an rpc, so repeat until it succeeds */
680  do {
681  status = pnfs_layout_state_prepare(layout, state->session,
682  &state->file, stateid, PNFS_IOMODE_READ, offset, length);
683  } while (status == PNFS_PENDING);
684 
685  if (status == PNFS_SUCCESS) {
686  /* interpret the layout and set up threads for io */
687  status = pattern_init(&pattern, root, &state->file, stateid,
688  layout, buffer_out, PNFS_IOMODE_READ, offset, length,
689  state->session->lease_time);
690  if (status)
691  eprintf("pattern_init() failed with %s\n",
692  pnfs_error_string(status));
693  }
694 
696 
697  if (status)
698  goto out;
699 
700  status = pattern_fork(&pattern, file_layout_read_thread);
701  if (status != PNFS_SUCCESS && status != PNFS_READ_EOF)
702  goto out_free_pattern;
703 
704  *len_out = (ULONG)pattern_bytes_transferred(&pattern, NULL);
705 
706 out_free_pattern:
707  pattern_free(&pattern);
708 out:
709  dprintf(IOLVL, "<-- pnfs_read() returning %s\n",
710  pnfs_error_string(status));
711  return status;
712 }
pnfs_status
Definition: pnfs.h:58
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
static uint64_t pattern_bytes_transferred(IN pnfs_io_pattern *pattern, OUT OPTIONAL enum stable_how4 *stable)
Definition: pnfs_io.c:442
static uint32_t WINAPI file_layout_read_thread(void *args)
Definition: pnfs_io.c:487
GLintptr offset
Definition: glext.h:5920
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
static enum pnfs_status pattern_fork(IN pnfs_io_pattern *pattern, IN pnfs_io_thread_fn thread_fn)
Definition: pnfs_io.c:387
static enum pnfs_status pattern_init(IN pnfs_io_pattern *pattern, IN nfs41_root *root, IN nfs41_path_fh *meta_file, IN const stateid_arg *stateid, IN pnfs_layout_state *state, IN unsigned char *buffer, IN enum pnfs_iomode iomode, IN uint64_t offset, IN uint64_t length, IN uint32_t default_lease)
Definition: pnfs_io.c:226
enum pnfs_status pnfs_layout_state_prepare(IN pnfs_layout_state *state, IN struct __nfs41_session *session, IN nfs41_path_fh *meta_file, IN struct __stateid_arg *stateid, IN enum pnfs_iomode iomode, IN uint64_t offset, IN uint64_t length)
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416
const char * pnfs_error_string(enum pnfs_status status)
Definition: pnfs_debug.c:28
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define IOLVL
Definition: pnfs_io.c:30
static FILE * out
Definition: regtests2xml.c:44
static void pattern_free(IN pnfs_io_pattern *pattern)
Definition: pnfs_io.c:274
static int state
Definition: maze.c:121
static DWORD layout
Definition: bitmap.c:46
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
unsigned int ULONG
Definition: retypes.h:1
static SERVICE_STATUS status
Definition: service.c:31
GLubyte * pattern
Definition: glext.h:7787

◆ pnfs_write()

enum pnfs_status pnfs_write ( IN nfs41_root root,
IN nfs41_open_state state,
IN stateid_arg stateid,
IN pnfs_layout_state layout,
IN uint64_t  offset,
IN uint64_t  length,
IN unsigned char buffer,
OUT ULONG len_out,
OUT nfs41_file_info info 
)

Definition at line 801 of file pnfs_io.c.

811 {
813  enum stable_how4 stable;
814  enum pnfs_status status;
815 
816  dprintf(IOLVL, "--> pnfs_write(%llu, %llu)\n", offset, length);
817 
818  *len_out = 0;
819 
821 
822  /* get layouts/devices for the entire range; PNFS_PENDING means we
823  * dropped the lock to send an rpc, so repeat until it succeeds */
824  do {
825  status = pnfs_layout_state_prepare(layout, state->session,
826  &state->file, stateid, PNFS_IOMODE_RW, offset, length);
827  } while (status == PNFS_PENDING);
828 
829  if (status == PNFS_SUCCESS) {
830  /* interpret the layout and set up threads for io */
831  status = pattern_init(&pattern, root, &state->file, stateid,
833  state->session->lease_time);
834  if (status)
835  eprintf("pattern_init() failed with %s\n",
836  pnfs_error_string(status));
837  }
838 
840 
841  if (status)
842  goto out;
843 
844  status = pattern_fork(&pattern, file_layout_write_thread);
845  /* on layout recall, we still attempt to commit what we wrote */
846  if (status != PNFS_SUCCESS && status != PNFSERR_LAYOUT_RECALLED)
847  goto out_free_pattern;
848 
849  *len_out = (ULONG)pattern_bytes_transferred(&pattern, &stable);
850  if (*len_out == 0)
851  goto out_free_pattern;
852 
853  if (stable == UNSTABLE4) {
854  /* send COMMIT to the mds and verify against all ds writes */
855  status = mds_commit(state, offset, *len_out, &pattern, info);
856  } else if (stable == DATA_SYNC4) {
857  /* send LAYOUTCOMMIT to sync the metadata */
858  status = layout_commit(state, layout, offset, *len_out, info);
859  } else {
860  /* send a GETATTR to update the cached size */
861  bitmap4 attr_request;
862  nfs41_superblock_getattr_mask(state->file.fh.superblock, &attr_request);
863  nfs41_getattr(state->session, &state->file, &attr_request, info);
864  }
865 out_free_pattern:
866  pattern_free(&pattern);
867 out:
868  dprintf(IOLVL, "<-- pnfs_write() returning %s\n",
869  pnfs_error_string(status));
870  return status;
871 }
pnfs_status
Definition: pnfs.h:58
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
static uint64_t pattern_bytes_transferred(IN pnfs_io_pattern *pattern, OUT OPTIONAL enum stable_how4 *stable)
Definition: pnfs_io.c:442
static enum pnfs_status layout_commit(IN nfs41_open_state *state, IN pnfs_layout_state *layout, IN uint64_t offset, IN uint64_t length, OUT nfs41_file_info *info)
Definition: pnfs_io.c:762
GLintptr offset
Definition: glext.h:5920
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
GLuint buffer
Definition: glext.h:5915
static enum pnfs_status pattern_fork(IN pnfs_io_pattern *pattern, IN pnfs_io_thread_fn thread_fn)
Definition: pnfs_io.c:387
static enum pnfs_status pattern_init(IN pnfs_io_pattern *pattern, IN nfs41_root *root, IN nfs41_path_fh *meta_file, IN const stateid_arg *stateid, IN pnfs_layout_state *state, IN unsigned char *buffer, IN enum pnfs_iomode iomode, IN uint64_t offset, IN uint64_t length, IN uint32_t default_lease)
Definition: pnfs_io.c:226
stable_how4
Definition: nfs41_ops.h:835
enum pnfs_status pnfs_layout_state_prepare(IN pnfs_layout_state *state, IN struct __nfs41_session *session, IN nfs41_path_fh *meta_file, IN struct __stateid_arg *stateid, IN enum pnfs_iomode iomode, IN uint64_t offset, IN uint64_t length)
#define dprintf
Definition: regdump.c:33
const char * pnfs_error_string(enum pnfs_status status)
Definition: pnfs_debug.c:28
int nfs41_getattr(IN nfs41_session *session, IN OPTIONAL nfs41_path_fh *file, IN bitmap4 *attr_request, OUT nfs41_file_info *info)
Definition: nfs41_ops.c:1063
static enum pnfs_status mds_commit(IN nfs41_open_state *state, IN uint64_t offset, IN uint32_t length, IN const pnfs_io_pattern *pattern, OUT nfs41_file_info *info)
Definition: pnfs_io.c:714
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define IOLVL
Definition: pnfs_io.c:30
static FILE * out
Definition: regtests2xml.c:44
static void pattern_free(IN pnfs_io_pattern *pattern)
Definition: pnfs_io.c:274
static int state
Definition: maze.c:121
static DWORD layout
Definition: bitmap.c:46
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
static uint32_t WINAPI file_layout_write_thread(void *args)
Definition: pnfs_io.c:552
static __inline void nfs41_superblock_getattr_mask(IN const nfs41_superblock *superblock, OUT bitmap4 *attrs)
Definition: nfs41.h:448
unsigned int ULONG
Definition: retypes.h:1
static SERVICE_STATUS status
Definition: service.c:31
GLubyte * pattern
Definition: glext.h:7787

◆ positive_remainder()

static __inline uint64_t positive_remainder ( IN uint64_t  dividend,
IN uint32_t  divisor 
)
static

Definition at line 282 of file pnfs_io.c.

Referenced by stripe_next_unit().

285 {
286  const uint64_t remainder = dividend % divisor;
287  return remainder < divisor ? remainder : remainder + divisor;
288 }
double __cdecl remainder(double, double)
GLuint divisor
Definition: glext.h:6313
UINT64 uint64_t
Definition: types.h:77

◆ stripe_next_unit()

static enum pnfs_status stripe_next_unit ( IN const pnfs_file_layout layout,
IN uint32_t  stripeid,
IN uint64_t position,
IN uint64_t  offset_end,
OUT pnfs_io_unit io 
)
static

Definition at line 291 of file pnfs_io.c.

Referenced by pattern_threads_init(), and thread_next_unit().

297 {
298  const uint32_t unit_size = layout_unit_size(layout);
299  const uint32_t stripe_count = layout->device->stripes.count;
300  uint64_t sui = stripe_unit_number(layout, *position, unit_size);
301 
302  /* advance to the desired stripeid */
303  sui += abs(stripeid - stripe_index(layout, sui, stripe_count));
304 
305  io->offset = stripe_unit_offset(layout, sui, unit_size);
306  if (io->offset < *position) /* don't start before position */
307  io->offset = *position;
308  else
309  *position = io->offset;
310 
311  io->length = stripe_unit_offset(layout, sui + 1, unit_size);
312  if (io->length > offset_end) /* don't end past offset_end */
313  io->length = offset_end;
314 
315  if (io->offset >= io->length) /* nothing to do, return success */
316  return PNFS_SUCCESS;
317 
318  io->length -= io->offset;
319 
320  if (is_dense(layout)) {
321  const uint64_t rel_offset = io->offset - layout->pattern_offset;
322  const uint64_t remainder = positive_remainder(rel_offset, unit_size);
323  const uint32_t stride = unit_size * stripe_count;
324 
325  io->offset = (rel_offset / stride) * unit_size + remainder;
326  }
327  return PNFS_PENDING;
328 }
#define abs(i)
Definition: fconv.c:206
__inline uint64_t stripe_unit_offset(IN const pnfs_file_layout *layout, IN uint64_t sui, IN uint32_t unit_size)
Definition: pnfs.h:336
__inline uint32_t stripe_index(IN const pnfs_file_layout *layout, IN uint64_t sui, IN uint32_t stripe_count)
Definition: pnfs.h:347
__inline uint32_t layout_unit_size(IN const pnfs_file_layout *layout)
Definition: pnfs.h:315
__inline uint64_t stripe_unit_number(IN const pnfs_file_layout *layout, IN uint64_t offset, IN uint32_t unit_size)
Definition: pnfs.h:324
double __cdecl remainder(double, double)
GLsizei stride
Definition: glext.h:5848
static DWORD layout
Definition: bitmap.c:46
UINT64 uint64_t
Definition: types.h:77
static __inline uint64_t positive_remainder(IN uint64_t dividend, IN uint32_t divisor)
Definition: pnfs_io.c:282
UINT32 uint32_t
Definition: types.h:75
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK io
Definition: file.c:100
__inline int is_dense(IN const pnfs_file_layout *layout)
Definition: pnfs.h:297

◆ thread_count()

static uint32_t thread_count ( IN pnfs_layout_state state,
IN enum pnfs_iomode  iomode,
IN uint64_t  offset,
IN uint64_t  length 
)
static

Definition at line 137 of file pnfs_io.c.

Referenced by pattern_init(), and test_GetPerformanceInfo().

142 {
143  uint64_t position = offset;
144  struct list_entry *entry;
145  uint32_t count = 0;
146 
147  list_for_each(entry, &state->layouts) {
149 
150  if (!layout_compatible(&layout->layout, iomode, position))
151  continue;
152 
153  position = layout->layout.offset + layout->layout.length;
154  count += layout->device->stripes.count;
155  }
156  return count;
157 }
uint64_t offset
Definition: pnfs.h:166
GLuint GLuint GLsizei count
Definition: gl.h:1545
uint8_t entry
Definition: isohybrid.c:63
GLintptr offset
Definition: glext.h:5920
pnfs_file_device * device
Definition: pnfs.h:181
uint32_t count
Definition: pnfs.h:124
pnfs_stripe_indices stripes
Definition: pnfs.h:141
#define list_for_each(entry, head)
Definition: list.h:36
uint64_t length
Definition: pnfs.h:167
static __inline bool_t layout_compatible(IN const pnfs_layout *layout, IN enum pnfs_iomode iomode, IN uint64_t position)
Definition: pnfs_io.c:125
static int state
Definition: maze.c:121
static DWORD layout
Definition: bitmap.c:46
UINT64 uint64_t
Definition: types.h:77
Definition: list.h:27
UINT32 uint32_t
Definition: types.h:75
pnfs_layout layout
Definition: pnfs.h:178
#define file_layout_entry(pos)
Definition: pnfs_io.c:32

◆ thread_data_server()

static enum pnfs_status thread_data_server ( IN pnfs_io_thread thread,
OUT pnfs_data_server **  server_out 
)
static

Definition at line 355 of file pnfs_io.c.

Referenced by file_layout_read_thread(), and file_layout_write_thread().

358 {
359  pnfs_file_device *device = thread->layout->device;
360  const uint32_t serverid = data_server_index(device, thread->id);
361 
362  if (serverid >= device->servers.count)
364 
365  *server_out = &device->servers.arr[serverid];
366  return PNFS_SUCCESS;
367 }
Definition: devices.h:39
pnfs_data_server_list servers
Definition: pnfs.h:142
pnfs_data_server * arr
Definition: pnfs.h:136
static HANDLE thread
Definition: service.c:33
UINT32 uint32_t
Definition: types.h:75
__inline uint32_t data_server_index(IN const pnfs_file_device *device, IN uint32_t stripeid)
Definition: pnfs.h:358

◆ thread_init()

static enum pnfs_status thread_init ( IN pnfs_io_pattern pattern,
IN pnfs_io_thread thread,
IN pnfs_file_layout layout,
IN uint32_t  stripeid,
IN uint64_t  offset 
)
static

Definition at line 159 of file pnfs_io.c.

Referenced by pattern_threads_init().

165 {
166  thread->pattern = pattern;
167  thread->layout = layout;
168  thread->stable = FILE_SYNC4;
169  thread->offset = offset;
170  thread->id = stripeid;
171 
172  return is_dense(layout) ? get_dense_fh(layout, stripeid, &thread->file)
173  : get_sparse_fh(layout, pattern->meta_file, stripeid, &thread->file);
174 }
static enum pnfs_status get_sparse_fh(IN pnfs_file_layout *layout, IN nfs41_path_fh *meta_file, IN uint32_t stripeid, OUT nfs41_path_fh **file_out)
Definition: pnfs_io.c:78
GLintptr offset
Definition: glext.h:5920
static HANDLE thread
Definition: service.c:33
static DWORD layout
Definition: bitmap.c:46
static enum pnfs_status get_dense_fh(IN pnfs_file_layout *layout, IN uint32_t stripeid, OUT nfs41_path_fh **file_out)
Definition: pnfs_io.c:106
GLubyte * pattern
Definition: glext.h:7787
__inline int is_dense(IN const pnfs_file_layout *layout)
Definition: pnfs.h:297
Definition: fci.c:126

◆ thread_next_unit()

static enum pnfs_status thread_next_unit ( IN pnfs_io_thread thread,
OUT pnfs_io_unit io 
)
static

Definition at line 330 of file pnfs_io.c.

Referenced by file_layout_read_thread(), and file_layout_write_thread().

333 {
334  pnfs_io_pattern *pattern = thread->pattern;
335  pnfs_layout_state *state = pattern->state;
336  enum pnfs_status status;
337 
338  AcquireSRWLockShared(&state->lock);
339 
340  /* stop io if the layout is recalled */
341  status = pnfs_layout_recall_status(state, &thread->layout->layout);
342  if (status)
343  goto out_unlock;
344 
345  status = stripe_next_unit(thread->layout, thread->id,
346  &thread->offset, pattern->offset_end, io);
347  if (status == PNFS_PENDING)
348  io->buffer = pattern->buffer + thread->offset - pattern->offset_start;
349 
350 out_unlock:
351  ReleaseSRWLockShared(&state->lock);
352  return status;
353 }
pnfs_status
Definition: pnfs.h:58
uint64_t offset_start
Definition: pnfs_io.c:41
uint64_t offset_end
Definition: pnfs_io.c:42
static enum pnfs_status stripe_next_unit(IN const pnfs_file_layout *layout, IN uint32_t stripeid, IN uint64_t *position, IN uint64_t offset_end, OUT pnfs_io_unit *io)
Definition: pnfs_io.c:291
unsigned char * buffer
Definition: pnfs_io.c:40
static HANDLE thread
Definition: service.c:33
static int state
Definition: maze.c:121
pnfs_layout_state * state
Definition: pnfs_io.c:39
SRWLOCK lock
Definition: pnfs.h:160
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK io
Definition: file.c:100
static SERVICE_STATUS status
Definition: service.c:31
VOID WINAPI AcquireSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:61
VOID WINAPI ReleaseSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:89
GLubyte * pattern
Definition: glext.h:7787
enum pnfs_status pnfs_layout_recall_status(IN const pnfs_layout_state *state, IN const pnfs_layout *layout)
Definition: pnfs_layout.c:1211