ReactOS  0.4.12-dev-18-gf469aca
pnfs_layout.c File Reference
#include <stdio.h>
#include "nfs41_ops.h"
#include "nfs41_callback.h"
#include "util.h"
#include "daemon_debug.h"
Include dependency graph for pnfs_layout.c:

Go to the source code of this file.

Classes

struct  pnfs_layout_list
 
struct  layout_recall
 

Macros

#define FLLVL   2 /* dprintf level for file layout logging */
 
#define state_entry(pos)   list_container(pos, pnfs_layout_state, entry)
 
#define layout_entry(pos)   list_container(pos, pnfs_layout, entry)
 
#define file_layout_entry(pos)   list_container(pos, pnfs_file_layout, layout.entry)
 
#define recall_entry(pos)   list_container(pos, struct layout_recall, layout.entry)
 

Functions

static enum pnfs_status layout_state_create (IN const nfs41_fh *meta_fh, OUT pnfs_layout_state **layout_out)
 
static void file_layout_free (IN pnfs_file_layout *layout)
 
static void layout_state_free_layouts (IN pnfs_layout_state *state)
 
static void layout_state_free_recalls (IN pnfs_layout_state *state)
 
static void layout_state_free (IN pnfs_layout_state *state)
 
static int layout_entry_compare (IN const struct list_entry *entry, IN const void *value)
 
static enum pnfs_status layout_entry_find (IN struct pnfs_layout_list *layouts, IN const nfs41_fh *meta_fh, OUT struct list_entry **entry_out)
 
enum pnfs_status pnfs_layout_list_create (OUT struct pnfs_layout_list **layouts_out)
 
void pnfs_layout_list_free (IN struct pnfs_layout_list *layouts)
 
static enum pnfs_status layout_state_find_or_create (IN struct pnfs_layout_list *layouts, IN const nfs41_fh *meta_fh, OUT pnfs_layout_state **layout_out)
 
static enum pnfs_status layout_state_find_and_delete (IN struct pnfs_layout_list *layouts, IN const nfs41_fh *meta_fh)
 
static uint64_t range_max (IN const pnfs_layout *layout)
 
static bool_t layout_sanity_check (IN pnfs_file_layout *layout)
 
static int layout_filehandles_cmp (IN const pnfs_file_layout_handles *lhs, IN const pnfs_file_layout_handles *rhs)
 
static bool_t layout_merge_segments (IN pnfs_file_layout *to, IN pnfs_file_layout *from)
 
static enum pnfs_status layout_state_merge (IN pnfs_layout_state *state, IN pnfs_file_layout *from)
 
static void layout_ordered_insert (IN pnfs_layout_state *state, IN pnfs_layout *layout)
 
static enum pnfs_status layout_update_range (IN OUT pnfs_layout_state *state, IN const struct list_entry *layouts)
 
static enum pnfs_status layout_update_stateid (IN OUT pnfs_layout_state *state, IN const stateid4 *stateid)
 
static enum pnfs_status layout_update (IN OUT pnfs_layout_state *state, IN const pnfs_layoutget_res_ok *layoutget_res)
 
static enum pnfs_status file_layout_fetch (IN OUT pnfs_layout_state *state, IN nfs41_session *session, IN nfs41_path_fh *meta_file, IN stateid_arg *stateid, IN enum pnfs_iomode iomode, IN uint64_t offset, IN uint64_t minlength, IN uint64_t length)
 
static enum pnfs_status layout_coverage_status (IN pnfs_layout_state *state, IN enum pnfs_iomode iomode, IN uint64_t offset, IN uint64_t length, OUT uint64_t *offset_missing)
 
static enum pnfs_status layout_fetch (IN pnfs_layout_state *state, IN nfs41_session *session, IN nfs41_path_fh *meta_file, IN stateid_arg *stateid, IN enum pnfs_iomode iomode, IN uint64_t offset, IN uint64_t length)
 
static enum pnfs_status device_status (IN pnfs_layout_state *state, IN uint64_t offset, IN uint64_t length, OUT unsigned char *deviceid)
 
static void device_assign (IN pnfs_layout_state *state, IN const unsigned char *deviceid, IN pnfs_file_device *device)
 
static enum pnfs_status device_fetch (IN pnfs_layout_state *state, IN nfs41_session *session, IN unsigned char *deviceid)
 
static enum pnfs_status client_supports_pnfs (IN nfs41_client *client)
 
static enum pnfs_status fs_supports_layout (IN const nfs41_superblock *superblock, IN enum pnfs_layout_type type)
 
static enum pnfs_status open_state_layout_cached (IN nfs41_open_state *state, OUT pnfs_layout_state **layout_out)
 
enum pnfs_status pnfs_layout_state_open (IN nfs41_open_state *state, OUT pnfs_layout_state **layout_out)
 
enum pnfs_status pnfs_layout_state_prepare (IN pnfs_layout_state *state, IN nfs41_session *session, IN nfs41_path_fh *meta_file, IN stateid_arg *stateid, IN enum pnfs_iomode iomode, IN uint64_t offset, IN uint64_t length)
 
static enum pnfs_status layout_return_status (IN const pnfs_layout_state *state)
 
static enum pnfs_status file_layout_return (IN nfs41_session *session, IN nfs41_path_fh *file, IN pnfs_layout_state *state)
 
void pnfs_layout_state_close (IN nfs41_session *session, IN nfs41_open_state *state, IN bool_t remove)
 
static bool_t layout_recall_compatible (IN const pnfs_layout *layout, IN const pnfs_layout *recall)
 
static pnfs_file_layoutlayout_allocate_copy (IN const pnfs_file_layout *existing)
 
static void layout_recall_range (IN pnfs_layout_state *state, IN const pnfs_layout *recall)
 
static void layout_state_deferred_recalls (IN pnfs_layout_state *state)
 
static void layout_recall_entry_init (OUT struct layout_recall *lrc, IN const struct cb_layoutrecall_args *recall)
 
static enum pnfs_status layout_recall_merge (IN struct list_entry *list, IN pnfs_layout *from)
 
static enum pnfs_status file_layout_recall (IN pnfs_layout_state *state, IN const struct cb_layoutrecall_args *recall)
 
static enum pnfs_status file_layout_recall_file (IN nfs41_client *client, IN const struct cb_layoutrecall_args *recall)
 
static bool_t fsid_matches (IN const nfs41_fsid *lhs, IN const nfs41_fsid *rhs)
 
static enum pnfs_status file_layout_recall_fsid (IN nfs41_client *client, IN const struct cb_layoutrecall_args *recall)
 
static enum pnfs_status file_layout_recall_all (IN nfs41_client *client, IN const struct cb_layoutrecall_args *recall)
 
enum pnfs_status pnfs_file_layout_recall (IN nfs41_client *client, IN const struct cb_layoutrecall_args *recall)
 
enum pnfs_status pnfs_layout_recall_status (IN const pnfs_layout_state *state, IN const pnfs_layout *layout)
 
void pnfs_layout_recall_fenced (IN pnfs_layout_state *state, IN const pnfs_layout *layout)
 
void pnfs_layout_io_start (IN pnfs_layout_state *state)
 
void pnfs_layout_io_finished (IN pnfs_layout_state *state)
 

Macro Definition Documentation

◆ file_layout_entry

◆ FLLVL

◆ layout_entry

◆ recall_entry

Definition at line 872 of file pnfs_layout.c.

Referenced by pnfs_layout_recall_status().

◆ state_entry

Function Documentation

◆ client_supports_pnfs()

static enum pnfs_status client_supports_pnfs ( IN nfs41_client client)
static

Definition at line 617 of file pnfs_layout.c.

Referenced by pnfs_layout_state_open().

619 {
620  enum pnfs_status status;
621  AcquireSRWLockShared(&client->exid_lock);
622  status = client->roles & EXCHGID4_FLAG_USE_PNFS_MDS
624  ReleaseSRWLockShared(&client->exid_lock);
625  return status;
626 }
pnfs_status
Definition: pnfs.h:58
static FILE * client
Definition: client.c:41
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

◆ device_assign()

static void device_assign ( IN pnfs_layout_state state,
IN const unsigned char deviceid,
IN pnfs_file_device device 
)
static

Definition at line 575 of file pnfs_layout.c.

Referenced by device_fetch().

579 {
580  struct list_entry *entry;
581  list_for_each(entry, &state->layouts) {
583 
584  /* assign the device to any matching layouts */
585  if (layout->device == NULL &&
586  memcmp(layout->deviceid, deviceid, PNFS_DEVICEID_SIZE) == 0) {
587  layout->device = device;
588 
589  /* XXX: only assign the device to a single segment, because
590  * pnfs_file_device_get() only gives us a single reference */
591  break;
592  }
593  }
594 }
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
uint8_t entry
Definition: isohybrid.c:63
#define PNFS_DEVICEID_SIZE
Definition: pnfs.h:111
pnfs_file_device * device
Definition: pnfs.h:181
unsigned char deviceid[PNFS_DEVICEID_SIZE]
Definition: pnfs.h:180
Definition: devices.h:39
#define list_for_each(entry, head)
Definition: list.h:36
smooth NULL
Definition: ftsmooth.c:416
static int state
Definition: maze.c:121
static DWORD layout
Definition: bitmap.c:46
#define file_layout_entry(pos)
Definition: pnfs_layout.c:41
Definition: list.h:27

◆ device_fetch()

static enum pnfs_status device_fetch ( IN pnfs_layout_state state,
IN nfs41_session session,
IN unsigned char deviceid 
)
static

Definition at line 596 of file pnfs_layout.c.

Referenced by pnfs_layout_state_prepare().

600 {
602  enum pnfs_status status;
603 
604  /* drop the layoutstate lock for the rpc call */
606  status = pnfs_file_device_get(session,
607  session->client->devices, deviceid, &device);
609 
610  if (status == PNFS_SUCCESS)
611  device_assign(state, deviceid, device);
612  return status;
613 }
pnfs_status
Definition: pnfs.h:58
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
enum pnfs_status pnfs_file_device_get(IN struct __nfs41_session *session, IN struct pnfs_file_device_list *devices, IN unsigned char *deviceid, OUT pnfs_file_device **device_out)
Definition: devices.h:39
static void device_assign(IN pnfs_layout_state *state, IN const unsigned char *deviceid, IN pnfs_file_device *device)
Definition: pnfs_layout.c:575
static int state
Definition: maze.c:121
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
static SERVICE_STATUS status
Definition: service.c:31

◆ device_status()

static enum pnfs_status device_status ( IN pnfs_layout_state state,
IN uint64_t  offset,
IN uint64_t  length,
OUT unsigned char deviceid 
)
static

