Loading Documentation/filesystems/caching/backend-api.txt +23 −0 Original line number Diff line number Diff line Loading @@ -676,6 +676,29 @@ FS-Cache provides some utilities that a cache backend may make use of: as possible. (*) Indicate that a stale object was found and discarded: void fscache_object_retrying_stale(struct fscache_object *object); This is called to indicate that the lookup procedure found an object in the cache that the netfs decided was stale. The object has been discarded from the cache and the lookup will be performed again. (*) Indicate that the caching backend killed an object: void fscache_object_mark_killed(struct fscache_object *object, enum fscache_why_object_killed why); This is called to indicate that the cache backend preemptively killed an object. The why parameter should be set to indicate the reason: FSCACHE_OBJECT_IS_STALE - the object was stale and needs discarding. FSCACHE_OBJECT_NO_SPACE - there was insufficient cache space FSCACHE_OBJECT_WAS_RETIRED - the object was retired when relinquished. FSCACHE_OBJECT_WAS_CULLED - the object was culled to make space. (*) Get and release references on a retrieval record: void fscache_get_retrieval(struct fscache_retrieval *op); Loading Documentation/filesystems/caching/fscache.txt +6 −1 Original line number Diff line number Diff line Loading @@ -284,8 +284,9 @@ proc files. enq=N Number of times async ops queued for processing can=N Number of async ops cancelled rej=N Number of async ops rejected due to object lookup/create failure ini=N Number of async ops initialised dfr=N Number of async ops queued for deferred release rel=N Number of async ops released rel=N Number of async ops released (should equal ini=N when idle) gc=N Number of deferred-release async ops garbage collected CacheOp alo=N Number of in-progress alloc_object() cache ops luo=N Number of in-progress lookup_object() cache ops Loading @@ -303,6 +304,10 @@ proc files. wrp=N Number of in-progress write_page() cache ops ucp=N Number of in-progress uncache_page() cache ops dsp=N Number of in-progress dissociate_pages() cache ops CacheEv nsp=N Number of object lookups/creations rejected due to lack of space stl=N Number of stale objects deleted rtr=N Number of objects retired when relinquished cul=N Number of objects culled (*) /proc/fs/fscache/histogram Loading fs/cachefiles/internal.h +0 −1 Original line number Diff line number Diff line Loading @@ -43,7 +43,6 @@ struct cachefiles_object { loff_t i_size; /* object size */ unsigned long flags; #define CACHEFILES_OBJECT_ACTIVE 0 /* T if marked active */ #define CACHEFILES_OBJECT_BURIED 1 /* T if preemptively buried */ atomic_t usage; /* object usage count */ uint8_t type; /* object type */ uint8_t new; /* T if object new */ Loading fs/cachefiles/namei.c +21 −12 Original line number Diff line number Diff line Loading @@ -97,7 +97,8 @@ static noinline void cachefiles_printk_object(struct cachefiles_object *object, * call vfs_unlink(), vfs_rmdir() or vfs_rename() */ static void cachefiles_mark_object_buried(struct cachefiles_cache *cache, struct dentry *dentry) struct dentry *dentry, enum fscache_why_object_killed why) { struct cachefiles_object *object; struct rb_node *p; Loading Loading @@ -132,8 +133,9 @@ static void cachefiles_mark_object_buried(struct cachefiles_cache *cache, pr_err("\n"); pr_err("Error: Can't preemptively bury live object\n"); cachefiles_printk_object(object, NULL); } else if (test_and_set_bit(CACHEFILES_OBJECT_BURIED, &object->flags)) { pr_err("Error: Object already preemptively buried\n"); } else { if (why != FSCACHE_OBJECT_IS_STALE) fscache_object_mark_killed(&object->fscache, why); } write_unlock(&cache->active_lock); Loading Loading @@ -265,7 +267,8 @@ static int cachefiles_mark_object_active(struct cachefiles_cache *cache, static int cachefiles_bury_object(struct cachefiles_cache *cache, struct dentry *dir, struct dentry *rep, bool preemptive) bool preemptive, enum fscache_why_object_killed why) { struct dentry *grave, *trap; struct path path, path_to_graveyard; Loading @@ -289,7 +292,7 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache, ret = vfs_unlink(d_inode(dir), rep, NULL); if (preemptive) cachefiles_mark_object_buried(cache, rep); cachefiles_mark_object_buried(cache, rep, why); } mutex_unlock(&d_inode(dir)->i_mutex); Loading Loading @@ -394,7 +397,7 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache, "Rename failed with error %d", ret); if (preemptive) cachefiles_mark_object_buried(cache, rep); cachefiles_mark_object_buried(cache, rep, why); } unlock_rename(cache->graveyard, dir); Loading Loading @@ -422,7 +425,7 @@ int cachefiles_delete_object(struct cachefiles_cache *cache, mutex_lock_nested(&d_inode(dir)->i_mutex, I_MUTEX_PARENT); if (test_bit(CACHEFILES_OBJECT_BURIED, &object->flags)) { if (test_bit(FSCACHE_OBJECT_KILLED_BY_CACHE, &object->fscache.flags)) { /* object allocation for the same key preemptively deleted this * object's file so that it could create its own file */ _debug("object preemptively buried"); Loading @@ -433,7 +436,8 @@ int cachefiles_delete_object(struct cachefiles_cache *cache, * may have been renamed */ if (dir == object->dentry->d_parent) { ret = cachefiles_bury_object(cache, dir, object->dentry, false); object->dentry, false, FSCACHE_OBJECT_WAS_RETIRED); } else { /* it got moved, presumably by cachefilesd culling it, * so it's no longer in the key path and we can ignore Loading Loading @@ -522,7 +526,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, if (d_is_negative(next)) { ret = cachefiles_has_space(cache, 1, 0); if (ret < 0) goto create_error; goto no_space_error; path.dentry = dir; ret = security_path_mkdir(&path, next, 0); Loading Loading @@ -551,7 +555,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, if (d_is_negative(next)) { ret = cachefiles_has_space(cache, 1, 0); if (ret < 0) goto create_error; goto no_space_error; path.dentry = dir; ret = security_path_mknod(&path, next, S_IFREG, 0); Loading Loading @@ -602,7 +606,8 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, * mutex) */ object->dentry = NULL; ret = cachefiles_bury_object(cache, dir, next, true); ret = cachefiles_bury_object(cache, dir, next, true, FSCACHE_OBJECT_IS_STALE); dput(next); next = NULL; Loading @@ -610,6 +615,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, goto delete_error; _debug("redo lookup"); fscache_object_retrying_stale(&object->fscache); goto lookup_again; } } Loading Loading @@ -662,6 +668,8 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, _leave(" = 0 [%lu]", d_backing_inode(object->dentry)->i_ino); return 0; no_space_error: fscache_object_mark_killed(&object->fscache, FSCACHE_OBJECT_NO_SPACE); create_error: _debug("create error %d", ret); if (ret == -EIO) Loading Loading @@ -927,7 +935,8 @@ int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir, /* actually remove the victim (drops the dir mutex) */ _debug("bury"); ret = cachefiles_bury_object(cache, dir, victim, false); ret = cachefiles_bury_object(cache, dir, victim, false, FSCACHE_OBJECT_WAS_CULLED); if (ret < 0) goto error; Loading fs/fscache/cookie.c +4 −4 Original line number Diff line number Diff line Loading @@ -327,7 +327,8 @@ static int fscache_alloc_object(struct fscache_cache *cache, object_already_extant: ret = -ENOBUFS; if (fscache_object_is_dead(object)) { if (fscache_object_is_dying(object) || fscache_cache_is_broken(object)) { spin_unlock(&cookie->lock); goto error; } Loading Loading @@ -671,7 +672,7 @@ int __fscache_check_consistency(struct fscache_cookie *cookie) if (!op) return -ENOMEM; fscache_operation_init(op, NULL, NULL); fscache_operation_init(op, NULL, NULL, NULL); op->flags = FSCACHE_OP_MYTHREAD | (1 << FSCACHE_OP_WAITING) | (1 << FSCACHE_OP_UNUSE_COOKIE); Loading @@ -695,8 +696,7 @@ int __fscache_check_consistency(struct fscache_cookie *cookie) /* the work queue now carries its own ref on the object */ spin_unlock(&cookie->lock); ret = fscache_wait_for_operation_activation(object, op, NULL, NULL, NULL); ret = fscache_wait_for_operation_activation(object, op, NULL, NULL); if (ret == 0) { /* ask the cache to honour the operation */ ret = object->cache->ops->check_consistency(op); Loading Loading
Documentation/filesystems/caching/backend-api.txt +23 −0 Original line number Diff line number Diff line Loading @@ -676,6 +676,29 @@ FS-Cache provides some utilities that a cache backend may make use of: as possible. (*) Indicate that a stale object was found and discarded: void fscache_object_retrying_stale(struct fscache_object *object); This is called to indicate that the lookup procedure found an object in the cache that the netfs decided was stale. The object has been discarded from the cache and the lookup will be performed again. (*) Indicate that the caching backend killed an object: void fscache_object_mark_killed(struct fscache_object *object, enum fscache_why_object_killed why); This is called to indicate that the cache backend preemptively killed an object. The why parameter should be set to indicate the reason: FSCACHE_OBJECT_IS_STALE - the object was stale and needs discarding. FSCACHE_OBJECT_NO_SPACE - there was insufficient cache space FSCACHE_OBJECT_WAS_RETIRED - the object was retired when relinquished. FSCACHE_OBJECT_WAS_CULLED - the object was culled to make space. (*) Get and release references on a retrieval record: void fscache_get_retrieval(struct fscache_retrieval *op); Loading
Documentation/filesystems/caching/fscache.txt +6 −1 Original line number Diff line number Diff line Loading @@ -284,8 +284,9 @@ proc files. enq=N Number of times async ops queued for processing can=N Number of async ops cancelled rej=N Number of async ops rejected due to object lookup/create failure ini=N Number of async ops initialised dfr=N Number of async ops queued for deferred release rel=N Number of async ops released rel=N Number of async ops released (should equal ini=N when idle) gc=N Number of deferred-release async ops garbage collected CacheOp alo=N Number of in-progress alloc_object() cache ops luo=N Number of in-progress lookup_object() cache ops Loading @@ -303,6 +304,10 @@ proc files. wrp=N Number of in-progress write_page() cache ops ucp=N Number of in-progress uncache_page() cache ops dsp=N Number of in-progress dissociate_pages() cache ops CacheEv nsp=N Number of object lookups/creations rejected due to lack of space stl=N Number of stale objects deleted rtr=N Number of objects retired when relinquished cul=N Number of objects culled (*) /proc/fs/fscache/histogram Loading
fs/cachefiles/internal.h +0 −1 Original line number Diff line number Diff line Loading @@ -43,7 +43,6 @@ struct cachefiles_object { loff_t i_size; /* object size */ unsigned long flags; #define CACHEFILES_OBJECT_ACTIVE 0 /* T if marked active */ #define CACHEFILES_OBJECT_BURIED 1 /* T if preemptively buried */ atomic_t usage; /* object usage count */ uint8_t type; /* object type */ uint8_t new; /* T if object new */ Loading
fs/cachefiles/namei.c +21 −12 Original line number Diff line number Diff line Loading @@ -97,7 +97,8 @@ static noinline void cachefiles_printk_object(struct cachefiles_object *object, * call vfs_unlink(), vfs_rmdir() or vfs_rename() */ static void cachefiles_mark_object_buried(struct cachefiles_cache *cache, struct dentry *dentry) struct dentry *dentry, enum fscache_why_object_killed why) { struct cachefiles_object *object; struct rb_node *p; Loading Loading @@ -132,8 +133,9 @@ static void cachefiles_mark_object_buried(struct cachefiles_cache *cache, pr_err("\n"); pr_err("Error: Can't preemptively bury live object\n"); cachefiles_printk_object(object, NULL); } else if (test_and_set_bit(CACHEFILES_OBJECT_BURIED, &object->flags)) { pr_err("Error: Object already preemptively buried\n"); } else { if (why != FSCACHE_OBJECT_IS_STALE) fscache_object_mark_killed(&object->fscache, why); } write_unlock(&cache->active_lock); Loading Loading @@ -265,7 +267,8 @@ static int cachefiles_mark_object_active(struct cachefiles_cache *cache, static int cachefiles_bury_object(struct cachefiles_cache *cache, struct dentry *dir, struct dentry *rep, bool preemptive) bool preemptive, enum fscache_why_object_killed why) { struct dentry *grave, *trap; struct path path, path_to_graveyard; Loading @@ -289,7 +292,7 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache, ret = vfs_unlink(d_inode(dir), rep, NULL); if (preemptive) cachefiles_mark_object_buried(cache, rep); cachefiles_mark_object_buried(cache, rep, why); } mutex_unlock(&d_inode(dir)->i_mutex); Loading Loading @@ -394,7 +397,7 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache, "Rename failed with error %d", ret); if (preemptive) cachefiles_mark_object_buried(cache, rep); cachefiles_mark_object_buried(cache, rep, why); } unlock_rename(cache->graveyard, dir); Loading Loading @@ -422,7 +425,7 @@ int cachefiles_delete_object(struct cachefiles_cache *cache, mutex_lock_nested(&d_inode(dir)->i_mutex, I_MUTEX_PARENT); if (test_bit(CACHEFILES_OBJECT_BURIED, &object->flags)) { if (test_bit(FSCACHE_OBJECT_KILLED_BY_CACHE, &object->fscache.flags)) { /* object allocation for the same key preemptively deleted this * object's file so that it could create its own file */ _debug("object preemptively buried"); Loading @@ -433,7 +436,8 @@ int cachefiles_delete_object(struct cachefiles_cache *cache, * may have been renamed */ if (dir == object->dentry->d_parent) { ret = cachefiles_bury_object(cache, dir, object->dentry, false); object->dentry, false, FSCACHE_OBJECT_WAS_RETIRED); } else { /* it got moved, presumably by cachefilesd culling it, * so it's no longer in the key path and we can ignore Loading Loading @@ -522,7 +526,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, if (d_is_negative(next)) { ret = cachefiles_has_space(cache, 1, 0); if (ret < 0) goto create_error; goto no_space_error; path.dentry = dir; ret = security_path_mkdir(&path, next, 0); Loading Loading @@ -551,7 +555,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, if (d_is_negative(next)) { ret = cachefiles_has_space(cache, 1, 0); if (ret < 0) goto create_error; goto no_space_error; path.dentry = dir; ret = security_path_mknod(&path, next, S_IFREG, 0); Loading Loading @@ -602,7 +606,8 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, * mutex) */ object->dentry = NULL; ret = cachefiles_bury_object(cache, dir, next, true); ret = cachefiles_bury_object(cache, dir, next, true, FSCACHE_OBJECT_IS_STALE); dput(next); next = NULL; Loading @@ -610,6 +615,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, goto delete_error; _debug("redo lookup"); fscache_object_retrying_stale(&object->fscache); goto lookup_again; } } Loading Loading @@ -662,6 +668,8 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, _leave(" = 0 [%lu]", d_backing_inode(object->dentry)->i_ino); return 0; no_space_error: fscache_object_mark_killed(&object->fscache, FSCACHE_OBJECT_NO_SPACE); create_error: _debug("create error %d", ret); if (ret == -EIO) Loading Loading @@ -927,7 +935,8 @@ int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir, /* actually remove the victim (drops the dir mutex) */ _debug("bury"); ret = cachefiles_bury_object(cache, dir, victim, false); ret = cachefiles_bury_object(cache, dir, victim, false, FSCACHE_OBJECT_WAS_CULLED); if (ret < 0) goto error; Loading
fs/fscache/cookie.c +4 −4 Original line number Diff line number Diff line Loading @@ -327,7 +327,8 @@ static int fscache_alloc_object(struct fscache_cache *cache, object_already_extant: ret = -ENOBUFS; if (fscache_object_is_dead(object)) { if (fscache_object_is_dying(object) || fscache_cache_is_broken(object)) { spin_unlock(&cookie->lock); goto error; } Loading Loading @@ -671,7 +672,7 @@ int __fscache_check_consistency(struct fscache_cookie *cookie) if (!op) return -ENOMEM; fscache_operation_init(op, NULL, NULL); fscache_operation_init(op, NULL, NULL, NULL); op->flags = FSCACHE_OP_MYTHREAD | (1 << FSCACHE_OP_WAITING) | (1 << FSCACHE_OP_UNUSE_COOKIE); Loading @@ -695,8 +696,7 @@ int __fscache_check_consistency(struct fscache_cookie *cookie) /* the work queue now carries its own ref on the object */ spin_unlock(&cookie->lock); ret = fscache_wait_for_operation_activation(object, op, NULL, NULL, NULL); ret = fscache_wait_for_operation_activation(object, op, NULL, NULL); if (ret == 0) { /* ask the cache to honour the operation */ ret = object->cache->ops->check_consistency(op); Loading