aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-20 21:14:31 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-20 21:14:31 -0500
commit1f0377ff088ed2971c57debc9b0c3b846ec431fd (patch)
treecd53c8981269e57e38e4285abd71cc990e1cfc67 /include
parent54d46ea993744c5408e39ce0cb4851e13cbea716 (diff)
parentb729d75d19777a5dd34672020516eada43ff026f (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull VFS update from Al Viro: "fscache fixes, ESTALE patchset, vmtruncate removal series, assorted misc stuff." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (79 commits) vfs: make lremovexattr retry once on ESTALE error vfs: make removexattr retry once on ESTALE vfs: make llistxattr retry once on ESTALE error vfs: make listxattr retry once on ESTALE error vfs: make lgetxattr retry once on ESTALE vfs: make getxattr retry once on an ESTALE error vfs: allow lsetxattr() to retry once on ESTALE errors vfs: allow setxattr to retry once on ESTALE errors vfs: allow utimensat() calls to retry once on an ESTALE error vfs: fix user_statfs to retry once on ESTALE errors vfs: make fchownat retry once on ESTALE errors vfs: make fchmodat retry once on ESTALE errors vfs: have chroot retry once on ESTALE error vfs: have chdir retry lookup and call once on ESTALE error vfs: have faccessat retry once on an ESTALE error vfs: have do_sys_truncate retry once on an ESTALE error vfs: fix renameat to retry on ESTALE errors vfs: make do_unlinkat retry once on ESTALE errors vfs: make do_rmdir retry once on ESTALE errors vfs: add a flags argument to user_path_parent ...
Diffstat (limited to 'include')
-rw-r--r--include/linux/dcache.h8
-rw-r--r--include/linux/fs.h6
-rw-r--r--include/linux/fscache-cache.h71
-rw-r--r--include/linux/fscache.h50
-rw-r--r--include/linux/mm.h1
-rw-r--r--include/linux/namei.h20
6 files changed, 121 insertions, 35 deletions
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 59200795482e..c1754b59ddd3 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -202,7 +202,6 @@ struct dentry_operations {
202#define DCACHE_MOUNTED 0x10000 /* is a mountpoint */ 202#define DCACHE_MOUNTED 0x10000 /* is a mountpoint */
203#define DCACHE_NEED_AUTOMOUNT 0x20000 /* handle automount on this dir */ 203#define DCACHE_NEED_AUTOMOUNT 0x20000 /* handle automount on this dir */
204#define DCACHE_MANAGE_TRANSIT 0x40000 /* manage transit from this dirent */ 204#define DCACHE_MANAGE_TRANSIT 0x40000 /* manage transit from this dirent */
205#define DCACHE_NEED_LOOKUP 0x80000 /* dentry requires i_op->lookup */
206#define DCACHE_MANAGED_DENTRY \ 205#define DCACHE_MANAGED_DENTRY \
207 (DCACHE_MOUNTED|DCACHE_NEED_AUTOMOUNT|DCACHE_MANAGE_TRANSIT) 206 (DCACHE_MOUNTED|DCACHE_NEED_AUTOMOUNT|DCACHE_MANAGE_TRANSIT)
208 207
@@ -408,13 +407,6 @@ static inline bool d_mountpoint(struct dentry *dentry)
408 return dentry->d_flags & DCACHE_MOUNTED; 407 return dentry->d_flags & DCACHE_MOUNTED;
409} 408}
410 409
411static inline bool d_need_lookup(struct dentry *dentry)
412{
413 return dentry->d_flags & DCACHE_NEED_LOOKUP;
414}
415
416extern void d_clear_need_lookup(struct dentry *dentry);
417
418extern int sysctl_vfs_cache_pressure; 410extern int sysctl_vfs_cache_pressure;
419 411
420#endif /* __LINUX_DCACHE_H */ 412#endif /* __LINUX_DCACHE_H */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index a823d4be38e7..7617ee04f066 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1445,10 +1445,6 @@ static inline void sb_start_intwrite(struct super_block *sb)
1445 1445
1446extern bool inode_owner_or_capable(const struct inode *inode); 1446extern bool inode_owner_or_capable(const struct inode *inode);
1447 1447
1448/* not quite ready to be deprecated, but... */
1449extern void lock_super(struct super_block *);
1450extern void unlock_super(struct super_block *);
1451
1452/* 1448/*
1453 * VFS helper functions.. 1449 * VFS helper functions..
1454 */ 1450 */
@@ -1565,7 +1561,6 @@ struct inode_operations {
1565 int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t); 1561 int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t);
1566 int (*rename) (struct inode *, struct dentry *, 1562 int (*rename) (struct inode *, struct dentry *,
1567 struct inode *, struct dentry *); 1563 struct inode *, struct dentry *);
1568 void (*truncate) (struct inode *);
1569 int (*setattr) (struct dentry *, struct iattr *); 1564 int (*setattr) (struct dentry *, struct iattr *);
1570 int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *); 1565 int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
1571 int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); 1566 int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
@@ -1999,6 +1994,7 @@ struct filename {
1999 bool separate; /* should "name" be freed? */ 1994 bool separate; /* should "name" be freed? */
2000}; 1995};
2001 1996
1997extern long vfs_truncate(struct path *, loff_t);
2002extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs, 1998extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
2003 struct file *filp); 1999 struct file *filp);
2004extern int do_fallocate(struct file *file, int mode, loff_t offset, 2000extern int do_fallocate(struct file *file, int mode, loff_t offset,
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h
index ce31408b1e47..5dfa0aa216b6 100644
--- a/include/linux/fscache-cache.h
+++ b/include/linux/fscache-cache.h
@@ -75,6 +75,16 @@ extern wait_queue_head_t fscache_cache_cleared_wq;
75typedef void (*fscache_operation_release_t)(struct fscache_operation *op); 75typedef void (*fscache_operation_release_t)(struct fscache_operation *op);
76typedef void (*fscache_operation_processor_t)(struct fscache_operation *op); 76typedef void (*fscache_operation_processor_t)(struct fscache_operation *op);
77 77
78enum fscache_operation_state {
79 FSCACHE_OP_ST_BLANK, /* Op is not yet submitted */
80 FSCACHE_OP_ST_INITIALISED, /* Op is initialised */
81 FSCACHE_OP_ST_PENDING, /* Op is blocked from running */
82 FSCACHE_OP_ST_IN_PROGRESS, /* Op is in progress */
83 FSCACHE_OP_ST_COMPLETE, /* Op is complete */
84 FSCACHE_OP_ST_CANCELLED, /* Op has been cancelled */
85 FSCACHE_OP_ST_DEAD /* Op is now dead */
86};
87
78struct fscache_operation { 88struct fscache_operation {
79 struct work_struct work; /* record for async ops */ 89 struct work_struct work; /* record for async ops */
80 struct list_head pend_link; /* link in object->pending_ops */ 90 struct list_head pend_link; /* link in object->pending_ops */
@@ -86,10 +96,10 @@ struct fscache_operation {
86#define FSCACHE_OP_MYTHREAD 0x0002 /* - processing is done be issuing thread, not pool */ 96#define FSCACHE_OP_MYTHREAD 0x0002 /* - processing is done be issuing thread, not pool */
87#define FSCACHE_OP_WAITING 4 /* cleared when op is woken */ 97#define FSCACHE_OP_WAITING 4 /* cleared when op is woken */
88#define FSCACHE_OP_EXCLUSIVE 5 /* exclusive op, other ops must wait */ 98#define FSCACHE_OP_EXCLUSIVE 5 /* exclusive op, other ops must wait */
89#define FSCACHE_OP_DEAD 6 /* op is now dead */ 99#define FSCACHE_OP_DEC_READ_CNT 6 /* decrement object->n_reads on destruction */
90#define FSCACHE_OP_DEC_READ_CNT 7 /* decrement object->n_reads on destruction */ 100#define FSCACHE_OP_KEEP_FLAGS 0x0070 /* flags to keep when repurposing an op */
91#define FSCACHE_OP_KEEP_FLAGS 0xc0 /* flags to keep when repurposing an op */
92 101
102 enum fscache_operation_state state;
93 atomic_t usage; 103 atomic_t usage;
94 unsigned debug_id; /* debugging ID */ 104 unsigned debug_id; /* debugging ID */
95 105
@@ -106,6 +116,7 @@ extern atomic_t fscache_op_debug_id;
106extern void fscache_op_work_func(struct work_struct *work); 116extern void fscache_op_work_func(struct work_struct *work);
107 117
108extern void fscache_enqueue_operation(struct fscache_operation *); 118extern void fscache_enqueue_operation(struct fscache_operation *);
119extern void fscache_op_complete(struct fscache_operation *, bool);
109extern void fscache_put_operation(struct fscache_operation *); 120extern void fscache_put_operation(struct fscache_operation *);
110 121
111/** 122/**
@@ -122,6 +133,7 @@ static inline void fscache_operation_init(struct fscache_operation *op,
122{ 133{
123 INIT_WORK(&op->work, fscache_op_work_func); 134 INIT_WORK(&op->work, fscache_op_work_func);
124 atomic_set(&op->usage, 1); 135 atomic_set(&op->usage, 1);
136 op->state = FSCACHE_OP_ST_INITIALISED;
125 op->debug_id = atomic_inc_return(&fscache_op_debug_id); 137 op->debug_id = atomic_inc_return(&fscache_op_debug_id);
126 op->processor = processor; 138 op->processor = processor;
127 op->release = release; 139 op->release = release;
@@ -138,6 +150,7 @@ struct fscache_retrieval {
138 void *context; /* netfs read context (pinned) */ 150 void *context; /* netfs read context (pinned) */
139 struct list_head to_do; /* list of things to be done by the backend */ 151 struct list_head to_do; /* list of things to be done by the backend */
140 unsigned long start_time; /* time at which retrieval started */ 152 unsigned long start_time; /* time at which retrieval started */
153 unsigned n_pages; /* number of pages to be retrieved */
141}; 154};
142 155
143typedef int (*fscache_page_retrieval_func_t)(struct fscache_retrieval *op, 156typedef int (*fscache_page_retrieval_func_t)(struct fscache_retrieval *op,
@@ -174,8 +187,22 @@ static inline void fscache_enqueue_retrieval(struct fscache_retrieval *op)
174} 187}
175 188
176/** 189/**
190 * fscache_retrieval_complete - Record (partial) completion of a retrieval
191 * @op: The retrieval operation affected
192 * @n_pages: The number of pages to account for
193 */
194static inline void fscache_retrieval_complete(struct fscache_retrieval *op,
195 int n_pages)
196{
197 op->n_pages -= n_pages;
198 if (op->n_pages <= 0)
199 fscache_op_complete(&op->op, true);
200}
201
202/**
177 * fscache_put_retrieval - Drop a reference to a retrieval operation 203 * fscache_put_retrieval - Drop a reference to a retrieval operation
178 * @op: The retrieval operation affected 204 * @op: The retrieval operation affected
205 * @n_pages: The number of pages to account for
179 * 206 *
180 * Drop a reference to a retrieval operation. 207 * Drop a reference to a retrieval operation.
181 */ 208 */
@@ -227,6 +254,9 @@ struct fscache_cache_ops {
227 /* store the updated auxiliary data on an object */ 254 /* store the updated auxiliary data on an object */
228 void (*update_object)(struct fscache_object *object); 255 void (*update_object)(struct fscache_object *object);
229 256
257 /* Invalidate an object */
258 void (*invalidate_object)(struct fscache_operation *op);
259
230 /* discard the resources pinned by an object and effect retirement if 260 /* discard the resources pinned by an object and effect retirement if
231 * necessary */ 261 * necessary */
232 void (*drop_object)(struct fscache_object *object); 262 void (*drop_object)(struct fscache_object *object);
@@ -301,11 +331,30 @@ struct fscache_cookie {
301#define FSCACHE_COOKIE_PENDING_FILL 3 /* T if pending initial fill on object */ 331#define FSCACHE_COOKIE_PENDING_FILL 3 /* T if pending initial fill on object */
302#define FSCACHE_COOKIE_FILLING 4 /* T if filling object incrementally */ 332#define FSCACHE_COOKIE_FILLING 4 /* T if filling object incrementally */
303#define FSCACHE_COOKIE_UNAVAILABLE 5 /* T if cookie is unavailable (error, etc) */ 333#define FSCACHE_COOKIE_UNAVAILABLE 5 /* T if cookie is unavailable (error, etc) */
334#define FSCACHE_COOKIE_WAITING_ON_READS 6 /* T if cookie is waiting on reads */
335#define FSCACHE_COOKIE_INVALIDATING 7 /* T if cookie is being invalidated */
304}; 336};
305 337
306extern struct fscache_cookie fscache_fsdef_index; 338extern struct fscache_cookie fscache_fsdef_index;
307 339
308/* 340/*
341 * Event list for fscache_object::{event_mask,events}
342 */
343enum {
344 FSCACHE_OBJECT_EV_REQUEUE, /* T if object should be requeued */
345 FSCACHE_OBJECT_EV_UPDATE, /* T if object should be updated */
346 FSCACHE_OBJECT_EV_INVALIDATE, /* T if cache requested object invalidation */
347 FSCACHE_OBJECT_EV_CLEARED, /* T if accessors all gone */
348 FSCACHE_OBJECT_EV_ERROR, /* T if fatal error occurred during processing */
349 FSCACHE_OBJECT_EV_RELEASE, /* T if netfs requested object release */
350 FSCACHE_OBJECT_EV_RETIRE, /* T if netfs requested object retirement */
351 FSCACHE_OBJECT_EV_WITHDRAW, /* T if cache requested object withdrawal */
352 NR_FSCACHE_OBJECT_EVENTS
353};
354
355#define FSCACHE_OBJECT_EVENTS_MASK ((1UL << NR_FSCACHE_OBJECT_EVENTS) - 1)
356
357/*
309 * on-disk cache file or index handle 358 * on-disk cache file or index handle
310 */ 359 */
311struct fscache_object { 360struct fscache_object {
@@ -317,6 +366,7 @@ struct fscache_object {
317 /* active states */ 366 /* active states */
318 FSCACHE_OBJECT_AVAILABLE, /* cleaning up object after creation */ 367 FSCACHE_OBJECT_AVAILABLE, /* cleaning up object after creation */
319 FSCACHE_OBJECT_ACTIVE, /* object is usable */ 368 FSCACHE_OBJECT_ACTIVE, /* object is usable */
369 FSCACHE_OBJECT_INVALIDATING, /* object is invalidating */
320 FSCACHE_OBJECT_UPDATING, /* object is updating */ 370 FSCACHE_OBJECT_UPDATING, /* object is updating */
321 371
322 /* terminal states */ 372 /* terminal states */
@@ -332,10 +382,10 @@ struct fscache_object {
332 382
333 int debug_id; /* debugging ID */ 383 int debug_id; /* debugging ID */
334 int n_children; /* number of child objects */ 384 int n_children; /* number of child objects */
335 int n_ops; /* number of ops outstanding on object */ 385 int n_ops; /* number of extant ops on object */
336 int n_obj_ops; /* number of object ops outstanding on object */ 386 int n_obj_ops; /* number of object ops outstanding on object */
337 int n_in_progress; /* number of ops in progress */ 387 int n_in_progress; /* number of ops in progress */
338 int n_exclusive; /* number of exclusive ops queued */ 388 int n_exclusive; /* number of exclusive ops queued or in progress */
339 atomic_t n_reads; /* number of read ops in progress */ 389 atomic_t n_reads; /* number of read ops in progress */
340 spinlock_t lock; /* state and operations lock */ 390 spinlock_t lock; /* state and operations lock */
341 391
@@ -343,14 +393,6 @@ struct fscache_object {
343 unsigned long event_mask; /* events this object is interested in */ 393 unsigned long event_mask; /* events this object is interested in */
344 unsigned long events; /* events to be processed by this object 394 unsigned long events; /* events to be processed by this object
345 * (order is important - using fls) */ 395 * (order is important - using fls) */
346#define FSCACHE_OBJECT_EV_REQUEUE 0 /* T if object should be requeued */
347#define FSCACHE_OBJECT_EV_UPDATE 1 /* T if object should be updated */
348#define FSCACHE_OBJECT_EV_CLEARED 2 /* T if accessors all gone */
349#define FSCACHE_OBJECT_EV_ERROR 3 /* T if fatal error occurred during processing */
350#define FSCACHE_OBJECT_EV_RELEASE 4 /* T if netfs requested object release */
351#define FSCACHE_OBJECT_EV_RETIRE 5 /* T if netfs requested object retirement */
352#define FSCACHE_OBJECT_EV_WITHDRAW 6 /* T if cache requested object withdrawal */
353#define FSCACHE_OBJECT_EVENTS_MASK 0x7f /* mask of all events*/
354 396
355 unsigned long flags; 397 unsigned long flags;
356#define FSCACHE_OBJECT_LOCK 0 /* T if object is busy being processed */ 398#define FSCACHE_OBJECT_LOCK 0 /* T if object is busy being processed */
@@ -504,6 +546,9 @@ extern void fscache_withdraw_cache(struct fscache_cache *cache);
504 546
505extern void fscache_io_error(struct fscache_cache *cache); 547extern void fscache_io_error(struct fscache_cache *cache);
506 548
549extern void fscache_mark_page_cached(struct fscache_retrieval *op,
550 struct page *page);
551
507extern void fscache_mark_pages_cached(struct fscache_retrieval *op, 552extern void fscache_mark_pages_cached(struct fscache_retrieval *op,
508 struct pagevec *pagevec); 553 struct pagevec *pagevec);
509 554
diff --git a/include/linux/fscache.h b/include/linux/fscache.h
index 9ec20dec3353..7a086235da4b 100644
--- a/include/linux/fscache.h
+++ b/include/linux/fscache.h
@@ -135,14 +135,14 @@ struct fscache_cookie_def {
135 */ 135 */
136 void (*put_context)(void *cookie_netfs_data, void *context); 136 void (*put_context)(void *cookie_netfs_data, void *context);
137 137
138 /* indicate pages that now have cache metadata retained 138 /* indicate page that now have cache metadata retained
139 * - this function should mark the specified pages as now being cached 139 * - this function should mark the specified page as now being cached
140 * - the pages will have been marked with PG_fscache before this is 140 * - the page will have been marked with PG_fscache before this is
141 * called, so this is optional 141 * called, so this is optional
142 */ 142 */
143 void (*mark_pages_cached)(void *cookie_netfs_data, 143 void (*mark_page_cached)(void *cookie_netfs_data,
144 struct address_space *mapping, 144 struct address_space *mapping,
145 struct pagevec *cached_pvec); 145 struct page *page);
146 146
147 /* indicate the cookie is no longer cached 147 /* indicate the cookie is no longer cached
148 * - this function is called when the backing store currently caching 148 * - this function is called when the backing store currently caching
@@ -185,6 +185,8 @@ extern struct fscache_cookie *__fscache_acquire_cookie(
185extern void __fscache_relinquish_cookie(struct fscache_cookie *, int); 185extern void __fscache_relinquish_cookie(struct fscache_cookie *, int);
186extern void __fscache_update_cookie(struct fscache_cookie *); 186extern void __fscache_update_cookie(struct fscache_cookie *);
187extern int __fscache_attr_changed(struct fscache_cookie *); 187extern int __fscache_attr_changed(struct fscache_cookie *);
188extern void __fscache_invalidate(struct fscache_cookie *);
189extern void __fscache_wait_on_invalidate(struct fscache_cookie *);
188extern int __fscache_read_or_alloc_page(struct fscache_cookie *, 190extern int __fscache_read_or_alloc_page(struct fscache_cookie *,
189 struct page *, 191 struct page *,
190 fscache_rw_complete_t, 192 fscache_rw_complete_t,
@@ -390,6 +392,42 @@ int fscache_attr_changed(struct fscache_cookie *cookie)
390} 392}
391 393
392/** 394/**
395 * fscache_invalidate - Notify cache that an object needs invalidation
396 * @cookie: The cookie representing the cache object
397 *
398 * Notify the cache that an object is needs to be invalidated and that it
399 * should abort any retrievals or stores it is doing on the cache. The object
400 * is then marked non-caching until such time as the invalidation is complete.
401 *
402 * This can be called with spinlocks held.
403 *
404 * See Documentation/filesystems/caching/netfs-api.txt for a complete
405 * description.
406 */
407static inline
408void fscache_invalidate(struct fscache_cookie *cookie)
409{
410 if (fscache_cookie_valid(cookie))
411 __fscache_invalidate(cookie);
412}
413
414/**
415 * fscache_wait_on_invalidate - Wait for invalidation to complete
416 * @cookie: The cookie representing the cache object
417 *
418 * Wait for the invalidation of an object to complete.
419 *
420 * See Documentation/filesystems/caching/netfs-api.txt for a complete
421 * description.
422 */
423static inline
424void fscache_wait_on_invalidate(struct fscache_cookie *cookie)
425{
426 if (fscache_cookie_valid(cookie))
427 __fscache_wait_on_invalidate(cookie);
428}
429
430/**
393 * fscache_reserve_space - Reserve data space for a cached object 431 * fscache_reserve_space - Reserve data space for a cached object
394 * @cookie: The cookie representing the cache object 432 * @cookie: The cookie representing the cache object
395 * @i_size: The amount of space to be reserved 433 * @i_size: The amount of space to be reserved
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 7f4f906190bd..63204078f72b 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1007,7 +1007,6 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping,
1007 1007
1008extern void truncate_pagecache(struct inode *inode, loff_t old, loff_t new); 1008extern void truncate_pagecache(struct inode *inode, loff_t old, loff_t new);
1009extern void truncate_setsize(struct inode *inode, loff_t newsize); 1009extern void truncate_setsize(struct inode *inode, loff_t newsize);
1010extern int vmtruncate(struct inode *inode, loff_t offset);
1011void truncate_pagecache_range(struct inode *inode, loff_t offset, loff_t end); 1010void truncate_pagecache_range(struct inode *inode, loff_t offset, loff_t end);
1012int truncate_inode_page(struct address_space *mapping, struct page *page); 1011int truncate_inode_page(struct address_space *mapping, struct page *page);
1013int generic_error_remove_page(struct address_space *mapping, struct page *page); 1012int generic_error_remove_page(struct address_space *mapping, struct page *page);
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 4bf19d8174ed..e998c030061d 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -65,8 +65,8 @@ extern int user_path_at_empty(int, const char __user *, unsigned, struct path *,
65 65
66extern int kern_path(const char *, unsigned, struct path *); 66extern int kern_path(const char *, unsigned, struct path *);
67 67
68extern struct dentry *kern_path_create(int, const char *, struct path *, int); 68extern struct dentry *kern_path_create(int, const char *, struct path *, unsigned int);
69extern struct dentry *user_path_create(int, const char __user *, struct path *, int); 69extern struct dentry *user_path_create(int, const char __user *, struct path *, unsigned int);
70extern void done_path_create(struct path *, struct dentry *); 70extern void done_path_create(struct path *, struct dentry *);
71extern struct dentry *kern_path_locked(const char *, struct path *); 71extern struct dentry *kern_path_locked(const char *, struct path *);
72extern int vfs_path_lookup(struct dentry *, struct vfsmount *, 72extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
@@ -98,4 +98,20 @@ static inline void nd_terminate_link(void *name, size_t len, size_t maxlen)
98 ((char *) name)[min(len, maxlen)] = '\0'; 98 ((char *) name)[min(len, maxlen)] = '\0';
99} 99}
100 100
101/**
102 * retry_estale - determine whether the caller should retry an operation
103 * @error: the error that would currently be returned
104 * @flags: flags being used for next lookup attempt
105 *
106 * Check to see if the error code was -ESTALE, and then determine whether
107 * to retry the call based on whether "flags" already has LOOKUP_REVAL set.
108 *
109 * Returns true if the caller should try the operation again.
110 */
111static inline bool
112retry_estale(const long error, const unsigned int flags)
113{
114 return error == -ESTALE && !(flags & LOOKUP_REVAL);
115}
116
101#endif /* _LINUX_NAMEI_H */ 117#endif /* _LINUX_NAMEI_H */