Definition at line 553 of file pnfs_layout.c.

Referenced by pnfs_layout_state_prepare().

558 {
559  struct list_entry *entry;
561 
562  list_for_each(entry, &state->layouts) {
564 
565  if (layout->device == NULL) {
566  /* copy missing deviceid */
567  memcpy(deviceid, layout->deviceid, PNFS_DEVICEID_SIZE);
568  status = PNFS_PENDING;
569  break;
570  }
571  }
572  return status;
573 }
pnfs_status
Definition: pnfs.h:58
uint8_t entry
Definition: isohybrid.c:63
#define PNFS_DEVICEID_SIZE
Definition: pnfs.h:111
pnfs_file_device * device
Definition: pnfs.h:181
unsigned char deviceid[PNFS_DEVICEID_SIZE]
Definition: pnfs.h:180
#define list_for_each(entry, head)
Definition: list.h:36
smooth NULL
Definition: ftsmooth.c:416
static int state
Definition: maze.c:121
static DWORD layout
Definition: bitmap.c:46
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define file_layout_entry(pos)
Definition: pnfs_layout.c:41
Definition: list.h:27
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ file_layout_fetch()

static enum pnfs_status file_layout_fetch ( IN OUT pnfs_layout_state state,
IN nfs41_session session,
IN nfs41_path_fh meta_file,
IN stateid_arg stateid,
IN enum pnfs_iomode  iomode,
IN uint64_t  offset,
IN uint64_t  minlength,
IN uint64_t  length 
)
static

Definition at line 418 of file pnfs_layout.c.

Referenced by layout_fetch().

427 {
428  pnfs_layoutget_res_ok layoutget_res = { 0 };
429  enum pnfs_status pnfsstat = PNFS_SUCCESS;
430  enum nfsstat4 nfsstat;
431 
432  dprintf(FLLVL, "--> file_layout_fetch(%s, seqid=%u)\n",
433  pnfs_iomode_string(iomode), state->stateid.seqid);
434 
435  list_init(&layoutget_res.layouts);
436 
437  /* drop the lock during the rpc call */
439  nfsstat = pnfs_rpc_layoutget(session, meta_file, stateid,
440  iomode, offset, minlength, length, &layoutget_res);
442 
443  if (nfsstat) {
444  dprintf(FLLVL, "pnfs_rpc_layoutget() failed with %s\n",
445  nfs_error_string(nfsstat));
446  pnfsstat = PNFSERR_NOT_SUPPORTED;
447  }
448 
449  switch (nfsstat) {
450  case NFS4_OK:
451  /* use the LAYOUTGET results to update our view of the layout */
452  pnfsstat = layout_update(state, &layoutget_res);
453  break;
454 
455  case NFS4ERR_BADIOMODE:
456  /* don't try RW again */
457  if (iomode == PNFS_IOMODE_RW)
458  state->status |= PNFS_LAYOUT_NOT_RW;
459  break;
460 
463  case NFS4ERR_BADLAYOUT:
464  /* don't try again at all */
465  state->status |= PNFS_LAYOUT_UNAVAILABLE;
466  break;
467  }
468 
469  dprintf(FLLVL, "<-- file_layout_fetch() returning %s\n",
470  pnfs_error_string(pnfsstat));
471  return pnfsstat;
472 }
pnfs_status
Definition: pnfs.h:58
struct list_entry layouts
Definition: nfs41_ops.h:920
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
const char * pnfs_iomode_string(enum pnfs_iomode iomode)
Definition: pnfs_debug.c:58
GLintptr offset
Definition: glext.h:5920
enum nfsstat4 pnfs_rpc_layoutget(IN nfs41_session *session, IN nfs41_path_fh *file, IN stateid_arg *stateid, IN enum pnfs_iomode iomode, IN uint64_t offset, IN uint64_t minlength, IN uint64_t length, OUT pnfs_layoutget_res_ok *layoutget_res_ok)
Definition: nfs41_ops.c:1935
#define dprintf
Definition: regdump.c:33
const char * pnfs_error_string(enum pnfs_status status)
Definition: pnfs_debug.c:28
#define FLLVL
Definition: pnfs_layout.c:30
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
nfsstat4
Definition: nfs41_const.h:86
static int state
Definition: maze.c:121
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149
static enum pnfs_status layout_update(IN OUT pnfs_layout_state *state, IN const pnfs_layoutget_res_ok *layoutget_res)
Definition: pnfs_layout.c:393

◆ file_layout_free()

static void file_layout_free ( IN pnfs_file_layout layout)
static

Definition at line 67 of file pnfs_layout.c.

Referenced by layout_allocate_copy(), layout_recall_range(), layout_state_free_layouts(), layout_state_merge(), and layout_update_range().

69 {
70  if (layout->device) pnfs_file_device_put(layout->device);
71  free(layout->filehandles.arr);
72  free(layout);
73 }
#define free
Definition: debug_ros.c:5
static DWORD layout
Definition: bitmap.c:46
void pnfs_file_device_put(IN pnfs_file_device *device)
Definition: pnfs_device.c:245

◆ file_layout_recall()

static enum pnfs_status file_layout_recall ( IN pnfs_layout_state state,
IN const struct cb_layoutrecall_args recall 
)
static

Definition at line 1032 of file pnfs_layout.c.

Referenced by file_layout_recall_all(), file_layout_recall_file(), and file_layout_recall_fsid().

1035 {
1036  const stateid4 *stateid = &recall->recall.args.file.stateid;
1038 
1039  /* under an exclusive lock, flag the layout as recalled */
1041 
1042  if (state->stateid.seqid == 0) {
1043  /* return NOMATCHINGLAYOUT if it wasn't actually granted */
1044  status = PNFSERR_NO_LAYOUT;
1045  goto out;
1046  }
1047 
1048  if (recall->recall.type == PNFS_RETURN_FILE) {
1049  /* detect races between CB_LAYOUTRECALL and LAYOUTGET/LAYOUTRETURN */
1050  if (stateid->seqid > state->stateid.seqid + 1) {
1051  /* the server has processed an outstanding LAYOUTGET or
1052  * LAYOUTRETURN; we must return ERR_DELAY until we get the
1053  * response and update our view of the layout */
1054  status = PNFS_PENDING;
1055  goto out;
1056  }
1057 
1058  /* save the updated seqid */
1059  state->stateid.seqid = stateid->seqid;
1060  }
1061 
1062  if (state->io_count) {
1063  /* save an entry for this recall, and process it once io finishes */
1064  struct layout_recall *lrc = calloc(1, sizeof(struct layout_recall));
1065  if (lrc == NULL) {
1066  /* on failure to allocate, we'll have to respond
1067  * to the CB_LAYOUTRECALL with NFS4ERR_DELAY */
1068  status = PNFS_PENDING;
1069  goto out;
1070  }
1071  layout_recall_entry_init(lrc, recall);
1072  if (layout_recall_merge(&state->recalls, &lrc->layout) != PNFS_SUCCESS)
1073  list_add_tail(&state->recalls, &lrc->layout.entry);
1074  } else {
1075  /* if there is no pending io, process the recall immediately */
1076  struct layout_recall lrc = { 0 };
1077  layout_recall_entry_init(&lrc, recall);
1079  }
1080 out:
1082  return status;
1083 }
pnfs_status
Definition: pnfs.h:58
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
uint32_t seqid
Definition: nfs41_types.h:144
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
smooth NULL
Definition: ftsmooth.c:416
static enum pnfs_status layout_recall_merge(IN struct list_entry *list, IN pnfs_layout *from)
Definition: pnfs_layout.c:992
static FILE * out
Definition: regtests2xml.c:44
static void layout_recall_range(IN pnfs_layout_state *state, IN const pnfs_layout *recall)
Definition: pnfs_layout.c:916
struct list_entry entry
Definition: pnfs.h:165
static int state
Definition: maze.c:121
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
pnfs_layout layout
Definition: pnfs_layout.c:869
#define calloc
Definition: rosglue.h:14
static void layout_recall_entry_init(OUT struct layout_recall *lrc, IN const struct cb_layoutrecall_args *recall)
Definition: pnfs_layout.c:975
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ file_layout_recall_all()

static enum pnfs_status file_layout_recall_all ( IN nfs41_client client,
IN const struct cb_layoutrecall_args recall 
)
static

Definition at line 1147 of file pnfs_layout.c.

Referenced by pnfs_file_layout_recall().

1150 {
1151  struct list_entry *entry;
1153 
1154  dprintf(FLLVL, "--> file_layout_recall_all()\n");
1155 
1156  EnterCriticalSection(&client->layouts->lock);
1157 
1158  list_for_each(entry, &client->layouts->head)
1159  status = file_layout_recall(state_entry(entry), recall);
1160 
1161  LeaveCriticalSection(&client->layouts->lock);
1162 
1163  /* bulk recalls require invalidation of cached device info */
1165 
1166  dprintf(FLLVL, "<-- file_layout_recall_all() returning %s\n",
1167  pnfs_error_string(status));
1168  return status;
1169 }
pnfs_status
Definition: pnfs.h:58
return
Definition: dirsup.c:529
rwlock_t lock
Definition: tcpcore.h:1163
const char * devices
Definition: diskspace.c:793
uint8_t entry
Definition: isohybrid.c:63
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void pnfs_file_device_list_invalidate(IN struct pnfs_file_device_list *devices)
Definition: pnfs_device.c:159
GLuint n
Definition: s_context.h:57
#define list_for_each(entry, head)
Definition: list.h:36
#define dprintf
Definition: regdump.c:33
const char * pnfs_error_string(enum pnfs_status status)
Definition: pnfs_debug.c:28
#define FLLVL
Definition: pnfs_layout.c:30
static FILE * client
Definition: client.c:41
#define state_entry(pos)
Definition: pnfs_layout.c:39
GLdouble s
Definition: gl.h:2039
static enum pnfs_status file_layout_recall_all(IN nfs41_client *client, IN const struct cb_layoutrecall_args *recall)
Definition: pnfs_layout.c:1147
Definition: list.h:27
static enum pnfs_status file_layout_recall(IN pnfs_layout_state *state, IN const struct cb_layoutrecall_args *recall)
Definition: pnfs_layout.c:1032
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
Definition: ps.c:97

◆ file_layout_recall_file()

static enum pnfs_status file_layout_recall_file ( IN nfs41_client client,
IN const struct cb_layoutrecall_args recall 
)
static

Definition at line 1085 of file pnfs_layout.c.

Referenced by pnfs_file_layout_recall().

