ReactOS  0.4.12-dev-18-gf469aca
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

Definition at line 121 of file name_cache.c.

Referenced by attr_cache_entry_create().

◆ ATTR_ENTRY_SIZE

#define ATTR_ENTRY_SIZE   sizeof(struct attr_cache_entry)

Definition at line 103 of file name_cache.c.

Referenced by attr_cache_init().

◆ MAX_PUTFH_PER_COMPOUND

#define MAX_PUTFH_PER_COMPOUND   16

◆ NAME_CACHE_EXPIRATION

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

Definition at line 42 of file name_cache.c.

Referenced by attr_cache_update(), and nfs41_name_cache_create().

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

Referenced by nfs41_name_cache_create().

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

Referenced by name_cache_entry_create().

◆ NAME_ENTRY_SIZE

#define NAME_ENTRY_SIZE   sizeof(struct name_cache_entry)

Definition at line 373 of file name_cache.c.

Referenced by nfs41_name_cache_create().

◆ 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 };

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.

Referenced by attr_cache_find_or_create().

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)) {
133  status = ERROR_OUTOFMEMORY;
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;
143 out:
144  return status;
145 }
Definition: cache.c:46
uint8_t entry
Definition: isohybrid.c:63
#define NO_ERROR
Definition: dderror.h:5
Definition: name_cache.c:80
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
#define attr_entry(pos)
Definition: name_cache.c:121
static FILE * out
Definition: regtests2xml.c:44
__WINE_SERVER_LIST_INLINE int list_empty(const struct list *list)
Definition: list.h:143
static SERVICE_STATUS status
Definition: service.c:31
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
Definition: ps.c:97

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

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

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 }
Definition: cache.c:46
uint8_t entry
Definition: isohybrid.c:63
#define dprintf
Definition: regdump.c:33
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

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

Referenced by entry_invis(), and nfs41_attr_cache_lookup().

180 {
181  return entry->invalidated ||
182  (!entry->delegated && time(NULL) > entry->expiration);
183 }
uint8_t entry
Definition: isohybrid.c:63
__u16 time
Definition: mkdosfs.c:366
smooth NULL
Definition: ftsmooth.c:416

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

Referenced by attr_cache_entry_deref(), and attr_cache_find_or_create().

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 }
Definition: cache.c:46
uint8_t entry
Definition: isohybrid.c:63
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
#define dprintf
Definition: regdump.c:33
#define RB_REMOVE(name, x, y)
Definition: tree.h:727

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

Referenced by attr_cache_find_or_create(), and name_cache_entry_update().

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 }
uint8_t entry
Definition: isohybrid.c:63
#define dprintf
Definition: regdump.c:33
UINT32 uint32_t
Definition: types.h:75

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

Referenced by name_cache_entry_update(), and nfs41_name_cache_insert().

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 */
258  status = attr_cache_entry_create(cache, fileid, &entry);
259  if (status)
260  goto out;
261 
262  status = attr_cache_insert(cache, entry);
263  if (status)
264  goto out_err_free;
265  }
266 
267  /* take a reference on success */
268  attr_cache_entry_ref(cache, entry);
269 
270 out:
271  *entry_out = entry;
272  dprintf(NCLVL1, "<-- attr_cache_find_or_create() returning %d\n",
273  status);
274  return status;
275 
276 out_err_free:
278  entry = NULL;
279  goto out;
280 }
Definition: cache.c:46
static __inline void attr_cache_entry_ref(IN struct attr_cache *cache, IN struct attr_cache_entry *entry)
Definition: name_cache.c:157
uint8_t entry
Definition: isohybrid.c:63
static int attr_cache_insert(IN struct attr_cache *cache, IN struct attr_cache_entry *entry)
Definition: name_cache.c:229
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
#define NO_ERROR
Definition: dderror.h:5
Definition: name_cache.c:80
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416
static FILE * out
Definition: regtests2xml.c:44
static __inline void attr_cache_entry_free(IN struct attr_cache *cache, IN struct attr_cache_entry *entry)
Definition: name_cache.c:147
static SERVICE_STATUS status
Definition: service.c:31
static struct attr_cache_entry * attr_cache_search(IN struct attr_cache *cache, IN uint64_t fileid)
Definition: name_cache.c:219
Definition: ps.c:97

◆ attr_cache_free()

static void attr_cache_free ( IN struct attr_cache cache)
static

Definition at line 210 of file name_cache.c.

Referenced by nfs41_name_cache_free().

212 {
213  /* free the pool */
214  free(cache->pool);
215  cache->pool = NULL;
216  list_init(&cache->free_entries);
217 }
Definition: cache.c:46
#define free
Definition: debug_ros.c:5
smooth NULL
Definition: ftsmooth.c:416
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149

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

