ReactOS 0.4.15-dev-8393-g61b7fb9
name_cache.c File Reference
#include <windows.h>
#include <strsafe.h>
#include <time.h>
#include <assert.h>
#include "nfs41_ops.h"
#include "nfs41_compound.h"
#include "name_cache.h"
#include "util.h"
#include "tree.h"
#include "daemon_debug.h"
Include dependency graph for name_cache.c:

Go to the source code of this file.

Classes

struct  attr_cache_entry
 
struct  attr_cache
 
struct  name_cache_entry
 
struct  nfs41_name_cache
 

Macros

#define NAME_CACHE_EXPIRATION   20 /* TODO: get from configuration */
 
#define NAME_CACHE_MAX_SIZE   262144
 
#define ATTR_ENTRY_SIZE   sizeof(struct attr_cache_entry)
 
#define attr_entry(pos)   list_container(pos, struct attr_cache_entry, free_entry)
 
#define NAME_ENTRY_SIZE   sizeof(struct name_cache_entry)
 
#define name_entry(pos)   list_container(pos, struct name_cache_entry, exp_entry)
 
#define SIZE_PER_ENTRY   (ATTR_ENTRY_SIZE + NAME_ENTRY_SIZE)
 
#define NAME_CACHE_MAX_ENTRIES   (NAME_CACHE_MAX_SIZE / SIZE_PER_ENTRY)
 
#define MAX_PUTFH_PER_COMPOUND   16
 

Enumerations

enum  { NCLVL1 = 2 , NCLVL2 }
 

Functions

static __inline bool_t is_delegation (IN enum open_delegation_type4 type)
 
 RB_HEAD (attr_tree, attr_cache_entry)
 
int attr_cmp (struct attr_cache_entry *lhs, struct attr_cache_entry *rhs)
 
static int attr_cache_entry_create (IN struct attr_cache *cache, IN uint64_t fileid, OUT struct attr_cache_entry **entry_out)
 
static __inline void attr_cache_entry_free (IN struct attr_cache *cache, IN struct attr_cache_entry *entry)
 
static __inline void attr_cache_entry_ref (IN struct attr_cache *cache, IN struct attr_cache_entry *entry)
 
static __inline void attr_cache_entry_deref (IN struct attr_cache *cache, IN struct attr_cache_entry *entry)
 
static __inline int attr_cache_entry_expired (IN const struct attr_cache_entry *entry)
 
static int attr_cache_init (IN struct attr_cache *cache, IN uint32_t max_entries)
 
static void attr_cache_free (IN struct attr_cache *cache)
 
static struct attr_cache_entryattr_cache_search (IN struct attr_cache *cache, IN uint64_t fileid)
 
static int attr_cache_insert (IN struct attr_cache *cache, IN struct attr_cache_entry *entry)
 
static int attr_cache_find_or_create (IN struct attr_cache *cache, IN uint64_t fileid, OUT struct attr_cache_entry **entry_out)
 
static void attr_cache_update (IN struct attr_cache_entry *entry, IN const nfs41_file_info *info, IN enum open_delegation_type4 delegation)
 
static void copy_attrs (OUT nfs41_file_info *dst, IN const struct attr_cache_entry *src)
 
 RB_HEAD (name_tree, name_cache_entry)
 
int name_cmp (struct name_cache_entry *lhs, struct name_cache_entry *rhs)
 
static __inline bool_t name_cache_enabled (IN struct nfs41_name_cache *cache)
 
static __inline void name_cache_entry_rename (OUT struct name_cache_entry *entry, IN const nfs41_component *component)
 
static __inline void name_cache_remove (IN struct name_cache_entry *entry, IN struct name_cache_entry *parent)
 
static void name_cache_unlink_children_recursive (IN struct nfs41_name_cache *cache, IN struct name_cache_entry *parent)
 
static __inline void name_cache_unlink (IN struct nfs41_name_cache *cache, IN struct name_cache_entry *entry)
 
static int name_cache_entry_create (IN struct nfs41_name_cache *cache, IN const nfs41_component *component, OUT struct name_cache_entry **entry_out)
 
static void name_cache_entry_accessed (IN struct nfs41_name_cache *cache, IN struct name_cache_entry *entry)
 
static void name_cache_entry_updated (IN struct nfs41_name_cache *cache, IN struct name_cache_entry *entry)
 
static int name_cache_entry_update (IN struct nfs41_name_cache *cache, IN struct name_cache_entry *entry, IN OPTIONAL const nfs41_fh *fh, IN OPTIONAL const nfs41_file_info *info, IN enum open_delegation_type4 delegation)
 
static int name_cache_entry_changed (IN struct nfs41_name_cache *cache, IN struct name_cache_entry *entry, IN const change_info4 *cinfo)
 
static void name_cache_entry_invalidate (IN struct nfs41_name_cache *cache, IN struct name_cache_entry *entry)
 
static struct name_cache_entryname_cache_search (IN struct nfs41_name_cache *cache, IN struct name_cache_entry *parent, IN const nfs41_component *component)
 
static int entry_invis (IN struct name_cache_entry *entry, OUT OPTIONAL bool_t *is_negative)
 
static int name_cache_lookup (IN struct nfs41_name_cache *cache, IN bool_t skip_invis, IN const char *path, IN const char *path_end, OUT OPTIONAL const char **remaining_path_out, OUT OPTIONAL struct name_cache_entry **parent_out, OUT OPTIONAL struct name_cache_entry **target_out, OUT OPTIONAL bool_t *is_negative)
 
static int name_cache_insert (IN struct name_cache_entry *entry, IN struct name_cache_entry *parent)
 
static int name_cache_find_or_create (IN struct nfs41_name_cache *cache, IN struct name_cache_entry *parent, IN const nfs41_component *component, OUT struct name_cache_entry **target_out)
 
int nfs41_name_cache_create (OUT struct nfs41_name_cache **cache_out)
 
int nfs41_name_cache_free (IN struct nfs41_name_cache **cache_out)
 
static __inline void copy_fh (OUT nfs41_fh *dst, IN OPTIONAL const struct name_cache_entry *src)
 
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)
 
int nfs41_attr_cache_lookup (IN struct nfs41_name_cache *cache, IN uint64_t fileid, OUT nfs41_file_info *info_out)
 
int nfs41_attr_cache_update (IN struct nfs41_name_cache *cache, IN uint64_t fileid, IN const nfs41_file_info *info)
 
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)
 
int nfs41_name_cache_delegreturn (IN struct nfs41_name_cache *cache, IN uint64_t fileid, IN const char *path, IN const nfs41_component *name)
 
int nfs41_name_cache_remove (IN struct nfs41_name_cache *cache, IN const char *path, IN const nfs41_component *name, IN uint64_t fileid, IN const change_info4 *cinfo)
 
int nfs41_name_cache_rename (IN struct nfs41_name_cache *cache, IN const char *src_path, IN const nfs41_component *src_name, IN const change_info4 *src_cinfo, IN const char *dst_path, IN const nfs41_component *dst_name, IN const change_info4 *dst_cinfo)
 
static bool_t get_path_fhs (IN struct nfs41_name_cache *cache, IN nfs41_abs_path *path, IN OUT const char **path_pos, IN uint32_t max_components, OUT nfs41_path_fh *files, OUT uint32_t *count)
 
static int rpc_array_putfh (IN nfs41_session *session, IN nfs41_path_fh *files, IN uint32_t count, OUT uint32_t *valid_out)
 
static int delete_stale_component (IN struct nfs41_name_cache *cache, IN nfs41_session *session, IN const nfs41_abs_path *path, IN const nfs41_component *component)
 
static __inline uint32_t max_putfh_components (IN const nfs41_session *session)
 
int nfs41_name_cache_remove_stale (IN struct nfs41_name_cache *cache, IN nfs41_session *session, IN nfs41_abs_path *path)
 

Macro Definition Documentation

◆ attr_entry