1088 {
1089  struct list_entry *entry;
1090  enum pnfs_status status;
1091 
1092  dprintf(FLLVL, "--> file_layout_recall_file()\n");
1093 
1094  EnterCriticalSection(&client->layouts->lock);
1095 
1096  status = layout_entry_find(client->layouts, &recall->recall.args.file.fh, &entry);
1097  if (status == PNFS_SUCCESS)
1098  status = file_layout_recall(state_entry(entry), recall);
1099 
1100  LeaveCriticalSection(&client->layouts->lock);
1101 
1102  dprintf(FLLVL, "<-- file_layout_recall_file() returning %s\n",
1103  pnfs_error_string(status));
1104  return status;
1105 }
pnfs_status
Definition: pnfs.h:58
uint8_t entry
Definition: isohybrid.c:63
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define dprintf
Definition: regdump.c:33
const char * pnfs_error_string(enum pnfs_status status)
Definition: pnfs_debug.c:28
#define FLLVL
Definition: pnfs_layout.c:30
static enum pnfs_status layout_entry_find(IN struct pnfs_layout_list *layouts, IN const nfs41_fh *meta_fh, OUT struct list_entry **entry_out)
Definition: pnfs_layout.c:112
static FILE * client
Definition: client.c:41
#define state_entry(pos)
Definition: pnfs_layout.c:39
Definition: list.h:27
static enum pnfs_status file_layout_recall(IN pnfs_layout_state *state, IN const struct cb_layoutrecall_args *recall)
Definition: pnfs_layout.c:1032
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
static SERVICE_STATUS status
Definition: service.c:31

◆ file_layout_recall_fsid()

static enum pnfs_status file_layout_recall_fsid ( IN nfs41_client client,
IN const struct cb_layoutrecall_args recall 
)
static

Definition at line 1114 of file pnfs_layout.c.

Referenced by pnfs_file_layout_recall().

1117 {
1118  struct list_entry *entry;
1120  nfs41_fh *fh;
1122 
1123  dprintf(FLLVL, "--> file_layout_recall_fsid(%llu, %llu)\n",
1124  recall->recall.args.fsid.major, recall->recall.args.fsid.minor);
1125 
1126  EnterCriticalSection(&client->layouts->lock);
1127 
1128  list_for_each(entry, &client->layouts->head) {
1129  state = state_entry(entry);
1130  /* no locks needed to read layout.meta_fh or superblock.fsid,
1131  * because they are only written once on creation */
1132  fh = &state->meta_fh;
1133  if (fsid_matches(&recall->recall.args.fsid, &fh->superblock->fsid))
1134  status = file_layout_recall(state, recall);
1135  }
1136 
1137  LeaveCriticalSection(&client->layouts->lock);
1138 
1139  /* bulk recalls require invalidation of cached device info */
1141 
1142  dprintf(FLLVL, "<-- file_layout_recall_fsid() returning %s\n",
1143  pnfs_error_string(status));
1144  return status;
1145 }
pnfs_status
Definition: pnfs.h:58
static bool_t fsid_matches(IN const nfs41_fsid *lhs, IN const nfs41_fsid *rhs)
Definition: pnfs_layout.c:1107
struct __nfs41_superblock * superblock
Definition: nfs41_types.h:56
uint8_t entry
Definition: isohybrid.c:63
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void pnfs_file_device_list_invalidate(IN struct pnfs_file_device_list *devices)
Definition: pnfs_device.c:159
#define list_for_each(entry, head)
Definition: list.h:36
#define dprintf
Definition: regdump.c:33
const char * pnfs_error_string(enum pnfs_status status)
Definition: pnfs_debug.c:28
#define FLLVL
Definition: pnfs_layout.c:30
static FILE * client
Definition: client.c:41
#define state_entry(pos)
Definition: pnfs_layout.c:39
static int state
Definition: maze.c:121
nfs41_fh meta_fh
Definition: pnfs.h:150
Definition: list.h:27
static enum pnfs_status file_layout_recall(IN pnfs_layout_state *state, IN const struct cb_layoutrecall_args *recall)
Definition: pnfs_layout.c:1032
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ file_layout_return()

static enum pnfs_status file_layout_return ( IN nfs41_session session,
IN nfs41_path_fh file,
IN pnfs_layout_state state 
)
static

Definition at line 765 of file pnfs_layout.c.

Referenced by pnfs_layout_state_close().

769 {
770  enum pnfs_status status;
771  enum nfsstat4 nfsstat;
772 
773  dprintf(FLLVL, "--> file_layout_return()\n");
774 
775  /* under shared lock, determine whether we need to return the layout */
776  AcquireSRWLockShared(&state->lock);
777  status = layout_return_status(state);
778  ReleaseSRWLockShared(&state->lock);
779 
780  if (status != PNFS_PENDING)
781  goto out;
782 
783  /* under exclusive lock, return the layout and reset status flags */
785 
786  /* wait for any pending LAYOUTGETs/LAYOUTRETURNs */
787  while (state->pending)
788  SleepConditionVariableSRW(&state->cond, &state->lock, INFINITE, 0);
789  state->pending = TRUE;
790 
791  status = layout_return_status(state);
792  if (status == PNFS_PENDING) {
793  pnfs_layoutreturn_res layoutreturn_res = { 0 };
794  stateid4 stateid;
795  memcpy(&stateid, &state->stateid, sizeof(stateid));
796 
797  /* drop the lock during the rpc call */
799  nfsstat = pnfs_rpc_layoutreturn(session, file, PNFS_LAYOUTTYPE_FILE,
800  PNFS_IOMODE_ANY, 0, NFS4_UINT64_MAX, &stateid, &layoutreturn_res);
802 
803  if (nfsstat) {
804  eprintf("pnfs_rpc_layoutreturn() failed with %s\n",
805  nfs_error_string(nfsstat));
806  status = PNFSERR_NO_LAYOUT;
807  } else {
808  status = PNFS_SUCCESS;
809 
810  /* update the layout range held by the client */
812 
813  /* 12.5.3. Layout Stateid: Once a client has no more
814  * layouts on a file, the layout stateid is no longer
815  * valid and MUST NOT be used. */
816  ZeroMemory(&state->stateid, sizeof(stateid4));
817  }
818  }
819 
820  state->pending = FALSE;
823 
824 out:
825  dprintf(FLLVL, "<-- file_layout_return() returning %s\n",
826  pnfs_error_string(status));
827  return status;
828 }
pnfs_status
Definition: pnfs.h:58
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
#define TRUE
Definition: types.h:120
VOID WINAPI WakeConditionVariable(PCONDITION_VARIABLE ConditionVariable)
Definition: sync.c:144
static enum pnfs_status layout_return_status(IN const pnfs_layout_state *state)
Definition: pnfs_layout.c:758
#define ZeroMemory
Definition: winbase.h:1635
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
enum nfsstat4 pnfs_rpc_layoutreturn(IN nfs41_session *session, IN nfs41_path_fh *file, IN enum pnfs_layout_type type, IN enum pnfs_iomode iomode, IN uint64_t offset, IN uint64_t length, IN stateid4 *stateid, OUT pnfs_layoutreturn_res *layoutreturn_res)
Definition: nfs41_ops.c:2062
static void layout_state_free_layouts(IN pnfs_layout_state *state)
Definition: pnfs_layout.c:75
#define dprintf
Definition: regdump.c:33
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
#define FLLVL
Definition: pnfs_layout.c:30
BOOL WINAPI SleepConditionVariableSRW(PCONDITION_VARIABLE ConditionVariable, PSRWLOCK Lock, DWORD Timeout, ULONG Flags)
Definition: sync.c:121
static FILE * out
Definition: regtests2xml.c:44
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
nfsstat4
Definition: nfs41_const.h:86
static int state
Definition: maze.c:121
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define INFINITE
Definition: serial.h:102
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: fci.c:126

◆ fs_supports_layout()

static enum pnfs_status fs_supports_layout ( IN const nfs41_superblock superblock,
IN enum pnfs_layout_type  type 
)
static

Definition at line 628 of file pnfs_layout.c.

Referenced by pnfs_layout_state_open().

631 {
632  const uint32_t flag = 1 << (type - 1);
633  return (superblock->layout_types & flag) == 0
635 }
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint 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 GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean flag
Definition: glfuncs.h:72
UINT32 uint32_t
Definition: types.h:75

◆ fsid_matches()

static bool_t fsid_matches ( IN const nfs41_fsid lhs,
IN const nfs41_fsid rhs 
)
static

Definition at line 1107 of file pnfs_layout.c.

Referenced by file_layout_recall_fsid().

1110 {
1111  return lhs->major == rhs->major && lhs->minor == rhs->minor;
1112 }

◆ layout_allocate_copy()

static pnfs_file_layout* layout_allocate_copy ( IN const pnfs_file_layout existing)
static

Definition at line 885 of file pnfs_layout.c.

Referenced by layout_recall_range().

887 {
888  /* allocate a segment to cover the end of the range */
890  if (layout == NULL)
891  goto out;
892 
893  memcpy(layout, existing, sizeof(pnfs_file_layout));
894 
895  /* XXX: don't use the device from existing layout;
896  * we need to get a reference for ourselves */
897  layout->device = NULL;
898 
899  /* allocate a copy of the filehandle array */
900  layout->filehandles.arr = calloc(layout->filehandles.count,
901  sizeof(nfs41_path_fh));
902  if (layout->filehandles.arr == NULL)
903  goto out_free;
904 
905  memcpy(layout->filehandles.arr, existing->filehandles.arr,
906  layout->filehandles.count * sizeof(nfs41_path_fh));
907 out:
908  return layout;
909 
910 out_free:
911  file_layout_free(layout);
912  layout = NULL;
913  goto out;
914 }
nfs41_path_fh * arr
Definition: pnfs.h:174
pnfs_file_layout_handles filehandles
Definition: pnfs.h:179
pnfs_file_device * device
Definition: pnfs.h:181
static void file_layout_free(IN pnfs_file_layout *layout)
Definition: pnfs_layout.c:67
smooth NULL
Definition: ftsmooth.c:416
static FILE * out
Definition: regtests2xml.c:44
static DWORD layout
Definition: bitmap.c:46
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define calloc
Definition: rosglue.h:14

◆ layout_coverage_status()

static enum pnfs_status layout_coverage_status ( IN pnfs_layout_state state,
IN enum pnfs_iomode  iomode,
IN uint64_t  offset,
IN uint64_t  length,
OUT uint64_t offset_missing 
)
static

Definition at line 477 of file pnfs_layout.c.

Referenced by pnfs_layout_state_prepare().

