Merge tag 'mmc-v4.8-rc7' of git://git.linaro.org/people/ulf.hansson/mmc
[cascardo/linux.git] / fs / nfsd / nfsfh.c
index a891944..cfe7500 100644 (file)
@@ -59,14 +59,20 @@ static int nfsd_acceptable(void *expv, struct dentry *dentry)
  * the write call).
  */
 static inline __be32
-nfsd_mode_check(struct svc_rqst *rqstp, umode_t mode, umode_t requested)
+nfsd_mode_check(struct svc_rqst *rqstp, struct dentry *dentry,
+               umode_t requested)
 {
-       mode &= S_IFMT;
+       umode_t mode = d_inode(dentry)->i_mode & S_IFMT;
 
        if (requested == 0) /* the caller doesn't care */
                return nfs_ok;
-       if (mode == requested)
+       if (mode == requested) {
+               if (mode == S_IFDIR && !d_can_lookup(dentry)) {
+                       WARN_ON_ONCE(1);
+                       return nfserr_notdir;
+               }
                return nfs_ok;
+       }
        /*
         * v4 has an error more specific than err_notdir which we should
         * return in preference to err_notdir:
@@ -298,7 +304,7 @@ out:
  * that it expects something not of the given type.
  *
  * @access is formed from the NFSD_MAY_* constants defined in
- * include/linux/nfsd/nfsd.h.
+ * fs/nfsd/vfs.h.
  */
 __be32
 fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int access)
@@ -340,7 +346,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int access)
        if (error)
                goto out;
 
-       error = nfsd_mode_check(rqstp, d_inode(dentry)->i_mode, type);
+       error = nfsd_mode_check(rqstp, dentry, type);
        if (error)
                goto out;
 
@@ -533,7 +539,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
         * the reference filehandle (if it is in the same export)
         * or the export options.
         */
-        set_version_and_fsid_type(fhp, exp, ref_fh);
+       set_version_and_fsid_type(fhp, exp, ref_fh);
 
        if (ref_fh == fhp)
                fh_put(ref_fh);