|
@@ -590,6 +590,13 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
|
|
first_entry_in_buffer =
|
|
first_entry_in_buffer =
|
|
cifsFile->srch_inf.index_of_last_entry -
|
|
cifsFile->srch_inf.index_of_last_entry -
|
|
cifsFile->srch_inf.entries_in_buffer;
|
|
cifsFile->srch_inf.entries_in_buffer;
|
|
|
|
+
|
|
|
|
+ /* if first entry in buf is zero then is first buffer
|
|
|
|
+ in search response data which means it is likely . and ..
|
|
|
|
+ will be in this buffer, although some servers do not return
|
|
|
|
+ . and .. for the root of a drive and for those we need
|
|
|
|
+ to start two entries earlier */
|
|
|
|
+
|
|
/* dump_cifs_file_struct(file, "In fce ");*/
|
|
/* dump_cifs_file_struct(file, "In fce ");*/
|
|
if(((index_to_find < cifsFile->srch_inf.index_of_last_entry) &&
|
|
if(((index_to_find < cifsFile->srch_inf.index_of_last_entry) &&
|
|
is_dir_changed(file)) ||
|
|
is_dir_changed(file)) ||
|
|
@@ -632,23 +639,14 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
|
|
char * end_of_smb = cifsFile->srch_inf.ntwrk_buf_start +
|
|
char * end_of_smb = cifsFile->srch_inf.ntwrk_buf_start +
|
|
smbCalcSize((struct smb_hdr *)
|
|
smbCalcSize((struct smb_hdr *)
|
|
cifsFile->srch_inf.ntwrk_buf_start);
|
|
cifsFile->srch_inf.ntwrk_buf_start);
|
|
|
|
+
|
|
|
|
+ current_entry = cifsFile->srch_inf.srch_entries_start;
|
|
first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry
|
|
first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry
|
|
- cifsFile->srch_inf.entries_in_buffer;
|
|
- cifsFile->srch_inf.entries_in_buffer;
|
|
pos_in_buf = index_to_find - first_entry_in_buffer;
|
|
pos_in_buf = index_to_find - first_entry_in_buffer;
|
|
cFYI(1,("found entry - pos_in_buf %d",pos_in_buf));
|
|
cFYI(1,("found entry - pos_in_buf %d",pos_in_buf));
|
|
- current_entry = cifsFile->srch_inf.srch_entries_start;
|
|
|
|
for(i=0;(i<(pos_in_buf)) && (current_entry != NULL);i++) {
|
|
for(i=0;(i<(pos_in_buf)) && (current_entry != NULL);i++) {
|
|
/* go entry by entry figuring out which is first */
|
|
/* go entry by entry figuring out which is first */
|
|
- /* if( . or ..)
|
|
|
|
- skip */
|
|
|
|
- rc = cifs_entry_is_dot(current_entry,cifsFile);
|
|
|
|
- if(rc == 1) /* is . or .. so skip */ {
|
|
|
|
- cFYI(1,("Entry is .")); /* BB removeme BB */
|
|
|
|
- /* continue; */
|
|
|
|
- } else if (rc == 2 ) {
|
|
|
|
- cFYI(1,("Entry is ..")); /* BB removeme BB */
|
|
|
|
- /* continue; */
|
|
|
|
- }
|
|
|
|
current_entry = nxt_dir_entry(current_entry,end_of_smb);
|
|
current_entry = nxt_dir_entry(current_entry,end_of_smb);
|
|
}
|
|
}
|
|
if((current_entry == NULL) && (i < pos_in_buf)) {
|
|
if((current_entry == NULL) && (i < pos_in_buf)) {
|
|
@@ -768,6 +766,11 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
|
|
if(file->f_dentry == NULL)
|
|
if(file->f_dentry == NULL)
|
|
return -ENOENT;
|
|
return -ENOENT;
|
|
|
|
|
|
|
|
+ rc = cifs_entry_is_dot(pfindEntry,cifsF);
|
|
|
|
+ /* skip . and .. since we added them first */
|
|
|
|
+ if(rc != 0)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
cifs_sb = CIFS_SB(file->f_dentry->d_sb);
|
|
cifs_sb = CIFS_SB(file->f_dentry->d_sb);
|
|
|
|
|
|
qstring.name = scratch_buf;
|
|
qstring.name = scratch_buf;
|
|
@@ -896,22 +899,22 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
|
|
|
|
|
|
switch ((int) file->f_pos) {
|
|
switch ((int) file->f_pos) {
|
|
case 0:
|
|
case 0:
|
|
- /*if (filldir(direntry, ".", 1, file->f_pos,
|
|
|
|
|
|
+ if (filldir(direntry, ".", 1, file->f_pos,
|
|
file->f_dentry->d_inode->i_ino, DT_DIR) < 0) {
|
|
file->f_dentry->d_inode->i_ino, DT_DIR) < 0) {
|
|
- cERROR(1, ("Filldir for current dir failed "));
|
|
|
|
|
|
+ cERROR(1, ("Filldir for current dir failed"));
|
|
rc = -ENOMEM;
|
|
rc = -ENOMEM;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- file->f_pos++; */
|
|
|
|
|
|
+ file->f_pos++;
|
|
case 1:
|
|
case 1:
|
|
- /* if (filldir(direntry, "..", 2, file->f_pos,
|
|
|
|
|
|
+ if (filldir(direntry, "..", 2, file->f_pos,
|
|
file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) {
|
|
file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) {
|
|
cERROR(1, ("Filldir for parent dir failed "));
|
|
cERROR(1, ("Filldir for parent dir failed "));
|
|
rc = -ENOMEM;
|
|
rc = -ENOMEM;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- file->f_pos++; */
|
|
|
|
- case 2:
|
|
|
|
|
|
+ file->f_pos++;
|
|
|
|
+ default:
|
|
/* 1) If search is active,
|
|
/* 1) If search is active,
|
|
is in current search buffer?
|
|
is in current search buffer?
|
|
if it before then restart search
|
|
if it before then restart search
|
|
@@ -925,7 +928,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- default:
|
|
|
|
if(file->private_data == NULL) {
|
|
if(file->private_data == NULL) {
|
|
rc = -EINVAL;
|
|
rc = -EINVAL;
|
|
FreeXid(xid);
|
|
FreeXid(xid);
|
|
@@ -945,8 +947,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
|
|
kfree(cifsFile->search_resume_name);
|
|
kfree(cifsFile->search_resume_name);
|
|
cifsFile->search_resume_name = NULL; */
|
|
cifsFile->search_resume_name = NULL; */
|
|
|
|
|
|
- /* BB account for . and .. in f_pos as special case */
|
|
|
|
-
|
|
|
|
rc = find_cifs_entry(xid,pTcon, file,
|
|
rc = find_cifs_entry(xid,pTcon, file,
|
|
¤t_entry,&num_to_fill);
|
|
¤t_entry,&num_to_fill);
|
|
if(rc) {
|
|
if(rc) {
|
|
@@ -975,7 +975,8 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
|
|
num_to_fill, i));
|
|
num_to_fill, i));
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+ /* if buggy server returns . and .. late do
|
|
|
|
+ we want to check for that here? */
|
|
rc = cifs_filldir(current_entry, file,
|
|
rc = cifs_filldir(current_entry, file,
|
|
filldir, direntry,tmp_buf);
|
|
filldir, direntry,tmp_buf);
|
|
file->f_pos++;
|
|
file->f_pos++;
|