#define attr_entry (   pos)    list_container(pos, struct attr_cache_entry, free_entry)

Definition at line 121 of file name_cache.c.

◆ ATTR_ENTRY_SIZE

#define ATTR_ENTRY_SIZE   sizeof(struct attr_cache_entry)

Definition at line 103 of file name_cache.c.

◆ MAX_PUTFH_PER_COMPOUND

#define MAX_PUTFH_PER_COMPOUND   16

Definition at line 1231 of file name_cache.c.

◆ NAME_CACHE_EXPIRATION

#define NAME_CACHE_EXPIRATION   20 /* TODO: get from configuration */

Definition at line 42 of file name_cache.c.

◆ NAME_CACHE_MAX_ENTRIES

#define NAME_CACHE_MAX_ENTRIES   (NAME_CACHE_MAX_SIZE / SIZE_PER_ENTRY)

Definition at line 750 of file name_cache.c.

◆ NAME_CACHE_MAX_SIZE

#define NAME_CACHE_MAX_SIZE   262144

Definition at line 45 of file name_cache.c.

◆ name_entry

#define name_entry (   pos)    list_container(pos, struct name_cache_entry, exp_entry)

Definition at line 399 of file name_cache.c.

◆ NAME_ENTRY_SIZE

#define NAME_ENTRY_SIZE   sizeof(struct name_cache_entry)

Definition at line 373 of file name_cache.c.

◆ SIZE_PER_ENTRY

#define SIZE_PER_ENTRY   (ATTR_ENTRY_SIZE + NAME_ENTRY_SIZE)

Definition at line 749 of file name_cache.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
NCLVL1 
NCLVL2 

Definition at line 36 of file name_cache.c.

36 {
37 NCLVL1 = 2,
38 NCLVL2
39};
@ NCLVL1
Definition: name_cache.c:37
@ NCLVL2
Definition: name_cache.c:38

Function Documentation

◆ attr_cache_entry_create()

static int attr_cache_entry_create ( IN struct attr_cache cache,
IN uint64_t  fileid,
OUT struct attr_cache_entry **  entry_out 
)
static

Definition at line 123 of file name_cache.c.

127{
128 struct attr_cache_entry *entry;
129 int status = NO_ERROR;
130
131 /* get the next entry from free_entries and remove it */
132 if (list_empty(&cache->free_entries)) {
134 goto out;
135 }
136 entry = attr_entry(cache->free_entries.next);
137 list_remove(&entry->free_entry);
138
139 entry->fileid = fileid;
140 entry->invalidated = FALSE;
141 entry->delegated = FALSE;
142 *entry_out = entry;
143out:
144 return status;
145}
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static int list_empty(struct list_entry *head)
Definition: list.h:58
#define NO_ERROR
Definition: dderror.h:5
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define FALSE
Definition: types.h:117
uint32_t entry
Definition: isohybrid.c:63
#define attr_entry(pos)
Definition: name_cache.c:121
static FILE * out
Definition: regtests2xml.c:44
Definition: name_cache.c:80
Definition: cache.c:49
Definition: ps.c:97

Referenced by attr_cache_find_or_create().

◆ attr_cache_entry_deref()

static __inline void attr_cache_entry_deref ( IN struct attr_cache cache,
IN struct attr_cache_entry entry 
)
static

Definition at line 166 of file name_cache.c.

169{
170 const uint32_t previous = entry->ref_count--;
171 dprintf(NCLVL2, "attr_cache_entry_deref(%llu) %u -> %u\n",
172 entry->fileid, previous, entry->ref_count);
173
174 if (entry->ref_count == 0)
176}
UINT32 uint32_t
Definition: types.h:75
static __inline void attr_cache_entry_free(IN struct attr_cache *cache, IN struct attr_cache_entry *entry)
Definition: name_cache.c:147
#define dprintf
Definition: regdump.c:33

Referenced by name_cache_entry_update(), name_cache_unlink(), and nfs41_name_cache_delegreturn().

◆ attr_cache_entry_expired()

static __inline int attr_cache_entry_expired ( IN const struct attr_cache_entry entry)
static

Definition at line 178 of file name_cache.c.

180{
181 return entry->invalidated ||
182 (!entry->delegated && time(NULL) > entry->expiration);
183}
#define NULL
Definition: types.h:112
__u16 time
Definition: mkdosfs.c:8

Referenced by entry_invis(), and nfs41_attr_cache_lookup().

◆ attr_cache_entry_free()

static __inline void attr_cache_entry_free ( IN struct attr_cache cache,
IN struct attr_cache_entry entry 
)
static

Definition at line 147 of file name_cache.c.

150{
151 dprintf(NCLVL1, "attr_cache_entry_free(%llu)\n", entry->fileid);
152 RB_REMOVE(attr_tree, &cache->head, entry);
153 /* add it back to free_entries */
154 list_add_tail(&cache->free_entries, &entry->free_entry);
155}
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
#define RB_REMOVE(name, x, y)
Definition: tree.h:725

Referenced by attr_cache_entry_deref(), and attr_cache_find_or_create().

◆ attr_cache_entry_ref()

static __inline void attr_cache_entry_ref ( IN struct attr_cache cache,
IN struct attr_cache_entry entry 
)
static

Definition at line 157 of file name_cache.c.

160{
161 const uint32_t previous = entry->ref_count++;
162 dprintf(NCLVL2, "attr_cache_entry_ref(%llu) %u -> %u\n",
163 entry->fileid, previous, entry->ref_count);
164}

Referenced by attr_cache_find_or_create(), and name_cache_entry_update().

◆ attr_cache_find_or_create()

static int attr_cache_find_or_create ( IN struct attr_cache cache,
IN uint64_t  fileid,
OUT struct attr_cache_entry **  entry_out 
)
static

Definition at line 244 of file name_cache.c.

248{
249 struct attr_cache_entry *entry;
250 int status = NO_ERROR;
251
252 dprintf(NCLVL1, "--> attr_cache_find_or_create(%llu)\n", fileid);
253
254 /* look for an existing entry */
255 entry = attr_cache_search(cache, fileid);
256 if (entry == NULL) {
257 /* create and insert */
259 if (status)
260 goto out;
261
263 if (status)
264 goto out_err_free;
265 }
266
267 /* take a reference on success */
269
270out:
271 *entry_out = entry;
272 dprintf(NCLVL1, "<-- attr_cache_find_or_create() returning %d\n",
273 status);
274 return status;
275
276out_err_free:
278 entry = NULL;
279 goto out;
280}
static __inline void attr_cache_entry_ref(IN struct attr_cache *cache, IN struct attr_cache_entry *entry)
Definition: name_cache.c:157
static int attr_cache_entry_create(IN struct attr_cache *cache, IN uint64_t fileid, OUT struct attr_cache_entry **entry_out)
Definition: name_cache.c:123
static struct attr_cache_entry * attr_cache_search(IN struct attr_cache *cache, IN uint64_t fileid)
Definition: name_cache.c:219
static int attr_cache_insert(IN struct attr_cache *cache, IN struct attr_cache_entry *entry)
Definition: name_cache.c:229

Referenced by name_cache_entry_update(), and nfs41_name_cache_insert().

◆ attr_cache_free()

static void attr_cache_free ( IN struct attr_cache cache)
static

Definition at line 210 of file name_cache.c.

212{
213 /* free the pool */
214 free(cache->pool);
215 cache->pool = NULL;
216 list_init(&cache->free_entries);
217}
static void list_init(struct list_entry *head)
Definition: list.h:51
#define free
Definition: debug_ros.c:5

Referenced by nfs41_name_cache_free().

◆ attr_cache_init()

static int attr_cache_init ( IN struct attr_cache cache,
IN uint32_t  max_entries 
)
static

Definition at line 186 of file name_cache.c.

