ReactOS 0.4.15-dev-8109-gd7be748
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

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

Definition at line 41 of file pnfs_layout.c.

◆ FLLVL

#define FLLVL   2 /* dprintf level for file layout logging */

Definition at line 30 of file pnfs_layout.c.

◆ layout_entry

#define layout_entry (   pos)    list_container(pos, pnfs_layout, entry)

Definition at line 40 of file pnfs_layout.c.

◆ recall_entry

Definition at line 872 of file pnfs_layout.c.

◆ state_entry

#define state_entry (   pos)    list_container(pos, pnfs_layout_state, entry)

Definition at line 39 of file pnfs_layout.c.

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.

619{
620 enum pnfs_status status;
621 AcquireSRWLockShared(&client->exid_lock);
624 ReleaseSRWLockShared(&client->exid_lock);
625 return status;
626}
VOID WINAPI ReleaseSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:89
VOID WINAPI AcquireSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:61
@ EXCHGID4_FLAG_USE_PNFS_MDS
Definition: nfs41_ops.h:101
pnfs_status
Definition: pnfs.h:58
@ PNFSERR_NOT_SUPPORTED
Definition: pnfs.h:62
@ PNFS_SUCCESS
Definition: pnfs.h:59
static FILE * client
Definition: client.c:41
Definition: ps.c:97

Referenced by pnfs_layout_state_open().

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

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
static int state
Definition: maze.c:121
#define list_for_each(entry, head)
Definition: list.h:36
#define NULL
Definition: types.h:112
uint32_t entry
Definition: isohybrid.c:63
static DWORD layout
Definition: bitmap.c:46
#define PNFS_DEVICEID_SIZE
Definition: pnfs.h:111
#define file_layout_entry(pos)
Definition: pnfs_layout.c:41
Definition: devices.h:37
Definition: list.h:27

Referenced by device_fetch().

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

600{
602 enum pnfs_status status;
603
604 /* drop the layoutstate lock for the rpc call */
607 session->client->devices, deviceid, &device);
609
610 if (status == PNFS_SUCCESS)
611 device_assign(state, deviceid, device);
612 return status;
613}
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
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)
static void device_assign(IN pnfs_layout_state *state, IN const unsigned char *deviceid, IN pnfs_file_device *device)
Definition: pnfs_layout.c:575

Referenced by pnfs_layout_state_prepare().

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

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);
569 break;
570 }
571 }
572 return status;
573}
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
@ PNFS_PENDING
Definition: pnfs.h:60

Referenced by pnfs_layout_state_prepare().

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

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
456 /* don't try RW again */
457 if (iomode == PNFS_IOMODE_RW)
458 state->status |= PNFS_LAYOUT_NOT_RW;
459 break;
460
464 /* don't try again at all */
466 break;
467 }
468
469 dprintf(FLLVL, "<-- file_layout_fetch() returning %s\n",
470 pnfs_error_string(pnfsstat));
471 return pnfsstat;
472}
static void list_init(struct list_entry *head)
Definition: list.h:51
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
const char * pnfs_iomode_string(enum pnfs_iomode iomode)
Definition: pnfs_debug.c:58
const char * pnfs_error_string(enum pnfs_status status)
Definition: pnfs_debug.c:28
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLintptr offset
Definition: glext.h:5920
nfsstat4
Definition: nfs41_const.h:86
@ NFS4ERR_BADLAYOUT
Definition: nfs41_const.h:159
@ NFS4ERR_BADIOMODE
Definition: nfs41_const.h:158
@ NFS4_OK
Definition: nfs41_const.h:87
@ NFS4ERR_UNKNOWN_LAYOUTTYPE
Definition: nfs41_const.h:171
@ NFS4ERR_LAYOUTUNAVAILABLE
Definition: nfs41_const.h:168
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
@ PNFS_IOMODE_RW
Definition: pnfs.h:82
@ PNFS_LAYOUT_NOT_RW
Definition: pnfs.h:90
@ PNFS_LAYOUT_UNAVAILABLE
Definition: pnfs.h:88
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
#define FLLVL
Definition: pnfs_layout.c:30
#define dprintf
Definition: regdump.c:33
struct list_entry layouts
Definition: nfs41_ops.h:920

