summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoe Gorse <jhgorse@gmail.com>2019-04-25 09:26:52 -0400
committerDavid Howells <dhowells@redhat.com>2019-05-07 11:48:44 -0400
commitb10494af4989d2d20679d0e3b7d1a45c2f8f8f1a (patch)
tree27a9fcdea021ddcb324da97695aa2efb8326ff69
parent260f082bae6dcf70aeae2cc3e24aecb55bdb1c99 (diff)
afs: implement acl setting
Implements the setting of ACLs in AFS by means of setting the afs.acl extended attribute on the file. Signed-off-by: Joe Gorse <jhgorse@gmail.com> Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r--fs/afs/afs_fs.h1
-rw-r--r--fs/afs/fsclient.c61
-rw-r--r--fs/afs/internal.h1
-rw-r--r--fs/afs/xattr.c52
-rw-r--r--include/trace/events/afs.h1
5 files changed, 110 insertions, 6 deletions
diff --git a/fs/afs/afs_fs.h b/fs/afs/afs_fs.h
index 4df1f1eec0ab..18a54ca422f8 100644
--- a/fs/afs/afs_fs.h
+++ b/fs/afs/afs_fs.h
@@ -20,6 +20,7 @@ enum AFS_FS_Operations {
20 FSFETCHACL = 131, /* AFS Fetch file ACL */ 20 FSFETCHACL = 131, /* AFS Fetch file ACL */
21 FSFETCHSTATUS = 132, /* AFS Fetch file status */ 21 FSFETCHSTATUS = 132, /* AFS Fetch file status */
22 FSSTOREDATA = 133, /* AFS Store file data */ 22 FSSTOREDATA = 133, /* AFS Store file data */
23 FSSTOREACL = 134, /* AFS Store file ACL */
23 FSSTORESTATUS = 135, /* AFS Store file status */ 24 FSSTORESTATUS = 135, /* AFS Store file status */
24 FSREMOVEFILE = 136, /* AFS Remove a file */ 25 FSREMOVEFILE = 136, /* AFS Remove a file */
25 FSCREATEFILE = 137, /* AFS Create a file */ 26 FSCREATEFILE = 137, /* AFS Create a file */
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c
index 283f486c59f4..7f1722b9e432 100644
--- a/fs/afs/fsclient.c
+++ b/fs/afs/fsclient.c
@@ -836,9 +836,10 @@ int afs_fs_create(struct afs_fs_cursor *fc,
836} 836}
837 837
838/* 838/*
839 * deliver reply data to an FS.RemoveFile or FS.RemoveDir 839 * Deliver reply data to any operation that returns file status and volume
840 * sync.
840 */ 841 */
841static int afs_deliver_fs_remove(struct afs_call *call) 842static int afs_deliver_fs_status_and_vol(struct afs_call *call)
842{ 843{
843 struct afs_vnode *vnode = call->reply[0]; 844 struct afs_vnode *vnode = call->reply[0];
844 const __be32 *bp; 845 const __be32 *bp;
@@ -868,14 +869,14 @@ static int afs_deliver_fs_remove(struct afs_call *call)
868static const struct afs_call_type afs_RXFSRemoveFile = { 869static const struct afs_call_type afs_RXFSRemoveFile = {
869 .name = "FS.RemoveFile", 870 .name = "FS.RemoveFile",
870 .op = afs_FS_RemoveFile, 871 .op = afs_FS_RemoveFile,
871 .deliver = afs_deliver_fs_remove, 872 .deliver = afs_deliver_fs_status_and_vol,
872 .destructor = afs_flat_call_destructor, 873 .destructor = afs_flat_call_destructor,
873}; 874};
874 875
875static const struct afs_call_type afs_RXFSRemoveDir = { 876static const struct afs_call_type afs_RXFSRemoveDir = {
876 .name = "FS.RemoveDir", 877 .name = "FS.RemoveDir",
877 .op = afs_FS_RemoveDir, 878 .op = afs_FS_RemoveDir,
878 .deliver = afs_deliver_fs_remove, 879 .deliver = afs_deliver_fs_status_and_vol,
879 .destructor = afs_flat_call_destructor, 880 .destructor = afs_flat_call_destructor,
880}; 881};
881 882
@@ -2513,3 +2514,55 @@ struct afs_acl *afs_fs_fetch_acl(struct afs_fs_cursor *fc)
2513 afs_make_call(&fc->ac, call, GFP_KERNEL); 2514 afs_make_call(&fc->ac, call, GFP_KERNEL);
2514 return (struct afs_acl *)afs_wait_for_call_to_complete(call, &fc->ac); 2515 return (struct afs_acl *)afs_wait_for_call_to_complete(call, &fc->ac);
2515} 2516}
2517
2518/*
2519 * FS.StoreACL operation type
2520 */
2521static const struct afs_call_type afs_RXFSStoreACL = {
2522 .name = "FS.StoreACL",
2523 .op = afs_FS_StoreACL,
2524 .deliver = afs_deliver_fs_status_and_vol,
2525 .destructor = afs_flat_call_destructor,
2526};
2527
2528/*
2529 * Fetch the ACL for a file.
2530 */
2531int afs_fs_store_acl(struct afs_fs_cursor *fc, const struct afs_acl *acl)
2532{
2533 struct afs_vnode *vnode = fc->vnode;
2534 struct afs_call *call;
2535 struct afs_net *net = afs_v2net(vnode);
2536 size_t size;
2537 __be32 *bp;
2538
2539 _enter(",%x,{%llx:%llu},,",
2540 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
2541
2542 size = round_up(acl->size, 4);
2543 call = afs_alloc_flat_call(net, &afs_RXFSStoreACL,
2544 5 * 4 + size, (21 + 6) * 4);
2545 if (!call) {
2546 fc->ac.error = -ENOMEM;
2547 return -ENOMEM;
2548 }
2549
2550 call->key = fc->key;
2551 call->reply[0] = vnode;
2552 call->reply[2] = NULL; /* volsync */
2553
2554 /* marshall the parameters */
2555 bp = call->request;
2556 bp[0] = htonl(FSSTOREACL);
2557 bp[1] = htonl(vnode->fid.vid);
2558 bp[2] = htonl(vnode->fid.vnode);
2559 bp[3] = htonl(vnode->fid.unique);
2560 bp[4] = htonl(acl->size);
2561 memcpy(&bp[5], acl->data, acl->size);
2562 if (acl->size != size)
2563 memset((void *)&bp[5] + acl->size, 0, size - acl->size);
2564
2565 trace_afs_make_fs_call(call, &vnode->fid);
2566 afs_make_call(&fc->ac, call, GFP_KERNEL);
2567 return afs_wait_for_call_to_complete(call, &fc->ac);
2568}
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index 683b802c20ea..5269824244c6 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -983,6 +983,7 @@ struct afs_acl {
983}; 983};
984 984
985extern struct afs_acl *afs_fs_fetch_acl(struct afs_fs_cursor *); 985extern struct afs_acl *afs_fs_fetch_acl(struct afs_fs_cursor *);
986extern int afs_fs_store_acl(struct afs_fs_cursor *, const struct afs_acl *);
986 987
987/* 988/*
988 * fs_probe.c 989 * fs_probe.c
diff --git a/fs/afs/xattr.c b/fs/afs/xattr.c
index b7d3d714d8ff..31db360947a6 100644
--- a/fs/afs/xattr.c
+++ b/fs/afs/xattr.c
@@ -80,9 +80,57 @@ static int afs_xattr_get_acl(const struct xattr_handler *handler,
80 return ret; 80 return ret;
81} 81}
82 82
83/*
84 * Set a file's AFS3 ACL.
85 */
86static int afs_xattr_set_acl(const struct xattr_handler *handler,
87 struct dentry *dentry,
88 struct inode *inode, const char *name,
89 const void *buffer, size_t size, int flags)
90{
91 struct afs_fs_cursor fc;
92 struct afs_vnode *vnode = AFS_FS_I(inode);
93 struct afs_acl *acl = NULL;
94 struct key *key;
95 int ret;
96
97 if (flags == XATTR_CREATE)
98 return -EINVAL;
99
100 key = afs_request_key(vnode->volume->cell);
101 if (IS_ERR(key))
102 return PTR_ERR(key);
103
104 acl = kmalloc(sizeof(*acl) + size, GFP_KERNEL);
105 if (!acl) {
106 key_put(key);
107 return -ENOMEM;
108 }
109
110 acl->size = size;
111 memcpy(acl->data, buffer, size);
112
113 ret = -ERESTARTSYS;
114 if (afs_begin_vnode_operation(&fc, vnode, key)) {
115 while (afs_select_fileserver(&fc)) {
116 fc.cb_break = afs_calc_vnode_cb_break(vnode);
117 afs_fs_store_acl(&fc, acl);
118 }
119
120 afs_check_for_remote_deletion(&fc, fc.vnode);
121 afs_vnode_commit_status(&fc, vnode, fc.cb_break);
122 ret = afs_end_vnode_operation(&fc);
123 }
124
125 kfree(acl);
126 key_put(key);
127 return ret;
128}
129
83static const struct xattr_handler afs_xattr_afs_acl_handler = { 130static const struct xattr_handler afs_xattr_afs_acl_handler = {
84 .name = "afs.acl", 131 .name = "afs.acl",
85 .get = afs_xattr_get_acl, 132 .get = afs_xattr_get_acl,
133 .set = afs_xattr_set_acl,
86}; 134};
87 135
88/* 136/*
diff --git a/include/trace/events/afs.h b/include/trace/events/afs.h
index 25c2e089c6ea..562f854ac4bf 100644
--- a/include/trace/events/afs.h
+++ b/include/trace/events/afs.h
@@ -36,6 +36,7 @@ enum afs_fs_operation {
36 afs_FS_FetchACL = 131, /* AFS Fetch file ACL */ 36 afs_FS_FetchACL = 131, /* AFS Fetch file ACL */
37 afs_FS_FetchStatus = 132, /* AFS Fetch file status */ 37 afs_FS_FetchStatus = 132, /* AFS Fetch file status */
38 afs_FS_StoreData = 133, /* AFS Store file data */ 38 afs_FS_StoreData = 133, /* AFS Store file data */
39 afs_FS_StoreACL = 134, /* AFS Store file ACL */
39 afs_FS_StoreStatus = 135, /* AFS Store file status */ 40 afs_FS_StoreStatus = 135, /* AFS Store file status */
40 afs_FS_RemoveFile = 136, /* AFS Remove a file */ 41 afs_FS_RemoveFile = 136, /* AFS Remove a file */
41 afs_FS_CreateFile = 137, /* AFS Create a file */ 42 afs_FS_CreateFile = 137, /* AFS Create a file */