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