1 #include <linux/fs.h> 2 #include <linux/nfs.h> 3 #include <linux/nfs3.h> 4 #include <linux/nfs_fs.h> 5 #include <linux/posix_acl_xattr.h> 6 #include <linux/nfsacl.h> 7 8 #include "internal.h" 9 10 #define NFSDBG_FACILITY NFSDBG_PROC 11 12 ssize_t nfs3_listxattr(struct dentry *dentry, char *buffer, size_t size) 13 { 14 struct inode *inode = dentry->d_inode; 15 struct posix_acl *acl; 16 int pos=0, len=0; 17 18 # define output(s) do { \ 19 if (pos + sizeof(s) <= size) { \ 20 memcpy(buffer + pos, s, sizeof(s)); \ 21 pos += sizeof(s); \ 22 } \ 23 len += sizeof(s); \ 24 } while(0) 25 26 acl = nfs3_proc_getacl(inode, ACL_TYPE_ACCESS); 27 if (IS_ERR(acl)) 28 return PTR_ERR(acl); 29 if (acl) { 30 output("system.posix_acl_access"); 31 posix_acl_release(acl); 32 } 33 34 if (S_ISDIR(inode->i_mode)) { 35 acl = nfs3_proc_getacl(inode, ACL_TYPE_DEFAULT); 36 if (IS_ERR(acl)) 37 return PTR_ERR(acl); 38 if (acl) { 39 output("system.posix_acl_default"); 40 posix_acl_release(acl); 41 } 42 } 43 44 # undef output 45 46 if (!buffer || len <= size) 47 return len; 48 return -ERANGE; 49 } 50 51 ssize_t nfs3_getxattr(struct dentry *dentry, const char *name, 52 void *buffer, size_t size) 53 { 54 struct inode *inode = dentry->d_inode; 55 struct posix_acl *acl; 56 int type, error = 0; 57 58 if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) 59 type = ACL_TYPE_ACCESS; 60 else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) 61 type = ACL_TYPE_DEFAULT; 62 else 63 return -EOPNOTSUPP; 64 65 acl = nfs3_proc_getacl(inode, type); 66 if (IS_ERR(acl)) 67 return PTR_ERR(acl); 68 else if (acl) { 69 if (type == ACL_TYPE_ACCESS && acl->a_count == 0) 70 error = -ENODATA; 71 else 72 error = posix_acl_to_xattr(acl, buffer, size); 73 posix_acl_release(acl); 74 } else 75 error = -ENODATA; 76 77 return error; 78 } 79 80 int nfs3_setxattr(struct dentry *dentry, const char *name, 81 const void *value, size_t size, int flags) 82 { 83 struct inode *inode = dentry->d_inode; 84 struct posix_acl *acl; 85 int type, error; 86 87 if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) 88 type = ACL_TYPE_ACCESS; 89 else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) 90 type = ACL_TYPE_DEFAULT; 91 else 92 return -EOPNOTSUPP; 93 94 acl = posix_acl_from_xattr(value, size); 95 if (IS_ERR(acl)) 96 return PTR_ERR(acl); 97 error = nfs3_proc_setacl(inode, type, acl); 98 posix_acl_release(acl); 99 100 return error; 101 } 102 103 int nfs3_removexattr(struct dentry *dentry, const char *name) 104 { 105 struct inode *inode = dentry->d_inode; 106 int type; 107 108 if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) 109 type = ACL_TYPE_ACCESS; 110 else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) 111 type = ACL_TYPE_DEFAULT; 112 else 113 return -EOPNOTSUPP; 114 115 return nfs3_proc_setacl(inode, type, NULL); 116 } 117 118 static void __nfs3_forget_cached_acls(struct nfs_inode *nfsi) 119 { 120 if (!IS_ERR(nfsi->acl_access)) { 121 posix_acl_release(nfsi->acl_access); 122 nfsi->acl_access = ERR_PTR(-EAGAIN); 123 } 124 if (!IS_ERR(nfsi->acl_default)) { 125 posix_acl_release(nfsi->acl_default); 126 nfsi->acl_default = ERR_PTR(-EAGAIN); 127 } 128 } 129 130 void nfs3_forget_cached_acls(struct inode *inode) 131 { 132 dprintk("NFS: nfs3_forget_cached_acls(%s/%ld)\n", inode->i_sb->s_id, 133 inode->i_ino); 134 spin_lock(&inode->i_lock); 135 __nfs3_forget_cached_acls(NFS_I(inode)); 136 spin_unlock(&inode->i_lock); 137 } 138 139 static struct posix_acl *nfs3_get_cached_acl(struct inode *inode, int type) 140 { 141 struct nfs_inode *nfsi = NFS_I(inode); 142 struct posix_acl *acl = ERR_PTR(-EINVAL); 143 144 spin_lock(&inode->i_lock); 145 switch(type) { 146 case ACL_TYPE_ACCESS: 147 acl = nfsi->acl_access; 148 break; 149 150 case ACL_TYPE_DEFAULT: 151 acl = nfsi->acl_default; 152 break; 153 154 default: 155 goto out; 156 } 157 if (IS_ERR(acl)) 158 acl = ERR_PTR(-EAGAIN); 159 else 160 acl = posix_acl_dup(acl); 161 out: 162 spin_unlock(&inode->i_lock); 163 dprintk("NFS: nfs3_get_cached_acl(%s/%ld, %d) = %p\n", inode->i_sb->s_id, 164 inode->i_ino, type, acl); 165 return acl; 166 } 167 168 static void nfs3_cache_acls(struct inode *inode, struct posix_acl *acl, 169 struct posix_acl *dfacl) 170 { 171 struct nfs_inode *nfsi = NFS_I(inode); 172 173 dprintk("nfs3_cache_acls(%s/%ld, %p, %p)\n", inode->i_sb->s_id, 174 inode->i_ino, acl, dfacl); 175 spin_lock(&inode->i_lock); 176 __nfs3_forget_cached_acls(NFS_I(inode)); 177 if (!IS_ERR(acl)) 178 nfsi->acl_access = posix_acl_dup(acl); 179 if (!IS_ERR(dfacl)) 180 nfsi->acl_default = posix_acl_dup(dfacl); 181 spin_unlock(&inode->i_lock); 182 } 183 184 struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type) 185 { 186 struct nfs_server *server = NFS_SERVER(inode); 187 struct nfs_fattr fattr; 188 struct page *pages[NFSACL_MAXPAGES] = { }; 189 struct nfs3_getaclargs args = { 190 .fh = NFS_FH(inode), 191 /* The xdr layer may allocate pages here. */ 192 .pages = pages, 193 }; 194 struct nfs3_getaclres res = { 195 .fattr = &fattr, 196 }; 197 struct rpc_message msg = { 198 .rpc_argp = &args, 199 .rpc_resp = &res, 200 }; 201 struct posix_acl *acl; 202 int status, count; 203 204 if (!nfs_server_capable(inode, NFS_CAP_ACLS)) 205 return ERR_PTR(-EOPNOTSUPP); 206 207 status = nfs_revalidate_inode(server, inode); 208 if (status < 0) 209 return ERR_PTR(status); 210 acl = nfs3_get_cached_acl(inode, type); 211 if (acl != ERR_PTR(-EAGAIN)) 212 return acl; 213 acl = NULL; 214 215 /* 216 * Only get the access acl when explicitly requested: We don't 217 * need it for access decisions, and only some applications use 218 * it. Applications which request the access acl first are not 219 * penalized from this optimization. 220 */ 221 if (type == ACL_TYPE_ACCESS) 222 args.mask |= NFS_ACLCNT|NFS_ACL; 223 if (S_ISDIR(inode->i_mode)) 224 args.mask |= NFS_DFACLCNT|NFS_DFACL; 225 if (args.mask == 0) 226 return NULL; 227 228 dprintk("NFS call getacl\n"); 229 msg.rpc_proc = &server->client_acl->cl_procinfo[ACLPROC3_GETACL]; 230 nfs_fattr_init(&fattr); 231 status = rpc_call_sync(server->client_acl, &msg, 0); 232 dprintk("NFS reply getacl: %d\n", status); 233 234 /* pages may have been allocated at the xdr layer. */ 235 for (count = 0; count < NFSACL_MAXPAGES && args.pages[count]; count++) 236 __free_page(args.pages[count]); 237 238 switch (status) { 239 case 0: 240 status = nfs_refresh_inode(inode, &fattr); 241 break; 242 case -EPFNOSUPPORT: 243 case -EPROTONOSUPPORT: 244 dprintk("NFS_V3_ACL extension not supported; disabling\n"); 245 server->caps &= ~NFS_CAP_ACLS; 246 case -ENOTSUPP: 247 status = -EOPNOTSUPP; 248 default: 249 goto getout; 250 } 251 if ((args.mask & res.mask) != args.mask) { 252 status = -EIO; 253 goto getout; 254 } 255 256 if (res.acl_access != NULL) { 257 if (posix_acl_equiv_mode(res.acl_access, NULL) == 0) { 258 posix_acl_release(res.acl_access); 259 res.acl_access = NULL; 260 } 261 } 262 nfs3_cache_acls(inode, 263 (res.mask & NFS_ACL) ? res.acl_access : ERR_PTR(-EINVAL), 264 (res.mask & NFS_DFACL) ? res.acl_default : ERR_PTR(-EINVAL)); 265 266 switch(type) { 267 case ACL_TYPE_ACCESS: 268 acl = res.acl_access; 269 res.acl_access = NULL; 270 break; 271 272 case ACL_TYPE_DEFAULT: 273 acl = res.acl_default; 274 res.acl_default = NULL; 275 } 276 277 getout: 278 posix_acl_release(res.acl_access); 279 posix_acl_release(res.acl_default); 280 281 if (status != 0) { 282 posix_acl_release(acl); 283 acl = ERR_PTR(status); 284 } 285 return acl; 286 } 287 288 static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, 289 struct posix_acl *dfacl) 290 { 291 struct nfs_server *server = NFS_SERVER(inode); 292 struct nfs_fattr fattr; 293 struct page *pages[NFSACL_MAXPAGES]; 294 struct nfs3_setaclargs args = { 295 .inode = inode, 296 .mask = NFS_ACL, 297 .acl_access = acl, 298 .pages = pages, 299 }; 300 struct rpc_message msg = { 301 .rpc_argp = &args, 302 .rpc_resp = &fattr, 303 }; 304 int status; 305 306 status = -EOPNOTSUPP; 307 if (!nfs_server_capable(inode, NFS_CAP_ACLS)) 308 goto out; 309 310 /* We are doing this here, because XDR marshalling can only 311 return -ENOMEM. */ 312 status = -ENOSPC; 313 if (acl != NULL && acl->a_count > NFS_ACL_MAX_ENTRIES) 314 goto out; 315 if (dfacl != NULL && dfacl->a_count > NFS_ACL_MAX_ENTRIES) 316 goto out; 317 if (S_ISDIR(inode->i_mode)) { 318 args.mask |= NFS_DFACL; 319 args.acl_default = dfacl; 320 args.len = nfsacl_size(acl, dfacl); 321 } else 322 args.len = nfsacl_size(acl, NULL); 323 324 if (args.len > NFS_ACL_INLINE_BUFSIZE) { 325 unsigned int npages = 1 + ((args.len - 1) >> PAGE_SHIFT); 326 327 status = -ENOMEM; 328 do { 329 args.pages[args.npages] = alloc_page(GFP_KERNEL); 330 if (args.pages[args.npages] == NULL) 331 goto out_freepages; 332 args.npages++; 333 } while (args.npages < npages); 334 } 335 336 dprintk("NFS call setacl\n"); 337 msg.rpc_proc = &server->client_acl->cl_procinfo[ACLPROC3_SETACL]; 338 nfs_fattr_init(&fattr); 339 status = rpc_call_sync(server->client_acl, &msg, 0); 340 nfs_access_zap_cache(inode); 341 nfs_zap_acl_cache(inode); 342 dprintk("NFS reply setacl: %d\n", status); 343 344 switch (status) { 345 case 0: 346 status = nfs_refresh_inode(inode, &fattr); 347 nfs3_cache_acls(inode, acl, dfacl); 348 break; 349 case -EPFNOSUPPORT: 350 case -EPROTONOSUPPORT: 351 dprintk("NFS_V3_ACL SETACL RPC not supported" 352 "(will not retry)\n"); 353 server->caps &= ~NFS_CAP_ACLS; 354 case -ENOTSUPP: 355 status = -EOPNOTSUPP; 356 } 357 out_freepages: 358 while (args.npages != 0) { 359 args.npages--; 360 __free_page(args.pages[args.npages]); 361 } 362 out: 363 return status; 364 } 365 366 int nfs3_proc_setacl(struct inode *inode, int type, struct posix_acl *acl) 367 { 368 struct posix_acl *alloc = NULL, *dfacl = NULL; 369 int status; 370 371 if (S_ISDIR(inode->i_mode)) { 372 switch(type) { 373 case ACL_TYPE_ACCESS: 374 alloc = dfacl = nfs3_proc_getacl(inode, 375 ACL_TYPE_DEFAULT); 376 if (IS_ERR(alloc)) 377 goto fail; 378 break; 379 380 case ACL_TYPE_DEFAULT: 381 dfacl = acl; 382 alloc = acl = nfs3_proc_getacl(inode, 383 ACL_TYPE_ACCESS); 384 if (IS_ERR(alloc)) 385 goto fail; 386 break; 387 388 default: 389 return -EINVAL; 390 } 391 } else if (type != ACL_TYPE_ACCESS) 392 return -EINVAL; 393 394 if (acl == NULL) { 395 alloc = acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); 396 if (IS_ERR(alloc)) 397 goto fail; 398 } 399 status = nfs3_proc_setacls(inode, acl, dfacl); 400 posix_acl_release(alloc); 401 return status; 402 403 fail: 404 return PTR_ERR(alloc); 405 } 406 407 int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode, 408 mode_t mode) 409 { 410 struct posix_acl *dfacl, *acl; 411 int error = 0; 412 413 dfacl = nfs3_proc_getacl(dir, ACL_TYPE_DEFAULT); 414 if (IS_ERR(dfacl)) { 415 error = PTR_ERR(dfacl); 416 return (error == -EOPNOTSUPP) ? 0 : error; 417 } 418 if (!dfacl) 419 return 0; 420 acl = posix_acl_clone(dfacl, GFP_KERNEL); 421 error = -ENOMEM; 422 if (!acl) 423 goto out_release_dfacl; 424 error = posix_acl_create_masq(acl, &mode); 425 if (error < 0) 426 goto out_release_acl; 427 error = nfs3_proc_setacls(inode, acl, S_ISDIR(inode->i_mode) ? 428 dfacl : NULL); 429 out_release_acl: 430 posix_acl_release(acl); 431 out_release_dfacl: 432 posix_acl_release(dfacl); 433 return error; 434 } 435