Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 26 Jul 2011 18:11:28 +0000 (11:11 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 26 Jul 2011 18:11:28 +0000 (11:11 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
  cifs: Cleanup: check return codes of crypto api calls
  CIFS: Fix oops while mounting with prefixpath
  [CIFS] Redundant null check after dereference
  cifs: use cifs_dirent in cifs_save_resume_key
  cifs: use cifs_dirent to replace cifs_get_name_from_search_buf
  cifs: introduce cifs_dirent
  cifs: cleanup cifs_filldir

1  2 
fs/cifs/dir.c
fs/cifs/readdir.c

diff --combined fs/cifs/dir.c
@@@ -57,11 -57,6 +57,6 @@@ build_path_from_dentry(struct dentry *d
        struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
        unsigned seq;
  
-       if (direntry == NULL)
-               return NULL;  /* not much we can do if dentry is freed and
-               we need to reopen the file after it was closed implicitly
-               when the server crashed */
        dirsep = CIFS_DIR_SEP(cifs_sb);
        if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
                dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
@@@ -179,7 -174,7 +174,7 @@@ cifs_create(struct inode *inode, struc
        if (oplockEnabled)
                oplock = REQ_OPLOCK;
  
 -      if (nd && (nd->flags & LOOKUP_OPEN))
 +      if (nd)
                oflags = nd->intent.open.file->f_flags;
        else
                oflags = O_RDONLY | O_CREAT;
                   which should be rare for path not covered on files) */
        }
  
 -      if (nd && (nd->flags & LOOKUP_OPEN)) {
 +      if (nd) {
                /* if the file is going to stay open, then we
                   need to set the desired access properly */
                desiredAccess = 0;
@@@ -328,7 -323,7 +323,7 @@@ cifs_create_set_dentry
        else
                cFYI(1, "Create worked, get_inode_info failed rc = %d", rc);
  
 -      if (newinode && nd && (nd->flags & LOOKUP_OPEN)) {
 +      if (newinode && nd) {
                struct cifsFileInfo *pfile_info;
                struct file *filp;
  
@@@ -568,7 -563,7 +563,7 @@@ cifs_lookup(struct inode *parent_dir_in
         * reduction in network traffic in the other paths.
         */
        if (pTcon->unix_ext) {
 -              if (nd && !(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) &&
 +              if (nd && !(nd->flags & LOOKUP_DIRECTORY) &&
                     (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
                     (nd->intent.open.file->f_flags & O_CREAT)) {
                        rc = cifs_posix_open(full_path, &newInode,
@@@ -663,8 -658,10 +658,8 @@@ cifs_d_revalidate(struct dentry *dirent
         * case sensitive name which is specified by user if this is
         * for creation.
         */
 -      if (!(nd->flags & (LOOKUP_CONTINUE | LOOKUP_PARENT))) {
 -              if (nd->flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
 -                      return 0;
 -      }
 +      if (nd->flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
 +              return 0;
  
        if (time_after(jiffies, direntry->d_time + HZ) || !lookupCacheEnabled)
                return 0;
diff --combined fs/cifs/readdir.c
@@@ -4,6 -4,7 +4,7 @@@
   *   Directory search handling
   *
   *   Copyright (C) International Business Machines  Corp., 2004, 2008
+  *   Copyright (C) Red Hat, Inc., 2011
   *   Author(s): Steve French (sfrench@us.ibm.com)
   *
   *   This library is free software; you can redistribute it and/or modify
@@@ -290,10 -291,10 +291,10 @@@ error_exit
  }
  
  /* return length of unicode string in bytes */
- static int cifs_unicode_bytelen(char *str)
+ static int cifs_unicode_bytelen(const char *str)
  {
        int len;
-       __le16 *ustr = (__le16 *)str;
+       const __le16 *ustr = (const __le16 *)str;
  
        for (len = 0; len <= PATH_MAX; len++) {
                if (ustr[len] == 0)
@@@ -334,78 -335,128 +335,128 @@@ static char *nxt_dir_entry(char *old_en
  
  }
  
+ struct cifs_dirent {
+       const char      *name;
+       size_t          namelen;
+       u32             resume_key;
+       u64             ino;
+ };
+ static void cifs_fill_dirent_unix(struct cifs_dirent *de,
+               const FILE_UNIX_INFO *info, bool is_unicode)
+ {
+       de->name = &info->FileName[0];
+       if (is_unicode)
+               de->namelen = cifs_unicode_bytelen(de->name);
+       else
+               de->namelen = strnlen(de->name, PATH_MAX);
+       de->resume_key = info->ResumeKey;
+       de->ino = le64_to_cpu(info->basic.UniqueId);
+ }
+ static void cifs_fill_dirent_dir(struct cifs_dirent *de,
+               const FILE_DIRECTORY_INFO *info)
+ {
+       de->name = &info->FileName[0];
+       de->namelen = le32_to_cpu(info->FileNameLength);
+       de->resume_key = info->FileIndex;
+ }
+ static void cifs_fill_dirent_full(struct cifs_dirent *de,
+               const FILE_FULL_DIRECTORY_INFO *info)
+ {
+       de->name = &info->FileName[0];
+       de->namelen = le32_to_cpu(info->FileNameLength);
+       de->resume_key = info->FileIndex;
+ }
+ static void cifs_fill_dirent_search(struct cifs_dirent *de,
+               const SEARCH_ID_FULL_DIR_INFO *info)
+ {
+       de->name = &info->FileName[0];
+       de->namelen = le32_to_cpu(info->FileNameLength);
+       de->resume_key = info->FileIndex;
+       de->ino = le64_to_cpu(info->UniqueId);
+ }
+ static void cifs_fill_dirent_both(struct cifs_dirent *de,
+               const FILE_BOTH_DIRECTORY_INFO *info)
+ {
+       de->name = &info->FileName[0];
+       de->namelen = le32_to_cpu(info->FileNameLength);
+       de->resume_key = info->FileIndex;
+ }
+ static void cifs_fill_dirent_std(struct cifs_dirent *de,
+               const FIND_FILE_STANDARD_INFO *info)
+ {
+       de->name = &info->FileName[0];
+       /* one byte length, no endianess conversion */
+       de->namelen = info->FileNameLength;
+       de->resume_key = info->ResumeKey;
+ }
+ static int cifs_fill_dirent(struct cifs_dirent *de, const void *info,
+               u16 level, bool is_unicode)
+ {
+       memset(de, 0, sizeof(*de));
+       switch (level) {
+       case SMB_FIND_FILE_UNIX:
+               cifs_fill_dirent_unix(de, info, is_unicode);
+               break;
+       case SMB_FIND_FILE_DIRECTORY_INFO:
+               cifs_fill_dirent_dir(de, info);
+               break;
+       case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
+               cifs_fill_dirent_full(de, info);
+               break;
+       case SMB_FIND_FILE_ID_FULL_DIR_INFO:
+               cifs_fill_dirent_search(de, info);
+               break;
+       case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
+               cifs_fill_dirent_both(de, info);
+               break;
+       case SMB_FIND_FILE_INFO_STANDARD:
+               cifs_fill_dirent_std(de, info);
+               break;
+       default:
+               cFYI(1, "Unknown findfirst level %d", level);
+               return -EINVAL;
+       }
+       return 0;
+ }
  #define UNICODE_DOT cpu_to_le16(0x2e)
  
  /* return 0 if no match and 1 for . (current directory) and 2 for .. (parent) */
- static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
+ static int cifs_entry_is_dot(struct cifs_dirent *de, bool is_unicode)
  {
        int rc = 0;
-       char *filename = NULL;
-       int len = 0;
-       if (cfile->srch_inf.info_level == SMB_FIND_FILE_UNIX) {
-               FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;
-               filename = &pFindData->FileName[0];
-               if (cfile->srch_inf.unicode) {
-                       len = cifs_unicode_bytelen(filename);
-               } else {
-                       /* BB should we make this strnlen of PATH_MAX? */
-                       len = strnlen(filename, 5);
-               }
-       } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_DIRECTORY_INFO) {
-               FILE_DIRECTORY_INFO *pFindData =
-                       (FILE_DIRECTORY_INFO *)current_entry;
-               filename = &pFindData->FileName[0];
-               len = le32_to_cpu(pFindData->FileNameLength);
-       } else if (cfile->srch_inf.info_level ==
-                       SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
-               FILE_FULL_DIRECTORY_INFO *pFindData =
-                       (FILE_FULL_DIRECTORY_INFO *)current_entry;
-               filename = &pFindData->FileName[0];
-               len = le32_to_cpu(pFindData->FileNameLength);
-       } else if (cfile->srch_inf.info_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 = le32_to_cpu(pFindData->FileNameLength);
-       } else if (cfile->srch_inf.info_level ==
-                       SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
-               FILE_BOTH_DIRECTORY_INFO *pFindData =
-                       (FILE_BOTH_DIRECTORY_INFO *)current_entry;
-               filename = &pFindData->FileName[0];
-               len = le32_to_cpu(pFindData->FileNameLength);
-       } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) {
-               FIND_FILE_STANDARD_INFO *pFindData =
-                       (FIND_FILE_STANDARD_INFO *)current_entry;
-               filename = &pFindData->FileName[0];
-               len = pFindData->FileNameLength;
-       } else {
-               cFYI(1, "Unknown findfirst level %d",
-                        cfile->srch_inf.info_level);
-       }
  
-       if (filename) {
-               if (cfile->srch_inf.unicode) {
-                       __le16 *ufilename = (__le16 *)filename;
-                       if (len == 2) {
-                               /* check for . */
-                               if (ufilename[0] == UNICODE_DOT)
-                                       rc = 1;
-                       } else if (len == 4) {
-                               /* check for .. */
-                               if ((ufilename[0] == UNICODE_DOT)
-                                  && (ufilename[1] == UNICODE_DOT))
-                                       rc = 2;
-                       }
-               } else /* ASCII */ {
-                       if (len == 1) {
-                               if (filename[0] == '.')
-                                       rc = 1;
-                       } else if (len == 2) {
-                               if ((filename[0] == '.') && (filename[1] == '.'))
-                                       rc = 2;
-                       }
+       if (!de->name)
+               return 0;
+       if (is_unicode) {
+               __le16 *ufilename = (__le16 *)de->name;
+               if (de->namelen == 2) {
+                       /* check for . */
+                       if (ufilename[0] == UNICODE_DOT)
+                               rc = 1;
+               } else if (de->namelen == 4) {
+                       /* check for .. */
+                       if (ufilename[0] == UNICODE_DOT &&
+                           ufilename[1] == UNICODE_DOT)
+                               rc = 2;
+               }
+       } else /* ASCII */ {
+               if (de->namelen == 1) {
+                       if (de->name[0] == '.')
+                               rc = 1;
+               } else if (de->namelen == 2) {
+                       if (de->name[0] == '.' && de->name[1] == '.')
+                               rc = 2;
                }
        }
  
@@@ -427,66 -478,18 +478,18 @@@ static int is_dir_changed(struct file *
  }
  
  static int cifs_save_resume_key(const char *current_entry,
-       struct cifsFileInfo *cifsFile)
+       struct cifsFileInfo *file_info)
  {
-       int rc = 0;
-       unsigned int len = 0;
-       __u16 level;
-       char *filename;
-       if ((cifsFile == NULL) || (current_entry == NULL))
-               return -EINVAL;
-       level = cifsFile->srch_inf.info_level;
-       if (level == SMB_FIND_FILE_UNIX) {
-               FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;
+       struct cifs_dirent de;
+       int rc;
  
-               filename = &pFindData->FileName[0];
-               if (cifsFile->srch_inf.unicode) {
-                       len = cifs_unicode_bytelen(filename);
-               } else {
-                       /* BB should we make this strnlen of PATH_MAX? */
-                       len = strnlen(filename, PATH_MAX);
-               }
-               cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
-       } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {
-               FILE_DIRECTORY_INFO *pFindData =
-                       (FILE_DIRECTORY_INFO *)current_entry;
-               filename = &pFindData->FileName[0];
-               len = le32_to_cpu(pFindData->FileNameLength);
-               cifsFile->srch_inf.resume_key = pFindData->FileIndex;
-       } 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 = le32_to_cpu(pFindData->FileNameLength);
-               cifsFile->srch_inf.resume_key = pFindData->FileIndex;
-       } 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 = le32_to_cpu(pFindData->FileNameLength);
-               cifsFile->srch_inf.resume_key = pFindData->FileIndex;
-       } else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
-               FILE_BOTH_DIRECTORY_INFO *pFindData =
-                       (FILE_BOTH_DIRECTORY_INFO *)current_entry;
-               filename = &pFindData->FileName[0];
-               len = le32_to_cpu(pFindData->FileNameLength);
-               cifsFile->srch_inf.resume_key = pFindData->FileIndex;
-       } else if (level == SMB_FIND_FILE_INFO_STANDARD) {
-               FIND_FILE_STANDARD_INFO *pFindData =
-                       (FIND_FILE_STANDARD_INFO *)current_entry;
-               filename = &pFindData->FileName[0];
-               /* one byte length, no name conversion */
-               len = (unsigned int)pFindData->FileNameLength;
-               cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
-       } else {
-               cFYI(1, "Unknown findfirst level %d", level);
-               return -EINVAL;
+       rc = cifs_fill_dirent(&de, current_entry, file_info->srch_inf.info_level,
+                             file_info->srch_inf.unicode);
+       if (!rc) {
+               file_info->srch_inf.presume_name = de.name;
+               file_info->srch_inf.resume_name_len = de.namelen;
+               file_info->srch_inf.resume_key = de.resume_key;
        }
-       cifsFile->srch_inf.resume_name_len = len;
-       cifsFile->srch_inf.presume_name = filename;
        return rc;
  }
  
@@@ -605,136 -608,70 +608,70 @@@ static int find_cifs_entry(const int xi
        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 cifs_sb_info *cifs_sb, unsigned int max_len, __u64 *pinum)
+ static int cifs_filldir(char *find_entry, struct file *file, filldir_t filldir,
+               void *dirent, char *scratch_buf, unsigned int max_len)
  {
+       struct cifsFileInfo *file_info = file->private_data;
+       struct super_block *sb = file->f_path.dentry->d_sb;
+       struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+       struct cifs_dirent de = { NULL, };
+       struct cifs_fattr fattr;
+       struct dentry *dentry;
+       struct qstr name;
        int rc = 0;
-       unsigned int len = 0;
-       char *filename;
-       struct nls_table *nlt = cifs_sb->local_nls;
-       *pinum = 0;
-       if (level == SMB_FIND_FILE_UNIX) {
-               FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;
-               filename = &pFindData->FileName[0];
-               if (unicode) {
-                       len = cifs_unicode_bytelen(filename);
-               } else {
-                       /* BB should we make this strnlen of PATH_MAX? */
-                       len = strnlen(filename, PATH_MAX);
-               }
+       ino_t ino;
  
-               *pinum = le64_to_cpu(pFindData->basic.UniqueId);
-       } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {
-               FILE_DIRECTORY_INFO *pFindData =
-                       (FILE_DIRECTORY_INFO *)current_entry;
-               filename = &pFindData->FileName[0];
-               len = le32_to_cpu(pFindData->FileNameLength);
-       } 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 = le32_to_cpu(pFindData->FileNameLength);
-       } 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 = le32_to_cpu(pFindData->FileNameLength);
-               *pinum = le64_to_cpu(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];
-               len = le32_to_cpu(pFindData->FileNameLength);
-       } else if (level == SMB_FIND_FILE_INFO_STANDARD) {
-               FIND_FILE_STANDARD_INFO *pFindData =
-                       (FIND_FILE_STANDARD_INFO *)current_entry;
-               filename = &pFindData->FileName[0];
-               /* one byte length, no name conversion */
-               len = (unsigned int)pFindData->FileNameLength;
-       } else {
-               cFYI(1, "Unknown findfirst level %d", level);
-               return -EINVAL;
-       }
+       rc = cifs_fill_dirent(&de, find_entry, file_info->srch_inf.info_level,
+                             file_info->srch_inf.unicode);
+       if (rc)
+               return rc;
  
-       if (len > max_len) {
-               cERROR(1, "bad search response length %d past smb end", len);
+       if (de.namelen > max_len) {
+               cERROR(1, "bad search response length %zd past smb end",
+                         de.namelen);
                return -EINVAL;
        }
  
-       if (unicode) {
-               pqst->len = cifs_from_ucs2((char *) pqst->name,
-                                          (__le16 *) filename,
-                                          UNICODE_NAME_MAX,
-                                          min(len, max_len), nlt,
-                                          cifs_sb->mnt_cifs_flags &
-                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
-               pqst->len -= nls_nullsize(nlt);
-       } else {
-               pqst->name = filename;
-               pqst->len = len;
-       }
-       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)
+       if (cifs_entry_is_dot(&de, file_info->srch_inf.unicode))
                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 (file_info->srch_inf.unicode) {
+               struct nls_table *nlt = cifs_sb->local_nls;
  
-       if (rc)
-               return rc;
+               name.name = scratch_buf;
+               name.len =
+                       cifs_from_ucs2((char *)name.name, (__le16 *)de.name,
+                                      UNICODE_NAME_MAX,
+                                      min(de.namelen, (size_t)max_len), nlt,
+                                      cifs_sb->mnt_cifs_flags &
+                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
+               name.len -= nls_nullsize(nlt);
+       } else {
+               name.name = de.name;
+               name.len = de.namelen;
+       }
  
-       if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX)
+       switch (file_info->srch_inf.info_level) {
+       case 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);
+                                        &((FILE_UNIX_INFO *)find_entry)->basic,
+                                        cifs_sb);
+               break;
+       case SMB_FIND_FILE_INFO_STANDARD:
+               cifs_std_info_to_fattr(&fattr,
+                                      (FIND_FILE_STANDARD_INFO *)find_entry,
+                                      cifs_sb);
+               break;
+       default:
+               cifs_dir_info_to_fattr(&fattr,
+                                      (FILE_DIRECTORY_INFO *)find_entry,
+                                      cifs_sb);
+               break;
+       }
  
-       if (inum && (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
-               fattr.cf_uniqueid = inum;
+       if (de.ino && (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
+               fattr.cf_uniqueid = de.ino;
        } else {
                fattr.cf_uniqueid = iunique(sb, ROOT_I);
                cifs_autodisable_serverino(cifs_sb);
                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);
+       dentry = cifs_readdir_lookup(file->f_dentry, &name, &fattr);
  
-       rc = filldir(direntry, qstring.name, qstring.len, file->f_pos,
-                    ino, fattr.cf_dtype);
+       rc = filldir(dirent, name.name, name.len, file->f_pos, ino,
+                    fattr.cf_dtype);
  
-       dput(tmp_dentry);
+       dput(dentry);
        return rc;
  }
  
@@@ -796,7 -733,7 +733,7 @@@ int cifs_readdir(struct file *file, voi
                file->f_pos++;
        case 1:
                if (filldir(direntry, "..", 2, file->f_pos,
 -                   file->f_path.dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) {
 +                   parent_ino(file->f_path.dentry), DT_DIR) < 0) {
                        cERROR(1, "Filldir for parent dir failed");
                        rc = -ENOMEM;
                        break;