189{
190 uint32_t i;
191 int status = NO_ERROR;
192
193 /* allocate a pool of entries */
194 cache->pool = calloc(max_entries, ATTR_ENTRY_SIZE);
195 if (cache->pool == NULL) {
197 goto out;
198 }
199
200 /* initialize the list of free entries */
201 list_init(&cache->free_entries);
202 for (i = 0; i < max_entries; i++) {
203 list_init(&cache->pool[i].free_entry);
204 list_add_tail(&cache->free_entries, &cache->pool[i].free_entry);
205 }
206out:
207 return status;
208}
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
#define ATTR_ENTRY_SIZE
Definition: name_cache.c:103
#define calloc
Definition: rosglue.h:14
DWORD WINAPI GetLastError(void)
Definition: except.c:1042

Referenced by nfs41_name_cache_create().

◆ attr_cache_insert()

static int attr_cache_insert ( IN struct attr_cache cache,
IN struct attr_cache_entry entry 
)
static

Definition at line 229 of file name_cache.c.

232{
233 int status = NO_ERROR;
234
235 dprintf(NCLVL2, "--> attr_cache_insert(%llu)\n", entry->fileid);
236
237 if (RB_INSERT(attr_tree, &cache->head, entry))
239
240 dprintf(NCLVL2, "<-- attr_cache_insert() returning %d\n", status);
241 return status;
242}
#define RB_INSERT(name, x, y)
Definition: tree.h:724
#define ERROR_FILE_EXISTS
Definition: winerror.h:165

Referenced by attr_cache_find_or_create().

◆ attr_cache_search()

static struct attr_cache_entry * attr_cache_search ( IN struct attr_cache cache,
IN uint64_t  fileid 
)
static

Definition at line 219 of file name_cache.c.

222{
223 /* find an entry that matches fileid */
224 struct attr_cache_entry tmp;
225 tmp.fileid = fileid;
226 return RB_FIND(attr_tree, &cache->head, &tmp);
227}
#define RB_FIND(name, x, y)
Definition: tree.h:726

Referenced by attr_cache_find_or_create(), nfs41_attr_cache_lookup(), nfs41_attr_cache_update(), nfs41_name_cache_delegreturn(), and nfs41_name_cache_remove().

◆ attr_cache_update()

static void attr_cache_update ( IN struct attr_cache_entry entry,
IN const nfs41_file_info info,
IN enum open_delegation_type4  delegation 
)
static

Definition at line 282 of file name_cache.c.

286{
287 /* update the attributes present in mask */
288 if (info->attrmask.count >= 1) {
289 if (info->attrmask.arr[0] & FATTR4_WORD0_TYPE)
290 entry->type = (unsigned char)(info->type & NFS_FTYPE_MASK);
291 if (info->attrmask.arr[0] & FATTR4_WORD0_CHANGE) {
292 entry->change = info->change;
293 /* revalidate whenever we get a change attribute */
294 entry->invalidated = 0;
295 entry->expiration = time(NULL) + NAME_CACHE_EXPIRATION;
296 }
297 if (info->attrmask.arr[0] & FATTR4_WORD0_SIZE)
298 entry->size = info->size;
299 if (info->attrmask.arr[0] & FATTR4_WORD0_HIDDEN)
300 entry->hidden = info->hidden;
301 if (info->attrmask.arr[0] & FATTR4_WORD0_ARCHIVE)
302 entry->archive = info->archive;
303 }
304 if (info->attrmask.count >= 2) {
305 if (info->attrmask.arr[1] & FATTR4_WORD1_MODE)
306 entry->mode = info->mode;
307 if (info->attrmask.arr[1] & FATTR4_WORD1_NUMLINKS)
308 entry->numlinks = info->numlinks;
309 if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_ACCESS) {
310 entry->time_access_s = info->time_access.seconds;
311 entry->time_access_ns = info->time_access.nseconds;
312 }
313 if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_CREATE) {
314 entry->time_create_s = info->time_create.seconds;
315 entry->time_create_ns = info->time_create.nseconds;
316 }
317 if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_MODIFY) {
318 entry->time_modify_s = info->time_modify.seconds;
319 entry->time_modify_ns = info->time_modify.nseconds;
320 }
321 if (info->attrmask.arr[1] & FATTR4_WORD1_SYSTEM)
322 entry->system = info->system;
323 }
324
325 if (is_delegation(delegation))
326 entry->delegated = TRUE;
327}
#define TRUE
Definition: types.h:120
unsigned char
Definition: typeof.h:29
#define NAME_CACHE_EXPIRATION
Definition: name_cache.c:42
static __inline bool_t is_delegation(IN enum open_delegation_type4 type)
Definition: name_cache.c:72
@ NFS_FTYPE_MASK
Definition: nfs41_const.h:304
@ 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_SIZE
Definition: nfs41_const.h:211
unsigned int count
Definition: notification.c:64

Referenced by name_cache_entry_update(), nfs41_attr_cache_update(), and nfs41_name_cache_insert().

◆ attr_cmp()

int attr_cmp ( struct attr_cache_entry lhs,
struct attr_cache_entry rhs 
)

Definition at line 113 of file name_cache.c.

114{
115 return lhs->fileid < rhs->fileid ? -1 : lhs->fileid > rhs->fileid;
116}

Referenced by VfdMakeFileDesc().

◆ copy_attrs()

static void copy_attrs ( OUT nfs41_file_info dst,
IN const struct attr_cache_entry src 
)
static

Definition at line 329 of file name_cache.c.

332{
333 dst->change = src->change;
334 dst->size = src->size;
335 dst->time_access.seconds = src->time_access_s;
336 dst->time_access.nseconds = src->time_access_ns;
337 dst->time_create.seconds = src->time_create_s;
338 dst->time_create.nseconds = src->time_create_ns;
339 dst->time_modify.seconds = src->time_modify_s;
340 dst->time_modify.nseconds = src->time_modify_ns;
341 dst->type = src->type;
342 dst->numlinks = src->numlinks;
343 dst->mode = src->mode;
344 dst->fileid = src->fileid;
345 dst->hidden = src->hidden;
346 dst->system = src->system;
347 dst->archive = src->archive;
348
349 dst->attrmask.count = 2;
350 dst->attrmask.arr[0] = FATTR4_WORD0_TYPE | FATTR4_WORD0_CHANGE
353 dst->attrmask.arr[1] = FATTR4_WORD1_MODE
357}
GLenum src
Definition: glext.h:6340
GLenum GLenum dst
Definition: glext.h:6340
@ FATTR4_WORD0_FILEID
Definition: nfs41_const.h:232

Referenced by nfs41_attr_cache_lookup(), and nfs41_name_cache_lookup().

◆ copy_fh()

static __inline void copy_fh ( OUT nfs41_fh dst,
IN OPTIONAL const struct name_cache_entry src 
)
static

Definition at line 814 of file name_cache.c.

817{
818 if (src)
819 fh_copy(dst, &src->fh);
820 else
821 dst->len = 0;
822}
void fh_copy(OUT nfs41_fh *dst, IN const nfs41_fh *src)
Definition: util.c:354

Referenced by nfs41_name_cache_lookup().

◆ delete_stale_component()

static int delete_stale_component ( IN struct nfs41_name_cache cache,
IN nfs41_session session,
IN const nfs41_abs_path path,
IN const nfs41_component component 
)
static

Definition at line 1327 of file name_cache.c.

