diff options
author | David Howells <dhowells@redhat.com> | 2018-04-04 08:41:27 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2018-04-04 08:41:27 -0400 |
commit | a18feb55769b705a44c4107786c4045eae2e87b6 (patch) | |
tree | 3db7d160e672aa9f16a0437b767b3d3bbb10ecc8 /fs/cachefiles/namei.c | |
parent | 2c98425720233ae3e135add0c7e869b32913502f (diff) |
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.c | 42 |
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, | |||
120 | } | 120 | } |
121 | 121 | ||
122 | write_unlock(&cache->active_lock); | 122 | write_unlock(&cache->active_lock); |
123 | trace_cachefiles_mark_buried(NULL, dentry, why); | ||
123 | _leave(" [no owner]"); | 124 | _leave(" [no owner]"); |
124 | return; | 125 | return; |
125 | 126 | ||
@@ -130,6 +131,8 @@ found_dentry: | |||
130 | object->fscache.state->name, | 131 | object->fscache.state->name, |
131 | dentry); | 132 | dentry); |
132 | 133 | ||
134 | trace_cachefiles_mark_buried(object, dentry, why); | ||
135 | |||
133 | if (fscache_object_is_live(&object->fscache)) { | 136 | if (fscache_object_is_live(&object->fscache)) { |
134 | pr_err("\n"); | 137 | pr_err("\n"); |
135 | pr_err("Error: Can't preemptively bury live object\n"); | 138 | pr_err("Error: Can't preemptively bury live object\n"); |
@@ -158,13 +161,15 @@ static int cachefiles_mark_object_active(struct cachefiles_cache *cache, | |||
158 | try_again: | 161 | try_again: |
159 | write_lock(&cache->active_lock); | 162 | write_lock(&cache->active_lock); |
160 | 163 | ||
164 | dentry = object->dentry; | ||
165 | trace_cachefiles_mark_active(object, dentry); | ||
166 | |||
161 | if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) { | 167 | if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) { |
162 | pr_err("Error: Object already active\n"); | 168 | pr_err("Error: Object already active\n"); |
163 | cachefiles_printk_object(object, NULL); | 169 | cachefiles_printk_object(object, NULL); |
164 | BUG(); | 170 | BUG(); |
165 | } | 171 | } |
166 | 172 | ||
167 | dentry = object->dentry; | ||
168 | _p = &cache->active_nodes.rb_node; | 173 | _p = &cache->active_nodes.rb_node; |
169 | while (*_p) { | 174 | while (*_p) { |
170 | _parent = *_p; | 175 | _parent = *_p; |
@@ -191,6 +196,8 @@ try_again: | |||
191 | /* an old object from a previous incarnation is hogging the slot - we | 196 | /* an old object from a previous incarnation is hogging the slot - we |
192 | * need to wait for it to be destroyed */ | 197 | * need to wait for it to be destroyed */ |
193 | wait_for_old_object: | 198 | wait_for_old_object: |
199 | trace_cachefiles_wait_active(object, dentry, xobject); | ||
200 | |||
194 | if (fscache_object_is_live(&xobject->fscache)) { | 201 | if (fscache_object_is_live(&xobject->fscache)) { |
195 | pr_err("\n"); | 202 | pr_err("\n"); |
196 | pr_err("Error: Unexpected object collision\n"); | 203 | pr_err("Error: Unexpected object collision\n"); |
@@ -248,12 +255,12 @@ wait_for_old_object: | |||
248 | 255 | ||
249 | ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)); | 256 | ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)); |
250 | 257 | ||
251 | cache->cache.ops->put_object(&xobject->fscache); | 258 | cache->cache.ops->put_object(&xobject->fscache, cachefiles_obj_put_wait_retry); |
252 | goto try_again; | 259 | goto try_again; |
253 | 260 | ||
254 | requeue: | 261 | requeue: |
255 | clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags); | 262 | clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags); |
256 | cache->cache.ops->put_object(&xobject->fscache); | 263 | cache->cache.ops->put_object(&xobject->fscache, cachefiles_obj_put_wait_timeo); |
257 | _leave(" = -ETIMEDOUT"); | 264 | _leave(" = -ETIMEDOUT"); |
258 | return -ETIMEDOUT; | 265 | return -ETIMEDOUT; |
259 | } | 266 | } |
@@ -265,6 +272,11 @@ void cachefiles_mark_object_inactive(struct cachefiles_cache *cache, | |||
265 | struct cachefiles_object *object, | 272 | struct cachefiles_object *object, |
266 | blkcnt_t i_blocks) | 273 | blkcnt_t i_blocks) |
267 | { | 274 | { |
275 | struct dentry *dentry = object->dentry; | ||
276 | struct inode *inode = d_backing_inode(dentry); | ||
277 | |||
278 | trace_cachefiles_mark_inactive(object, dentry, inode); | ||
279 | |||
268 | write_lock(&cache->active_lock); | 280 | write_lock(&cache->active_lock); |
269 | rb_erase(&object->active_node, &cache->active_nodes); | 281 | rb_erase(&object->active_node, &cache->active_nodes); |
270 | clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags); | 282 | clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags); |
@@ -288,6 +300,7 @@ void cachefiles_mark_object_inactive(struct cachefiles_cache *cache, | |||
288 | * - unlocks the directory mutex | 300 | * - unlocks the directory mutex |
289 | */ | 301 | */ |
290 | static int cachefiles_bury_object(struct cachefiles_cache *cache, | 302 | static int cachefiles_bury_object(struct cachefiles_cache *cache, |
303 | struct cachefiles_object *object, | ||
291 | struct dentry *dir, | 304 | struct dentry *dir, |
292 | struct dentry *rep, | 305 | struct dentry *rep, |
293 | bool preemptive, | 306 | bool preemptive, |
@@ -312,6 +325,7 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache, | |||
312 | if (ret < 0) { | 325 | if (ret < 0) { |
313 | cachefiles_io_error(cache, "Unlink security error"); | 326 | cachefiles_io_error(cache, "Unlink security error"); |
314 | } else { | 327 | } else { |
328 | trace_cachefiles_unlink(object, rep, why); | ||
315 | ret = vfs_unlink(d_inode(dir), rep, NULL); | 329 | ret = vfs_unlink(d_inode(dir), rep, NULL); |
316 | 330 | ||
317 | if (preemptive) | 331 | if (preemptive) |
@@ -413,6 +427,7 @@ try_again: | |||
413 | if (ret < 0) { | 427 | if (ret < 0) { |
414 | cachefiles_io_error(cache, "Rename security error %d", ret); | 428 | cachefiles_io_error(cache, "Rename security error %d", ret); |
415 | } else { | 429 | } else { |
430 | trace_cachefiles_rename(object, rep, grave, why); | ||
416 | ret = vfs_rename(d_inode(dir), rep, | 431 | ret = vfs_rename(d_inode(dir), rep, |
417 | d_inode(cache->graveyard), grave, NULL, 0); | 432 | d_inode(cache->graveyard), grave, NULL, 0); |
418 | if (ret != 0 && ret != -ENOMEM) | 433 | if (ret != 0 && ret != -ENOMEM) |
@@ -458,7 +473,7 @@ int cachefiles_delete_object(struct cachefiles_cache *cache, | |||
458 | /* we need to check that our parent is _still_ our parent - it | 473 | /* we need to check that our parent is _still_ our parent - it |
459 | * may have been renamed */ | 474 | * may have been renamed */ |
460 | if (dir == object->dentry->d_parent) { | 475 | if (dir == object->dentry->d_parent) { |
461 | ret = cachefiles_bury_object(cache, dir, | 476 | ret = cachefiles_bury_object(cache, object, dir, |
462 | object->dentry, false, | 477 | object->dentry, false, |
463 | FSCACHE_OBJECT_WAS_RETIRED); | 478 | FSCACHE_OBJECT_WAS_RETIRED); |
464 | } else { | 479 | } else { |
@@ -486,6 +501,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, | |||
486 | { | 501 | { |
487 | struct cachefiles_cache *cache; | 502 | struct cachefiles_cache *cache; |
488 | struct dentry *dir, *next = NULL; | 503 | struct dentry *dir, *next = NULL; |
504 | struct inode *inode; | ||
489 | struct path path; | 505 | struct path path; |
490 | unsigned long start; | 506 | unsigned long start; |
491 | const char *name; | 507 | const char *name; |
@@ -529,13 +545,17 @@ lookup_again: | |||
529 | start = jiffies; | 545 | start = jiffies; |
530 | next = lookup_one_len(name, dir, nlen); | 546 | next = lookup_one_len(name, dir, nlen); |
531 | cachefiles_hist(cachefiles_lookup_histogram, start); | 547 | cachefiles_hist(cachefiles_lookup_histogram, start); |
532 | if (IS_ERR(next)) | 548 | if (IS_ERR(next)) { |
549 | trace_cachefiles_lookup(object, next, NULL); | ||
533 | goto lookup_error; | 550 | goto lookup_error; |
551 | } | ||
534 | 552 | ||
535 | _debug("next -> %p %s", next, d_backing_inode(next) ? "positive" : "negative"); | 553 | inode = d_backing_inode(next); |
554 | trace_cachefiles_lookup(object, next, inode); | ||
555 | _debug("next -> %p %s", next, inode ? "positive" : "negative"); | ||
536 | 556 | ||
537 | if (!key) | 557 | if (!key) |
538 | object->new = !d_backing_inode(next); | 558 | object->new = !inode; |
539 | 559 | ||
540 | /* if this element of the path doesn't exist, then the lookup phase | 560 | /* if this element of the path doesn't exist, then the lookup phase |
541 | * failed, and we can release any readers in the certain knowledge that | 561 | * failed, and we can release any readers in the certain knowledge that |
@@ -558,6 +578,8 @@ lookup_again: | |||
558 | start = jiffies; | 578 | start = jiffies; |
559 | ret = vfs_mkdir(d_inode(dir), next, 0); | 579 | ret = vfs_mkdir(d_inode(dir), next, 0); |
560 | cachefiles_hist(cachefiles_mkdir_histogram, start); | 580 | cachefiles_hist(cachefiles_mkdir_histogram, start); |
581 | if (!key) | ||
582 | trace_cachefiles_mkdir(object, next, ret); | ||
561 | if (ret < 0) | 583 | if (ret < 0) |
562 | goto create_error; | 584 | goto create_error; |
563 | 585 | ||
@@ -587,6 +609,7 @@ lookup_again: | |||
587 | start = jiffies; | 609 | start = jiffies; |
588 | ret = vfs_create(d_inode(dir), next, S_IFREG, true); | 610 | ret = vfs_create(d_inode(dir), next, S_IFREG, true); |
589 | cachefiles_hist(cachefiles_create_histogram, start); | 611 | cachefiles_hist(cachefiles_create_histogram, start); |
612 | trace_cachefiles_create(object, next, ret); | ||
590 | if (ret < 0) | 613 | if (ret < 0) |
591 | goto create_error; | 614 | goto create_error; |
592 | 615 | ||
@@ -629,7 +652,8 @@ lookup_again: | |||
629 | * mutex) */ | 652 | * mutex) */ |
630 | object->dentry = NULL; | 653 | object->dentry = NULL; |
631 | 654 | ||
632 | ret = cachefiles_bury_object(cache, dir, next, true, | 655 | ret = cachefiles_bury_object(cache, object, dir, next, |
656 | true, | ||
633 | FSCACHE_OBJECT_IS_STALE); | 657 | FSCACHE_OBJECT_IS_STALE); |
634 | dput(next); | 658 | dput(next); |
635 | next = NULL; | 659 | next = NULL; |
@@ -955,7 +979,7 @@ int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir, | |||
955 | /* actually remove the victim (drops the dir mutex) */ | 979 | /* actually remove the victim (drops the dir mutex) */ |
956 | _debug("bury"); | 980 | _debug("bury"); |
957 | 981 | ||
958 | ret = cachefiles_bury_object(cache, dir, victim, false, | 982 | ret = cachefiles_bury_object(cache, NULL, dir, victim, false, |
959 | FSCACHE_OBJECT_WAS_CULLED); | 983 | FSCACHE_OBJECT_WAS_CULLED); |
960 | if (ret < 0) | 984 | if (ret < 0) |
961 | goto error; | 985 | goto error; |