1/*
2 * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2010, Michael Lotz, mmlr@mlotz.ch.
4 * Distributed under the terms of the MIT License.
5 */
6#ifndef VFS_TRACING_H
7#define VFS_TRACING_H
8
9
10#include <fs/fd.h>
11#include <tracing.h>
12#include <vfs.h>
13
14
15// #pragma mark - File Descriptor Tracing
16
17
18#if FILE_DESCRIPTOR_TRACING
19
20namespace FileDescriptorTracing {
21
22
23class FDTraceEntry : public AbstractTraceEntry {
24public:
25	FDTraceEntry(file_descriptor* descriptor)
26		:
27		fDescriptor(descriptor),
28		fReferenceCount(descriptor->ref_count)
29	{
30#if FILE_DESCRIPTOR_TRACING_STACK_TRACE
31		fStackTrace = capture_tracing_stack_trace(
32			FILE_DESCRIPTOR_TRACING_STACK_TRACE, 0, false);
33#endif
34	}
35
36#if FILE_DESCRIPTOR_TRACING_STACK_TRACE
37	virtual void DumpStackTrace(TraceOutput& out)
38	{
39		out.PrintStackTrace(fStackTrace);
40	}
41#endif
42
43protected:
44	file_descriptor*		fDescriptor;
45	int32					fReferenceCount;
46#if FILE_DESCRIPTOR_TRACING_STACK_TRACE
47	tracing_stack_trace*	fStackTrace;
48#endif
49};
50
51
52class NewFD : public FDTraceEntry {
53public:
54	NewFD(io_context* context, int fd, file_descriptor* descriptor)
55		:
56		FDTraceEntry(descriptor),
57		fContext(context),
58		fFD(fd)
59	{
60		Initialized();
61	}
62
63	virtual void AddDump(TraceOutput& out)
64	{
65		out.Print("fd new:     descriptor: %p (%" B_PRId32 "), context: %p, "
66			"fd: %d", fDescriptor, fReferenceCount, fContext, fFD);
67	}
68
69private:
70	io_context*	fContext;
71	int			fFD;
72};
73
74
75class PutFD : public FDTraceEntry {
76public:
77	PutFD(file_descriptor* descriptor)
78		:
79		FDTraceEntry(descriptor)
80	{
81		Initialized();
82	}
83
84	virtual void AddDump(TraceOutput& out)
85	{
86		out.Print("fd put:     descriptor: %p (%" B_PRId32 ")", fDescriptor,
87			fReferenceCount);
88	}
89};
90
91
92class GetFD : public FDTraceEntry {
93public:
94	GetFD(io_context* context, int fd, file_descriptor* descriptor)
95		:
96		FDTraceEntry(descriptor),
97		fContext(context),
98		fFD(fd)
99	{
100		Initialized();
101	}
102
103	virtual void AddDump(TraceOutput& out)
104	{
105		out.Print("fd get:     descriptor: %p (%" B_PRId32 "), context: %p, "
106			"fd: %d", fDescriptor, fReferenceCount, fContext, fFD);
107	}
108
109private:
110	io_context*	fContext;
111	int			fFD;
112};
113
114
115class RemoveFD : public FDTraceEntry {
116public:
117	RemoveFD(io_context* context, int fd, file_descriptor* descriptor)
118		:
119		FDTraceEntry(descriptor),
120		fContext(context),
121		fFD(fd)
122	{
123		Initialized();
124	}
125
126	virtual void AddDump(TraceOutput& out)
127	{
128		out.Print("fd remove:  descriptor: %p (%" B_PRId32 "), context: %p, "
129			"fd: %d", fDescriptor, fReferenceCount, fContext, fFD);
130	}
131
132private:
133	io_context*	fContext;
134	int			fFD;
135};
136
137
138class Dup2FD : public FDTraceEntry {
139public:
140	Dup2FD(io_context* context, int oldFD, int newFD)
141		:
142		FDTraceEntry(context->fds[oldFD]),
143		fContext(context),
144		fEvictedDescriptor(context->fds[newFD]),
145		fEvictedReferenceCount(
146			fEvictedDescriptor != NULL ? fEvictedDescriptor->ref_count : 0),
147		fOldFD(oldFD),
148		fNewFD(newFD)
149	{
150		Initialized();
151	}
152
153	virtual void AddDump(TraceOutput& out)
154	{
155		out.Print("fd dup2:    descriptor: %p (%" B_PRId32 "), context: %p, "
156			"fd: %d -> %d, evicted: %p (%" B_PRId32 ")", fDescriptor,
157			fReferenceCount, fContext, fOldFD, fNewFD, fEvictedDescriptor,
158			fEvictedReferenceCount);
159	}
160
161private:
162	io_context*			fContext;
163	file_descriptor*	fEvictedDescriptor;
164	int32				fEvictedReferenceCount;
165	int					fOldFD;
166	int					fNewFD;
167};
168
169
170class InheritFD : public FDTraceEntry {
171public:
172	InheritFD(io_context* context, int fd, file_descriptor* descriptor,
173		io_context* parentContext)
174		:
175		FDTraceEntry(descriptor),
176		fContext(context),
177		fParentContext(parentContext),
178		fFD(fd)
179	{
180		Initialized();
181	}
182
183	virtual void AddDump(TraceOutput& out)
184	{
185		out.Print("fd inherit: descriptor: %p (%" B_PRId32 "), context: %p, "
186			"fd: %d, parentContext: %p", fDescriptor, fReferenceCount, fContext,
187			fFD, fParentContext);
188	}
189
190private:
191	io_context*	fContext;
192	io_context*	fParentContext;
193	int			fFD;
194};
195
196
197}	// namespace FileDescriptorTracing
198
199#	define TFD(x)	new(std::nothrow) FileDescriptorTracing::x
200
201#else
202#	define TFD(x)
203#endif	// FILE_DESCRIPTOR_TRACING
204
205
206// #pragma mark - IO Context Tracing
207
208
209
210#if IO_CONTEXT_TRACING
211
212namespace IOContextTracing {
213
214
215class IOContextTraceEntry : public AbstractTraceEntry {
216public:
217	IOContextTraceEntry(io_context* context)
218		:
219		fContext(context)
220	{
221#if IO_CONTEXT_TRACING_STACK_TRACE
222		fStackTrace = capture_tracing_stack_trace(
223			IO_CONTEXT_TRACING_STACK_TRACE, 0, false);
224#endif
225	}
226
227#if IO_CONTEXT_TRACING_STACK_TRACE
228	virtual void DumpStackTrace(TraceOutput& out)
229	{
230		out.PrintStackTrace(fStackTrace);
231	}
232#endif
233
234protected:
235	io_context*				fContext;
236#if IO_CONTEXT_TRACING_STACK_TRACE
237	tracing_stack_trace*	fStackTrace;
238#endif
239};
240
241
242class NewIOContext : public IOContextTraceEntry {
243public:
244	NewIOContext(io_context* context, io_context* parentContext)
245		:
246		IOContextTraceEntry(context),
247		fParentContext(parentContext)
248	{
249		Initialized();
250	}
251
252	virtual void AddDump(TraceOutput& out)
253	{
254		out.Print("iocontext new:    context: %p, parent: %p", fContext,
255			fParentContext);
256	}
257
258private:
259	io_context*	fParentContext;
260};
261
262
263class FreeIOContext : public IOContextTraceEntry {
264public:
265	FreeIOContext(io_context* context)
266		:
267		IOContextTraceEntry(context)
268	{
269		Initialized();
270	}
271
272	virtual void AddDump(TraceOutput& out)
273	{
274		out.Print("iocontext free:   context: %p", fContext);
275	}
276};
277
278
279class ResizeIOContext : public IOContextTraceEntry {
280public:
281	ResizeIOContext(io_context* context, uint32 newTableSize)
282		:
283		IOContextTraceEntry(context),
284		fOldTableSize(context->table_size),
285		fNewTableSize(newTableSize)
286	{
287		Initialized();
288	}
289
290	virtual void AddDump(TraceOutput& out)
291	{
292		out.Print("iocontext resize: context: %p, size: %" B_PRIu32	" -> %"
293			B_PRIu32, fContext, fOldTableSize, fNewTableSize);
294	}
295
296private:
297	uint32	fOldTableSize;
298	uint32	fNewTableSize;
299};
300
301
302}	// namespace IOContextTracing
303
304#	define TIOC(x)	new(std::nothrow) IOContextTracing::x
305
306#else
307#	define TIOC(x)
308#endif	// IO_CONTEXT_TRACING
309
310
311#endif // VFS_TRACING_H
312