ReactOS  0.4.12-dev-714-gfaac916
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.

◆ IOLVL

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

Definition at line 30 of file pnfs_io.c.

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.

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 */
504  if (status) {
505  eprintf("thread_data_server() failed with %s\n",
507  goto out;
508  }
509  /* find or establish a client for this data server */
511  server, pattern->default_lease, &client);
512  if (status) {
513  eprintf("pnfs_data_server_client() failed with %s\n",
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",
549  return status;
550 }
pnfs_status
Definition: pnfs.h:58
static rfbScreenInfoPtr server
Definition: vnc.c:74
int32_t bool_t
Definition: types.h:101
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
Definition: match.c:390
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
const char * pnfs_error_string(enum pnfs_status status)
Definition: pnfs_debug.c:28
#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
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)
stateid4 stateid
Definition: nfs41_ops.h:284
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
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
Definition: ps.c:97

Referenced by pnfs_read().

◆ file_layout_write_thread()

static uint32_t WINAPI file_layout_write_thread ( void args)
static

Definition at line 552 of file pnfs_io.c.

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 */
570  if (status) {
571  eprintf("thread_data_server() failed with %s\n",
573  goto out;
574  }
575  /* find or establish a client for this data server */
577  server, pattern->default_lease, &client);
578  if (status) {
579  eprintf("pnfs_data_server_client() failed with %s\n",
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 */
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 */
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",
655  return status;
656 }
pnfs_status
Definition: pnfs.h:58
static rfbScreenInfoPtr server
Definition: vnc.c:74
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
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
Definition: match.c:390
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
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
__inline int should_commit_to_mds(IN const pnfs_file_layout *layout)
Definition: pnfs.h:306
#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
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
stateid4 stateid
Definition: nfs41_ops.h:284
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
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
GLubyte * pattern
Definition: glext.h:7787
Definition: ps.c:97

Referenced by pnfs_write().

◆ 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.

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);
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

Referenced by thread_init().

◆ 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.

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);
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

Referenced by thread_init().

◆ 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.

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

Referenced by pnfs_write().

◆ 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.

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

Referenced by pattern_threads_init(), and thread_count().

◆ 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.

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

Referenced by file_layout_read_thread(), and file_layout_write_thread().

◆ 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.

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
GLintptr offset
Definition: glext.h:5920
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
#define NFS4_VERIFIER_SIZE
Definition: nfs41_const.h:30
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
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
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

Referenced by pnfs_write().

◆ 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.

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 }
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
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

Referenced by pnfs_read(), and pnfs_write().

◆ 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.

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) {
408  goto out;
409  }
410 
411  for (i = 0; i < pattern->count; i++) {
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 
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
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
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

Referenced by pnfs_read(), and pnfs_write().

◆ pattern_free()

static void pattern_free ( IN pnfs_io_pattern pattern)
static

Definition at line 274 of file pnfs_io.c.

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

Referenced by pnfs_read(), and pnfs_write().

◆ 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.

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) {
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 */
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
Definition: ps.c:97

Referenced by pnfs_read(), and pnfs_write().

◆ pattern_join()

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

Definition at line 369 of file pnfs_io.c.

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
GLdouble n
Definition: glext.h:7729
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
#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
Definition: ps.c:97

Referenced by pattern_fork().

◆ 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.

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? */
199  if (status != PNFS_PENDING)
200  continue;
201 
202  if (t >= pattern->count) { /* miscounted threads needed? */
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 */
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
uint8_t entry
Definition: isohybrid.c:63
GLintptr offset
Definition: glext.h:5920
GLdouble GLdouble t
Definition: gl.h:2047
#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
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
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

Referenced by pattern_init().

◆ 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 {
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",
693  }
694 
696 
697  if (status)
698  goto out;
699 
702  goto out_free_pattern;
703 
705 
706 out_free_pattern:
708 out:
709  dprintf(IOLVL, "<-- pnfs_read() returning %s\n",
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
Definition: ps.c:97

◆ 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 {
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",
837  }
838 
840 
841  if (status)
842  goto out;
843 
845  /* on layout recall, we still attempt to commit what we wrote */
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:
867 out:
868  dprintf(IOLVL, "<-- pnfs_write() returning %s\n",
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
Definition: ps.c:97

◆ 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.

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

Referenced by stripe_next_unit().

◆ 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.

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

Referenced by pattern_threads_init(), and thread_next_unit().

◆ 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.

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 }
GLuint GLuint GLsizei count
Definition: gl.h:1545
uint8_t entry
Definition: isohybrid.c:63
GLintptr offset
Definition: glext.h:5920
#define list_for_each(entry, head)
Definition: list.h:36
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
#define file_layout_entry(pos)
Definition: pnfs_io.c:32

Referenced by pattern_init(), and test_GetPerformanceInfo().

◆ 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.

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:37
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

Referenced by file_layout_read_thread(), and file_layout_write_thread().

◆ 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.

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

Referenced by pattern_threads_init().

◆ 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.

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
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
static HANDLE thread
Definition: service.c:33
static int state
Definition: maze.c:121
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
Definition: ps.c:97

Referenced by file_layout_read_thread(), and file_layout_write_thread().