Referenced by layout_fetch().

◆ file_layout_free()

static void file_layout_free ( IN pnfs_file_layout layout)
static

Definition at line 67 of file pnfs_layout.c.

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
void pnfs_file_device_put(IN pnfs_file_device *device)
Definition: pnfs_device.c:245

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

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

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 */
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 */
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 */
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 }
1080out:
1082 return status;
1083}
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
@ PNFSERR_NO_LAYOUT
Definition: pnfs.h:66
@ PNFS_RETURN_FILE
Definition: pnfs.h:101
static void layout_recall_range(IN pnfs_layout_state *state, IN const pnfs_layout *recall)
Definition: pnfs_layout.c:916
static void layout_recall_entry_init(OUT struct layout_recall *lrc, IN const struct cb_layoutrecall_args *recall)
Definition: pnfs_layout.c:975
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
#define calloc
Definition: rosglue.h:14
struct list_entry entry
Definition: pnfs.h:165
uint32_t seqid
Definition: nfs41_types.h:144
pnfs_layout layout
Definition: pnfs_layout.c:869

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

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

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)
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",
1168 return status;
1169}
return
Definition: dirsup.c:529
static struct all_devices * devices
Definition: dsm_ctrl.c:48
GLdouble s
Definition: gl.h:2039
GLdouble n
Definition: glext.h:7729
void pnfs_file_device_list_invalidate(IN struct pnfs_file_device_list *devices)
Definition: pnfs_device.c:159
static enum pnfs_status file_layout_recall_all(IN nfs41_client *client, IN const struct cb_layoutrecall_args *recall)
Definition: pnfs_layout.c:1147
#define state_entry(pos)
Definition: pnfs_layout.c:39
static enum pnfs_status file_layout_recall(IN pnfs_layout_state *state, IN const struct cb_layoutrecall_args *recall)
Definition: pnfs_layout.c:1032
rwlock_t lock
Definition: tcpcore.h:0
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)

Referenced by pnfs_file_layout_recall().

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

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)
1099
1100 LeaveCriticalSection(&client->layouts->lock);
1101
1102 dprintf(FLLVL, "<-- file_layout_recall_file() returning %s\n",
1104 return status;
1105}
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

Referenced by pnfs_file_layout_recall().

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

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) {
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",
1144 return status;
1145}
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

Referenced by pnfs_file_layout_recall().

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

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 */
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
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 */
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));
807 } else {
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
824out:
825 dprintf(FLLVL, "<-- file_layout_return() returning %s\n",
827 return status;
828}
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOL WINAPI SleepConditionVariableSRW(PCONDITION_VARIABLE ConditionVariable, PSRWLOCK Lock, DWORD Timeout, ULONG Flags)
Definition: sync.c:121
VOID WINAPI WakeConditionVariable(PCONDITION_VARIABLE ConditionVariable)
Definition: sync.c:144
#define INFINITE
Definition: serial.h:102
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 const uint64_t NFS4_UINT64_MAX
Definition: nfs41_types.h:32
@ PNFS_IOMODE_ANY
Definition: pnfs.h:83
@ PNFS_LAYOUTTYPE_FILE
Definition: pnfs.h:75
static enum pnfs_status layout_return_status(IN const pnfs_layout_state *state)
Definition: pnfs_layout.c:758
static void layout_state_free_layouts(IN pnfs_layout_state *state)
Definition: pnfs_layout.c:75
Definition: fci.c:127
#define ZeroMemory
Definition: winbase.h:1712

Referenced by pnfs_layout_state_close().

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

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

Referenced by pnfs_layout_state_open().

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

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

Referenced by file_layout_recall_fsid().

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

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));
907out:
908 return layout;
909
910out_free:
912 layout = NULL;
913 goto out;
914}
static void file_layout_free(IN pnfs_file_layout *layout)
Definition: pnfs_layout.c:67

Referenced by layout_recall_range().

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

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 */
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}
UINT64 uint64_t
Definition: types.h:77
#define layout_entry(pos)
Definition: pnfs_layout.c:40

