aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/inode.c5
-rw-r--r--fs/nfs/nfs3acl.c29
-rw-r--r--fs/nfs/nfs3proc.c36
-rw-r--r--include/linux/nfs_fs.h9
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)
301fail: 301fail:
302 return PTR_ERR(alloc); 302 return PTR_ERR(alloc);
303} 303}
304
305int 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);
327out_release_acl:
328 posix_acl_release(acl);
329out_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
327again: 330again:
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);
373out: 379out:
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);
565out:
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);
686out:
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);
478extern struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type); 478extern struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type);
479extern int nfs3_proc_setacl(struct inode *inode, int type, 479extern int nfs3_proc_setacl(struct inode *inode, int type,
480 struct posix_acl *acl); 480 struct posix_acl *acl);
481extern int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode,
482 mode_t mode);
483#else
484static 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/*