ReactOS  0.4.12-dev-75-g00dd17e
lookup.c File Reference
#include <windows.h>
#include <strsafe.h>
#include <time.h>
#include "nfs41_compound.h"
#include "nfs41_ops.h"
#include "name_cache.h"
#include "util.h"
#include "daemon_debug.h"
Include dependency graph for lookup.c:

Go to the source code of this file.

Classes

struct  lookup_referral
 
struct  __nfs41_lookup_component_args
 
struct  __nfs41_lookup_component_res
 

Macros

#define LULVL   2 /* dprintf level for lookup logging */
 
#define MAX_LOOKUP_COMPONENTS   8
 
#define ERROR_FILESYSTEM_ABSENT   ERROR_DEVICE_REMOVED
 

Typedefs

typedef struct __nfs41_lookup_component_args nfs41_lookup_component_args
 
typedef struct __nfs41_lookup_component_res nfs41_lookup_component_res
 

Functions

static void init_component_args (IN nfs41_lookup_component_args *args, IN nfs41_lookup_component_res *res, IN nfs41_abs_path *path, IN struct lookup_referral *referral)
 
static int lookup_rpc (IN nfs41_session *session, IN nfs41_path_fh *dir, IN uint32_t component_count, IN nfs41_lookup_component_args *args, OUT nfs41_lookup_component_res *res)
 
static int map_lookup_error (int status, bool_t last_component)
 
static int server_lookup (IN nfs41_session *session, IN nfs41_path_fh *dir, IN const char *path, IN const char *path_end, IN uint32_t count, IN nfs41_lookup_component_args *args, IN nfs41_lookup_component_res *res, OUT OPTIONAL nfs41_path_fh **parent_out, OUT OPTIONAL nfs41_path_fh **target_out, OUT OPTIONAL nfs41_file_info *info_out)
 
static uint32_t max_lookup_components (IN const nfs41_session *session)
 
static uint32_t get_component_array (IN OUT const char **path_pos, IN const char *path_end, IN uint32_t max_components, OUT nfs41_path_fh *components, OUT uint32_t *component_count)
 
static int server_lookup_loop (IN nfs41_session *session, IN OPTIONAL nfs41_path_fh *parent_in, IN nfs41_abs_path *path, IN const char *path_pos, IN struct lookup_referral *referral, OUT OPTIONAL nfs41_path_fh *parent_out, OUT OPTIONAL nfs41_path_fh *target_out, OUT OPTIONAL nfs41_file_info *info_out)
 
static void referral_locations_free (IN fs_locations4 *locations)
 
static int referral_resolve (IN nfs41_root *root, IN nfs41_session *session_in, IN struct lookup_referral *referral, OUT nfs41_abs_path *path_out, OUT nfs41_session **session_out)
 
int nfs41_lookup (IN nfs41_root *root, IN nfs41_session *session, IN OUT nfs41_abs_path *path_inout, OUT OPTIONAL nfs41_path_fh *parent_out, OUT OPTIONAL nfs41_path_fh *target_out, OUT OPTIONAL nfs41_file_info *info_out, OUT nfs41_session **session_out)
 

Macro Definition Documentation

◆ ERROR_FILESYSTEM_ABSENT

#define ERROR_FILESYSTEM_ABSENT   ERROR_DEVICE_REMOVED

Definition at line 39 of file lookup.c.

Referenced by map_lookup_error(), and nfs41_lookup().

◆ LULVL

#define LULVL   2 /* dprintf level for lookup logging */

Definition at line 33 of file lookup.c.

Referenced by nfs41_lookup().

◆ MAX_LOOKUP_COMPONENTS

#define MAX_LOOKUP_COMPONENTS   8

Definition at line 36 of file lookup.c.

Referenced by init_component_args(), lookup_rpc(), and max_lookup_components().

Typedef Documentation

◆ nfs41_lookup_component_args

◆ nfs41_lookup_component_res

Function Documentation