1332{
1333 struct name_cache_entry *target;
1334 int status;
1335
1336 dprintf(NCLVL1, "--> delete_stale_component('%s')\n",
1337 component->name);
1338
1340
1341 status = name_cache_lookup(cache, 0, path->path,
1342 component->name + component->len, NULL, NULL, &target, NULL);
1343 if (status == NO_ERROR)
1345
1347
1348 dprintf(NCLVL1, "<-- delete_stale_component() returning %d\n", status);
1349 return status;
1350}
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:8
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:36
GLenum target
Definition: glext.h:7315
static __inline void name_cache_unlink(IN struct nfs41_name_cache *cache, IN struct name_cache_entry *entry)
Definition: name_cache.c:428
static int name_cache_lookup(IN struct nfs41_name_cache *cache, IN bool_t skip_invis, IN const char *path, IN const char *path_end, OUT OPTIONAL const char **remaining_path_out, OUT OPTIONAL struct name_cache_entry **parent_out, OUT OPTIONAL struct name_cache_entry **target_out, OUT OPTIONAL bool_t *is_negative)
Definition: name_cache.c:648
HANDLE lock
Definition: cache.c:52
Definition: name_cache.c:362
char component[NFS41_MAX_COMPONENT_LEN]
Definition: name_cache.c:363

Referenced by nfs41_name_cache_remove_stale().

◆ entry_invis()

static int entry_invis ( IN struct name_cache_entry entry,
OUT OPTIONAL bool_t is_negative 
)
static

Definition at line 624 of file name_cache.c.

627{
628 /* name entry timer expired? */
629 if (!list_empty(&entry->exp_entry) && time(NULL) > entry->expiration) {
630 dprintf(NCLVL2, "name_entry_expired('%s')\n", entry->component);
631 return 1;
632 }
633 /* negative lookup entry? */
634 if (entry->attributes == NULL) {
635 if (is_negative) *is_negative = 1;
636 dprintf(NCLVL2, "name_entry_negative('%s')\n", entry->component);
637 return 1;
638 }
639 /* attribute entry expired? */
640 if (attr_cache_entry_expired(entry->attributes)) {
641 dprintf(NCLVL2, "attr_entry_expired(%llu)\n",
642 entry->attributes->fileid);
643 return 1;
644 }
645 return 0;
646}
static __inline int attr_cache_entry_expired(IN const struct attr_cache_entry *entry)
Definition: name_cache.c:178

Referenced by get_path_fhs(), and name_cache_lookup().

◆ get_path_fhs()

static bool_t get_path_fhs ( IN struct nfs41_name_cache cache,
IN nfs41_abs_path path,
IN OUT const char **  path_pos,
IN uint32_t  max_components,
OUT nfs41_path_fh files,
OUT uint32_t count 
)
static

Definition at line 1233 of file name_cache.c.

1240{
1241 struct name_cache_entry *target;
1242 const char *path_end = path->path + path->len;
1244 uint32_t i;
1245 int status;
1246
1247 *count = 0;
1248
1250
1251 /* look up the parent of the first component */
1252 status = name_cache_lookup(cache, 1, path->path,
1253 *path_pos, NULL, NULL, &target, NULL);
1254 if (status)
1255 goto out_unlock;
1256
1257 for (i = 0; i < max_components; i++) {
1258 files[i].path = path;
1259 name = &files[i].name;
1260
1261 if (!next_component(*path_pos, path_end, name))
1262 break;
1263 *path_pos = name->name + name->len;
1264
1266 if (target == NULL || entry_invis(target, NULL)) {
1267 if (is_last_component(name->name, path_end))
1269 else
1271 goto out_unlock;
1272 }
1273 /* make copies for use outside of cache->lock */
1274 fh_copy(&files[i].fh, &target->fh);
1275 (*count)++;
1276 }
1277
1278out_unlock:
1280 return *count && status == 0;
1281}
bool_t is_last_component(IN const char *path, IN const char *path_end)
Definition: util.c:330
bool_t next_component(IN const char *path, IN const char *path_end, OUT nfs41_component *component)
Definition: util.c:305
VOID WINAPI ReleaseSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:43
VOID WINAPI AcquireSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:15
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static int entry_invis(IN struct name_cache_entry *entry, OUT OPTIONAL bool_t *is_negative)
Definition: name_cache.c:624
static struct name_cache_entry * name_cache_search(IN struct nfs41_name_cache *cache, IN struct name_cache_entry *parent, IN const nfs41_component *component)
Definition: name_cache.c:601
unsigned char fh[NFS4_FHSIZE]
Definition: nfs41_types.h:53
nfs41_fh fh
Definition: name_cache.c:364
Definition: name.c:39
WCHAR * name
Definition: name.c:42
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106

Referenced by nfs41_name_cache_remove_stale().

◆ is_delegation()

static __inline bool_t is_delegation ( IN enum open_delegation_type4  type)
static

Definition at line 72 of file name_cache.c.

74{
76}
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
@ OPEN_DELEGATE_READ
Definition: nfs41_ops.h:587
@ OPEN_DELEGATE_WRITE
Definition: nfs41_ops.h:588

Referenced by attr_cache_update(), name_cache_entry_update(), and nfs41_name_cache_insert().

◆ max_putfh_components()

static __inline uint32_t max_putfh_components ( IN const nfs41_session session)
static

Definition at line 1352 of file name_cache.c.

1354{
1355 const uint32_t comps = session->fore_chan_attrs.ca_maxoperations - 1;
1356 return min(comps, MAX_PUTFH_PER_COMPOUND);
1357}
#define min(a, b)
Definition: monoChain.cc:55
#define MAX_PUTFH_PER_COMPOUND
Definition: name_cache.c:1231

Referenced by nfs41_name_cache_remove_stale().

◆ name_cache_enabled()

◆ name_cache_entry_accessed()

static void name_cache_entry_accessed ( IN struct nfs41_name_cache cache,
IN struct name_cache_entry entry 
)
static

Definition at line 492 of file name_cache.c.

495{
496 /* move the entry to the front of cache->exp_entries, then do
497 * the same for its parents, which are more costly to evict */
498 while (entry) {
499 /* if entry is delegated, it won't be in the list */
500 if (!list_empty(&entry->exp_entry)) {
501 list_remove(&entry->exp_entry);
502 list_add_head(&cache->exp_entries, &entry->exp_entry);
503 }
504 if (entry == entry->parent)
505 break;
506 entry = entry->parent;
507 }
508}
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76

Referenced by name_cache_entry_updated().

◆ name_cache_entry_changed()

static int name_cache_entry_changed ( IN struct nfs41_name_cache cache,
IN struct name_cache_entry entry,
IN const change_info4 cinfo 
)
static

Definition at line 563 of file name_cache.c.

567{
568 if (entry->attributes == NULL)
569 return FALSE;
570
571 if (cinfo->after == entry->attributes->change ||
572 (cinfo->atomic && cinfo->before == entry->attributes->change)) {
573 entry->attributes->change = cinfo->after;
575 dprintf(NCLVL1, "name_cache_entry_changed('%s') has not changed. "
576 "updated change=%llu\n", entry->component,
577 entry->attributes->change);
578 return FALSE;
579 } else {
580 dprintf(NCLVL1, "name_cache_entry_changed('%s') has changed: was %llu, "
581 "got before=%llu\n", entry->component,
582 entry->attributes->change, cinfo->before);
583 return TRUE;
584 }
585}
static void name_cache_entry_updated(IN struct nfs41_name_cache *cache, IN struct name_cache_entry *entry)
Definition: name_cache.c:510

Referenced by nfs41_name_cache_insert(), nfs41_name_cache_remove(), and nfs41_name_cache_rename().

◆ name_cache_entry_create()

static int name_cache_entry_create ( IN struct nfs41_name_cache cache,
IN const nfs41_component component,
OUT struct name_cache_entry **  entry_out 
)
static

Definition at line 459 of file name_cache.c.

463{
464 int status = NO_ERROR;
465 struct name_cache_entry *entry;
466
467 if (cache->entries >= cache->max_entries) {
468 /* scavenge the oldest entry */
469 if (list_empty(&cache->exp_entries)) {
471 goto out;
472 }
473 entry = name_entry(cache->exp_entries.prev);
475
476 dprintf(NCLVL2, "name_cache_entry_create('%s') scavenged 0x%p\n",
477 component->name, entry);
478 } else {
479 /* take the next entry in the pool and add it to exp_entries */
480 entry = &cache->pool[cache->entries++];
481 list_init(&entry->exp_entry);
482 list_add_tail(&cache->exp_entries, &entry->exp_entry);
483 }
484
486
487 *entry_out = entry;
488out:
489 return status;
490}
static __inline void name_cache_entry_rename(OUT struct name_cache_entry *entry, IN const nfs41_component *component)
Definition: name_cache.c:407
#define name_entry(pos)
Definition: name_cache.c:399

