Merge tag 'ovl-update-5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs
[linux-2.6-microblaze.git] / fs / nfsd / nfsfh.c
index c81dbba..66f2ef6 100644 (file)
@@ -268,12 +268,20 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp)
        if (fileid_type == FILEID_ROOT)
                dentry = dget(exp->ex_path.dentry);
        else {
-               dentry = exportfs_decode_fh(exp->ex_path.mnt, fid,
-                               data_left, fileid_type,
-                               nfsd_acceptable, exp);
-               if (IS_ERR_OR_NULL(dentry))
+               dentry = exportfs_decode_fh_raw(exp->ex_path.mnt, fid,
+                                               data_left, fileid_type,
+                                               nfsd_acceptable, exp);
+               if (IS_ERR_OR_NULL(dentry)) {
                        trace_nfsd_set_fh_dentry_badhandle(rqstp, fhp,
                                        dentry ?  PTR_ERR(dentry) : -ESTALE);
+                       switch (PTR_ERR(dentry)) {
+                       case -ENOMEM:
+                       case -ETIMEDOUT:
+                               break;
+                       default:
+                               dentry = ERR_PTR(-ESTALE);
+                       }
+               }
        }
        if (dentry == NULL)
                goto out;
@@ -291,6 +299,20 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp)
 
        fhp->fh_dentry = dentry;
        fhp->fh_export = exp;
+
+       switch (rqstp->rq_vers) {
+       case 4:
+               if (dentry->d_sb->s_export_op->flags & EXPORT_OP_NOATOMIC_ATTR)
+                       fhp->fh_no_atomic_attr = true;
+               break;
+       case 3:
+               if (dentry->d_sb->s_export_op->flags & EXPORT_OP_NOWCC)
+                       fhp->fh_no_wcc = true;
+               break;
+       case 2:
+               fhp->fh_no_wcc = true;
+       }
+
        return 0;
 out:
        exp_put(exp);
@@ -559,6 +581,9 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
         */
        set_version_and_fsid_type(fhp, exp, ref_fh);
 
+       /* If we have a ref_fh, then copy the fh_no_wcc setting from it. */
+       fhp->fh_no_wcc = ref_fh ? ref_fh->fh_no_wcc : false;
+
        if (ref_fh == fhp)
                fh_put(ref_fh);
 
@@ -662,6 +687,7 @@ fh_put(struct svc_fh *fhp)
                exp_put(exp);
                fhp->fh_export = NULL;
        }
+       fhp->fh_no_wcc = false;
        return;
 }