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
  ...
This commit is contained in:
Linus Torvalds
2012-12-20 18:14:31 -08:00
80 changed files with 1311 additions and 531 deletions
-8
View File
@@ -202,7 +202,6 @@ struct dentry_operations {
#define DCACHE_MOUNTED 0x10000 /* is a mountpoint */
#define DCACHE_NEED_AUTOMOUNT 0x20000 /* handle automount on this dir */
#define DCACHE_MANAGE_TRANSIT 0x40000 /* manage transit from this dirent */
#define DCACHE_NEED_LOOKUP 0x80000 /* dentry requires i_op->lookup */
#define DCACHE_MANAGED_DENTRY \
(DCACHE_MOUNTED|DCACHE_NEED_AUTOMOUNT|DCACHE_MANAGE_TRANSIT)
@@ -408,13 +407,6 @@ static inline bool d_mountpoint(struct dentry *dentry)
return dentry->d_flags & DCACHE_MOUNTED;
}
static inline bool d_need_lookup(struct dentry *dentry)
{
return dentry->d_flags & DCACHE_NEED_LOOKUP;
}
extern void d_clear_need_lookup(struct dentry *dentry);
extern int sysctl_vfs_cache_pressure;
#endif /* __LINUX_DCACHE_H */
+1 -5
View File
@@ -1445,10 +1445,6 @@ static inline void sb_start_intwrite(struct super_block *sb)
extern bool inode_owner_or_capable(const struct inode *inode);
/* not quite ready to be deprecated, but... */
extern void lock_super(struct super_block *);
extern void unlock_super(struct super_block *);
/*
* VFS helper functions..
*/
@@ -1565,7 +1561,6 @@ struct inode_operations {
int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t);
int (*rename) (struct inode *, struct dentry *,
struct inode *, struct dentry *);
void (*truncate) (struct inode *);
int (*setattr) (struct dentry *, struct iattr *);
int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
@@ -1999,6 +1994,7 @@ struct filename {
bool separate; /* should "name" be freed? */
};
extern long vfs_truncate(struct path *, loff_t);
extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
struct file *filp);
extern int do_fallocate(struct file *file, int mode, loff_t offset,
+58 -13
View File
@@ -75,6 +75,16 @@ extern wait_queue_head_t fscache_cache_cleared_wq;
typedef void (*fscache_operation_release_t)(struct fscache_operation *op);
typedef void (*fscache_operation_processor_t)(struct fscache_operation *op);
enum fscache_operation_state {
FSCACHE_OP_ST_BLANK, /* Op is not yet submitted */
FSCACHE_OP_ST_INITIALISED, /* Op is initialised */
FSCACHE_OP_ST_PENDING, /* Op is blocked from running */
FSCACHE_OP_ST_IN_PROGRESS, /* Op is in progress */
FSCACHE_OP_ST_COMPLETE, /* Op is complete */
FSCACHE_OP_ST_CANCELLED, /* Op has been cancelled */
FSCACHE_OP_ST_DEAD /* Op is now dead */
};
struct fscache_operation {
struct work_struct work; /* record for async ops */
struct list_head pend_link; /* link in object->pending_ops */
@@ -86,10 +96,10 @@ struct fscache_operation {
#define FSCACHE_OP_MYTHREAD 0x0002 /* - processing is done be issuing thread, not pool */
#define FSCACHE_OP_WAITING 4 /* cleared when op is woken */
#define FSCACHE_OP_EXCLUSIVE 5 /* exclusive op, other ops must wait */
#define FSCACHE_OP_DEAD 6 /* op is now dead */
#define FSCACHE_OP_DEC_READ_CNT 7 /* decrement object->n_reads on destruction */
#define FSCACHE_OP_KEEP_FLAGS 0xc0 /* flags to keep when repurposing an op */
#define FSCACHE_OP_DEC_READ_CNT 6 /* decrement object->n_reads on destruction */
#define FSCACHE_OP_KEEP_FLAGS 0x0070 /* flags to keep when repurposing an op */
enum fscache_operation_state state;
atomic_t usage;
unsigned debug_id; /* debugging ID */
@@ -106,6 +116,7 @@ extern atomic_t fscache_op_debug_id;
extern void fscache_op_work_func(struct work_struct *work);
extern void fscache_enqueue_operation(struct fscache_operation *);
extern void fscache_op_complete(struct fscache_operation *, bool);
extern void fscache_put_operation(struct fscache_operation *);
/**
@@ -122,6 +133,7 @@ static inline void fscache_operation_init(struct fscache_operation *op,
{
INIT_WORK(&op->work, fscache_op_work_func);
atomic_set(&op->usage, 1);
op->state = FSCACHE_OP_ST_INITIALISED;
op->debug_id = atomic_inc_return(&fscache_op_debug_id);
op->processor = processor;
op->release = release;
@@ -138,6 +150,7 @@ struct fscache_retrieval {
void *context; /* netfs read context (pinned) */
struct list_head to_do; /* list of things to be done by the backend */
unsigned long start_time; /* time at which retrieval started */
unsigned n_pages; /* number of pages to be retrieved */
};
typedef int (*fscache_page_retrieval_func_t)(struct fscache_retrieval *op,
@@ -173,9 +186,23 @@ static inline void fscache_enqueue_retrieval(struct fscache_retrieval *op)
fscache_enqueue_operation(&op->op);
}
/**
* fscache_retrieval_complete - Record (partial) completion of a retrieval
* @op: The retrieval operation affected
* @n_pages: The number of pages to account for
*/
static inline void fscache_retrieval_complete(struct fscache_retrieval *op,
int n_pages)
{
op->n_pages -= n_pages;
if (op->n_pages <= 0)
fscache_op_complete(&op->op, true);
}
/**
* fscache_put_retrieval - Drop a reference to a retrieval operation
* @op: The retrieval operation affected
* @n_pages: The number of pages to account for
*
* Drop a reference to a retrieval operation.
*/
@@ -227,6 +254,9 @@ struct fscache_cache_ops {
/* store the updated auxiliary data on an object */
void (*update_object)(struct fscache_object *object);
/* Invalidate an object */
void (*invalidate_object)(struct fscache_operation *op);
/* discard the resources pinned by an object and effect retirement if
* necessary */
void (*drop_object)(struct fscache_object *object);
@@ -301,10 +331,29 @@ struct fscache_cookie {
#define FSCACHE_COOKIE_PENDING_FILL 3 /* T if pending initial fill on object */
#define FSCACHE_COOKIE_FILLING 4 /* T if filling object incrementally */
#define FSCACHE_COOKIE_UNAVAILABLE 5 /* T if cookie is unavailable (error, etc) */
#define FSCACHE_COOKIE_WAITING_ON_READS 6 /* T if cookie is waiting on reads */
#define FSCACHE_COOKIE_INVALIDATING 7 /* T if cookie is being invalidated */
};
extern struct fscache_cookie fscache_fsdef_index;
/*
* Event list for fscache_object::{event_mask,events}
*/
enum {
FSCACHE_OBJECT_EV_REQUEUE, /* T if object should be requeued */
FSCACHE_OBJECT_EV_UPDATE, /* T if object should be updated */
FSCACHE_OBJECT_EV_INVALIDATE, /* T if cache requested object invalidation */
FSCACHE_OBJECT_EV_CLEARED, /* T if accessors all gone */
FSCACHE_OBJECT_EV_ERROR, /* T if fatal error occurred during processing */
FSCACHE_OBJECT_EV_RELEASE, /* T if netfs requested object release */
FSCACHE_OBJECT_EV_RETIRE, /* T if netfs requested object retirement */
FSCACHE_OBJECT_EV_WITHDRAW, /* T if cache requested object withdrawal */
NR_FSCACHE_OBJECT_EVENTS
};
#define FSCACHE_OBJECT_EVENTS_MASK ((1UL << NR_FSCACHE_OBJECT_EVENTS) - 1)
/*
* on-disk cache file or index handle
*/
@@ -317,6 +366,7 @@ struct fscache_object {
/* active states */
FSCACHE_OBJECT_AVAILABLE, /* cleaning up object after creation */
FSCACHE_OBJECT_ACTIVE, /* object is usable */
FSCACHE_OBJECT_INVALIDATING, /* object is invalidating */
FSCACHE_OBJECT_UPDATING, /* object is updating */
/* terminal states */
@@ -332,10 +382,10 @@ struct fscache_object {
int debug_id; /* debugging ID */
int n_children; /* number of child objects */
int n_ops; /* number of ops outstanding on object */
int n_ops; /* number of extant ops on object */
int n_obj_ops; /* number of object ops outstanding on object */
int n_in_progress; /* number of ops in progress */
int n_exclusive; /* number of exclusive ops queued */
int n_exclusive; /* number of exclusive ops queued or in progress */
atomic_t n_reads; /* number of read ops in progress */
spinlock_t lock; /* state and operations lock */
@@ -343,14 +393,6 @@ struct fscache_object {
unsigned long event_mask; /* events this object is interested in */
unsigned long events; /* events to be processed by this object
* (order is important - using fls) */
#define FSCACHE_OBJECT_EV_REQUEUE 0 /* T if object should be requeued */
#define FSCACHE_OBJECT_EV_UPDATE 1 /* T if object should be updated */
#define FSCACHE_OBJECT_EV_CLEARED 2 /* T if accessors all gone */
#define FSCACHE_OBJECT_EV_ERROR 3 /* T if fatal error occurred during processing */
#define FSCACHE_OBJECT_EV_RELEASE 4 /* T if netfs requested object release */
#define FSCACHE_OBJECT_EV_RETIRE 5 /* T if netfs requested object retirement */
#define FSCACHE_OBJECT_EV_WITHDRAW 6 /* T if cache requested object withdrawal */
#define FSCACHE_OBJECT_EVENTS_MASK 0x7f /* mask of all events*/
unsigned long flags;
#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);
extern void fscache_io_error(struct fscache_cache *cache);
extern void fscache_mark_page_cached(struct fscache_retrieval *op,
struct page *page);
extern void fscache_mark_pages_cached(struct fscache_retrieval *op,
struct pagevec *pagevec);
+44 -6
View File
@@ -135,14 +135,14 @@ struct fscache_cookie_def {
*/
void (*put_context)(void *cookie_netfs_data, void *context);
/* indicate pages that now have cache metadata retained
* - this function should mark the specified pages as now being cached
* - the pages will have been marked with PG_fscache before this is
/* indicate page that now have cache metadata retained
* - this function should mark the specified page as now being cached
* - the page will have been marked with PG_fscache before this is
* called, so this is optional
*/
void (*mark_pages_cached)(void *cookie_netfs_data,
struct address_space *mapping,
struct pagevec *cached_pvec);
void (*mark_page_cached)(void *cookie_netfs_data,
struct address_space *mapping,
struct page *page);
/* indicate the cookie is no longer cached
* - this function is called when the backing store currently caching
@@ -185,6 +185,8 @@ extern struct fscache_cookie *__fscache_acquire_cookie(
extern void __fscache_relinquish_cookie(struct fscache_cookie *, int);
extern void __fscache_update_cookie(struct fscache_cookie *);
extern int __fscache_attr_changed(struct fscache_cookie *);
extern void __fscache_invalidate(struct fscache_cookie *);
extern void __fscache_wait_on_invalidate(struct fscache_cookie *);
extern int __fscache_read_or_alloc_page(struct fscache_cookie *,
struct page *,
fscache_rw_complete_t,
@@ -389,6 +391,42 @@ int fscache_attr_changed(struct fscache_cookie *cookie)
return -ENOBUFS;
}
/**
* fscache_invalidate - Notify cache that an object needs invalidation
* @cookie: The cookie representing the cache object
*
* Notify the cache that an object is needs to be invalidated and that it
* should abort any retrievals or stores it is doing on the cache. The object
* is then marked non-caching until such time as the invalidation is complete.
*
* This can be called with spinlocks held.
*
* See Documentation/filesystems/caching/netfs-api.txt for a complete
* description.
*/
static inline
void fscache_invalidate(struct fscache_cookie *cookie)
{
if (fscache_cookie_valid(cookie))
__fscache_invalidate(cookie);
}
/**
* fscache_wait_on_invalidate - Wait for invalidation to complete
* @cookie: The cookie representing the cache object
*
* Wait for the invalidation of an object to complete.
*
* See Documentation/filesystems/caching/netfs-api.txt for a complete
* description.
*/
static inline
void fscache_wait_on_invalidate(struct fscache_cookie *cookie)
{
if (fscache_cookie_valid(cookie))
__fscache_wait_on_invalidate(cookie);
}
/**
* fscache_reserve_space - Reserve data space for a cached object
* @cookie: The cookie representing the cache object
-1
View File
@@ -1007,7 +1007,6 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping,
extern void truncate_pagecache(struct inode *inode, loff_t old, loff_t new);
extern void truncate_setsize(struct inode *inode, loff_t newsize);
extern int vmtruncate(struct inode *inode, loff_t offset);
void truncate_pagecache_range(struct inode *inode, loff_t offset, loff_t end);
int truncate_inode_page(struct address_space *mapping, struct page *page);
int generic_error_remove_page(struct address_space *mapping, struct page *page);
+18 -2
View File
@@ -65,8 +65,8 @@ extern int user_path_at_empty(int, const char __user *, unsigned, struct path *,
extern int kern_path(const char *, unsigned, struct path *);
extern struct dentry *kern_path_create(int, const char *, struct path *, int);
extern struct dentry *user_path_create(int, const char __user *, struct path *, int);
extern struct dentry *kern_path_create(int, const char *, struct path *, unsigned int);
extern struct dentry *user_path_create(int, const char __user *, struct path *, unsigned int);
extern void done_path_create(struct path *, struct dentry *);
extern struct dentry *kern_path_locked(const char *, struct path *);
extern 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)
((char *) name)[min(len, maxlen)] = '\0';
}
/**
* retry_estale - determine whether the caller should retry an operation
* @error: the error that would currently be returned
* @flags: flags being used for next lookup attempt
*
* Check to see if the error code was -ESTALE, and then determine whether
* to retry the call based on whether "flags" already has LOOKUP_REVAL set.
*
* Returns true if the caller should try the operation again.
*/
static inline bool
retry_estale(const long error, const unsigned int flags)
{
return error == -ESTALE && !(flags & LOOKUP_REVAL);
}
#endif /* _LINUX_NAMEI_H */