summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@citi.umich.edu>2005-06-22 19:16:23 +0200
committerTrond Myklebust <Trond.Myklebust@netapp.com>2005-06-22 22:07:14 +0200
commit4b580ee3dc00f9828a9a7aad2724f448fdc94075 (patch)
treea39ca6a5be4766420c6cc6ea8141fb421280bcb3
parent[PATCH] NFSv4: Client-side xdr for writing NFSv4 acls (diff)
downloadlinux-4b580ee3dc00f9828a9a7aad2724f448fdc94075.tar.xz
linux-4b580ee3dc00f9828a9a7aad2724f448fdc94075.zip
[PATCH] NFSv4: ACL support for the NFSv4 client: write
Client-side write support for NFSv4 ACLs. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/nfs4proc.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index c91c09938a55..d969dd13e7db 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2216,6 +2216,29 @@ static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen)
return ret;
}
+static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
+{
+ struct nfs_server *server = NFS_SERVER(inode);
+ struct page *pages[NFS4ACL_MAXPAGES];
+ struct nfs_setaclargs arg = {
+ .fh = NFS_FH(inode),
+ .acl_pages = pages,
+ .acl_len = buflen,
+ };
+ struct rpc_message msg = {
+ .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETACL],
+ .rpc_argp = &arg,
+ .rpc_resp = NULL,
+ };
+ int ret;
+
+ if (!nfs4_server_supports_acls(server))
+ return -EOPNOTSUPP;
+ buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
+ ret = rpc_call_sync(NFS_SERVER(inode)->client, &msg, 0);
+ return ret;
+}
+
static int
nfs4_async_handle_error(struct rpc_task *task, struct nfs_server *server)
{
@@ -2792,7 +2815,16 @@ nfs4_proc_lock(struct file *filp, int cmd, struct file_lock *request)
int nfs4_setxattr(struct dentry *dentry, const char *key, const void *buf,
size_t buflen, int flags)
{
- return -EOPNOTSUPP;
+ struct inode *inode = dentry->d_inode;
+
+ if (strcmp(key, XATTR_NAME_NFSV4_ACL) != 0)
+ return -EOPNOTSUPP;
+
+ if (!S_ISREG(inode->i_mode) &&
+ (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
+ return -EPERM;
+
+ return nfs4_proc_set_acl(inode, buf, buflen);
}
/* The getxattr man page suggests returning -ENODATA for unknown attributes,