diff options
Diffstat (limited to 'fs/afs')
-rw-r--r-- | fs/afs/cell.c | 2 | ||||
-rw-r--r-- | fs/afs/fs_operation.c | 4 | ||||
-rw-r--r-- | fs/afs/internal.h | 10 | ||||
-rw-r--r-- | fs/afs/super.c | 10 | ||||
-rw-r--r-- | fs/afs/vl_alias.c | 9 | ||||
-rw-r--r-- | fs/afs/volume.c | 27 |
6 files changed, 39 insertions, 23 deletions
diff --git a/fs/afs/cell.c b/fs/afs/cell.c index 212098514ebf..8bfc8a05fd46 100644 --- a/fs/afs/cell.c +++ b/fs/afs/cell.c @@ -482,7 +482,7 @@ static void afs_cell_destroy(struct rcu_head *rcu) ASSERTCMP(atomic_read(&cell->usage), ==, 0); - afs_put_volume(cell->net, cell->root_volume); + afs_put_volume(cell->net, cell->root_volume, afs_volume_trace_put_cell_root); afs_put_vlserverlist(cell->net, rcu_access_pointer(cell->vl_servers)); afs_put_cell(cell->net, cell->alias_of); key_put(cell->anonymous_key); diff --git a/fs/afs/fs_operation.c b/fs/afs/fs_operation.c index f7a768d12141..f57efd9d2db0 100644 --- a/fs/afs/fs_operation.c +++ b/fs/afs/fs_operation.c @@ -36,7 +36,7 @@ struct afs_operation *afs_alloc_operation(struct key *key, struct afs_volume *vo } op->key = key; - op->volume = afs_get_volume(volume); + op->volume = afs_get_volume(volume, afs_volume_trace_get_new_op); op->net = volume->cell->net; op->cb_v_break = volume->cb_v_break; op->debug_id = atomic_inc_return(&afs_operation_debug_counter); @@ -233,7 +233,7 @@ int afs_put_operation(struct afs_operation *op) afs_end_cursor(&op->ac); afs_put_cb_interest(op->net, op->cbi); afs_put_serverlist(op->net, op->server_list); - afs_put_volume(op->net, op->volume); + afs_put_volume(op->net, op->volume, afs_volume_trace_put_put_op); kfree(op); return ret; } diff --git a/fs/afs/internal.h b/fs/afs/internal.h index a3ef97d560ca..e084936066b0 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -1429,17 +1429,11 @@ extern struct afs_vlserver_list *afs_extract_vlserver_list(struct afs_cell *, /* * volume.c */ -static inline struct afs_volume *afs_get_volume(struct afs_volume *volume) -{ - if (volume) - atomic_inc(&volume->usage); - return volume; -} - extern struct afs_volume *afs_create_volume(struct afs_fs_context *); extern void afs_activate_volume(struct afs_volume *); extern void afs_deactivate_volume(struct afs_volume *); -extern void afs_put_volume(struct afs_net *, struct afs_volume *); +extern struct afs_volume *afs_get_volume(struct afs_volume *, enum afs_volume_trace); +extern void afs_put_volume(struct afs_net *, struct afs_volume *, enum afs_volume_trace); extern int afs_check_volume_status(struct afs_volume *, struct afs_operation *); /* diff --git a/fs/afs/super.c b/fs/afs/super.c index aae6866ed209..f92ccdafc729 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c @@ -376,7 +376,8 @@ static int afs_validate_fc(struct fs_context *fc) ctx->key = key; if (ctx->volume) { - afs_put_volume(ctx->net, ctx->volume); + afs_put_volume(ctx->net, ctx->volume, + afs_volume_trace_put_validate_fc); ctx->volume = NULL; } @@ -507,7 +508,8 @@ static struct afs_super_info *afs_alloc_sbi(struct fs_context *fc) as->dyn_root = true; } else { as->cell = afs_get_cell(ctx->cell); - as->volume = afs_get_volume(ctx->volume); + as->volume = afs_get_volume(ctx->volume, + afs_volume_trace_get_alloc_sbi); } } return as; @@ -517,7 +519,7 @@ static void afs_destroy_sbi(struct afs_super_info *as) { if (as) { struct afs_net *net = afs_net(as->net_ns); - afs_put_volume(net, as->volume); + afs_put_volume(net, as->volume, afs_volume_trace_put_destroy_sbi); afs_put_cell(net, as->cell); put_net(as->net_ns); kfree(as); @@ -605,7 +607,7 @@ static void afs_free_fc(struct fs_context *fc) struct afs_fs_context *ctx = fc->fs_private; afs_destroy_sbi(fc->s_fs_info); - afs_put_volume(ctx->net, ctx->volume); + afs_put_volume(ctx->net, ctx->volume, afs_volume_trace_put_free_fc); afs_put_cell(ctx->net, ctx->cell); key_put(ctx->key); kfree(ctx); diff --git a/fs/afs/vl_alias.c b/fs/afs/vl_alias.c index ac7a59e951ed..c61dd9410202 100644 --- a/fs/afs/vl_alias.c +++ b/fs/afs/vl_alias.c @@ -193,7 +193,8 @@ static int afs_query_for_alias_one(struct afs_cell *cell, struct key *key, read_lock(&p->proc_lock); if (!list_empty(&p->proc_volumes)) pvol = afs_get_volume(list_first_entry(&p->proc_volumes, - struct afs_volume, proc_link)); + struct afs_volume, proc_link), + afs_volume_trace_get_query_alias); read_unlock(&p->proc_lock); if (!pvol) return 0; @@ -203,7 +204,7 @@ static int afs_query_for_alias_one(struct afs_cell *cell, struct key *key, /* And see if it's in the new cell. */ volume = afs_sample_volume(cell, key, pvol->name, pvol->name_len); if (IS_ERR(volume)) { - afs_put_volume(cell->net, pvol); + afs_put_volume(cell->net, pvol, afs_volume_trace_put_query_alias); if (PTR_ERR(volume) != -ENOMEDIUM) return PTR_ERR(volume); /* That volume is not in the new cell, so not an alias */ @@ -221,8 +222,8 @@ static int afs_query_for_alias_one(struct afs_cell *cell, struct key *key, rcu_read_unlock(); } - afs_put_volume(cell->net, volume); - afs_put_volume(cell->net, pvol); + afs_put_volume(cell->net, volume, afs_volume_trace_put_query_alias); + afs_put_volume(cell->net, pvol, afs_volume_trace_put_query_alias); return ret; } diff --git a/fs/afs/volume.c b/fs/afs/volume.c index d4d9a8fbba3d..0393f4910a92 100644 --- a/fs/afs/volume.c +++ b/fs/afs/volume.c @@ -52,6 +52,7 @@ static struct afs_volume *afs_alloc_volume(struct afs_fs_context *params, refcount_set(&slist->usage, 1); rcu_assign_pointer(volume->servers, slist); + trace_afs_volume(volume->vid, 1, afs_volume_trace_alloc); return volume; error_1: @@ -158,20 +159,38 @@ static void afs_destroy_volume(struct afs_net *net, struct afs_volume *volume) afs_put_serverlist(net, rcu_access_pointer(volume->servers)); afs_put_cell(net, volume->cell); + trace_afs_volume(volume->vid, atomic_read(&volume->usage), + afs_volume_trace_free); kfree(volume); _leave(" [destroyed]"); } /* - * Drop a reference on a volume record. + * Get a reference on a volume record. */ -void afs_put_volume(struct afs_net *net, struct afs_volume *volume) +struct afs_volume *afs_get_volume(struct afs_volume *volume, + enum afs_volume_trace reason) { if (volume) { - _enter("%s", volume->name); + int u = atomic_inc_return(&volume->usage); + trace_afs_volume(volume->vid, u, reason); + } + return volume; +} + - if (atomic_dec_and_test(&volume->usage)) +/* + * Drop a reference on a volume record. + */ +void afs_put_volume(struct afs_net *net, struct afs_volume *volume, + enum afs_volume_trace reason) +{ + if (volume) { + afs_volid_t vid = volume->vid; + int u = atomic_dec_return(&volume->usage); + trace_afs_volume(vid, u, reason); + if (u == 0) afs_destroy_volume(net, volume); } } |