diff options
| -rw-r--r-- | fs/cifs/cifsproto.h | 6 | ||||
| -rw-r--r-- | fs/cifs/cifssmb.c | 12 | ||||
| -rw-r--r-- | fs/cifs/readdir.c | 15 |
3 files changed, 22 insertions, 11 deletions
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index eeb789d8e855..0a3fa960b84d 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
| @@ -192,11 +192,13 @@ extern int CIFSTCon(unsigned int xid, struct cifs_ses *ses, | |||
| 192 | 192 | ||
| 193 | extern int CIFSFindFirst(const int xid, struct cifs_tcon *tcon, | 193 | extern int CIFSFindFirst(const int xid, struct cifs_tcon *tcon, |
| 194 | const char *searchName, const struct nls_table *nls_codepage, | 194 | const char *searchName, const struct nls_table *nls_codepage, |
| 195 | __u16 *searchHandle, struct cifs_search_info *psrch_inf, | 195 | __u16 *searchHandle, __u16 search_flags, |
| 196 | struct cifs_search_info *psrch_inf, | ||
| 196 | int map, const char dirsep); | 197 | int map, const char dirsep); |
| 197 | 198 | ||
| 198 | extern int CIFSFindNext(const int xid, struct cifs_tcon *tcon, | 199 | extern int CIFSFindNext(const int xid, struct cifs_tcon *tcon, |
| 199 | __u16 searchHandle, struct cifs_search_info *psrch_inf); | 200 | __u16 searchHandle, __u16 search_flags, |
| 201 | struct cifs_search_info *psrch_inf); | ||
| 200 | 202 | ||
| 201 | extern int CIFSFindClose(const int, struct cifs_tcon *tcon, | 203 | extern int CIFSFindClose(const int, struct cifs_tcon *tcon, |
| 202 | const __u16 search_handle); | 204 | const __u16 search_handle); |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 45633da461a8..3563c93d9f17 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
| @@ -4238,7 +4238,7 @@ int | |||
| 4238 | CIFSFindFirst(const int xid, struct cifs_tcon *tcon, | 4238 | CIFSFindFirst(const int xid, struct cifs_tcon *tcon, |
| 4239 | const char *searchName, | 4239 | const char *searchName, |
| 4240 | const struct nls_table *nls_codepage, | 4240 | const struct nls_table *nls_codepage, |
| 4241 | __u16 *pnetfid, | 4241 | __u16 *pnetfid, __u16 search_flags, |
| 4242 | struct cifs_search_info *psrch_inf, int remap, const char dirsep) | 4242 | struct cifs_search_info *psrch_inf, int remap, const char dirsep) |
| 4243 | { | 4243 | { |
| 4244 | /* level 257 SMB_ */ | 4244 | /* level 257 SMB_ */ |
| @@ -4310,8 +4310,7 @@ findFirstRetry: | |||
| 4310 | cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | | 4310 | cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | |
| 4311 | ATTR_DIRECTORY); | 4311 | ATTR_DIRECTORY); |
| 4312 | pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO)); | 4312 | pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO)); |
| 4313 | pSMB->SearchFlags = cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END | | 4313 | pSMB->SearchFlags = cpu_to_le16(search_flags); |
| 4314 | CIFS_SEARCH_RETURN_RESUME); | ||
| 4315 | pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); | 4314 | pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); |
| 4316 | 4315 | ||
| 4317 | /* BB what should we set StorageType to? Does it matter? BB */ | 4316 | /* BB what should we set StorageType to? Does it matter? BB */ |
| @@ -4381,8 +4380,8 @@ findFirstRetry: | |||
| 4381 | return rc; | 4380 | return rc; |
| 4382 | } | 4381 | } |
| 4383 | 4382 | ||
| 4384 | int CIFSFindNext(const int xid, struct cifs_tcon *tcon, | 4383 | int CIFSFindNext(const int xid, struct cifs_tcon *tcon, __u16 searchHandle, |
| 4385 | __u16 searchHandle, struct cifs_search_info *psrch_inf) | 4384 | __u16 search_flags, struct cifs_search_info *psrch_inf) |
| 4386 | { | 4385 | { |
| 4387 | TRANSACTION2_FNEXT_REQ *pSMB = NULL; | 4386 | TRANSACTION2_FNEXT_REQ *pSMB = NULL; |
| 4388 | TRANSACTION2_FNEXT_RSP *pSMBr = NULL; | 4387 | TRANSACTION2_FNEXT_RSP *pSMBr = NULL; |
| @@ -4425,8 +4424,7 @@ int CIFSFindNext(const int xid, struct cifs_tcon *tcon, | |||
| 4425 | cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO)); | 4424 | cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO)); |
| 4426 | pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); | 4425 | pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); |
| 4427 | pSMB->ResumeKey = psrch_inf->resume_key; | 4426 | pSMB->ResumeKey = psrch_inf->resume_key; |
| 4428 | pSMB->SearchFlags = | 4427 | pSMB->SearchFlags = cpu_to_le16(search_flags); |
| 4429 | cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME); | ||
| 4430 | 4428 | ||
| 4431 | name_len = psrch_inf->resume_name_len; | 4429 | name_len = psrch_inf->resume_name_len; |
| 4432 | params += name_len; | 4430 | params += name_len; |
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index e2bbc683e018..0a8224d1c4c5 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
| @@ -219,6 +219,7 @@ int get_symlink_reparse_path(char *full_path, struct cifs_sb_info *cifs_sb, | |||
| 219 | 219 | ||
| 220 | static int initiate_cifs_search(const int xid, struct file *file) | 220 | static int initiate_cifs_search(const int xid, struct file *file) |
| 221 | { | 221 | { |
| 222 | __u16 search_flags; | ||
| 222 | int rc = 0; | 223 | int rc = 0; |
| 223 | char *full_path = NULL; | 224 | char *full_path = NULL; |
| 224 | struct cifsFileInfo *cifsFile; | 225 | struct cifsFileInfo *cifsFile; |
| @@ -270,8 +271,12 @@ ffirst_retry: | |||
| 270 | cifsFile->srch_inf.info_level = SMB_FIND_FILE_DIRECTORY_INFO; | 271 | cifsFile->srch_inf.info_level = SMB_FIND_FILE_DIRECTORY_INFO; |
| 271 | } | 272 | } |
| 272 | 273 | ||
| 274 | search_flags = CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME; | ||
| 275 | if (backup_cred(cifs_sb)) | ||
| 276 | search_flags |= CIFS_SEARCH_BACKUP_SEARCH; | ||
| 277 | |||
| 273 | rc = CIFSFindFirst(xid, pTcon, full_path, cifs_sb->local_nls, | 278 | rc = CIFSFindFirst(xid, pTcon, full_path, cifs_sb->local_nls, |
| 274 | &cifsFile->netfid, &cifsFile->srch_inf, | 279 | &cifsFile->netfid, search_flags, &cifsFile->srch_inf, |
| 275 | cifs_sb->mnt_cifs_flags & | 280 | cifs_sb->mnt_cifs_flags & |
| 276 | CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb)); | 281 | CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb)); |
| 277 | if (rc == 0) | 282 | if (rc == 0) |
| @@ -502,11 +507,13 @@ static int cifs_save_resume_key(const char *current_entry, | |||
| 502 | static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon, | 507 | static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon, |
| 503 | struct file *file, char **ppCurrentEntry, int *num_to_ret) | 508 | struct file *file, char **ppCurrentEntry, int *num_to_ret) |
| 504 | { | 509 | { |
| 510 | __u16 search_flags; | ||
| 505 | int rc = 0; | 511 | int rc = 0; |
| 506 | int pos_in_buf = 0; | 512 | int pos_in_buf = 0; |
| 507 | loff_t first_entry_in_buffer; | 513 | loff_t first_entry_in_buffer; |
| 508 | loff_t index_to_find = file->f_pos; | 514 | loff_t index_to_find = file->f_pos; |
| 509 | struct cifsFileInfo *cifsFile = file->private_data; | 515 | struct cifsFileInfo *cifsFile = file->private_data; |
| 516 | struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | ||
| 510 | /* check if index in the buffer */ | 517 | /* check if index in the buffer */ |
| 511 | 518 | ||
| 512 | if ((cifsFile == NULL) || (ppCurrentEntry == NULL) || | 519 | if ((cifsFile == NULL) || (ppCurrentEntry == NULL) || |
| @@ -560,10 +567,14 @@ static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon, | |||
| 560 | cifsFile); | 567 | cifsFile); |
| 561 | } | 568 | } |
| 562 | 569 | ||
| 570 | search_flags = CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME; | ||
| 571 | if (backup_cred(cifs_sb)) | ||
| 572 | search_flags |= CIFS_SEARCH_BACKUP_SEARCH; | ||
| 573 | |||
| 563 | while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) && | 574 | while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) && |
| 564 | (rc == 0) && !cifsFile->srch_inf.endOfSearch) { | 575 | (rc == 0) && !cifsFile->srch_inf.endOfSearch) { |
| 565 | cFYI(1, "calling findnext2"); | 576 | cFYI(1, "calling findnext2"); |
| 566 | rc = CIFSFindNext(xid, pTcon, cifsFile->netfid, | 577 | rc = CIFSFindNext(xid, pTcon, cifsFile->netfid, search_flags, |
| 567 | &cifsFile->srch_inf); | 578 | &cifsFile->srch_inf); |
| 568 | /* FindFirst/Next set last_entry to NULL on malformed reply */ | 579 | /* FindFirst/Next set last_entry to NULL on malformed reply */ |
| 569 | if (cifsFile->srch_inf.last_entry) | 580 | if (cifsFile->srch_inf.last_entry) |
