diff options
Diffstat (limited to 'fs/cifs/file.c')
| -rw-r--r-- | fs/cifs/file.c | 72 |
1 files changed, 22 insertions, 50 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index ae82159cf7fa..06c3e83fa387 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -146,12 +146,7 @@ client_can_cache: | |||
| 146 | rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb, | 146 | rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb, |
| 147 | xid, NULL); | 147 | xid, NULL); |
| 148 | 148 | ||
| 149 | if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { | 149 | cifs_set_oplock_level(pCifsInode, oplock); |
| 150 | pCifsInode->clientCanCacheAll = true; | ||
| 151 | pCifsInode->clientCanCacheRead = true; | ||
| 152 | cFYI(1, "Exclusive Oplock granted on inode %p", inode); | ||
| 153 | } else if ((oplock & 0xF) == OPLOCK_READ) | ||
| 154 | pCifsInode->clientCanCacheRead = true; | ||
| 155 | 150 | ||
| 156 | return rc; | 151 | return rc; |
| 157 | } | 152 | } |
| @@ -253,12 +248,7 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file, | |||
| 253 | list_add_tail(&pCifsFile->flist, &pCifsInode->openFileList); | 248 | list_add_tail(&pCifsFile->flist, &pCifsInode->openFileList); |
| 254 | spin_unlock(&cifs_file_list_lock); | 249 | spin_unlock(&cifs_file_list_lock); |
| 255 | 250 | ||
| 256 | if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { | 251 | cifs_set_oplock_level(pCifsInode, oplock); |
| 257 | pCifsInode->clientCanCacheAll = true; | ||
| 258 | pCifsInode->clientCanCacheRead = true; | ||
| 259 | cFYI(1, "Exclusive Oplock inode %p", inode); | ||
| 260 | } else if ((oplock & 0xF) == OPLOCK_READ) | ||
| 261 | pCifsInode->clientCanCacheRead = true; | ||
| 262 | 252 | ||
| 263 | file->private_data = pCifsFile; | 253 | file->private_data = pCifsFile; |
| 264 | return pCifsFile; | 254 | return pCifsFile; |
| @@ -271,8 +261,9 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file, | |||
| 271 | */ | 261 | */ |
| 272 | void cifsFileInfo_put(struct cifsFileInfo *cifs_file) | 262 | void cifsFileInfo_put(struct cifsFileInfo *cifs_file) |
| 273 | { | 263 | { |
| 264 | struct inode *inode = cifs_file->dentry->d_inode; | ||
| 274 | struct cifsTconInfo *tcon = tlink_tcon(cifs_file->tlink); | 265 | struct cifsTconInfo *tcon = tlink_tcon(cifs_file->tlink); |
| 275 | struct cifsInodeInfo *cifsi = CIFS_I(cifs_file->dentry->d_inode); | 266 | struct cifsInodeInfo *cifsi = CIFS_I(inode); |
| 276 | struct cifsLockInfo *li, *tmp; | 267 | struct cifsLockInfo *li, *tmp; |
| 277 | 268 | ||
| 278 | spin_lock(&cifs_file_list_lock); | 269 | spin_lock(&cifs_file_list_lock); |
| @@ -288,8 +279,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) | |||
| 288 | if (list_empty(&cifsi->openFileList)) { | 279 | if (list_empty(&cifsi->openFileList)) { |
| 289 | cFYI(1, "closing last open instance for inode %p", | 280 | cFYI(1, "closing last open instance for inode %p", |
| 290 | cifs_file->dentry->d_inode); | 281 | cifs_file->dentry->d_inode); |
| 291 | cifsi->clientCanCacheRead = false; | 282 | cifs_set_oplock_level(cifsi, 0); |
| 292 | cifsi->clientCanCacheAll = false; | ||
| 293 | } | 283 | } |
| 294 | spin_unlock(&cifs_file_list_lock); | 284 | spin_unlock(&cifs_file_list_lock); |
| 295 | 285 | ||
| @@ -607,8 +597,6 @@ reopen_success: | |||
| 607 | rc = filemap_write_and_wait(inode->i_mapping); | 597 | rc = filemap_write_and_wait(inode->i_mapping); |
| 608 | mapping_set_error(inode->i_mapping, rc); | 598 | mapping_set_error(inode->i_mapping, rc); |
| 609 | 599 | ||
| 610 | pCifsInode->clientCanCacheAll = false; | ||
| 611 | pCifsInode->clientCanCacheRead = false; | ||
| 612 | if (tcon->unix_ext) | 600 | if (tcon->unix_ext) |
| 613 | rc = cifs_get_inode_info_unix(&inode, | 601 | rc = cifs_get_inode_info_unix(&inode, |
| 614 | full_path, inode->i_sb, xid); | 602 | full_path, inode->i_sb, xid); |
| @@ -622,18 +610,9 @@ reopen_success: | |||
| 622 | invalidate the current end of file on the server | 610 | invalidate the current end of file on the server |
| 623 | we can not go to the server to get the new inod | 611 | we can not go to the server to get the new inod |
| 624 | info */ | 612 | info */ |
| 625 | if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { | 613 | |
| 626 | pCifsInode->clientCanCacheAll = true; | 614 | cifs_set_oplock_level(pCifsInode, oplock); |
| 627 | pCifsInode->clientCanCacheRead = true; | 615 | |
| 628 | cFYI(1, "Exclusive Oplock granted on inode %p", | ||
| 629 | pCifsFile->dentry->d_inode); | ||
| 630 | } else if ((oplock & 0xF) == OPLOCK_READ) { | ||
| 631 | pCifsInode->clientCanCacheRead = true; | ||
| 632 | pCifsInode->clientCanCacheAll = false; | ||
| 633 | } else { | ||
| 634 | pCifsInode->clientCanCacheRead = false; | ||
| 635 | pCifsInode->clientCanCacheAll = false; | ||
| 636 | } | ||
| 637 | cifs_relock_file(pCifsFile); | 616 | cifs_relock_file(pCifsFile); |
| 638 | 617 | ||
| 639 | reopen_error_exit: | 618 | reopen_error_exit: |
| @@ -775,12 +754,6 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
| 775 | 754 | ||
| 776 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 755 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
| 777 | tcon = tlink_tcon(((struct cifsFileInfo *)file->private_data)->tlink); | 756 | tcon = tlink_tcon(((struct cifsFileInfo *)file->private_data)->tlink); |
| 778 | |||
| 779 | if (file->private_data == NULL) { | ||
| 780 | rc = -EBADF; | ||
| 781 | FreeXid(xid); | ||
| 782 | return rc; | ||
| 783 | } | ||
| 784 | netfid = ((struct cifsFileInfo *)file->private_data)->netfid; | 757 | netfid = ((struct cifsFileInfo *)file->private_data)->netfid; |
| 785 | 758 | ||
| 786 | if ((tcon->ses->capabilities & CAP_UNIX) && | 759 | if ((tcon->ses->capabilities & CAP_UNIX) && |
| @@ -956,6 +929,7 @@ cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset, | |||
| 956 | ssize_t cifs_user_write(struct file *file, const char __user *write_data, | 929 | ssize_t cifs_user_write(struct file *file, const char __user *write_data, |
| 957 | size_t write_size, loff_t *poffset) | 930 | size_t write_size, loff_t *poffset) |
| 958 | { | 931 | { |
| 932 | struct inode *inode = file->f_path.dentry->d_inode; | ||
| 959 | int rc = 0; | 933 | int rc = 0; |
| 960 | unsigned int bytes_written = 0; | 934 | unsigned int bytes_written = 0; |
| 961 | unsigned int total_written; | 935 | unsigned int total_written; |
| @@ -963,7 +937,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
| 963 | struct cifsTconInfo *pTcon; | 937 | struct cifsTconInfo *pTcon; |
| 964 | int xid, long_op; | 938 | int xid, long_op; |
| 965 | struct cifsFileInfo *open_file; | 939 | struct cifsFileInfo *open_file; |
| 966 | struct cifsInodeInfo *cifsi = CIFS_I(file->f_path.dentry->d_inode); | 940 | struct cifsInodeInfo *cifsi = CIFS_I(inode); |
| 967 | 941 | ||
| 968 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 942 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
| 969 | 943 | ||
| @@ -1029,21 +1003,17 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
| 1029 | 1003 | ||
| 1030 | cifs_stats_bytes_written(pTcon, total_written); | 1004 | cifs_stats_bytes_written(pTcon, total_written); |
| 1031 | 1005 | ||
| 1032 | /* since the write may have blocked check these pointers again */ | ||
| 1033 | if ((file->f_path.dentry) && (file->f_path.dentry->d_inode)) { | ||
| 1034 | struct inode *inode = file->f_path.dentry->d_inode; | ||
| 1035 | /* Do not update local mtime - server will set its actual value on write | 1006 | /* Do not update local mtime - server will set its actual value on write |
| 1036 | * inode->i_ctime = inode->i_mtime = | 1007 | * inode->i_ctime = inode->i_mtime = |
| 1037 | * current_fs_time(inode->i_sb);*/ | 1008 | * current_fs_time(inode->i_sb);*/ |
| 1038 | if (total_written > 0) { | 1009 | if (total_written > 0) { |
| 1039 | spin_lock(&inode->i_lock); | 1010 | spin_lock(&inode->i_lock); |
| 1040 | if (*poffset > file->f_path.dentry->d_inode->i_size) | 1011 | if (*poffset > inode->i_size) |
| 1041 | i_size_write(file->f_path.dentry->d_inode, | 1012 | i_size_write(inode, *poffset); |
| 1042 | *poffset); | 1013 | spin_unlock(&inode->i_lock); |
| 1043 | spin_unlock(&inode->i_lock); | ||
| 1044 | } | ||
| 1045 | mark_inode_dirty_sync(file->f_path.dentry->d_inode); | ||
| 1046 | } | 1014 | } |
| 1015 | mark_inode_dirty_sync(inode); | ||
| 1016 | |||
| 1047 | FreeXid(xid); | 1017 | FreeXid(xid); |
| 1048 | return total_written; | 1018 | return total_written; |
| 1049 | } | 1019 | } |
| @@ -1178,7 +1148,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, | |||
| 1178 | bool fsuid_only) | 1148 | bool fsuid_only) |
| 1179 | { | 1149 | { |
| 1180 | struct cifsFileInfo *open_file; | 1150 | struct cifsFileInfo *open_file; |
| 1181 | struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); | 1151 | struct cifs_sb_info *cifs_sb; |
| 1182 | bool any_available = false; | 1152 | bool any_available = false; |
| 1183 | int rc; | 1153 | int rc; |
| 1184 | 1154 | ||
| @@ -1192,6 +1162,8 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, | |||
| 1192 | return NULL; | 1162 | return NULL; |
| 1193 | } | 1163 | } |
| 1194 | 1164 | ||
| 1165 | cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); | ||
| 1166 | |||
| 1195 | /* only filter by fsuid on multiuser mounts */ | 1167 | /* only filter by fsuid on multiuser mounts */ |
| 1196 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) | 1168 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) |
| 1197 | fsuid_only = false; | 1169 | fsuid_only = false; |
