Hi,
I ported a file system from Kernel version 2.6.18.* to 2.6.32.46 (RHEL6.1) as the VFS implementation has changed and prepare_write/commit_write are replaced by write_begin/write_end pairs.
Implemented the feature by writing a wrapper for write_begin and write_end and calling original functions for prepare_write and commit_write respectively by drawing the parameters prepare_write/commit_write need.
like :
Code:
int myNewfs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata) {
struct inode *inode = mapping->host;
int ret, error, retStatus;
int retries = 0;
struct page *page;
pgoff_t index;
unsigned from, to;
int needed_blocks = ext3_writepage_trans_blocks(inode) + 1;
ret = 0;
error = 0;
retries = 0;
index = pos >> PAGE_CACHE_SHIFT;
from = pos & (PAGE_CACHE_SIZE - 1);
to = from + len;
findpage:
page=NULL;
page = grab_cache_page_write_begin(mapping, index, flags);
if (!page) {
return -ENOMEM;
}
/*
** Calling the original _My_OldFS_prepare_write.
** The call ensures the same old handling of
** the filesystem wraped with the new VFS APIs.
*/
*pagep = page;
retStatus = _My_OldFS_prepare_write(file, page, from, to);
return retStatus;
}
//Similarly,
int _myNewfs_write_end(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned copied,
struct page *page, void *fsdata) {
unsigned start, ret;
start = pos & (PAGE_CACHE_SIZE - 1);
struct inode *inode = mapping->host;
/* This could be a short (even 0-length) commit */
ret = 0;
/*
** Calling OLD Commit Write.
*/
ret = _myOldFS_commit_write(file, page, start, start+copied);
/*
** Update the radix page ref count.
*/
//mapping->nrpages--;
/*
** Unlock the page, locked from the write_begin.
*/
unlock_page(page);
/*
** Release the page.
*/
//flush_dcache_page(page);
page_cache_release(page);
return ret? ret : copied;
}
The issue is that despite the new write is working, I'm observing a kernel hang except in situations when I fire '
sync' command from the prompt and in which case the kernel doesn't hang.
sync is flushing back dirty pages, hence at some point I tried using flush_dcache_page(page) too but the problem persisted.
A simple
cp <some file to copy> </mnt/My_Newfs_MountPoint/abc.txt> hangs, if I don't use
sync immediately following the cp operation and this hang is temporary and the system bounces back in a minutes time, leaving a dump under /var/crash/<core file> directory, unmounting the filesystem.
However, when I use the
sync command within some time (say 5 to 10 seconds) the
cp command succeed and the file gets copied perfectly without any issue on my new filesystem.
I'm using a VM for this purpose.
Any input/pointer from anyone is appreciated.
Thanks in advance.