483 {
484  uint64_t position = offset;
485  struct list_entry *entry;
486 
487  list_for_each(entry, &state->layouts) {
488  /* if the current position intersects with a compatible
489  * layout, move the position to the end of that layout */
490  pnfs_layout *layout = layout_entry(entry);
491  if (layout->iomode >= iomode &&
492  layout->offset <= position &&
493  position < layout->offset + layout->length)
494  position = layout->offset + layout->length;
495  }
496 
497  if (position >= offset + length)
498  return PNFS_SUCCESS;
499 
500  *offset_missing = position;
501  return PNFS_PENDING;
502 }
enum pnfs_iomode iomode
Definition: pnfs.h:168
uint64_t offset
Definition: pnfs.h:166
uint8_t entry
Definition: isohybrid.c:63
GLintptr offset
Definition: glext.h:5920
#define layout_entry(pos)
Definition: pnfs_layout.c:40
#define list_for_each(entry, head)
Definition: list.h:36
uint64_t length
Definition: pnfs.h:167
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
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

◆ layout_entry_compare()

static int layout_entry_compare ( IN const struct list_entry entry,
IN const void value 
)
static

Definition at line 101 of file pnfs_layout.c.

Referenced by layout_entry_find().

104 {
106  const nfs41_fh *meta_fh = (const nfs41_fh*)value;
107  const nfs41_fh *layout_fh = (const nfs41_fh*)&layout->meta_fh;
108  const uint32_t diff = layout_fh->len - meta_fh->len;
109  return diff ? diff : memcmp(layout_fh->fh, meta_fh->fh, meta_fh->len);
110 }
Definition: get.c:139
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
uint8_t entry
Definition: isohybrid.c:63
uint32_t len
Definition: nfs41_types.h:54
#define state_entry(pos)
Definition: pnfs_layout.c:39
static DWORD layout
Definition: bitmap.c:46
nfs41_fh meta_fh
Definition: pnfs.h:150
unsigned char fh[NFS4_FHSIZE]
Definition: nfs41_types.h:53
UINT32 uint32_t
Definition: types.h:75

◆ layout_entry_find()

static enum pnfs_status layout_entry_find ( IN struct pnfs_layout_list layouts,
IN const nfs41_fh meta_fh,
OUT struct list_entry **  entry_out 
)
static

Definition at line 112 of file pnfs_layout.c.

Referenced by file_layout_recall_file(), layout_state_find_and_delete(), and layout_state_find_or_create().

116 {
117  *entry_out = list_search(&layouts->head, meta_fh, layout_entry_compare);
118  return *entry_out ? PNFS_SUCCESS : PNFSERR_NO_LAYOUT;
119 }
static int layout_entry_compare(IN const struct list_entry *entry, IN const void *value)
Definition: pnfs_layout.c:101
static struct list_entry * list_search(const struct list_entry *head, const void *value, list_compare_fn compare)
Definition: list.h:102

◆ layout_fetch()

static enum pnfs_status layout_fetch ( IN pnfs_layout_state state,
IN nfs41_session session,
IN nfs41_path_fh meta_file,
IN stateid_arg stateid,
IN enum pnfs_iomode  iomode,
IN uint64_t  offset,
IN uint64_t  length 
)
static

Definition at line 504 of file pnfs_layout.c.

Referenced by pnfs_layout_state_prepare().

512 {
513  stateid_arg layout_stateid = { 0 };
515 
516  /* check for previous errors from LAYOUTGET */
517  if ((state->status & PNFS_LAYOUT_UNAVAILABLE) ||
518  ((state->status & PNFS_LAYOUT_NOT_RW) && iomode == PNFS_IOMODE_RW)) {
519  status = PNFSERR_NO_LAYOUT;
520  goto out;
521  }
522 
523  /* wait for any pending LAYOUTGETs/LAYOUTRETURNs */
524  while (state->pending)
525  SleepConditionVariableSRW(&state->cond, &state->lock, INFINITE, 0);
526  state->pending = TRUE;
527 
528  /* if there's an existing layout stateid, use it */
529  if (state->stateid.seqid) {
530  memcpy(&layout_stateid.stateid, &state->stateid, sizeof(stateid4));
531  layout_stateid.type = STATEID_LAYOUT;
532  stateid = &layout_stateid;
533  }
534 
535  if ((state->status & PNFS_LAYOUT_NOT_RW) == 0) {
536  /* try to get a RW layout first */
537  status = file_layout_fetch(state, session, meta_file,
539  }
540 
541  if (status && iomode == PNFS_IOMODE_READ) {
542  /* fall back on READ if necessary */
543  status = file_layout_fetch(state, session, meta_file,
544  stateid, iomode, offset, length, NFS4_UINT64_MAX);
545  }
546 
547  state->pending = FALSE;
549 out:
550  return status;
551 }
pnfs_status
Definition: pnfs.h:58
static enum pnfs_status file_layout_fetch(IN OUT pnfs_layout_state *state, IN nfs41_session *session, IN nfs41_path_fh *meta_file, IN stateid_arg *stateid, IN enum pnfs_iomode iomode, IN uint64_t offset, IN uint64_t minlength, IN uint64_t length)
Definition: pnfs_layout.c:418
#define TRUE
Definition: types.h:120
VOID WINAPI WakeConditionVariable(PCONDITION_VARIABLE ConditionVariable)
Definition: sync.c:144
GLintptr offset
Definition: glext.h:5920
static const uint64_t NFS4_UINT64_MAX
Definition: nfs41_types.h:32
BOOL WINAPI SleepConditionVariableSRW(PCONDITION_VARIABLE ConditionVariable, PSRWLOCK Lock, DWORD Timeout, ULONG Flags)
Definition: sync.c:121
enum stateid_type type
Definition: nfs41_ops.h:285
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static FILE * out
Definition: regtests2xml.c:44
static int state
Definition: maze.c:121
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
stateid4 stateid
Definition: nfs41_ops.h:284
#define INFINITE
Definition: serial.h:102
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ layout_filehandles_cmp()

static int layout_filehandles_cmp ( IN const pnfs_file_layout_handles lhs,
IN const pnfs_file_layout_handles rhs 
)
static

Definition at line 242 of file pnfs_layout.c.

Referenced by layout_merge_segments().

245 {
246  const uint32_t diff = rhs->count - lhs->count;
247  return diff ? diff : memcmp(rhs->arr, lhs->arr,
248  rhs->count * sizeof(nfs41_path_fh));
249 }
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
UINT32 uint32_t
Definition: types.h:75

◆ layout_merge_segments()

static bool_t layout_merge_segments ( IN pnfs_file_layout to,
IN pnfs_file_layout from 
)
static

Definition at line 251 of file pnfs_layout.c.

Referenced by layout_state_merge().

254 {
255  const uint64_t to_max = range_max(&to->layout);
256  const uint64_t from_max = range_max(&from->layout);
257 
258  /* cannot merge a segment with itself */
259  if (to == from)
260  return FALSE;
261 
262  /* the ranges must meet or overlap */
263  if (to_max < from->layout.offset || from_max < to->layout.offset)
264  return FALSE;
265 
266  /* the following fields must match: */
267  if (to->layout.iomode != from->layout.iomode ||
268  to->layout.type != from->layout.type ||
269  layout_filehandles_cmp(&to->filehandles, &from->filehandles) != 0 ||
270  memcmp(to->deviceid, from->deviceid, PNFS_DEVICEID_SIZE) != 0 ||
271  to->pattern_offset != from->pattern_offset ||
272  to->first_index != from->first_index ||
273  to->util != from->util)
274  return FALSE;
275 
276  dprintf(FLLVL, "merging layout range {%llu, %llu} with {%llu, %llu}\n",
277  to->layout.offset, to->layout.length,
278  from->layout.offset, from->layout.length);
279 
280  /* calculate the union of the two ranges */
281  to->layout.offset = min(to->layout.offset, from->layout.offset);
282  to->layout.length = max(to_max, from_max) - to->layout.offset;
283  return TRUE;
284 }
#define max(a, b)
Definition: svc.c:63
#define TRUE
Definition: types.h:120
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define PNFS_DEVICEID_SIZE
Definition: pnfs.h:111
#define dprintf
Definition: regdump.c:33
static int layout_filehandles_cmp(IN const pnfs_file_layout_handles *lhs, IN const pnfs_file_layout_handles *rhs)
Definition: pnfs_layout.c:242
#define FLLVL
Definition: pnfs_layout.c:30
static DWORD layout
Definition: bitmap.c:46
static uint64_t range_max(IN const pnfs_layout *layout)
Definition: pnfs_layout.c:220
UINT64 uint64_t
Definition: types.h:77
#define min(a, b)
Definition: monoChain.cc:55
CardRegion * from
Definition: spigame.cpp:19

◆ layout_ordered_insert()

static void layout_ordered_insert ( IN pnfs_layout_state state,
IN pnfs_layout layout 
)
static

Definition at line 317 of file pnfs_layout.c.

Referenced by layout_recall_range(), and layout_update_range().

320 {
321  struct list_entry *entry;
322  list_for_each(entry, &state->layouts) {
323  pnfs_layout *existing = layout_entry(entry);
324 
325  /* maintain an order of increasing offset */
326  if (existing->offset < layout->offset)
327  continue;
328 
329  /* when offsets are equal, prefer a longer segment first */
330  if (existing->offset == layout->offset &&
331  existing->length > layout->length)
332  continue;
333 
334  list_add(&layout->entry, existing->entry.prev, &existing->entry);
335  return;
336  }
337 
338  list_add_tail(&state->layouts, &layout->entry);
339 }
static void list_add(struct list_entry *entry, struct list_entry *prev, struct list_entry *next)
Definition: list.h:64
uint64_t offset
Definition: pnfs.h:166
uint8_t entry
Definition: isohybrid.c:63
#define layout_entry(pos)
Definition: pnfs_layout.c:40
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
#define list_for_each(entry, head)
Definition: list.h:36
uint64_t length
Definition: pnfs.h:167
struct list_entry entry
Definition: pnfs.h:165
static int state
Definition: maze.c:121
static DWORD layout
Definition: bitmap.c:46
Definition: list.h:27

◆ layout_recall_compatible()

static bool_t layout_recall_compatible ( IN const pnfs_layout layout,
IN const pnfs_layout recall 
)
static

Definition at line 874 of file pnfs_layout.c.

Referenced by layout_recall_range(), and pnfs_layout_recall_status().

877 {
878  return layout->type == recall->type
879  && layout->offset <= (recall->offset + recall->length)
880  && recall->offset <= (layout->offset + layout->length)
881  && (recall->iomode == PNFS_IOMODE_ANY ||
882  layout->iomode == recall->iomode);
883 }
static DWORD layout
Definition: bitmap.c:46

◆ layout_recall_entry_init()

static void layout_recall_entry_init ( OUT struct layout_recall lrc,
IN const struct cb_layoutrecall_args recall 
)
static

Definition at line 975 of file pnfs_layout.c.

Referenced by file_layout_recall().

978 {
979  list_init(&lrc->layout.entry);
980  if (recall->recall.type == PNFS_RETURN_FILE) {
981  lrc->layout.offset = recall->recall.args.file.offset;
982  lrc->layout.length = recall->recall.args.file.length;
983  } else {
984  lrc->layout.offset = 0;
985  lrc->layout.length = NFS4_UINT64_MAX;
986  }
987  lrc->layout.iomode = recall->iomode;
988  lrc->layout.type = PNFS_LAYOUTTYPE_FILE;
989  lrc->changed = recall->changed;
990 }
static const uint64_t NFS4_UINT64_MAX
Definition: nfs41_types.h:32
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149

◆ layout_recall_merge()

static enum pnfs_status layout_recall_merge ( IN struct list_entry list,
IN pnfs_layout from 
)
static

Definition at line 992 of file pnfs_layout.c.

Referenced by file_layout_recall(), and pnfs_layout_recall_fenced().

995 {
996  struct list_entry *entry, *tmp;
998 
999  /* attempt to merge the new recall with each existing recall */
1000  list_for_each_tmp(entry, tmp, list) {
1001  pnfs_layout *to = layout_entry(entry);
1002  const uint64_t to_max = to->offset + to->length;
1003  const uint64_t from_max = from->offset + from->length;
1004 
1005  /* the ranges must meet or overlap */
1006  if (to_max < from->offset || from_max < to->offset)
1007  continue;
1008 
1009  /* the following fields must match: */
1010  if (to->iomode != from->iomode || to->type != from->type)
1011  continue;
1012 
1013  dprintf(FLLVL, "merging recalled range {%llu, %llu} with {%llu, %llu}\n",
1014  to->offset, to->length, from->offset, from->length);
1015 
1016  /* calculate the union of the two ranges */
1017  to->offset = min(to->offset, from->offset);
1018  to->length = max(to_max, from_max) - to->offset;
1019 
1020  /* on success, remove/free the new segment */
1021  list_remove(&from->entry);
1022  free(from);
1023  status = PNFS_SUCCESS;
1024 
1025  /* because the existing segment 'to' has grown, we may
1026  * be able to merge it with later segments */
1027  from = to;
1028  }
1029  return status;
1030 }
pnfs_status
Definition: pnfs.h:58
enum pnfs_layout_type type
Definition: pnfs.h:169
#define max(a, b)
Definition: svc.c:63
enum pnfs_iomode iomode
Definition: pnfs.h:168
uint64_t offset
Definition: pnfs.h:166
#define free
Definition: debug_ros.c:5
uint8_t entry
Definition: isohybrid.c:63
GLintptr offset
Definition: glext.h:5920
#define layout_entry(pos)
Definition: pnfs_layout.c:40
#define dprintf
Definition: regdump.c:33
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
uint64_t length
Definition: pnfs.h:167
#define FLLVL
Definition: pnfs_layout.c:30
Definition: _list.h:228
UINT64 uint64_t
Definition: types.h:77
#define min(a, b)
Definition: monoChain.cc:55
Definition: list.h:27
#define list_for_each_tmp(entry, tmp, head)
Definition: list.h:39
CardRegion * from
Definition: spigame.cpp:19
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ layout_recall_range()

static void layout_recall_range ( IN pnfs_layout_state state,
IN const pnfs_layout recall 
)
static

Definition at line 916 of file pnfs_layout.c.

Referenced by file_layout_recall(), and layout_state_deferred_recalls().

919 {
920  struct list_entry *entry, *tmp;
921  list_for_each_tmp(entry, tmp, &state->layouts) {
923  const uint64_t layout_end = layout->layout.offset + layout->layout.length;
924 
925  if (!layout_recall_compatible(&layout->layout, recall))
926  continue;
927 
928  if (recall->offset > layout->layout.offset) {
929  /* segment starts before recall; shrink length */
930  layout->layout.length = recall->offset - layout->layout.offset;
931 
932  if (layout_end > recall->offset + recall->length) {
933  /* middle chunk of the segment is recalled;
934  * allocate a new segment to cover the end */
936  if (remainder == NULL) {
937  /* silently ignore allocation errors here. behave
938  * as if we 'forgot' this last segment */
939  } else {
940  layout->layout.offset = recall->offset + recall->length;
941  layout->layout.length = layout_end - layout->layout.offset;
942  layout_ordered_insert(state, &remainder->layout);
943  }
944  }
945  } else {
946  /* segment starts after recall */
947  if (layout_end <= recall->offset + recall->length) {
948  /* entire segment is recalled */
949  list_remove(&layout->layout.entry);
950  file_layout_free(layout);
951  } else {
952  /* beginning of segment is recalled; shrink offset/length */
953  layout->layout.offset = recall->offset + recall->length;
954  layout->layout.length = layout_end - layout->layout.offset;
955  }
956  }
957  }
958 }
uint64_t offset
Definition: pnfs.h:166
uint8_t entry
Definition: isohybrid.c:63
GLintptr offset
Definition: glext.h:5920
static void file_layout_free(IN pnfs_file_layout *layout)
Definition: pnfs_layout.c:67
smooth NULL
Definition: ftsmooth.c:416
double __cdecl remainder(double, double)
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
uint64_t length
Definition: pnfs.h:167
static void layout_ordered_insert(IN pnfs_layout_state *state, IN pnfs_layout *layout)
Definition: pnfs_layout.c:317
static pnfs_file_layout * layout_allocate_copy(IN const pnfs_file_layout *existing)
Definition: pnfs_layout.c:885
struct list_entry entry
Definition: pnfs.h:165
static int state
Definition: maze.c:121
static DWORD layout
Definition: bitmap.c:46
static bool_t layout_recall_compatible(IN const pnfs_layout *layout, IN const pnfs_layout *recall)
Definition: pnfs_layout.c:874
UINT64 uint64_t
Definition: types.h:77
#define file_layout_entry(pos)
Definition: pnfs_layout.c:41
Definition: list.h:27
pnfs_layout layout
Definition: pnfs.h:178
#define list_for_each_tmp(entry, tmp, head)
Definition: list.h:39

◆ layout_return_status()

static enum pnfs_status layout_return_status ( IN const pnfs_layout_state state)
static

Definition at line 758 of file pnfs_layout.c.

Referenced by file_layout_return().

760 {
761  /* return the layout if we have a stateid */
762  return state->stateid.seqid ? PNFS_SUCCESS : PNFS_PENDING;
763 }
static int state
Definition: maze.c:121

◆ layout_sanity_check()

static bool_t layout_sanity_check ( IN pnfs_file_layout layout)
static

Definition at line 227 of file pnfs_layout.c.

Referenced by layout_update_range().

229 {
230  /* prevent div/0 */
231  if (layout->layout.length == 0 ||
232  layout->layout.iomode < PNFS_IOMODE_READ ||
233  layout->layout.iomode > PNFS_IOMODE_RW ||
234  layout_unit_size(layout) == 0)
235  return FALSE;
236 
237  /* put a cap on layout.length to prevent overflow */
238  layout->layout.length = range_max(&layout->layout) - layout->layout.offset;
239  return TRUE;
240 }
#define TRUE
Definition: types.h:120
__inline uint32_t layout_unit_size(IN const pnfs_file_layout *layout)
Definition: pnfs.h:315
static DWORD layout
Definition: bitmap.c:46
static uint64_t range_max(IN const pnfs_layout *layout)
Definition: pnfs_layout.c:220

◆ layout_state_create()

static enum pnfs_status layout_state_create ( IN const nfs41_fh meta_fh,
OUT pnfs_layout_state **  layout_out 
)
static

Definition at line 43 of file pnfs_layout.c.

Referenced by layout_state_find_or_create().

46 {
49 
50  layout = calloc(1, sizeof(pnfs_layout_state));
51  if (layout == NULL) {
52  status = PNFSERR_RESOURCES;
53  goto out;
54  }
55 
56  fh_copy(&layout->meta_fh, meta_fh);
57  list_init(&layout->layouts);
58  list_init(&layout->recalls);
59  InitializeSRWLock(&layout->lock);
61 
62  *layout_out = layout;
63 out:
64  return status;
65 }
pnfs_status
Definition: pnfs.h:58
CONDITION_VARIABLE cond
Definition: pnfs.h:161
struct list_entry recalls
Definition: pnfs.h:154
smooth NULL
Definition: ftsmooth.c:416
static FILE * out
Definition: regtests2xml.c:44
void fh_copy(OUT nfs41_fh *dst, IN const nfs41_fh *src)
Definition: util.c:354
static DWORD layout
Definition: bitmap.c:46
nfs41_fh meta_fh
Definition: pnfs.h:150
VOID WINAPI InitializeSRWLock(PSRWLOCK Lock)
Definition: sync.c:75
VOID WINAPI InitializeConditionVariable(PCONDITION_VARIABLE ConditionVariable)
Definition: sync.c:68
#define calloc
Definition: rosglue.h:14
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149
SRWLOCK lock
Definition: pnfs.h:160
static SERVICE_STATUS status
Definition: service.c:31
struct list_entry layouts
Definition: pnfs.h:153
Definition: ps.c:97

◆ layout_state_deferred_recalls()

static void layout_state_deferred_recalls ( IN pnfs_layout_state state)
static

Definition at line 960 of file pnfs_layout.c.

Referenced by pnfs_layout_io_finished().

962 {
963  struct list_entry *entry, *tmp;
964  list_for_each_tmp(entry, tmp, &state->recalls) {
965  /* process each deferred layout recall */
966  pnfs_layout *recall = layout_entry(entry);
967  layout_recall_range(state, recall);
968 
969  /* remove/free the recall entry */
970  list_remove(&recall->entry);
971  free(recall);
972  }
973 }
#define free
Definition: debug_ros.c:5
uint8_t entry
Definition: isohybrid.c:63
#define layout_entry(pos)
Definition: pnfs_layout.c:40
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
static void layout_recall_range(IN pnfs_layout_state *state, IN const pnfs_layout *recall)
Definition: pnfs_layout.c:916
struct list_entry entry
Definition: pnfs.h:165
static int state
Definition: maze.c:121
Definition: list.h:27
#define list_for_each_tmp(entry, tmp, head)
Definition: list.h:39

◆ layout_state_find_and_delete()

static enum pnfs_status layout_state_find_and_delete ( IN struct pnfs_layout_list layouts,
IN const nfs41_fh meta_fh 
)
static

Definition at line 194 of file pnfs_layout.c.

Referenced by pnfs_layout_state_close().

197 {
198  struct list_entry *entry;
199  enum pnfs_status status;
200 
201  dprintf(FLLVL, "--> layout_state_find_and_delete()\n");
202 
203  EnterCriticalSection(&layouts->lock);
204 
205  status = layout_entry_find(layouts, meta_fh, &entry);
206  if (status == PNFS_SUCCESS) {
207  list_remove(entry);
209  }
210 
211  LeaveCriticalSection(&layouts->lock);
212 
213  dprintf(FLLVL, "<-- layout_state_find_and_delete() "
214  "returning %s\n", pnfs_error_string(status));
215  return status;
216 }
pnfs_status
Definition: pnfs.h:58
uint8_t entry
Definition: isohybrid.c:63
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define dprintf
Definition: regdump.c:33
const char * pnfs_error_string(enum pnfs_status status)
Definition: pnfs_debug.c:28
static void layout_state_free(IN pnfs_layout_state *state)
Definition: pnfs_layout.c:93
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
#define FLLVL
Definition: pnfs_layout.c:30
static enum pnfs_status layout_entry_find(IN struct pnfs_layout_list *layouts, IN const nfs41_fh *meta_fh, OUT struct list_entry **entry_out)
Definition: pnfs_layout.c:112
#define state_entry(pos)
Definition: pnfs_layout.c:39
Definition: list.h:27
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
static SERVICE_STATUS status
Definition: service.c:31

◆ layout_state_find_or_create()

static enum pnfs_status layout_state_find_or_create ( IN struct pnfs_layout_list layouts,
IN const nfs41_fh meta_fh,
OUT pnfs_layout_state **  layout_out 
)
static

Definition at line 154 of file pnfs_layout.c.

Referenced by pnfs_layout_state_open().

158 {
159  struct list_entry *entry;
160  enum pnfs_status status;
161 
162  dprintf(FLLVL, "--> layout_state_find_or_create()\n");
163 
164  EnterCriticalSection(&layouts->lock);
165 
166  /* search for an existing layout */
167  status = layout_entry_find(layouts, meta_fh, &entry);
168  if (status) {
169  /* create a new layout */
171  status = layout_state_create(meta_fh, &layout);
172  if (status == PNFS_SUCCESS) {
173  /* add it to the list */
174  list_add_head(&layouts->head, &layout->entry);
175  *layout_out = layout;
176 
177  dprintf(FLLVL, "<-- layout_state_find_or_create() "
178  "returning new layout %p\n", layout);
179  } else {
180  dprintf(FLLVL, "<-- layout_state_find_or_create() "
181  "returning %s\n", pnfs_error_string(status));
182  }
183  } else {
184  *layout_out = state_entry(entry);
185 
186  dprintf(FLLVL, "<-- layout_state_find_or_create() "
187  "returning existing layout %p\n", *layout_out);
188  }
189 
190  LeaveCriticalSection(&layouts->lock);
191  return status;
192 }
pnfs_status
Definition: pnfs.h:58
uint8_t entry
Definition: isohybrid.c:63
__WINE_SERVER_LIST_INLINE void list_add_head(struct list *list, struct list *elem)
Definition: list.h:96
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
struct list_entry entry
Definition: pnfs.h:152
#define dprintf
Definition: regdump.c:33
const char * pnfs_error_string(enum pnfs_status status)
Definition: pnfs_debug.c:28
static enum pnfs_status layout_state_create(IN const nfs41_fh *meta_fh, OUT pnfs_layout_state **layout_out)
Definition: pnfs_layout.c:43
#define FLLVL
Definition: pnfs_layout.c:30
static enum pnfs_status layout_entry_find(IN struct pnfs_layout_list *layouts, IN const nfs41_fh *meta_fh, OUT struct list_entry **entry_out)
Definition: pnfs_layout.c:112
#define state_entry(pos)
Definition: pnfs_layout.c:39
static DWORD layout
Definition: bitmap.c:46
Definition: list.h:27
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
static SERVICE_STATUS status
Definition: service.c:31

◆ layout_state_free()

static void layout_state_free ( IN pnfs_layout_state state)
static

Definition at line 93 of file pnfs_layout.c.

Referenced by layout_state_find_and_delete(), and pnfs_layout_list_free().

95 {
98  free(state);
99 }
#define free
Definition: debug_ros.c:5
static void layout_state_free_layouts(IN pnfs_layout_state *state)
Definition: pnfs_layout.c:75
static int state
Definition: maze.c:121
static void layout_state_free_recalls(IN pnfs_layout_state *state)
Definition: pnfs_layout.c:84

◆ layout_state_free_layouts()

static void layout_state_free_layouts ( IN pnfs_layout_state state)
static

Definition at line 75 of file pnfs_layout.c.

Referenced by file_layout_return(), and layout_state_free().

77 {
78  struct list_entry *entry, *tmp;
79  list_for_each_tmp(entry, tmp, &state->layouts)
81  list_init(&state->layouts);
82 }
uint8_t entry
Definition: isohybrid.c:63
static void file_layout_free(IN pnfs_file_layout *layout)
Definition: pnfs_layout.c:67
static int state
Definition: maze.c:121
#define file_layout_entry(pos)
Definition: pnfs_layout.c:41
Definition: list.h:27
#define list_for_each_tmp(entry, tmp, head)
Definition: list.h:39
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149

◆ layout_state_free_recalls()

static void layout_state_free_recalls ( IN pnfs_layout_state state)
static

Definition at line 84 of file pnfs_layout.c.

Referenced by layout_state_free().

86 {
87  struct list_entry *entry, *tmp;
88  list_for_each_tmp(entry, tmp, &state->recalls)
89  free(layout_entry(entry));
90  list_init(&state->recalls);
91 }
#define free
Definition: debug_ros.c:5
uint8_t entry
Definition: isohybrid.c:63
#define layout_entry(pos)
Definition: pnfs_layout.c:40
static int state
Definition: maze.c:121
Definition: list.h:27
#define list_for_each_tmp(entry, tmp, head)
Definition: list.h:39
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149

◆ layout_state_merge()

static enum pnfs_status layout_state_merge ( IN pnfs_layout_state state,
IN pnfs_file_layout from 
)
static

Definition at line 286 of file pnfs_layout.c.

Referenced by layout_update_range(), and pnfs_layout_io_finished().

289 {
290  struct list_entry *entry, *tmp;
291  pnfs_file_layout *to;
293 
294  /* attempt to merge the new segment with each existing segment */
295  list_for_each_tmp(entry, tmp, &state->layouts) {
296  to = file_layout_entry(entry);
297  if (!layout_merge_segments(to, from))
298  continue;
299 
300  /* on success, remove/free the new segment */
301  list_remove(&from->layout.entry);
303  status = PNFS_SUCCESS;
304 
305  /* because the existing segment 'to' has grown, we may
306  * be able to merge it with later segments */
307  from = to;
308 
309  /* but if there could be io threads referencing this segment,
310  * we can't free it until io is finished */
311  if (state->io_count)
312  break;
313  }
314  return status;
315 }
pnfs_status
Definition: pnfs.h:58
uint8_t entry
Definition: isohybrid.c:63
static bool_t layout_merge_segments(IN pnfs_file_layout *to, IN pnfs_file_layout *from)
Definition: pnfs_layout.c:251
static void file_layout_free(IN pnfs_file_layout *layout)
Definition: pnfs_layout.c:67
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
static int state
Definition: maze.c:121
#define file_layout_entry(pos)
Definition: pnfs_layout.c:41
Definition: list.h:27
#define list_for_each_tmp(entry, tmp, head)
Definition: list.h:39
CardRegion * from
Definition: spigame.cpp:19
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ layout_update()

static enum pnfs_status layout_update ( IN OUT pnfs_layout_state state,
IN const pnfs_layoutget_res_ok layoutget_res 
)
static

Definition at line 393 of file pnfs_layout.c.

Referenced by file_layout_fetch().

396 {
397  enum pnfs_status status;
398 
399  /* update the layout ranges held by the client */
400  status = layout_update_range(state, &layoutget_res->layouts);
401  if (status) {
402  eprintf("LAYOUTGET didn't return any file layouts\n");
403  goto out;
404  }
405  /* update the layout stateid */
406  status = layout_update_stateid(state, &layoutget_res->stateid);
407  if (status) {
408  eprintf("LAYOUTGET returned a new stateid when we already had one\n");
409  goto out;
410  }
411  /* if a previous LAYOUTGET set return_on_close, don't overwrite it */
412  if (!state->return_on_close)
413  state->return_on_close = layoutget_res->return_on_close;
414 out:
415  return status;
416 }
pnfs_status
Definition: pnfs.h:58
static enum pnfs_status layout_update_range(IN OUT pnfs_layout_state *state, IN const struct list_entry *layouts)
Definition: pnfs_layout.c:341
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
static FILE * out
Definition: regtests2xml.c:44
static int state
Definition: maze.c:121
static SERVICE_STATUS status
Definition: service.c:31
static enum pnfs_status layout_update_stateid(IN OUT pnfs_layout_state *state, IN const stateid4 *stateid)
Definition: pnfs_layout.c:374

◆ layout_update_range()

static enum pnfs_status layout_update_range ( IN OUT pnfs_layout_state state,
IN const struct list_entry layouts 
)
static

Definition at line 341 of file pnfs_layout.c.

Referenced by layout_update().

344 {
345  struct list_entry *entry, *tmp;
348 
349  list_for_each_tmp(entry, tmp, layouts) {
350  layout = file_layout_entry(entry);
351 
352  /* don't know what to do with non-file layouts */
353  if (layout->layout.type != PNFS_LAYOUTTYPE_FILE)
354  continue;
355 
356  if (!layout_sanity_check(layout)) {
357  file_layout_free(layout);
358  continue;
359  }
360 
361  /* attempt to merge the range with existing segments */
362  status = layout_state_merge(state, layout);
363  if (status) {
364  dprintf(FLLVL, "saving new layout:\n");
365  dprint_layout(FLLVL, layout);
366 
368  status = PNFS_SUCCESS;
369  }
370  }
371  return status;
372 }
pnfs_status
Definition: pnfs.h:58
enum pnfs_layout_type type
Definition: pnfs.h:169
uint8_t entry
Definition: isohybrid.c:63
static enum pnfs_status layout_state_merge(IN pnfs_layout_state *state, IN pnfs_file_layout *from)
Definition: pnfs_layout.c:286
void dprint_layout(int level, const struct __pnfs_file_layout *layout)
#define dprintf
Definition: regdump.c:33
static void file_layout_free(IN pnfs_file_layout *layout)
Definition: pnfs_layout.c:67
#define FLLVL
Definition: pnfs_layout.c:30
static void layout_ordered_insert(IN pnfs_layout_state *state, IN pnfs_layout *layout)
Definition: pnfs_layout.c:317
static int state
Definition: maze.c:121
static DWORD layout
Definition: bitmap.c:46
static bool_t layout_sanity_check(IN pnfs_file_layout *layout)
Definition: pnfs_layout.c:227
#define file_layout_entry(pos)
Definition: pnfs_layout.c:41
Definition: list.h:27
pnfs_layout layout
Definition: pnfs.h:178
#define list_for_each_tmp(entry, tmp, head)
Definition: list.h:39
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ layout_update_stateid()

static enum pnfs_status layout_update_stateid ( IN OUT pnfs_layout_state state,
IN const stateid4 stateid 
)
static

Definition at line 374 of file pnfs_layout.c.

Referenced by layout_update().

377 {
379 
380  if (state->stateid.seqid == 0) {
381  /* save a new layout stateid */
382  memcpy(&state->stateid, stateid, sizeof(stateid4));
383  } else if (memcmp(&state->stateid.other, stateid->other,
384  NFS4_STATEID_OTHER) == 0) {
385  /* update an existing layout stateid */
386  state->stateid.seqid = stateid->seqid;
387  } else {
388  status = PNFSERR_NO_LAYOUT;
389  }
390  return status;
391 }
pnfs_status
Definition: pnfs.h:58
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define NFS4_STATEID_OTHER
Definition: nfs41_const.h:33
static int state
Definition: maze.c:121
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ open_state_layout_cached()

static enum pnfs_status open_state_layout_cached ( IN nfs41_open_state state,
OUT pnfs_layout_state **  layout_out 
)
static

Definition at line 637 of file pnfs_layout.c.

Referenced by pnfs_layout_state_open().

640 {
642 
643  if (state->layout) {
644  status = PNFS_SUCCESS;
645  *layout_out = state->layout;
646 
647  dprintf(FLLVL, "pnfs_open_state_layout() found "
648  "cached layout %p\n", *layout_out);
649  }
650  return status;
651 }
pnfs_status
Definition: pnfs.h:58
#define dprintf
Definition: regdump.c:33
#define FLLVL
Definition: pnfs_layout.c:30
static int state
Definition: maze.c:121
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ pnfs_file_layout_recall()

enum pnfs_status pnfs_file_layout_recall ( IN nfs41_client client,
IN const struct cb_layoutrecall_args recall 
)

Definition at line 1171 of file pnfs_layout.c.

1174 {
1176 
1177  dprintf(FLLVL, "--> pnfs_file_layout_recall(%u, %s, %u)\n",
1178  recall->recall.type, pnfs_iomode_string(recall->iomode),
1179  recall->changed);
1180 
1181  if (recall->type != PNFS_LAYOUTTYPE_FILE) {
1182  dprintf(FLLVL, "invalid layout type %u (%s)!\n",
1183  recall->type, pnfs_layout_type_string(recall->type));
1184  status = PNFSERR_NOT_SUPPORTED;
1185  goto out;
1186  }
1187 
1188  switch (recall->recall.type) {
1189  case PNFS_RETURN_FILE:
1190  status = file_layout_recall_file(client, recall);
1191  break;
1192  case PNFS_RETURN_FSID:
1193  status = file_layout_recall_fsid(client, recall);
1194  break;
1195  case PNFS_RETURN_ALL:
1196  status = file_layout_recall_all(client, recall);
1197  break;
1198 
1199  default:
1200  dprintf(FLLVL, "invalid return type %u!\n", recall->recall);
1201  status = PNFSERR_NOT_SUPPORTED;
1202  goto out;
1203  }
1204 out:
1205  dprintf(FLLVL, "<-- pnfs_file_layout_recall() returning %s\n",
1206  pnfs_error_string(status));
1207  return status;
1208 }
pnfs_status
Definition: pnfs.h:58
const char * pnfs_iomode_string(enum pnfs_iomode iomode)
Definition: pnfs_debug.c:58
static enum pnfs_status file_layout_recall_fsid(IN nfs41_client *client, IN const struct cb_layoutrecall_args *recall)
Definition: pnfs_layout.c:1114
#define dprintf
Definition: regdump.c:33
const char * pnfs_layout_type_string(enum pnfs_layout_type type)
Definition: pnfs_debug.c:48
const char * pnfs_error_string(enum pnfs_status status)
Definition: pnfs_debug.c:28
static enum pnfs_status file_layout_recall_file(IN nfs41_client *client, IN const struct cb_layoutrecall_args *recall)
Definition: pnfs_layout.c:1085
#define FLLVL
Definition: pnfs_layout.c:30
static FILE * client
Definition: client.c:41
static FILE * out
Definition: regtests2xml.c:44
static enum pnfs_status file_layout_recall_all(IN nfs41_client *client, IN const struct cb_layoutrecall_args *recall)
Definition: pnfs_layout.c:1147
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ pnfs_layout_io_finished()

void pnfs_layout_io_finished ( IN pnfs_layout_state state)

Definition at line 1267 of file pnfs_layout.c.

Referenced by pattern_free().

1269 {
1271 
1272  /* return the reference to signify that an io request is finished */
1273  state->io_count--;
1274  dprintf(FLLVL, "pnfs_layout_io_finished() count -> %u\n",
1275  state->io_count);
1276 
1277  if (state->io_count > 0) /* more io pending */
1278  goto out_unlock;
1279 
1280  /* once all io is finished, process any layout recalls */
1282 
1283  /* finish any segment merging that was delayed during io */
1284  if (!list_empty(&state->layouts))
1286 
1287 out_unlock:
1289 }
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
static enum pnfs_status layout_state_merge(IN pnfs_layout_state *state, IN pnfs_file_layout *from)
Definition: pnfs_layout.c:286
#define dprintf
Definition: regdump.c:33
#define FLLVL
Definition: pnfs_layout.c:30
static void layout_state_deferred_recalls(IN pnfs_layout_state *state)
Definition: pnfs_layout.c:960
static int state
Definition: maze.c:121
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
__WINE_SERVER_LIST_INLINE int list_empty(const struct list *list)
Definition: list.h:143
#define file_layout_entry(pos)
Definition: pnfs_layout.c:41

◆ pnfs_layout_io_start()

void pnfs_layout_io_start ( IN pnfs_layout_state state)

Definition at line 1257 of file pnfs_layout.c.

Referenced by pattern_init().

1259 {
1260  /* take a reference on the layout, so that it won't be recalled
1261  * until all io is finished */
1262  state->io_count++;
1263  dprintf(FLLVL, "pnfs_layout_io_start(): count -> %u\n",
1264  state->io_count);
1265 }
#define dprintf
Definition: regdump.c:33
#define FLLVL
Definition: pnfs_layout.c:30
static int state
Definition: maze.c:121

◆ pnfs_layout_list_create()

enum pnfs_status pnfs_layout_list_create ( OUT struct pnfs_layout_list **  layouts_out)

Definition at line 121 of file pnfs_layout.c.

Referenced by pnfs_client_init().

123 {
124  struct pnfs_layout_list *layouts;
126 
127  layouts = calloc(1, sizeof(struct pnfs_layout_list));
128  if (layouts == NULL) {
129  status = PNFSERR_RESOURCES;
130  goto out;
131  }
132  list_init(&layouts->head);
133  InitializeCriticalSection(&layouts->lock);
134  *layouts_out = layouts;
135 out:
136  return status;
137 }
pnfs_status
Definition: pnfs.h:58
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:697
smooth NULL
Definition: ftsmooth.c:416
static FILE * out
Definition: regtests2xml.c:44
CRITICAL_SECTION lock
Definition: pnfs_layout.c:36
struct list_entry head
Definition: pnfs_layout.c:35
#define calloc
Definition: rosglue.h:14
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ pnfs_layout_list_free()

void pnfs_layout_list_free ( IN struct pnfs_layout_list layouts)

Definition at line 139 of file pnfs_layout.c.

Referenced by nfs41_client_free(), and pnfs_client_init().

141 {
142  struct list_entry *entry, *tmp;
143 
144  EnterCriticalSection(&layouts->lock);
145 
146  list_for_each_tmp(entry, tmp, &layouts->head)
148 
149  LeaveCriticalSection(&layouts->lock);
150  DeleteCriticalSection(&layouts->lock);
151  free(layouts);
152 }
rwlock_t lock
Definition: tcpcore.h:1163
#define free
Definition: debug_ros.c:5
uint8_t entry
Definition: isohybrid.c:63
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
static void layout_state_free(IN pnfs_layout_state *state)
Definition: pnfs_layout.c:93
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define state_entry(pos)
Definition: pnfs_layout.c:39
Definition: list.h:27
#define list_for_each_tmp(entry, tmp, head)
Definition: list.h:39
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)

