#define FF_LAYOUT_POLL_RETRY_MAX     (15*HZ)
 
+static struct group_info       *ff_zero_group;
+
 static struct pnfs_layout_hdr *
 ff_layout_alloc_layout_hdr(struct inode *inode, gfp_t gfp_flags)
 {
                struct nfs4_ff_layout_mirror *mirror;
                struct nfs4_deviceid devid;
                struct nfs4_deviceid_node *idnode;
-               u32 ds_count;
-               u32 fh_count;
+               struct auth_cred acred = { .group_info = ff_zero_group };
+               struct rpc_cred *cred;
+               u32 ds_count, fh_count, id;
                int j;
 
                rc = -EIO;
                fls->mirror_array[i]->fh_versions_cnt = fh_count;
 
                /* user */
-               rc = decode_name(&stream, &fls->mirror_array[i]->uid);
+               rc = decode_name(&stream, &id);
                if (rc)
                        goto out_err_free;
 
+               acred.uid = make_kuid(&init_user_ns, id);
+
                /* group */
-               rc = decode_name(&stream, &fls->mirror_array[i]->gid);
+               rc = decode_name(&stream, &id);
                if (rc)
                        goto out_err_free;
 
+               acred.gid = make_kgid(&init_user_ns, id);
+
+               /* find the cred for it */
+               cred = rpc_lookup_generic_cred(&acred, 0, gfp_flags);
+               if (IS_ERR(cred)) {
+                       rc = PTR_ERR(cred);
+                       goto out_err_free;
+               }
+
+               rcu_assign_pointer(fls->mirror_array[i]->cred, cred);
+
                mirror = ff_layout_add_mirror(lh, fls->mirror_array[i]);
                if (mirror != fls->mirror_array[i]) {
+                       /* swap cred ptrs so free_mirror will clean up old */
+                       fls->mirror_array[i]->cred = xchg(&mirror->cred, cred);
                        ff_layout_free_mirror(fls->mirror_array[i]);
                        fls->mirror_array[i] = mirror;
                }
 
-               dprintk("%s: uid %d gid %d\n", __func__,
-                       fls->mirror_array[i]->uid,
-                       fls->mirror_array[i]->gid);
+               dprintk("%s: uid %u gid %u\n", __func__,
+                       from_kuid(&init_user_ns, acred.uid),
+                       from_kgid(&init_user_ns, acred.gid));
        }
 
        p = xdr_inline_decode(&stream, 4);
 {
        printk(KERN_INFO "%s: NFSv4 Flexfile Layout Driver Registering...\n",
               __func__);
+       if (!ff_zero_group) {
+               ff_zero_group = groups_alloc(0);
+               if (!ff_zero_group)
+                       return -ENOMEM;
+       }
        return pnfs_register_layoutdriver(&flexfilelayout_type);
 }
 
        printk(KERN_INFO "%s: NFSv4 Flexfile Layout Driver Unregistering...\n",
               __func__);
        pnfs_unregister_layoutdriver(&flexfilelayout_type);
+       if (ff_zero_group) {
+               put_group_info(ff_zero_group);
+               ff_zero_group = NULL;
+       }
 }
 
 MODULE_ALIAS("nfs-layouttype4-4");
 
        return 0;
 }
 
-/* currently we only support AUTH_NONE and AUTH_SYS */
-static rpc_authflavor_t
-nfs4_ff_layout_choose_authflavor(struct nfs4_ff_layout_mirror *mirror)
-{
-       if (mirror->uid == (u32)-1)
-               return RPC_AUTH_NULL;
-       return RPC_AUTH_UNIX;
-}
-
-/* fetch cred for NFSv3 DS */
-static int ff_layout_update_mirror_cred(struct nfs4_ff_layout_mirror *mirror,
-                                     struct nfs4_pnfs_ds *ds)
-{
-       if (ds->ds_clp && !mirror->cred &&
-           mirror->mirror_ds->ds_versions[0].version == 3) {
-               struct rpc_auth *auth = ds->ds_clp->cl_rpcclient->cl_auth;
-               struct rpc_cred *cred;
-               struct auth_cred acred = {
-                       .uid = make_kuid(&init_user_ns, mirror->uid),
-                       .gid = make_kgid(&init_user_ns, mirror->gid),
-               };
-
-               /* AUTH_NULL ignores acred */
-               cred = auth->au_ops->lookup_cred(auth, &acred, 0);
-               if (IS_ERR(cred)) {
-                       dprintk("%s: lookup_cred failed with %ld\n",
-                               __func__, PTR_ERR(cred));
-                       return PTR_ERR(cred);
-               } else {
-                       if (cmpxchg(&mirror->cred, NULL, cred))
-                               put_rpccred(cred);
-               }
-       }
-       return 0;
-}
-
 static struct rpc_cred *
 ff_layout_get_mirror_cred(struct nfs4_ff_layout_mirror *mirror, u32 iomode)
 {
        struct inode *ino = lseg->pls_layout->plh_inode;
        struct nfs_server *s = NFS_SERVER(ino);
        unsigned int max_payload;
-       rpc_authflavor_t flavor;
 
        if (!ff_layout_mirror_valid(lseg, mirror)) {
                pr_err_ratelimited("NFS: %s: No data server for offset index %d\n",
        /* matching smp_wmb() in _nfs4_pnfs_v3/4_ds_connect */
        smp_rmb();
        if (ds->ds_clp)
-               goto out_update_creds;
-
-       flavor = nfs4_ff_layout_choose_authflavor(mirror);
+               goto out;
 
        /* FIXME: For now we assume the server sent only one version of NFS
         * to use for the DS.
                             dataserver_retrans,
                             mirror->mirror_ds->ds_versions[0].version,
                             mirror->mirror_ds->ds_versions[0].minor_version,
-                            flavor);
+                            RPC_AUTH_UNIX);
 
        /* connect success, check rsize/wsize limit */
        if (ds->ds_clp) {
                } else
                        pnfs_error_mark_layout_for_return(ino, lseg);
                ds = NULL;
-               goto out;
        }
-out_update_creds:
-       if (ff_layout_update_mirror_cred(mirror, ds))
-               ds = NULL;
 out:
        return ds;
 }