Commit 409924e4c943072a63c43bb6b77576bf12f1896b

Authored by Trond Myklebust
1 parent f26c7a7887

NFSv4: Make decode_getfattr() set fattr->valid to reflect what was decoded

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

Showing 1 changed file with 73 additions and 19 deletions Side-by-side Diff

... ... @@ -2157,6 +2157,7 @@
2157 2157 static int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *type)
2158 2158 {
2159 2159 __be32 *p;
  2160 + int ret = 0;
2160 2161  
2161 2162 *type = 0;
2162 2163 if (unlikely(bitmap[0] & (FATTR4_WORD0_TYPE - 1U)))
2163 2164  
2164 2165  
... ... @@ -2169,14 +2170,16 @@
2169 2170 return -EIO;
2170 2171 }
2171 2172 bitmap[0] &= ~FATTR4_WORD0_TYPE;
  2173 + ret = NFS_ATTR_FATTR_TYPE;
2172 2174 }
2173 2175 dprintk("%s: type=0%o\n", __func__, nfs_type2fmt[*type]);
2174   - return 0;
  2176 + return ret;
2175 2177 }
2176 2178  
2177 2179 static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *change)
2178 2180 {
2179 2181 __be32 *p;
  2182 + int ret = 0;
2180 2183  
2181 2184 *change = 0;
2182 2185 if (unlikely(bitmap[0] & (FATTR4_WORD0_CHANGE - 1U)))
2183 2186  
2184 2187  
... ... @@ -2185,15 +2188,17 @@
2185 2188 READ_BUF(8);
2186 2189 READ64(*change);
2187 2190 bitmap[0] &= ~FATTR4_WORD0_CHANGE;
  2191 + ret = NFS_ATTR_FATTR_CHANGE;
2188 2192 }
2189 2193 dprintk("%s: change attribute=%Lu\n", __func__,
2190 2194 (unsigned long long)*change);
2191   - return 0;
  2195 + return ret;
2192 2196 }
2193 2197  
2194 2198 static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *size)
2195 2199 {
2196 2200 __be32 *p;
  2201 + int ret = 0;
2197 2202  
2198 2203 *size = 0;
2199 2204 if (unlikely(bitmap[0] & (FATTR4_WORD0_SIZE - 1U)))
2200 2205  
... ... @@ -2202,9 +2207,10 @@
2202 2207 READ_BUF(8);
2203 2208 READ64(*size);
2204 2209 bitmap[0] &= ~FATTR4_WORD0_SIZE;
  2210 + ret = NFS_ATTR_FATTR_SIZE;
2205 2211 }
2206 2212 dprintk("%s: file size=%Lu\n", __func__, (unsigned long long)*size);
2207   - return 0;
  2213 + return ret;
2208 2214 }
2209 2215  
2210 2216 static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
... ... @@ -2242,6 +2248,7 @@
2242 2248 static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fsid *fsid)
2243 2249 {
2244 2250 __be32 *p;
  2251 + int ret = 0;
2245 2252  
2246 2253 fsid->major = 0;
2247 2254 fsid->minor = 0;
2248 2255  
... ... @@ -2252,11 +2259,12 @@
2252 2259 READ64(fsid->major);
2253 2260 READ64(fsid->minor);
2254 2261 bitmap[0] &= ~FATTR4_WORD0_FSID;
  2262 + ret = NFS_ATTR_FATTR_FSID;
2255 2263 }
2256 2264 dprintk("%s: fsid=(0x%Lx/0x%Lx)\n", __func__,
2257 2265 (unsigned long long)fsid->major,
2258 2266 (unsigned long long)fsid->minor);
2259   - return 0;
  2267 + return ret;
2260 2268 }
2261 2269  
2262 2270 static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
... ... @@ -2294,6 +2302,7 @@
2294 2302 static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid)
2295 2303 {
2296 2304 __be32 *p;
  2305 + int ret = 0;
2297 2306  
2298 2307 *fileid = 0;
2299 2308 if (unlikely(bitmap[0] & (FATTR4_WORD0_FILEID - 1U)))
2300 2309  
2301 2310  
... ... @@ -2302,14 +2311,16 @@
2302 2311 READ_BUF(8);
2303 2312 READ64(*fileid);
2304 2313 bitmap[0] &= ~FATTR4_WORD0_FILEID;
  2314 + ret = NFS_ATTR_FATTR_FILEID;
2305 2315 }
2306 2316 dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid);
2307   - return 0;
  2317 + return ret;
