diff options
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r-- | fs/cifs/file.c | 78 |
1 files changed, 25 insertions, 53 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index ae82159cf7fa..5a28660ca2b5 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 | } |
@@ -1138,7 +1108,6 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file, | |||
1138 | return total_written; | 1108 | return total_written; |
1139 | } | 1109 | } |
1140 | 1110 | ||
1141 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
1142 | struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, | 1111 | struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, |
1143 | bool fsuid_only) | 1112 | bool fsuid_only) |
1144 | { | 1113 | { |
@@ -1172,13 +1141,12 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, | |||
1172 | spin_unlock(&cifs_file_list_lock); | 1141 | spin_unlock(&cifs_file_list_lock); |
1173 | return NULL; | 1142 | return NULL; |
1174 | } | 1143 | } |
1175 | #endif | ||
1176 | 1144 | ||
1177 | struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, | 1145 | struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, |
1178 | bool fsuid_only) | 1146 | bool fsuid_only) |
1179 | { | 1147 | { |
1180 | struct cifsFileInfo *open_file; | 1148 | struct cifsFileInfo *open_file; |
1181 | struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); | 1149 | struct cifs_sb_info *cifs_sb; |
1182 | bool any_available = false; | 1150 | bool any_available = false; |
1183 | int rc; | 1151 | int rc; |
1184 | 1152 | ||
@@ -1192,6 +1160,8 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, | |||
1192 | return NULL; | 1160 | return NULL; |
1193 | } | 1161 | } |
1194 | 1162 | ||
1163 | cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); | ||
1164 | |||
1195 | /* only filter by fsuid on multiuser mounts */ | 1165 | /* only filter by fsuid on multiuser mounts */ |
1196 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) | 1166 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) |
1197 | fsuid_only = false; | 1167 | fsuid_only = false; |
@@ -2299,8 +2269,10 @@ void cifs_oplock_break_get(struct cifsFileInfo *cfile) | |||
2299 | 2269 | ||
2300 | void cifs_oplock_break_put(struct cifsFileInfo *cfile) | 2270 | void cifs_oplock_break_put(struct cifsFileInfo *cfile) |
2301 | { | 2271 | { |
2272 | struct super_block *sb = cfile->dentry->d_sb; | ||
2273 | |||
2302 | cifsFileInfo_put(cfile); | 2274 | cifsFileInfo_put(cfile); |
2303 | cifs_sb_deactive(cfile->dentry->d_sb); | 2275 | cifs_sb_deactive(sb); |
2304 | } | 2276 | } |
2305 | 2277 | ||
2306 | const struct address_space_operations cifs_addr_ops = { | 2278 | const struct address_space_operations cifs_addr_ops = { |