Referenced by nfs41_name_cache_create().

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) {
196  status = GetLastError();
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  }
206 out:
207  return status;
208 }
Definition: cache.c:46
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define NO_ERROR
Definition: dderror.h:5
#define ATTR_ENTRY_SIZE
Definition: name_cache.c:103
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
GLenum GLclampf GLint i
Definition: glfuncs.h:14
smooth NULL
Definition: ftsmooth.c:416
static FILE * out
Definition: regtests2xml.c:44
UINT32 uint32_t
Definition: types.h:75
#define calloc
Definition: rosglue.h:14
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

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

Referenced by attr_cache_find_or_create().

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))
238  status = ERROR_FILE_EXISTS;
239 
240  dprintf(NCLVL2, "<-- attr_cache_insert() returning %d\n", status);
241  return status;
242 }
Definition: cache.c:46
#define ERROR_FILE_EXISTS
Definition: winerror.h:165
#define RB_INSERT(name, x, y)
Definition: tree.h:726
uint8_t entry
Definition: isohybrid.c:63
#define NO_ERROR
Definition: dderror.h:5
#define dprintf
Definition: regdump.c:33
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

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

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

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 }
Definition: cache.c:46
#define RB_FIND(name, x, y)
Definition: tree.h:728
Definition: name_cache.c:80

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

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

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
#define NAME_CACHE_EXPIRATION
Definition: name_cache.c:42
uint8_t entry
Definition: isohybrid.c:63
__u16 time
Definition: mkdosfs.c:366
unsigned int count
Definition: notification.c:64
static __inline bool_t is_delegation(IN enum open_delegation_type4 type)
Definition: name_cache.c:72
smooth NULL
Definition: ftsmooth.c:416
unsigned char
Definition: typeof.h:27

◆ attr_cmp()

int attr_cmp ( struct attr_cache_entry lhs,
struct attr_cache_entry rhs 
)

Definition at line 113 of file name_cache.c.

Referenced by VfdMakeFileDesc().

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

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

Referenced by nfs41_attr_cache_lookup(), and nfs41_name_cache_lookup().

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 }
GLuint const GLubyte GLvoid * src
Definition: s_context.h:57
GLuint const GLubyte GLvoid const GLvoid * dst
Definition: s_context.h:57

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

Referenced by nfs41_name_cache_lookup().

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

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

Referenced by nfs41_name_cache_remove_stale().

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)
1344  name_cache_unlink(cache, target);
1345 
1347 
1348  dprintf(NCLVL1, "<-- delete_stale_component() returning %d\n", status);
1349  return status;
1350 }
Definition: cache.c:46
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
#define NO_ERROR
Definition: dderror.h:5
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416
HANDLE lock
Definition: cache.c:50
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
char component[NFS41_MAX_COMPONENT_LEN]
Definition: name_cache.c:363
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
Definition: services.c:325
GLenum target
Definition: glext.h:7315
static SERVICE_STATUS status
Definition: service.c:31
Definition: name_cache.c:362
static __inline void name_cache_unlink(IN struct nfs41_name_cache *cache, IN struct name_cache_entry *entry)
Definition: name_cache.c:428

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

Referenced by get_path_fhs(), and name_cache_lookup().

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 }
uint8_t entry
Definition: isohybrid.c:63
static __inline int attr_cache_entry_expired(IN const struct attr_cache_entry *entry)
Definition: name_cache.c:178
__u16 time
Definition: mkdosfs.c:366
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416
__WINE_SERVER_LIST_INLINE int list_empty(const struct list *list)
Definition: list.h:143

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

Referenced by nfs41_name_cache_remove_stale().

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 
1265  target = name_cache_search(cache, target, name);
1266  if (target == NULL || entry_invis(target, NULL)) {
1267  if (is_last_component(name->name, path_end))
1268  status = ERROR_FILE_NOT_FOUND;
1269  else
1270  status = ERROR_PATH_NOT_FOUND;
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 
1278 out_unlock:
1280  return *count && status == 0;
1281 }
Definition: cache.c:46
GLsizei const GLchar ** path
Definition: glext.h:7234
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLenum GLclampf GLint i
Definition: glfuncs.h:14
smooth NULL
Definition: ftsmooth.c:416
HANDLE lock
Definition: cache.c:50
bool_t next_component(IN const char *path, IN const char *path_end, OUT nfs41_component *component)
Definition: util.c:305
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
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
const char * name
Definition: nfs41_types.h:48
void fh_copy(OUT nfs41_fh *dst, IN const nfs41_fh *src)
Definition: util.c:354
nfs41_fh fh
Definition: name_cache.c:364
Definition: services.c:325
UINT32 uint32_t
Definition: types.h:75
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
bool_t is_last_component(IN const char *path, IN const char *path_end)
Definition: util.c:330
GLenum target
Definition: glext.h:7315
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
static int entry_invis(IN struct name_cache_entry *entry, OUT OPTIONAL bool_t *is_negative)
Definition: name_cache.c:624
unsigned short len
Definition: nfs41_types.h:49
static SERVICE_STATUS status
Definition: service.c:31
Definition: name_cache.c:362
VOID WINAPI AcquireSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:61
VOID WINAPI ReleaseSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:89
GLuint const GLchar * name
Definition: glext.h:6031