2308 2318 }
2309 2319  
2310 2320 static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid)
2311 2321 {
2312 2322 __be32 *p;
  2323 + int ret = 0;
2313 2324  
2314 2325 *fileid = 0;
2315 2326 if (unlikely(bitmap[1] & (FATTR4_WORD1_MOUNTED_ON_FILEID - 1U)))
2316 2327  
... ... @@ -2318,9 +2329,10 @@
2318 2329 READ_BUF(8);
2319 2330 READ64(*fileid);
2320 2331 bitmap[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID;
  2332 + ret = NFS_ATTR_FATTR_FILEID;
2321 2333 }
2322 2334 dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid);
2323   - return 0;
  2335 + return ret;
2324 2336 }
2325 2337  
2326 2338 static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
... ... @@ -2476,6 +2488,8 @@
2476 2488 if (res->nlocations < NFS4_FS_LOCATIONS_MAXENTRIES)
2477 2489 res->nlocations++;
2478 2490 }
  2491 + if (res->nlocations != 0)
  2492 + status = NFS_ATTR_FATTR_V4_REFERRAL;
2479 2493 out:
2480 2494 dprintk("%s: fs_locations done, error = %d\n", __func__, status);
2481 2495 return status;
... ... @@ -2581,6 +2595,7 @@
2581 2595 {
2582 2596 uint32_t tmp;
2583 2597 __be32 *p;
  2598 + int ret = 0;
2584 2599  
2585 2600 *mode = 0;
2586 2601 if (unlikely(bitmap[1] & (FATTR4_WORD1_MODE - 1U)))
2587 2602  
2588 2603  
... ... @@ -2590,14 +2605,16 @@
2590 2605 READ32(tmp);
2591 2606 *mode = tmp & ~S_IFMT;
2592 2607 bitmap[1] &= ~FATTR4_WORD1_MODE;
  2608 + ret = NFS_ATTR_FATTR_MODE;
2593 2609 }
2594 2610 dprintk("%s: file mode=0%o\n", __func__, (unsigned int)*mode);
2595   - return 0;
  2611 + return ret;
2596 2612 }
2597 2613  
2598 2614 static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *nlink)
2599 2615 {
2600 2616 __be32 *p;
  2617 + int ret = 0;
2601 2618  
2602 2619 *nlink = 1;
2603 2620 if (unlikely(bitmap[1] & (FATTR4_WORD1_NUMLINKS - 1U)))
2604 2621  
2605 2622  
... ... @@ -2606,15 +2623,17 @@
2606 2623 READ_BUF(4);
2607 2624 READ32(*nlink);
2608 2625 bitmap[1] &= ~FATTR4_WORD1_NUMLINKS;
  2626 + ret = NFS_ATTR_FATTR_NLINK;
2609 2627 }
2610 2628 dprintk("%s: nlink=%u\n", __func__, (unsigned int)*nlink);
2611   - return 0;
  2629 + return ret;
2612 2630 }
2613 2631  
2614 2632 static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, uint32_t *uid)
2615 2633 {
2616 2634 uint32_t len;
2617 2635 __be32 *p;
  2636 + int ret = 0;
2618 2637  
2619 2638 *uid = -2;
2620 2639 if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER - 1U)))
... ... @@ -2624,7 +2643,9 @@
2624 2643 READ32(len);
2625 2644 READ_BUF(len);
2626 2645 if (len < XDR_MAX_NETOBJ) {
2627   - if (nfs_map_name_to_uid(clp, (char *)p, len, uid) != 0)
  2646 + if (nfs_map_name_to_uid(clp, (char *)p, len, uid) == 0)
  2647 + ret = NFS_ATTR_FATTR_OWNER;
  2648 + else
2628 2649 dprintk("%s: nfs_map_name_to_uid failed!\n",
2629 2650 __func__);
2630 2651 } else
2631 2652  
... ... @@ -2633,13 +2654,14 @@
2633 2654 bitmap[1] &= ~FATTR4_WORD1_OWNER;
2634 2655 }
2635 2656 dprintk("%s: uid=%d\n", __func__, (int)*uid);
2636   - return 0;
  2657 + return ret;
