diff options
-rw-r--r-- | fs/cifs/cifsglob.h | 2 | ||||
-rw-r--r-- | fs/cifs/file.c | 2 | ||||
-rw-r--r-- | fs/cifs/readdir.c | 2 | ||||
-rw-r--r-- | fs/cifs/smb1ops.c | 7 | ||||
-rw-r--r-- | fs/cifs/smb2maperror.c | 2 | ||||
-rw-r--r-- | fs/cifs/smb2ops.c | 9 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.c | 9 |
7 files changed, 25 insertions, 8 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index bc20a6ea6754..ce24c1fc2123 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -409,6 +409,8 @@ struct smb_version_operations { | |||
409 | /* get mtu credits */ | 409 | /* get mtu credits */ |
410 | int (*wait_mtu_credits)(struct TCP_Server_Info *, unsigned int, | 410 | int (*wait_mtu_credits)(struct TCP_Server_Info *, unsigned int, |
411 | unsigned int *, unsigned int *); | 411 | unsigned int *, unsigned int *); |
412 | /* check if we need to issue closedir */ | ||
413 | bool (*dir_needs_close)(struct cifsFileInfo *); | ||
412 | }; | 414 | }; |
413 | 415 | ||
414 | struct smb_version_values { | 416 | struct smb_version_values { |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 4ab2f79ffa7a..d5fec92e0360 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -762,7 +762,7 @@ int cifs_closedir(struct inode *inode, struct file *file) | |||
762 | 762 | ||
763 | cifs_dbg(FYI, "Freeing private data in close dir\n"); | 763 | cifs_dbg(FYI, "Freeing private data in close dir\n"); |
764 | spin_lock(&cifs_file_list_lock); | 764 | spin_lock(&cifs_file_list_lock); |
765 | if (!cfile->srch_inf.endOfSearch && !cfile->invalidHandle) { | 765 | if (server->ops->dir_needs_close(cfile)) { |
766 | cfile->invalidHandle = true; | 766 | cfile->invalidHandle = true; |
767 | spin_unlock(&cifs_file_list_lock); | 767 | spin_unlock(&cifs_file_list_lock); |
768 | if (server->ops->close_dir) | 768 | if (server->ops->close_dir) |
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index b15862e0f68c..798c80a41c88 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -593,7 +593,7 @@ find_cifs_entry(const unsigned int xid, struct cifs_tcon *tcon, loff_t pos, | |||
593 | /* close and restart search */ | 593 | /* close and restart search */ |
594 | cifs_dbg(FYI, "search backing up - close and restart search\n"); | 594 | cifs_dbg(FYI, "search backing up - close and restart search\n"); |
595 | spin_lock(&cifs_file_list_lock); | 595 | spin_lock(&cifs_file_list_lock); |
596 | if (!cfile->srch_inf.endOfSearch && !cfile->invalidHandle) { | 596 | if (server->ops->dir_needs_close(cfile)) { |
597 | cfile->invalidHandle = true; | 597 | cfile->invalidHandle = true; |
598 | spin_unlock(&cifs_file_list_lock); | 598 | spin_unlock(&cifs_file_list_lock); |
599 | if (server->ops->close) | 599 | if (server->ops->close) |
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index 5e8c22d6c7b9..1a6df4b03f67 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c | |||
@@ -1015,6 +1015,12 @@ cifs_wp_retry_size(struct inode *inode) | |||
1015 | return CIFS_SB(inode->i_sb)->wsize; | 1015 | return CIFS_SB(inode->i_sb)->wsize; |
1016 | } | 1016 | } |
1017 | 1017 | ||
1018 | static bool | ||
1019 | cifs_dir_needs_close(struct cifsFileInfo *cfile) | ||
1020 | { | ||
1021 | return !cfile->srch_inf.endOfSearch && !cfile->invalidHandle; | ||
1022 | } | ||
1023 | |||
1018 | struct smb_version_operations smb1_operations = { | 1024 | struct smb_version_operations smb1_operations = { |
1019 | .send_cancel = send_nt_cancel, | 1025 | .send_cancel = send_nt_cancel, |
1020 | .compare_fids = cifs_compare_fids, | 1026 | .compare_fids = cifs_compare_fids, |
@@ -1086,6 +1092,7 @@ struct smb_version_operations smb1_operations = { | |||
1086 | .create_mf_symlink = cifs_create_mf_symlink, | 1092 | .create_mf_symlink = cifs_create_mf_symlink, |
1087 | .is_read_op = cifs_is_read_op, | 1093 | .is_read_op = cifs_is_read_op, |
1088 | .wp_retry_size = cifs_wp_retry_size, | 1094 | .wp_retry_size = cifs_wp_retry_size, |
1095 | .dir_needs_close = cifs_dir_needs_close, | ||
1089 | #ifdef CONFIG_CIFS_XATTR | 1096 | #ifdef CONFIG_CIFS_XATTR |
1090 | .query_all_EAs = CIFSSMBQAllEAs, | 1097 | .query_all_EAs = CIFSSMBQAllEAs, |
1091 | .set_EA = CIFSSMBSetEA, | 1098 | .set_EA = CIFSSMBSetEA, |
diff --git a/fs/cifs/smb2maperror.c b/fs/cifs/smb2maperror.c index e31a9dfdcd39..a689514e260f 100644 --- a/fs/cifs/smb2maperror.c +++ b/fs/cifs/smb2maperror.c | |||
@@ -214,7 +214,7 @@ static const struct status_to_posix_error smb2_error_map_table[] = { | |||
214 | {STATUS_BREAKPOINT, -EIO, "STATUS_BREAKPOINT"}, | 214 | {STATUS_BREAKPOINT, -EIO, "STATUS_BREAKPOINT"}, |
215 | {STATUS_SINGLE_STEP, -EIO, "STATUS_SINGLE_STEP"}, | 215 | {STATUS_SINGLE_STEP, -EIO, "STATUS_SINGLE_STEP"}, |
216 | {STATUS_BUFFER_OVERFLOW, -EIO, "STATUS_BUFFER_OVERFLOW"}, | 216 | {STATUS_BUFFER_OVERFLOW, -EIO, "STATUS_BUFFER_OVERFLOW"}, |
217 | {STATUS_NO_MORE_FILES, -EIO, "STATUS_NO_MORE_FILES"}, | 217 | {STATUS_NO_MORE_FILES, -ENODATA, "STATUS_NO_MORE_FILES"}, |
218 | {STATUS_WAKE_SYSTEM_DEBUGGER, -EIO, "STATUS_WAKE_SYSTEM_DEBUGGER"}, | 218 | {STATUS_WAKE_SYSTEM_DEBUGGER, -EIO, "STATUS_WAKE_SYSTEM_DEBUGGER"}, |
219 | {STATUS_HANDLES_CLOSED, -EIO, "STATUS_HANDLES_CLOSED"}, | 219 | {STATUS_HANDLES_CLOSED, -EIO, "STATUS_HANDLES_CLOSED"}, |
220 | {STATUS_NO_INHERITANCE, -EIO, "STATUS_NO_INHERITANCE"}, | 220 | {STATUS_NO_INHERITANCE, -EIO, "STATUS_NO_INHERITANCE"}, |
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 85be34ad8d76..3fcd410cee31 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
@@ -1222,6 +1222,12 @@ smb2_wp_retry_size(struct inode *inode) | |||
1222 | SMB2_MAX_BUFFER_SIZE); | 1222 | SMB2_MAX_BUFFER_SIZE); |
1223 | } | 1223 | } |
1224 | 1224 | ||
1225 | static bool | ||
1226 | smb2_dir_needs_close(struct cifsFileInfo *cfile) | ||
1227 | { | ||
1228 | return !cfile->invalidHandle; | ||
1229 | } | ||
1230 | |||
1225 | struct smb_version_operations smb20_operations = { | 1231 | struct smb_version_operations smb20_operations = { |
1226 | .compare_fids = smb2_compare_fids, | 1232 | .compare_fids = smb2_compare_fids, |
1227 | .setup_request = smb2_setup_request, | 1233 | .setup_request = smb2_setup_request, |
@@ -1297,6 +1303,7 @@ struct smb_version_operations smb20_operations = { | |||
1297 | .parse_lease_buf = smb2_parse_lease_buf, | 1303 | .parse_lease_buf = smb2_parse_lease_buf, |
1298 | .clone_range = smb2_clone_range, | 1304 | .clone_range = smb2_clone_range, |
1299 | .wp_retry_size = smb2_wp_retry_size, | 1305 | .wp_retry_size = smb2_wp_retry_size, |
1306 | .dir_needs_close = smb2_dir_needs_close, | ||
1300 | }; | 1307 | }; |
1301 | 1308 | ||
1302 | struct smb_version_operations smb21_operations = { | 1309 | struct smb_version_operations smb21_operations = { |
@@ -1374,6 +1381,7 @@ struct smb_version_operations smb21_operations = { | |||
1374 | .parse_lease_buf = smb2_parse_lease_buf, | 1381 | .parse_lease_buf = smb2_parse_lease_buf, |
1375 | .clone_range = smb2_clone_range, | 1382 | .clone_range = smb2_clone_range, |
1376 | .wp_retry_size = smb2_wp_retry_size, | 1383 | .wp_retry_size = smb2_wp_retry_size, |
1384 | .dir_needs_close = smb2_dir_needs_close, | ||
1377 | }; | 1385 | }; |
1378 | 1386 | ||
1379 | struct smb_version_operations smb30_operations = { | 1387 | struct smb_version_operations smb30_operations = { |
@@ -1454,6 +1462,7 @@ struct smb_version_operations smb30_operations = { | |||
1454 | .clone_range = smb2_clone_range, | 1462 | .clone_range = smb2_clone_range, |
1455 | .validate_negotiate = smb3_validate_negotiate, | 1463 | .validate_negotiate = smb3_validate_negotiate, |
1456 | .wp_retry_size = smb2_wp_retry_size, | 1464 | .wp_retry_size = smb2_wp_retry_size, |
1465 | .dir_needs_close = smb2_dir_needs_close, | ||
1457 | }; | 1466 | }; |
1458 | 1467 | ||
1459 | struct smb_version_values smb20_values = { | 1468 | struct smb_version_values smb20_values = { |
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 240c627bc0c6..fa0dd044213b 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
@@ -2180,6 +2180,10 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon, | |||
2180 | rsp = (struct smb2_query_directory_rsp *)iov[0].iov_base; | 2180 | rsp = (struct smb2_query_directory_rsp *)iov[0].iov_base; |
2181 | 2181 | ||
2182 | if (rc) { | 2182 | if (rc) { |
2183 | if (rc == -ENODATA && rsp->hdr.Status == STATUS_NO_MORE_FILES) { | ||
2184 | srch_inf->endOfSearch = true; | ||
2185 | rc = 0; | ||
2186 | } | ||
2183 | cifs_stats_fail_inc(tcon, SMB2_QUERY_DIRECTORY_HE); | 2187 | cifs_stats_fail_inc(tcon, SMB2_QUERY_DIRECTORY_HE); |
2184 | goto qdir_exit; | 2188 | goto qdir_exit; |
2185 | } | 2189 | } |
@@ -2217,11 +2221,6 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon, | |||
2217 | else | 2221 | else |
2218 | cifs_dbg(VFS, "illegal search buffer type\n"); | 2222 | cifs_dbg(VFS, "illegal search buffer type\n"); |
2219 | 2223 | ||
2220 | if (rsp->hdr.Status == STATUS_NO_MORE_FILES) | ||
2221 | srch_inf->endOfSearch = 1; | ||
2222 | else | ||
2223 | srch_inf->endOfSearch = 0; | ||
2224 | |||
2225 | return rc; | 2224 | return rc; |
2226 | 2225 | ||
2227 | qdir_exit: | 2226 | qdir_exit: |