◆ is_delegation()

static __inline bool_t is_delegation ( IN enum open_delegation_type4  type)
static

Definition at line 72 of file name_cache.c.

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

74 {
76 }
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545

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

Referenced by nfs41_name_cache_remove_stale().

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

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

Referenced by name_cache_entry_updated().

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 }
Definition: cache.c:46
uint8_t entry
Definition: isohybrid.c:63
__WINE_SERVER_LIST_INLINE void list_add_head(struct list *list, struct list *elem)
Definition: list.h:96
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
__WINE_SERVER_LIST_INLINE int list_empty(const struct list *list)
Definition: list.h:143

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

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

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 }
Definition: cache.c:46
#define TRUE
Definition: types.h:120
static void name_cache_entry_updated(IN struct nfs41_name_cache *cache, IN struct name_cache_entry *entry)
Definition: name_cache.c:510
uint8_t entry
Definition: isohybrid.c:63
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416

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

Referenced by name_cache_find_or_create(), and nfs41_name_cache_insert().

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)) {
470  status = ERROR_OUTOFMEMORY;
471  goto out;
472  }
473  entry = name_entry(cache->exp_entries.prev);
474  name_cache_unlink(cache, entry);
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;
488 out:
489  return status;
490 }
Definition: cache.c:46
uint8_t entry
Definition: isohybrid.c:63
#define NO_ERROR
Definition: dderror.h:5
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
#define dprintf
Definition: regdump.c:33
#define name_entry(pos)
Definition: name_cache.c:399
char component[NFS41_MAX_COMPONENT_LEN]
Definition: name_cache.c:363
static FILE * out
Definition: regtests2xml.c:44
static __inline void name_cache_entry_rename(OUT struct name_cache_entry *entry, IN const nfs41_component *component)
Definition: name_cache.c:407
__WINE_SERVER_LIST_INLINE int list_empty(const struct list *list)
Definition: list.h:143
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149
static SERVICE_STATUS status
Definition: service.c:31
Definition: name_cache.c:362
static __inline void name_cache_unlink(IN struct nfs41_name_cache *cache, IN struct name_cache_entry *entry)
Definition: name_cache.c:428
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
Definition: ps.c:97

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

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

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 }
Definition: cache.c:46
uint8_t entry
Definition: isohybrid.c:63
#define dprintf
Definition: regdump.c:33
static __inline void name_cache_unlink(IN struct nfs41_name_cache *cache, IN struct name_cache_entry *entry)
Definition: name_cache.c:428

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

Referenced by name_cache_entry_create(), and nfs41_name_cache_rename().

410 {
412  component->name, component->len);
413  entry->component_len = component->len;
414 }
#define NFS41_MAX_COMPONENT_LEN
Definition: nfs41_const.h:45
uint8_t entry
Definition: isohybrid.c:63
STRSAFEAPI StringCchCopyNA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc, size_t cchToCopy)
Definition: strsafe.h:230
char component[NFS41_MAX_COMPONENT_LEN]
Definition: name_cache.c:363

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

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

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 */
536  status = attr_cache_find_or_create(&cache->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  }
559 out:
560  return status;
561 }
Definition: cache.c:46
static void name_cache_entry_updated(IN struct nfs41_name_cache *cache, IN struct name_cache_entry *entry)
Definition: name_cache.c:510
static __inline void attr_cache_entry_ref(IN struct attr_cache *cache, IN struct attr_cache_entry *entry)
Definition: name_cache.c:157
uint8_t entry
Definition: isohybrid.c:63
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
#define NO_ERROR
Definition: dderror.h:5
static __inline bool_t is_delegation(IN enum open_delegation_type4 type)
Definition: name_cache.c:72
smooth NULL
Definition: ftsmooth.c:416
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
static FILE * out
Definition: regtests2xml.c:44
static __inline void attr_cache_entry_deref(IN struct attr_cache *cache, IN struct attr_cache_entry *entry)
Definition: name_cache.c:166
void fh_copy(OUT nfs41_fh *dst, IN const nfs41_fh *src)
Definition: util.c:354
nfs41_fh fh
Definition: name_cache.c:364
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 SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

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

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