Referenced by name_cache_find_or_create(), and nfs41_name_cache_insert().

◆ name_cache_entry_invalidate()

static void name_cache_entry_invalidate ( IN struct nfs41_name_cache cache,
IN struct name_cache_entry entry 
)
static

Definition at line 587 of file name_cache.c.

590{
591 dprintf(NCLVL1, "name_cache_entry_invalidate('%s')\n", entry->component);
592
593 if (entry->attributes) {
594 /* flag attributes so that entry_invis() will return true
595 * if another entry attempts to use them */
596 entry->attributes->invalidated = 1;
597 }
599}

Referenced by nfs41_name_cache_insert(), nfs41_name_cache_remove(), and nfs41_name_cache_rename().

◆ name_cache_entry_rename()

static __inline void name_cache_entry_rename ( OUT struct name_cache_entry entry,
IN const nfs41_component component 
)
static

Definition at line 407 of file name_cache.c.

410{
412 component->name, component->len);
413 entry->component_len = component->len;
414}
#define StringCchCopyNA
#define NFS41_MAX_COMPONENT_LEN
Definition: nfs41_const.h:45
char * name
Definition: compiler.c:66

Referenced by name_cache_entry_create(), and nfs41_name_cache_rename().

◆ name_cache_entry_update()

static int name_cache_entry_update ( IN struct nfs41_name_cache cache,
IN struct name_cache_entry entry,
IN OPTIONAL const nfs41_fh fh,
IN OPTIONAL const nfs41_file_info info,
IN enum open_delegation_type4  delegation 
)
static

Definition at line 519 of file name_cache.c.

525{
526 int status = NO_ERROR;
527
528 if (fh)
529 fh_copy(&entry->fh, fh);
530 else
531 entry->fh.len = 0;
532
533 if (info) {
534 if (entry->attributes == NULL) {
535 /* negative -> positive entry, create the attributes */
537 info->fileid, &entry->attributes);
538 if (status)
539 goto out;
540 }
541
542 attr_cache_update(entry->attributes, info, delegation);
543
544 /* hold a reference as long as we have the delegation */
545 if (is_delegation(delegation)) {
546 attr_cache_entry_ref(&cache->attributes, entry->attributes);
547 cache->delegations++;
548 }
549
550 /* keep the entry from expiring */
551 if (entry->attributes->delegated)
552 list_remove(&entry->exp_entry);
553 } else if (entry->attributes) {
554 /* positive -> negative entry, deref the attributes */
555 attr_cache_entry_deref(&cache->attributes, entry->attributes);
556 entry->attributes = NULL;
557 }
559out:
560 return status;
561}
static void attr_cache_update(IN struct attr_cache_entry *entry, IN const nfs41_file_info *info, IN enum open_delegation_type4 delegation)
Definition: name_cache.c:282
static __inline void attr_cache_entry_deref(IN struct attr_cache *cache, IN struct attr_cache_entry *entry)
Definition: name_cache.c:166
static int attr_cache_find_or_create(IN struct attr_cache *cache, IN uint64_t fileid, OUT struct attr_cache_entry **entry_out)
Definition: name_cache.c:244

Referenced by nfs41_name_cache_insert(), nfs41_name_cache_remove(), and nfs41_name_cache_rename().

◆ name_cache_entry_updated()

static void name_cache_entry_updated ( IN struct nfs41_name_cache cache,
IN struct name_cache_entry entry 
)
static

Definition at line 510 of file name_cache.c.

513{
514 /* update the expiration timer */
515 entry->expiration = time(NULL) + cache->expiration;
517}
static void name_cache_entry_accessed(IN struct nfs41_name_cache *cache, IN struct name_cache_entry *entry)
Definition: name_cache.c:492

Referenced by name_cache_entry_changed(), name_cache_entry_update(), and nfs41_name_cache_delegreturn().

◆ name_cache_find_or_create()

static int name_cache_find_or_create ( IN struct nfs41_name_cache cache,
IN struct name_cache_entry parent,
IN const nfs41_component component,
OUT struct name_cache_entry **  target_out 
)
static

Definition at line 712 of file name_cache.c.

717{
718 int status = NO_ERROR;
719
720 dprintf(NCLVL1, "--> name_cache_find_or_create('%.*s' under '%s')\n",
721 component->len, component->name, parent->component);
722
723 *target_out = name_cache_search(cache, parent, component);
724 if (*target_out)
725 goto out;
726
727 status = name_cache_entry_create(cache, component, target_out);
728 if (status)
729 goto out;
730
731 status = name_cache_insert(*target_out, parent);
732 if (status)
733 goto out_err;
734
735out:
736 dprintf(NCLVL1, "<-- name_cache_find_or_create() returning %d\n",
737 status);
738 return status;
739
740out_err:
741 *target_out = NULL;
742 goto out;
743}
r parent
Definition: btrfs.c:3010
static int name_cache_entry_create(IN struct nfs41_name_cache *cache, IN const nfs41_component *component, OUT struct name_cache_entry **entry_out)
Definition: name_cache.c:459
static int name_cache_insert(IN struct name_cache_entry *entry, IN struct name_cache_entry *parent)
Definition: name_cache.c:696

Referenced by nfs41_name_cache_insert(), and nfs41_name_cache_rename().

◆ name_cache_insert()

static int name_cache_insert ( IN struct name_cache_entry entry,
IN struct name_cache_entry parent 
)
static

Definition at line 696 of file name_cache.c.

699{
700 int status = NO_ERROR;
701
702 dprintf(NCLVL2, "--> name_cache_insert('%s')\n", entry->component);
703
704 if (RB_INSERT(name_tree, &parent->rbchildren, entry))
706 entry->parent = parent;
707
708 dprintf(NCLVL2, "<-- name_cache_insert() returning %u\n", status);
709 return status;
710}

Referenced by name_cache_find_or_create(), and nfs41_name_cache_rename().

◆ name_cache_lookup()

static int name_cache_lookup ( IN struct nfs41_name_cache cache,
IN bool_t  skip_invis,
IN const char path,
IN const char path_end,
OUT OPTIONAL const char **  remaining_path_out,
OUT OPTIONAL struct name_cache_entry **  parent_out,
OUT OPTIONAL struct name_cache_entry **  target_out,
OUT OPTIONAL bool_t is_negative 
)
static

Definition at line 648 of file name_cache.c.

657{
660 const char *path_pos;
661 int status = NO_ERROR;
662
663 dprintf(NCLVL1, "--> name_cache_lookup('%s')\n", path);
664
665 parent = NULL;
666 target = cache->root;
667 component.name = path_pos = path;
668
669 if (target == NULL || (skip_invis && entry_invis(target, is_negative))) {
670 target = NULL;
672 goto out;
673 }
674
675 while (next_component(path_pos, path_end, &component)) {
676 parent = target;
678 path_pos = component.name + component.len;
679 if (target == NULL || (skip_invis && entry_invis(target, is_negative))) {
680 target = NULL;
681 if (is_last_component(component.name, path_end))
683 else
685 break;
686 }
687 }
688out:
689 if (remaining_path_out) *remaining_path_out = component.name;
690 if (parent_out) *parent_out = parent;
691 if (target_out) *target_out = target;
692 dprintf(NCLVL1, "<-- name_cache_lookup() returning %d\n", status);
693 return status;
694}

Referenced by delete_stale_component(), get_path_fhs(), nfs41_name_cache_delegreturn(), nfs41_name_cache_insert(), nfs41_name_cache_lookup(), nfs41_name_cache_remove(), and nfs41_name_cache_rename().