◆ pnfs_layout_recall_fenced()

void pnfs_layout_recall_fenced ( IN pnfs_layout_state state,
IN const pnfs_layout layout 
)

Definition at line 1233 of file pnfs_layout.c.

Referenced by map_ds_error().

1236 {
1237  struct layout_recall *lrc = calloc(1, sizeof(struct layout_recall));
1238  if (lrc == NULL)
1239  return;
1240 
1242 
1243  list_init(&lrc->layout.entry);
1244  lrc->layout.offset = layout->offset;
1245  lrc->layout.length = layout->length;
1246  lrc->layout.iomode = layout->iomode;
1247  lrc->layout.type = layout->type;
1248  lrc->changed = TRUE;
1249 
1250  if (layout_recall_merge(&state->recalls, &lrc->layout) != PNFS_SUCCESS)
1251  list_add_tail(&state->recalls, &lrc->layout.entry);
1252 
1254 }
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
enum pnfs_layout_type type
Definition: pnfs.h:169
#define TRUE
Definition: types.h:120
enum pnfs_iomode iomode
Definition: pnfs.h:168
uint64_t offset
Definition: pnfs.h:166
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
smooth NULL
Definition: ftsmooth.c:416
static enum pnfs_status layout_recall_merge(IN struct list_entry *list, IN pnfs_layout *from)
Definition: pnfs_layout.c:992
uint64_t length
Definition: pnfs.h:167
struct list_entry entry
Definition: pnfs.h:165
static int state
Definition: maze.c:121
static DWORD layout
Definition: bitmap.c:46
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
pnfs_layout layout
Definition: pnfs_layout.c:869
bool_t changed
Definition: pnfs_layout.c:870
#define calloc
Definition: rosglue.h:14
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149