513 {
514  /* update the expiration timer */
515  entry->expiration = time(NULL) + cache->expiration;
517 }
Definition: cache.c:46
uint8_t entry
Definition: isohybrid.c:63
__u16 time
Definition: mkdosfs.c:366
smooth NULL
Definition: ftsmooth.c:416
static void name_cache_entry_accessed(IN struct nfs41_name_cache *cache, IN struct name_cache_entry *entry)
Definition: name_cache.c:492

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

Referenced by nfs41_name_cache_insert(), and nfs41_name_cache_rename().

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 
735 out:
736  dprintf(NCLVL1, "<-- name_cache_find_or_create() returning %d\n",
737  status);
738  return status;
739 
740 out_err:
741  *target_out = NULL;
742  goto out;
743 }
Definition: cache.c:46
static int name_cache_insert(IN struct name_cache_entry *entry, IN struct name_cache_entry *parent)
Definition: name_cache.c:696
#define NO_ERROR
Definition: dderror.h:5
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416
char component[NFS41_MAX_COMPONENT_LEN]
Definition: name_cache.c:363
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
r parent
Definition: btrfs.c:2644
static FILE * out
Definition: regtests2xml.c:44
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
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

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

Referenced by name_cache_find_or_create(), and nfs41_name_cache_rename().

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))
705  status = ERROR_FILE_EXISTS;
706  entry->parent = parent;
707 
708  dprintf(NCLVL2, "<-- name_cache_insert() returning %u\n", status);
709  return status;
710 }
#define ERROR_FILE_EXISTS
Definition: winerror.h:165
#define RB_INSERT(name, x, y)
Definition: tree.h:726
uint8_t entry
Definition: isohybrid.c:63
#define NO_ERROR
Definition: dderror.h:5
#define dprintf
Definition: regdump.c:33
r parent
Definition: btrfs.c:2644
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

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

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().

657 {
658  struct name_cache_entry *parent, *target;
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;
671  status = ERROR_PATH_NOT_FOUND;
672  goto out;
673  }
674 
675  while (next_component(path_pos, path_end, &component)) {
676  parent = target;
677  target = name_cache_search(cache, parent, &component);
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))
682  status = ERROR_FILE_NOT_FOUND;
683  else
684  status = ERROR_PATH_NOT_FOUND;
685  break;
686  }
687  }
688 out:
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 }
Definition: cache.c:46
GLsizei const GLchar ** path
Definition: glext.h:7234
#define NO_ERROR
Definition: dderror.h:5
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416
bool_t next_component(IN const char *path, IN const char *path_end, OUT nfs41_component *component)
Definition: util.c:305
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
char component[NFS41_MAX_COMPONENT_LEN]
Definition: name_cache.c:363
const char * name
Definition: nfs41_types.h:48
r parent
Definition: btrfs.c:2644
static FILE * out
Definition: regtests2xml.c:44
Definition: services.c:325
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
bool_t is_last_component(IN const char *path, IN const char *path_end)
Definition: util.c:330
GLenum target
Definition: glext.h:7315
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
static int entry_invis(IN struct name_cache_entry *entry, OUT OPTIONAL bool_t *is_negative)
Definition: name_cache.c:624
unsigned short len
Definition: nfs41_types.h:49
static SERVICE_STATUS status
Definition: service.c:31
Definition: name_cache.c:362
Definition: ps.c:97

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

Referenced by name_cache_unlink(), and nfs41_name_cache_rename().

419 {
420  RB_REMOVE(name_tree, &parent->rbchildren, entry);
421  entry->parent = NULL;
422 }
uint8_t entry
Definition: isohybrid.c:63
smooth NULL
Definition: ftsmooth.c:416
r parent
Definition: btrfs.c:2644
#define RB_REMOVE(name, x, y)
Definition: tree.h:727

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

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

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 }
#define NFS41_MAX_COMPONENT_LEN
Definition: nfs41_const.h:45
uint8_t entry
Definition: isohybrid.c:63
#define RB_FIND(name, x, y)
Definition: tree.h:728
STRSAFEAPI StringCchCopyNA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc, size_t cchToCopy)
Definition: strsafe.h:230
#define dprintf
Definition: regdump.c:33
char component[NFS41_MAX_COMPONENT_LEN]
Definition: name_cache.c:363
r parent
Definition: btrfs.c:2644
Definition: name_cache.c:362

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

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

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 }
Definition: cache.c:46
uint8_t entry
Definition: isohybrid.c:63
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
smooth NULL
Definition: ftsmooth.c:416
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
static void name_cache_unlink_children_recursive(IN struct nfs41_name_cache *cache, IN struct name_cache_entry *parent)
Definition: name_cache.c:450
static __inline void attr_cache_entry_deref(IN struct attr_cache *cache, IN struct attr_cache_entry *entry)
Definition: name_cache.c:166
static __inline void name_cache_remove(IN struct name_cache_entry *entry, IN struct name_cache_entry *parent)
Definition: name_cache.c:416

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

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