◆ name_cache_remove()

static __inline void name_cache_remove ( IN struct name_cache_entry entry,
IN struct name_cache_entry parent 
)
static

Definition at line 416 of file name_cache.c.

419{
420 RB_REMOVE(name_tree, &parent->rbchildren, entry);
421 entry->parent = NULL;
422}

Referenced by name_cache_unlink(), and nfs41_name_cache_rename().

◆ name_cache_search()

static struct name_cache_entry * name_cache_search ( IN struct nfs41_name_cache cache,
IN struct name_cache_entry parent,
IN const nfs41_component component 
)
static

Definition at line 601 of file name_cache.c.

605{
606 struct name_cache_entry tmp, *entry;
607
608 dprintf(NCLVL2, "--> name_cache_search('%.*s' under '%s')\n",
609 component->len, component->name, parent->component);
610
612 component->name, component->len);
613 tmp.component_len = component->len;
614
615 entry = RB_FIND(name_tree, &parent->rbchildren, &tmp);
616 if (entry)
617 dprintf(NCLVL2, "<-- name_cache_search() "
618 "found existing entry 0x%p\n", entry);
619 else
620 dprintf(NCLVL2, "<-- name_cache_search() returning NULL\n");
621 return entry;
622}

Referenced by get_path_fhs(), name_cache_find_or_create(), name_cache_lookup(), and nfs41_name_cache_rename().

◆ name_cache_unlink()

static __inline void name_cache_unlink ( IN struct nfs41_name_cache cache,
IN struct name_cache_entry entry 
)
static

Definition at line 428 of file name_cache.c.

431{
432 /* remove the entry from the tree */
433 if (entry->parent)
434 name_cache_remove(entry, entry->parent);
435 else if (entry == cache->root)
436 cache->root = NULL;
437
438 /* unlink all of its children */
440 /* release the cached attributes */
441 if (entry->attributes) {
442 attr_cache_entry_deref(&cache->attributes, entry->attributes);
443 entry->attributes = NULL;
444 }
445 /* move it to the end of exp_entries for scavenging */
446 list_remove(&entry->exp_entry);
447 list_add_tail(&cache->exp_entries, &entry->exp_entry);
448}
static __inline void name_cache_remove(IN struct name_cache_entry *entry, IN struct name_cache_entry *parent)
Definition: name_cache.c:416
static void name_cache_unlink_children_recursive(IN struct nfs41_name_cache *cache, IN struct name_cache_entry *parent)
Definition: name_cache.c:450

Referenced by delete_stale_component(), name_cache_entry_create(), name_cache_entry_invalidate(), name_cache_unlink_children_recursive(), and nfs41_name_cache_rename().

◆ name_cache_unlink_children_recursive()

static void name_cache_unlink_children_recursive ( IN struct nfs41_name_cache cache,
IN struct name_cache_entry parent 
)
static

Definition at line 450 of file name_cache.c.

453{
454 struct name_cache_entry *entry, *tmp;
455 RB_FOREACH_SAFE(entry, name_tree, &parent->rbchildren, tmp)
457}
#define RB_FOREACH_SAFE(x, name, head, y)
Definition: tree.h:743

Referenced by name_cache_unlink(), nfs41_name_cache_remove(), and nfs41_name_cache_rename().

◆ name_cmp()

int name_cmp ( struct name_cache_entry lhs,
struct name_cache_entry rhs 
)

Definition at line 375 of file name_cache.c.

376{
377 const int diff = rhs->component_len - lhs->component_len;
378 return diff ? diff : strncmp(lhs->component, rhs->component, lhs->component_len);
379}
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534

◆ nfs41_attr_cache_lookup()

int nfs41_attr_cache_lookup ( IN struct nfs41_name_cache cache,
IN uint64_t  fileid,
OUT nfs41_file_info info_out 
)

Definition at line 859 of file name_cache.c.

863{
864 struct attr_cache_entry *entry;
865 int status = NO_ERROR;
866
867 dprintf(NCLVL1, "--> nfs41_attr_cache_lookup(%llu)\n", fileid);
868
870
873 goto out_unlock;
874 }
875
876 entry = attr_cache_search(&cache->attributes, fileid);
879 goto out_unlock;
880 }
881
882 copy_attrs(info_out, entry);
883
884out_unlock:
886
887 dprintf(NCLVL1, "<-- nfs41_attr_cache_lookup() returning %d\n", status);
888 return status;
889}
#define ERROR_NOT_SUPPORTED
Definition: compat.h:100
static void copy_attrs(OUT nfs41_file_info *dst, IN const struct attr_cache_entry *src)
Definition: name_cache.c:329
static __inline bool_t name_cache_enabled(IN struct nfs41_name_cache *cache)
Definition: name_cache.c:401

Referenced by nfs41_cached_getattr(), and nfs41_delegation_getattr().

◆ nfs41_attr_cache_update()

int nfs41_attr_cache_update ( IN struct nfs41_name_cache cache,
IN uint64_t  fileid,
IN const nfs41_file_info info 
)

Definition at line 891 of file name_cache.c.

895{
896 struct attr_cache_entry *entry;
897 int status = NO_ERROR;
898
899 dprintf(NCLVL1, "--> nfs41_attr_cache_update(%llu)\n", fileid);
900
902
905 goto out_unlock;
906 }
907
908 entry = attr_cache_search(&cache->attributes, fileid);
909 if (entry == NULL) {
911 goto out_unlock;
912 }
913
915
916out_unlock:
918
919 dprintf(NCLVL1, "<-- nfs41_attr_cache_update() returning %d\n", status);
920 return status;
921}
@ OPEN_DELEGATE_NONE
Definition: nfs41_ops.h:586

Referenced by nfs41_close(), nfs41_commit(), nfs41_create(), nfs41_getattr(), nfs41_link(), nfs41_remove(), nfs41_rename(), nfs41_setattr(), nfs41_write(), open_update_cache(), and pnfs_rpc_layoutcommit().

◆ nfs41_name_cache_create()

int nfs41_name_cache_create ( OUT struct nfs41_name_cache **  cache_out)

Definition at line 752 of file name_cache.c.

754{
755 struct nfs41_name_cache *cache;
756 int status = NO_ERROR;
757
758 dprintf(NCLVL1, "nfs41_name_cache_create()\n");
759
760 /* allocate the cache */
761 cache = calloc(1, sizeof(struct nfs41_name_cache));
762 if (cache == NULL) {
764 goto out;
765 }
766
767 list_init(&cache->exp_entries);
768 cache->expiration = NAME_CACHE_EXPIRATION;
769 cache->max_entries = NAME_CACHE_MAX_ENTRIES;
770 cache->max_delegations = NAME_CACHE_MAX_ENTRIES / 2;
772
773 /* allocate a pool of entries */
774 cache->pool = calloc(cache->max_entries, NAME_ENTRY_SIZE);
775 if (cache->pool == NULL) {
777 goto out_err_cache;
778 }
779
780 /* initialize the attribute cache */
781 status = attr_cache_init(&cache->attributes, cache->max_entries);
782 if (status)
783 goto out_err_pool;
784
785 *cache_out = cache;
786out:
787 return status;
788
789out_err_pool:
790 free(cache->pool);
791out_err_cache:
792 free(cache);
793 goto out;
794}
VOID WINAPI InitializeSRWLock(PSRWLOCK Lock)
Definition: sync.c:29
#define NAME_CACHE_MAX_ENTRIES
Definition: name_cache.c:750
static int attr_cache_init(IN struct attr_cache *cache, IN uint32_t max_entries)
Definition: name_cache.c:186
#define NAME_ENTRY_SIZE
Definition: name_cache.c:373

Referenced by server_create().

◆ nfs41_name_cache_delegreturn()

int nfs41_name_cache_delegreturn ( IN struct nfs41_name_cache cache,
IN uint64_t  fileid,
IN const char path,
IN const nfs41_component name 
)

