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; }
static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir, void *direntry, char *scratch_buf, unsigned int max_len) { int rc = 0; struct qstr qstring; struct cifsFileInfo *pCifsF; u64 inum; ino_t ino; struct super_block *sb; struct cifs_sb_info *cifs_sb; struct dentry *tmp_dentry; struct cifs_fattr fattr; /* 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; sb = file->f_path.dentry->d_sb; cifs_sb = CIFS_SB(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; if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX) cifs_unix_basic_to_fattr(&fattr, &((FILE_UNIX_INFO *) pfindEntry)->basic, cifs_sb); else if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) cifs_std_info_to_fattr(&fattr, (FIND_FILE_STANDARD_INFO *) pfindEntry, cifs_sb); else cifs_dir_info_to_fattr(&fattr, (FILE_DIRECTORY_INFO *) pfindEntry, cifs_sb); if (inum && (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) { fattr.cf_uniqueid = inum; } else { fattr.cf_uniqueid = iunique(sb, ROOT_I); cifs_autodisable_serverino(cifs_sb); } if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) && CIFSCouldBeMFSymlink(&fattr)) /* * trying to get the type and mode can be slow, * so just call those regular files for now, and mark * for reval */ fattr.cf_flags |= CIFS_FATTR_NEED_REVAL; ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid); tmp_dentry = cifs_readdir_lookup(file->f_dentry, &qstring, &fattr); rc = filldir(direntry, qstring.name, qstring.len, file->f_pos, ino, fattr.cf_dtype); dput(tmp_dentry); return rc; }
static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir, void *direntry, char *scratch_buf, unsigned int max_len) { int rc = 0; struct qstr qstring; struct cifsFileInfo *pCifsF; u64 inum; ino_t ino; struct super_block *sb; struct cifs_sb_info *cifs_sb; struct dentry *tmp_dentry; struct cifs_fattr fattr; /* 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; sb = file->f_path.dentry->d_sb; cifs_sb = CIFS_SB(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; if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX) cifs_unix_basic_to_fattr(&fattr, &((FILE_UNIX_INFO *) pfindEntry)->basic, cifs_sb); else if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) cifs_std_info_to_fattr(&fattr, (FIND_FILE_STANDARD_INFO *) pfindEntry, cifs_sb); else cifs_dir_info_to_fattr(&fattr, (FILE_DIRECTORY_INFO *) pfindEntry, cifs_sb); if (inum && (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) { fattr.cf_uniqueid = inum; } else { fattr.cf_uniqueid = iunique(sb, ROOT_I); cifs_autodisable_serverino(cifs_sb); } ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid); tmp_dentry = cifs_readdir_lookup(file->f_dentry, &qstring, &fattr); rc = filldir(direntry, qstring.name, qstring.len, file->f_pos, ino, fattr.cf_dtype); /* * 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 * * FIXME: This looks bogus. filldir returns -EOVERFLOW in the above * case already. Why should we be clobbering other errors from it? */ if (rc) { cFYI(1, ("filldir rc = %d", rc)); rc = -EOVERFLOW; } dput(tmp_dentry); return rc; }