◆ get_component_array()

static uint32_t get_component_array ( IN OUT const char **  path_pos,
IN const char path_end,
IN uint32_t  max_components,
OUT nfs41_path_fh components,
OUT uint32_t component_count 
)
static

Definition at line 279 of file lookup.c.

Referenced by server_lookup_loop().

285 {
286  uint32_t i;
287 
288  for (i = 0; i < max_components; i++) {
289  if (!next_component(*path_pos, path_end, &components[i].name))
290  break;
291  *path_pos = components[i].name.name + components[i].name.len;
292  }
293 
294  *component_count = i;
295  return i;
296 }
GLenum GLclampf GLint i
Definition: glfuncs.h:14
unsigned int component_count
bool_t next_component(IN const char *path, IN const char *path_end, OUT nfs41_component *component)
Definition: util.c:305
GLenum GLenum GLuint components
Definition: glext.h:9620
UINT32 uint32_t
Definition: types.h:75
Definition: name.c:36

◆ init_component_args()

static void init_component_args ( IN nfs41_lookup_component_args args,
IN nfs41_lookup_component_res res,
IN nfs41_abs_path path,
IN struct lookup_referral referral 
)
static

Definition at line 72 of file lookup.c.

Referenced by server_lookup_loop().

77 {
78  uint32_t i;
79 
80  args->attr_request.count = 2;
81  args->attr_request.arr[0] = FATTR4_WORD0_TYPE
85  args->attr_request.arr[1] = FATTR4_WORD1_MODE
89 
90  args->getrootattr.attr_request = &args->attr_request;
91  res->root.path = path;
92  res->getrootfh.fh = &res->root.fh;
93  res->getrootattr.info = &res->rootinfo;
94  res->getrootattr.obj_attributes.attr_vals_len = NFS4_OPAQUE_LIMIT;
95  res->referral = referral;
96 
97  for (i = 0; i < MAX_LOOKUP_COMPONENTS; i++) {
98  args->getattr[i].attr_request = &args->attr_request;
99  res->file[i].path = path;
100  args->lookup[i].name = &res->file[i].name;
101  res->getfh[i].fh = &res->file[i].fh;
102  res->getattr[i].info = &res->info[i];
103  res->getattr[i].obj_attributes.attr_vals_len = NFS4_OPAQUE_LIMIT;
104  }
105 }
GLsizei const GLchar ** path
Definition: glext.h:7234
Definition: match.c:390
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define NFS4_OPAQUE_LIMIT
Definition: nfs41_const.h:31
UINT32 uint32_t
Definition: types.h:75
GLuint res
Definition: glext.h:9613
#define MAX_LOOKUP_COMPONENTS
Definition: lookup.c:36

◆ lookup_rpc()

static int lookup_rpc ( IN nfs41_session session,
IN nfs41_path_fh dir,
IN uint32_t  component_count,
IN nfs41_lookup_component_args args,
OUT nfs41_lookup_component_res res 
)
static

Definition at line 107 of file lookup.c.

Referenced by server_lookup().

113 {
114  int status;
115  uint32_t i;
116  nfs41_compound compound;
117  nfs_argop4 argops[4+MAX_LOOKUP_COMPONENTS*3];
118  nfs_resop4 resops[4+MAX_LOOKUP_COMPONENTS*3];
119 
120  compound_init(&compound, argops, resops, "lookup");
121 
122  compound_add_op(&compound, OP_SEQUENCE, &args->sequence, &res->sequence);
123  nfs41_session_sequence(&args->sequence, session, 0);
124 
125  if (dir == &res->root) {
126  compound_add_op(&compound, OP_PUTROOTFH, NULL, &res->putfh);
127  compound_add_op(&compound, OP_GETFH, NULL, &res->getrootfh);
128  compound_add_op(&compound, OP_GETATTR, &args->getrootattr,
129  &res->getrootattr);
130  } else {
131  args->putfh.file = dir;
132  compound_add_op(&compound, OP_PUTFH, &args->putfh, &res->putfh);
133  }
134 
135  for (i = 0; i < component_count; i++) {
136  compound_add_op(&compound, OP_LOOKUP, &args->lookup[i], &res->lookup[i]);
137  compound_add_op(&compound, OP_GETFH, NULL, &res->getfh[i]);
138  compound_add_op(&compound, OP_GETATTR, &args->getattr[i],
139  &res->getattr[i]);
140  }
141 
142  status = compound_encode_send_decode(session, &compound, TRUE);
143  if (status)
144  goto out;
145 
146  compound_error(status = compound.res.status);
147 out:
148  return status;
149 }
#define TRUE
Definition: types.h:120
int compound_encode_send_decode(nfs41_session *session, nfs41_compound *compound, bool_t try_recovery)
Definition: match.c:390
GLenum GLclampf GLint i
Definition: glfuncs.h:14
unsigned int component_count
nfs41_compound_res res
smooth NULL
Definition: ftsmooth.c:416
unsigned int dir
Definition: maze.c:112
int compound_error(int status)
static FILE * out
Definition: regtests2xml.c:44
void compound_add_op(nfs41_compound *compound, uint32_t opnum, void *arg, void *res)
UINT32 uint32_t
Definition: types.h:75
void nfs41_session_sequence(struct __nfs41_sequence_args *args, nfs41_session *session, bool_t cachethis)
void compound_init(nfs41_compound *compound, nfs_argop4 *argops, nfs_resop4 *resops, const char *tag)
GLuint res
Definition: glext.h:9613
#define MAX_LOOKUP_COMPONENTS
Definition: lookup.c:36
static SERVICE_STATUS status
Definition: service.c:31

◆ map_lookup_error()

static int map_lookup_error ( int  status,
bool_t  last_component 
)
static

Definition at line 151 of file lookup.c.

Referenced by server_lookup().

152 {
153  switch (status) {
154  case NFS4ERR_NOENT:
156  else return ERROR_PATH_NOT_FOUND;
157  case NFS4ERR_SYMLINK: return ERROR_REPARSE;
160  }
161 }
int nfs_to_windows_error(int status, int default_error)
Definition: util.c:235
bool_t last_component(IN const char *path, IN const char *path_end, OUT nfs41_component *component)
Definition: util.c:317
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define ERROR_REPARSE
Definition: winerror.h:522
#define ERROR_FILESYSTEM_ABSENT
Definition: lookup.c:39
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
Definition: ps.c:97

◆ max_lookup_components()

static uint32_t max_lookup_components ( IN const nfs41_session session)
static

Definition at line 272 of file lookup.c.

Referenced by server_lookup_loop().

274 {
275  const uint32_t comps = (session->fore_chan_attrs.ca_maxoperations - 4) / 3;
276  return min(comps, MAX_LOOKUP_COMPONENTS);
277 }
#define min(a, b)
Definition: monoChain.cc:55
UINT32 uint32_t
Definition: types.h:75
#define MAX_LOOKUP_COMPONENTS
Definition: lookup.c:36

◆ nfs41_lookup()

int nfs41_lookup ( IN nfs41_root root,
IN nfs41_session session,
IN OUT nfs41_abs_path path_inout,
OUT OPTIONAL nfs41_path_fh parent_out,
OUT OPTIONAL nfs41_path_fh target_out,
OUT OPTIONAL nfs41_file_info info_out,
OUT nfs41_session **  session_out 
)

Definition at line 424 of file lookup.c.

Referenced by handle_mount(), handle_open(), lookup_entry(), lookup_symlink(), nfs41_lookup(), and nfs41_symlink_follow().

