aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/readdir.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2006-04-22 11:53:05 -0400
committerSteve French <sfrench@us.ibm.com>2006-04-22 11:53:05 -0400
commit60808233f374aebba26488d06a5f25443f6763c3 (patch)
treee2f85a165398f0c6c7432a7fa715d18efc3d8d5b /fs/cifs/readdir.c
parent45af7a0f2ebad1304cab956e15f0b37318226fcd (diff)
[CIFS] Readdir fixes to allow search to start at arbitrary position
in directory Also includes first part of fix to compensate for servers which forget to return . and .. as well as updates to changelog and cifs readme. Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/readdir.c')
-rw-r--r--fs/cifs/readdir.c43
1 files changed, 22 insertions, 21 deletions
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 7b8591acc5ad..41c022e3c132 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -590,6 +590,13 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
590 first_entry_in_buffer = 590 first_entry_in_buffer =
591 cifsFile->srch_inf.index_of_last_entry - 591 cifsFile->srch_inf.index_of_last_entry -
592 cifsFile->srch_inf.entries_in_buffer; 592 cifsFile->srch_inf.entries_in_buffer;
593
594 /* if first entry in buf is zero then is first buffer
595 in search response data which means it is likely . and ..
596 will be in this buffer, although some servers do not return
597 . and .. for the root of a drive and for those we need
598 to start two entries earlier */
599
593/* dump_cifs_file_struct(file, "In fce ");*/ 600/* dump_cifs_file_struct(file, "In fce ");*/
594 if(((index_to_find < cifsFile->srch_inf.index_of_last_entry) && 601 if(((index_to_find < cifsFile->srch_inf.index_of_last_entry) &&
595 is_dir_changed(file)) || 602 is_dir_changed(file)) ||
@@ -632,23 +639,14 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
632 char * end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + 639 char * end_of_smb = cifsFile->srch_inf.ntwrk_buf_start +
633 smbCalcSize((struct smb_hdr *) 640 smbCalcSize((struct smb_hdr *)
634 cifsFile->srch_inf.ntwrk_buf_start); 641 cifsFile->srch_inf.ntwrk_buf_start);
642
643 current_entry = cifsFile->srch_inf.srch_entries_start;
635 first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry 644 first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry
636 - cifsFile->srch_inf.entries_in_buffer; 645 - cifsFile->srch_inf.entries_in_buffer;
637 pos_in_buf = index_to_find - first_entry_in_buffer; 646 pos_in_buf = index_to_find - first_entry_in_buffer;
638 cFYI(1,("found entry - pos_in_buf %d",pos_in_buf)); 647 cFYI(1,("found entry - pos_in_buf %d",pos_in_buf));
639 current_entry = cifsFile->srch_inf.srch_entries_start;
640 for(i=0;(i<(pos_in_buf)) && (current_entry != NULL);i++) { 648 for(i=0;(i<(pos_in_buf)) && (current_entry != NULL);i++) {
641 /* go entry by entry figuring out which is first */ 649 /* go entry by entry figuring out which is first */
642 /* if( . or ..)
643 skip */
644 rc = cifs_entry_is_dot(current_entry,cifsFile);
645 if(rc == 1) /* is . or .. so skip */ {
646 cFYI(1,("Entry is .")); /* BB removeme BB */
647 /* continue; */
648 } else if (rc == 2 ) {
649 cFYI(1,("Entry is ..")); /* BB removeme BB */
650 /* continue; */
651 }
652 current_entry = nxt_dir_entry(current_entry,end_of_smb); 650 current_entry = nxt_dir_entry(current_entry,end_of_smb);
653 } 651 }
654 if((current_entry == NULL) && (i < pos_in_buf)) { 652 if((current_entry == NULL) && (i < pos_in_buf)) {
@@ -768,6 +766,11 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
768 if(file->f_dentry == NULL) 766 if(file->f_dentry == NULL)
769 return -ENOENT; 767 return -ENOENT;
770 768
769 rc = cifs_entry_is_dot(pfindEntry,cifsF);
770 /* skip . and .. since we added them first */
771 if(rc != 0)
772 return 0;
773
771 cifs_sb = CIFS_SB(file->f_dentry->d_sb); 774 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
772 775
773 qstring.name = scratch_buf; 776 qstring.name = scratch_buf;
@@ -896,22 +899,22 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
896 899
897 switch ((int) file->f_pos) { 900 switch ((int) file->f_pos) {
898 case 0: 901 case 0:
899 /*if (filldir(direntry, ".", 1, file->f_pos, 902 if (filldir(direntry, ".", 1, file->f_pos,
900 file->f_dentry->d_inode->i_ino, DT_DIR) < 0) { 903 file->f_dentry->d_inode->i_ino, DT_DIR) < 0) {
901 cERROR(1, ("Filldir for current dir failed ")); 904 cERROR(1, ("Filldir for current dir failed"));
902 rc = -ENOMEM; 905 rc = -ENOMEM;
903 break; 906 break;
904 } 907 }
905 file->f_pos++; */ 908 file->f_pos++;
906 case 1: 909 case 1:
907 /* if (filldir(direntry, "..", 2, file->f_pos, 910 if (filldir(direntry, "..", 2, file->f_pos,
908 file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) { 911 file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) {
909 cERROR(1, ("Filldir for parent dir failed ")); 912 cERROR(1, ("Filldir for parent dir failed "));
910 rc = -ENOMEM; 913 rc = -ENOMEM;
911 break; 914 break;
912 } 915 }
913 file->f_pos++; */ 916 file->f_pos++;
914 case 2: 917 default:
915 /* 1) If search is active, 918 /* 1) If search is active,
916 is in current search buffer? 919 is in current search buffer?
917 if it before then restart search 920 if it before then restart search
@@ -925,7 +928,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
925 return rc; 928 return rc;
926 } 929 }
927 } 930 }
928 default:
929 if(file->private_data == NULL) { 931 if(file->private_data == NULL) {
930 rc = -EINVAL; 932 rc = -EINVAL;
931 FreeXid(xid); 933 FreeXid(xid);
@@ -945,8 +947,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
945 kfree(cifsFile->search_resume_name); 947 kfree(cifsFile->search_resume_name);
946 cifsFile->search_resume_name = NULL; */ 948 cifsFile->search_resume_name = NULL; */
947 949
948 /* BB account for . and .. in f_pos as special case */
949
950 rc = find_cifs_entry(xid,pTcon, file, 950 rc = find_cifs_entry(xid,pTcon, file,
951 &current_entry,&num_to_fill); 951 &current_entry,&num_to_fill);
952 if(rc) { 952 if(rc) {
@@ -975,7 +975,8 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
975 num_to_fill, i)); 975 num_to_fill, i));
976 break; 976 break;
977 } 977 }
978 978 /* if buggy server returns . and .. late do
979 we want to check for that here? */
979 rc = cifs_filldir(current_entry, file, 980 rc = cifs_filldir(current_entry, file,
980 filldir, direntry,tmp_buf); 981 filldir, direntry,tmp_buf);
981 file->f_pos++; 982 file->f_pos++;