453 {
454  struct name_cache_entry *entry, *tmp;
455  RB_FOREACH_SAFE(entry, name_tree, &parent->rbchildren, tmp)
456  name_cache_unlink(cache, entry);
457 }
Definition: cache.c:46
uint8_t entry
Definition: isohybrid.c:63
#define RB_FOREACH_SAFE(x, name, head, y)
Definition: tree.h:745
r parent
Definition: btrfs.c:2644
Definition: name_cache.c:362
static __inline void name_cache_unlink(IN struct nfs41_name_cache *cache, IN struct name_cache_entry *entry)
Definition: name_cache.c:428

◆ 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 }
char component[NFS41_MAX_COMPONENT_LEN]
Definition: name_cache.c:363
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.

Referenced by nfs41_cached_getattr(), nfs41_delegation_getattr(), and session_name_cache().

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 
871  if (!name_cache_enabled(cache)) {
872  status = ERROR_NOT_SUPPORTED;
873  goto out_unlock;
874  }
875 
876  entry = attr_cache_search(&cache->attributes, fileid);
877  if (entry == NULL || attr_cache_entry_expired(entry)) {
878  status = ERROR_FILE_NOT_FOUND;
879  goto out_unlock;
880  }
881 
882  copy_attrs(info_out, entry);
883 
884 out_unlock:
886 
887  dprintf(NCLVL1, "<-- nfs41_attr_cache_lookup() returning %d\n", status);
888  return status;
889 }
Definition: cache.c:46
static void copy_attrs(OUT nfs41_file_info *dst, IN const struct attr_cache_entry *src)
Definition: name_cache.c:329
uint8_t entry
Definition: isohybrid.c:63
static __inline bool_t name_cache_enabled(IN struct nfs41_name_cache *cache)
Definition: name_cache.c:401
static __inline int attr_cache_entry_expired(IN const struct attr_cache_entry *entry)
Definition: name_cache.c:178
#define NO_ERROR
Definition: dderror.h:5
Definition: name_cache.c:80
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416
HANDLE lock
Definition: cache.c:50
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define ERROR_NOT_SUPPORTED
Definition: compat.h:90
static SERVICE_STATUS status
Definition: service.c:31
VOID WINAPI AcquireSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:61
VOID WINAPI ReleaseSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:89
static struct attr_cache_entry * attr_cache_search(IN struct attr_cache *cache, IN uint64_t fileid)
Definition: name_cache.c:219
Definition: ps.c:97

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

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

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 
903  if (!name_cache_enabled(cache)) {
904  status = ERROR_NOT_SUPPORTED;
905  goto out_unlock;
906  }
907 
908  entry = attr_cache_search(&cache->attributes, fileid);
909  if (entry == NULL) {
910  status = ERROR_FILE_NOT_FOUND;
911  goto out_unlock;
912  }
913 
915 
916 out_unlock:
918 
919  dprintf(NCLVL1, "<-- nfs41_attr_cache_update() returning %d\n", status);
920  return status;
921 }
Definition: cache.c:46
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
uint8_t entry
Definition: isohybrid.c:63
static __inline bool_t name_cache_enabled(IN struct nfs41_name_cache *cache)
Definition: name_cache.c:401
#define NO_ERROR
Definition: dderror.h:5
Definition: name_cache.c:80
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416
HANDLE lock
Definition: cache.c:50
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
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
#define ERROR_NOT_SUPPORTED
Definition: compat.h:90
static SERVICE_STATUS status
Definition: service.c:31
static struct attr_cache_entry * attr_cache_search(IN struct attr_cache *cache, IN uint64_t fileid)
Definition: name_cache.c:219
Definition: ps.c:97

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

