aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cachefiles/namei.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2018-04-04 13:41:27 +0100
committerDavid Howells <dhowells@redhat.com>2018-04-04 13:41:27 +0100
commita18feb55769b705a44c4107786c4045eae2e87b6 (patch)
tree3db7d160e672aa9f16a0437b767b3d3bbb10ecc8 /fs/cachefiles/namei.c
parentfscache: Fix hanging wait on page discarded by writeback (diff)
downloadlinux-dev-a18feb55769b705a44c4107786c4045eae2e87b6.tar.xz
linux-dev-a18feb55769b705a44c4107786c4045eae2e87b6.zip
fscache: Add tracepoints
Add some tracepoints to fscache: (*) fscache_cookie - Tracks a cookie's usage count. (*) fscache_netfs - Logs registration of a network filesystem, including the pointer to the cookie allocated. (*) fscache_acquire - Logs cookie acquisition. (*) fscache_relinquish - Logs cookie relinquishment. (*) fscache_enable - Logs enablement of a cookie. (*) fscache_disable - Logs disablement of a cookie. (*) fscache_osm - Tracks execution of states in the object state machine. and cachefiles: (*) cachefiles_ref - Tracks a cachefiles object's usage count. (*) cachefiles_lookup - Logs result of lookup_one_len(). (*) cachefiles_mkdir - Logs result of vfs_mkdir(). (*) cachefiles_create - Logs result of vfs_create(). (*) cachefiles_unlink - Logs calls to vfs_unlink(). (*) cachefiles_rename - Logs calls to vfs_rename(). (*) cachefiles_mark_active - Logs an object becoming active. (*) cachefiles_wait_active - Logs a wait for an old object to be destroyed. (*) cachefiles_mark_inactive - Logs an object becoming inactive. (*) cachefiles_mark_buried - Logs the burial of an object. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/cachefiles/namei.c')
-rw-r--r--fs/cachefiles/namei.c42
1 files changed, 33 insertions, 9 deletions
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
index 3978b324cbca..5fc214256316 100644
--- a/fs/cachefiles/namei.c
+++ b/fs/cachefiles/namei.c
@@ -120,6 +120,7 @@ static void cachefiles_mark_object_buried(struct cachefiles_cache *cache,
}
write_unlock(&cache->active_lock);
+ trace_cachefiles_mark_buried(NULL, dentry, why);
_leave(" [no owner]");
return;
@@ -130,6 +131,8 @@ found_dentry:
object->fscache.state->name,
dentry);
+ trace_cachefiles_mark_buried(object, dentry, why);
+
if (fscache_object_is_live(&object->fscache)) {
pr_err("\n");
pr_err("Error: Can't preemptively bury live object\n");
@@ -158,13 +161,15 @@ static int cachefiles_mark_object_active(struct cachefiles_cache *cache,
try_again:
write_lock(&cache->active_lock);
+ dentry = object->dentry;
+ trace_cachefiles_mark_active(object, dentry);
+
if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) {
pr_err("Error: Object already active\n");
cachefiles_printk_object(object, NULL);
BUG();
}
- dentry = object->dentry;
_p = &cache->active_nodes.rb_node;
while (*_p) {
_parent = *_p;
@@ -191,6 +196,8 @@ try_again:
/* an old object from a previous incarnation is hogging the slot - we
* need to wait for it to be destroyed */
wait_for_old_object:
+ trace_cachefiles_wait_active(object, dentry, xobject);
+
if (fscache_object_is_live(&xobject->fscache)) {
pr_err("\n");
pr_err("Error: Unexpected object collision\n");
@@ -248,12 +255,12 @@ wait_for_old_object:
ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags));
- cache->cache.ops->put_object(&xobject->fscache);
+ cache->cache.ops->put_object(&xobject->fscache, cachefiles_obj_put_wait_retry);
goto try_again;
requeue:
clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
- cache->cache.ops->put_object(&xobject->fscache);
+ cache->cache.ops->put_object(&xobject->fscache, cachefiles_obj_put_wait_timeo);
_leave(" = -ETIMEDOUT");
return -ETIMEDOUT;
}
@@ -265,6 +272,11 @@ void cachefiles_mark_object_inactive(struct cachefiles_cache *cache,
struct cachefiles_object *object,
blkcnt_t i_blocks)
{
+ struct dentry *dentry = object->dentry;
+ struct inode *inode = d_backing_inode(dentry);
+
+ trace_cachefiles_mark_inactive(object, dentry, inode);
+
write_lock(&cache->active_lock);
rb_erase(&object->active_node, &cache->active_nodes);
clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
@@ -288,6 +300,7 @@ void cachefiles_mark_object_inactive(struct cachefiles_cache *cache,
* - unlocks the directory mutex
*/
static int cachefiles_bury_object(struct cachefiles_cache *cache,
+ struct cachefiles_object *object,
struct dentry *dir,
struct dentry *rep,
bool preemptive,
@@ -312,6 +325,7 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache,
if (ret < 0) {
cachefiles_io_error(cache, "Unlink security error");
} else {
+ trace_cachefiles_unlink(object, rep, why);
ret = vfs_unlink(d_inode(dir), rep, NULL);
if (preemptive)
@@ -413,6 +427,7 @@ try_again:
if (ret < 0) {
cachefiles_io_error(cache, "Rename security error %d", ret);
} else {
+ trace_cachefiles_rename(object, rep, grave, why);
ret = vfs_rename(d_inode(dir), rep,
d_inode(cache->graveyard), grave, NULL, 0);
if (ret != 0 && ret != -ENOMEM)
@@ -458,7 +473,7 @@ int cachefiles_delete_object(struct cachefiles_cache *cache,
/* we need to check that our parent is _still_ our parent - it
* may have been renamed */
if (dir == object->dentry->d_parent) {
- ret = cachefiles_bury_object(cache, dir,
+ ret = cachefiles_bury_object(cache, object, dir,
object->dentry, false,
FSCACHE_OBJECT_WAS_RETIRED);
} else {
@@ -486,6 +501,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent,
{
struct cachefiles_cache *cache;
struct dentry *dir, *next = NULL;
+ struct inode *inode;
struct path path;
unsigned long start;
const char *name;
@@ -529,13 +545,17 @@ lookup_again:
start = jiffies;
next = lookup_one_len(name, dir, nlen);
cachefiles_hist(cachefiles_lookup_histogram, start);
- if (IS_ERR(next))
+ if (IS_ERR(next)) {
+ trace_cachefiles_lookup(object, next, NULL);
goto lookup_error;
+ }
- _debug("next -> %p %s", next, d_backing_inode(next) ? "positive" : "negative");
+ inode = d_backing_inode(next);
+ trace_cachefiles_lookup(object, next, inode);
+ _debug("next -> %p %s", next, inode ? "positive" : "negative");
if (!key)
- object->new = !d_backing_inode(next);
+ object->new = !inode;
/* if this element of the path doesn't exist, then the lookup phase
* failed, and we can release any readers in the certain knowledge that
@@ -558,6 +578,8 @@ lookup_again:
start = jiffies;
ret = vfs_mkdir(d_inode(dir), next, 0);
cachefiles_hist(cachefiles_mkdir_histogram, start);
+ if (!key)
+ trace_cachefiles_mkdir(object, next, ret);
if (ret < 0)
goto create_error;
@@ -587,6 +609,7 @@ lookup_again:
start = jiffies;
ret = vfs_create(d_inode(dir), next, S_IFREG, true);
cachefiles_hist(cachefiles_create_histogram, start);
+ trace_cachefiles_create(object, next, ret);
if (ret < 0)
goto create_error;
@@ -629,7 +652,8 @@ lookup_again:
* mutex) */
object->dentry = NULL;
- ret = cachefiles_bury_object(cache, dir, next, true,
+ ret = cachefiles_bury_object(cache, object, dir, next,
+ true,
FSCACHE_OBJECT_IS_STALE);
dput(next);
next = NULL;
@@ -955,7 +979,7 @@ 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, NULL, dir, victim, false,
FSCACHE_OBJECT_WAS_CULLED);
if (ret < 0)
goto error;