432 {
434  struct nfs41_name_cache *cache = session_name_cache(session);
436  const char *path_pos, *path_end;
437  struct lookup_referral referral;
438  bool_t negative = 0;
439  int status;
440 
441  if (session_out) *session_out = session;
442 
443  InitializeSRWLock(&path.lock);
444 
445  /* to avoid holding this lock over multiple rpcs,
446  * make a copy of the path and use that instead */
447  AcquireSRWLockShared(&path_inout->lock);
448  abs_path_copy(&path, path_inout);
449  ReleaseSRWLockShared(&path_inout->lock);
450 
451  path_pos = path.path;
452  path_end = path.path + path.len;
453 
454  dprintf(LULVL, "--> nfs41_lookup('%s')\n", path.path);
455 
456  if (parent_out == NULL) parent_out = &parent;
457  if (target_out == NULL) target_out = &target;
458  parent_out->fh.len = target_out->fh.len = 0;
459 
460  status = nfs41_name_cache_lookup(cache, path_pos, path_end, &path_pos,
461  &parent_out->fh, &target_out->fh, info_out, &negative);
462  if (status == NO_ERROR || negative)
463  goto out;
464 
465  if (parent_out->fh.len) {
466  /* start where the name cache left off */
467  if (&parent != parent_out) {
468  /* must make a copy for server_start, because
469  * server_lookup_loop() will overwrite parent_out */
470  path_fh_copy(&parent, parent_out);
471  }
472  server_start = &parent;
473  } else {
474  /* start with PUTROOTFH */
475  server_start = NULL;
476  }
477 
478  status = server_lookup_loop(session, server_start,
479  &path, path_pos, &referral, parent_out, target_out, info_out);
480 
481  if (status == ERROR_FILESYSTEM_ABSENT) {
482  nfs41_session *new_session;
483 
484  /* create a session to the referred server and
485  * reformat the path relative to that server's root */
486  status = referral_resolve(root, session,
487  &referral, path_inout, &new_session);
488  if (status) {
489  eprintf("referral_resolve() failed with %d\n", status);
490  goto out;
491  }
492 
493  /* update the positions of the parent and target components */
494  last_component(path_inout->path, path_inout->path + path_inout->len,
495  &target_out->name);
496  last_component(path_inout->path, target_out->name.name,
497  &parent_out->name);
498 
499  if (session_out) *session_out = new_session;
500 
501  /* look up the new path */
502  status = nfs41_lookup(root, new_session, path_inout,
503  parent_out, target_out, info_out, session_out);
504  }
505 out:
506  dprintf(LULVL, "<-- nfs41_lookup() returning %d\n", status);
507  return status;
508 }
Definition: cache.c:46
int32_t bool_t
Definition: types.h:101
GLsizei const GLchar ** path
Definition: glext.h:7234
#define LULVL
Definition: lookup.c:33
int nfs41_lookup(IN nfs41_root *root, IN nfs41_session *session, IN OUT nfs41_abs_path *path_inout, OUT OPTIONAL nfs41_path_fh *parent_out, OUT OPTIONAL nfs41_path_fh *target_out, OUT OPTIONAL nfs41_file_info *info_out, OUT nfs41_session **session_out)
Definition: lookup.c:424
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
int nfs41_name_cache_lookup(IN struct nfs41_name_cache *cache, IN const char *path, IN const char *path_end, OUT OPTIONAL const char **remaining_path_out, OUT OPTIONAL nfs41_fh *parent_out, OUT OPTIONAL nfs41_fh *target_out, OUT OPTIONAL nfs41_file_info *info_out, OUT OPTIONAL bool_t *is_negative)
Definition: name_cache.c:824
#define NO_ERROR
Definition: dderror.h:5
bool_t last_component(IN const char *path, IN const char *path_end, OUT nfs41_component *component)
Definition: util.c:317
static int referral_resolve(IN nfs41_root *root, IN nfs41_session *session_in, IN struct lookup_referral *referral, OUT nfs41_abs_path *path_out, OUT nfs41_session **session_out)
Definition: lookup.c:373
void abs_path_copy(OUT nfs41_abs_path *dst, IN const nfs41_abs_path *src)
Definition: util.c:338
static __inline struct nfs41_name_cache * session_name_cache(IN nfs41_session *session)
Definition: name_cache.h:34
static void server_start(server_params *par)
Definition: sock.c:522
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416
r parent
Definition: btrfs.c:2644
unsigned short len
Definition: nfs41_types.h:43
static FILE * out
Definition: regtests2xml.c:44
VOID WINAPI InitializeSRWLock(PSRWLOCK Lock)
Definition: sync.c:75
#define ERROR_FILESYSTEM_ABSENT
Definition: lookup.c:39
static int server_lookup_loop(IN nfs41_session *session, IN OPTIONAL nfs41_path_fh *parent_in, IN nfs41_abs_path *path, IN const char *path_pos, IN struct lookup_referral *referral, OUT OPTIONAL nfs41_path_fh *parent_out, OUT OPTIONAL nfs41_path_fh *target_out, OUT OPTIONAL nfs41_file_info *info_out)
Definition: lookup.c:298
GLenum target
Definition: glext.h:7315
char path[NFS41_MAX_PATH_LEN]
Definition: nfs41_types.h:42
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
void path_fh_copy(OUT nfs41_path_fh *dst, IN const nfs41_path_fh *src)
Definition: util.c:364

