On 01/07/11 07:26, Rajat Sharma wrote: > so, suitable position is to add hooks on readpage a_op. And of-course > for doing that, you may have to capture various path thorugh which inode > can come in memory, e.g. lookup and create directory inode operation > (for regular files). For your worst nightmare, NFS implements its > readdir with an additional feature with v3 protocol called READDIR PLUS, > which not only gives you name of children of a directory, but also > initializes their inodes in memory, so you may have to hook readdir as > well and trap aops of all regular file child after nfs_readdir is finished. I see. > As far as offset and length of I/O are concerned, page->index gives you > its index in the page cache which in turn is equivalent to file offset > (page->index << PAGE_SHIFT). readpage is invoked to bring in complete > page in memory. It may so happen that page is a partial page (e.g. last > page of file), in that case your I/O lenght will be inode->i_size & > ~PAGE_MASK, otherwise it can be PAGE_SIZE. don't worry about file > wholes, that is taken care by filesystem's original readpage method. That sounds great. I have added these lines of code to read_pages() of mm/readahead.c: ================================================ { struct page *page = list_to_page(pages); for (page_idx = 0; page_idx < nr_pages; page_idx++, page = list_to_page(page->lru.next)) { pgoff_t offset = 0; pgoff_t len = PAGE_SIZE; if (page) { offset = page->index << PAGE_SHIFT; if (page->mapping && page->mapping->host) { struct inode *inode = page->mapping->host; len = inode->i_size & ~PAGE_MASK; } } printk(KERN_DEBUG "VFS: BODY@1 read_pages(...)[" "page_idx=%u, offset=%lu, len=%lu, page_size=%lu]", page_idx, offset, len, PAGE_SIZE); } } ================================================ Suprisingly I never get len != PAGE_SIZE, i.e. partial pages. Also, in a list of pages given, the offsets are all the same, all 0 in this case: ================================================ [ 2811.993564] VFS: BODY@1 read_pages(...)[page_idx=0, offset=0, len=4096, page_size=4096] [ 2811.996456] VFS: BODY@1 read_pages(...)[page_idx=1, offset=0, len=4096, page_size=4096] [ 2811.999305] VFS: BODY@1 read_pages(...)[page_idx=2, offset=0, len=4096, page_size=4096] [ 2812.002152] VFS: BODY@1 read_pages(...)[page_idx=3, offset=0, len=4096, page_size=4096] ================================================ Is page = list_to_page(page->lru.next) the correct way of walking pages? I am wondering how the main loop of read_pages() for (page_idx = 0; page_idx < nr_pages; page_idx++) { struct page *page = list_to_page(pages); [..] } really iterates, if neither the address of pages changes in the loop nor page_idx is passed to anything. I would think the loop is actually accessing the same page again and again, but somehow my own page = list_to_page(page->lru.next) above doesn't seem to do better. Any insights? Thanks! > Having said above, it will still be better if you can state what you > want to achieve in little layman language. I want to trace down all reads and writes to the file system including filename, offset and byte count into a log that I can reply inside a simulator. Best, Sebastian _______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies