dirty pages in the mapping after filemap_fdatawrite returns 0 called in cifs_flush

From: Shirish Pargaonkar
Date: Sat Nov 08 2008 - 04:34:26 EST


On a 2.6.18-120.el5PAE,
if filemap_fdatawrite returns without any errors, is it not the case that
there are no more dirty pages in the mapping of this inode?
Yet pagevec_lookup_tag called after filemap_fdatawrite returns with 0, sasys so.
If filemap_fdatawrite has returned with value of 0, cifs_writepages has returned
with value of 0 as well!


CIFS VFS: cifs_flush for 7.test has dr_pages: 6 drrc: 0
CIFS VFS: No writable handles for inode
CIFS VFS: cifs_flush for 13.test has dr_pages: 1 drrc: 0
CIFS VFS: No writable handles for inode
CIFS VFS: cifs_flush for 17.test has dr_pages: 1 drrc: 0
CIFS VFS: No writable handles for inode



/*
* As file closes, flush all cached write data for this inode checking
* for write behind errors.
*/
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)
int cifs_flush(struct file *file, fl_owner_t id)
#else
int cifs_flush(struct file *file)
#endif /* 2.6.17 */
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
struct inode *inode = file->f_dentry->d_inode;
#else
struct inode *inode = file->f_path.dentry->d_inode;
#endif
int rc = 0;
unsigned dr_pages;
int drrc = 0;
pgoff_t start = 0;
struct pagevec pvec;

/* Rather than do the steps manually:
lock the inode for writing
loop through pages looking for write behind data (dirty pages)
coalesce into contiguous 16K (or smaller) chunks to write to server
send to server (prefer in parallel)
deal with writebehind errors
unlock inode for writing
filemapfdatawrite appears easier for the time being */

rc = filemap_fdatawrite(inode->i_mapping);
/* reset wb rc if we were able to write out dirty pages */
if (!rc) {
rc = CIFS_I(inode)->write_behind_rc;
CIFS_I(inode)->write_behind_rc = 0;
} else {
cERROR(1, ("cifs_flush error inode %p file %p rc %d",
inode, file, rc));
}

cFYI(1, ("Flush inode %p file %p rc %d", inode, file, rc));

pagevec_init(&pvec, 0);
dr_pages = pagevec_lookup_tag(&pvec,
file->f_dentry->d_inode->i_mapping, &start,
PAGECACHE_TAG_DIRTY, 14);
if (dr_pages) {
// drrc = filemap_fdatawrite(inode->i_mapping);
cERROR(1, ("cifs_flush for %s has dr_pages: %d drrc: %d",
file->f_dentry->d_iname, dr_pages, drrc));
}

return rc;
}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/