@@ -2204,3 +2204,191 @@ int yfs_fs_inline_bulk_status(struct afs_fs_cursor *fc,
22042204 afs_make_call (& fc -> ac , call , GFP_NOFS );
22052205 return afs_wait_for_call_to_complete (call , & fc -> ac );
22062206}
2207+
2208+ /*
2209+ * Deliver reply data to an YFS.FetchOpaqueACL.
2210+ */
2211+ static int yfs_deliver_fs_fetch_opaque_acl (struct afs_call * call )
2212+ {
2213+ struct afs_volsync * volsync = call -> reply [2 ];
2214+ struct afs_vnode * vnode = call -> reply [1 ];
2215+ struct yfs_acl * yacl = call -> reply [0 ];
2216+ struct afs_acl * acl ;
2217+ const __be32 * bp ;
2218+ unsigned int size ;
2219+ int ret ;
2220+
2221+ _enter ("{%u}" , call -> unmarshall );
2222+
2223+ switch (call -> unmarshall ) {
2224+ case 0 :
2225+ afs_extract_to_tmp (call );
2226+ call -> unmarshall ++ ;
2227+
2228+ /* Extract the file ACL length */
2229+ case 1 :
2230+ ret = afs_extract_data (call , true);
2231+ if (ret < 0 )
2232+ return ret ;
2233+
2234+ size = call -> count2 = ntohl (call -> tmp );
2235+ size = round_up (size , 4 );
2236+
2237+ if (yacl -> flags & YFS_ACL_WANT_ACL ) {
2238+ acl = kmalloc (struct_size (acl , data , size ), GFP_KERNEL );
2239+ if (!acl )
2240+ return - ENOMEM ;
2241+ yacl -> acl = acl ;
2242+ acl -> size = call -> count2 ;
2243+ afs_extract_begin (call , acl -> data , size );
2244+ } else {
2245+ iov_iter_discard (& call -> iter , READ , size );
2246+ }
2247+ call -> unmarshall ++ ;
2248+
2249+ /* Extract the file ACL */
2250+ case 2 :
2251+ ret = afs_extract_data (call , true);
2252+ if (ret < 0 )
2253+ return ret ;
2254+
2255+ afs_extract_to_tmp (call );
2256+ call -> unmarshall ++ ;
2257+
2258+ /* Extract the volume ACL length */
2259+ case 3 :
2260+ ret = afs_extract_data (call , true);
2261+ if (ret < 0 )
2262+ return ret ;
2263+
2264+ size = call -> count2 = ntohl (call -> tmp );
2265+ size = round_up (size , 4 );
2266+
2267+ if (yacl -> flags & YFS_ACL_WANT_VOL_ACL ) {
2268+ acl = kmalloc (struct_size (acl , data , size ), GFP_KERNEL );
2269+ if (!acl )
2270+ return - ENOMEM ;
2271+ yacl -> vol_acl = acl ;
2272+ acl -> size = call -> count2 ;
2273+ afs_extract_begin (call , acl -> data , size );
2274+ } else {
2275+ iov_iter_discard (& call -> iter , READ , size );
2276+ }
2277+ call -> unmarshall ++ ;
2278+
2279+ /* Extract the volume ACL */
2280+ case 4 :
2281+ ret = afs_extract_data (call , true);
2282+ if (ret < 0 )
2283+ return ret ;
2284+
2285+ afs_extract_to_buf (call ,
2286+ sizeof (__be32 ) * 2 +
2287+ sizeof (struct yfs_xdr_YFSFetchStatus ) +
2288+ sizeof (struct yfs_xdr_YFSVolSync ));
2289+ call -> unmarshall ++ ;
2290+
2291+ /* extract the metadata */
2292+ case 5 :
2293+ ret = afs_extract_data (call , false);
2294+ if (ret < 0 )
2295+ return ret ;
2296+
2297+ bp = call -> buffer ;
2298+ yacl -> inherit_flag = ntohl (* bp ++ );
2299+ yacl -> num_cleaned = ntohl (* bp ++ );
2300+ ret = yfs_decode_status (call , & bp , & vnode -> status , vnode ,
2301+ & call -> expected_version , NULL );
2302+ if (ret < 0 )
2303+ return ret ;
2304+ xdr_decode_YFSVolSync (& bp , volsync );
2305+
2306+ call -> unmarshall ++ ;
2307+
2308+ case 6 :
2309+ break ;
2310+ }
2311+
2312+ _leave (" = 0 [done]" );
2313+ return 0 ;
2314+ }
2315+
2316+ void yfs_free_opaque_acl (struct yfs_acl * yacl )
2317+ {
2318+ if (yacl ) {
2319+ kfree (yacl -> acl );
2320+ kfree (yacl -> vol_acl );
2321+ kfree (yacl );
2322+ }
2323+ }
2324+
2325+ static void yfs_destroy_fs_fetch_opaque_acl (struct afs_call * call )
2326+ {
2327+ yfs_free_opaque_acl (call -> reply [0 ]);
2328+ afs_flat_call_destructor (call );
2329+ }
2330+
2331+ /*
2332+ * YFS.FetchOpaqueACL operation type
2333+ */
2334+ static const struct afs_call_type yfs_RXYFSFetchOpaqueACL = {
2335+ .name = "YFS.FetchOpaqueACL" ,
2336+ .op = yfs_FS_FetchOpaqueACL ,
2337+ .deliver = yfs_deliver_fs_fetch_opaque_acl ,
2338+ .destructor = yfs_destroy_fs_fetch_opaque_acl ,
2339+ };
2340+
2341+ /*
2342+ * Fetch the YFS advanced ACLs for a file.
2343+ */
2344+ struct yfs_acl * yfs_fs_fetch_opaque_acl (struct afs_fs_cursor * fc ,
2345+ unsigned int flags )
2346+ {
2347+ struct afs_vnode * vnode = fc -> vnode ;
2348+ struct afs_call * call ;
2349+ struct yfs_acl * yacl ;
2350+ struct afs_net * net = afs_v2net (vnode );
2351+ __be32 * bp ;
2352+
2353+ _enter (",%x,{%llx:%llu},," ,
2354+ key_serial (fc -> key ), vnode -> fid .vid , vnode -> fid .vnode );
2355+
2356+ call = afs_alloc_flat_call (net , & yfs_RXYFSFetchOpaqueACL ,
2357+ sizeof (__be32 ) * 2 +
2358+ sizeof (struct yfs_xdr_YFSFid ),
2359+ sizeof (__be32 ) * 2 +
2360+ sizeof (struct yfs_xdr_YFSFetchStatus ) +
2361+ sizeof (struct yfs_xdr_YFSVolSync ));
2362+ if (!call )
2363+ goto nomem ;
2364+
2365+ yacl = kzalloc (sizeof (struct yfs_acl ), GFP_KERNEL );
2366+ if (!yacl )
2367+ goto nomem_call ;
2368+
2369+ yacl -> flags = flags ;
2370+ call -> key = fc -> key ;
2371+ call -> reply [0 ] = yacl ;
2372+ call -> reply [1 ] = vnode ;
2373+ call -> reply [2 ] = NULL ; /* volsync */
2374+ call -> ret_reply0 = true;
2375+
2376+ /* marshall the parameters */
2377+ bp = call -> request ;
2378+ bp = xdr_encode_u32 (bp , YFSFETCHOPAQUEACL );
2379+ bp = xdr_encode_u32 (bp , 0 ); /* RPC flags */
2380+ bp = xdr_encode_YFSFid (bp , & vnode -> fid );
2381+ yfs_check_req (call , bp );
2382+
2383+ call -> cb_break = fc -> cb_break ;
2384+ afs_use_fs_server (call , fc -> cbi );
2385+ trace_afs_make_fs_call (call , & vnode -> fid );
2386+ afs_make_call (& fc -> ac , call , GFP_KERNEL );
2387+ return (struct yfs_acl * )afs_wait_for_call_to_complete (call , & fc -> ac );
2388+
2389+ nomem_call :
2390+ afs_put_call (call );
2391+ nomem :
2392+ fc -> ac .error = - ENOMEM ;
2393+ return ERR_PTR (- ENOMEM );
2394+ }
0 commit comments