◆ referral_locations_free()

static void referral_locations_free ( IN fs_locations4 locations)
static

Definition at line 362 of file lookup.c.

Referenced by referral_resolve().

364 {
365  uint32_t i;
366  if (locations->locations) {
367  for (i = 0; i < locations->location_count; i++)
368  free(locations->locations[i].servers);
369  free(locations->locations);
370  }
371 }
#define free
Definition: debug_ros.c:5
GLenum GLclampf GLint i
Definition: glfuncs.h:14
GLsizei const GLint * locations
Definition: glext.h:10542
UINT32 uint32_t
Definition: types.h:75

◆ referral_resolve()

static int referral_resolve ( IN nfs41_root root,
IN nfs41_session session_in,
IN struct lookup_referral referral,
OUT nfs41_abs_path path_out,
OUT nfs41_session **  session_out 
)
static

Definition at line 373 of file lookup.c.

Referenced by nfs41_lookup().

379 {
380  char rest_of_path[NFS41_MAX_PATH_LEN];
381  fs_locations4 locations = { 0 };
382  const fs_location4 *location;
384  int status;
385 
386  /* get fs_locations */
387  status = nfs41_fs_locations(session_in, &referral->parent,
388  &referral->name, &locations);
389  if (status) {
390  eprintf("nfs41_fs_locations() failed with %s\n",
391  nfs_error_string(status));
392  status = nfs_to_windows_error(status, ERROR_PATH_NOT_FOUND);
393  goto out;
394  }
395 
396  /* mount the first location available */
397  status = nfs41_root_mount_referral(root, &locations, &location, &client);
398  if (status) {
399  eprintf("nfs41_root_mount_referral() failed with %d\n",
400  status);
401  goto out;
402  }
403 
404  /* format a new path from that location's root */
405  if (FAILED(StringCchCopyA(rest_of_path, NFS41_MAX_PATH_LEN,
406  referral->name.name + referral->name.len))) {
408  goto out;
409  }
410 
411  AcquireSRWLockExclusive(&path_out->lock);
412  abs_path_copy(path_out, &location->path);
413  if (FAILED(StringCchCatA(path_out->path, NFS41_MAX_PATH_LEN, rest_of_path)))
415  path_out->len = path_out->len + (unsigned short)strlen(rest_of_path);
416  ReleaseSRWLockExclusive(&path_out->lock);
417 
418  if (session_out) *session_out = client->session;
419 out:
420  referral_locations_free(&locations);
421  return status;
422 }
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
char * name
Definition: wpp.c:36
int nfs_to_windows_error(int status, int default_error)
Definition: util.c:235
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
#define NFS41_MAX_PATH_LEN
Definition: nfs41_const.h:46
void abs_path_copy(OUT nfs41_abs_path *dst, IN const nfs41_abs_path *src)
Definition: util.c:338
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:91
STRSAFEAPI StringCchCatA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:320
static FILE * client
Definition: client.c:41
static FILE * out
Definition: regtests2xml.c:44
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
enum nfsstat4 nfs41_fs_locations(IN nfs41_session *session, IN nfs41_path_fh *parent, IN const nfs41_component *name, OUT fs_locations4 *locations)
Definition: nfs41_ops.c:1737
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
GLsizei const GLint * locations
Definition: glext.h:10542
#define location(file, line)
Definition: kmtest.h:18
STRSAFEAPI StringCchCopyA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:145
nfs41_abs_path path
Definition: nfs41_types.h:178
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
static void referral_locations_free(IN fs_locations4 *locations)
Definition: lookup.c:362
static SERVICE_STATUS status
Definition: service.c:31
int nfs41_root_mount_referral(IN nfs41_root *root, IN const fs_locations4 *locations, OUT const fs_location4 **loc_out, OUT nfs41_client **client_out)
Definition: namespace.c:459
struct __nfs41_session * session
Definition: nfs41.h:199
#define ERROR_FILENAME_EXCED_RANGE
Definition: winerror.h:263

