diff options
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r-- | fs/cifs/file.c | 200 |
1 files changed, 125 insertions, 75 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 70b6f4c3a0c1..0a6677ba212b 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -505,16 +505,36 @@ out: | |||
505 | return rc; | 505 | return rc; |
506 | } | 506 | } |
507 | 507 | ||
508 | static int cifs_push_posix_locks(struct cifsFileInfo *cfile); | ||
509 | |||
508 | /* | 510 | /* |
509 | * Try to reacquire byte range locks that were released when session | 511 | * Try to reacquire byte range locks that were released when session |
510 | * to server was lost | 512 | * to server was lost. |
511 | */ | 513 | */ |
512 | static int cifs_relock_file(struct cifsFileInfo *cifsFile) | 514 | static int |
515 | cifs_relock_file(struct cifsFileInfo *cfile) | ||
513 | { | 516 | { |
517 | struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb); | ||
518 | struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode); | ||
519 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); | ||
514 | int rc = 0; | 520 | int rc = 0; |
515 | 521 | ||
516 | /* BB list all locks open on this file and relock */ | 522 | /* we are going to update can_cache_brlcks here - need a write access */ |
523 | down_write(&cinode->lock_sem); | ||
524 | if (cinode->can_cache_brlcks) { | ||
525 | /* can cache locks - no need to push them */ | ||
526 | up_write(&cinode->lock_sem); | ||
527 | return rc; | ||
528 | } | ||
517 | 529 | ||
530 | if (cap_unix(tcon->ses) && | ||
531 | (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && | ||
532 | ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) | ||
533 | rc = cifs_push_posix_locks(cfile); | ||
534 | else | ||
535 | rc = tcon->ses->server->ops->push_mand_locks(cfile); | ||
536 | |||
537 | up_write(&cinode->lock_sem); | ||
518 | return rc; | 538 | return rc; |
519 | } | 539 | } |
520 | 540 | ||
@@ -739,10 +759,15 @@ cifs_del_lock_waiters(struct cifsLockInfo *lock) | |||
739 | } | 759 | } |
740 | } | 760 | } |
741 | 761 | ||
762 | #define CIFS_LOCK_OP 0 | ||
763 | #define CIFS_READ_OP 1 | ||
764 | #define CIFS_WRITE_OP 2 | ||
765 | |||
766 | /* @rw_check : 0 - no op, 1 - read, 2 - write */ | ||
742 | static bool | 767 | static bool |
743 | cifs_find_fid_lock_conflict(struct cifs_fid_locks *fdlocks, __u64 offset, | 768 | cifs_find_fid_lock_conflict(struct cifs_fid_locks *fdlocks, __u64 offset, |
744 | __u64 length, __u8 type, struct cifsFileInfo *cfile, | 769 | __u64 length, __u8 type, struct cifsFileInfo *cfile, |
745 | struct cifsLockInfo **conf_lock, bool rw_check) | 770 | struct cifsLockInfo **conf_lock, int rw_check) |
746 | { | 771 | { |
747 | struct cifsLockInfo *li; | 772 | struct cifsLockInfo *li; |
748 | struct cifsFileInfo *cur_cfile = fdlocks->cfile; | 773 | struct cifsFileInfo *cur_cfile = fdlocks->cfile; |
@@ -752,9 +777,13 @@ cifs_find_fid_lock_conflict(struct cifs_fid_locks *fdlocks, __u64 offset, | |||
752 | if (offset + length <= li->offset || | 777 | if (offset + length <= li->offset || |
753 | offset >= li->offset + li->length) | 778 | offset >= li->offset + li->length) |
754 | continue; | 779 | continue; |
755 | if (rw_check && server->ops->compare_fids(cfile, cur_cfile) && | 780 | if (rw_check != CIFS_LOCK_OP && current->tgid == li->pid && |
756 | current->tgid == li->pid) | 781 | server->ops->compare_fids(cfile, cur_cfile)) { |
757 | continue; | 782 | /* shared lock prevents write op through the same fid */ |
783 | if (!(li->type & server->vals->shared_lock_type) || | ||
784 | rw_check != CIFS_WRITE_OP) | ||
785 | continue; | ||
786 | } | ||
758 | if ((type & server->vals->shared_lock_type) && | 787 | if ((type & server->vals->shared_lock_type) && |
759 | ((server->ops->compare_fids(cfile, cur_cfile) && | 788 | ((server->ops->compare_fids(cfile, cur_cfile) && |
760 | current->tgid == li->pid) || type == li->type)) | 789 | current->tgid == li->pid) || type == li->type)) |
@@ -769,7 +798,7 @@ cifs_find_fid_lock_conflict(struct cifs_fid_locks *fdlocks, __u64 offset, | |||
769 | bool | 798 | bool |
770 | cifs_find_lock_conflict(struct cifsFileInfo *cfile, __u64 offset, __u64 length, | 799 | cifs_find_lock_conflict(struct cifsFileInfo *cfile, __u64 offset, __u64 length, |
771 | __u8 type, struct cifsLockInfo **conf_lock, | 800 | __u8 type, struct cifsLockInfo **conf_lock, |
772 | bool rw_check) | 801 | int rw_check) |
773 | { | 802 | { |
774 | bool rc = false; | 803 | bool rc = false; |
775 | struct cifs_fid_locks *cur; | 804 | struct cifs_fid_locks *cur; |
@@ -805,7 +834,7 @@ cifs_lock_test(struct cifsFileInfo *cfile, __u64 offset, __u64 length, | |||
805 | down_read(&cinode->lock_sem); | 834 | down_read(&cinode->lock_sem); |
806 | 835 | ||
807 | exist = cifs_find_lock_conflict(cfile, offset, length, type, | 836 | exist = cifs_find_lock_conflict(cfile, offset, length, type, |
808 | &conf_lock, false); | 837 | &conf_lock, CIFS_LOCK_OP); |
809 | if (exist) { | 838 | if (exist) { |
810 | flock->fl_start = conf_lock->offset; | 839 | flock->fl_start = conf_lock->offset; |
811 | flock->fl_end = conf_lock->offset + conf_lock->length - 1; | 840 | flock->fl_end = conf_lock->offset + conf_lock->length - 1; |
@@ -852,7 +881,7 @@ try_again: | |||
852 | down_write(&cinode->lock_sem); | 881 | down_write(&cinode->lock_sem); |
853 | 882 | ||
854 | exist = cifs_find_lock_conflict(cfile, lock->offset, lock->length, | 883 | exist = cifs_find_lock_conflict(cfile, lock->offset, lock->length, |
855 | lock->type, &conf_lock, false); | 884 | lock->type, &conf_lock, CIFS_LOCK_OP); |
856 | if (!exist && cinode->can_cache_brlcks) { | 885 | if (!exist && cinode->can_cache_brlcks) { |
857 | list_add_tail(&lock->llist, &cfile->llist->locks); | 886 | list_add_tail(&lock->llist, &cfile->llist->locks); |
858 | up_write(&cinode->lock_sem); | 887 | up_write(&cinode->lock_sem); |
@@ -948,7 +977,6 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile) | |||
948 | int rc = 0, stored_rc; | 977 | int rc = 0, stored_rc; |
949 | struct cifsLockInfo *li, *tmp; | 978 | struct cifsLockInfo *li, *tmp; |
950 | struct cifs_tcon *tcon; | 979 | struct cifs_tcon *tcon; |
951 | struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode); | ||
952 | unsigned int num, max_num, max_buf; | 980 | unsigned int num, max_num, max_buf; |
953 | LOCKING_ANDX_RANGE *buf, *cur; | 981 | LOCKING_ANDX_RANGE *buf, *cur; |
954 | int types[] = {LOCKING_ANDX_LARGE_FILES, | 982 | int types[] = {LOCKING_ANDX_LARGE_FILES, |
@@ -958,21 +986,12 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile) | |||
958 | xid = get_xid(); | 986 | xid = get_xid(); |
959 | tcon = tlink_tcon(cfile->tlink); | 987 | tcon = tlink_tcon(cfile->tlink); |
960 | 988 | ||
961 | /* we are going to update can_cache_brlcks here - need a write access */ | ||
962 | down_write(&cinode->lock_sem); | ||
963 | if (!cinode->can_cache_brlcks) { | ||
964 | up_write(&cinode->lock_sem); | ||
965 | free_xid(xid); | ||
966 | return rc; | ||
967 | } | ||
968 | |||
969 | /* | 989 | /* |
970 | * Accessing maxBuf is racy with cifs_reconnect - need to store value | 990 | * Accessing maxBuf is racy with cifs_reconnect - need to store value |
971 | * and check it for zero before using. | 991 | * and check it for zero before using. |
972 | */ | 992 | */ |
973 | max_buf = tcon->ses->server->maxBuf; | 993 | max_buf = tcon->ses->server->maxBuf; |
974 | if (!max_buf) { | 994 | if (!max_buf) { |
975 | up_write(&cinode->lock_sem); | ||
976 | free_xid(xid); | 995 | free_xid(xid); |
977 | return -EINVAL; | 996 | return -EINVAL; |
978 | } | 997 | } |
@@ -981,7 +1000,6 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile) | |||
981 | sizeof(LOCKING_ANDX_RANGE); | 1000 | sizeof(LOCKING_ANDX_RANGE); |
982 | buf = kzalloc(max_num * sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL); | 1001 | buf = kzalloc(max_num * sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL); |
983 | if (!buf) { | 1002 | if (!buf) { |
984 | up_write(&cinode->lock_sem); | ||
985 | free_xid(xid); | 1003 | free_xid(xid); |
986 | return -ENOMEM; | 1004 | return -ENOMEM; |
987 | } | 1005 | } |
@@ -1018,9 +1036,6 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile) | |||
1018 | } | 1036 | } |
1019 | } | 1037 | } |
1020 | 1038 | ||
1021 | cinode->can_cache_brlcks = false; | ||
1022 | up_write(&cinode->lock_sem); | ||
1023 | |||
1024 | kfree(buf); | 1039 | kfree(buf); |
1025 | free_xid(xid); | 1040 | free_xid(xid); |
1026 | return rc; | 1041 | return rc; |
@@ -1043,7 +1058,6 @@ struct lock_to_push { | |||
1043 | static int | 1058 | static int |
1044 | cifs_push_posix_locks(struct cifsFileInfo *cfile) | 1059 | cifs_push_posix_locks(struct cifsFileInfo *cfile) |
1045 | { | 1060 | { |
1046 | struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode); | ||
1047 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); | 1061 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
1048 | struct file_lock *flock, **before; | 1062 | struct file_lock *flock, **before; |
1049 | unsigned int count = 0, i = 0; | 1063 | unsigned int count = 0, i = 0; |
@@ -1054,14 +1068,6 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile) | |||
1054 | 1068 | ||
1055 | xid = get_xid(); | 1069 | xid = get_xid(); |
1056 | 1070 | ||
1057 | /* we are going to update can_cache_brlcks here - need a write access */ | ||
1058 | down_write(&cinode->lock_sem); | ||
1059 | if (!cinode->can_cache_brlcks) { | ||
1060 | up_write(&cinode->lock_sem); | ||
1061 | free_xid(xid); | ||
1062 | return rc; | ||
1063 | } | ||
1064 | |||
1065 | lock_flocks(); | 1071 | lock_flocks(); |
1066 | cifs_for_each_lock(cfile->dentry->d_inode, before) { | 1072 | cifs_for_each_lock(cfile->dentry->d_inode, before) { |
1067 | if ((*before)->fl_flags & FL_POSIX) | 1073 | if ((*before)->fl_flags & FL_POSIX) |
@@ -1127,9 +1133,6 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile) | |||
1127 | } | 1133 | } |
1128 | 1134 | ||
1129 | out: | 1135 | out: |
1130 | cinode->can_cache_brlcks = false; | ||
1131 | up_write(&cinode->lock_sem); | ||
1132 | |||
1133 | free_xid(xid); | 1136 | free_xid(xid); |
1134 | return rc; | 1137 | return rc; |
1135 | err_out: | 1138 | err_out: |
@@ -1144,14 +1147,27 @@ static int | |||
1144 | cifs_push_locks(struct cifsFileInfo *cfile) | 1147 | cifs_push_locks(struct cifsFileInfo *cfile) |
1145 | { | 1148 | { |
1146 | struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb); | 1149 | struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb); |
1150 | struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode); | ||
1147 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); | 1151 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
1152 | int rc = 0; | ||
1153 | |||
1154 | /* we are going to update can_cache_brlcks here - need a write access */ | ||
1155 | down_write(&cinode->lock_sem); | ||
1156 | if (!cinode->can_cache_brlcks) { | ||
1157 | up_write(&cinode->lock_sem); | ||
1158 | return rc; | ||
1159 | } | ||
1148 | 1160 | ||
1149 | if (cap_unix(tcon->ses) && | 1161 | if (cap_unix(tcon->ses) && |
1150 | (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && | 1162 | (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && |
1151 | ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) | 1163 | ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) |
1152 | return cifs_push_posix_locks(cfile); | 1164 | rc = cifs_push_posix_locks(cfile); |
1165 | else | ||
1166 | rc = tcon->ses->server->ops->push_mand_locks(cfile); | ||
1153 | 1167 | ||
1154 | return tcon->ses->server->ops->push_mand_locks(cfile); | 1168 | cinode->can_cache_brlcks = false; |
1169 | up_write(&cinode->lock_sem); | ||
1170 | return rc; | ||
1155 | } | 1171 | } |
1156 | 1172 | ||
1157 | static void | 1173 | static void |
@@ -1436,16 +1452,18 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type, | |||
1436 | return -ENOMEM; | 1452 | return -ENOMEM; |
1437 | 1453 | ||
1438 | rc = cifs_lock_add_if(cfile, lock, wait_flag); | 1454 | rc = cifs_lock_add_if(cfile, lock, wait_flag); |
1439 | if (rc < 0) | 1455 | if (rc < 0) { |
1440 | kfree(lock); | 1456 | kfree(lock); |
1441 | if (rc <= 0) | 1457 | return rc; |
1458 | } | ||
1459 | if (!rc) | ||
1442 | goto out; | 1460 | goto out; |
1443 | 1461 | ||
1444 | rc = server->ops->mand_lock(xid, cfile, flock->fl_start, length, | 1462 | rc = server->ops->mand_lock(xid, cfile, flock->fl_start, length, |
1445 | type, 1, 0, wait_flag); | 1463 | type, 1, 0, wait_flag); |
1446 | if (rc) { | 1464 | if (rc) { |
1447 | kfree(lock); | 1465 | kfree(lock); |
1448 | goto out; | 1466 | return rc; |
1449 | } | 1467 | } |
1450 | 1468 | ||
1451 | cifs_lock_add(cfile, lock); | 1469 | cifs_lock_add(cfile, lock); |
@@ -2085,7 +2103,15 @@ static int cifs_write_end(struct file *file, struct address_space *mapping, | |||
2085 | } else { | 2103 | } else { |
2086 | rc = copied; | 2104 | rc = copied; |
2087 | pos += copied; | 2105 | pos += copied; |
2088 | set_page_dirty(page); | 2106 | /* |
2107 | * When we use strict cache mode and cifs_strict_writev was run | ||
2108 | * with level II oplock (indicated by leave_pages_clean field of | ||
2109 | * CIFS_I(inode)), we can leave pages clean - cifs_strict_writev | ||
2110 | * sent the data to the server itself. | ||
2111 | */ | ||
2112 | if (!CIFS_I(inode)->leave_pages_clean || | ||
2113 | !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO)) | ||
2114 | set_page_dirty(page); | ||
2089 | } | 2115 | } |
2090 | 2116 | ||
2091 | if (rc > 0) { | 2117 | if (rc > 0) { |
@@ -2436,8 +2462,8 @@ ssize_t cifs_user_writev(struct kiocb *iocb, const struct iovec *iov, | |||
2436 | } | 2462 | } |
2437 | 2463 | ||
2438 | static ssize_t | 2464 | static ssize_t |
2439 | cifs_writev(struct kiocb *iocb, const struct iovec *iov, | 2465 | cifs_pagecache_writev(struct kiocb *iocb, const struct iovec *iov, |
2440 | unsigned long nr_segs, loff_t pos) | 2466 | unsigned long nr_segs, loff_t pos, bool cache_ex) |
2441 | { | 2467 | { |
2442 | struct file *file = iocb->ki_filp; | 2468 | struct file *file = iocb->ki_filp; |
2443 | struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data; | 2469 | struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data; |
@@ -2457,10 +2483,14 @@ cifs_writev(struct kiocb *iocb, const struct iovec *iov, | |||
2457 | down_read(&cinode->lock_sem); | 2483 | down_read(&cinode->lock_sem); |
2458 | if (!cifs_find_lock_conflict(cfile, pos, iov_length(iov, nr_segs), | 2484 | if (!cifs_find_lock_conflict(cfile, pos, iov_length(iov, nr_segs), |
2459 | server->vals->exclusive_lock_type, NULL, | 2485 | server->vals->exclusive_lock_type, NULL, |
2460 | true)) { | 2486 | CIFS_WRITE_OP)) { |
2461 | mutex_lock(&inode->i_mutex); | 2487 | mutex_lock(&inode->i_mutex); |
2488 | if (!cache_ex) | ||
2489 | cinode->leave_pages_clean = true; | ||
2462 | rc = __generic_file_aio_write(iocb, iov, nr_segs, | 2490 | rc = __generic_file_aio_write(iocb, iov, nr_segs, |
2463 | &iocb->ki_pos); | 2491 | &iocb->ki_pos); |
2492 | if (!cache_ex) | ||
2493 | cinode->leave_pages_clean = false; | ||
2464 | mutex_unlock(&inode->i_mutex); | 2494 | mutex_unlock(&inode->i_mutex); |
2465 | } | 2495 | } |
2466 | 2496 | ||
@@ -2487,42 +2517,62 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov, | |||
2487 | struct cifsFileInfo *cfile = (struct cifsFileInfo *) | 2517 | struct cifsFileInfo *cfile = (struct cifsFileInfo *) |
2488 | iocb->ki_filp->private_data; | 2518 | iocb->ki_filp->private_data; |
2489 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); | 2519 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
2490 | 2520 | ssize_t written, written2; | |
2491 | #ifdef CONFIG_CIFS_SMB2 | ||
2492 | /* | 2521 | /* |
2493 | * If we have an oplock for read and want to write a data to the file | 2522 | * We need to store clientCanCacheAll here to prevent race |
2494 | * we need to store it in the page cache and then push it to the server | 2523 | * conditions - this value can be changed during an execution |
2495 | * to be sure the next read will get a valid data. | 2524 | * of generic_file_aio_write. For CIFS it can be changed from |
2525 | * true to false only, but for SMB2 it can be changed both from | ||
2526 | * true to false and vice versa. So, we can end up with a data | ||
2527 | * stored in the cache, not marked dirty and not sent to the | ||
2528 | * server if this value changes its state from false to true | ||
2529 | * after cifs_write_end. | ||
2496 | */ | 2530 | */ |
2497 | if (!cinode->clientCanCacheAll && cinode->clientCanCacheRead) { | 2531 | bool cache_ex = cinode->clientCanCacheAll; |
2498 | ssize_t written; | 2532 | bool cache_read = cinode->clientCanCacheRead; |
2499 | int rc; | 2533 | int rc; |
2500 | 2534 | loff_t saved_pos; | |
2501 | written = generic_file_aio_write(iocb, iov, nr_segs, pos); | ||
2502 | rc = filemap_fdatawrite(inode->i_mapping); | ||
2503 | if (rc) | ||
2504 | return (ssize_t)rc; | ||
2505 | 2535 | ||
2506 | return written; | 2536 | if (cache_ex) { |
2537 | if (cap_unix(tcon->ses) && | ||
2538 | ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0) && | ||
2539 | (CIFS_UNIX_FCNTL_CAP & le64_to_cpu( | ||
2540 | tcon->fsUnixInfo.Capability))) | ||
2541 | return generic_file_aio_write(iocb, iov, nr_segs, pos); | ||
2542 | return cifs_pagecache_writev(iocb, iov, nr_segs, pos, cache_ex); | ||
2507 | } | 2543 | } |
2508 | #endif | ||
2509 | 2544 | ||
2510 | /* | 2545 | /* |
2511 | * For non-oplocked files in strict cache mode we need to write the data | 2546 | * For files without exclusive oplock in strict cache mode we need to |
2512 | * to the server exactly from the pos to pos+len-1 rather than flush all | 2547 | * write the data to the server exactly from the pos to pos+len-1 rather |
2513 | * affected pages because it may cause a error with mandatory locks on | 2548 | * than flush all affected pages because it may cause a error with |
2514 | * these pages but not on the region from pos to ppos+len-1. | 2549 | * mandatory locks on these pages but not on the region from pos to |
2550 | * ppos+len-1. | ||
2515 | */ | 2551 | */ |
2552 | written = cifs_user_writev(iocb, iov, nr_segs, pos); | ||
2553 | if (!cache_read || written <= 0) | ||
2554 | return written; | ||
2516 | 2555 | ||
2517 | if (!cinode->clientCanCacheAll) | 2556 | saved_pos = iocb->ki_pos; |
2518 | return cifs_user_writev(iocb, iov, nr_segs, pos); | 2557 | iocb->ki_pos = pos; |
2519 | 2558 | /* we have a read oplock - need to store a data in the page cache */ | |
2520 | if (cap_unix(tcon->ses) && | 2559 | if (cap_unix(tcon->ses) && |
2521 | (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && | 2560 | ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0) && |
2522 | ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) | 2561 | (CIFS_UNIX_FCNTL_CAP & le64_to_cpu( |
2523 | return generic_file_aio_write(iocb, iov, nr_segs, pos); | 2562 | tcon->fsUnixInfo.Capability))) |
2524 | 2563 | written2 = generic_file_aio_write(iocb, iov, nr_segs, pos); | |
2525 | return cifs_writev(iocb, iov, nr_segs, pos); | 2564 | else |
2565 | written2 = cifs_pagecache_writev(iocb, iov, nr_segs, pos, | ||
2566 | cache_ex); | ||
2567 | /* errors occured during writing - invalidate the page cache */ | ||
2568 | if (written2 < 0) { | ||
2569 | rc = cifs_invalidate_mapping(inode); | ||
2570 | if (rc) | ||
2571 | written = (ssize_t)rc; | ||
2572 | else | ||
2573 | iocb->ki_pos = saved_pos; | ||
2574 | } | ||
2575 | return written; | ||
2526 | } | 2576 | } |
2527 | 2577 | ||
2528 | static struct cifs_readdata * | 2578 | static struct cifs_readdata * |
@@ -2892,7 +2942,7 @@ cifs_strict_readv(struct kiocb *iocb, const struct iovec *iov, | |||
2892 | down_read(&cinode->lock_sem); | 2942 | down_read(&cinode->lock_sem); |
2893 | if (!cifs_find_lock_conflict(cfile, pos, iov_length(iov, nr_segs), | 2943 | if (!cifs_find_lock_conflict(cfile, pos, iov_length(iov, nr_segs), |
2894 | tcon->ses->server->vals->shared_lock_type, | 2944 | tcon->ses->server->vals->shared_lock_type, |
2895 | NULL, true)) | 2945 | NULL, CIFS_READ_OP)) |
2896 | rc = generic_file_aio_read(iocb, iov, nr_segs, pos); | 2946 | rc = generic_file_aio_read(iocb, iov, nr_segs, pos); |
2897 | up_read(&cinode->lock_sem); | 2947 | up_read(&cinode->lock_sem); |
2898 | return rc; | 2948 | return rc; |
@@ -3536,7 +3586,7 @@ void cifs_oplock_break(struct work_struct *work) | |||
3536 | if (cinode->clientCanCacheRead == 0) { | 3586 | if (cinode->clientCanCacheRead == 0) { |
3537 | rc = filemap_fdatawait(inode->i_mapping); | 3587 | rc = filemap_fdatawait(inode->i_mapping); |
3538 | mapping_set_error(inode->i_mapping, rc); | 3588 | mapping_set_error(inode->i_mapping, rc); |
3539 | invalidate_remote_inode(inode); | 3589 | cifs_invalidate_mapping(inode); |
3540 | } | 3590 | } |
3541 | cFYI(1, "Oplock flush inode %p rc %d", inode, rc); | 3591 | cFYI(1, "Oplock flush inode %p rc %d", inode, rc); |
3542 | } | 3592 | } |