mirror of
https://github.com/torvalds/linux.git
synced 2024-11-28 23:21:31 +00:00
da4a827416
We got the following issue in a fuzz test of randomly issuing the restore
command:
==================================================================
BUG: KASAN: slab-use-after-free in cachefiles_ondemand_daemon_read+0xb41/0xb60
Read of size 8 at addr ffff888122e84088 by task ondemand-04-dae/963
CPU: 13 PID: 963 Comm: ondemand-04-dae Not tainted 6.8.0-dirty #564
Call Trace:
kasan_report+0x93/0xc0
cachefiles_ondemand_daemon_read+0xb41/0xb60
vfs_read+0x169/0xb50
ksys_read+0xf5/0x1e0
Allocated by task 116:
kmem_cache_alloc+0x140/0x3a0
cachefiles_lookup_cookie+0x140/0xcd0
fscache_cookie_state_machine+0x43c/0x1230
[...]
Freed by task 792:
kmem_cache_free+0xfe/0x390
cachefiles_put_object+0x241/0x480
fscache_cookie_state_machine+0x5c8/0x1230
[...]
==================================================================
Following is the process that triggers the issue:
mount | daemon_thread1 | daemon_thread2
------------------------------------------------------------
cachefiles_withdraw_cookie
cachefiles_ondemand_clean_object(object)
cachefiles_ondemand_send_req
REQ_A = kzalloc(sizeof(*req) + data_len)
wait_for_completion(&REQ_A->done)
cachefiles_daemon_read
cachefiles_ondemand_daemon_read
REQ_A = cachefiles_ondemand_select_req
msg->object_id = req->object->ondemand->ondemand_id
------ restore ------
cachefiles_ondemand_restore
xas_for_each(&xas, req, ULONG_MAX)
xas_set_mark(&xas, CACHEFILES_REQ_NEW)
cachefiles_daemon_read
cachefiles_ondemand_daemon_read
REQ_A = cachefiles_ondemand_select_req
copy_to_user(_buffer, msg, n)
xa_erase(&cache->reqs, id)
complete(&REQ_A->done)
------ close(fd) ------
cachefiles_ondemand_fd_release
cachefiles_put_object
cachefiles_put_object
kmem_cache_free(cachefiles_object_jar, object)
REQ_A->object->ondemand->ondemand_id
// object UAF !!!
When we see the request within xa_lock, req->object must not have been
freed yet, so grab the reference count of object before xa_unlock to
avoid the above issue.
Fixes: 0a7e54c195
("cachefiles: resend an open request if the read request's object is closed")
Signed-off-by: Baokun Li <libaokun1@huawei.com>
Link: https://lore.kernel.org/r/20240522114308.2402121-5-libaokun@huaweicloud.com
Acked-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Jia Zhu <zhujia.zj@bytedance.com>
Reviewed-by: Jingbo Xu <jefflexu@linux.alibaba.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
861 lines
23 KiB
C
861 lines
23 KiB
C
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
/* CacheFiles tracepoints
|
|
*
|
|
* Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
|
|
* Written by David Howells (dhowells@redhat.com)
|
|
*/
|
|
#undef TRACE_SYSTEM
|
|
#define TRACE_SYSTEM cachefiles
|
|
|
|
#if !defined(_TRACE_CACHEFILES_H) || defined(TRACE_HEADER_MULTI_READ)
|
|
#define _TRACE_CACHEFILES_H
|
|
|
|
#include <linux/tracepoint.h>
|
|
|
|
/*
|
|
* Define enums for tracing information.
|
|
*/
|
|
#ifndef __CACHEFILES_DECLARE_TRACE_ENUMS_ONCE_ONLY
|
|
#define __CACHEFILES_DECLARE_TRACE_ENUMS_ONCE_ONLY
|
|
|
|
enum cachefiles_obj_ref_trace {
|
|
cachefiles_obj_get_ioreq,
|
|
cachefiles_obj_new,
|
|
cachefiles_obj_put_alloc_fail,
|
|
cachefiles_obj_put_detach,
|
|
cachefiles_obj_put_ioreq,
|
|
cachefiles_obj_see_clean_commit,
|
|
cachefiles_obj_see_clean_delete,
|
|
cachefiles_obj_see_clean_drop_tmp,
|
|
cachefiles_obj_see_lookup_cookie,
|
|
cachefiles_obj_see_lookup_failed,
|
|
cachefiles_obj_see_withdraw_cookie,
|
|
cachefiles_obj_see_withdrawal,
|
|
cachefiles_obj_get_ondemand_fd,
|
|
cachefiles_obj_put_ondemand_fd,
|
|
cachefiles_obj_get_read_req,
|
|
cachefiles_obj_put_read_req,
|
|
};
|
|
|
|
enum fscache_why_object_killed {
|
|
FSCACHE_OBJECT_IS_STALE,
|
|
FSCACHE_OBJECT_IS_WEIRD,
|
|
FSCACHE_OBJECT_INVALIDATED,
|
|
FSCACHE_OBJECT_NO_SPACE,
|
|
FSCACHE_OBJECT_WAS_RETIRED,
|
|
FSCACHE_OBJECT_WAS_CULLED,
|
|
FSCACHE_VOLUME_IS_WEIRD,
|
|
};
|
|
|
|
enum cachefiles_coherency_trace {
|
|
cachefiles_coherency_check_aux,
|
|
cachefiles_coherency_check_content,
|
|
cachefiles_coherency_check_dirty,
|
|
cachefiles_coherency_check_len,
|
|
cachefiles_coherency_check_objsize,
|
|
cachefiles_coherency_check_ok,
|
|
cachefiles_coherency_check_type,
|
|
cachefiles_coherency_check_xattr,
|
|
cachefiles_coherency_set_fail,
|
|
cachefiles_coherency_set_ok,
|
|
cachefiles_coherency_vol_check_cmp,
|
|
cachefiles_coherency_vol_check_ok,
|
|
cachefiles_coherency_vol_check_resv,
|
|
cachefiles_coherency_vol_check_xattr,
|
|
cachefiles_coherency_vol_set_fail,
|
|
cachefiles_coherency_vol_set_ok,
|
|
};
|
|
|
|
enum cachefiles_trunc_trace {
|
|
cachefiles_trunc_dio_adjust,
|
|
cachefiles_trunc_expand_tmpfile,
|
|
cachefiles_trunc_shrink,
|
|
};
|
|
|
|
enum cachefiles_prepare_read_trace {
|
|
cachefiles_trace_read_after_eof,
|
|
cachefiles_trace_read_found_hole,
|
|
cachefiles_trace_read_found_part,
|
|
cachefiles_trace_read_have_data,
|
|
cachefiles_trace_read_no_data,
|
|
cachefiles_trace_read_no_file,
|
|
cachefiles_trace_read_seek_error,
|
|
cachefiles_trace_read_seek_nxio,
|
|
};
|
|
|
|
enum cachefiles_error_trace {
|
|
cachefiles_trace_fallocate_error,
|
|
cachefiles_trace_getxattr_error,
|
|
cachefiles_trace_link_error,
|
|
cachefiles_trace_lookup_error,
|
|
cachefiles_trace_mkdir_error,
|
|
cachefiles_trace_notify_change_error,
|
|
cachefiles_trace_open_error,
|
|
cachefiles_trace_read_error,
|
|
cachefiles_trace_remxattr_error,
|
|
cachefiles_trace_rename_error,
|
|
cachefiles_trace_seek_error,
|
|
cachefiles_trace_setxattr_error,
|
|
cachefiles_trace_statfs_error,
|
|
cachefiles_trace_tmpfile_error,
|
|
cachefiles_trace_trunc_error,
|
|
cachefiles_trace_unlink_error,
|
|
cachefiles_trace_write_error,
|
|
};
|
|
|
|
#endif
|
|
|
|
/*
|
|
* Define enum -> string mappings for display.
|
|
*/
|
|
#define cachefiles_obj_kill_traces \
|
|
EM(FSCACHE_OBJECT_IS_STALE, "stale") \
|
|
EM(FSCACHE_OBJECT_IS_WEIRD, "weird") \
|
|
EM(FSCACHE_OBJECT_INVALIDATED, "inval") \
|
|
EM(FSCACHE_OBJECT_NO_SPACE, "no_space") \
|
|
EM(FSCACHE_OBJECT_WAS_RETIRED, "was_retired") \
|
|
EM(FSCACHE_OBJECT_WAS_CULLED, "was_culled") \
|
|
E_(FSCACHE_VOLUME_IS_WEIRD, "volume_weird")
|
|
|
|
#define cachefiles_obj_ref_traces \
|
|
EM(cachefiles_obj_get_ioreq, "GET ioreq") \
|
|
EM(cachefiles_obj_new, "NEW obj") \
|
|
EM(cachefiles_obj_put_alloc_fail, "PUT alloc_fail") \
|
|
EM(cachefiles_obj_put_detach, "PUT detach") \
|
|
EM(cachefiles_obj_put_ioreq, "PUT ioreq") \
|
|
EM(cachefiles_obj_see_clean_commit, "SEE clean_commit") \
|
|
EM(cachefiles_obj_see_clean_delete, "SEE clean_delete") \
|
|
EM(cachefiles_obj_see_clean_drop_tmp, "SEE clean_drop_tmp") \
|
|
EM(cachefiles_obj_see_lookup_cookie, "SEE lookup_cookie") \
|
|
EM(cachefiles_obj_see_lookup_failed, "SEE lookup_failed") \
|
|
EM(cachefiles_obj_see_withdraw_cookie, "SEE withdraw_cookie") \
|
|
EM(cachefiles_obj_see_withdrawal, "SEE withdrawal") \
|
|
EM(cachefiles_obj_get_ondemand_fd, "GET ondemand_fd") \
|
|
EM(cachefiles_obj_put_ondemand_fd, "PUT ondemand_fd") \
|
|
EM(cachefiles_obj_get_read_req, "GET read_req") \
|
|
E_(cachefiles_obj_put_read_req, "PUT read_req")
|
|
|
|
#define cachefiles_coherency_traces \
|
|
EM(cachefiles_coherency_check_aux, "BAD aux ") \
|
|
EM(cachefiles_coherency_check_content, "BAD cont") \
|
|
EM(cachefiles_coherency_check_dirty, "BAD dirt") \
|
|
EM(cachefiles_coherency_check_len, "BAD len ") \
|
|
EM(cachefiles_coherency_check_objsize, "BAD osiz") \
|
|
EM(cachefiles_coherency_check_ok, "OK ") \
|
|
EM(cachefiles_coherency_check_type, "BAD type") \
|
|
EM(cachefiles_coherency_check_xattr, "BAD xatt") \
|
|
EM(cachefiles_coherency_set_fail, "SET fail") \
|
|
EM(cachefiles_coherency_set_ok, "SET ok ") \
|
|
EM(cachefiles_coherency_vol_check_cmp, "VOL BAD cmp ") \
|
|
EM(cachefiles_coherency_vol_check_ok, "VOL OK ") \
|
|
EM(cachefiles_coherency_vol_check_resv, "VOL BAD resv") \
|
|
EM(cachefiles_coherency_vol_check_xattr,"VOL BAD xatt") \
|
|
EM(cachefiles_coherency_vol_set_fail, "VOL SET fail") \
|
|
E_(cachefiles_coherency_vol_set_ok, "VOL SET ok ")
|
|
|
|
#define cachefiles_trunc_traces \
|
|
EM(cachefiles_trunc_dio_adjust, "DIOADJ") \
|
|
EM(cachefiles_trunc_expand_tmpfile, "EXPTMP") \
|
|
E_(cachefiles_trunc_shrink, "SHRINK")
|
|
|
|
#define cachefiles_prepare_read_traces \
|
|
EM(cachefiles_trace_read_after_eof, "after-eof ") \
|
|
EM(cachefiles_trace_read_found_hole, "found-hole") \
|
|
EM(cachefiles_trace_read_found_part, "found-part") \
|
|
EM(cachefiles_trace_read_have_data, "have-data ") \
|
|
EM(cachefiles_trace_read_no_data, "no-data ") \
|
|
EM(cachefiles_trace_read_no_file, "no-file ") \
|
|
EM(cachefiles_trace_read_seek_error, "seek-error") \
|
|
E_(cachefiles_trace_read_seek_nxio, "seek-enxio")
|
|
|
|
#define cachefiles_error_traces \
|
|
EM(cachefiles_trace_fallocate_error, "fallocate") \
|
|
EM(cachefiles_trace_getxattr_error, "getxattr") \
|
|
EM(cachefiles_trace_link_error, "link") \
|
|
EM(cachefiles_trace_lookup_error, "lookup") \
|
|
EM(cachefiles_trace_mkdir_error, "mkdir") \
|
|
EM(cachefiles_trace_notify_change_error, "notify_change") \
|
|
EM(cachefiles_trace_open_error, "open") \
|
|
EM(cachefiles_trace_read_error, "read") \
|
|
EM(cachefiles_trace_remxattr_error, "remxattr") \
|
|
EM(cachefiles_trace_rename_error, "rename") \
|
|
EM(cachefiles_trace_seek_error, "seek") \
|
|
EM(cachefiles_trace_setxattr_error, "setxattr") \
|
|
EM(cachefiles_trace_statfs_error, "statfs") \
|
|
EM(cachefiles_trace_tmpfile_error, "tmpfile") \
|
|
EM(cachefiles_trace_trunc_error, "trunc") \
|
|
EM(cachefiles_trace_unlink_error, "unlink") \
|
|
E_(cachefiles_trace_write_error, "write")
|
|
|
|
|
|
/*
|
|
* Export enum symbols via userspace.
|
|
*/
|
|
#undef EM
|
|
#undef E_
|
|
#define EM(a, b) TRACE_DEFINE_ENUM(a);
|
|
#define E_(a, b) TRACE_DEFINE_ENUM(a);
|
|
|
|
cachefiles_obj_kill_traces;
|
|
cachefiles_obj_ref_traces;
|
|
cachefiles_coherency_traces;
|
|
cachefiles_trunc_traces;
|
|
cachefiles_prepare_read_traces;
|
|
cachefiles_error_traces;
|
|
|
|
/*
|
|
* Now redefine the EM() and E_() macros to map the enums to the strings that
|
|
* will be printed in the output.
|
|
*/
|
|
#undef EM
|
|
#undef E_
|
|
#define EM(a, b) { a, b },
|
|
#define E_(a, b) { a, b }
|
|
|
|
|
|
TRACE_EVENT(cachefiles_ref,
|
|
TP_PROTO(unsigned int object_debug_id,
|
|
unsigned int cookie_debug_id,
|
|
int usage,
|
|
enum cachefiles_obj_ref_trace why),
|
|
|
|
TP_ARGS(object_debug_id, cookie_debug_id, usage, why),
|
|
|
|
/* Note that obj may be NULL */
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, obj )
|
|
__field(unsigned int, cookie )
|
|
__field(enum cachefiles_obj_ref_trace, why )
|
|
__field(int, usage )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = object_debug_id;
|
|
__entry->cookie = cookie_debug_id;
|
|
__entry->usage = usage;
|
|
__entry->why = why;
|
|
),
|
|
|
|
TP_printk("c=%08x o=%08x u=%d %s",
|
|
__entry->cookie, __entry->obj, __entry->usage,
|
|
__print_symbolic(__entry->why, cachefiles_obj_ref_traces))
|
|
);
|
|
|
|
TRACE_EVENT(cachefiles_lookup,
|
|
TP_PROTO(struct cachefiles_object *obj,
|
|
struct dentry *dir,
|
|
struct dentry *de),
|
|
|
|
TP_ARGS(obj, dir, de),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, obj )
|
|
__field(short, error )
|
|
__field(unsigned long, dino )
|
|
__field(unsigned long, ino )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj ? obj->debug_id : 0;
|
|
__entry->dino = d_backing_inode(dir)->i_ino;
|
|
__entry->ino = (!IS_ERR(de) && d_backing_inode(de) ?
|
|
d_backing_inode(de)->i_ino : 0);
|
|
__entry->error = IS_ERR(de) ? PTR_ERR(de) : 0;
|
|
),
|
|
|
|
TP_printk("o=%08x dB=%lx B=%lx e=%d",
|
|
__entry->obj, __entry->dino, __entry->ino, __entry->error)
|
|
);
|
|
|
|
TRACE_EVENT(cachefiles_mkdir,
|
|
TP_PROTO(struct dentry *dir, struct dentry *subdir),
|
|
|
|
TP_ARGS(dir, subdir),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, dir )
|
|
__field(unsigned int, subdir )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->dir = d_backing_inode(dir)->i_ino;
|
|
__entry->subdir = d_backing_inode(subdir)->i_ino;
|
|
),
|
|
|
|
TP_printk("dB=%x sB=%x",
|
|
__entry->dir,
|
|
__entry->subdir)
|
|
);
|
|
|
|
TRACE_EVENT(cachefiles_tmpfile,
|
|
TP_PROTO(struct cachefiles_object *obj, struct inode *backer),
|
|
|
|
TP_ARGS(obj, backer),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, obj )
|
|
__field(unsigned int, backer )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj->debug_id;
|
|
__entry->backer = backer->i_ino;
|
|
),
|
|
|
|
TP_printk("o=%08x B=%x",
|
|
__entry->obj,
|
|
__entry->backer)
|
|
);
|
|
|
|
TRACE_EVENT(cachefiles_link,
|
|
TP_PROTO(struct cachefiles_object *obj, struct inode *backer),
|
|
|
|
TP_ARGS(obj, backer),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, obj )
|
|
__field(unsigned int, backer )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj->debug_id;
|
|
__entry->backer = backer->i_ino;
|
|
),
|
|
|
|
TP_printk("o=%08x B=%x",
|
|
__entry->obj,
|
|
__entry->backer)
|
|
);
|
|
|
|
TRACE_EVENT(cachefiles_unlink,
|
|
TP_PROTO(struct cachefiles_object *obj,
|
|
ino_t ino,
|
|
enum fscache_why_object_killed why),
|
|
|
|
TP_ARGS(obj, ino, why),
|
|
|
|
/* Note that obj may be NULL */
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, obj )
|
|
__field(unsigned int, ino )
|
|
__field(enum fscache_why_object_killed, why )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj ? obj->debug_id : UINT_MAX;
|
|
__entry->ino = ino;
|
|
__entry->why = why;
|
|
),
|
|
|
|
TP_printk("o=%08x B=%x w=%s",
|
|
__entry->obj, __entry->ino,
|
|
__print_symbolic(__entry->why, cachefiles_obj_kill_traces))
|
|
);
|
|
|
|
TRACE_EVENT(cachefiles_rename,
|
|
TP_PROTO(struct cachefiles_object *obj,
|
|
ino_t ino,
|
|
enum fscache_why_object_killed why),
|
|
|
|
TP_ARGS(obj, ino, why),
|
|
|
|
/* Note that obj may be NULL */
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, obj )
|
|
__field(unsigned int, ino )
|
|
__field(enum fscache_why_object_killed, why )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj ? obj->debug_id : UINT_MAX;
|
|
__entry->ino = ino;
|
|
__entry->why = why;
|
|
),
|
|
|
|
TP_printk("o=%08x B=%x w=%s",
|
|
__entry->obj, __entry->ino,
|
|
__print_symbolic(__entry->why, cachefiles_obj_kill_traces))
|
|
);
|
|
|
|
TRACE_EVENT(cachefiles_coherency,
|
|
TP_PROTO(struct cachefiles_object *obj,
|
|
ino_t ino,
|
|
enum cachefiles_content content,
|
|
enum cachefiles_coherency_trace why),
|
|
|
|
TP_ARGS(obj, ino, content, why),
|
|
|
|
/* Note that obj may be NULL */
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, obj )
|
|
__field(enum cachefiles_coherency_trace, why )
|
|
__field(enum cachefiles_content, content )
|
|
__field(u64, ino )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj->debug_id;
|
|
__entry->why = why;
|
|
__entry->content = content;
|
|
__entry->ino = ino;
|
|
),
|
|
|
|
TP_printk("o=%08x %s B=%llx c=%u",
|
|
__entry->obj,
|
|
__print_symbolic(__entry->why, cachefiles_coherency_traces),
|
|
__entry->ino,
|
|
__entry->content)
|
|
);
|
|
|
|
TRACE_EVENT(cachefiles_vol_coherency,
|
|
TP_PROTO(struct cachefiles_volume *volume,
|
|
ino_t ino,
|
|
enum cachefiles_coherency_trace why),
|
|
|
|
TP_ARGS(volume, ino, why),
|
|
|
|
/* Note that obj may be NULL */
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, vol )
|
|
__field(enum cachefiles_coherency_trace, why )
|
|
__field(u64, ino )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->vol = volume->vcookie->debug_id;
|
|
__entry->why = why;
|
|
__entry->ino = ino;
|
|
),
|
|
|
|
TP_printk("V=%08x %s B=%llx",
|
|
__entry->vol,
|
|
__print_symbolic(__entry->why, cachefiles_coherency_traces),
|
|
__entry->ino)
|
|
);
|
|
|
|
TRACE_EVENT(cachefiles_prep_read,
|
|
TP_PROTO(struct cachefiles_object *obj,
|
|
loff_t start,
|
|
size_t len,
|
|
unsigned short flags,
|
|
enum netfs_io_source source,
|
|
enum cachefiles_prepare_read_trace why,
|
|
ino_t cache_inode, ino_t netfs_inode),
|
|
|
|
TP_ARGS(obj, start, len, flags, source, why, cache_inode, netfs_inode),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, obj )
|
|
__field(unsigned short, flags )
|
|
__field(enum netfs_io_source, source )
|
|
__field(enum cachefiles_prepare_read_trace, why )
|
|
__field(size_t, len )
|
|
__field(loff_t, start )
|
|
__field(unsigned int, netfs_inode )
|
|
__field(unsigned int, cache_inode )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj ? obj->debug_id : 0;
|
|
__entry->flags = flags;
|
|
__entry->source = source;
|
|
__entry->why = why;
|
|
__entry->len = len;
|
|
__entry->start = start;
|
|
__entry->netfs_inode = netfs_inode;
|
|
__entry->cache_inode = cache_inode;
|
|
),
|
|
|
|
TP_printk("o=%08x %s %s f=%02x s=%llx %zx ni=%x B=%x",
|
|
__entry->obj,
|
|
__print_symbolic(__entry->source, netfs_sreq_sources),
|
|
__print_symbolic(__entry->why, cachefiles_prepare_read_traces),
|
|
__entry->flags,
|
|
__entry->start, __entry->len,
|
|
__entry->netfs_inode, __entry->cache_inode)
|
|
);
|
|
|
|
TRACE_EVENT(cachefiles_read,
|
|
TP_PROTO(struct cachefiles_object *obj,
|
|
struct inode *backer,
|
|
loff_t start,
|
|
size_t len),
|
|
|
|
TP_ARGS(obj, backer, start, len),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, obj )
|
|
__field(unsigned int, backer )
|
|
__field(size_t, len )
|
|
__field(loff_t, start )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj->debug_id;
|
|
__entry->backer = backer->i_ino;
|
|
__entry->start = start;
|
|
__entry->len = len;
|
|
),
|
|
|
|
TP_printk("o=%08x B=%x s=%llx l=%zx",
|
|
__entry->obj,
|
|
__entry->backer,
|
|
__entry->start,
|
|
__entry->len)
|
|
);
|
|
|
|
TRACE_EVENT(cachefiles_write,
|
|
TP_PROTO(struct cachefiles_object *obj,
|
|
struct inode *backer,
|
|
loff_t start,
|
|
size_t len),
|
|
|
|
TP_ARGS(obj, backer, start, len),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, obj )
|
|
__field(unsigned int, backer )
|
|
__field(size_t, len )
|
|
__field(loff_t, start )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj->debug_id;
|
|
__entry->backer = backer->i_ino;
|
|
__entry->start = start;
|
|
__entry->len = len;
|
|
),
|
|
|
|
TP_printk("o=%08x B=%x s=%llx l=%zx",
|
|
__entry->obj,
|
|
__entry->backer,
|
|
__entry->start,
|
|
__entry->len)
|
|
);
|
|
|
|
TRACE_EVENT(cachefiles_trunc,
|
|
TP_PROTO(struct cachefiles_object *obj, struct inode *backer,
|
|
loff_t from, loff_t to, enum cachefiles_trunc_trace why),
|
|
|
|
TP_ARGS(obj, backer, from, to, why),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, obj )
|
|
__field(unsigned int, backer )
|
|
__field(enum cachefiles_trunc_trace, why )
|
|
__field(loff_t, from )
|
|
__field(loff_t, to )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj->debug_id;
|
|
__entry->backer = backer->i_ino;
|
|
__entry->from = from;
|
|
__entry->to = to;
|
|
__entry->why = why;
|
|
),
|
|
|
|
TP_printk("o=%08x B=%x %s l=%llx->%llx",
|
|
__entry->obj,
|
|
__entry->backer,
|
|
__print_symbolic(__entry->why, cachefiles_trunc_traces),
|
|
__entry->from,
|
|
__entry->to)
|
|
);
|
|
|
|
TRACE_EVENT(cachefiles_mark_active,
|
|
TP_PROTO(struct cachefiles_object *obj,
|
|
struct inode *inode),
|
|
|
|
TP_ARGS(obj, inode),
|
|
|
|
/* Note that obj may be NULL */
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, obj )
|
|
__field(ino_t, inode )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj ? obj->debug_id : 0;
|
|
__entry->inode = inode->i_ino;
|
|
),
|
|
|
|
TP_printk("o=%08x B=%lx",
|
|
__entry->obj, __entry->inode)
|
|
);
|
|
|
|
TRACE_EVENT(cachefiles_mark_failed,
|
|
TP_PROTO(struct cachefiles_object *obj,
|
|
struct inode *inode),
|
|
|
|
TP_ARGS(obj, inode),
|
|
|
|
/* Note that obj may be NULL */
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, obj )
|
|
__field(ino_t, inode )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj ? obj->debug_id : 0;
|
|
__entry->inode = inode->i_ino;
|
|
),
|
|
|
|
TP_printk("o=%08x B=%lx",
|
|
__entry->obj, __entry->inode)
|
|
);
|
|
|
|
TRACE_EVENT(cachefiles_mark_inactive,
|
|
TP_PROTO(struct cachefiles_object *obj,
|
|
struct inode *inode),
|
|
|
|
TP_ARGS(obj, inode),
|
|
|
|
/* Note that obj may be NULL */
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, obj )
|
|
__field(ino_t, inode )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj ? obj->debug_id : 0;
|
|
__entry->inode = inode->i_ino;
|
|
),
|
|
|
|
TP_printk("o=%08x B=%lx",
|
|
__entry->obj, __entry->inode)
|
|
);
|
|
|
|
TRACE_EVENT(cachefiles_vfs_error,
|
|
TP_PROTO(struct cachefiles_object *obj, struct inode *backer,
|
|
int error, enum cachefiles_error_trace where),
|
|
|
|
TP_ARGS(obj, backer, error, where),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, obj )
|
|
__field(unsigned int, backer )
|
|
__field(enum cachefiles_error_trace, where )
|
|
__field(short, error )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj ? obj->debug_id : 0;
|
|
__entry->backer = backer->i_ino;
|
|
__entry->error = error;
|
|
__entry->where = where;
|
|
),
|
|
|
|
TP_printk("o=%08x B=%x %s e=%d",
|
|
__entry->obj,
|
|
__entry->backer,
|
|
__print_symbolic(__entry->where, cachefiles_error_traces),
|
|
__entry->error)
|
|
);
|
|
|
|
TRACE_EVENT(cachefiles_io_error,
|
|
TP_PROTO(struct cachefiles_object *obj, struct inode *backer,
|
|
int error, enum cachefiles_error_trace where),
|
|
|
|
TP_ARGS(obj, backer, error, where),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, obj )
|
|
__field(unsigned int, backer )
|
|
__field(enum cachefiles_error_trace, where )
|
|
__field(short, error )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj ? obj->debug_id : 0;
|
|
__entry->backer = backer->i_ino;
|
|
__entry->error = error;
|
|
__entry->where = where;
|
|
),
|
|
|
|
TP_printk("o=%08x B=%x %s e=%d",
|
|
__entry->obj,
|
|
__entry->backer,
|
|
__print_symbolic(__entry->where, cachefiles_error_traces),
|
|
__entry->error)
|
|
);
|
|
|
|
TRACE_EVENT(cachefiles_ondemand_open,
|
|
TP_PROTO(struct cachefiles_object *obj, struct cachefiles_msg *msg,
|
|
struct cachefiles_open *load),
|
|
|
|
TP_ARGS(obj, msg, load),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, obj )
|
|
__field(unsigned int, msg_id )
|
|
__field(unsigned int, object_id )
|
|
__field(unsigned int, fd )
|
|
__field(unsigned int, flags )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj ? obj->debug_id : 0;
|
|
__entry->msg_id = msg->msg_id;
|
|
__entry->object_id = msg->object_id;
|
|
__entry->fd = load->fd;
|
|
__entry->flags = load->flags;
|
|
),
|
|
|
|
TP_printk("o=%08x mid=%x oid=%x fd=%d f=%x",
|
|
__entry->obj,
|
|
__entry->msg_id,
|
|
__entry->object_id,
|
|
__entry->fd,
|
|
__entry->flags)
|
|
);
|
|
|
|
TRACE_EVENT(cachefiles_ondemand_copen,
|
|
TP_PROTO(struct cachefiles_object *obj, unsigned int msg_id,
|
|
long len),
|
|
|
|
TP_ARGS(obj, msg_id, len),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, obj )
|
|
__field(unsigned int, msg_id )
|
|
__field(long, len )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj ? obj->debug_id : 0;
|
|
__entry->msg_id = msg_id;
|
|
__entry->len = len;
|
|
),
|
|
|
|
TP_printk("o=%08x mid=%x l=%lx",
|
|
__entry->obj,
|
|
__entry->msg_id,
|
|
__entry->len)
|
|
);
|
|
|
|
TRACE_EVENT(cachefiles_ondemand_close,
|
|
TP_PROTO(struct cachefiles_object *obj, struct cachefiles_msg *msg),
|
|
|
|
TP_ARGS(obj, msg),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, obj )
|
|
__field(unsigned int, msg_id )
|
|
__field(unsigned int, object_id )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj ? obj->debug_id : 0;
|
|
__entry->msg_id = msg->msg_id;
|
|
__entry->object_id = msg->object_id;
|
|
),
|
|
|
|
TP_printk("o=%08x mid=%x oid=%x",
|
|
__entry->obj,
|
|
__entry->msg_id,
|
|
__entry->object_id)
|
|
);
|
|
|
|
TRACE_EVENT(cachefiles_ondemand_read,
|
|
TP_PROTO(struct cachefiles_object *obj, struct cachefiles_msg *msg,
|
|
struct cachefiles_read *load),
|
|
|
|
TP_ARGS(obj, msg, load),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, obj )
|
|
__field(unsigned int, msg_id )
|
|
__field(unsigned int, object_id )
|
|
__field(loff_t, start )
|
|
__field(size_t, len )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj ? obj->debug_id : 0;
|
|
__entry->msg_id = msg->msg_id;
|
|
__entry->object_id = msg->object_id;
|
|
__entry->start = load->off;
|
|
__entry->len = load->len;
|
|
),
|
|
|
|
TP_printk("o=%08x mid=%x oid=%x s=%llx l=%zx",
|
|
__entry->obj,
|
|
__entry->msg_id,
|
|
__entry->object_id,
|
|
__entry->start,
|
|
__entry->len)
|
|
);
|
|
|
|
TRACE_EVENT(cachefiles_ondemand_cread,
|
|
TP_PROTO(struct cachefiles_object *obj, unsigned int msg_id),
|
|
|
|
TP_ARGS(obj, msg_id),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, obj )
|
|
__field(unsigned int, msg_id )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj ? obj->debug_id : 0;
|
|
__entry->msg_id = msg_id;
|
|
),
|
|
|
|
TP_printk("o=%08x mid=%x",
|
|
__entry->obj,
|
|
__entry->msg_id)
|
|
);
|
|
|
|
TRACE_EVENT(cachefiles_ondemand_fd_write,
|
|
TP_PROTO(struct cachefiles_object *obj, struct inode *backer,
|
|
loff_t start, size_t len),
|
|
|
|
TP_ARGS(obj, backer, start, len),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, obj )
|
|
__field(unsigned int, backer )
|
|
__field(loff_t, start )
|
|
__field(size_t, len )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj ? obj->debug_id : 0;
|
|
__entry->backer = backer->i_ino;
|
|
__entry->start = start;
|
|
__entry->len = len;
|
|
),
|
|
|
|
TP_printk("o=%08x iB=%x s=%llx l=%zx",
|
|
__entry->obj,
|
|
__entry->backer,
|
|
__entry->start,
|
|
__entry->len)
|
|
);
|
|
|
|
TRACE_EVENT(cachefiles_ondemand_fd_release,
|
|
TP_PROTO(struct cachefiles_object *obj, int object_id),
|
|
|
|
TP_ARGS(obj, object_id),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, obj )
|
|
__field(unsigned int, object_id )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->obj = obj ? obj->debug_id : 0;
|
|
__entry->object_id = object_id;
|
|
),
|
|
|
|
TP_printk("o=%08x oid=%x",
|
|
__entry->obj,
|
|
__entry->object_id)
|
|
);
|
|
|
|
#endif /* _TRACE_CACHEFILES_H */
|
|
|
|
/* This part must be outside protection */
|
|
#include <trace/define_trace.h>
|