aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs3acl.c
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@suse.de>2005-06-22 13:16:27 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2005-06-22 16:07:24 -0400
commit055ffbea0596942579b0dae71d5dab78de8135f6 (patch)
tree4799088989e9923c45089cab905f40247af52a45 /fs/nfs/nfs3acl.c
parentb7fa0554cf1ba6d6895cd0a5b02989a26e0bc704 (diff)
[PATCH] NFS: Fix handling of the umask when an NFSv3 default acl is present.
NFSv3 has no concept of a umask on the server side: The client applies the umask locally, and sends the effective permissions to the server. This behavior is wrong when files are created in a directory that has a default ACL. In this case, the umask is supposed to be ignored, and only the default ACL determines the file's effective permissions. Usually its the server's task to conditionally apply the umask. But since the server knows nothing about the umask, we have to do it on the client side. This patch tries to fetch the parent directory's default ACL before creating a new file, computes the appropriate create mode to send to the server, and finally sets the new file's access and default acl appropriately. Many thanks to Buck Huppmann <buchk@pobox.com> for sending the initial version of this patch, as well as for arguing why we need this change. Signed-off-by: Andreas Gruenbacher <agruen@suse.de> Acked-by: Olaf Kirch <okir@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs3acl.c')
-rw-r--r--fs/nfs/nfs3acl.c29
1 files changed, 29 insertions, 0 deletions
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}