Definition at line 1012 of file name_cache.c.

1017{
1018 struct name_cache_entry *parent, *target;
1019 struct attr_cache_entry *attributes;
1020 int status;
1021
1022 dprintf(NCLVL1, "--> nfs41_name_cache_delegreturn(%llu, '%s')\n",
1023 fileid, path);
1024
1026
1027 if (!name_cache_enabled(cache)) {
1029 goto out_unlock;
1030 }
1031
1033 name->name + name->len, NULL, &parent, &target, NULL);
1034 if (status == NO_ERROR) {
1035 /* put the name cache entry back on the exp_entries list */
1036 list_add_head(&cache->exp_entries, &target->exp_entry);
1038
1039 attributes = target->attributes;
1040 } else {
1041 /* should still have an attr cache entry */
1042 attributes = attr_cache_search(&cache->attributes, fileid);
1043 }
1044
1045 if (attributes == NULL) {
1047 goto out_unlock;
1048 }
1049
1050 /* release the reference from name_cache_entry_update() */
1051 if (attributes->delegated) {
1052 attributes->delegated = FALSE;
1053 attr_cache_entry_deref(&cache->attributes, attributes);
1054 assert(cache->delegations > 0);
1055 cache->delegations--;
1056 }
1057 status = NO_ERROR;
1058
1059out_unlock:
1061
1062 dprintf(NCLVL1, "<-- nfs41_name_cache_delegreturn() returning %d\n", status);
1063 return status;
1064}
#define assert(x)
Definition: debug.h:53

Referenced by nfs41_delegreturn().

◆ nfs41_name_cache_free()

int nfs41_name_cache_free ( IN struct nfs41_name_cache **  cache_out)

Definition at line 796 of file name_cache.c.

798{
799 struct nfs41_name_cache *cache = *cache_out;
800 int status = NO_ERROR;
801
802 dprintf(NCLVL1, "nfs41_name_cache_free()\n");
803
804 /* free the attribute cache */
805 attr_cache_free(&cache->attributes);
806
807 /* free the name entry pool */
808 free(cache->pool);
809 free(cache);
810 *cache_out = NULL;
811 return status;
812}
static void attr_cache_free(IN struct attr_cache *cache)
Definition: name_cache.c:210

Referenced by server_free().

◆ nfs41_name_cache_insert()

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 at line 923 of file name_cache.c.

931{
933 int status;
934
935 dprintf(NCLVL1, "--> nfs41_name_cache_insert('%.*s')\n",
936 name->name + name->len - path, path);
937
939
942 goto out_unlock;
943 }
944
945 /* limit the number of delegations to prevent attr cache starvation */
946 if (is_delegation(delegation) &&
947 cache->delegations >= cache->max_delegations) {
949 goto out_unlock;
950 }
951
952 /* an empty path or component implies the root entry */
953 if (path == NULL || name == NULL || name->len == 0) {
954 /* create the root entry if it doesn't exist */
955 if (cache->root == NULL) {
956 const nfs41_component name = { "ROOT", 4 };
958 if (status)
959 goto out_err_deleg;
960 }
961 target = cache->root;
962 } else {
963 /* find/create an entry under its parent */
965 name->name, NULL, NULL, &parent, NULL);
966 if (status)
967 goto out_err_deleg;
968
969 if (cinfo && name_cache_entry_changed(cache, parent, cinfo)) {
971 goto out_err_deleg;
972 }
973
975 if (status)
976 goto out_err_deleg;
977 }
978
979 /* pass in the new fh/attributes */
981 if (status)
982 goto out_err_update;
983
984out_unlock:
986
987 dprintf(NCLVL1, "<-- nfs41_name_cache_insert() returning %d\n",
988 status);
989 return status;
990
991out_err_update:
992 /* a failure in name_cache_entry_update() leaves a negative entry
993 * where there shouldn't be one; remove it from the cache */
995
996out_err_deleg:
997 if (is_delegation(delegation)) {
998 /* we still need a reference to the attributes for the delegation */
999 struct attr_cache_entry *attributes;
1000 status = attr_cache_find_or_create(&cache->attributes,
1001 info->fileid, &attributes);
1002 if (status == NO_ERROR) {
1003 attr_cache_update(attributes, info, delegation);
1004 cache->delegations++;
1005 }
1006 else
1008 }
1009 goto out_unlock;
1010}
static int name_cache_find_or_create(IN struct nfs41_name_cache *cache, IN struct name_cache_entry *parent, IN const nfs41_component *component, OUT struct name_cache_entry **target_out)
Definition: name_cache.c:712
static void name_cache_entry_invalidate(IN struct nfs41_name_cache *cache, IN struct name_cache_entry *entry)
Definition: name_cache.c:587
static int name_cache_entry_update(IN struct nfs41_name_cache *cache, IN struct name_cache_entry *entry, IN OPTIONAL const nfs41_fh *fh, IN OPTIONAL const nfs41_file_info *info, IN enum open_delegation_type4 delegation)
Definition: name_cache.c:519
static int name_cache_entry_changed(IN struct nfs41_name_cache *cache, IN struct name_cache_entry *entry, IN const change_info4 *cinfo)
Definition: name_cache.c:563
#define ERROR_TOO_MANY_OPEN_FILES
Definition: winerror.h:107

Referenced by nfs41_create(), nfs41_link(), open_update_cache(), and server_lookup().

◆ nfs41_name_cache_lookup()

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 at line 824 of file name_cache.c.

833{
835 const char *path_pos = path;
836 int status;
837
839
842 goto out_unlock;
843 }
844
845 status = name_cache_lookup(cache, 1, path, path_end,
846 &path_pos, &parent, &target, is_negative);
847
848 if (parent_out) copy_fh(parent_out, parent);
849 if (target_out) copy_fh(target_out, target);
850 if (info_out && target && target->attributes)
851 copy_attrs(info_out, target->attributes);
852
853out_unlock:
855 if (remaining_path_out) *remaining_path_out = path_pos;
856 return status;
857}
static __inline void copy_fh(OUT nfs41_fh *dst, IN OPTIONAL const struct name_cache_entry *src)
Definition: name_cache.c:814

Referenced by nfs41_lookup().

◆ nfs41_name_cache_remove()

int nfs41_name_cache_remove ( IN struct nfs41_name_cache cache,
IN const char path,
IN const nfs41_component name,
IN uint64_t  fileid,
IN const change_info4 cinfo 
)

Definition at line 1066 of file name_cache.c.

1072{
1073 struct name_cache_entry *parent, *target;
1074 struct attr_cache_entry *attributes = NULL;
1075 int status;
1076
1077 dprintf(NCLVL1, "--> nfs41_name_cache_remove('%s')\n", path);
1078
1080
1081 if (!name_cache_enabled(cache)) {
1083 goto out_unlock;
1084 }
1085
1087 name->name + name->len, NULL, &parent, &target, NULL);
1089 goto out_attributes;
1090
1091 if (cinfo && name_cache_entry_changed(cache, parent, cinfo)) {
1093 goto out_attributes;
1094 }
1095
1097 goto out_attributes;
1098
1099 if (target->attributes)
1100 target->attributes->numlinks--;
1101
1102 /* make this a negative entry and unlink children */
1105
1106out_unlock:
1108
1109 dprintf(NCLVL1, "<-- nfs41_name_cache_remove() returning %d\n", status);
1110 return status;
1111
1112out_attributes:
1113 /* in the presence of other links, we need to update numlinks
1114 * regardless of a failure to find the target entry */
1115 dprintf(NCLVL1, "nfs41_name_cache_remove: need to find attributes for %s\n", path);
1116 attributes = attr_cache_search(&cache->attributes, fileid);
1117 if (attributes)
1118 attributes->numlinks--;
1119 goto out_unlock;
1120}

Referenced by nfs41_remove().