Referenced by pnfs_layout_state_prepare().

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

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}
uint32_t len
Definition: nfs41_types.h:54
unsigned char fh[NFS4_FHSIZE]
Definition: nfs41_types.h:53
Definition: pdh_main.c:94

Referenced by layout_entry_find().

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

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

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

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

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)) {
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 */
539 }
540
541 if (status && iomode == PNFS_IOMODE_READ) {
542 /* fall back on READ if necessary */
544 stateid, iomode, offset, length, NFS4_UINT64_MAX);
545 }
546
547 state->pending = FALSE;
549out:
550 return status;
551}
@ STATEID_LAYOUT
Definition: nfs41_ops.h:280
@ PNFS_IOMODE_READ
Definition: pnfs.h:81
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
enum stateid_type type
Definition: nfs41_ops.h:285
stateid4 stateid
Definition: nfs41_ops.h:284

Referenced by pnfs_layout_state_prepare().

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

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}

Referenced by layout_merge_segments().

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

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 min(a, b)
Definition: monoChain.cc:55
static uint64_t range_max(IN const pnfs_layout *layout)
Definition: pnfs_layout.c:220
static int layout_filehandles_cmp(IN const pnfs_file_layout_handles *lhs, IN const pnfs_file_layout_handles *rhs)
Definition: pnfs_layout.c:242
CardRegion * from
Definition: spigame.cpp:19
#define max(a, b)
Definition: svc.c:63

Referenced by layout_state_merge().

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

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
uint64_t length
Definition: pnfs.h:167

Referenced by layout_recall_range(), and layout_update_range().

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

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}

Referenced by layout_recall_range(), and pnfs_layout_recall_status().

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

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}

Referenced by file_layout_recall().

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

995{
996 struct list_entry *entry, *tmp;
998
999 /* attempt to merge the new recall with each existing recall */
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);
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}
static void list_remove(struct list_entry *entry)
Definition: list.h:90
#define list_for_each_tmp(entry, tmp, head)
Definition: list.h:39
Definition: list.h:37
enum pnfs_layout_type type
Definition: pnfs.h:169
enum pnfs_iomode iomode
Definition: pnfs.h:168

Referenced by file_layout_recall(), and pnfs_layout_recall_fenced().

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

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;
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);
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}
double __cdecl remainder(double, double)
Definition: remainder.c:75
static pnfs_file_layout * layout_allocate_copy(IN const pnfs_file_layout *existing)
Definition: pnfs_layout.c:885
static void layout_ordered_insert(IN pnfs_layout_state *state, IN pnfs_layout *layout)
Definition: pnfs_layout.c:317
static bool_t layout_recall_compatible(IN const pnfs_layout *layout, IN const pnfs_layout *recall)
Definition: pnfs_layout.c:874

Referenced by file_layout_recall(), and layout_state_deferred_recalls().

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

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

Referenced by file_layout_return().

◆ layout_sanity_check()

static bool_t layout_sanity_check ( IN pnfs_file_layout layout)
static

Definition at line 227 of file pnfs_layout.c.

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 ||
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}
__inline uint32_t layout_unit_size(IN const pnfs_file_layout *layout)
Definition: pnfs.h:315

Referenced by layout_update_range().

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

46{
49
50 layout = calloc(1, sizeof(pnfs_layout_state));
51 if (layout == NULL) {
53 goto out;
54 }
55
56 fh_copy(&layout->meta_fh, meta_fh);
57 list_init(&layout->layouts);
58 list_init(&layout->recalls);
61
62 *layout_out = layout;
63out:
64 return status;
65}
void fh_copy(OUT nfs41_fh *dst, IN const nfs41_fh *src)
Definition: util.c:354
VOID WINAPI InitializeSRWLock(PSRWLOCK Lock)
Definition: sync.c:75
VOID WINAPI InitializeConditionVariable(PCONDITION_VARIABLE ConditionVariable)
Definition: sync.c:68
@ PNFSERR_RESOURCES
Definition: pnfs.h:69

