diff options
-rw-r--r-- | fs/nfs/inode.c | 5 | ||||
-rw-r--r-- | fs/nfs/nfs3acl.c | 29 | ||||
-rw-r--r-- | fs/nfs/nfs3proc.c | 36 | ||||
-rw-r--r-- | include/linux/nfs_fs.h | 9 |
4 files changed, 73 insertions, 6 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 440b9cbb6f81..50a03f1504a1 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -490,6 +490,11 @@ nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent) | |||
490 | #else | 490 | #else |
491 | server->flags &= ~NFS_MOUNT_NOACL; | 491 | server->flags &= ~NFS_MOUNT_NOACL; |
492 | #endif /* CONFIG_NFS_V3_ACL */ | 492 | #endif /* CONFIG_NFS_V3_ACL */ |
493 | /* | ||
494 | * The VFS shouldn't apply the umask to mode bits. We will | ||
495 | * do so ourselves when necessary. | ||
496 | */ | ||
497 | sb->s_flags |= MS_POSIXACL; | ||
493 | if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN) | 498 | if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN) |
494 | server->namelen = NFS3_MAXNAMLEN; | 499 | server->namelen = NFS3_MAXNAMLEN; |
495 | sb->s_time_gran = 1; | 500 | sb->s_time_gran = 1; |
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c index 393ba79fc14f..89b6468700e7 100644 --- a/fs/nfs/nfs3acl.c +++ b/fs/nfs/nfs3acl.c | |||
@@ -301,3 +301,32 @@ int nfs3_proc_setacl(struct inode *inode, int type, struct posix_acl *acl) | |||
301 | fail: | 301 | fail: |
302 | return PTR_ERR(alloc); | 302 | return PTR_ERR(alloc); |
303 | } | 303 | } |
304 | |||
305 | int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode, | ||
306 | mode_t mode) | ||
307 | { | ||
308 | struct posix_acl *dfacl, *acl; | ||
309 | int error = 0; | ||
310 | |||
311 | dfacl = nfs3_proc_getacl(dir, ACL_TYPE_DEFAULT); | ||
312 | if (IS_ERR(dfacl)) { | ||
313 | error = PTR_ERR(dfacl); | ||
314 | return (error == -EOPNOTSUPP) ? 0 : error; | ||
315 | } | ||
316 | if (!dfacl) | ||
317 | return 0; | ||
318 | acl = posix_acl_clone(dfacl, GFP_KERNEL); | ||
319 | error = -ENOMEM; | ||
320 | if (!acl) | ||
321 | goto out_release_dfacl; | ||
322 | error = posix_acl_create_masq(acl, &mode); | ||
323 | if (error < 0) | ||
324 | goto out_release_acl; | ||
325 | error = nfs3_proc_setacls(inode, acl, S_ISDIR(inode->i_mode) ? | ||
326 | dfacl : NULL); | ||
327 | out_release_acl: | ||
328 | posix_acl_release(acl); | ||
329 | out_release_dfacl: | ||
330 | posix_acl_release(dfacl); | ||
331 | return error; | ||
332 | } | ||
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index d03bac0cc42f..a9ddc196224d 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c | |||
@@ -314,7 +314,8 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
314 | .fh = &fhandle, | 314 | .fh = &fhandle, |
315 | .fattr = &fattr | 315 | .fattr = &fattr |
316 | }; | 316 | }; |
317 | int status; | 317 | mode_t mode = sattr->ia_mode; |
318 | int status; | ||
318 | 319 | ||
319 | dprintk("NFS call create %s\n", dentry->d_name.name); | 320 | dprintk("NFS call create %s\n", dentry->d_name.name); |
320 | arg.createmode = NFS3_CREATE_UNCHECKED; | 321 | arg.createmode = NFS3_CREATE_UNCHECKED; |
@@ -324,6 +325,8 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
324 | arg.verifier[1] = current->pid; | 325 | arg.verifier[1] = current->pid; |
325 | } | 326 | } |
326 | 327 | ||
328 | sattr->ia_mode &= ~current->fs->umask; | ||
329 | |||
327 | again: | 330 | again: |
328 | dir_attr.valid = 0; | 331 | dir_attr.valid = 0; |
329 | fattr.valid = 0; | 332 | fattr.valid = 0; |
@@ -370,6 +373,9 @@ again: | |||
370 | nfs_refresh_inode(dentry->d_inode, &fattr); | 373 | nfs_refresh_inode(dentry->d_inode, &fattr); |
371 | dprintk("NFS reply setattr (post-create): %d\n", status); | 374 | dprintk("NFS reply setattr (post-create): %d\n", status); |
372 | } | 375 | } |
376 | if (status != 0) | ||
377 | goto out; | ||
378 | status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode); | ||
373 | out: | 379 | out: |
374 | dprintk("NFS reply create: %d\n", status); | 380 | dprintk("NFS reply create: %d\n", status); |
375 | return status; | 381 | return status; |
@@ -539,15 +545,24 @@ nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr) | |||
539 | .fh = &fhandle, | 545 | .fh = &fhandle, |
540 | .fattr = &fattr | 546 | .fattr = &fattr |
541 | }; | 547 | }; |
542 | int status; | 548 | int mode = sattr->ia_mode; |
549 | int status; | ||
543 | 550 | ||
544 | dprintk("NFS call mkdir %s\n", dentry->d_name.name); | 551 | dprintk("NFS call mkdir %s\n", dentry->d_name.name); |
545 | dir_attr.valid = 0; | 552 | dir_attr.valid = 0; |
546 | fattr.valid = 0; | 553 | fattr.valid = 0; |
554 | |||
555 | sattr->ia_mode &= ~current->fs->umask; | ||
556 | |||
547 | status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKDIR, &arg, &res, 0); | 557 | status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKDIR, &arg, &res, 0); |
548 | nfs_refresh_inode(dir, &dir_attr); | 558 | nfs_refresh_inode(dir, &dir_attr); |
549 | if (status == 0) | 559 | if (status != 0) |
550 | status = nfs_instantiate(dentry, &fhandle, &fattr); | 560 | goto out; |
561 | status = nfs_instantiate(dentry, &fhandle, &fattr); | ||
562 | if (status != 0) | ||
563 | goto out; | ||
564 | status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode); | ||
565 | out: | ||
551 | dprintk("NFS reply mkdir: %d\n", status); | 566 | dprintk("NFS reply mkdir: %d\n", status); |
552 | return status; | 567 | return status; |
553 | } | 568 | } |
@@ -642,6 +657,7 @@ nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
642 | .fh = &fh, | 657 | .fh = &fh, |
643 | .fattr = &fattr | 658 | .fattr = &fattr |
644 | }; | 659 | }; |
660 | mode_t mode = sattr->ia_mode; | ||
645 | int status; | 661 | int status; |
646 | 662 | ||
647 | switch (sattr->ia_mode & S_IFMT) { | 663 | switch (sattr->ia_mode & S_IFMT) { |
@@ -654,12 +670,20 @@ nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
654 | 670 | ||
655 | dprintk("NFS call mknod %s %u:%u\n", dentry->d_name.name, | 671 | dprintk("NFS call mknod %s %u:%u\n", dentry->d_name.name, |
656 | MAJOR(rdev), MINOR(rdev)); | 672 | MAJOR(rdev), MINOR(rdev)); |
673 | |||
674 | sattr->ia_mode &= ~current->fs->umask; | ||
675 | |||
657 | dir_attr.valid = 0; | 676 | dir_attr.valid = 0; |
658 | fattr.valid = 0; | 677 | fattr.valid = 0; |
659 | status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKNOD, &arg, &res, 0); | 678 | status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKNOD, &arg, &res, 0); |
660 | nfs_refresh_inode(dir, &dir_attr); | 679 | nfs_refresh_inode(dir, &dir_attr); |
661 | if (status == 0) | 680 | if (status != 0) |
662 | status = nfs_instantiate(dentry, &fh, &fattr); | 681 | goto out; |
682 | status = nfs_instantiate(dentry, &fh, &fattr); | ||
683 | if (status != 0) | ||
684 | goto out; | ||
685 | status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode); | ||
686 | out: | ||
663 | dprintk("NFS reply mknod: %d\n", status); | 687 | dprintk("NFS reply mknod: %d\n", status); |
664 | return status; | 688 | return status; |
665 | } | 689 | } |
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 3a5e442ac776..7662c5131b47 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h | |||
@@ -478,6 +478,15 @@ extern void nfs_readdata_release(struct rpc_task *task); | |||
478 | extern struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type); | 478 | extern struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type); |
479 | extern int nfs3_proc_setacl(struct inode *inode, int type, | 479 | extern int nfs3_proc_setacl(struct inode *inode, int type, |
480 | struct posix_acl *acl); | 480 | struct posix_acl *acl); |
481 | extern int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode, | ||
482 | mode_t mode); | ||
483 | #else | ||
484 | static inline int nfs3_proc_set_default_acl(struct inode *dir, | ||
485 | struct inode *inode, | ||
486 | mode_t mode) | ||
487 | { | ||
488 | return 0; | ||
489 | } | ||
481 | #endif /* CONFIG_NFS_V3_ACL */ | 490 | #endif /* CONFIG_NFS_V3_ACL */ |
482 | 491 | ||
483 | /* | 492 | /* |