aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r--fs/cifs/file.c57
1 files changed, 18 insertions, 39 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 45af003865d2..ae82159cf7fa 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -131,8 +131,7 @@ static inline int cifs_open_inode_helper(struct inode *inode,
131 /* BB no need to lock inode until after invalidate 131 /* BB no need to lock inode until after invalidate
132 since namei code should already have it locked? */ 132 since namei code should already have it locked? */
133 rc = filemap_write_and_wait(inode->i_mapping); 133 rc = filemap_write_and_wait(inode->i_mapping);
134 if (rc != 0) 134 mapping_set_error(inode->i_mapping, rc);
135 pCifsInode->write_behind_rc = rc;
136 } 135 }
137 cFYI(1, "invalidating remote inode since open detected it " 136 cFYI(1, "invalidating remote inode since open detected it "
138 "changed"); 137 "changed");
@@ -232,6 +231,7 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
232 if (pCifsFile == NULL) 231 if (pCifsFile == NULL)
233 return pCifsFile; 232 return pCifsFile;
234 233
234 pCifsFile->count = 1;
235 pCifsFile->netfid = fileHandle; 235 pCifsFile->netfid = fileHandle;
236 pCifsFile->pid = current->tgid; 236 pCifsFile->pid = current->tgid;
237 pCifsFile->uid = current_fsuid(); 237 pCifsFile->uid = current_fsuid();
@@ -242,7 +242,6 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
242 mutex_init(&pCifsFile->fh_mutex); 242 mutex_init(&pCifsFile->fh_mutex);
243 mutex_init(&pCifsFile->lock_mutex); 243 mutex_init(&pCifsFile->lock_mutex);
244 INIT_LIST_HEAD(&pCifsFile->llist); 244 INIT_LIST_HEAD(&pCifsFile->llist);
245 atomic_set(&pCifsFile->count, 1);
246 INIT_WORK(&pCifsFile->oplock_break, cifs_oplock_break); 245 INIT_WORK(&pCifsFile->oplock_break, cifs_oplock_break);
247 246
248 spin_lock(&cifs_file_list_lock); 247 spin_lock(&cifs_file_list_lock);
@@ -267,7 +266,8 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
267 266
268/* 267/*
269 * Release a reference on the file private data. This may involve closing 268 * Release a reference on the file private data. This may involve closing
270 * the filehandle out on the server. 269 * the filehandle out on the server. Must be called without holding
270 * cifs_file_list_lock.
271 */ 271 */
272void cifsFileInfo_put(struct cifsFileInfo *cifs_file) 272void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
273{ 273{
@@ -276,7 +276,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
276 struct cifsLockInfo *li, *tmp; 276 struct cifsLockInfo *li, *tmp;
277 277
278 spin_lock(&cifs_file_list_lock); 278 spin_lock(&cifs_file_list_lock);
279 if (!atomic_dec_and_test(&cifs_file->count)) { 279 if (--cifs_file->count > 0) {
280 spin_unlock(&cifs_file_list_lock); 280 spin_unlock(&cifs_file_list_lock);
281 return; 281 return;
282 } 282 }
@@ -605,8 +605,7 @@ reopen_success:
605 605
606 if (can_flush) { 606 if (can_flush) {
607 rc = filemap_write_and_wait(inode->i_mapping); 607 rc = filemap_write_and_wait(inode->i_mapping);
608 if (rc != 0) 608 mapping_set_error(inode->i_mapping, rc);
609 CIFS_I(inode)->write_behind_rc = rc;
610 609
611 pCifsInode->clientCanCacheAll = false; 610 pCifsInode->clientCanCacheAll = false;
612 pCifsInode->clientCanCacheRead = false; 611 pCifsInode->clientCanCacheRead = false;
@@ -1353,6 +1352,7 @@ static int cifs_writepages(struct address_space *mapping,
1353 if (!experimEnabled && tcon->ses->server->secMode & 1352 if (!experimEnabled && tcon->ses->server->secMode &
1354 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { 1353 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
1355 cifsFileInfo_put(open_file); 1354 cifsFileInfo_put(open_file);
1355 kfree(iov);
1356 return generic_writepages(mapping, wbc); 1356 return generic_writepages(mapping, wbc);
1357 } 1357 }
1358 cifsFileInfo_put(open_file); 1358 cifsFileInfo_put(open_file);
@@ -1478,12 +1478,7 @@ retry:
1478 if (rc || bytes_written < bytes_to_write) { 1478 if (rc || bytes_written < bytes_to_write) {
1479 cERROR(1, "Write2 ret %d, wrote %d", 1479 cERROR(1, "Write2 ret %d, wrote %d",
1480 rc, bytes_written); 1480 rc, bytes_written);
1481 /* BB what if continued retry is 1481 mapping_set_error(mapping, rc);
1482 requested via mount flags? */
1483 if (rc == -ENOSPC)
1484 set_bit(AS_ENOSPC, &mapping->flags);
1485 else
1486 set_bit(AS_EIO, &mapping->flags);
1487 } else { 1482 } else {
1488 cifs_stats_bytes_written(tcon, bytes_written); 1483 cifs_stats_bytes_written(tcon, bytes_written);
1489 } 1484 }
@@ -1628,11 +1623,10 @@ int cifs_fsync(struct file *file, int datasync)
1628 1623
1629 rc = filemap_write_and_wait(inode->i_mapping); 1624 rc = filemap_write_and_wait(inode->i_mapping);
1630 if (rc == 0) { 1625 if (rc == 0) {
1631 rc = CIFS_I(inode)->write_behind_rc; 1626 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1632 CIFS_I(inode)->write_behind_rc = 0; 1627
1633 tcon = tlink_tcon(smbfile->tlink); 1628 tcon = tlink_tcon(smbfile->tlink);
1634 if (!rc && tcon && smbfile && 1629 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC))
1635 !(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC))
1636 rc = CIFSSMBFlush(xid, tcon, smbfile->netfid); 1630 rc = CIFSSMBFlush(xid, tcon, smbfile->netfid);
1637 } 1631 }
1638 1632
@@ -1677,21 +1671,8 @@ int cifs_flush(struct file *file, fl_owner_t id)
1677 struct inode *inode = file->f_path.dentry->d_inode; 1671 struct inode *inode = file->f_path.dentry->d_inode;
1678 int rc = 0; 1672 int rc = 0;
1679 1673
1680 /* Rather than do the steps manually: 1674 if (file->f_mode & FMODE_WRITE)
1681 lock the inode for writing 1675 rc = filemap_write_and_wait(inode->i_mapping);
1682 loop through pages looking for write behind data (dirty pages)
1683 coalesce into contiguous 16K (or smaller) chunks to write to server
1684 send to server (prefer in parallel)
1685 deal with writebehind errors
1686 unlock inode for writing
1687 filemapfdatawrite appears easier for the time being */
1688
1689 rc = filemap_fdatawrite(inode->i_mapping);
1690 /* reset wb rc if we were able to write out dirty pages */
1691 if (!rc) {
1692 rc = CIFS_I(inode)->write_behind_rc;
1693 CIFS_I(inode)->write_behind_rc = 0;
1694 }
1695 1676
1696 cFYI(1, "Flush inode %p file %p rc %d", inode, file, rc); 1677 cFYI(1, "Flush inode %p file %p rc %d", inode, file, rc);
1697 1678
@@ -2270,7 +2251,7 @@ void cifs_oplock_break(struct work_struct *work)
2270 oplock_break); 2251 oplock_break);
2271 struct inode *inode = cfile->dentry->d_inode; 2252 struct inode *inode = cfile->dentry->d_inode;
2272 struct cifsInodeInfo *cinode = CIFS_I(inode); 2253 struct cifsInodeInfo *cinode = CIFS_I(inode);
2273 int rc, waitrc = 0; 2254 int rc = 0;
2274 2255
2275 if (inode && S_ISREG(inode->i_mode)) { 2256 if (inode && S_ISREG(inode->i_mode)) {
2276 if (cinode->clientCanCacheRead) 2257 if (cinode->clientCanCacheRead)
@@ -2279,13 +2260,10 @@ void cifs_oplock_break(struct work_struct *work)
2279 break_lease(inode, O_WRONLY); 2260 break_lease(inode, O_WRONLY);
2280 rc = filemap_fdatawrite(inode->i_mapping); 2261 rc = filemap_fdatawrite(inode->i_mapping);
2281 if (cinode->clientCanCacheRead == 0) { 2262 if (cinode->clientCanCacheRead == 0) {
2282 waitrc = filemap_fdatawait(inode->i_mapping); 2263 rc = filemap_fdatawait(inode->i_mapping);
2264 mapping_set_error(inode->i_mapping, rc);
2283 invalidate_remote_inode(inode); 2265 invalidate_remote_inode(inode);
2284 } 2266 }
2285 if (!rc)
2286 rc = waitrc;
2287 if (rc)
2288 cinode->write_behind_rc = rc;
2289 cFYI(1, "Oplock flush inode %p rc %d", inode, rc); 2267 cFYI(1, "Oplock flush inode %p rc %d", inode, rc);
2290 } 2268 }
2291 2269
@@ -2304,7 +2282,7 @@ void cifs_oplock_break(struct work_struct *work)
2304 /* 2282 /*
2305 * We might have kicked in before is_valid_oplock_break() 2283 * We might have kicked in before is_valid_oplock_break()
2306 * finished grabbing reference for us. Make sure it's done by 2284 * finished grabbing reference for us. Make sure it's done by
2307 * waiting for GlobalSMSSeslock. 2285 * waiting for cifs_file_list_lock.
2308 */ 2286 */
2309 spin_lock(&cifs_file_list_lock); 2287 spin_lock(&cifs_file_list_lock);
2310 spin_unlock(&cifs_file_list_lock); 2288 spin_unlock(&cifs_file_list_lock);
@@ -2312,6 +2290,7 @@ void cifs_oplock_break(struct work_struct *work)
2312 cifs_oplock_break_put(cfile); 2290 cifs_oplock_break_put(cfile);
2313} 2291}
2314 2292
2293/* must be called while holding cifs_file_list_lock */
2315void cifs_oplock_break_get(struct cifsFileInfo *cfile) 2294void cifs_oplock_break_get(struct cifsFileInfo *cfile)
2316{ 2295{
2317 cifs_sb_active(cfile->dentry->d_sb); 2296 cifs_sb_active(cfile->dentry->d_sb);