@@ -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 should not 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,19 @@ 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);
+ /*
+ * We only need to flush all dirty pages and should not aware
+ * if some of them are busy (-EBUSY error code).
+ */
+ if (rc == -EBUSY)
+ rc = 0;
+ if (rc) {
+ FreeXid(xid);
+ return rc;
+ }
+ }
tcon = tlink_tcon(smbfile->tlink);
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC))
@@ -1916,8 +1927,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,10 +1683,10 @@ 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;
@@ -1697,13 +1697,14 @@ cifs_invalidate_mapping(struct inode *inode)
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);
+ cFYI(1, "%s: could not invalidate inode %p", __func__,
+ inode);
cifs_i->invalid_mapping = true;
}
}
cifs_fscache_reset_inode_cookie(inode);
+ return rc;
}
int cifs_revalidate_file(struct file *filp)
@@ -1722,7 +1723,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 +1765,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 +1777,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 inode attributes and should not aware about busy
+ * pages (-EBUSY error code).
+ */
+ if (err == -EBUSY)
+ err = 0;
if (!err) {
generic_fillattr(dentry->d_inode, stat);