ReactOS 0.4.15-dev-5666-gc548b97
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.

◆ LULVL

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

Definition at line 33 of file lookup.c.

◆ MAX_LOOKUP_COMPONENTS

#define MAX_LOOKUP_COMPONENTS   8

Definition at line 36 of file lookup.c.

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.

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
295 return i;
296}
bool_t next_component(IN const char *path, IN const char *path_end, OUT nfs41_component *component)
Definition: util.c:305
unsigned int component_count
UINT32 uint32_t
Definition: types.h:75
GLenum GLenum GLuint components
Definition: glext.h:9620
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
Definition: name.c:39

Referenced by server_lookup_loop().

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

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}
#define MAX_LOOKUP_COMPONENTS
Definition: lookup.c:36
GLuint res
Definition: glext.h:9613
@ FATTR4_WORD0_HIDDEN
Definition: nfs41_const.h:237
@ FATTR4_WORD1_TIME_CREATE
Definition: nfs41_const.h:262
@ FATTR4_WORD1_MODE
Definition: nfs41_const.h:245
@ FATTR4_WORD1_TIME_MODIFY
Definition: nfs41_const.h:265
@ FATTR4_WORD0_ARCHIVE
Definition: nfs41_const.h:227
@ FATTR4_WORD1_TIME_ACCESS
Definition: nfs41_const.h:259
@ FATTR4_WORD0_TYPE
Definition: nfs41_const.h:208
@ FATTR4_WORD1_SYSTEM
Definition: nfs41_const.h:258
@ FATTR4_WORD0_CHANGE
Definition: nfs41_const.h:210
@ FATTR4_WORD1_NUMLINKS
Definition: nfs41_const.h:247
@ FATTR4_WORD0_FILEID
Definition: nfs41_const.h:232
@ FATTR4_WORD0_SIZE
Definition: nfs41_const.h:211
@ FATTR4_WORD0_FSID
Definition: nfs41_const.h:215
#define NFS4_OPAQUE_LIMIT
Definition: nfs41_const.h:31
Definition: match.c:390

Referenced by server_lookup_loop().

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

113{
114 int status;
115 uint32_t i;
116 nfs41_compound compound;
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
143 if (status)
144 goto out;
145
146 compound_error(status = compound.res.status);
147out:
148 return status;
149}
unsigned int dir
Definition: maze.c:112
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
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)
int compound_encode_send_decode(nfs41_session *session, nfs41_compound *compound, bool_t try_recovery)
void compound_add_op(nfs41_compound *compound, uint32_t opnum, void *arg, void *res)
int compound_error(int status)
@ OP_GETFH
Definition: nfs41_ops.h:38
@ OP_PUTROOTFH
Definition: nfs41_ops.h:52
@ OP_GETATTR
Definition: nfs41_ops.h:37
@ OP_SEQUENCE
Definition: nfs41_ops.h:83
@ OP_PUTFH
Definition: nfs41_ops.h:50
@ OP_LOOKUP
Definition: nfs41_ops.h:43
static FILE * out
Definition: regtests2xml.c:44
nfs41_compound_res res
Definition: ps.c:97

Referenced by server_lookup().

◆ map_lookup_error()

static int map_lookup_error ( int  status,
bool_t  last_component 
)
static

Definition at line 151 of file lookup.c.

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

Referenced by server_lookup().

◆ max_lookup_components()

static uint32_t max_lookup_components ( IN const nfs41_session session)
static

Definition at line 272 of file lookup.c.

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

Referenced by server_lookup_loop().

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

432{
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 }
473 } else {
474 /* start with PUTROOTFH */
476 }
477
479 &path, path_pos, &referral, parent_out, target_out, info_out);
480
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 */
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 }
505out:
506 dprintf(LULVL, "<-- nfs41_lookup() returning %d\n", status);
507 return status;
508}
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
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
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
#define LULVL
Definition: lookup.c:33
void abs_path_copy(OUT nfs41_abs_path *dst, IN const nfs41_abs_path *src)
Definition: util.c:338
void path_fh_copy(OUT nfs41_path_fh *dst, IN const nfs41_path_fh *src)
Definition: util.c:364
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
#define NO_ERROR
Definition: dderror.h:5
int32_t bool_t
Definition: types.h:101
VOID WINAPI ReleaseSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:89
VOID WINAPI AcquireSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:61
VOID WINAPI InitializeSRWLock(PSRWLOCK Lock)
Definition: sync.c:75
r parent
Definition: btrfs.c:3010
GLenum target
Definition: glext.h:7315
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
static __inline struct nfs41_name_cache * session_name_cache(IN nfs41_session *session)
Definition: name_cache.h:34
#define dprintf
Definition: regdump.c:33
static void server_start(server_params *par)
Definition: sock.c:521
Definition: cache.c:49

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

◆ referral_locations_free()

static void referral_locations_free ( IN fs_locations4 locations)
static

Definition at line 362 of file lookup.c.

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
GLsizei const GLint * locations
Definition: glext.h:10542

Referenced by referral_resolve().

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

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",
393 goto out;
394 }
395
396 /* mount the first location available */
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;
419out:
421 return status;
422}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
static void referral_locations_free(IN fs_locations4 *locations)
Definition: lookup.c:362
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
#define FAILED(hr)
Definition: intsafe.h:51
#define location(file, line)
Definition: kmtest.h:18
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
#define NFS41_MAX_PATH_LEN
Definition: nfs41_const.h:46
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
static FILE * client
Definition: client.c:41
STRSAFEAPI StringCchCatA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:320
STRSAFEAPI StringCchCopyA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:145
char * name
Definition: compiler.c:66
#define ERROR_FILENAME_EXCED_RANGE
Definition: winerror.h:263

Referenced by nfs41_lookup().

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

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
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;
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;
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 }
268out:
269 return map_lookup_error(status, i == count-1);
270}
static int map_lookup_error(int status, bool_t last_component)
Definition: lookup.c:151
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
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
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
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)
@ OPEN_DELEGATE_NONE
Definition: nfs41_ops.h:586
Definition: fci.c:127
char name[1]
Definition: fci.c:135

Referenced by server_lookup_loop().

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

307{
311 const char *path_end;
312 const uint32_t max_components = max_lookup_components(session);
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);
355out_parent:
356 if (parent_out && parent) fh_copy(&parent_out->fh, &parent->fh);
357out:
358 return status;
359}
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
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
static uint32_t max_lookup_components(IN const nfs41_session *session)
Definition: lookup.c:272
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
bool_t is_last_component(IN const char *path, IN const char *path_end)
Definition: util.c:330
void fh_copy(OUT nfs41_fh *dst, IN const nfs41_fh *src)
Definition: util.c:354
__kernel_ptrdiff_t ptrdiff_t
Definition: linux.h:247
GLintptr offset
Definition: glext.h:5920

Referenced by nfs41_lookup().