diff options
Diffstat (limited to 'fs/nfsd/nfs4acl.c')
-rw-r--r-- | fs/nfsd/nfs4acl.c | 39 |
1 files changed, 22 insertions, 17 deletions
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index d714156a19fd..59fd76651781 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c | |||
@@ -146,35 +146,43 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, | |||
146 | int size = 0; | 146 | int size = 0; |
147 | 147 | ||
148 | pacl = get_acl(inode, ACL_TYPE_ACCESS); | 148 | pacl = get_acl(inode, ACL_TYPE_ACCESS); |
149 | if (!pacl) { | 149 | if (!pacl) |
150 | pacl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); | 150 | pacl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); |
151 | if (IS_ERR(pacl)) | 151 | |
152 | return PTR_ERR(pacl); | 152 | if (IS_ERR(pacl)) |
153 | } | 153 | return PTR_ERR(pacl); |
154 | |||
154 | /* allocate for worst case: one (deny, allow) pair each: */ | 155 | /* allocate for worst case: one (deny, allow) pair each: */ |
155 | size += 2 * pacl->a_count; | 156 | size += 2 * pacl->a_count; |
156 | 157 | ||
157 | if (S_ISDIR(inode->i_mode)) { | 158 | if (S_ISDIR(inode->i_mode)) { |
158 | flags = NFS4_ACL_DIR; | 159 | flags = NFS4_ACL_DIR; |
159 | dpacl = get_acl(inode, ACL_TYPE_DEFAULT); | 160 | dpacl = get_acl(inode, ACL_TYPE_DEFAULT); |
161 | if (IS_ERR(dpacl)) { | ||
162 | error = PTR_ERR(dpacl); | ||
163 | goto rel_pacl; | ||
164 | } | ||
165 | |||
160 | if (dpacl) | 166 | if (dpacl) |
161 | size += 2 * dpacl->a_count; | 167 | size += 2 * dpacl->a_count; |
162 | } | 168 | } |
163 | 169 | ||
164 | *acl = nfs4_acl_new(size); | 170 | *acl = kmalloc(nfs4_acl_bytes(size), GFP_KERNEL); |
165 | if (*acl == NULL) { | 171 | if (*acl == NULL) { |
166 | error = -ENOMEM; | 172 | error = -ENOMEM; |
167 | goto out; | 173 | goto out; |
168 | } | 174 | } |
175 | (*acl)->naces = 0; | ||
169 | 176 | ||
170 | _posix_to_nfsv4_one(pacl, *acl, flags & ~NFS4_ACL_TYPE_DEFAULT); | 177 | _posix_to_nfsv4_one(pacl, *acl, flags & ~NFS4_ACL_TYPE_DEFAULT); |
171 | 178 | ||
172 | if (dpacl) | 179 | if (dpacl) |
173 | _posix_to_nfsv4_one(dpacl, *acl, flags | NFS4_ACL_TYPE_DEFAULT); | 180 | _posix_to_nfsv4_one(dpacl, *acl, flags | NFS4_ACL_TYPE_DEFAULT); |
174 | 181 | ||
175 | out: | 182 | out: |
176 | posix_acl_release(pacl); | ||
177 | posix_acl_release(dpacl); | 183 | posix_acl_release(dpacl); |
184 | rel_pacl: | ||
185 | posix_acl_release(pacl); | ||
178 | return error; | 186 | return error; |
179 | } | 187 | } |
180 | 188 | ||
@@ -872,16 +880,13 @@ ace2type(struct nfs4_ace *ace) | |||
872 | return -1; | 880 | return -1; |
873 | } | 881 | } |
874 | 882 | ||
875 | struct nfs4_acl * | 883 | /* |
876 | nfs4_acl_new(int n) | 884 | * return the size of the struct nfs4_acl required to represent an acl |
885 | * with @entries entries. | ||
886 | */ | ||
887 | int nfs4_acl_bytes(int entries) | ||
877 | { | 888 | { |
878 | struct nfs4_acl *acl; | 889 | return sizeof(struct nfs4_acl) + entries * sizeof(struct nfs4_ace); |
879 | |||
880 | acl = kmalloc(sizeof(*acl) + n*sizeof(struct nfs4_ace), GFP_KERNEL); | ||
881 | if (acl == NULL) | ||
882 | return NULL; | ||
883 | acl->naces = 0; | ||
884 | return acl; | ||
885 | } | 890 | } |
886 | 891 | ||
887 | static struct { | 892 | static struct { |
@@ -935,5 +940,5 @@ __be32 nfs4_acl_write_who(struct xdr_stream *xdr, int who) | |||
935 | return 0; | 940 | return 0; |
936 | } | 941 | } |
937 | WARN_ON_ONCE(1); | 942 | WARN_ON_ONCE(1); |
938 | return -1; | 943 | return nfserr_serverfault; |
939 | } | 944 | } |