Referenced by layout_state_find_or_create().

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

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}

Referenced by pnfs_layout_io_finished().

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

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) {
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}
static void layout_state_free(IN pnfs_layout_state *state)
Definition: pnfs_layout.c:93

Referenced by pnfs_layout_state_close().

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

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}
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
static enum pnfs_status layout_state_create(IN const nfs41_fh *meta_fh, OUT pnfs_layout_state **layout_out)
Definition: pnfs_layout.c:43

Referenced by pnfs_layout_state_open().

◆ layout_state_free()

static void layout_state_free ( IN pnfs_layout_state state)
static

Definition at line 93 of file pnfs_layout.c.

95{
98 free(state);
99}
static void layout_state_free_recalls(IN pnfs_layout_state *state)
Definition: pnfs_layout.c:84

Referenced by layout_state_find_and_delete(), and pnfs_layout_list_free().

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

77{
78 struct list_entry *entry, *tmp;
79 list_for_each_tmp(entry, tmp, &state->layouts)
81 list_init(&state->layouts);
82}

Referenced by file_layout_return(), and layout_state_free().

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

86{
87 struct list_entry *entry, *tmp;
88 list_for_each_tmp(entry, tmp, &state->recalls)
90 list_init(&state->recalls);
91}

Referenced by layout_state_free().

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

289{
290 struct list_entry *entry, *tmp;
293
294 /* attempt to merge the new segment with each existing segment */
295 list_for_each_tmp(entry, tmp, &state->layouts) {
297 if (!layout_merge_segments(to, from))
298 continue;
299
300 /* on success, remove/free the new segment */
301 list_remove(&from->layout.entry);
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}
static bool_t layout_merge_segments(IN pnfs_file_layout *to, IN pnfs_file_layout *from)
Definition: pnfs_layout.c:251

Referenced by layout_update_range(), and pnfs_layout_io_finished().

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

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;
414out:
415 return status;
416}
static enum pnfs_status layout_update_range(IN OUT pnfs_layout_state *state, IN const struct list_entry *layouts)
Definition: pnfs_layout.c:341
static enum pnfs_status layout_update_stateid(IN OUT pnfs_layout_state *state, IN const stateid4 *stateid)
Definition: pnfs_layout.c:374

Referenced by file_layout_fetch().

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

344{
345 struct list_entry *entry, *tmp;
348
349 list_for_each_tmp(entry, tmp, layouts) {
351
352 /* don't know what to do with non-file layouts */
353 if (layout->layout.type != PNFS_LAYOUTTYPE_FILE)
354 continue;
355
358 continue;
359 }
360
361 /* attempt to merge the range with existing segments */
363 if (status) {
364 dprintf(FLLVL, "saving new layout:\n");
366
369 }
370 }
371 return status;
372}
void dprint_layout(int level, const struct __pnfs_file_layout *layout)
static bool_t layout_sanity_check(IN pnfs_file_layout *layout)
Definition: pnfs_layout.c:227
static enum pnfs_status layout_state_merge(IN pnfs_layout_state *state, IN pnfs_file_layout *from)
Definition: pnfs_layout.c:286

Referenced by layout_update().

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

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 {
389 }
390 return status;
391}
#define NFS4_STATEID_OTHER
Definition: nfs41_const.h:33

Referenced by layout_update().

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

640{
642
643 if (state->layout) {
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}

Referenced by pnfs_layout_state_open().

◆ 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));
1185 goto out;
1186 }
1187
1188 switch (recall->recall.type) {
1189 case PNFS_RETURN_FILE:
1191 break;
1192 case PNFS_RETURN_FSID:
1194 break;
1195 case PNFS_RETURN_ALL:
1197 break;
1198
1199 default:
1200 dprintf(FLLVL, "invalid return type %u!\n", recall->recall);
1202 goto out;
1203 }
1204out:
1205 dprintf(FLLVL, "<-- pnfs_file_layout_recall() returning %s\n",
1207 return status;
1208}
const char * pnfs_layout_type_string(enum pnfs_layout_type type)
Definition: pnfs_debug.c:48
@ PNFS_RETURN_FSID
Definition: pnfs.h:102
@ PNFS_RETURN_ALL
Definition: pnfs.h:103
static enum pnfs_status file_layout_recall_file(IN nfs41_client *client, IN const struct cb_layoutrecall_args *recall)
Definition: pnfs_layout.c:1085
static enum pnfs_status file_layout_recall_fsid(IN nfs41_client *client, IN const struct cb_layoutrecall_args *recall)
Definition: pnfs_layout.c:1114

