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.c161
1 files changed, 71 insertions, 90 deletions
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 2a374d5215ab..b5364f90d551 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -37,19 +37,19 @@ static void dump_cifs_file_struct(struct file *file, char *label)
37{ 37{
38 struct cifsFileInfo * cf; 38 struct cifsFileInfo * cf;
39 39
40 if(file) { 40 if (file) {
41 cf = file->private_data; 41 cf = file->private_data;
42 if(cf == NULL) { 42 if (cf == NULL) {
43 cFYI(1,("empty cifs private file data")); 43 cFYI(1,("empty cifs private file data"));
44 return; 44 return;
45 } 45 }
46 if(cf->invalidHandle) { 46 if (cf->invalidHandle) {
47 cFYI(1,("invalid handle")); 47 cFYI(1,("invalid handle"));
48 } 48 }
49 if(cf->srch_inf.endOfSearch) { 49 if (cf->srch_inf.endOfSearch) {
50 cFYI(1,("end of search")); 50 cFYI(1,("end of search"));
51 } 51 }
52 if(cf->srch_inf.emptyDir) { 52 if (cf->srch_inf.emptyDir) {
53 cFYI(1,("empty dir")); 53 cFYI(1,("empty dir"));
54 } 54 }
55 55
@@ -77,17 +77,17 @@ static int construct_dentry(struct qstr *qstring, struct file *file,
77 cFYI(0, ("existing dentry with inode 0x%p", tmp_dentry->d_inode)); 77 cFYI(0, ("existing dentry with inode 0x%p", tmp_dentry->d_inode));
78 *ptmp_inode = tmp_dentry->d_inode; 78 *ptmp_inode = tmp_dentry->d_inode;
79/* BB overwrite old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len??*/ 79/* BB overwrite old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len??*/
80 if(*ptmp_inode == NULL) { 80 if (*ptmp_inode == NULL) {
81 *ptmp_inode = new_inode(file->f_path.dentry->d_sb); 81 *ptmp_inode = new_inode(file->f_path.dentry->d_sb);
82 if(*ptmp_inode == NULL) 82 if (*ptmp_inode == NULL)
83 return rc; 83 return rc;
84 rc = 1; 84 rc = 1;
85 } 85 }
86 if(file->f_path.dentry->d_sb->s_flags & MS_NOATIME) 86 if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME)
87 (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME; 87 (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME;
88 } else { 88 } else {
89 tmp_dentry = d_alloc(file->f_path.dentry, qstring); 89 tmp_dentry = d_alloc(file->f_path.dentry, qstring);
90 if(tmp_dentry == NULL) { 90 if (tmp_dentry == NULL) {
91 cERROR(1,("Failed allocating dentry")); 91 cERROR(1,("Failed allocating dentry"));
92 *ptmp_inode = NULL; 92 *ptmp_inode = NULL;
93 return rc; 93 return rc;
@@ -98,9 +98,9 @@ static int construct_dentry(struct qstr *qstring, struct file *file,
98 tmp_dentry->d_op = &cifs_ci_dentry_ops; 98 tmp_dentry->d_op = &cifs_ci_dentry_ops;
99 else 99 else
100 tmp_dentry->d_op = &cifs_dentry_ops; 100 tmp_dentry->d_op = &cifs_dentry_ops;
101 if(*ptmp_inode == NULL) 101 if (*ptmp_inode == NULL)
102 return rc; 102 return rc;
103 if(file->f_path.dentry->d_sb->s_flags & MS_NOATIME) 103 if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME)
104 (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME; 104 (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME;
105 rc = 2; 105 rc = 2;
106 } 106 }
@@ -112,7 +112,7 @@ static int construct_dentry(struct qstr *qstring, struct file *file,
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;
117 inode->i_mtime.tv_sec += tcon->ses->server->timeAdj; 117 inode->i_mtime.tv_sec += tcon->ses->server->timeAdj;
118 inode->i_atime.tv_sec += tcon->ses->server->timeAdj; 118 inode->i_atime.tv_sec += tcon->ses->server->timeAdj;
@@ -137,7 +137,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
137 local_mtime = tmp_inode->i_mtime; 137 local_mtime = tmp_inode->i_mtime;
138 local_size = tmp_inode->i_size; 138 local_size = tmp_inode->i_size;
139 139
140 if(new_buf_type) { 140 if (new_buf_type) {
141 FILE_DIRECTORY_INFO *pfindData = (FILE_DIRECTORY_INFO *)buf; 141 FILE_DIRECTORY_INFO *pfindData = (FILE_DIRECTORY_INFO *)buf;
142 142
143 attr = le32_to_cpu(pfindData->ExtFileAttributes); 143 attr = le32_to_cpu(pfindData->ExtFileAttributes);
@@ -193,7 +193,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
193 if (attr & ATTR_DIRECTORY) { 193 if (attr & ATTR_DIRECTORY) {
194 *pobject_type = DT_DIR; 194 *pobject_type = DT_DIR;
195 /* override default perms since we do not lock dirs */ 195 /* override default perms since we do not lock dirs */
196 if(atomic_read(&cifsInfo->inUse) == 0) { 196 if (atomic_read(&cifsInfo->inUse) == 0) {
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;
@@ -250,25 +250,25 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
250 if (S_ISREG(tmp_inode->i_mode)) { 250 if (S_ISREG(tmp_inode->i_mode)) {
251 cFYI(1, ("File inode")); 251 cFYI(1, ("File inode"));
252 tmp_inode->i_op = &cifs_file_inode_ops; 252 tmp_inode->i_op = &cifs_file_inode_ops;
253 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { 253 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
254 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 254 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
255 tmp_inode->i_fop = &cifs_file_direct_nobrl_ops; 255 tmp_inode->i_fop = &cifs_file_direct_nobrl_ops;
256 else 256 else
257 tmp_inode->i_fop = &cifs_file_direct_ops; 257 tmp_inode->i_fop = &cifs_file_direct_ops;
258 258
259 } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 259 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
260 tmp_inode->i_fop = &cifs_file_nobrl_ops; 260 tmp_inode->i_fop = &cifs_file_nobrl_ops;
261 else 261 else
262 tmp_inode->i_fop = &cifs_file_ops; 262 tmp_inode->i_fop = &cifs_file_ops;
263 263
264 if((cifs_sb->tcon) && (cifs_sb->tcon->ses) && 264 if ((cifs_sb->tcon) && (cifs_sb->tcon->ses) &&
265 (cifs_sb->tcon->ses->server->maxBuf < 265 (cifs_sb->tcon->ses->server->maxBuf <
266 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)) 266 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE))
267 tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf; 267 tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
268 else 268 else
269 tmp_inode->i_data.a_ops = &cifs_addr_ops; 269 tmp_inode->i_data.a_ops = &cifs_addr_ops;
270 270
271 if(isNewInode) 271 if (isNewInode)
272 return; /* No sense invalidating pages for new inode 272 return; /* No sense invalidating pages for new inode
273 since have not started caching readahead file 273 since have not started caching readahead file
274 data yet */ 274 data yet */
@@ -357,8 +357,14 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
357 cFYI(1,("unknown inode type %d",type)); 357 cFYI(1,("unknown inode type %d",type));
358 } 358 }
359 359
360 tmp_inode->i_uid = le64_to_cpu(pfindData->Uid); 360 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
361 tmp_inode->i_gid = le64_to_cpu(pfindData->Gid); 361 tmp_inode->i_uid = cifs_sb->mnt_uid;
362 else
363 tmp_inode->i_uid = le64_to_cpu(pfindData->Uid);
364 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
365 tmp_inode->i_gid = cifs_sb->mnt_gid;
366 else
367 tmp_inode->i_gid = le64_to_cpu(pfindData->Gid);
362 tmp_inode->i_nlink = le64_to_cpu(pfindData->Nlinks); 368 tmp_inode->i_nlink = le64_to_cpu(pfindData->Nlinks);
363 369
364 spin_lock(&tmp_inode->i_lock); 370 spin_lock(&tmp_inode->i_lock);
@@ -377,25 +383,24 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
377 cFYI(1, ("File inode")); 383 cFYI(1, ("File inode"));
378 tmp_inode->i_op = &cifs_file_inode_ops; 384 tmp_inode->i_op = &cifs_file_inode_ops;
379 385
380 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { 386 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
381 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 387 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
382 tmp_inode->i_fop = &cifs_file_direct_nobrl_ops; 388 tmp_inode->i_fop = &cifs_file_direct_nobrl_ops;
383 else 389 else
384 tmp_inode->i_fop = &cifs_file_direct_ops; 390 tmp_inode->i_fop = &cifs_file_direct_ops;
385 391 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
386 } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
387 tmp_inode->i_fop = &cifs_file_nobrl_ops; 392 tmp_inode->i_fop = &cifs_file_nobrl_ops;
388 else 393 else
389 tmp_inode->i_fop = &cifs_file_ops; 394 tmp_inode->i_fop = &cifs_file_ops;
390 395
391 if((cifs_sb->tcon) && (cifs_sb->tcon->ses) && 396 if ((cifs_sb->tcon) && (cifs_sb->tcon->ses) &&
392 (cifs_sb->tcon->ses->server->maxBuf < 397 (cifs_sb->tcon->ses->server->maxBuf <
393 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)) 398 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE))
394 tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf; 399 tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
395 else 400 else
396 tmp_inode->i_data.a_ops = &cifs_addr_ops; 401 tmp_inode->i_data.a_ops = &cifs_addr_ops;
397 402
398 if(isNewInode) 403 if (isNewInode)
399 return; /* No sense invalidating pages for new inode since we 404 return; /* No sense invalidating pages for new inode since we
400 have not started caching readahead file data yet */ 405 have not started caching readahead file data yet */
401 406
@@ -430,34 +435,28 @@ static int initiate_cifs_search(const int xid, struct file *file)
430 struct cifs_sb_info *cifs_sb; 435 struct cifs_sb_info *cifs_sb;
431 struct cifsTconInfo *pTcon; 436 struct cifsTconInfo *pTcon;
432 437
433 if(file->private_data == NULL) { 438 if (file->private_data == NULL) {
434 file->private_data = 439 file->private_data =
435 kmalloc(sizeof(struct cifsFileInfo),GFP_KERNEL); 440 kzalloc(sizeof(struct cifsFileInfo),GFP_KERNEL);
436 } 441 }
437 442
438 if(file->private_data == NULL) { 443 if (file->private_data == NULL)
439 return -ENOMEM; 444 return -ENOMEM;
440 } else {
441 memset(file->private_data,0,sizeof(struct cifsFileInfo));
442 }
443 cifsFile = file->private_data; 445 cifsFile = file->private_data;
444 cifsFile->invalidHandle = TRUE; 446 cifsFile->invalidHandle = TRUE;
445 cifsFile->srch_inf.endOfSearch = FALSE; 447 cifsFile->srch_inf.endOfSearch = FALSE;
446 448
447 if(file->f_path.dentry == NULL)
448 return -ENOENT;
449
450 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 449 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
451 if(cifs_sb == NULL) 450 if (cifs_sb == NULL)
452 return -EINVAL; 451 return -EINVAL;
453 452
454 pTcon = cifs_sb->tcon; 453 pTcon = cifs_sb->tcon;
455 if(pTcon == NULL) 454 if (pTcon == NULL)
456 return -EINVAL; 455 return -EINVAL;
457 456
458 full_path = build_path_from_dentry(file->f_path.dentry); 457 full_path = build_path_from_dentry(file->f_path.dentry);
459 458
460 if(full_path == NULL) { 459 if (full_path == NULL) {
461 return -ENOMEM; 460 return -ENOMEM;
462 } 461 }
463 462
@@ -480,9 +479,9 @@ ffirst_retry:
480 &cifsFile->netfid, &cifsFile->srch_inf, 479 &cifsFile->netfid, &cifsFile->srch_inf,
481 cifs_sb->mnt_cifs_flags & 480 cifs_sb->mnt_cifs_flags &
482 CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb)); 481 CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb));
483 if(rc == 0) 482 if (rc == 0)
484 cifsFile->invalidHandle = FALSE; 483 cifsFile->invalidHandle = FALSE;
485 if((rc == -EOPNOTSUPP) && 484 if ((rc == -EOPNOTSUPP) &&
486 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) { 485 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
487 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM; 486 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
488 goto ffirst_retry; 487 goto ffirst_retry;
@@ -498,7 +497,7 @@ static int cifs_unicode_bytelen(char *str)
498 __le16 * ustr = (__le16 *)str; 497 __le16 * ustr = (__le16 *)str;
499 498
500 for(len=0;len <= PATH_MAX;len++) { 499 for(len=0;len <= PATH_MAX;len++) {
501 if(ustr[len] == 0) 500 if (ustr[len] == 0)
502 return len << 1; 501 return len << 1;
503 } 502 }
504 cFYI(1,("Unicode string longer than PATH_MAX found")); 503 cFYI(1,("Unicode string longer than PATH_MAX found"));
@@ -510,7 +509,7 @@ static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level)
510 char * new_entry; 509 char * new_entry;
511 FILE_DIRECTORY_INFO * pDirInfo = (FILE_DIRECTORY_INFO *)old_entry; 510 FILE_DIRECTORY_INFO * pDirInfo = (FILE_DIRECTORY_INFO *)old_entry;
512 511
513 if(level == SMB_FIND_FILE_INFO_STANDARD) { 512 if (level == SMB_FIND_FILE_INFO_STANDARD) {
514 FIND_FILE_STANDARD_INFO * pfData; 513 FIND_FILE_STANDARD_INFO * pfData;
515 pfData = (FIND_FILE_STANDARD_INFO *)pDirInfo; 514 pfData = (FIND_FILE_STANDARD_INFO *)pDirInfo;
516 515
@@ -520,12 +519,12 @@ static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level)
520 new_entry = old_entry + le32_to_cpu(pDirInfo->NextEntryOffset); 519 new_entry = old_entry + le32_to_cpu(pDirInfo->NextEntryOffset);
521 cFYI(1,("new entry %p old entry %p",new_entry,old_entry)); 520 cFYI(1,("new entry %p old entry %p",new_entry,old_entry));
522 /* validate that new_entry is not past end of SMB */ 521 /* validate that new_entry is not past end of SMB */
523 if(new_entry >= end_of_smb) { 522 if (new_entry >= end_of_smb) {
524 cERROR(1, 523 cERROR(1,
525 ("search entry %p began after end of SMB %p old entry %p", 524 ("search entry %p began after end of SMB %p old entry %p",
526 new_entry, end_of_smb, old_entry)); 525 new_entry, end_of_smb, old_entry));
527 return NULL; 526 return NULL;
528 } else if(((level == SMB_FIND_FILE_INFO_STANDARD) && 527 } else if (((level == SMB_FIND_FILE_INFO_STANDARD) &&
529 (new_entry + sizeof(FIND_FILE_STANDARD_INFO) > end_of_smb)) || 528 (new_entry + sizeof(FIND_FILE_STANDARD_INFO) > end_of_smb)) ||
530 ((level != SMB_FIND_FILE_INFO_STANDARD) && 529 ((level != SMB_FIND_FILE_INFO_STANDARD) &&
531 (new_entry + sizeof(FILE_DIRECTORY_INFO) > end_of_smb))) { 530 (new_entry + sizeof(FILE_DIRECTORY_INFO) > end_of_smb))) {
@@ -546,39 +545,39 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
546 char * filename = NULL; 545 char * filename = NULL;
547 int len = 0; 546 int len = 0;
548 547
549 if(cfile->srch_inf.info_level == SMB_FIND_FILE_UNIX) { 548 if (cfile->srch_inf.info_level == SMB_FIND_FILE_UNIX) {
550 FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry; 549 FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry;
551 filename = &pFindData->FileName[0]; 550 filename = &pFindData->FileName[0];
552 if(cfile->srch_inf.unicode) { 551 if (cfile->srch_inf.unicode) {
553 len = cifs_unicode_bytelen(filename); 552 len = cifs_unicode_bytelen(filename);
554 } else { 553 } else {
555 /* BB should we make this strnlen of PATH_MAX? */ 554 /* BB should we make this strnlen of PATH_MAX? */
556 len = strnlen(filename, 5); 555 len = strnlen(filename, 5);
557 } 556 }
558 } else if(cfile->srch_inf.info_level == SMB_FIND_FILE_DIRECTORY_INFO) { 557 } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_DIRECTORY_INFO) {
559 FILE_DIRECTORY_INFO * pFindData = 558 FILE_DIRECTORY_INFO * pFindData =
560 (FILE_DIRECTORY_INFO *)current_entry; 559 (FILE_DIRECTORY_INFO *)current_entry;
561 filename = &pFindData->FileName[0]; 560 filename = &pFindData->FileName[0];
562 len = le32_to_cpu(pFindData->FileNameLength); 561 len = le32_to_cpu(pFindData->FileNameLength);
563 } else if(cfile->srch_inf.info_level == 562 } else if (cfile->srch_inf.info_level ==
564 SMB_FIND_FILE_FULL_DIRECTORY_INFO) { 563 SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
565 FILE_FULL_DIRECTORY_INFO * pFindData = 564 FILE_FULL_DIRECTORY_INFO * pFindData =
566 (FILE_FULL_DIRECTORY_INFO *)current_entry; 565 (FILE_FULL_DIRECTORY_INFO *)current_entry;
567 filename = &pFindData->FileName[0]; 566 filename = &pFindData->FileName[0];
568 len = le32_to_cpu(pFindData->FileNameLength); 567 len = le32_to_cpu(pFindData->FileNameLength);
569 } else if(cfile->srch_inf.info_level == 568 } else if (cfile->srch_inf.info_level ==
570 SMB_FIND_FILE_ID_FULL_DIR_INFO) { 569 SMB_FIND_FILE_ID_FULL_DIR_INFO) {
571 SEARCH_ID_FULL_DIR_INFO * pFindData = 570 SEARCH_ID_FULL_DIR_INFO * pFindData =
572 (SEARCH_ID_FULL_DIR_INFO *)current_entry; 571 (SEARCH_ID_FULL_DIR_INFO *)current_entry;
573 filename = &pFindData->FileName[0]; 572 filename = &pFindData->FileName[0];
574 len = le32_to_cpu(pFindData->FileNameLength); 573 len = le32_to_cpu(pFindData->FileNameLength);
575 } else if(cfile->srch_inf.info_level == 574 } else if (cfile->srch_inf.info_level ==
576 SMB_FIND_FILE_BOTH_DIRECTORY_INFO) { 575 SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
577 FILE_BOTH_DIRECTORY_INFO * pFindData = 576 FILE_BOTH_DIRECTORY_INFO * pFindData =
578 (FILE_BOTH_DIRECTORY_INFO *)current_entry; 577 (FILE_BOTH_DIRECTORY_INFO *)current_entry;
579 filename = &pFindData->FileName[0]; 578 filename = &pFindData->FileName[0];
580 len = le32_to_cpu(pFindData->FileNameLength); 579 len = le32_to_cpu(pFindData->FileNameLength);
581 } else if(cfile->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) { 580 } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) {
582 FIND_FILE_STANDARD_INFO * pFindData = 581 FIND_FILE_STANDARD_INFO * pFindData =
583 (FIND_FILE_STANDARD_INFO *)current_entry; 582 (FIND_FILE_STANDARD_INFO *)current_entry;
584 filename = &pFindData->FileName[0]; 583 filename = &pFindData->FileName[0];
@@ -587,25 +586,25 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
587 cFYI(1,("Unknown findfirst level %d",cfile->srch_inf.info_level)); 586 cFYI(1,("Unknown findfirst level %d",cfile->srch_inf.info_level));
588 } 587 }
589 588
590 if(filename) { 589 if (filename) {
591 if(cfile->srch_inf.unicode) { 590 if (cfile->srch_inf.unicode) {
592 __le16 *ufilename = (__le16 *)filename; 591 __le16 *ufilename = (__le16 *)filename;
593 if(len == 2) { 592 if (len == 2) {
594 /* check for . */ 593 /* check for . */
595 if(ufilename[0] == UNICODE_DOT) 594 if (ufilename[0] == UNICODE_DOT)
596 rc = 1; 595 rc = 1;
597 } else if(len == 4) { 596 } else if (len == 4) {
598 /* check for .. */ 597 /* check for .. */
599 if((ufilename[0] == UNICODE_DOT) 598 if ((ufilename[0] == UNICODE_DOT)
600 &&(ufilename[1] == UNICODE_DOT)) 599 &&(ufilename[1] == UNICODE_DOT))
601 rc = 2; 600 rc = 2;
602 } 601 }
603 } else /* ASCII */ { 602 } else /* ASCII */ {
604 if(len == 1) { 603 if (len == 1) {
605 if(filename[0] == '.') 604 if (filename[0] == '.')
606 rc = 1; 605 rc = 1;
607 } else if(len == 2) { 606 } else if (len == 2) {
608 if((filename[0] == '.') && (filename[1] == '.')) 607 if((filename[0] == '.') && (filename[1] == '.'))
609 rc = 2; 608 rc = 2;
610 } 609 }
611 } 610 }
@@ -618,20 +617,10 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
618 whether we can use the cached search results from the previous search */ 617 whether we can use the cached search results from the previous search */
619static int is_dir_changed(struct file * file) 618static int is_dir_changed(struct file * file)
620{ 619{
621 struct inode * inode; 620 struct inode *inode = file->f_path.dentry->d_inode;
622 struct cifsInodeInfo *cifsInfo; 621 struct cifsInodeInfo *cifsInfo = CIFS_I(inode);
623 622
624 if(file->f_path.dentry == NULL) 623 if (cifsInfo->time == 0)
625 return 0;
626
627 inode = file->f_path.dentry->d_inode;
628
629 if(inode == NULL)
630 return 0;
631
632 cifsInfo = CIFS_I(inode);
633
634 if(cifsInfo->time == 0)
635 return 1; /* directory was changed, perhaps due to unlink */ 624 return 1; /* directory was changed, perhaps due to unlink */
636 else 625 else
637 return 0; 626 return 0;
@@ -654,7 +643,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
654 struct cifsFileInfo * cifsFile = file->private_data; 643 struct cifsFileInfo * cifsFile = file->private_data;
655 /* check if index in the buffer */ 644 /* check if index in the buffer */
656 645
657 if((cifsFile == NULL) || (ppCurrentEntry == NULL) || 646 if ((cifsFile == NULL) || (ppCurrentEntry == NULL) ||
658 (num_to_ret == NULL)) 647 (num_to_ret == NULL))
659 return -ENOENT; 648 return -ENOENT;
660 649
@@ -672,7 +661,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
672#ifdef CONFIG_CIFS_DEBUG2 661#ifdef CONFIG_CIFS_DEBUG2
673 dump_cifs_file_struct(file, "In fce "); 662 dump_cifs_file_struct(file, "In fce ");
674#endif 663#endif
675 if(((index_to_find < cifsFile->srch_inf.index_of_last_entry) && 664 if (((index_to_find < cifsFile->srch_inf.index_of_last_entry) &&
676 is_dir_changed(file)) || 665 is_dir_changed(file)) ||
677 (index_to_find < first_entry_in_buffer)) { 666 (index_to_find < first_entry_in_buffer)) {
678 /* close and restart search */ 667 /* close and restart search */
@@ -681,9 +670,9 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
681 CIFSFindClose(xid, pTcon, cifsFile->netfid); 670 CIFSFindClose(xid, pTcon, cifsFile->netfid);
682 kfree(cifsFile->search_resume_name); 671 kfree(cifsFile->search_resume_name);
683 cifsFile->search_resume_name = NULL; 672 cifsFile->search_resume_name = NULL;
684 if(cifsFile->srch_inf.ntwrk_buf_start) { 673 if (cifsFile->srch_inf.ntwrk_buf_start) {
685 cFYI(1,("freeing SMB ff cache buf on search rewind")); 674 cFYI(1,("freeing SMB ff cache buf on search rewind"));
686 if(cifsFile->srch_inf.smallBuf) 675 if (cifsFile->srch_inf.smallBuf)
687 cifs_small_buf_release(cifsFile->srch_inf. 676 cifs_small_buf_release(cifsFile->srch_inf.
688 ntwrk_buf_start); 677 ntwrk_buf_start);
689 else 678 else
@@ -691,7 +680,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
691 ntwrk_buf_start); 680 ntwrk_buf_start);
692 } 681 }
693 rc = initiate_cifs_search(xid,file); 682 rc = initiate_cifs_search(xid,file);
694 if(rc) { 683 if (rc) {
695 cFYI(1,("error %d reinitiating a search on rewind",rc)); 684 cFYI(1,("error %d reinitiating a search on rewind",rc));
696 return rc; 685 return rc;
697 } 686 }
@@ -702,10 +691,10 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
702 cFYI(1,("calling findnext2")); 691 cFYI(1,("calling findnext2"));
703 rc = CIFSFindNext(xid,pTcon,cifsFile->netfid, 692 rc = CIFSFindNext(xid,pTcon,cifsFile->netfid,
704 &cifsFile->srch_inf); 693 &cifsFile->srch_inf);
705 if(rc) 694 if (rc)
706 return -ENOENT; 695 return -ENOENT;
707 } 696 }
708 if(index_to_find < cifsFile->srch_inf.index_of_last_entry) { 697 if (index_to_find < cifsFile->srch_inf.index_of_last_entry) {
709 /* we found the buffer that contains the entry */ 698 /* we found the buffer that contains the entry */
710 /* scan and find it */ 699 /* scan and find it */
711 int i; 700 int i;
@@ -851,9 +840,6 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
851 if((scratch_buf == NULL) || (pfindEntry == NULL) || (pCifsF == NULL)) 840 if((scratch_buf == NULL) || (pfindEntry == NULL) || (pCifsF == NULL))
852 return -ENOENT; 841 return -ENOENT;
853 842
854 if(file->f_path.dentry == NULL)
855 return -ENOENT;
856
857 rc = cifs_entry_is_dot(pfindEntry,pCifsF); 843 rc = cifs_entry_is_dot(pfindEntry,pCifsF);
858 /* skip . and .. since we added them first */ 844 /* skip . and .. since we added them first */
859 if(rc != 0) 845 if(rc != 0)
@@ -997,11 +983,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
997 983
998 xid = GetXid(); 984 xid = GetXid();
999 985
1000 if(file->f_path.dentry == NULL) {
1001 FreeXid(xid);
1002 return -EIO;
1003 }
1004
1005 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 986 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1006 pTcon = cifs_sb->tcon; 987 pTcon = cifs_sb->tcon;
1007 if(pTcon == NULL) 988 if(pTcon == NULL)