Messages in this thread | | | Date | Sat, 8 Nov 2008 03:34:14 -0600 | From | "Shirish Pargaonkar" <> | Subject | dirty pages in the mapping after filemap_fdatawrite returns 0 called in cifs_flush |
| |
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; }
| |