2637 2658 }
2638 2659  
2639 2660 static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, uint32_t *gid)
2640 2661 {
2641 2662 uint32_t len;
2642 2663 __be32 *p;
  2664 + int ret = 0;
2643 2665  
2644 2666 *gid = -2;
2645 2667 if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER_GROUP - 1U)))
... ... @@ -2649,7 +2671,9 @@
2649 2671 READ32(len);
2650 2672 READ_BUF(len);
2651 2673 if (len < XDR_MAX_NETOBJ) {
2652   - if (nfs_map_group_to_gid(clp, (char *)p, len, gid) != 0)
  2674 + if (nfs_map_group_to_gid(clp, (char *)p, len, gid) == 0)
  2675 + ret = NFS_ATTR_FATTR_GROUP;
  2676 + else
2653 2677 dprintk("%s: nfs_map_group_to_gid failed!\n",
2654 2678 __func__);
2655 2679 } else
2656 2680  
... ... @@ -2658,13 +2682,14 @@
2658 2682 bitmap[1] &= ~FATTR4_WORD1_OWNER_GROUP;
2659 2683 }
2660 2684 dprintk("%s: gid=%d\n", __func__, (int)*gid);
2661   - return 0;
  2685 + return ret;
2662 2686 }
2663 2687  
2664 2688 static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rdev)
2665 2689 {
2666 2690 uint32_t major = 0, minor = 0;
2667 2691 __be32 *p;
  2692 + int ret = 0;
2668 2693  
2669 2694 *rdev = MKDEV(0,0);
2670 2695 if (unlikely(bitmap[1] & (FATTR4_WORD1_RAWDEV - 1U)))
2671 2696  
... ... @@ -2679,9 +2704,10 @@
2679 2704 if (MAJOR(tmp) == major && MINOR(tmp) == minor)
2680 2705 *rdev = tmp;
2681 2706 bitmap[1] &= ~ FATTR4_WORD1_RAWDEV;
  2707 + ret = NFS_ATTR_FATTR_RDEV;
2682 2708 }
2683 2709 dprintk("%s: rdev=(0x%x:0x%x)\n", __func__, major, minor);
2684   - return 0;
  2710 + return ret;
2685 2711 }
2686 2712  
2687 2713 static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
... ... @@ -2738,6 +2764,7 @@
2738 2764 static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *used)
2739 2765 {
2740 2766 __be32 *p;
  2767 + int ret = 0;
2741 2768  
2742 2769 *used = 0;
2743 2770 if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_USED - 1U)))
2744 2771  
... ... @@ -2746,10 +2773,11 @@
2746 2773 READ_BUF(8);
2747 2774 READ64(*used);
2748 2775 bitmap[1] &= ~FATTR4_WORD1_SPACE_USED;
  2776 + ret = NFS_ATTR_FATTR_SPACE_USED;
2749 2777 }
2750 2778 dprintk("%s: space used=%Lu\n", __func__,
2751 2779 (unsigned long long)*used);
2752   - return 0;
  2780 + return ret;
2753 2781 }
2754 2782  
2755 2783 static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time)
... ... @@ -2776,6 +2804,8 @@
2776 2804 return -EIO;
2777 2805 if (likely(bitmap[1] & FATTR4_WORD1_TIME_ACCESS)) {
2778 2806 status = decode_attr_time(xdr, time);
  2807 + if (status == 0)
  2808 + status = NFS_ATTR_FATTR_ATIME;
2779 2809 bitmap[1] &= ~FATTR4_WORD1_TIME_ACCESS;
2780 2810 }
2781 2811 dprintk("%s: atime=%ld\n", __func__, (long)time->tv_sec);
... ... @@ -2792,6 +2822,8 @@
2792 2822 return -EIO;
2793 2823 if (likely(bitmap[1] & FATTR4_WORD1_TIME_METADATA)) {
2794 2824 status = decode_attr_time(xdr, time);
  2825 + if (status == 0)
  2826 + status = NFS_ATTR_FATTR_CTIME;
2795 2827 bitmap[1] &= ~FATTR4_WORD1_TIME_METADATA;
2796 2828 }
2797 2829 dprintk("%s: ctime=%ld\n", __func__, (long)time->tv_sec);
... ... @@ -2808,6 +2840,8 @@
2808 2840 return -EIO;
2809 2841 if (likely(bitmap[1] & FATTR4_WORD1_TIME_MODIFY)) {
2810 2842 status = decode_attr_time(xdr, time);
  2843 + if (status == 0)
  2844 + status = NFS_ATTR_FATTR_MTIME;
2811 2845 bitmap[1] &= ~FATTR4_WORD1_TIME_MODIFY;
2812 2846 }
2813 2847 dprintk("%s: mtime=%ld\n", __func__, (long)time->tv_sec);
2814 2848  
2815 2849  
2816 2850  
2817 2851  
2818 2852  
2819 2853  
2820 2854  
2821 2855  
2822 2856  
2823 2857  
2824 2858  
2825 2859  
2826 2860  
2827 2861  
2828 2862  
2829 2863  
2830 2864  
... ... @@ -3012,76 +3046,96 @@
3012 3046 status = decode_attr_type(xdr, bitmap, &type);
3013 3047 if (status < 0)
3014 3048 goto xdr_error;
3015   - fattr->mode = nfs_type2fmt[type];
  3049 + fattr->mode = 0;
  3050 + if (status != 0) {
  3051 + fattr->mode |= nfs_type2fmt[type];
  3052 + fattr->valid |= status;
  3053 + }