◆ pnfs_layout_recall_status()

enum pnfs_status pnfs_layout_recall_status ( IN const pnfs_layout_state state,
IN const pnfs_layout layout 
)

Definition at line 1211 of file pnfs_layout.c.

Referenced by thread_next_unit().

1214 {
1215  struct list_entry *entry;
1217 
1218  /* search for a pending recall that intersects with the given segment */
1219  list_for_each(entry, &state->recalls) {
1220  const struct layout_recall *recall = recall_entry(entry);
1221  if (!layout_recall_compatible(layout, &recall->layout))
1222  continue;
1223 
1224  if (recall->changed)
1225  status = PNFSERR_LAYOUT_CHANGED;
1226  else
1227  status = PNFSERR_LAYOUT_RECALLED;
1228  break;
1229  }
1230  return status;
1231 }
pnfs_status
Definition: pnfs.h:58
uint8_t entry
Definition: isohybrid.c:63
#define list_for_each(entry, head)
Definition: list.h:36
static int state
Definition: maze.c:121
static DWORD layout
Definition: bitmap.c:46
static bool_t layout_recall_compatible(IN const pnfs_layout *layout, IN const pnfs_layout *recall)
Definition: pnfs_layout.c:874
pnfs_layout layout
Definition: pnfs_layout.c:869
#define recall_entry(pos)
Definition: pnfs_layout.c:872
Definition: list.h:27
bool_t changed
Definition: pnfs_layout.c:870
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ pnfs_layout_state_close()

