aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/readdir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/readdir.c')
-rw-r--r--fs/cifs/readdir.c179
1 files changed, 91 insertions, 88 deletions
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 52e657ec1f18..19c8be4696f9 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -110,7 +110,7 @@ static int construct_dentry(struct qstr *qstring, struct file *file,
110 return rc; 110 return rc;
111} 111}
112 112
113static void AdjustForTZ(struct cifsTconInfo * tcon, struct inode * inode) 113static void AdjustForTZ(struct cifsTconInfo *tcon, struct inode *inode)
114{ 114{
115 if ((tcon) && (tcon->ses) && (tcon->ses->server)) { 115 if ((tcon) && (tcon->ses) && (tcon->ses->server)) {
116 inode->i_ctime.tv_sec += tcon->ses->server->timeAdj; 116 inode->i_ctime.tv_sec += tcon->ses->server->timeAdj;
@@ -122,7 +122,7 @@ static void AdjustForTZ(struct cifsTconInfo * tcon, struct inode * inode)
122 122
123 123
124static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, 124static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
125 char * buf, int *pobject_type, int isNewInode) 125 char *buf, int *pobject_type, int isNewInode)
126{ 126{
127 loff_t local_size; 127 loff_t local_size;
128 struct timespec local_mtime; 128 struct timespec local_mtime;
@@ -151,7 +151,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
151 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); 151 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
152 } else { /* legacy, OS2 and DOS style */ 152 } else { /* legacy, OS2 and DOS style */
153/* struct timespec ts;*/ 153/* struct timespec ts;*/
154 FIND_FILE_STANDARD_INFO * pfindData = 154 FIND_FILE_STANDARD_INFO * pfindData =
155 (FIND_FILE_STANDARD_INFO *)buf; 155 (FIND_FILE_STANDARD_INFO *)buf;
156 156
157 tmp_inode->i_mtime = cnvrtDosUnixTm( 157 tmp_inode->i_mtime = cnvrtDosUnixTm(
@@ -176,7 +176,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
176 176
177 /* treat dos attribute of read-only as read-only mode bit e.g. 555? */ 177 /* treat dos attribute of read-only as read-only mode bit e.g. 555? */
178 /* 2767 perms - indicate mandatory locking */ 178 /* 2767 perms - indicate mandatory locking */
179 /* BB fill in uid and gid here? with help from winbind? 179 /* BB fill in uid and gid here? with help from winbind?
180 or retrieve from NTFS stream extended attribute */ 180 or retrieve from NTFS stream extended attribute */
181 if (atomic_read(&cifsInfo->inUse) == 0) { 181 if (atomic_read(&cifsInfo->inUse) == 0) {
182 tmp_inode->i_uid = cifs_sb->mnt_uid; 182 tmp_inode->i_uid = cifs_sb->mnt_uid;
@@ -197,7 +197,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
197 tmp_inode->i_mode = cifs_sb->mnt_dir_mode; 197 tmp_inode->i_mode = cifs_sb->mnt_dir_mode;
198 } 198 }
199 tmp_inode->i_mode |= S_IFDIR; 199 tmp_inode->i_mode |= S_IFDIR;
200 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && 200 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
201 (attr & ATTR_SYSTEM)) { 201 (attr & ATTR_SYSTEM)) {
202 if (end_of_file == 0) { 202 if (end_of_file == 0) {
203 *pobject_type = DT_FIFO; 203 *pobject_type = DT_FIFO;
@@ -207,13 +207,13 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
207 inode as needing revalidate and get the real type 207 inode as needing revalidate and get the real type
208 (blk vs chr vs. symlink) later ie in lookup */ 208 (blk vs chr vs. symlink) later ie in lookup */
209 *pobject_type = DT_REG; 209 *pobject_type = DT_REG;
210 tmp_inode->i_mode |= S_IFREG; 210 tmp_inode->i_mode |= S_IFREG;
211 cifsInfo->time = 0; 211 cifsInfo->time = 0;
212 } 212 }
213/* we no longer mark these because we could not follow them */ 213/* we no longer mark these because we could not follow them */
214/* } else if (attr & ATTR_REPARSE) { 214/* } else if (attr & ATTR_REPARSE) {
215 *pobject_type = DT_LNK; 215 *pobject_type = DT_LNK;
216 tmp_inode->i_mode |= S_IFLNK; */ 216 tmp_inode->i_mode |= S_IFLNK; */
217 } else { 217 } else {
218 *pobject_type = DT_REG; 218 *pobject_type = DT_REG;
219 tmp_inode->i_mode |= S_IFREG; 219 tmp_inode->i_mode |= S_IFREG;
@@ -221,7 +221,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
221 tmp_inode->i_mode &= ~(S_IWUGO); 221 tmp_inode->i_mode &= ~(S_IWUGO);
222 else if ((tmp_inode->i_mode & S_IWUGO) == 0) 222 else if ((tmp_inode->i_mode & S_IWUGO) == 0)
223 /* the ATTR_READONLY flag may have been changed on */ 223 /* the ATTR_READONLY flag may have been changed on */
224 /* server -- set any w bits allowed by mnt_file_mode */ 224 /* server -- set any w bits allowed by mnt_file_mode */
225 tmp_inode->i_mode |= (S_IWUGO & cifs_sb->mnt_file_mode); 225 tmp_inode->i_mode |= (S_IWUGO & cifs_sb->mnt_file_mode);
226 } /* could add code here - to validate if device or weird share type? */ 226 } /* could add code here - to validate if device or weird share type? */
227 227
@@ -232,7 +232,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
232 232
233 spin_lock(&tmp_inode->i_lock); 233 spin_lock(&tmp_inode->i_lock);
234 if (is_size_safe_to_change(cifsInfo, end_of_file)) { 234 if (is_size_safe_to_change(cifsInfo, end_of_file)) {
235 /* can not safely change the file size here if the 235 /* can not safely change the file size here if the
236 client is writing to it due to potential races */ 236 client is writing to it due to potential races */
237 i_size_write(tmp_inode, end_of_file); 237 i_size_write(tmp_inode, end_of_file);
238 238
@@ -323,8 +323,8 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
323 323
324 tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions); 324 tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions);
325 /* since we set the inode type below we need to mask off type 325 /* since we set the inode type below we need to mask off type
326 to avoid strange results if bits above were corrupt */ 326 to avoid strange results if bits above were corrupt */
327 tmp_inode->i_mode &= ~S_IFMT; 327 tmp_inode->i_mode &= ~S_IFMT;
328 if (type == UNIX_FILE) { 328 if (type == UNIX_FILE) {
329 *pobject_type = DT_REG; 329 *pobject_type = DT_REG;
330 tmp_inode->i_mode |= S_IFREG; 330 tmp_inode->i_mode |= S_IFREG;
@@ -354,7 +354,7 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
354 /* safest to just call it a file */ 354 /* safest to just call it a file */
355 *pobject_type = DT_REG; 355 *pobject_type = DT_REG;
356 tmp_inode->i_mode |= S_IFREG; 356 tmp_inode->i_mode |= S_IFREG;
357 cFYI(1,("unknown inode type %d",type)); 357 cFYI(1, ("unknown inode type %d", type));
358 } 358 }
359 359
360 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) 360 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
@@ -369,7 +369,7 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
369 369
370 spin_lock(&tmp_inode->i_lock); 370 spin_lock(&tmp_inode->i_lock);
371 if (is_size_safe_to_change(cifsInfo, end_of_file)) { 371 if (is_size_safe_to_change(cifsInfo, end_of_file)) {
372 /* can not safely change the file size here if the 372 /* can not safely change the file size here if the
373 client is writing to it due to potential races */ 373 client is writing to it due to potential races */
374 i_size_write(tmp_inode, end_of_file); 374 i_size_write(tmp_inode, end_of_file);
375 375
@@ -394,15 +394,16 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
394 tmp_inode->i_fop = &cifs_file_ops; 394 tmp_inode->i_fop = &cifs_file_ops;
395 395
396 if ((cifs_sb->tcon) && (cifs_sb->tcon->ses) && 396 if ((cifs_sb->tcon) && (cifs_sb->tcon->ses) &&
397 (cifs_sb->tcon->ses->server->maxBuf < 397 (cifs_sb->tcon->ses->server->maxBuf <
398 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)) 398 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE))
399 tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf; 399 tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
400 else 400 else
401 tmp_inode->i_data.a_ops = &cifs_addr_ops; 401 tmp_inode->i_data.a_ops = &cifs_addr_ops;
402 402
403 if (isNewInode) 403 if (isNewInode)
404 return; /* No sense invalidating pages for new inode since we 404 return; /* No sense invalidating pages for new inode
405 have not started caching readahead file data yet */ 405 since we have not started caching readahead
406 file data for it yet */
406 407
407 if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) && 408 if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) &&
408 (local_size == tmp_inode->i_size)) { 409 (local_size == tmp_inode->i_size)) {
@@ -421,7 +422,7 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
421 tmp_inode->i_op = &cifs_symlink_inode_ops; 422 tmp_inode->i_op = &cifs_symlink_inode_ops;
422/* tmp_inode->i_fop = *//* do not need to set to anything */ 423/* tmp_inode->i_fop = *//* do not need to set to anything */
423 } else { 424 } else {
424 cFYI(1, ("Special inode")); 425 cFYI(1, ("Special inode"));
425 init_special_inode(tmp_inode, tmp_inode->i_mode, 426 init_special_inode(tmp_inode, tmp_inode->i_mode,
426 tmp_inode->i_rdev); 427 tmp_inode->i_rdev);
427 } 428 }
@@ -500,7 +501,7 @@ static int cifs_unicode_bytelen(char *str)
500 if (ustr[len] == 0) 501 if (ustr[len] == 0)
501 return len << 1; 502 return len << 1;
502 } 503 }
503 cFYI(1,("Unicode string longer than PATH_MAX found")); 504 cFYI(1, ("Unicode string longer than PATH_MAX found"));
504 return len << 1; 505 return len << 1;
505} 506}
506 507
@@ -517,7 +518,7 @@ static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level)
517 pfData->FileNameLength; 518 pfData->FileNameLength;
518 } else 519 } else
519 new_entry = old_entry + le32_to_cpu(pDirInfo->NextEntryOffset); 520 new_entry = old_entry + le32_to_cpu(pDirInfo->NextEntryOffset);
520 cFYI(1,("new entry %p old entry %p",new_entry,old_entry)); 521 cFYI(1, ("new entry %p old entry %p", new_entry, old_entry));
521 /* validate that new_entry is not past end of SMB */ 522 /* validate that new_entry is not past end of SMB */
522 if (new_entry >= end_of_smb) { 523 if (new_entry >= end_of_smb) {
523 cERROR(1, 524 cERROR(1,
@@ -583,7 +584,8 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
583 filename = &pFindData->FileName[0]; 584 filename = &pFindData->FileName[0];
584 len = pFindData->FileNameLength; 585 len = pFindData->FileNameLength;
585 } else { 586 } else {
586 cFYI(1,("Unknown findfirst level %d",cfile->srch_inf.info_level)); 587 cFYI(1, ("Unknown findfirst level %d",
588 cfile->srch_inf.info_level));
587 } 589 }
588 590
589 if (filename) { 591 if (filename) {
@@ -604,7 +606,7 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
604 if (filename[0] == '.') 606 if (filename[0] == '.')
605 rc = 1; 607 rc = 1;
606 } else if (len == 2) { 608 } else if (len == 2) {
607 if((filename[0] == '.') && (filename[1] == '.')) 609 if ((filename[0] == '.') && (filename[1] == '.'))
608 rc = 2; 610 rc = 2;
609 } 611 }
610 } 612 }
@@ -665,13 +667,13 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
665 is_dir_changed(file)) || 667 is_dir_changed(file)) ||
666 (index_to_find < first_entry_in_buffer)) { 668 (index_to_find < first_entry_in_buffer)) {
667 /* close and restart search */ 669 /* close and restart search */
668 cFYI(1,("search backing up - close and restart search")); 670 cFYI(1, ("search backing up - close and restart search"));
669 cifsFile->invalidHandle = TRUE; 671 cifsFile->invalidHandle = TRUE;
670 CIFSFindClose(xid, pTcon, cifsFile->netfid); 672 CIFSFindClose(xid, pTcon, cifsFile->netfid);
671 kfree(cifsFile->search_resume_name); 673 kfree(cifsFile->search_resume_name);
672 cifsFile->search_resume_name = NULL; 674 cifsFile->search_resume_name = NULL;
673 if (cifsFile->srch_inf.ntwrk_buf_start) { 675 if (cifsFile->srch_inf.ntwrk_buf_start) {
674 cFYI(1,("freeing SMB ff cache buf on search rewind")); 676 cFYI(1, ("freeing SMB ff cache buf on search rewind"));
675 if (cifsFile->srch_inf.smallBuf) 677 if (cifsFile->srch_inf.smallBuf)
676 cifs_small_buf_release(cifsFile->srch_inf. 678 cifs_small_buf_release(cifsFile->srch_inf.
677 ntwrk_buf_start); 679 ntwrk_buf_start);
@@ -681,14 +683,15 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
681 } 683 }
682 rc = initiate_cifs_search(xid,file); 684 rc = initiate_cifs_search(xid,file);
683 if (rc) { 685 if (rc) {
684 cFYI(1,("error %d reinitiating a search on rewind",rc)); 686 cFYI(1, ("error %d reinitiating a search on rewind",
687 rc));
685 return rc; 688 return rc;
686 } 689 }
687 } 690 }
688 691
689 while((index_to_find >= cifsFile->srch_inf.index_of_last_entry) && 692 while((index_to_find >= cifsFile->srch_inf.index_of_last_entry) &&
690 (rc == 0) && (cifsFile->srch_inf.endOfSearch == FALSE)){ 693 (rc == 0) && (cifsFile->srch_inf.endOfSearch == FALSE)){
691 cFYI(1,("calling findnext2")); 694 cFYI(1, ("calling findnext2"));
692 rc = CIFSFindNext(xid,pTcon,cifsFile->netfid, 695 rc = CIFSFindNext(xid,pTcon,cifsFile->netfid,
693 &cifsFile->srch_inf); 696 &cifsFile->srch_inf);
694 if (rc) 697 if (rc)
@@ -707,14 +710,14 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
707 first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry 710 first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry
708 - cifsFile->srch_inf.entries_in_buffer; 711 - cifsFile->srch_inf.entries_in_buffer;
709 pos_in_buf = index_to_find - first_entry_in_buffer; 712 pos_in_buf = index_to_find - first_entry_in_buffer;
710 cFYI(1,("found entry - pos_in_buf %d",pos_in_buf)); 713 cFYI(1, ("found entry - pos_in_buf %d", pos_in_buf));
711 714
712 for(i=0;(i<(pos_in_buf)) && (current_entry != NULL);i++) { 715 for(i=0;(i<(pos_in_buf)) && (current_entry != NULL);i++) {
713 /* go entry by entry figuring out which is first */ 716 /* go entry by entry figuring out which is first */
714 current_entry = nxt_dir_entry(current_entry,end_of_smb, 717 current_entry = nxt_dir_entry(current_entry,end_of_smb,
715 cifsFile->srch_inf.info_level); 718 cifsFile->srch_inf.info_level);
716 } 719 }
717 if((current_entry == NULL) && (i < pos_in_buf)) { 720 if ((current_entry == NULL) && (i < pos_in_buf)) {
718 /* BB fixme - check if we should flag this error */ 721 /* BB fixme - check if we should flag this error */
719 cERROR(1,("reached end of buf searching for pos in buf" 722 cERROR(1,("reached end of buf searching for pos in buf"
720 " %d index to find %lld rc %d", 723 " %d index to find %lld rc %d",
@@ -723,12 +726,12 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
723 rc = 0; 726 rc = 0;
724 *ppCurrentEntry = current_entry; 727 *ppCurrentEntry = current_entry;
725 } else { 728 } else {
726 cFYI(1,("index not in buffer - could not findnext into it")); 729 cFYI(1, ("index not in buffer - could not findnext into it"));
727 return 0; 730 return 0;
728 } 731 }
729 732
730 if(pos_in_buf >= cifsFile->srch_inf.entries_in_buffer) { 733 if (pos_in_buf >= cifsFile->srch_inf.entries_in_buffer) {
731 cFYI(1,("can not return entries pos_in_buf beyond last entry")); 734 cFYI(1, ("can not return entries pos_in_buf beyond last"));
732 *num_to_ret = 0; 735 *num_to_ret = 0;
733 } else 736 } else
734 *num_to_ret = cifsFile->srch_inf.entries_in_buffer - pos_in_buf; 737 *num_to_ret = cifsFile->srch_inf.entries_in_buffer - pos_in_buf;
@@ -748,11 +751,11 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst,
748 751
749 *pinum = 0; 752 *pinum = 0;
750 753
751 if(level == SMB_FIND_FILE_UNIX) { 754 if (level == SMB_FIND_FILE_UNIX) {
752 FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry; 755 FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry;
753 756
754 filename = &pFindData->FileName[0]; 757 filename = &pFindData->FileName[0];
755 if(unicode) { 758 if (unicode) {
756 len = cifs_unicode_bytelen(filename); 759 len = cifs_unicode_bytelen(filename);
757 } else { 760 } else {
758 /* BB should we make this strnlen of PATH_MAX? */ 761 /* BB should we make this strnlen of PATH_MAX? */
@@ -760,49 +763,49 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst,
760 } 763 }
761 764
762 /* BB fixme - hash low and high 32 bits if not 64 bit arch BB fixme */ 765 /* BB fixme - hash low and high 32 bits if not 64 bit arch BB fixme */
763 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) 766 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
764 *pinum = pFindData->UniqueId; 767 *pinum = pFindData->UniqueId;
765 } else if(level == SMB_FIND_FILE_DIRECTORY_INFO) { 768 } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {
766 FILE_DIRECTORY_INFO * pFindData = 769 FILE_DIRECTORY_INFO * pFindData =
767 (FILE_DIRECTORY_INFO *)current_entry; 770 (FILE_DIRECTORY_INFO *)current_entry;
768 filename = &pFindData->FileName[0]; 771 filename = &pFindData->FileName[0];
769 len = le32_to_cpu(pFindData->FileNameLength); 772 len = le32_to_cpu(pFindData->FileNameLength);
770 } else if(level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) { 773 } else if (level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
771 FILE_FULL_DIRECTORY_INFO * pFindData = 774 FILE_FULL_DIRECTORY_INFO * pFindData =
772 (FILE_FULL_DIRECTORY_INFO *)current_entry; 775 (FILE_FULL_DIRECTORY_INFO *)current_entry;
773 filename = &pFindData->FileName[0]; 776 filename = &pFindData->FileName[0];
774 len = le32_to_cpu(pFindData->FileNameLength); 777 len = le32_to_cpu(pFindData->FileNameLength);
775 } else if(level == SMB_FIND_FILE_ID_FULL_DIR_INFO) { 778 } else if (level == SMB_FIND_FILE_ID_FULL_DIR_INFO) {
776 SEARCH_ID_FULL_DIR_INFO * pFindData = 779 SEARCH_ID_FULL_DIR_INFO * pFindData =
777 (SEARCH_ID_FULL_DIR_INFO *)current_entry; 780 (SEARCH_ID_FULL_DIR_INFO *)current_entry;
778 filename = &pFindData->FileName[0]; 781 filename = &pFindData->FileName[0];
779 len = le32_to_cpu(pFindData->FileNameLength); 782 len = le32_to_cpu(pFindData->FileNameLength);
780 *pinum = pFindData->UniqueId; 783 *pinum = pFindData->UniqueId;
781 } else if(level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) { 784 } else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
782 FILE_BOTH_DIRECTORY_INFO * pFindData = 785 FILE_BOTH_DIRECTORY_INFO * pFindData =
783 (FILE_BOTH_DIRECTORY_INFO *)current_entry; 786 (FILE_BOTH_DIRECTORY_INFO *)current_entry;
784 filename = &pFindData->FileName[0]; 787 filename = &pFindData->FileName[0];
785 len = le32_to_cpu(pFindData->FileNameLength); 788 len = le32_to_cpu(pFindData->FileNameLength);
786 } else if(level == SMB_FIND_FILE_INFO_STANDARD) { 789 } else if (level == SMB_FIND_FILE_INFO_STANDARD) {
787 FIND_FILE_STANDARD_INFO * pFindData = 790 FIND_FILE_STANDARD_INFO * pFindData =
788 (FIND_FILE_STANDARD_INFO *)current_entry; 791 (FIND_FILE_STANDARD_INFO *)current_entry;
789 filename = &pFindData->FileName[0]; 792 filename = &pFindData->FileName[0];
790 /* one byte length, no name conversion */ 793 /* one byte length, no name conversion */
791 len = (unsigned int)pFindData->FileNameLength; 794 len = (unsigned int)pFindData->FileNameLength;
792 } else { 795 } else {
793 cFYI(1,("Unknown findfirst level %d",level)); 796 cFYI(1, ("Unknown findfirst level %d", level));
794 return -EINVAL; 797 return -EINVAL;
795 } 798 }
796 799
797 if(len > max_len) { 800 if (len > max_len) {
798 cERROR(1,("bad search response length %d past smb end", len)); 801 cERROR(1,("bad search response length %d past smb end", len));
799 return -EINVAL; 802 return -EINVAL;
800 } 803 }
801 804
802 if(unicode) { 805 if (unicode) {
803 /* BB fixme - test with long names */ 806 /* BB fixme - test with long names */
804 /* Note converted filename can be longer than in unicode */ 807 /* Note converted filename can be longer than in unicode */
805 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR) 808 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
806 pqst->len = cifs_convertUCSpath((char *)pqst->name, 809 pqst->len = cifs_convertUCSpath((char *)pqst->name,
807 (__le16 *)filename, len/2, nlt); 810 (__le16 *)filename, len/2, nlt);
808 else 811 else
@@ -813,7 +816,7 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst,
813 pqst->len = len; 816 pqst->len = len;
814 } 817 }
815 pqst->hash = full_name_hash(pqst->name,pqst->len); 818 pqst->hash = full_name_hash(pqst->name,pqst->len);
816/* cFYI(1,("filldir on %s",pqst->name)); */ 819/* cFYI(1, ("filldir on %s",pqst->name)); */
817 return rc; 820 return rc;
818} 821}
819 822
@@ -832,17 +835,17 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
832 /* get filename and len into qstring */ 835 /* get filename and len into qstring */
833 /* get dentry */ 836 /* get dentry */
834 /* decide whether to create and populate ionde */ 837 /* decide whether to create and populate ionde */
835 if((direntry == NULL) || (file == NULL)) 838 if ((direntry == NULL) || (file == NULL))
836 return -EINVAL; 839 return -EINVAL;
837 840
838 pCifsF = file->private_data; 841 pCifsF = file->private_data;
839 842
840 if((scratch_buf == NULL) || (pfindEntry == NULL) || (pCifsF == NULL)) 843 if ((scratch_buf == NULL) || (pfindEntry == NULL) || (pCifsF == NULL))
841 return -ENOENT; 844 return -ENOENT;
842 845
843 rc = cifs_entry_is_dot(pfindEntry,pCifsF); 846 rc = cifs_entry_is_dot(pfindEntry,pCifsF);
844 /* skip . and .. since we added them first */ 847 /* skip . and .. since we added them first */
845 if(rc != 0) 848 if (rc != 0)
846 return 0; 849 return 0;
847 850
848 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 851 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
@@ -854,16 +857,16 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
854 max_len, 857 max_len,
855 &inum /* returned */); 858 &inum /* returned */);
856 859
857 if(rc) 860 if (rc)
858 return rc; 861 return rc;
859 862
860 rc = construct_dentry(&qstring,file,&tmp_inode, &tmp_dentry); 863 rc = construct_dentry(&qstring,file,&tmp_inode, &tmp_dentry);
861 if((tmp_inode == NULL) || (tmp_dentry == NULL)) 864 if ((tmp_inode == NULL) || (tmp_dentry == NULL))
862 return -ENOMEM; 865 return -ENOMEM;
863 866
864 if(rc) { 867 if (rc) {
865 /* inode created, we need to hash it with right inode number */ 868 /* inode created, we need to hash it with right inode number */
866 if(inum != 0) { 869 if (inum != 0) {
867 /* BB fixme - hash the 2 32 quantities bits together if necessary BB */ 870 /* BB fixme - hash the 2 32 quantities bits together if necessary BB */
868 tmp_inode->i_ino = inum; 871 tmp_inode->i_ino = inum;
869 } 872 }
@@ -873,27 +876,27 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
873 /* we pass in rc below, indicating whether it is a new inode, 876 /* we pass in rc below, indicating whether it is a new inode,
874 so we can figure out whether to invalidate the inode cached 877 so we can figure out whether to invalidate the inode cached
875 data if the file has changed */ 878 data if the file has changed */
876 if(pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX) 879 if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX)
877 unix_fill_in_inode(tmp_inode, 880 unix_fill_in_inode(tmp_inode,
878 (FILE_UNIX_INFO *)pfindEntry, 881 (FILE_UNIX_INFO *)pfindEntry,
879 &obj_type, rc); 882 &obj_type, rc);
880 else if(pCifsF->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) 883 else if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD)
881 fill_in_inode(tmp_inode, 0 /* old level 1 buffer type */, 884 fill_in_inode(tmp_inode, 0 /* old level 1 buffer type */,
882 pfindEntry, &obj_type, rc); 885 pfindEntry, &obj_type, rc);
883 else 886 else
884 fill_in_inode(tmp_inode, 1 /* NT */, pfindEntry, &obj_type, rc); 887 fill_in_inode(tmp_inode, 1 /* NT */, pfindEntry, &obj_type, rc);
885 888
886 if(rc) /* new inode - needs to be tied to dentry */ { 889 if (rc) /* new inode - needs to be tied to dentry */ {
887 d_instantiate(tmp_dentry, tmp_inode); 890 d_instantiate(tmp_dentry, tmp_inode);
888 if(rc == 2) 891 if (rc == 2)
889 d_rehash(tmp_dentry); 892 d_rehash(tmp_dentry);
890 } 893 }
891 894
892 895
893 rc = filldir(direntry,qstring.name,qstring.len,file->f_pos, 896 rc = filldir(direntry,qstring.name,qstring.len,file->f_pos,
894 tmp_inode->i_ino,obj_type); 897 tmp_inode->i_ino,obj_type);
895 if(rc) { 898 if (rc) {
896 cFYI(1,("filldir rc = %d",rc)); 899 cFYI(1, ("filldir rc = %d", rc));
897 /* we can not return filldir errors to the caller 900 /* we can not return filldir errors to the caller
898 since they are "normal" when the stat blocksize 901 since they are "normal" when the stat blocksize
899 is too small - we return remapped error instead */ 902 is too small - we return remapped error instead */
@@ -912,47 +915,47 @@ static int cifs_save_resume_key(const char *current_entry,
912 __u16 level; 915 __u16 level;
913 char * filename; 916 char * filename;
914 917
915 if((cifsFile == NULL) || (current_entry == NULL)) 918 if ((cifsFile == NULL) || (current_entry == NULL))
916 return -EINVAL; 919 return -EINVAL;
917 920
918 level = cifsFile->srch_inf.info_level; 921 level = cifsFile->srch_inf.info_level;
919 922
920 if(level == SMB_FIND_FILE_UNIX) { 923 if (level == SMB_FIND_FILE_UNIX) {
921 FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry; 924 FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry;
922 925
923 filename = &pFindData->FileName[0]; 926 filename = &pFindData->FileName[0];
924 if(cifsFile->srch_inf.unicode) { 927 if (cifsFile->srch_inf.unicode) {
925 len = cifs_unicode_bytelen(filename); 928 len = cifs_unicode_bytelen(filename);
926 } else { 929 } else {
927 /* BB should we make this strnlen of PATH_MAX? */ 930 /* BB should we make this strnlen of PATH_MAX? */
928 len = strnlen(filename, PATH_MAX); 931 len = strnlen(filename, PATH_MAX);
929 } 932 }
930 cifsFile->srch_inf.resume_key = pFindData->ResumeKey; 933 cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
931 } else if(level == SMB_FIND_FILE_DIRECTORY_INFO) { 934 } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {
932 FILE_DIRECTORY_INFO * pFindData = 935 FILE_DIRECTORY_INFO * pFindData =
933 (FILE_DIRECTORY_INFO *)current_entry; 936 (FILE_DIRECTORY_INFO *)current_entry;
934 filename = &pFindData->FileName[0]; 937 filename = &pFindData->FileName[0];
935 len = le32_to_cpu(pFindData->FileNameLength); 938 len = le32_to_cpu(pFindData->FileNameLength);
936 cifsFile->srch_inf.resume_key = pFindData->FileIndex; 939 cifsFile->srch_inf.resume_key = pFindData->FileIndex;
937 } else if(level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) { 940 } else if (level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
938 FILE_FULL_DIRECTORY_INFO * pFindData = 941 FILE_FULL_DIRECTORY_INFO * pFindData =
939 (FILE_FULL_DIRECTORY_INFO *)current_entry; 942 (FILE_FULL_DIRECTORY_INFO *)current_entry;
940 filename = &pFindData->FileName[0]; 943 filename = &pFindData->FileName[0];
941 len = le32_to_cpu(pFindData->FileNameLength); 944 len = le32_to_cpu(pFindData->FileNameLength);
942 cifsFile->srch_inf.resume_key = pFindData->FileIndex; 945 cifsFile->srch_inf.resume_key = pFindData->FileIndex;
943 } else if(level == SMB_FIND_FILE_ID_FULL_DIR_INFO) { 946 } else if (level == SMB_FIND_FILE_ID_FULL_DIR_INFO) {
944 SEARCH_ID_FULL_DIR_INFO * pFindData = 947 SEARCH_ID_FULL_DIR_INFO * pFindData =
945 (SEARCH_ID_FULL_DIR_INFO *)current_entry; 948 (SEARCH_ID_FULL_DIR_INFO *)current_entry;
946 filename = &pFindData->FileName[0]; 949 filename = &pFindData->FileName[0];
947 len = le32_to_cpu(pFindData->FileNameLength); 950 len = le32_to_cpu(pFindData->FileNameLength);
948 cifsFile->srch_inf.resume_key = pFindData->FileIndex; 951 cifsFile->srch_inf.resume_key = pFindData->FileIndex;
949 } else if(level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) { 952 } else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
950 FILE_BOTH_DIRECTORY_INFO * pFindData = 953 FILE_BOTH_DIRECTORY_INFO * pFindData =
951 (FILE_BOTH_DIRECTORY_INFO *)current_entry; 954 (FILE_BOTH_DIRECTORY_INFO *)current_entry;
952 filename = &pFindData->FileName[0]; 955 filename = &pFindData->FileName[0];
953 len = le32_to_cpu(pFindData->FileNameLength); 956 len = le32_to_cpu(pFindData->FileNameLength);
954 cifsFile->srch_inf.resume_key = pFindData->FileIndex; 957 cifsFile->srch_inf.resume_key = pFindData->FileIndex;
955 } else if(level == SMB_FIND_FILE_INFO_STANDARD) { 958 } else if (level == SMB_FIND_FILE_INFO_STANDARD) {
956 FIND_FILE_STANDARD_INFO * pFindData = 959 FIND_FILE_STANDARD_INFO * pFindData =
957 (FIND_FILE_STANDARD_INFO *)current_entry; 960 (FIND_FILE_STANDARD_INFO *)current_entry;
958 filename = &pFindData->FileName[0]; 961 filename = &pFindData->FileName[0];
@@ -960,7 +963,7 @@ static int cifs_save_resume_key(const char *current_entry,
960 len = (unsigned int)pFindData->FileNameLength; 963 len = (unsigned int)pFindData->FileNameLength;
961 cifsFile->srch_inf.resume_key = pFindData->ResumeKey; 964 cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
962 } else { 965 } else {
963 cFYI(1,("Unknown findfirst level %d",level)); 966 cFYI(1, ("Unknown findfirst level %d", level));
964 return -EINVAL; 967 return -EINVAL;
965 } 968 }
966 cifsFile->srch_inf.resume_name_len = len; 969 cifsFile->srch_inf.resume_name_len = len;
@@ -985,7 +988,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
985 988
986 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 989 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
987 pTcon = cifs_sb->tcon; 990 pTcon = cifs_sb->tcon;
988 if(pTcon == NULL) 991 if (pTcon == NULL)
989 return -EINVAL; 992 return -EINVAL;
990 993
991 switch ((int) file->f_pos) { 994 switch ((int) file->f_pos) {
@@ -1011,22 +1014,22 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
1011 if it before then restart search 1014 if it before then restart search
1012 if after then keep searching till find it */ 1015 if after then keep searching till find it */
1013 1016
1014 if(file->private_data == NULL) { 1017 if (file->private_data == NULL) {
1015 rc = initiate_cifs_search(xid,file); 1018 rc = initiate_cifs_search(xid,file);
1016 cFYI(1,("initiate cifs search rc %d",rc)); 1019 cFYI(1, ("initiate cifs search rc %d", rc));
1017 if(rc) { 1020 if (rc) {
1018 FreeXid(xid); 1021 FreeXid(xid);
1019 return rc; 1022 return rc;
1020 } 1023 }
1021 } 1024 }
1022 if(file->private_data == NULL) { 1025 if (file->private_data == NULL) {
1023 rc = -EINVAL; 1026 rc = -EINVAL;
1024 FreeXid(xid); 1027 FreeXid(xid);
1025 return rc; 1028 return rc;
1026 } 1029 }
1027 cifsFile = file->private_data; 1030 cifsFile = file->private_data;
1028 if (cifsFile->srch_inf.endOfSearch) { 1031 if (cifsFile->srch_inf.endOfSearch) {
1029 if(cifsFile->srch_inf.emptyDir) { 1032 if (cifsFile->srch_inf.emptyDir) {
1030 cFYI(1, ("End of search, empty dir")); 1033 cFYI(1, ("End of search, empty dir"));
1031 rc = 0; 1034 rc = 0;
1032 break; 1035 break;
@@ -1040,17 +1043,17 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
1040 1043
1041 rc = find_cifs_entry(xid,pTcon, file, 1044 rc = find_cifs_entry(xid,pTcon, file,
1042 &current_entry,&num_to_fill); 1045 &current_entry,&num_to_fill);
1043 if(rc) { 1046 if (rc) {
1044 cFYI(1,("fce error %d",rc)); 1047 cFYI(1, ("fce error %d", rc));
1045 goto rddir2_exit; 1048 goto rddir2_exit;
1046 } else if (current_entry != NULL) { 1049 } else if (current_entry != NULL) {
1047 cFYI(1,("entry %lld found",file->f_pos)); 1050 cFYI(1, ("entry %lld found", file->f_pos));
1048 } else { 1051 } else {
1049 cFYI(1,("could not find entry")); 1052 cFYI(1, ("could not find entry"));
1050 goto rddir2_exit; 1053 goto rddir2_exit;
1051 } 1054 }
1052 cFYI(1,("loop through %d times filling dir for net buf %p", 1055 cFYI(1, ("loop through %d times filling dir for net buf %p",
1053 num_to_fill,cifsFile->srch_inf.ntwrk_buf_start)); 1056 num_to_fill, cifsFile->srch_inf.ntwrk_buf_start));
1054 max_len = smbCalcSize((struct smb_hdr *) 1057 max_len = smbCalcSize((struct smb_hdr *)
1055 cifsFile->srch_inf.ntwrk_buf_start); 1058 cifsFile->srch_inf.ntwrk_buf_start);
1056 end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len; 1059 end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len;
@@ -1060,8 +1063,8 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
1060 such multibyte target UTF-8 characters. cifs_unicode.c, 1063 such multibyte target UTF-8 characters. cifs_unicode.c,
1061 which actually does the conversion, has the same limit */ 1064 which actually does the conversion, has the same limit */
1062 tmp_buf = kmalloc((2 * NAME_MAX) + 4, GFP_KERNEL); 1065 tmp_buf = kmalloc((2 * NAME_MAX) + 4, GFP_KERNEL);
1063 for(i=0;(i<num_to_fill) && (rc == 0);i++) { 1066 for (i = 0; (i < num_to_fill) && (rc == 0); i++) {
1064 if(current_entry == NULL) { 1067 if (current_entry == NULL) {
1065 /* evaluate whether this case is an error */ 1068 /* evaluate whether this case is an error */
1066 cERROR(1,("past end of SMB num to fill %d i %d", 1069 cERROR(1,("past end of SMB num to fill %d i %d",
1067 num_to_fill, i)); 1070 num_to_fill, i));
@@ -1071,20 +1074,20 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
1071 we want to check for that here? */ 1074 we want to check for that here? */
1072 rc = cifs_filldir(current_entry, file, 1075 rc = cifs_filldir(current_entry, file,
1073 filldir, direntry, tmp_buf, max_len); 1076 filldir, direntry, tmp_buf, max_len);
1074 if(rc == -EOVERFLOW) { 1077 if (rc == -EOVERFLOW) {
1075 rc = 0; 1078 rc = 0;
1076 break; 1079 break;
1077 } 1080 }
1078 1081
1079 file->f_pos++; 1082 file->f_pos++;
1080 if(file->f_pos == 1083 if (file->f_pos ==
1081 cifsFile->srch_inf.index_of_last_entry) { 1084 cifsFile->srch_inf.index_of_last_entry) {
1082 cFYI(1,("last entry in buf at pos %lld %s", 1085 cFYI(1, ("last entry in buf at pos %lld %s",
1083 file->f_pos,tmp_buf)); 1086 file->f_pos, tmp_buf));
1084 cifs_save_resume_key(current_entry,cifsFile); 1087 cifs_save_resume_key(current_entry, cifsFile);
1085 break; 1088 break;
1086 } else 1089 } else
1087 current_entry = 1090 current_entry =
1088 nxt_dir_entry(current_entry, end_of_smb, 1091 nxt_dir_entry(current_entry, end_of_smb,
1089 cifsFile->srch_inf.info_level); 1092 cifsFile->srch_inf.info_level);
1090 } 1093 }