static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir, void *direntry, char *scratch_buf, int max_len) { int rc = 0; struct qstr qstring; struct cifsFileInfo *pCifsF; unsigned int obj_type; __u64 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 */ if ((direntry == NULL) || (file == NULL)) return -EINVAL; pCifsF = file->private_data; if ((scratch_buf == NULL) || (pfindEntry == NULL) || (pCifsF == NULL)) return -ENOENT; rc = cifs_entry_is_dot(pfindEntry, pCifsF); /* skip . and .. since we added them first */ if (rc != 0) return 0; cifs_sb = CIFS_SB(file->f_path.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, max_len, &inum /* returned */); if (rc) return rc; /* only these two infolevels return valid inode numbers */ if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX || pCifsF->srch_inf.info_level == SMB_FIND_FILE_ID_FULL_DIR_INFO) rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry, &inum); else rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry, NULL); if ((tmp_inode == NULL) || (tmp_dentry == NULL)) return -ENOMEM; /* we pass in rc below, indicating whether it is a new inode, so we can figure out whether to invalidate the inode cached data if the file has changed */ if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX) unix_fill_in_inode(tmp_inode, (FILE_UNIX_INFO *)pfindEntry, &obj_type, rc); else if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) fill_in_inode(tmp_inode, 0 /* old level 1 buffer type */, pfindEntry, &obj_type, rc); else fill_in_inode(tmp_inode, 1 /* NT */, pfindEntry, &obj_type, rc); if (rc) /* new inode - needs to be tied to dentry */ { d_instantiate(tmp_dentry, tmp_inode); if (rc == 2) d_rehash(tmp_dentry); } rc = filldir(direntry, qstring.name, qstring.len, file->f_pos, tmp_inode->i_ino, obj_type); if (rc) { cFYI(1, ("filldir rc = %d", rc)); /* we can not return filldir errors to the caller since they are "normal" when the stat blocksize is too small - we return remapped error instead */ rc = -EOVERFLOW; } dput(tmp_dentry); return rc; }
static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir, void *direntry, char *scratch_buf) { int rc = 0; struct qstr qstring; struct cifsFileInfo * pCifsF; 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 */ if((direntry == NULL) || (file == NULL)) return -EINVAL; pCifsF = file->private_data; if((scratch_buf == NULL) || (pfindEntry == NULL) || (pCifsF == NULL)) return -ENOENT; if(file->f_dentry == NULL) return -ENOENT; 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, &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); } /* we pass in rc below, indicating whether it is a new inode, so we can figure out whether to invalidate the inode cached data if the file has changed */ if(pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX) { unix_fill_in_inode(tmp_inode, (FILE_UNIX_INFO *)pfindEntry,&obj_type, rc); } else { fill_in_inode(tmp_inode, (FILE_DIRECTORY_INFO *)pfindEntry,&obj_type, rc); } rc = filldir(direntry,qstring.name,qstring.len,file->f_pos,tmp_inode->i_ino,obj_type); if(rc) { cFYI(1,("filldir rc = %d",rc)); } dput(tmp_dentry); return rc; }