Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f2fe7bac authored by Mohan Srinivasan's avatar Mohan Srinivasan Committed by Todd Kjos
Browse files

ANDROID: fs: FS tracepoints to track IO.



Adds tracepoints in ext4/f2fs/mpage to track readpages/buffered
write()s. This allows us to track files that are being read/written
to PIDs.

Bug: 120445624
Change-Id: I44476230324e9397e292328463f846af4befbd6d
[joelaf: Needed for storaged fsync accounting ("storaged --uid" and
         "storaged --task".)]
Signed-off-by: default avatarMohan Srinivasan <srmohan@google.com>
[AmitP: Folded following android-4.9 commit changes into this patch
        a5c4dbb05ab7 ("ANDROID: Replace spaces by '_' for some
        android filesystem tracepoints.")]
Signed-off-by: default avatarAmit Pundir <amit.pundir@linaro.org>
[astrachan: Folded 63066f4acf92 ("ANDROID: fs: Refactor FS
            readpage/write tracepoints.") into this patch
Signed-off-by: default avatarAlistair Strachan <astrachan@google.com>
parent 27579ec9
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include "ext4.h"
#include "xattr.h"
#include "truncate.h"
#include <trace/events/android_fs.h>

#define EXT4_XATTR_SYSTEM_DATA	"data"
#define EXT4_MIN_INLINE_DATA_SIZE	((sizeof(__le32) * EXT4_N_BLOCKS))
@@ -505,6 +506,17 @@ int ext4_readpage_inline(struct inode *inode, struct page *page)
		return -EAGAIN;
	}

	if (trace_android_fs_dataread_start_enabled()) {
		char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];

		path = android_fstrace_get_pathname(pathbuf,
						    MAX_TRACE_PATHBUF_LEN,
						    inode);
		trace_android_fs_dataread_start(inode, page_offset(page),
						PAGE_SIZE, current->pid,
						path, current->comm);
	}

	/*
	 * Current inline data can only exist in the 1st page,
	 * So for all the other pages, just set them uptodate.
@@ -516,6 +528,8 @@ int ext4_readpage_inline(struct inode *inode, struct page *page)
		SetPageUptodate(page);
	}

	trace_android_fs_dataread_end(inode, page_offset(page), PAGE_SIZE);

	up_read(&EXT4_I(inode)->xattr_sem);

	unlock_page(page);
+55 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@
#include "truncate.h"

#include <trace/events/ext4.h>
#include <trace/events/android_fs.h>

#define MPAGE_DA_EXTENT_TAIL 0x01

@@ -1253,6 +1254,16 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping,
	if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb))))
		return -EIO;

	if (trace_android_fs_datawrite_start_enabled()) {
		char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];

		path = android_fstrace_get_pathname(pathbuf,
						    MAX_TRACE_PATHBUF_LEN,
						    inode);
		trace_android_fs_datawrite_start(inode, pos, len,
						 current->pid, path,
						 current->comm);
	}
	trace_ext4_write_begin(inode, pos, len, flags);
	/*
	 * Reserve one block more for addition to orphan list in case
@@ -1391,6 +1402,7 @@ static int ext4_write_end(struct file *file,
	int i_size_changed = 0;
	int inline_data = ext4_has_inline_data(inode);

	trace_android_fs_datawrite_end(inode, pos, len);
	trace_ext4_write_end(inode, pos, len, copied);
	if (inline_data) {
		ret = ext4_write_inline_data_end(inode, pos, len,
@@ -1496,6 +1508,7 @@ static int ext4_journalled_write_end(struct file *file,
	int size_changed = 0;
	int inline_data = ext4_has_inline_data(inode);

	trace_android_fs_datawrite_end(inode, pos, len);
	trace_ext4_journalled_write_end(inode, pos, len, copied);
	from = pos & (PAGE_SIZE - 1);
	to = from + len;
@@ -3024,6 +3037,16 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping,
					len, flags, pagep, fsdata);
	}
	*fsdata = (void *)0;
	if (trace_android_fs_datawrite_start_enabled()) {
		char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];

		path = android_fstrace_get_pathname(pathbuf,
						    MAX_TRACE_PATHBUF_LEN,
						    inode);
		trace_android_fs_datawrite_start(inode, pos, len,
						 current->pid,
						 path, current->comm);
	}
	trace_ext4_da_write_begin(inode, pos, len, flags);

	if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) {
@@ -3142,6 +3165,7 @@ static int ext4_da_write_end(struct file *file,
		return ext4_write_end(file, mapping, pos,
				      len, copied, page, fsdata);

	trace_android_fs_datawrite_end(inode, pos, len);
	trace_ext4_da_write_end(inode, pos, len, copied);
	start = pos & (PAGE_SIZE - 1);
	end = start + copied - 1;
@@ -3847,6 +3871,7 @@ static ssize_t ext4_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
	size_t count = iov_iter_count(iter);
	loff_t offset = iocb->ki_pos;
	ssize_t ret;
	int rw = iov_iter_rw(iter);

#ifdef CONFIG_EXT4_FS_ENCRYPTION
	if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode))
@@ -3863,12 +3888,42 @@ static ssize_t ext4_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
	if (ext4_has_inline_data(inode))
		return 0;

	if (trace_android_fs_dataread_start_enabled() &&
	    (rw == READ)) {
		char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];

		path = android_fstrace_get_pathname(pathbuf,
						    MAX_TRACE_PATHBUF_LEN,
						    inode);
		trace_android_fs_dataread_start(inode, offset, count,
						current->pid, path,
						current->comm);
	}
	if (trace_android_fs_datawrite_start_enabled() &&
	    (rw == WRITE)) {
		char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];

		path = android_fstrace_get_pathname(pathbuf,
						    MAX_TRACE_PATHBUF_LEN,
						    inode);
		trace_android_fs_datawrite_start(inode, offset, count,
						 current->pid, path,
						 current->comm);
	}
	trace_ext4_direct_IO_enter(inode, offset, count, iov_iter_rw(iter));
	if (iov_iter_rw(iter) == READ)
		ret = ext4_direct_IO_read(iocb, iter);
	else
		ret = ext4_direct_IO_write(iocb, iter);
	trace_ext4_direct_IO_exit(inode, offset, count, iov_iter_rw(iter), ret);

	if (trace_android_fs_dataread_start_enabled() &&
	    (rw == READ))
		trace_android_fs_dataread_end(inode, offset, count);
	if (trace_android_fs_datawrite_start_enabled() &&
	    (rw == WRITE))
		trace_android_fs_datawrite_end(inode, offset, count);

	return ret;
}

+43 −4
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@
#include <linux/cleancache.h>

#include "ext4.h"
#include <trace/events/android_fs.h>

static inline bool ext4_bio_encrypted(struct bio *bio)
{
@@ -56,6 +57,17 @@ static inline bool ext4_bio_encrypted(struct bio *bio)
#endif
}

static void
ext4_trace_read_completion(struct bio *bio)
{
	struct page *first_page = bio->bi_io_vec[0].bv_page;

	if (first_page != NULL)
		trace_android_fs_dataread_end(first_page->mapping->host,
					      page_offset(first_page),
					      bio->bi_iter.bi_size);
}

/*
 * I/O completion handler for multipage BIOs.
 *
@@ -73,6 +85,9 @@ static void mpage_end_io(struct bio *bio)
	struct bio_vec *bv;
	int i;

	if (trace_android_fs_dataread_start_enabled())
		ext4_trace_read_completion(bio);

	if (ext4_bio_encrypted(bio)) {
		if (bio->bi_status) {
			fscrypt_release_ctx(bio->bi_private);
@@ -96,6 +111,30 @@ static void mpage_end_io(struct bio *bio)
	bio_put(bio);
}

static void
ext4_submit_bio_read(struct bio *bio)
{
	if (trace_android_fs_dataread_start_enabled()) {
		struct page *first_page = bio->bi_io_vec[0].bv_page;

		if (first_page != NULL) {
			char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];

			path = android_fstrace_get_pathname(pathbuf,
						    MAX_TRACE_PATHBUF_LEN,
						    first_page->mapping->host);
			trace_android_fs_dataread_start(
				first_page->mapping->host,
				page_offset(first_page),
				bio->bi_iter.bi_size,
				current->pid,
				path,
				current->comm);
		}
	}
	submit_bio(bio);
}

int ext4_mpage_readpages(struct address_space *mapping,
			 struct list_head *pages, struct page *page,
			 unsigned nr_pages, bool is_readahead)
@@ -236,7 +275,7 @@ int ext4_mpage_readpages(struct address_space *mapping,
		 */
		if (bio && (last_block_in_bio != blocks[0] - 1)) {
		submit_and_realloc:
			submit_bio(bio);
			ext4_submit_bio_read(bio);
			bio = NULL;
		}
		if (bio == NULL) {
@@ -270,14 +309,14 @@ int ext4_mpage_readpages(struct address_space *mapping,
		if (((map.m_flags & EXT4_MAP_BOUNDARY) &&
		     (relative_block == map.m_len)) ||
		    (first_hole != blocks_per_page)) {
			submit_bio(bio);
			ext4_submit_bio_read(bio);
			bio = NULL;
		} else
			last_block_in_bio = blocks[blocks_per_page - 1];
		goto next_page;
	confused:
		if (bio) {
			submit_bio(bio);
			ext4_submit_bio_read(bio);
			bio = NULL;
		}
		if (!PageUptodate(page))
@@ -290,6 +329,6 @@ int ext4_mpage_readpages(struct address_space *mapping,
	}
	BUG_ON(pages && !list_empty(pages));
	if (bio)
		submit_bio(bio);
		ext4_submit_bio_read(bio);
	return 0;
}
+42 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include "segment.h"
#include "trace.h"
#include <trace/events/f2fs.h>
#include <trace/events/android_fs.h>

#define NUM_PREALLOC_POST_READ_CTXS	128

@@ -2330,6 +2331,16 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping,
	block_t blkaddr = NULL_ADDR;
	int err = 0;

	if (trace_android_fs_datawrite_start_enabled()) {
		char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];

		path = android_fstrace_get_pathname(pathbuf,
						    MAX_TRACE_PATHBUF_LEN,
						    inode);
		trace_android_fs_datawrite_start(inode, pos, len,
						 current->pid, path,
						 current->comm);
	}
	trace_f2fs_write_begin(inode, pos, len, flags);

	if ((f2fs_is_atomic_file(inode) &&
@@ -2429,6 +2440,7 @@ static int f2fs_write_end(struct file *file,
{
	struct inode *inode = page->mapping->host;

	trace_android_fs_datawrite_end(inode, pos, len);
	trace_f2fs_write_end(inode, pos, len, copied);

	/*
@@ -2496,6 +2508,29 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)

	trace_f2fs_direct_IO_enter(inode, offset, count, rw);

	if (trace_android_fs_dataread_start_enabled() &&
	    (rw == READ)) {
		char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];

		path = android_fstrace_get_pathname(pathbuf,
						    MAX_TRACE_PATHBUF_LEN,
						    inode);
		trace_android_fs_dataread_start(inode, offset,
						count, current->pid, path,
						current->comm);
	}
	if (trace_android_fs_datawrite_start_enabled() &&
	    (rw == WRITE)) {
		char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];

		path = android_fstrace_get_pathname(pathbuf,
						    MAX_TRACE_PATHBUF_LEN,
						    inode);
		trace_android_fs_datawrite_start(inode, offset, count,
						 current->pid, path,
						 current->comm);
	}

	if (rw == WRITE && whint_mode == WHINT_MODE_OFF)
		iocb->ki_hint = WRITE_LIFE_NOT_SET;

@@ -2524,6 +2559,13 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
	}

out:
	if (trace_android_fs_dataread_start_enabled() &&
	    (rw == READ))
		trace_android_fs_dataread_end(inode, offset, count);
	if (trace_android_fs_datawrite_start_enabled() &&
	    (rw == WRITE))
		trace_android_fs_datawrite_end(inode, offset, count);

	trace_f2fs_direct_IO_exit(inode, offset, count, rw, err);

	return err;
+18 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@

#include "f2fs.h"
#include "node.h"
#include <trace/events/android_fs.h>

bool f2fs_may_inline_data(struct inode *inode)
{
@@ -86,14 +87,29 @@ int f2fs_read_inline_data(struct inode *inode, struct page *page)
{
	struct page *ipage;

	if (trace_android_fs_dataread_start_enabled()) {
		char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];

		path = android_fstrace_get_pathname(pathbuf,
						    MAX_TRACE_PATHBUF_LEN,
						    inode);
		trace_android_fs_dataread_start(inode, page_offset(page),
						PAGE_SIZE, current->pid,
						path, current->comm);
	}

	ipage = f2fs_get_node_page(F2FS_I_SB(inode), inode->i_ino);
	if (IS_ERR(ipage)) {
		trace_android_fs_dataread_end(inode, page_offset(page),
					      PAGE_SIZE);
		unlock_page(page);
		return PTR_ERR(ipage);
	}

	if (!f2fs_has_inline_data(inode)) {
		f2fs_put_page(ipage, 1);
		trace_android_fs_dataread_end(inode, page_offset(page),
					      PAGE_SIZE);
		return -EAGAIN;
	}

@@ -105,6 +121,8 @@ int f2fs_read_inline_data(struct inode *inode, struct page *page)
	if (!PageUptodate(page))
		SetPageUptodate(page);
	f2fs_put_page(ipage, 1);
	trace_android_fs_dataread_end(inode, page_offset(page),
				      PAGE_SIZE);
	unlock_page(page);
	return 0;
}
Loading