Referenced by server_create(), and session_name_cache().

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) {
763  status = GetLastError();
764  goto out;
765  }
766 
767  list_init(&cache->exp_entries);
771  InitializeSRWLock(&cache->lock);
772 
773  /* allocate a pool of entries */
774  cache->pool = calloc(cache->max_entries, NAME_ENTRY_SIZE);
775  if (cache->pool == NULL) {
776  status = GetLastError();
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;
786 out:
787  return status;
788 
789 out_err_pool:
790  free(cache->pool);
791 out_err_cache:
792  free(cache);
793  goto out;
794 }
#define NAME_CACHE_EXPIRATION
Definition: name_cache.c:42
#define free
Definition: debug_ros.c:5
uint32_t max_delegations
Definition: name_cache.c:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
uint32_t expiration
Definition: name_cache.c:387
struct attr_cache attributes
Definition: name_cache.c:385
uint32_t max_entries
Definition: name_cache.c:389
#define NO_ERROR
Definition: dderror.h:5
struct list_entry exp_entries
Definition: name_cache.c:386
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416
#define NAME_CACHE_MAX_ENTRIES
Definition: name_cache.c:750
struct name_cache_entry * pool
Definition: name_cache.c:384
static FILE * out
Definition: regtests2xml.c:44
static IOleCache * cache
Definition: ole2.c:81
VOID WINAPI InitializeSRWLock(PSRWLOCK Lock)
Definition: sync.c:75
#define calloc
Definition: rosglue.h:14
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
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

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

Referenced by nfs41_delegreturn(), and session_name_cache().

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)) {
1028  status = ERROR_NOT_SUPPORTED;
1029  goto out_unlock;
1030  }
1031 
1032  status = name_cache_lookup(cache, 0, path,
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) {
1046  status = ERROR_FILE_NOT_FOUND;
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 
1059 out_unlock:
1061 
1062  dprintf(NCLVL1, "<-- nfs41_name_cache_delegreturn() returning %d\n", status);
1063  return status;
1064 }
Definition: cache.c:46
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
static void name_cache_entry_updated(IN struct nfs41_name_cache *cache, IN struct name_cache_entry *entry)
Definition: name_cache.c:510
static __inline bool_t name_cache_enabled(IN struct nfs41_name_cache *cache)
Definition: name_cache.c:401
__WINE_SERVER_LIST_INLINE void list_add_head(struct list *list, struct list *elem)
Definition: list.h:96
#define assert(x)
Definition: debug.h:53
#define NO_ERROR
Definition: dderror.h:5
Definition: name_cache.c:80
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416
HANDLE lock
Definition: cache.c:50
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
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
r parent
Definition: btrfs.c:2644
static __inline void attr_cache_entry_deref(IN struct attr_cache *cache, IN struct attr_cache_entry *entry)
Definition: name_cache.c:166
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
Definition: services.c:325
#define ERROR_NOT_SUPPORTED
Definition: compat.h:90
Definition: name.c:36
GLenum target
Definition: glext.h:7315
static SERVICE_STATUS status
Definition: service.c:31
Definition: name_cache.c:362
static struct attr_cache_entry * attr_cache_search(IN struct attr_cache *cache, IN uint64_t fileid)
Definition: name_cache.c:219
WCHAR * name
Definition: name.c:40

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

Referenced by server_free().

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
Definition: cache.c:46
#define free
Definition: debug_ros.c:5
struct attr_cache attributes
Definition: name_cache.c:385
#define NO_ERROR
Definition: dderror.h:5
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416
struct name_cache_entry * pool
Definition: name_cache.c:384
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

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

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

931 {
932  struct name_cache_entry *parent, *target;
933  int status;
934 
935  dprintf(NCLVL1, "--> nfs41_name_cache_insert('%.*s')\n",
936  name->name + name->len - path, path);
937 
939 
940  if (!name_cache_enabled(cache)) {
941  status = ERROR_NOT_SUPPORTED;
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) {
948  status = ERROR_TOO_MANY_OPEN_FILES;
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 };
957  status = name_cache_entry_create(cache, &name, &cache->root);
958  if (status)
959  goto out_err_deleg;
960  }
961  target = cache->root;
962  } else {
963  /* find/create an entry under its parent */
964  status = name_cache_lookup(cache, 0, path,
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 
974  status = name_cache_find_or_create(cache, parent, name, &target);
975  if (status)
976  goto out_err_deleg;
977  }
978 
979  /* pass in the new fh/attributes */
980  status = name_cache_entry_update(cache, target, fh, info, delegation);
981  if (status)
982  goto out_err_update;
983 
984 out_unlock:
986 
987  dprintf(NCLVL1, "<-- nfs41_name_cache_insert() returning %d\n",
988  status);
989  return status;
990 
991 out_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 
996 out_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
1007  status = ERROR_TOO_MANY_OPEN_FILES;
1008  }
1009  goto out_unlock;
1010 }
Definition: cache.c:46
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
static __inline bool_t name_cache_enabled(IN struct nfs41_name_cache *cache)
Definition: name_cache.c:401
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
#define NO_ERROR
Definition: dderror.h:5
Definition: name_cache.c:80
#define dprintf
Definition: regdump.c:33
static __inline bool_t is_delegation(IN enum open_delegation_type4 type)
Definition: name_cache.c:72
smooth NULL
Definition: ftsmooth.c:416
HANDLE lock
Definition: cache.c:50
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
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
r parent
Definition: btrfs.c:2644
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_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 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
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
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
#define ERROR_TOO_MANY_OPEN_FILES
Definition: winerror.h:107
nfs41_fh fh
Definition: name_cache.c:364
Definition: services.c:325
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
#define ERROR_NOT_SUPPORTED
Definition: compat.h:90
Definition: name.c:36
GLenum target
Definition: glext.h:7315
static SERVICE_STATUS status
Definition: service.c:31
Definition: name_cache.c:362
WCHAR * name
Definition: name.c:40

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

