The NFSv3 lookup method, which returns attributes for the directory
authorzoulasc <christos@zoulas.com>
Fri, 22 Jan 2016 15:16:31 +0000 (10:16 -0500)
committerzoulasc <christos@zoulas.com>
Fri, 22 Jan 2016 15:16:31 +0000 (10:16 -0500)
containing the object to be looked up, used incorrect mount point
attributes. This was causing unusual file system object visibility
problems. (Ian Kent)

amd/nfs_subr.c

index 85cf98c203cca9617589166ba9e938d751cbe5b1..6a1b717d38b74df10e2d66d20ec19f78b94c5474 100644 (file)
@@ -978,6 +978,29 @@ static void fattr_to_wcc_attr(nfsfattr *fattr, am_wcc_attr *wcc_attr)
   nfstime_to_am_nfstime3(&fattr->na_ctime, &wcc_attr->ctime);
 }
 
+static nfsfattr *get_parent_fattr(am_node *mp)
+{
+  nfsfattr *fattr;
+
+  /* Set attributes to those of the parent only if this
+   * isn't topvol otherwise just use the mp attributes.
+   */
+  fattr = &mp->am_fattr;
+  if (mp->am_parent && mp->am_parent->am_parent &&
+      !(mp->am_parent->am_parent->am_flags & AMF_ROOT))
+    fattr = &mp->am_parent->am_fattr;
+
+  return fattr;
+}
+
+static void parent_fattr_to_fattr3(am_node *mp, am_fattr3 *fattr3)
+{
+  nfsfattr *fattr;
+
+  fattr = get_parent_fattr(mp);
+  fattr_to_fattr3(fattr, fattr3);
+}
+
 static am_nfsstat3 return_estale_or_rofs(am_nfs_fh3 *fh,
                                          am_pre_op_attr *pre_op,
                                          am_post_op_attr *post_op)
@@ -1177,9 +1200,7 @@ am_nfs3_lookup_3_svc(am_LOOKUP3args *argp, struct svc_req *rqstp)
 
     /* dir attributes */
     post_op_dir->attributes_follow = 1;
-    fattr = &mp->am_fattr;
     fattr3 = &post_op_dir->am_post_op_attr_u.attributes;
-    fattr_to_fattr3(fattr, fattr3);
 
     post_op_obj->attributes_follow = 0;
 
@@ -1196,6 +1217,7 @@ am_nfs3_lookup_3_svc(am_LOOKUP3args *argp, struct svc_req *rqstp)
        amd_stats.d_drops++;
        return 0;
       }
+      parent_fattr_to_fattr3(mp, fattr3);
       result.status = nfs_error(error);
     } else {
       /*
@@ -1206,6 +1228,9 @@ am_nfs3_lookup_3_svc(am_LOOKUP3args *argp, struct svc_req *rqstp)
       if (ap->am_ttl < mp->am_ttl)
         ap->am_ttl = mp->am_ttl;
 
+      /* dir attrs, update after mount */
+      parent_fattr_to_fattr3(mp, fattr3);
+
       mp_to_fh3(ap, &result.res_u.ok.object);
 
       /* mount attributes */