◆ server_lookup()

static int server_lookup ( IN nfs41_session session,
IN nfs41_path_fh dir,
IN const char path,
IN const char path_end,
IN uint32_t  count,
IN nfs41_lookup_component_args args,
IN nfs41_lookup_component_res res,
OUT OPTIONAL nfs41_path_fh **  parent_out,
OUT OPTIONAL nfs41_path_fh **  target_out,
OUT OPTIONAL nfs41_file_info info_out 
)
static

Definition at line 163 of file lookup.c.

Referenced by server_lookup_loop().

174 {
176  uint32_t i = 0;
177  int status;
178 
179  if (parent_out) *parent_out = NULL;
180  if (target_out) *target_out = NULL;
181 
182  lookup_rpc(session, dir, count, args, res);
183 
184  status = res->sequence.sr_status; if (status) goto out;
185  status = res->putfh.status; if (status) goto out;
186  status = res->getrootfh.status; if (status) goto out;
187  status = res->getrootattr.status; if (status) goto out;
188 
189  if (dir == &res->root) {
190  nfs41_component name = { 0 };
191 
192  /* fill in the file handle's fileid and superblock */
193  dir->fh.fileid = res->getrootattr.info->fileid;
194  status = nfs41_superblock_for_fh(session,
195  &res->getrootattr.info->fsid, NULL, dir);
196  if (status)
197  goto out;
198 
199  /* get the name of the parent (empty if its the root) */
200  last_component(path, count ? args->lookup[0].name->name : path_end, &name);
201 
202  /* add the file handle and attributes to the name cache */
203  memcpy(&res->getrootattr.info->attrmask,
204  &res->getrootattr.obj_attributes.attrmask, sizeof(bitmap4));
206  &dir->fh, res->getrootattr.info, NULL, OPEN_DELEGATE_NONE);
207  }
208  file = dir;
209 
210  if (count == 0) {
211  if (target_out)
212  *target_out = dir;
213  if (info_out)
214  memcpy(info_out, res->getrootattr.info, sizeof(nfs41_file_info));
215  } else if (count == 1) {
216  if (parent_out)
217  *parent_out = dir;
218  }
219 
220  for (i = 0; i < count; i++) {
221  if (res->lookup[i].status == NFS4ERR_SYMLINK) {
222  /* return the symlink as the parent file */
223  last_component(path, args->lookup[i].name->name, &file->name);
224  if (parent_out) *parent_out = file;
225  } else if (res->lookup[i].status == NFS4ERR_NOENT) {
226  /* insert a negative lookup entry */
228  args->lookup[i].name, NULL, NULL, NULL, OPEN_DELEGATE_NONE);
229  }
230  status = res->lookup[i].status; if (status) break;
231 
232  if (res->getfh[i].status == NFS4ERR_MOVED) {
233  /* save enough information to follow the referral */
234  path_fh_copy(&res->referral->parent, file);
235  res->referral->name.name = args->lookup[i].name->name;
236  res->referral->name.len = args->lookup[i].name->len;
237  }
238  status = res->getfh[i].status; if (status) break;
239  status = res->getattr[i].status; if (status) break;
240 
241  parent = file;
242  file = &res->file[i];
243 
244  /* fill in the file handle's fileid and superblock */
245  file->fh.fileid = res->getattr[i].info->fileid;
246  status = nfs41_superblock_for_fh(session,
247  &res->getattr[i].info->fsid, &parent->fh, file);
248  if (status)
249  break;
250 
251  /* add the file handle and attributes to the name cache */
252  memcpy(&res->getattr[i].info->attrmask,
253  &res->getattr[i].obj_attributes.attrmask, sizeof(bitmap4));
255  path, args->lookup[i].name, &res->file[i].fh,
256  res->getattr[i].info, NULL, OPEN_DELEGATE_NONE);
257 
258  if (i == count-1) {
259  if (target_out)
260  *target_out = file;
261  if (info_out)
262  memcpy(info_out, res->getattr[i].info, sizeof(nfs41_file_info));
263  } else if (i == count-2) {
264  if (parent_out)
265  *parent_out = file;
266  }
267  }
268 out:
269  return map_lookup_error(status, i == count-1);
270 }
uint64_t fileid
Definition: nfs41_types.h:55
GLuint GLuint GLsizei count
Definition: gl.h:1545
Definition: match.c:390
int nfs41_superblock_for_fh(IN nfs41_session *session, IN const nfs41_fsid *fsid, IN const nfs41_fh *parent OPTIONAL, OUT nfs41_path_fh *file)
bool_t last_component(IN const char *path, IN const char *path_end, OUT nfs41_component *component)
Definition: util.c:317
GLenum GLclampf GLint i
Definition: glfuncs.h:14
static __inline struct nfs41_name_cache * session_name_cache(IN nfs41_session *session)
Definition: name_cache.h:34
int nfs41_name_cache_insert(IN struct nfs41_name_cache *cache, IN const char *path, IN const nfs41_component *name, IN OPTIONAL const nfs41_fh *fh, IN OPTIONAL const nfs41_file_info *info, IN OPTIONAL const change_info4 *cinfo, IN enum open_delegation_type4 delegation)
Definition: name_cache.c:923
smooth NULL
Definition: ftsmooth.c:416
unsigned int dir
Definition: maze.c:112
r parent
Definition: btrfs.c:2644
const char file[]
Definition: icontest.c:11
static FILE * out
Definition: regtests2xml.c:44
static int lookup_rpc(IN nfs41_session *session, IN nfs41_path_fh *dir, IN uint32_t component_count, IN nfs41_lookup_component_args *args, OUT nfs41_lookup_component_res *res)
Definition: lookup.c:107
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
nfs41_component name
Definition: nfs41_types.h:61
Definition: services.c:325
UINT32 uint32_t
Definition: types.h:75
static int map_lookup_error(int status, bool_t last_component)
Definition: lookup.c:151
Definition: name.c:36
GLuint res
Definition: glext.h:9613
static SERVICE_STATUS status
Definition: service.c:31
void path_fh_copy(OUT nfs41_path_fh *dst, IN const nfs41_path_fh *src)
Definition: util.c:364