3016 3054  
3017 3055 status = decode_attr_change(xdr, bitmap, &fattr->change_attr);
3018 3056 if (status < 0)
3019 3057 goto xdr_error;
  3058 + fattr->valid |= status;
3020 3059  
3021 3060 status = decode_attr_size(xdr, bitmap, &fattr->size);
3022 3061 if (status < 0)
3023 3062 goto xdr_error;
  3063 + fattr->valid |= status;
3024 3064  
3025 3065 status = decode_attr_fsid(xdr, bitmap, &fattr->fsid);
3026 3066 if (status < 0)
3027 3067 goto xdr_error;
  3068 + fattr->valid |= status;
3028 3069  
3029 3070 status = decode_attr_fileid(xdr, bitmap, &fattr->fileid);
3030 3071 if (status < 0)
3031 3072 goto xdr_error;
  3073 + fattr->valid |= status;
3032 3074  
3033 3075 status = decode_attr_fs_locations(xdr, bitmap, container_of(fattr,
3034 3076 struct nfs4_fs_locations,
3035 3077 fattr));
3036 3078 if (status < 0)
3037 3079 goto xdr_error;
  3080 + fattr->valid |= status;
3038 3081  
3039 3082 status = decode_attr_mode(xdr, bitmap, &fmode);
3040 3083 if (status < 0)
3041 3084 goto xdr_error;
3042   - fattr->mode |= fmode;
  3085 + if (status != 0) {
  3086 + fattr->mode |= fmode;
  3087 + fattr->valid |= status;
  3088 + }
3043 3089  
3044 3090 status = decode_attr_nlink(xdr, bitmap, &fattr->nlink);
3045 3091 if (status < 0)
3046 3092 goto xdr_error;
  3093 + fattr->valid |= status;
3047 3094  
3048 3095 status = decode_attr_owner(xdr, bitmap, server->nfs_client, &fattr->uid);
3049 3096 if (status < 0)
3050 3097 goto xdr_error;
  3098 + fattr->valid |= status;
3051 3099  
3052 3100 status = decode_attr_group(xdr, bitmap, server->nfs_client, &fattr->gid);
3053 3101 if (status < 0)
3054 3102 goto xdr_error;
  3103 + fattr->valid |= status;
3055 3104  
3056 3105 status = decode_attr_rdev(xdr, bitmap, &fattr->rdev);
3057 3106 if (status < 0)
3058 3107 goto xdr_error;
  3108 + fattr->valid |= status;
3059 3109  
3060 3110 status = decode_attr_space_used(xdr, bitmap, &fattr->du.nfs3.used);
3061 3111 if (status < 0)
3062 3112 goto xdr_error;
  3113 + fattr->valid |= status;
3063 3114  
3064 3115 status = decode_attr_time_access(xdr, bitmap, &fattr->atime);
3065 3116 if (status < 0)
3066 3117 goto xdr_error;
  3118 + fattr->valid |= status;
3067 3119  
3068 3120 status = decode_attr_time_metadata(xdr, bitmap, &fattr->ctime);
3069 3121 if (status < 0)
3070 3122 goto xdr_error;
  3123 + fattr->valid |= status;
3071 3124  
3072 3125 status = decode_attr_time_modify(xdr, bitmap, &fattr->mtime);
3073 3126 if (status < 0)
3074 3127 goto xdr_error;
  3128 + fattr->valid |= status;
3075 3129  
3076 3130 status = decode_attr_mounted_on_fileid(xdr, bitmap, &fileid);
3077 3131 if (status < 0)
3078 3132 goto xdr_error;
3079   - if (fattr->fileid == 0 && fileid != 0)
  3133 + if (status != 0 && !(fattr->valid & status)) {
3080 3134 fattr->fileid = fileid;
  3135 + fattr->valid |= status;
  3136 + }
3081 3137  
3082 3138 status = verify_attr_len(xdr, savep, attrlen);
3083   - if (status == 0)
3084   - fattr->valid = NFS_ATTR_FATTR_V4;
3085 3139 xdr_error:
3086 3140 dprintk("%s: xdr returned %d\n", __func__, -status);
3087 3141 return status;