Referenced by nfs41_lookup(), and session_name_cache().

833 {
834  struct name_cache_entry *parent, *target;
835  const char *path_pos = path;
836  int status;
837 
839 
840  if (!name_cache_enabled(cache)) {
841  status = ERROR_NOT_SUPPORTED;
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 
853 out_unlock:
855  if (remaining_path_out) *remaining_path_out = path_pos;
856  return status;
857 }
Definition: cache.c:46
static void copy_attrs(OUT nfs41_file_info *dst, IN const struct attr_cache_entry *src)
Definition: name_cache.c:329
GLsizei const GLchar ** path
Definition: glext.h:7234
static __inline bool_t name_cache_enabled(IN struct nfs41_name_cache *cache)
Definition: name_cache.c:401
HANDLE lock
Definition: cache.c:50
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
r parent
Definition: btrfs.c:2644
static __inline void copy_fh(OUT nfs41_fh *dst, IN OPTIONAL const struct name_cache_entry *src)
Definition: name_cache.c:814
Definition: services.c:325
#define ERROR_NOT_SUPPORTED
Definition: compat.h:90
GLenum target
Definition: glext.h:7315
static SERVICE_STATUS status
Definition: service.c:31
Definition: name_cache.c:362
VOID WINAPI AcquireSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:61
VOID WINAPI ReleaseSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:89

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

Referenced by nfs41_remove(), and session_name_cache().

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)) {
1082  status = ERROR_NOT_SUPPORTED;
1083  goto out_unlock;
1084  }
1085 
1086  status = name_cache_lookup(cache, 0, path,
1087  name->name + name->len, NULL, &parent, &target, NULL);
1088  if (status == ERROR_PATH_NOT_FOUND)
1089  goto out_attributes;
1090 
1091  if (cinfo && name_cache_entry_changed(cache, parent, cinfo)) {
1093  goto out_attributes;
1094  }
1095 
1096  if (status == ERROR_FILE_NOT_FOUND)
1097  goto out_attributes;
1098 
1099  if (target->attributes)
1100  target->attributes->numlinks--;
1101 
1102  /* make this a negative entry and unlink children */
1105 
1106 out_unlock:
1108 
1109  dprintf(NCLVL1, "<-- nfs41_name_cache_remove() returning %d\n", status);
1110  return status;
1111 
1112 out_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 }
Definition: cache.c:46
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
static __inline bool_t name_cache_enabled(IN struct nfs41_name_cache *cache)
Definition: name_cache.c:401
Definition: name_cache.c:80
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416
HANDLE lock
Definition: cache.c:50
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
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
r parent
Definition: btrfs.c:2644
static void name_cache_entry_invalidate(IN struct nfs41_name_cache *cache, IN struct name_cache_entry *entry)
Definition: name_cache.c:587
static void name_cache_unlink_children_recursive(IN struct nfs41_name_cache *cache, IN struct name_cache_entry *parent)
Definition: name_cache.c:450
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
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
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
Definition: services.c:325
#define ERROR_NOT_SUPPORTED
Definition: compat.h:90
Definition: name.c:36
GLenum target
Definition: glext.h:7315
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
static SERVICE_STATUS status
Definition: service.c:31
Definition: name_cache.c:362
static struct attr_cache_entry * attr_cache_search(IN struct attr_cache *cache, IN uint64_t fileid)
Definition: name_cache.c:219
WCHAR * name
Definition: name.c:40

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