◆ server_lookup_loop()

static int server_lookup_loop ( IN nfs41_session session,
IN OPTIONAL nfs41_path_fh parent_in,
IN nfs41_abs_path path,
IN const char path_pos,
IN struct lookup_referral referral,
OUT OPTIONAL nfs41_path_fh parent_out,
OUT OPTIONAL nfs41_path_fh target_out,
OUT OPTIONAL nfs41_file_info info_out 
)
static

Definition at line 298 of file lookup.c.

Referenced by nfs41_lookup().

307 {
311  const char *path_end;
312  const uint32_t max_components = max_lookup_components(session);
313  uint32_t count;
314  int status = NO_ERROR;
315 
316  init_component_args(&args, &res, path, referral);
317  parent = NULL;
318  target = NULL;
319 
320  path_end = path->path + path->len;
321  dir = parent_in ? parent_in : &res.root;
322 
323  while (get_component_array(&path_pos, path_end,
324  max_components, res.file, &count)) {
325 
326  status = server_lookup(session, dir, path->path, path_end, count,
327  &args, &res, &parent, &target, info_out);
328 
329  if (status == ERROR_REPARSE) {
330  /* copy the component name of the symlink */
331  if (parent_out && parent) {
332  const ptrdiff_t offset = parent->name.name - path->path;
333  parent_out->name.name = parent_out->path->path + offset;
334  parent_out->name.len = parent->name.len;
335  }
336  goto out_parent;
337  }
338  if (status == ERROR_FILE_NOT_FOUND && is_last_component(path_pos, path_end))
339  goto out_parent;
340  if (status)
341  goto out;
342 
343  dir = target;
344  }
345 
346  if (dir == &res.root && (target_out || info_out)) {
347  /* didn't get any components, so we just need the root */
348  status = server_lookup(session, dir, path->path, path_end,
349  0, &args, &res, &parent, &target, info_out);
350  if (status)
351  goto out;
352  }
353 
354  if (target_out && target) fh_copy(&target_out->fh, &target->fh);
355 out_parent:
356  if (parent_out && parent) fh_copy(&parent_out->fh, &parent->fh);
357 out:
358  return status;
359 }
static uint32_t max_lookup_components(IN const nfs41_session *session)
Definition: lookup.c:272
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLintptr offset
Definition: glext.h:5920
nfs41_path_fh root
Definition: lookup.c:62
static void init_component_args(IN nfs41_lookup_component_args *args, IN nfs41_lookup_component_res *res, IN nfs41_abs_path *path, IN struct lookup_referral *referral)
Definition: lookup.c:72
#define NO_ERROR
Definition: dderror.h:5
Definition: match.c:390
static int server_lookup(IN nfs41_session *session, IN nfs41_path_fh *dir, IN const char *path, IN const char *path_end, IN uint32_t count, IN nfs41_lookup_component_args *args, IN nfs41_lookup_component_res *res, OUT OPTIONAL nfs41_path_fh **parent_out, OUT OPTIONAL nfs41_path_fh **target_out, OUT OPTIONAL nfs41_file_info *info_out)
Definition: lookup.c:163
smooth NULL
Definition: ftsmooth.c:416
unsigned int dir
Definition: maze.c:112
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
const char * name
Definition: nfs41_types.h:48
r parent
Definition: btrfs.c:2644
static FILE * out
Definition: regtests2xml.c:44
static uint32_t get_component_array(IN OUT const char **path_pos, IN const char *path_end, IN uint32_t max_components, OUT nfs41_path_fh *components, OUT uint32_t *component_count)
Definition: lookup.c:279
void fh_copy(OUT nfs41_fh *dst, IN const nfs41_fh *src)
Definition: util.c:354
#define ERROR_REPARSE
Definition: winerror.h:522
nfs41_component name
Definition: nfs41_types.h:61
Definition: services.c:325
__kernel_ptrdiff_t ptrdiff_t
Definition: linux.h:247
UINT32 uint32_t
Definition: types.h:75
bool_t is_last_component(IN const char *path, IN const char *path_end)
Definition: util.c:330
nfs41_path_fh file[MAX_LOOKUP_COMPONENTS]
Definition: lookup.c:63
GLuint res
Definition: glext.h:9613
GLenum target
Definition: glext.h:7315
unsigned short len
Definition: nfs41_types.h:49
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97