◆ nfs41_name_cache_remove_stale()

int nfs41_name_cache_remove_stale ( IN struct nfs41_name_cache cache,
IN nfs41_session session,
IN nfs41_abs_path path 
)

Definition at line 1359 of file name_cache.c.

1363{
1365 const char *path_pos = path->path;
1366 const char* const path_end = path->path + path->len;
1367 const uint32_t max_components = max_putfh_components(session);
1369 int status = NO_ERROR;
1370
1372
1373 /* if there's no cache, don't check any components */
1375 path_pos = path_end;
1376
1378
1379 /* hold a lock on the path to protect against rename */
1380 AcquireSRWLockShared(&path->lock);
1381
1382 while (get_path_fhs(cache, path, &path_pos, max_components, files, &count)) {
1384
1387 session, path, &files[index].name);
1388 break;
1389 }
1390 if (status) {
1392 break;
1393 }
1394 }
1395
1396 ReleaseSRWLockShared(&path->lock);
1397
1398 return status;
1399}
#define index(s, c)
Definition: various.h:29
int nfs_to_windows_error(int status, int default_error)
Definition: util.c:235
GLuint index
Definition: glext.h:6031
static bool_t get_path_fhs(IN struct nfs41_name_cache *cache, IN nfs41_abs_path *path, IN OUT const char **path_pos, IN uint32_t max_components, OUT nfs41_path_fh *files, OUT uint32_t *count)
Definition: name_cache.c:1233
static int rpc_array_putfh(IN nfs41_session *session, IN nfs41_path_fh *files, IN uint32_t count, OUT uint32_t *valid_out)
Definition: name_cache.c:1283
static __inline uint32_t max_putfh_components(IN const nfs41_session *session)
Definition: name_cache.c:1352
static int delete_stale_component(IN struct nfs41_name_cache *cache, IN nfs41_session *session, IN const nfs41_abs_path *path, IN const nfs41_component *component)
Definition: name_cache.c:1327
@ NFS4ERR_FHEXPIRED
Definition: nfs41_const.h:119
@ NFS4ERR_STALE
Definition: nfs41_const.h:106

Referenced by compound_encode_send_decode().

◆ nfs41_name_cache_rename()

int nfs41_name_cache_rename ( IN struct nfs41_name_cache cache,
IN const char src_path,
IN const nfs41_component src_name,
IN const change_info4 src_cinfo,
IN const char dst_path,
IN const nfs41_component dst_name,
IN const change_info4 dst_cinfo 
)

Definition at line 1122 of file name_cache.c.

1130{
1131 struct name_cache_entry *src_parent, *src;
1132 struct name_cache_entry *dst_parent;
1133 int status = NO_ERROR;
1134
1135 dprintf(NCLVL1, "--> nfs41_name_cache_rename('%s' to '%s')\n",
1136 src_path, dst_path);
1137
1139
1140 if (!name_cache_enabled(cache)) {
1142 goto out_unlock;
1143 }
1144
1145 /* look up dst_parent */
1146 status = name_cache_lookup(cache, 0, dst_path,
1147 dst_name->name, NULL, NULL, &dst_parent, NULL);
1148 /* we can't create the dst entry without a parent */
1149 if (status || dst_parent->attributes == NULL) {
1150 /* if src exists, make it negative */
1151 dprintf(NCLVL1, "nfs41_name_cache_rename: adding negative cache "
1152 "entry for %.*s\n", src_name->len, src_name->name);
1153 status = name_cache_lookup(cache, 0, src_path,
1154 src_name->name + src_name->len, NULL, NULL, &src, NULL);
1155 if (status == NO_ERROR) {
1158 }
1160 goto out_unlock;
1161 }
1162
1163 /* look up src_parent and src */
1164 status = name_cache_lookup(cache, 0, src_path,
1165 src_name->name + src_name->len, NULL, &src_parent, &src, NULL);
1166 /* we can't create the dst entry without valid attributes */
1167 if (status || src->attributes == NULL) {
1168 /* remove dst if it exists */
1169 struct name_cache_entry *dst;
1170 dprintf(NCLVL1, "nfs41_name_cache_rename: removing negative cache "
1171 "entry for %.*s\n", dst_name->len, dst_name->name);
1172 dst = name_cache_search(cache, dst_parent, dst_name);
1174 goto out_unlock;
1175 }
1176
1177 if (name_cache_entry_changed(cache, dst_parent, dst_cinfo)) {
1179 /* if dst_parent and src_parent are both gone,
1180 * we no longer have an entry to rename */
1181 if (dst_parent == src_parent)
1182 goto out_unlock;
1183 } else {
1184 struct name_cache_entry *existing;
1185 existing = name_cache_search(cache, dst_parent, dst_name);
1186 if (existing) {
1187 if (existing == src)
1188 goto out_unlock;
1189 /* remove the existing entry, but don't unlink it yet;
1190 * we may reuse it for a negative entry */
1191 name_cache_remove(existing, dst_parent);
1192 }
1193
1194 /* move the src entry under dst_parent */
1195 name_cache_remove(src, src_parent);
1196 name_cache_entry_rename(src, dst_name);
1197 name_cache_insert(src, dst_parent);
1198
1199 if (existing) {
1200 /* recycle 'existing' as the negative entry 'src' */
1201 name_cache_entry_rename(existing, src_name);
1202 name_cache_insert(existing, src_parent);
1203 }
1204 src = existing;
1205 }
1206
1207 if (name_cache_entry_changed(cache, src_parent, src_cinfo)) {
1209 goto out_unlock;
1210 }
1211
1212 /* leave a negative entry where the file used to be */
1213 if (src == NULL) {
1214 /* src was moved, create a new entry in its place */
1215 status = name_cache_find_or_create(cache, src_parent, src_name, &src);
1216 if (status)
1217 goto out_unlock;
1218 }
1221
1222out_unlock:
1224
1225 dprintf(NCLVL1, "<-- nfs41_name_cache_rename() returning %d\n", status);
1226 return status;
1227}

Referenced by nfs41_rename().

◆ RB_HEAD() [1/2]

RB_HEAD ( attr_tree  ,
attr_cache_entry   
)

◆ RB_HEAD() [2/2]

RB_HEAD ( name_tree  ,
name_cache_entry   
)

◆ rpc_array_putfh()

static int rpc_array_putfh ( IN nfs41_session session,
IN nfs41_path_fh files,
IN uint32_t  count,
OUT uint32_t valid_out 
)
static

Definition at line 1283 of file name_cache.c.

1288{
1289 nfs41_compound compound;
1292 nfs41_sequence_args sequence_args;
1293 nfs41_sequence_res sequence_res = { 0 };
1295 nfs41_putfh_res putfh_res[MAX_PUTFH_PER_COMPOUND] = { 0 };
1296 uint32_t i;
1297 int status;
1298
1299 *valid_out = 0;
1300
1301 compound_init(&compound, argops, resops, "array_putfh");
1302
1303 compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
1304 nfs41_session_sequence(&sequence_args, session, 0);
1305
1306 for (i = 0; i < count; i++){
1307 compound_add_op(&compound, OP_PUTFH, &putfh_args[i], &putfh_res[i]);
1308 putfh_args[i].file = &files[i];
1309 putfh_args[i].in_recovery = 1;
1310 }
1311
1313 if (status) goto out;
1314
1315 status = sequence_res.sr_status;
1316 if (status) goto out;
1317
1318 for (i = 0; i < count; i++) {
1319 status = putfh_res[i].status;
1320 if (status) break;
1321 }
1322 *valid_out = i;
1323out:
1324 return status;
1325}
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)
@ OP_SEQUENCE
Definition: nfs41_ops.h:83
@ OP_PUTFH
Definition: nfs41_ops.h:50
nfs41_path_fh * file
Definition: nfs41_ops.h:510
uint32_t status
Definition: nfs41_ops.h:515

Referenced by nfs41_name_cache_remove_stale().