Referenced by compound_encode_send_decode(), and session_name_cache().

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);
1368  uint32_t count, index;
1369  int status = NO_ERROR;
1370 
1372 
1373  /* if there's no cache, don't check any components */
1374  if (!name_cache_enabled(cache))
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)) {
1383  status = rpc_array_putfh(session, files, count, &index);
1384 
1385  if (status == NFS4ERR_STALE || status == NFS4ERR_FHEXPIRED) {
1386  status = delete_stale_component(cache,
1387  session, path, &files[index].name);
1388  break;
1389  }
1390  if (status) {
1391  status = nfs_to_windows_error(status, ERROR_FILE_NOT_FOUND);
1392  break;
1393  }
1394  }
1395 
1396  ReleaseSRWLockShared(&path->lock);
1397 
1398  return status;
1399 }
#define MAX_PUTFH_PER_COMPOUND
Definition: name_cache.c:1231
Definition: cache.c:46
int nfs_to_windows_error(int status, int default_error)
Definition: util.c:235
GLuint GLuint GLsizei count
Definition: gl.h:1545
static __inline bool_t name_cache_enabled(IN struct nfs41_name_cache *cache)
Definition: name_cache.c:401
#define NO_ERROR
Definition: dderror.h:5
static __inline uint32_t max_putfh_components(IN const nfs41_session *session)
Definition: name_cache.c:1352
HANDLE lock
Definition: cache.c:50
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
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
#define index(s, c)
Definition: various.h:29
Definition: services.c:325
UINT32 uint32_t
Definition: types.h:75
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
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
Definition: name.c:36
static SERVICE_STATUS status
Definition: service.c:31
VOID WINAPI AcquireSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:61
VOID WINAPI ReleaseSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:89
Definition: ps.c:97

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

Referenced by nfs41_rename(), and session_name_cache().

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)) {
1141  status = ERROR_NOT_SUPPORTED;
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  }
1159  status = ERROR_PATH_NOT_FOUND;
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);
1173  if (dst) name_cache_unlink(cache, dst);
1174  goto out_unlock;
1175  }
1176 
1177  if (name_cache_entry_changed(cache, dst_parent, dst_cinfo)) {
1178  name_cache_entry_invalidate(cache, dst_parent);
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)) {
1208  name_cache_entry_invalidate(cache, src_parent);
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 
1222 out_unlock:
1224 
1225  dprintf(NCLVL1, "<-- nfs41_name_cache_rename() returning %d\n", status);
1226  return status;
1227 }
Definition: cache.c:46
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
static int name_cache_insert(IN struct name_cache_entry *entry, IN struct name_cache_entry *parent)
Definition: name_cache.c:696
static __inline bool_t name_cache_enabled(IN struct nfs41_name_cache *cache)
Definition: name_cache.c:401
#define NO_ERROR
Definition: dderror.h:5
GLuint const GLubyte GLvoid * src
Definition: s_context.h:57
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416
HANDLE lock
Definition: cache.c:50
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
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_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_unlink_children_recursive(IN struct nfs41_name_cache *cache, IN struct name_cache_entry *parent)
Definition: name_cache.c:450
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
static __inline void name_cache_entry_rename(OUT struct name_cache_entry *entry, IN const nfs41_component *component)
Definition: name_cache.c:407
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
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
GLuint const GLubyte GLvoid const GLvoid * dst
Definition: s_context.h:57
static __inline void name_cache_remove(IN struct name_cache_entry *entry, IN struct name_cache_entry *parent)
Definition: name_cache.c:416
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
#define ERROR_NOT_SUPPORTED
Definition: compat.h:90
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
static SERVICE_STATUS status
Definition: service.c:31
Definition: name_cache.c:362
static __inline void name_cache_unlink(IN struct nfs41_name_cache *cache, IN struct name_cache_entry *entry)
Definition: name_cache.c:428
Definition: ps.c:97

◆ RB_HEAD() [1/2]

RB_HEAD ( attr_tree  ,
attr_cache_entry   
)

Referenced by copy_attrs().

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

Referenced by nfs41_name_cache_remove_stale().

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 
1312  status = compound_encode_send_decode(session, &compound, TRUE);
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;
1323 out:
1324  return status;
1325 }
#define MAX_PUTFH_PER_COMPOUND
Definition: name_cache.c:1231
nfs41_path_fh * file
Definition: nfs41_ops.h:510
#define TRUE
Definition: types.h:120
GLuint GLuint GLsizei count
Definition: gl.h:1545
int compound_encode_send_decode(nfs41_session *session, nfs41_compound *compound, bool_t try_recovery)
GLenum GLclampf GLint i
Definition: glfuncs.h:14
uint32_t status
Definition: nfs41_ops.h:515
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)
static SERVICE_STATUS status
Definition: service.c:31