NFSv4: nfs4_proc_set_acl needs to restore NFS_CAP_UIDGID_NOMAP on error.

Currently if __nfs4_proc_set_acl fails with NFS4ERR_BADOWNER it
re-enables the idmapper by clearing NFS_CAP_UIDGID_NOMAP before
retrying again. The NFS_CAP_UIDGID_NOMAP remains cleared even if
the retry fails. This causes problem for subsequent setattr
requests for v4 server that does not have idmapping configured.

This patch modifies nfs4_proc_set_acl to detect NFS4ERR_BADOWNER
and NFS4ERR_BADNAME and skips the retry, since the kernel isn't
involved in encoding the ACEs, and return -EINVAL.

Steps to reproduce the problem:

# mount -o vers=4.1,sec=sys server:/export/test /tmp/mnt
# touch /tmp/mnt/file1
# chown 99 /tmp/mnt/file1
# nfs4_setfacl -a A::unknown.user@xyz.com:wrtncy /tmp/mnt/file1
Failed setxattr operation: Invalid argument
# chown 99 /tmp/mnt/file1
chown: changing ownership of ‘/tmp/mnt/file1’: Invalid argument
# umount /tmp/mnt
# mount -o vers=4.1,sec=sys server:/export/test /tmp/mnt
# chown 99 /tmp/mnt/file1
#

v2: detect NFS4ERR_BADOWNER and NFS4ERR_BADNAME and skip retry
in nfs4_proc_set_acl.
Signed-off-by: Dai Ngo <dai.ngo@oracle.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>

authored by Dai Ngo and committed by Trond Myklebust f8849e20 8124c8a6

+8
+8
fs/nfs/nfs4proc.c
··· 5968 do { 5969 err = __nfs4_proc_set_acl(inode, buf, buflen); 5970 trace_nfs4_set_acl(inode, err); 5971 err = nfs4_handle_exception(NFS_SERVER(inode), err, 5972 &exception); 5973 } while (exception.retry);
··· 5968 do { 5969 err = __nfs4_proc_set_acl(inode, buf, buflen); 5970 trace_nfs4_set_acl(inode, err); 5971 + if (err == -NFS4ERR_BADOWNER || err == -NFS4ERR_BADNAME) { 5972 + /* 5973 + * no need to retry since the kernel 5974 + * isn't involved in encoding the ACEs. 5975 + */ 5976 + err = -EINVAL; 5977 + break; 5978 + } 5979 err = nfs4_handle_exception(NFS_SERVER(inode), err, 5980 &exception); 5981 } while (exception.retry);