diff options
Diffstat (limited to 'fs/cifs/cifsfs.c')
-rw-r--r-- | fs/cifs/cifsfs.c | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index f736d8a2e771..0f6a54f14eff 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -618,16 +618,29 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int origin) | |||
618 | { | 618 | { |
619 | /* origin == SEEK_END => we must revalidate the cached file length */ | 619 | /* origin == SEEK_END => we must revalidate the cached file length */ |
620 | if (origin == SEEK_END) { | 620 | if (origin == SEEK_END) { |
621 | int retval; | 621 | int rc; |
622 | 622 | struct inode *inode = file->f_path.dentry->d_inode; | |
623 | /* some applications poll for the file length in this strange | 623 | |
624 | way so we must seek to end on non-oplocked files by | 624 | /* |
625 | setting the revalidate time to zero */ | 625 | * We need to be sure that all dirty pages are written and the |
626 | CIFS_I(file->f_path.dentry->d_inode)->time = 0; | 626 | * server has the newest file length. |
627 | 627 | */ | |
628 | retval = cifs_revalidate_file(file); | 628 | if (!CIFS_I(inode)->clientCanCacheRead && inode->i_mapping && |
629 | if (retval < 0) | 629 | inode->i_mapping->nrpages != 0) { |
630 | return (loff_t)retval; | 630 | rc = filemap_fdatawait(inode->i_mapping); |
631 | mapping_set_error(inode->i_mapping, rc); | ||
632 | return rc; | ||
633 | } | ||
634 | /* | ||
635 | * Some applications poll for the file length in this strange | ||
636 | * way so we must seek to end on non-oplocked files by | ||
637 | * setting the revalidate time to zero. | ||
638 | */ | ||
639 | CIFS_I(inode)->time = 0; | ||
640 | |||
641 | rc = cifs_revalidate_file_attr(file); | ||
642 | if (rc < 0) | ||
643 | return (loff_t)rc; | ||
631 | } | 644 | } |
632 | return generic_file_llseek_unlocked(file, offset, origin); | 645 | return generic_file_llseek_unlocked(file, offset, origin); |
633 | } | 646 | } |