void pnfs_layout_state_close ( IN nfs41_session session,
IN nfs41_open_state state,
IN bool_t  remove 
)

Definition at line 830 of file pnfs_layout.c.

834 {
836  bool_t return_layout;
837  enum pnfs_status status;
838 
840  layout = state->layout;
841  state->layout = NULL;
843 
844  if (layout) {
845  LONG open_count = InterlockedDecrement(&layout->open_count);
846 
847  AcquireSRWLockShared(&layout->lock);
848  /* only return on close if it's the last close */
849  return_layout = layout->return_on_close && (open_count <= 0);
850  ReleaseSRWLockShared(&layout->lock);
851 
852  if (return_layout) {
853  status = file_layout_return(session, &state->file, layout);
854  if (status)
855  eprintf("file_layout_return() failed with %s\n",
856  pnfs_error_string(status));
857  }
858  }
859 
860  if (remove && session->client->layouts) {
861  /* free the layout when the file is removed */
862  layout_state_find_and_delete(session->client->layouts, &state->file.fh);
863  }
864 }
pnfs_status
Definition: pnfs.h:58
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
int32_t bool_t
Definition: types.h:101
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
long LONG
Definition: pedump.c:60
smooth NULL
Definition: ftsmooth.c:416
const char * pnfs_error_string(enum pnfs_status status)
Definition: pnfs_debug.c:28
static enum pnfs_status file_layout_return(IN nfs41_session *session, IN nfs41_path_fh *file, IN pnfs_layout_state *state)
Definition: pnfs_layout.c:765
bool_t return_on_close
Definition: pnfs.h:156
#define InterlockedDecrement
Definition: armddk.h:52
static int state
Definition: maze.c:121
static DWORD layout
Definition: bitmap.c:46
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
static enum pnfs_status layout_state_find_and_delete(IN struct pnfs_layout_list *layouts, IN const nfs41_fh *meta_fh)
Definition: pnfs_layout.c:194
SRWLOCK lock
Definition: pnfs.h:160
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

◆ pnfs_layout_state_open()

enum pnfs_status pnfs_layout_state_open ( IN nfs41_open_state state,
OUT pnfs_layout_state **  layout_out 
)

Definition at line 653 of file pnfs_layout.c.

656 {
657  struct pnfs_layout_list *layouts = state->session->client->layouts;
658  nfs41_session *session = state->session;
660  enum pnfs_status status;
661 
662  dprintf(FLLVL, "--> pnfs_layout_state_open()\n");
663 
664  status = client_supports_pnfs(session->client);
665  if (status)
666  goto out;
667  status = fs_supports_layout(state->file.fh.superblock, PNFS_LAYOUTTYPE_FILE);
668  if (status)
669  goto out;
670 
671  /* under shared lock, check open state for cached layouts */
672  AcquireSRWLockShared(&state->lock);
673  status = open_state_layout_cached(state, &layout);
674  ReleaseSRWLockShared(&state->lock);
675 
676  if (status) {
677  /* under exclusive lock, find or create a layout for this file */
679 
680  status = open_state_layout_cached(state, &layout);
681  if (status) {
682  status = layout_state_find_or_create(layouts, &state->file.fh, &layout);
683  if (status == PNFS_SUCCESS) {
684  LONG open_count = InterlockedIncrement(&layout->open_count);
685  state->layout = layout;
686 
687  dprintf(FLLVL, "pnfs_layout_state_open() caching layout %p "
688  "(%u opens)\n", state->layout, open_count);
689  }
690  }
691 
693 
694  if (status)
695  goto out;
696  }
697 
698  *layout_out = layout;
699 out:
700  dprintf(FLLVL, "<-- pnfs_layout_state_open() returning %s\n",
701  pnfs_error_string(status));
702  return status;
703 }
pnfs_status
Definition: pnfs.h:58
static enum pnfs_status fs_supports_layout(IN const nfs41_superblock *superblock, IN enum pnfs_layout_type type)
Definition: pnfs_layout.c:628
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
long LONG
Definition: pedump.c:60
nfs41_client * client
Definition: nfs41.h:256
#define dprintf
Definition: regdump.c:33
const char * pnfs_error_string(enum pnfs_status status)
Definition: pnfs_debug.c:28
#define FLLVL
Definition: pnfs_layout.c:30
static enum pnfs_status client_supports_pnfs(IN nfs41_client *client)
Definition: pnfs_layout.c:617
static FILE * out
Definition: regtests2xml.c:44
static int state
Definition: maze.c:121
static DWORD layout
Definition: bitmap.c:46
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
#define InterlockedIncrement
Definition: armddk.h:53
static enum pnfs_status layout_state_find_or_create(IN struct pnfs_layout_list *layouts, IN const nfs41_fh *meta_fh, OUT pnfs_layout_state **layout_out)
Definition: pnfs_layout.c:154
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
static enum pnfs_status open_state_layout_cached(IN nfs41_open_state *state, OUT pnfs_layout_state **layout_out)
Definition: pnfs_layout.c:637

◆ pnfs_layout_state_prepare()

enum pnfs_status pnfs_layout_state_prepare ( IN pnfs_layout_state state,
IN nfs41_session session,
IN nfs41_path_fh meta_file,
IN stateid_arg stateid,
IN enum pnfs_iomode  iomode,
IN uint64_t  offset,
IN uint64_t  length 
)

Definition at line 706 of file pnfs_layout.c.

714 {
715  unsigned char deviceid[PNFS_DEVICEID_SIZE];
716  struct list_entry *entry;
717  uint64_t missing;
718  enum pnfs_status status;
719 
720  /* fail if the range intersects any pending recalls */
721  list_for_each(entry, &state->recalls) {
722  const pnfs_layout *recall = layout_entry(entry);
723  if (offset <= recall->offset + recall->length
724  && recall->offset <= offset + length) {
725  status = PNFSERR_LAYOUT_RECALLED;
726  goto out;
727  }
728  }
729 
730  /* if part of the given range is not covered by a layout,
731  * attempt to fetch it with LAYOUTGET */
732  status = layout_coverage_status(state, iomode, offset, length, &missing);
733  if (status == PNFS_PENDING) {
734  status = layout_fetch(state, session, meta_file, stateid,
735  iomode, missing, offset + length - missing);
736 
737  /* return pending because layout_fetch() dropped the lock */
738  if (status == PNFS_SUCCESS)
739  status = PNFS_PENDING;
740  goto out;
741  }
742 
743  /* if any layouts in the range are missing device info,
744  * fetch them with GETDEVICEINFO */
745  status = device_status(state, offset, length, deviceid);
746  if (status == PNFS_PENDING) {
747  status = device_fetch(state, session, deviceid);
748 
749  /* return pending because device_fetch() dropped the lock */
750  if (status == PNFS_SUCCESS)
751  status = PNFS_PENDING;
752  goto out;
753  }
754 out:
755  return status;
756 }
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
static enum pnfs_status layout_fetch(IN pnfs_layout_state *state, IN nfs41_session *session, IN nfs41_path_fh *meta_file, IN stateid_arg *stateid, IN enum pnfs_iomode iomode, IN uint64_t offset, IN uint64_t length)
Definition: pnfs_layout.c:504
#define PNFS_DEVICEID_SIZE
Definition: pnfs.h:111
#define layout_entry(pos)
Definition: pnfs_layout.c:40
#define list_for_each(entry, head)
Definition: list.h:36
static enum pnfs_status device_status(IN pnfs_layout_state *state, IN uint64_t offset, IN uint64_t length, OUT unsigned char *deviceid)
Definition: pnfs_layout.c:553
uint64_t length
Definition: pnfs.h:167
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static FILE * out
Definition: regtests2xml.c:44
static int state
Definition: maze.c:121
UINT64 uint64_t
Definition: types.h:77
static enum pnfs_status device_fetch(IN pnfs_layout_state *state, IN nfs41_session *session, IN unsigned char *deviceid)
Definition: pnfs_layout.c:596
Definition: list.h:27
static SERVICE_STATUS status
Definition: service.c:31
static enum pnfs_status layout_coverage_status(IN pnfs_layout_state *state, IN enum pnfs_iomode iomode, IN uint64_t offset, IN uint64_t length, OUT uint64_t *offset_missing)
Definition: pnfs_layout.c:477

◆ range_max()

static uint64_t range_max ( IN const pnfs_layout layout)
static

Definition at line 220 of file pnfs_layout.c.

Referenced by layout_merge_segments(), layout_sanity_check(), write_range_tfs(), and write_remoting_arg().

222 {
223  uint64_t result = layout->offset + layout->length;
224  return result < layout->offset ? NFS4_UINT64_MAX : result;
225 }
static const uint64_t NFS4_UINT64_MAX
Definition: nfs41_types.h:32
static DWORD layout
Definition: bitmap.c:46
UINT64 uint64_t
Definition: types.h:77
GLuint64EXT * result
Definition: glext.h:11304