@@ -634,7 +634,13 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
CIFS_I(file->f_path.dentry->d_inode)->time = 0;
retval = cifs_revalidate_file(file);
- if (retval < 0)
+ /*
+ * We only need to get right file length and don't need to
+ * aware about busy pages (-EBUSY error code).
+ */
+ if (retval == -EBUSY)
+ retval = 0;
+ else if (retval < 0)
return (loff_t)retval;
}
return generic_file_llseek_unlocked(file, offset, origin);
@@ -61,7 +61,7 @@ extern int cifs_rename(struct inode *, struct dentry *, struct inode *,
struct dentry *);
extern int cifs_revalidate_file(struct file *filp);
extern int cifs_revalidate_dentry(struct dentry *);
-extern void cifs_invalidate_mapping(struct inode *inode);
+extern int cifs_invalidate_mapping(struct inode *inode);
extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
extern int cifs_setattr(struct dentry *, struct iattr *);
@@ -1448,8 +1448,13 @@ int cifs_strict_fsync(struct file *file, int datasync)
cFYI(1, "Sync file - name: %s datasync: 0x%x",
file->f_path.dentry->d_name.name, datasync);
- if (!CIFS_I(inode)->clientCanCacheRead)
- cifs_invalidate_mapping(inode);
+ if (!CIFS_I(inode)->clientCanCacheRead) {
+ rc = cifs_invalidate_mapping(inode);
+ if (rc) {
+ FreeXid(xid);
+ return rc;
+ }
+ }
tcon = tlink_tcon(smbfile->tlink);
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC))
@@ -1916,8 +1921,13 @@ int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma)
xid = GetXid();
- if (!CIFS_I(inode)->clientCanCacheRead)
- cifs_invalidate_mapping(inode);
+ if (!CIFS_I(inode)->clientCanCacheRead) {
+ rc = cifs_invalidate_mapping(inode);
+ if (rc) {
+ FreeXid(xid);
+ return rc;
+ }
+ }
rc = generic_file_mmap(file, vma);
FreeXid(xid);
@@ -1683,27 +1683,25 @@ cifs_inode_needs_reval(struct inode *inode)
/*
* Zap the cache. Called when invalid_mapping flag is set.
*/
-void
+int
cifs_invalidate_mapping(struct inode *inode)
{
- int rc;
+ int rc = 0;
struct cifsInodeInfo *cifs_i = CIFS_I(inode);
- cifs_i->invalid_mapping = false;
-
if (inode->i_mapping && inode->i_mapping->nrpages != 0) {
/* write back any cached data */
rc = filemap_write_and_wait(inode->i_mapping);
mapping_set_error(inode->i_mapping, rc);
rc = invalidate_inode_pages2(inode->i_mapping);
- if (rc) {
- cERROR(1, "%s: could not invalidate inode %p", __func__,
- inode);
- cifs_i->invalid_mapping = true;
- }
+ if (rc)
+ cFYI(1, "%s: could not invalidate inode %p", __func__,
+ inode);
+ cifs_i->invalid_mapping = (rc != 0) ? true : false;
}
cifs_fscache_reset_inode_cookie(inode);
+ return rc;
}
int cifs_revalidate_file(struct file *filp)
@@ -1722,7 +1720,7 @@ int cifs_revalidate_file(struct file *filp)
check_inval:
if (CIFS_I(inode)->invalid_mapping)
- cifs_invalidate_mapping(inode);
+ rc = cifs_invalidate_mapping(inode);
return rc;
}
@@ -1764,7 +1762,7 @@ int cifs_revalidate_dentry(struct dentry *dentry)
check_inval:
if (CIFS_I(inode)->invalid_mapping)
- cifs_invalidate_mapping(inode);
+ rc = cifs_invalidate_mapping(inode);
kfree(full_path);
FreeXid(xid);
@@ -1776,7 +1774,15 @@ int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
{
struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
- int err = cifs_revalidate_dentry(dentry);
+ int err;
+
+ err = cifs_revalidate_dentry(dentry);
+ /*
+ * We only need to get file attributes and don't need to
+ * aware about busy pages (-EBUSY error code).
+ */
+ if (err == -EBUSY)
+ err = 0;
if (!err) {
generic_fillattr(dentry->d_inode, stat);