◆ pnfs_layout_io_finished()

void pnfs_layout_io_finished ( IN pnfs_layout_state state)

Definition at line 1267 of file pnfs_layout.c.

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
1287out_unlock:
1289}
static int list_empty(struct list_entry *head)
Definition: list.h:58
static void layout_state_deferred_recalls(IN pnfs_layout_state *state)
Definition: pnfs_layout.c:960

Referenced by pattern_free().

◆ pnfs_layout_io_start()

void pnfs_layout_io_start ( IN pnfs_layout_state state)

Definition at line 1257 of file pnfs_layout.c.

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}

Referenced by pattern_init().

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

123{
124 struct pnfs_layout_list *layouts;
126
127 layouts = calloc(1, sizeof(struct pnfs_layout_list));
128 if (layouts == NULL) {
130 goto out;
131 }
132 list_init(&layouts->head);
134 *layouts_out = layouts;
135out:
136 return status;
137}
CRITICAL_SECTION lock
Definition: pnfs_layout.c:36
struct list_entry head
Definition: pnfs_layout.c:35
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751

Referenced by pnfs_client_init().

◆ pnfs_layout_list_free()

void pnfs_layout_list_free ( IN struct pnfs_layout_list layouts)

Definition at line 139 of file pnfs_layout.c.

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}
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)

Referenced by nfs41_client_free(), and pnfs_client_init().

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

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}
bool_t changed
Definition: pnfs_layout.c:870

Referenced by map_ds_error().

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

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)
1226 else
1228 break;
1229 }
1230 return status;
1231}
@ PNFSERR_LAYOUT_CHANGED
Definition: pnfs.h:71
@ PNFSERR_LAYOUT_RECALLED
Definition: pnfs.h:70
#define recall_entry(pos)
Definition: pnfs_layout.c:872

Referenced by thread_next_unit().

◆ 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
848 /* only return on close if it's the last close */
849 return_layout = layout->return_on_close && (open_count <= 0);
851
852 if (return_layout) {
854 if (status)
855 eprintf("file_layout_return() failed with %s\n",
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}
#define InterlockedDecrement
Definition: armddk.h:52
int32_t bool_t
Definition: types.h:101
int remove
Definition: msacm.c:1366
long LONG
Definition: pedump.c:60
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
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

◆ 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
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 */
675
676 if (status) {
677 /* under exclusive lock, find or create a layout for this file */
679
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;
699out:
700 dprintf(FLLVL, "<-- pnfs_layout_state_open() returning %s\n",
702 return status;
703}
#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 enum pnfs_status client_supports_pnfs(IN nfs41_client *client)
Definition: pnfs_layout.c:617
static enum pnfs_status open_state_layout_cached(IN nfs41_open_state *state, OUT pnfs_layout_state **layout_out)
Definition: pnfs_layout.c:637
static enum pnfs_status fs_supports_layout(IN const nfs41_superblock *superblock, IN enum pnfs_layout_type type)
Definition: pnfs_layout.c:628

◆ 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) {
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)
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)
752 goto out;
753 }
754out:
755 return status;
756}
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
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
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
static enum pnfs_status device_fetch(IN pnfs_layout_state *state, IN nfs41_session *session, IN unsigned char *deviceid)
Definition: pnfs_layout.c:596

◆ range_max()

static uint64_t range_max ( IN const pnfs_layout layout)
static

Definition at line 220 of file pnfs_layout.c.

222{
223 uint64_t result = layout->offset + layout->length;
224 return result < layout->offset ? NFS4_UINT64_MAX : result;
225}
GLuint64EXT * result
Definition: glext.h:11304

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