Commit 61dd271d authored by Steve French's avatar Steve French Committed by Steve French

[CIFS] cifs readdir part 11. Also renames unused /proc/fs/cifs/QuotaEnabled...

[CIFS] cifs readdir part 11.  Also renames unused /proc/fs/cifs/QuotaEnabled config switch to NewReaddirEnabled for turning on testing of new readdir code

Signed-off-by: Steve French (sfrench@us.ibm.com)
parent b1fb0b05
......@@ -337,7 +337,7 @@ cifs_proc_init(void)
if (pde)
pde->write_proc = oplockEnabled_write;
pde = create_proc_read_entry("QuotaEnabled", 0, proc_fs_cifs,
pde = create_proc_read_entry("NewReaddirEnabled", 0, proc_fs_cifs,
quotaEnabled_read, NULL);
if (pde)
pde->write_proc = quotaEnabled_write;
......@@ -396,7 +396,7 @@ cifs_proc_clean(void)
remove_proc_entry("ExtendedSecurity",proc_fs_cifs);
remove_proc_entry("PacketSigningEnabled",proc_fs_cifs);
remove_proc_entry("LinuxExtensionsEnabled",proc_fs_cifs);
remove_proc_entry("QuotaEnabled",proc_fs_cifs);
remove_proc_entry("NewReaddirEnabled",proc_fs_cifs);
remove_proc_entry("LookupCacheEnabled",proc_fs_cifs);
remove_proc_entry("cifs", proc_root_fs);
}
......@@ -485,7 +485,7 @@ quotaEnabled_read(char *page, char **start, off_t off,
{
int len;
len = sprintf(page, "%d\n", quotaEnabled);
len = sprintf(page, "%d\n", experimEnabled);
/* could also check if quotas are enabled in kernel
as a whole first */
len -= off;
......@@ -512,9 +512,9 @@ quotaEnabled_write(struct file *file, const char __user *buffer,
if (rc)
return rc;
if (c == '0' || c == 'n' || c == 'N')
quotaEnabled = 0;
experimEnabled = 0;
else if (c == '1' || c == 'y' || c == 'Y')
quotaEnabled = 1;
experimEnabled = 1;
return count;
}
......
......@@ -50,7 +50,7 @@ int cifsFYI = 0;
int cifsERROR = 1;
int traceSMB = 0;
unsigned int oplockEnabled = 1;
unsigned int quotaEnabled = 0;
unsigned int experimEnabled = 0;
unsigned int linuxExtEnabled = 1;
unsigned int lookupCacheEnabled = 1;
unsigned int multiuser_mount = 0;
......
......@@ -243,7 +243,7 @@ struct cifsLockInfo {
struct cifs_search_info {
loff_t index_of_last_entry;
__u16 entries_in_buffer;
unsigned info_level;
__u16 info_level;
char * ntwrk_buf_start;
char * srch_entries_start;
unsigned endOfSearch:1;
......@@ -418,7 +418,7 @@ GLOBAL_EXTERN unsigned int multiuser_mount; /* if enabled allows new sessions
have the uid/password or Kerberos credential
or equivalent for current user */
GLOBAL_EXTERN unsigned int oplockEnabled;
GLOBAL_EXTERN unsigned int quotaEnabled;
GLOBAL_EXTERN unsigned int experimEnabled;
GLOBAL_EXTERN unsigned int lookupCacheEnabled;
GLOBAL_EXTERN unsigned int extended_security; /* if on, session setup sent
with more secure ntlmssp2 challenge/resp */
......
......@@ -2096,7 +2096,6 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
return rc;
}
#ifdef CIFS_EXPERIMENTAL
/* xid, tcon, searchName and codepage are input parms, rest are returned */
int
CIFSFindFirst2(const int xid, struct cifsTconInfo *tcon,
......@@ -2166,16 +2165,8 @@ CIFSFindFirst2(const int xid, struct cifsTconInfo *tcon,
pSMB->SearchCount= cpu_to_le16(CIFS_MAX_MSGSIZE/sizeof(FILE_UNIX_INFO));
pSMB->SearchFlags = cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END |
CIFS_SEARCH_RETURN_RESUME);
pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
/* test for Unix extensions */
if (tcon->ses->capabilities & CAP_UNIX) {
pSMB->InformationLevel = cpu_to_le16(SMB_FIND_FILE_UNIX);
psrch_inf->info_level = SMB_FIND_FILE_UNIX;
} else {
pSMB->InformationLevel =
cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO);
psrch_inf->info_level = SMB_FIND_FILE_DIRECTORY_INFO;
}
/* BB what should we set StorageType to? Does it matter? BB */
pSMB->SearchStorageType = 0;
pSMB->hdr.smb_buf_length += byte_count;
......@@ -2271,14 +2262,15 @@ int CIFSFindNext2(const int xid, struct cifsTconInfo *tcon,
pSMB->SearchCount =
cpu_to_le16(CIFS_MAX_MSGSIZE / sizeof (FILE_UNIX_INFO));
/* test for Unix extensions */
if (tcon->ses->capabilities & CAP_UNIX) {
/* if (tcon->ses->capabilities & CAP_UNIX) {
pSMB->InformationLevel = cpu_to_le16(SMB_FIND_FILE_UNIX);
psrch_inf->info_level = SMB_FIND_FILE_UNIX;
} else {
pSMB->InformationLevel =
cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO);
psrch_inf->info_level = SMB_FIND_FILE_DIRECTORY_INFO;
}
} */
pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
pSMB->ResumeKey = 0; /* BB fixme add resume_key BB */
pSMB->SearchFlags =
cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME);
......@@ -2345,8 +2337,6 @@ int CIFSFindNext2(const int xid, struct cifsTconInfo *tcon,
return rc;
}
#endif /* CIFS_EXPERIMENTAL */
int
CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
FILE_DIRECTORY_INFO * findData, T2_FNEXT_RSP_PARMS * findParms,
......
......@@ -35,6 +35,8 @@
#include "cifs_debug.h"
#include "cifs_fs_sb.h"
extern int cifs_readdir2(struct file *file, void *direntry, filldir_t filldir); /* BB removeme BB */
int
cifs_open(struct inode *inode, struct file *file)
{
......@@ -452,20 +454,44 @@ cifs_closedir(struct inode *inode, struct file *file)
{
int rc = 0;
int xid;
struct cifsFileInfo *pSMBFileStruct =
struct cifsFileInfo *pCFileStruct =
(struct cifsFileInfo *) file->private_data;
char * ptmp;
cFYI(1, ("Closedir inode = 0x%p with ", inode));
xid = GetXid();
/* BB add code to close search if not end of search BB */
if (pCFileStruct) {
struct cifsTconInfo *pTcon;
struct cifs_sb_info * cifs_sb = CIFS_SB(file->f_dentry->d_sb);
pTcon = cifs_sb->tcon;
if (pSMBFileStruct) {
cFYI(1, ("Freeing private data in close dir"));
if(pCFileStruct->srch_inf.endOfSearch == FALSE) {
pCFileStruct->invalidHandle = TRUE;
rc = CIFSFindClose(xid, pTcon, pCFileStruct->netfid);
cFYI(1,("Closing uncompleted readdir with rc %d",rc));
/* not much we can do if it fails anywway, ignore rc */
rc = 0;
}
ptmp = pCFileStruct->srch_inf.ntwrk_buf_start;
if(ptmp) {
cFYI(1,("freeing smb buf in srch struct in closedir")); /* BB removeme BB */
pCFileStruct->srch_inf.ntwrk_buf_start = NULL;
cifs_buf_release(ptmp);
}
ptmp = pCFileStruct->search_resume_name;
if(ptmp) {
cFYI(1,("freeing resume name in closedir")); /* BB removeme BB */
pCFileStruct->search_resume_name = NULL;
kfree(ptmp);
}
kfree(file->private_data);
file->private_data = NULL;
}
/* BB can we lock the filestruct while this is going on? */
FreeXid(xid);
return rc;
}
......@@ -1519,7 +1545,7 @@ unix_fill_in_inode(struct inode *tmp_inode,
/* Returns one if new inode created (which therefore needs to be hashed) */
/* Might check in the future if inode number changed so we can rehash inode */
static int
int
construct_dentry(struct qstr *qstring, struct file *file,
struct inode **ptmp_inode, struct dentry **pnew_dentry)
{
......@@ -1696,6 +1722,13 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
FILE_DIRECTORY_INFO *lastFindData;
FILE_UNIX_INFO *pfindDataUnix;
/* BB removeme begin */
if(experimEnabled)
return cifs_readdir2(file,direntry,filldir);
/* BB removeme end */
xid = GetXid();
if(file->f_dentry == NULL) {
......
......@@ -30,7 +30,6 @@
#include "cifs_debug.h"
#include "cifs_fs_sb.h"
#ifdef CIFS_EXPERIMENTAL
extern int CIFSFindFirst2(const int xid, struct cifsTconInfo *tcon,
const char *searchName, const struct nls_table *nls_codepage,
__u16 *searchHandle, struct cifs_search_info * psrch_inf);
......@@ -38,10 +37,44 @@ extern int CIFSFindFirst2(const int xid, struct cifsTconInfo *tcon,
extern int CIFSFindNext2(const int xid, struct cifsTconInfo *tcon,
__u16 searchHandle, struct cifs_search_info * psrch_inf);
extern int construct_dentry(struct qstr *qstring, struct file *file,
struct inode **ptmp_inode, struct dentry **pnew_dentry);
static int initiate_cifs_search(const int xid, struct file * file, char * full_path)
extern void fill_in_inode(struct inode *tmp_inode,
FILE_DIRECTORY_INFO * pfindData, int *pobject_type);
extern void unix_fill_in_inode(struct inode *tmp_inode,
FILE_UNIX_INFO * pfindData, int *pobject_type);
/* BB fixme - add debug wrappers around this function to disable it fixme BB */
/* static void dump_cifs_file_struct(struct file * file, char * label)
{
struct cifsFileInfo * cf;
if(file) {
cf = (struct cifsFileInfo *)file->private_data;
if(cf == NULL) {
cFYI(1,("empty cifs private file data"));
return;
}
if(cf->invalidHandle) {
cFYI(1,("invalid handle"));
}
if(cf->srch_inf.endOfSearch) {
cFYI(1,("end of search"));
}
if(cf->srch_inf.emptyDir) {
cFYI(1,("empty dir"));
}
}
} */
static int initiate_cifs_search(const int xid, struct file * file)
{
int rc = 0;
char * full_path;
struct cifsFileInfo * cifsFile;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
......@@ -49,14 +82,13 @@ static int initiate_cifs_search(const int xid, struct file * file, char * full_p
if(file->private_data == NULL) {
file->private_data =
kmalloc(sizeof(struct cifsFileInfo),GFP_KERNEL);
}
if(file->private_data == NULL) {
return -ENOMEM;
} else {
memset(file->private_data,0,sizeof(struct cifsFileInfo));
}
if(file->private_data == NULL) {
return -ENOMEM;
} else {
memset(file->private_data,0,sizeof(struct cifsFileInfo));
}
/* if not end of search do we have to close it first? */
cifsFile = (struct cifsFileInfo *)file->private_data;
cifsFile->invalidHandle = TRUE;
......@@ -68,9 +100,32 @@ static int initiate_cifs_search(const int xid, struct file * file, char * full_p
if(pTcon == NULL)
return -EINVAL;
if(file->f_dentry == NULL)
return -ENOENT;
down(&file->f_dentry->d_sb->s_vfs_rename_sem);
full_path = build_wildcard_path_from_dentry(file->f_dentry);
up(&file->f_dentry->d_sb->s_vfs_rename_sem);
if(full_path == NULL) {
return -ENOMEM;
}
cFYI(1, ("Full path: %s start at: %lld ", full_path, file->f_pos));
/* test for Unix extensions */
if (pTcon->ses->capabilities & CAP_UNIX) {
cifsFile->srch_inf.info_level = SMB_FIND_FILE_UNIX;
} else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
cifsFile->srch_inf.info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO;
} else /* not srvinos - BB fixme add check for backlevel? */ {
cifsFile->srch_inf.info_level = SMB_FIND_FILE_DIRECTORY_INFO;
}
rc = CIFSFindFirst2(xid, pTcon,full_path,cifs_sb->local_nls,
&cifsFile->netfid, &cifsFile->srch_inf);
cFYI(1,("search initiated with rc %d num entries %d",rc,cifsFile->srch_inf.entries_in_buffer));
if(full_path)
kfree(full_path);
return rc;
}
......@@ -94,9 +149,10 @@ static char * nxt_dir_entry(char * old_entry, char * end_of_smb)
FILE_DIRECTORY_INFO * pDirInfo = (FILE_DIRECTORY_INFO *)old_entry;
new_entry = old_entry + pDirInfo->NextEntryOffset;
cFYI(1,("new entry %p old entry %p",new_entry,old_entry));
/* validate that new_entry is not past end of SMB */
if(new_entry >= end_of_smb) {
cERROR(1,("search entry began after end of SMB"));
cFYI(1,("search entry %p began after end of SMB %p old entry is %p",new_entry,end_of_smb,old_entry)); /* BB removeme BB */
return NULL;
} else
return new_entry;
......@@ -179,43 +235,63 @@ static int cifs_entry_is_dot(char * current_entry, struct cifsFileInfo * cfile)
/* We start counting in the buffer with entry 2 and increment for every
entry (do not increment for . or .. entry) */
static int find_cifs_entry(const int xid, struct cifsTconInfo * pTcon,
const loff_t index_to_find, struct cifsFileInfo * cifsFile,
char ** ppCurrentEntry,int * num_to_ret)
struct file * file, char ** ppCurrentEntry,int * num_to_ret)
{
int rc = 0;
int pos_in_buf = 0;
loff_t first_entry_in_buffer;
loff_t index_to_find = file->f_pos;
struct cifsFileInfo * cifsFile = (struct cifsFileInfo *)file->private_data;
/* check if index in the buffer */
if((cifsFile == NULL) || (ppCurrentEntry == NULL) || (num_to_ret == NULL))
return -ENOENT;
*ppCurrentEntry = NULL;
first_entry_in_buffer =
cifsFile->srch_inf.index_of_last_entry -
cifsFile->srch_inf.entries_in_buffer;
/* dump_cifs_file_struct(file, "In fce ");*/
if(index_to_find < first_entry_in_buffer) {
/* close and restart search */
/* after restart first_entry_in_buffer = 0 */
cFYI(1,("search backing up - close and restart search"));
cifsFile->invalidHandle = TRUE;
CIFSFindClose(xid, pTcon, cifsFile->netfid);
if(cifsFile->search_resume_name) {
kfree(cifsFile->search_resume_name);
cifsFile->search_resume_name = NULL;
}
if(cifsFile->srch_inf.ntwrk_buf_start) {
cFYI(1,("freeing SMB ff cache buf on search rewind")); /* BB removeme BB */
cifs_buf_release(cifsFile->srch_inf.ntwrk_buf_start);
}
rc = initiate_cifs_search(xid,file);
if(rc) {
cFYI(1,("error %d reinitiating a search on rewind",rc));
return rc;
}
}
while((index_to_find > cifsFile->srch_inf.index_of_last_entry) &&
if(cifsFile->srch_inf.endOfSearch) {
cFYI(1,("end of search")); /* BB removeme BB */
}
while((index_to_find >= cifsFile->srch_inf.index_of_last_entry) &&
(rc == 0) && (cifsFile->srch_inf.endOfSearch == FALSE)){
cFYI(1,("calling findnext2"));
rc = CIFSFindNext2(xid,pTcon,cifsFile->netfid, &cifsFile->srch_inf);
}
if(index_to_find <= cifsFile->srch_inf.index_of_last_entry) {
if(index_to_find < cifsFile->srch_inf.index_of_last_entry) {
/* we found the buffer that contains the entry */
/* scan and find it */
int i;
char * current_entry;
char * end_of_smb = cifsFile->srch_inf.ntwrk_buf_start +
smbCalcSize((struct smb_hdr *)cifsFile->srch_inf.ntwrk_buf_start);
/* dump_cifs_file_struct(file,"found entry in fce "); */
first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry -
cifsFile->srch_inf.entries_in_buffer;
pos_in_buf = index_to_find - first_entry_in_buffer;
cFYI(1,("found entry - pos_in_buf %d",pos_in_buf)); /* BB removeme BB */
current_entry = cifsFile->srch_inf.srch_entries_start;
for(i=0;(i<(pos_in_buf)) && (current_entry != NULL);i++) {
/* go entry to next entry figuring out which we need to start with */
......@@ -224,83 +300,74 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo * pTcon,
rc = cifs_entry_is_dot(current_entry,cifsFile);
if(rc == 1) /* is . or .. so skip */ {
cFYI(1,("Entry is .")); /* BB removeme BB */
continue;
/* continue; */
} else if (rc == 2 ) {
cFYI(1,("Entry is ..")); /* BB removeme BB */
continue;
/* continue; */
}
current_entry = nxt_dir_entry(current_entry,end_of_smb);
}
if((current_entry == NULL) && (i < pos_in_buf)) {
cERROR(1,("reached end of buf searching for pos in buf %d index to find %lld rc %d",pos_in_buf,index_to_find,rc)); /* BB removeme BB */
}
rc = 0;
*ppCurrentEntry = current_entry;
} else {
cFYI(1,("index not in buffer - could not findnext into it"));
return -ENOENT; /* BB fixme - return 0? */
}
if(pos_in_buf > cifsFile->srch_inf.entries_in_buffer) {
if(pos_in_buf >= cifsFile->srch_inf.entries_in_buffer) {
cFYI(1,("can not return entries when pos_in_buf beyond last entry"));
*num_to_ret = 0;
} else
*num_to_ret = cifsFile->srch_inf.entries_in_buffer - pos_in_buf;
/* dump_cifs_file_struct(file, "end fce ");*/
return rc;
}
/* inode num, inode type and filename returned */
static int cifs_get_name_from_search_buf(struct qstr * pqst,char * current_entry,
__u16 level,unsigned int unicode,struct nls_table * nlt,
ino_t * pinum, unsigned * pobject_type)
ino_t * pinum)
{
int rc = 0;
unsigned int len = 0;
char * filename;
*pinum = 11; /* BB removeme BB */
*pinum = 0;
if(level == 0x202) {
if(level == SMB_FIND_FILE_UNIX) {
FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry;
__u32 type;
filename = &pFindData->FileName[0];
if(unicode) {
len = cifs_unicode_bytelen(filename);
} else {
/* BB should we make this strnlen of PATH_MAX? */
len = strnlen(filename, 5);
len = strnlen(filename, PATH_MAX);
}
/* BB fixme - hash low and high 32 bits if not 64 bit arch BB fixme */
*pinum = pFindData->UniqueId;
type=le32_to_cpu(pFindData->Type);
if (type == UNIX_FILE) {
*pobject_type = DT_REG;
} else if (type == UNIX_SYMLINK) {
*pobject_type = DT_LNK;
} else if (type == UNIX_DIR) {
*pobject_type = DT_DIR;
} else if (type == UNIX_CHARDEV) {
*pobject_type = DT_CHR;
} else if (type == UNIX_BLOCKDEV) {
*pobject_type = DT_BLK;
} else if (type == UNIX_FIFO) {
*pobject_type = DT_FIFO;
} else if (type == UNIX_SOCKET) {
*pobject_type = DT_SOCK;
}
} else if(level == 0x101) {
} else if(level == SMB_FIND_FILE_DIRECTORY_INFO) {
FILE_DIRECTORY_INFO * pFindData =
(FILE_DIRECTORY_INFO *)current_entry;
filename = &pFindData->FileName[0];
len = pFindData->FileNameLength;
} else if(level == 0x102) {
} else if(level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
FILE_FULL_DIRECTORY_INFO * pFindData =
(FILE_FULL_DIRECTORY_INFO *)current_entry;
filename = &pFindData->FileName[0];
len = pFindData->FileNameLength;
} else if(level == 0x105) {
} else if(level == SMB_FIND_FILE_ID_FULL_DIR_INFO) {
SEARCH_ID_FULL_DIR_INFO * pFindData =
(SEARCH_ID_FULL_DIR_INFO *)current_entry;
filename = &pFindData->FileName[0];
len = pFindData->FileNameLength;
} else if(level == 0x104) {
*pinum = pFindData->UniqueId;
} else if(level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
FILE_BOTH_DIRECTORY_INFO * pFindData =
(FILE_BOTH_DIRECTORY_INFO *)current_entry;
filename = &pFindData->FileName[0];
......@@ -309,12 +376,13 @@ static int cifs_get_name_from_search_buf(struct qstr * pqst,char * current_entry
cFYI(1,("Unknown findfirst level %d",level));
return -EINVAL;
}
pqst->len = len;
if(unicode) {
/* BB fixme - test with long names */
cifs_strfromUCS_le((char *)pqst->name,(wchar_t *)filename,NAME_MAX,nlt);
/* Note converted filename can be longer than in unicode */
pqst->len = cifs_strfromUCS_le((char *)pqst->name,(wchar_t *)filename,len/2,nlt);
} else {
pqst->name = filename;
pqst->len = len;
}
pqst->hash = full_name_hash(pqst->name,pqst->len);
cFYI(1,("filldir on %s",pqst->name)); /* BB removeme BB */
......@@ -332,6 +400,9 @@ cifs_filldir2(char * pfindEntry, struct file *file,
unsigned obj_type;
ino_t inum;
struct cifs_sb_info * cifs_sb;
struct inode *tmp_inode;
struct dentry *tmp_dentry;
/* get filename and len into qstring */
/* get dentry */
/* decide whether to create and populate ionde */
......@@ -348,18 +419,39 @@ cifs_filldir2(char * pfindEntry, struct file *file,
cifs_sb = CIFS_SB(file->f_dentry->d_sb);
qstring.name = scratch_buf;
rc = cifs_get_name_from_search_buf(&qstring,pfindEntry,
pCifsF->srch_inf.info_level,
pCifsF->srch_inf.unicode,cifs_sb->local_nls,
&inum /* returned */,&obj_type /* returned */);
&inum /* returned */);
if(rc)
return rc;
rc = construct_dentry(&qstring,file,&tmp_inode, &tmp_dentry);
if((tmp_inode == NULL) || (tmp_dentry == NULL))
return -ENOMEM;
if(rc) {
/* inode created, we need to hash it with right inode number */
if(inum != 0) {
/* BB fixme - hash the 2 32 quantities bits together if necessary BB */
tmp_inode->i_ino = inum;
}
insert_inode_hash(tmp_inode);
}
if(pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX) {
unix_fill_in_inode(tmp_inode,(FILE_UNIX_INFO *)pfindEntry,&obj_type);
} else {
fill_in_inode(tmp_inode,(FILE_DIRECTORY_INFO *)pfindEntry,&obj_type);
}
rc = filldir(direntry,qstring.name,qstring.len,file->f_pos,inum,obj_type);
if(rc) {
cFYI(1,("filldir rc = %d",rc));
}
dput(tmp_dentry);
return rc;
}
......@@ -371,45 +463,25 @@ int cifs_readdir2(struct file *file, void *direntry, filldir_t filldir)
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
struct cifsFileInfo *cifsFile = NULL;
char *full_path = NULL;
char * current_entry;
int num_to_fill = 0;
char * tmp_buf = NULL;
char * end_of_smb;
/* int Unicode = FALSE;
int UnixSearch = FALSE;
unsigned int bufsize, i;
__u16 searchHandle;
char *data;
struct qstr qstring;
T2_FFIRST_RSP_PARMS findParms;
T2_FNEXT_RSP_PARMS findNextParms;
FILE_DIRECTORY_INFO *pfindData;
FILE_DIRECTORY_INFO *lastFindData;
FILE_UNIX_INFO *pfindDataUnix;*/
xid = GetXid();
if(file->f_dentry == NULL) {
FreeXid(xid);
return -EIO;
}
/* dump_cifs_file_struct(file, "Begin rdir "); */
cifs_sb = CIFS_SB(file->f_dentry->d_sb);
pTcon = cifs_sb->tcon;
if(pTcon == NULL)
return -EINVAL;
down(&file->f_dentry->d_sb->s_vfs_rename_sem);
full_path = build_wildcard_path_from_dentry(file->f_dentry);
up(&file->f_dentry->d_sb->s_vfs_rename_sem);
if(full_path == NULL) {
FreeXid(xid);
return -ENOMEM;
}
cFYI(1, ("Full path: %s start at: %lld ", full_path, file->f_pos));
cFYI(1,("readdir2 pos: %lld",file->f_pos)); /* BB removeme BB */
switch ((int) file->f_pos) {
case 0:
......@@ -435,16 +507,19 @@ int cifs_readdir2(struct file *file, void *direntry, filldir_t filldir)
if after then keep searching till find it */
if(file->private_data == NULL) {
rc = initiate_cifs_search(xid,file,full_path);
rc = initiate_cifs_search(xid,file);
cFYI(1,("initiate cifs search rc %d",rc));
if(rc || (file->private_data == NULL)) {
if(rc) {
FreeXid(xid);
if(full_path)
kfree(full_path);
return rc;
}
}
default:
if(file->private_data == NULL) {
rc = -EINVAL;
FreeXid(xid);
return rc;
}
cifsFile = (struct cifsFileInfo *) file->private_data;
if (cifsFile->srch_inf.endOfSearch) {
if(cifsFile->srch_inf.emptyDir) {
......@@ -461,21 +536,44 @@ int cifs_readdir2(struct file *file, void *direntry, filldir_t filldir)
cifsFile->search_resume_name = NULL;
} */
/* BB account for . and .. in f_pos */
rc = find_cifs_entry(xid,pTcon, file->f_pos, cifsFile,&current_entry,&num_to_fill);
if(rc)
/* dump_cifs_file_struct(file, "rdir after default ");*/
rc = find_cifs_entry(xid,pTcon, file,
&current_entry,&num_to_fill);
if(rc) {
cFYI(1,("fce error %d",rc)); /* BB removeme BB */
goto rddir2_exit;
} else {
cFYI(1,("entry %lld found",file->f_pos));
}
if(current_entry == NULL) {
cERROR(1,("current search entry null,exiting"));
goto rddir2_exit;
}
/* 2) initiate search, */
/* 3) seek into search buffer */
/* 4) if not found && later - FindNext */
/* else if earlier in search, close search and
restart, continuing search till found or EndOfSearch */
cFYI(1,("loop through %d times filling dir",num_to_fill)); /* BB removeme BB */
cFYI(1,("loop through %d times filling dir for net buf start %p",num_to_fill,cifsFile->srch_inf.ntwrk_buf_start)); /* BB removeme BB */
end_of_smb = cifsFile->srch_inf.ntwrk_buf_start +
smbCalcSize((struct smb_hdr *)cifsFile->srch_inf.ntwrk_buf_start);
tmp_buf = kmalloc(NAME_MAX+1,GFP_KERNEL);
cFYI(1,("end of smb %p and tmp_buf %p current_entry %p",end_of_smb,tmp_buf,current_entry)); /* BB removeme BB */
for(i=0;(i<num_to_fill) && (rc == 0);i++) {
if(current_entry == NULL)
if(current_entry == NULL) {
cERROR(1,("beyond end of smb with num to fill %d i %d",num_to_fill,i)); /* BB removeme BB */
break;
}
/* if((!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) ||
(cifsFile->srch_inf.info_level != something that supports server inodes)) {
create dentry
create inode
fill in inode new_inode (which makes number locally)
}
also create local inode for per reasons unless new mount parm says otherwise */
rc = cifs_filldir2(current_entry, file,
filldir, direntry,tmp_buf);
file->f_pos++;
......@@ -484,16 +582,11 @@ int cifs_readdir2(struct file *file, void *direntry, filldir_t filldir)
if(tmp_buf != NULL)
kfree(tmp_buf);
break;
default:
cFYI(1,("default case - exiting")); /* BB fixme BB */
rc = 0;
} /* end switch */
rddir2_exit:
if (full_path)
kfree(full_path);
/* dump_cifs_file_struct(file, "end rdir "); */
FreeXid(xid);
return rc;
}
#endif /* CIFS_EXPERIMENTAL */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment