aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorPavel Shilovsky <pshilovsky@samba.org>2012-09-18 19:20:32 -0400
committerSteve French <smfrench@gmail.com>2012-09-24 22:46:29 -0400
commit92fc65a74a2be1388d774f7dbf82c9adea1745cf (patch)
tree262ccb0fcb9edbf09cd2480facaa9135ec511088 /fs
parent1feeaac753e0a9b3864740556b7840643642abdb (diff)
CIFS: Move readdir code to ops struct
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org> Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/cifsglob.h15
-rw-r--r--fs/cifs/cifsproto.h2
-rw-r--r--fs/cifs/file.c60
-rw-r--r--fs/cifs/netmisc.c3
-rw-r--r--fs/cifs/readdir.c165
-rw-r--r--fs/cifs/smb1ops.c31
6 files changed, 173 insertions, 103 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index dff35830601f..9adf211ca95a 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -177,6 +177,7 @@ struct cifs_fid;
177struct cifs_readdata; 177struct cifs_readdata;
178struct cifs_writedata; 178struct cifs_writedata;
179struct cifs_io_parms; 179struct cifs_io_parms;
180struct cifs_search_info;
180 181
181struct smb_version_operations { 182struct smb_version_operations {
182 int (*send_cancel)(struct TCP_Server_Info *, void *, 183 int (*send_cancel)(struct TCP_Server_Info *, void *,
@@ -313,6 +314,20 @@ struct smb_version_operations {
313 int (*sync_write)(const unsigned int, struct cifsFileInfo *, 314 int (*sync_write)(const unsigned int, struct cifsFileInfo *,
314 struct cifs_io_parms *, unsigned int *, struct kvec *, 315 struct cifs_io_parms *, unsigned int *, struct kvec *,
315 unsigned long); 316 unsigned long);
317 /* open dir, start readdir */
318 int (*query_dir_first)(const unsigned int, struct cifs_tcon *,
319 const char *, struct cifs_sb_info *,
320 struct cifs_fid *, __u16,
321 struct cifs_search_info *);
322 /* continue readdir */
323 int (*query_dir_next)(const unsigned int, struct cifs_tcon *,
324 struct cifs_fid *,
325 __u16, struct cifs_search_info *srch_inf);
326 /* close dir */
327 int (*close_dir)(const unsigned int, struct cifs_tcon *,
328 struct cifs_fid *);
329 /* calculate a size of SMB message */
330 unsigned int (*calc_smb_size)(void *);
316}; 331};
317 332
318struct smb_version_values { 333struct smb_version_values {
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 3d99fe9afccc..c7ad9a8cf82a 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -100,7 +100,7 @@ extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
100 unsigned int bytes_written); 100 unsigned int bytes_written);
101extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool); 101extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool);
102extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool); 102extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
103extern unsigned int smbCalcSize(struct smb_hdr *ptr); 103extern unsigned int smbCalcSize(void *buf);
104extern int decode_negTokenInit(unsigned char *security_blob, int length, 104extern int decode_negTokenInit(unsigned char *security_blob, int length,
105 struct TCP_Server_Info *server); 105 struct TCP_Server_Info *server);
106extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len); 106extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 39fff77e38d4..fb6b4413255b 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -618,39 +618,47 @@ int cifs_closedir(struct inode *inode, struct file *file)
618 int rc = 0; 618 int rc = 0;
619 unsigned int xid; 619 unsigned int xid;
620 struct cifsFileInfo *cfile = file->private_data; 620 struct cifsFileInfo *cfile = file->private_data;
621 char *tmp; 621 struct cifs_tcon *tcon;
622 struct TCP_Server_Info *server;
623 char *buf;
622 624
623 cFYI(1, "Closedir inode = 0x%p", inode); 625 cFYI(1, "Closedir inode = 0x%p", inode);
624 626
627 if (cfile == NULL)
628 return rc;
629
625 xid = get_xid(); 630 xid = get_xid();
631 tcon = tlink_tcon(cfile->tlink);
632 server = tcon->ses->server;
626 633
627 if (cfile) { 634 cFYI(1, "Freeing private data in close dir");
628 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 635 spin_lock(&cifs_file_list_lock);
636 if (!cfile->srch_inf.endOfSearch && !cfile->invalidHandle) {
637 cfile->invalidHandle = true;
638 spin_unlock(&cifs_file_list_lock);
639 if (server->ops->close_dir)
640 rc = server->ops->close_dir(xid, tcon, &cfile->fid);
641 else
642 rc = -ENOSYS;
643 cFYI(1, "Closing uncompleted readdir with rc %d", rc);
644 /* not much we can do if it fails anyway, ignore rc */
645 rc = 0;
646 } else
647 spin_unlock(&cifs_file_list_lock);
629 648
630 cFYI(1, "Freeing private data in close dir"); 649 buf = cfile->srch_inf.ntwrk_buf_start;
631 spin_lock(&cifs_file_list_lock); 650 if (buf) {
632 if (!cfile->srch_inf.endOfSearch && !cfile->invalidHandle) { 651 cFYI(1, "closedir free smb buf in srch struct");
633 cfile->invalidHandle = true; 652 cfile->srch_inf.ntwrk_buf_start = NULL;
634 spin_unlock(&cifs_file_list_lock); 653 if (cfile->srch_inf.smallBuf)
635 rc = CIFSFindClose(xid, tcon, cfile->fid.netfid); 654 cifs_small_buf_release(buf);
636 cFYI(1, "Closing uncompleted readdir with rc %d", rc); 655 else
637 /* not much we can do if it fails anyway, ignore rc */ 656 cifs_buf_release(buf);
638 rc = 0;
639 } else
640 spin_unlock(&cifs_file_list_lock);
641 tmp = cfile->srch_inf.ntwrk_buf_start;
642 if (tmp) {
643 cFYI(1, "closedir free smb buf in srch struct");
644 cfile->srch_inf.ntwrk_buf_start = NULL;
645 if (cfile->srch_inf.smallBuf)
646 cifs_small_buf_release(tmp);
647 else
648 cifs_buf_release(tmp);
649 }
650 cifs_put_tlink(cfile->tlink);
651 kfree(file->private_data);
652 file->private_data = NULL;
653 } 657 }
658
659 cifs_put_tlink(cfile->tlink);
660 kfree(file->private_data);
661 file->private_data = NULL;
654 /* BB can we lock the filestruct while this is going on? */ 662 /* BB can we lock the filestruct while this is going on? */
655 free_xid(xid); 663 free_xid(xid);
656 return rc; 664 return rc;
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index 581c225f7f50..e7bab3be5cf9 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -913,8 +913,9 @@ map_smb_to_linux_error(char *buf, bool logErr)
913 * portion, the number of word parameters and the data portion of the message 913 * portion, the number of word parameters and the data portion of the message
914 */ 914 */
915unsigned int 915unsigned int
916smbCalcSize(struct smb_hdr *ptr) 916smbCalcSize(void *buf)
917{ 917{
918 struct smb_hdr *ptr = (struct smb_hdr *)buf;
918 return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) + 919 return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) +
919 2 /* size of the bcc field */ + get_bcc(ptr)); 920 2 /* size of the bcc field */ + get_bcc(ptr));
920} 921}
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 9e76e3b3289b..b0f4a428398d 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -220,7 +220,8 @@ int get_symlink_reparse_path(char *full_path, struct cifs_sb_info *cifs_sb,
220} 220}
221 */ 221 */
222 222
223static int initiate_cifs_search(const unsigned int xid, struct file *file) 223static int
224initiate_cifs_search(const unsigned int xid, struct file *file)
224{ 225{
225 __u16 search_flags; 226 __u16 search_flags;
226 int rc = 0; 227 int rc = 0;
@@ -229,6 +230,7 @@ static int initiate_cifs_search(const unsigned int xid, struct file *file)
229 struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 230 struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
230 struct tcon_link *tlink = NULL; 231 struct tcon_link *tlink = NULL;
231 struct cifs_tcon *tcon; 232 struct cifs_tcon *tcon;
233 struct TCP_Server_Info *server;
232 234
233 if (file->private_data == NULL) { 235 if (file->private_data == NULL) {
234 tlink = cifs_sb_tlink(cifs_sb); 236 tlink = cifs_sb_tlink(cifs_sb);
@@ -248,6 +250,13 @@ static int initiate_cifs_search(const unsigned int xid, struct file *file)
248 tcon = tlink_tcon(cifsFile->tlink); 250 tcon = tlink_tcon(cifsFile->tlink);
249 } 251 }
250 252
253 server = tcon->ses->server;
254
255 if (!server->ops->query_dir_first) {
256 rc = -ENOSYS;
257 goto error_exit;
258 }
259
251 cifsFile->invalidHandle = true; 260 cifsFile->invalidHandle = true;
252 cifsFile->srch_inf.endOfSearch = false; 261 cifsFile->srch_inf.endOfSearch = false;
253 262
@@ -278,10 +287,10 @@ ffirst_retry:
278 if (backup_cred(cifs_sb)) 287 if (backup_cred(cifs_sb))
279 search_flags |= CIFS_SEARCH_BACKUP_SEARCH; 288 search_flags |= CIFS_SEARCH_BACKUP_SEARCH;
280 289
281 rc = CIFSFindFirst(xid, tcon, full_path, cifs_sb->local_nls, 290 rc = server->ops->query_dir_first(xid, tcon, full_path, cifs_sb,
282 &cifsFile->fid.netfid, search_flags, &cifsFile->srch_inf, 291 &cifsFile->fid, search_flags,
283 cifs_sb->mnt_cifs_flags & 292 &cifsFile->srch_inf);
284 CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb)); 293
285 if (rc == 0) 294 if (rc == 0)
286 cifsFile->invalidHandle = false; 295 cifsFile->invalidHandle = false;
287 /* BB add following call to handle readdir on new NTFS symlink errors 296 /* BB add following call to handle readdir on new NTFS symlink errors
@@ -501,62 +510,67 @@ static int cifs_save_resume_key(const char *current_entry,
501 return rc; 510 return rc;
502} 511}
503 512
504/* find the corresponding entry in the search */ 513/*
505/* Note that the SMB server returns search entries for . and .. which 514 * Find the corresponding entry in the search. Note that the SMB server returns
506 complicates logic here if we choose to parse for them and we do not 515 * search entries for . and .. which complicates logic here if we choose to
507 assume that they are located in the findfirst return buffer.*/ 516 * parse for them and we do not assume that they are located in the findfirst
508/* We start counting in the buffer with entry 2 and increment for every 517 * return buffer. We start counting in the buffer with entry 2 and increment for
509 entry (do not increment for . or .. entry) */ 518 * every entry (do not increment for . or .. entry).
510static int find_cifs_entry(const unsigned int xid, struct cifs_tcon *pTcon, 519 */
511 struct file *file, char **ppCurrentEntry, int *num_to_ret) 520static int
521find_cifs_entry(const unsigned int xid, struct cifs_tcon *tcon,
522 struct file *file, char **current_entry, int *num_to_ret)
512{ 523{
513 __u16 search_flags; 524 __u16 search_flags;
514 int rc = 0; 525 int rc = 0;
515 int pos_in_buf = 0; 526 int pos_in_buf = 0;
516 loff_t first_entry_in_buffer; 527 loff_t first_entry_in_buffer;
517 loff_t index_to_find = file->f_pos; 528 loff_t index_to_find = file->f_pos;
518 struct cifsFileInfo *cifsFile = file->private_data; 529 struct cifsFileInfo *cfile = file->private_data;
519 struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 530 struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
531 struct TCP_Server_Info *server = tcon->ses->server;
520 /* check if index in the buffer */ 532 /* check if index in the buffer */
521 533
522 if ((cifsFile == NULL) || (ppCurrentEntry == NULL) || 534 if (!server->ops->query_dir_first || !server->ops->query_dir_next)
523 (num_to_ret == NULL)) 535 return -ENOSYS;
536
537 if ((cfile == NULL) || (current_entry == NULL) || (num_to_ret == NULL))
524 return -ENOENT; 538 return -ENOENT;
525 539
526 *ppCurrentEntry = NULL; 540 *current_entry = NULL;
527 first_entry_in_buffer = 541 first_entry_in_buffer = cfile->srch_inf.index_of_last_entry -
528 cifsFile->srch_inf.index_of_last_entry - 542 cfile->srch_inf.entries_in_buffer;
529 cifsFile->srch_inf.entries_in_buffer;
530 543
531 /* if first entry in buf is zero then is first buffer 544 /*
532 in search response data which means it is likely . and .. 545 * If first entry in buf is zero then is first buffer
533 will be in this buffer, although some servers do not return 546 * in search response data which means it is likely . and ..
534 . and .. for the root of a drive and for those we need 547 * will be in this buffer, although some servers do not return
535 to start two entries earlier */ 548 * . and .. for the root of a drive and for those we need
549 * to start two entries earlier.
550 */
536 551
537 dump_cifs_file_struct(file, "In fce "); 552 dump_cifs_file_struct(file, "In fce ");
538 if (((index_to_find < cifsFile->srch_inf.index_of_last_entry) && 553 if (((index_to_find < cfile->srch_inf.index_of_last_entry) &&
539 is_dir_changed(file)) || 554 is_dir_changed(file)) || (index_to_find < first_entry_in_buffer)) {
540 (index_to_find < first_entry_in_buffer)) {
541 /* close and restart search */ 555 /* close and restart search */
542 cFYI(1, "search backing up - close and restart search"); 556 cFYI(1, "search backing up - close and restart search");
543 spin_lock(&cifs_file_list_lock); 557 spin_lock(&cifs_file_list_lock);
544 if (!cifsFile->srch_inf.endOfSearch && 558 if (!cfile->srch_inf.endOfSearch && !cfile->invalidHandle) {
545 !cifsFile->invalidHandle) { 559 cfile->invalidHandle = true;
546 cifsFile->invalidHandle = true;
547 spin_unlock(&cifs_file_list_lock); 560 spin_unlock(&cifs_file_list_lock);
548 CIFSFindClose(xid, pTcon, cifsFile->fid.netfid); 561 if (server->ops->close)
562 server->ops->close(xid, tcon, &cfile->fid);
549 } else 563 } else
550 spin_unlock(&cifs_file_list_lock); 564 spin_unlock(&cifs_file_list_lock);
551 if (cifsFile->srch_inf.ntwrk_buf_start) { 565 if (cfile->srch_inf.ntwrk_buf_start) {
552 cFYI(1, "freeing SMB ff cache buf on search rewind"); 566 cFYI(1, "freeing SMB ff cache buf on search rewind");
553 if (cifsFile->srch_inf.smallBuf) 567 if (cfile->srch_inf.smallBuf)
554 cifs_small_buf_release(cifsFile->srch_inf. 568 cifs_small_buf_release(cfile->srch_inf.
555 ntwrk_buf_start); 569 ntwrk_buf_start);
556 else 570 else
557 cifs_buf_release(cifsFile->srch_inf. 571 cifs_buf_release(cfile->srch_inf.
558 ntwrk_buf_start); 572 ntwrk_buf_start);
559 cifsFile->srch_inf.ntwrk_buf_start = NULL; 573 cfile->srch_inf.ntwrk_buf_start = NULL;
560 } 574 }
561 rc = initiate_cifs_search(xid, file); 575 rc = initiate_cifs_search(xid, file);
562 if (rc) { 576 if (rc) {
@@ -565,65 +579,64 @@ static int find_cifs_entry(const unsigned int xid, struct cifs_tcon *pTcon,
565 return rc; 579 return rc;
566 } 580 }
567 /* FindFirst/Next set last_entry to NULL on malformed reply */ 581 /* FindFirst/Next set last_entry to NULL on malformed reply */
568 if (cifsFile->srch_inf.last_entry) 582 if (cfile->srch_inf.last_entry)
569 cifs_save_resume_key(cifsFile->srch_inf.last_entry, 583 cifs_save_resume_key(cfile->srch_inf.last_entry, cfile);
570 cifsFile);
571 } 584 }
572 585
573 search_flags = CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME; 586 search_flags = CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME;
574 if (backup_cred(cifs_sb)) 587 if (backup_cred(cifs_sb))
575 search_flags |= CIFS_SEARCH_BACKUP_SEARCH; 588 search_flags |= CIFS_SEARCH_BACKUP_SEARCH;
576 589
577 while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) && 590 while ((index_to_find >= cfile->srch_inf.index_of_last_entry) &&
578 (rc == 0) && !cifsFile->srch_inf.endOfSearch) { 591 (rc == 0) && !cfile->srch_inf.endOfSearch) {
579 cFYI(1, "calling findnext2"); 592 cFYI(1, "calling findnext2");
580 rc = CIFSFindNext(xid, pTcon, cifsFile->fid.netfid, 593 rc = server->ops->query_dir_next(xid, tcon, &cfile->fid,
581 search_flags, &cifsFile->srch_inf); 594 search_flags,
595 &cfile->srch_inf);
582 /* FindFirst/Next set last_entry to NULL on malformed reply */ 596 /* FindFirst/Next set last_entry to NULL on malformed reply */
583 if (cifsFile->srch_inf.last_entry) 597 if (cfile->srch_inf.last_entry)
584 cifs_save_resume_key(cifsFile->srch_inf.last_entry, 598 cifs_save_resume_key(cfile->srch_inf.last_entry, cfile);
585 cifsFile);
586 if (rc) 599 if (rc)
587 return -ENOENT; 600 return -ENOENT;
588 } 601 }
589 if (index_to_find < cifsFile->srch_inf.index_of_last_entry) { 602 if (index_to_find < cfile->srch_inf.index_of_last_entry) {
590 /* we found the buffer that contains the entry */ 603 /* we found the buffer that contains the entry */
591 /* scan and find it */ 604 /* scan and find it */
592 int i; 605 int i;
593 char *current_entry; 606 char *cur_ent;
594 char *end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + 607 char *end_of_smb = cfile->srch_inf.ntwrk_buf_start +
595 smbCalcSize((struct smb_hdr *) 608 server->ops->calc_smb_size(
596 cifsFile->srch_inf.ntwrk_buf_start); 609 cfile->srch_inf.ntwrk_buf_start);
597 610
598 current_entry = cifsFile->srch_inf.srch_entries_start; 611 cur_ent = cfile->srch_inf.srch_entries_start;
599 first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry 612 first_entry_in_buffer = cfile->srch_inf.index_of_last_entry
600 - cifsFile->srch_inf.entries_in_buffer; 613 - cfile->srch_inf.entries_in_buffer;
601 pos_in_buf = index_to_find - first_entry_in_buffer; 614 pos_in_buf = index_to_find - first_entry_in_buffer;
602 cFYI(1, "found entry - pos_in_buf %d", pos_in_buf); 615 cFYI(1, "found entry - pos_in_buf %d", pos_in_buf);
603 616
604 for (i = 0; (i < (pos_in_buf)) && (current_entry != NULL); i++) { 617 for (i = 0; (i < (pos_in_buf)) && (cur_ent != NULL); i++) {
605 /* go entry by entry figuring out which is first */ 618 /* go entry by entry figuring out which is first */
606 current_entry = nxt_dir_entry(current_entry, end_of_smb, 619 cur_ent = nxt_dir_entry(cur_ent, end_of_smb,
607 cifsFile->srch_inf.info_level); 620 cfile->srch_inf.info_level);
608 } 621 }
609 if ((current_entry == NULL) && (i < pos_in_buf)) { 622 if ((cur_ent == NULL) && (i < pos_in_buf)) {
610 /* BB fixme - check if we should flag this error */ 623 /* BB fixme - check if we should flag this error */
611 cERROR(1, "reached end of buf searching for pos in buf" 624 cERROR(1, "reached end of buf searching for pos in buf"
612 " %d index to find %lld rc %d", 625 " %d index to find %lld rc %d", pos_in_buf,
613 pos_in_buf, index_to_find, rc); 626 index_to_find, rc);
614 } 627 }
615 rc = 0; 628 rc = 0;
616 *ppCurrentEntry = current_entry; 629 *current_entry = cur_ent;
617 } else { 630 } else {
618 cFYI(1, "index not in buffer - could not findnext into it"); 631 cFYI(1, "index not in buffer - could not findnext into it");
619 return 0; 632 return 0;
620 } 633 }
621 634
622 if (pos_in_buf >= cifsFile->srch_inf.entries_in_buffer) { 635 if (pos_in_buf >= cfile->srch_inf.entries_in_buffer) {
623 cFYI(1, "can not return entries pos_in_buf beyond last"); 636 cFYI(1, "can not return entries pos_in_buf beyond last");
624 *num_to_ret = 0; 637 *num_to_ret = 0;
625 } else 638 } else
626 *num_to_ret = cifsFile->srch_inf.entries_in_buffer - pos_in_buf; 639 *num_to_ret = cfile->srch_inf.entries_in_buffer - pos_in_buf;
627 640
628 return rc; 641 return rc;
629} 642}
@@ -723,7 +736,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
723 int rc = 0; 736 int rc = 0;
724 unsigned int xid; 737 unsigned int xid;
725 int i; 738 int i;
726 struct cifs_tcon *pTcon; 739 struct cifs_tcon *tcon;
727 struct cifsFileInfo *cifsFile = NULL; 740 struct cifsFileInfo *cifsFile = NULL;
728 char *current_entry; 741 char *current_entry;
729 int num_to_fill = 0; 742 int num_to_fill = 0;
@@ -781,12 +794,12 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
781 } 794 }
782 } /* else { 795 } /* else {
783 cifsFile->invalidHandle = true; 796 cifsFile->invalidHandle = true;
784 CIFSFindClose(xid, pTcon, cifsFile->fid.netfid); 797 tcon->ses->server->close(xid, tcon, &cifsFile->fid);
785 } */ 798 } */
786 799
787 pTcon = tlink_tcon(cifsFile->tlink); 800 tcon = tlink_tcon(cifsFile->tlink);
788 rc = find_cifs_entry(xid, pTcon, file, 801 rc = find_cifs_entry(xid, tcon, file, &current_entry,
789 &current_entry, &num_to_fill); 802 &num_to_fill);
790 if (rc) { 803 if (rc) {
791 cFYI(1, "fce error %d", rc); 804 cFYI(1, "fce error %d", rc);
792 goto rddir2_exit; 805 goto rddir2_exit;
@@ -798,7 +811,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
798 } 811 }
799 cFYI(1, "loop through %d times filling dir for net buf %p", 812 cFYI(1, "loop through %d times filling dir for net buf %p",
800 num_to_fill, cifsFile->srch_inf.ntwrk_buf_start); 813 num_to_fill, cifsFile->srch_inf.ntwrk_buf_start);
801 max_len = smbCalcSize((struct smb_hdr *) 814 max_len = tcon->ses->server->ops->calc_smb_size(
802 cifsFile->srch_inf.ntwrk_buf_start); 815 cifsFile->srch_inf.ntwrk_buf_start);
803 end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len; 816 end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len;
804 817
@@ -815,10 +828,12 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
815 num_to_fill, i); 828 num_to_fill, i);
816 break; 829 break;
817 } 830 }
818 /* if buggy server returns . and .. late do 831 /*
819 we want to check for that here? */ 832 * if buggy server returns . and .. late do we want to
820 rc = cifs_filldir(current_entry, file, 833 * check for that here?
821 filldir, direntry, tmp_buf, max_len); 834 */
835 rc = cifs_filldir(current_entry, file, filldir,
836 direntry, tmp_buf, max_len);
822 if (rc == -EOVERFLOW) { 837 if (rc == -EOVERFLOW) {
823 rc = 0; 838 rc = 0;
824 break; 839 break;
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
index ed311968437a..068d609bd02a 100644
--- a/fs/cifs/smb1ops.c
+++ b/fs/cifs/smb1ops.c
@@ -836,6 +836,33 @@ out:
836 return rc; 836 return rc;
837} 837}
838 838
839static int
840cifs_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
841 const char *path, struct cifs_sb_info *cifs_sb,
842 struct cifs_fid *fid, __u16 search_flags,
843 struct cifs_search_info *srch_inf)
844{
845 return CIFSFindFirst(xid, tcon, path, cifs_sb->local_nls,
846 &fid->netfid, search_flags, srch_inf,
847 cifs_sb->mnt_cifs_flags &
848 CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb));
849}
850
851static int
852cifs_query_dir_next(const unsigned int xid, struct cifs_tcon *tcon,
853 struct cifs_fid *fid, __u16 search_flags,
854 struct cifs_search_info *srch_inf)
855{
856 return CIFSFindNext(xid, tcon, fid->netfid, search_flags, srch_inf);
857}
858
859static int
860cifs_close_dir(const unsigned int xid, struct cifs_tcon *tcon,
861 struct cifs_fid *fid)
862{
863 return CIFSFindClose(xid, tcon, fid->netfid);
864}
865
839struct smb_version_operations smb1_operations = { 866struct smb_version_operations smb1_operations = {
840 .send_cancel = send_nt_cancel, 867 .send_cancel = send_nt_cancel,
841 .compare_fids = cifs_compare_fids, 868 .compare_fids = cifs_compare_fids,
@@ -891,6 +918,10 @@ struct smb_version_operations smb1_operations = {
891 .async_writev = cifs_async_writev, 918 .async_writev = cifs_async_writev,
892 .sync_read = cifs_sync_read, 919 .sync_read = cifs_sync_read,
893 .sync_write = cifs_sync_write, 920 .sync_write = cifs_sync_write,
921 .query_dir_first = cifs_query_dir_first,
922 .query_dir_next = cifs_query_dir_next,
923 .close_dir = cifs_close_dir,
924 .calc_smb_size = smbCalcSize,
894}; 925};
895 926
896struct smb_version_values smb1_values = { 927struct smb_version_values smb1_values = {