aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2019-04-30 13:30:21 -0400
committerDavid Howells <dhowells@redhat.com>2019-05-07 11:48:44 -0400
commitae46578b963f6daa9853791ab4c6ac1d6375937c (patch)
tree2ec257ba3ec3b10321c03ea6205879edabd28d9d
parentb10494af4989d2d20679d0e3b7d1a45c2f8f8f1a (diff)
afs: Get YFS ACLs and information through xattrs
The YFS/AuriStor variant of AFS provides more capable ACLs and provides per-volume ACLs and per-file ACLs as well as per-directory ACLs. It also provides some extra information that can be retrieved through four ACLs: (1) afs.yfs.acl The YFS file ACL (not the same format as afs.acl). (2) afs.yfs.vol_acl The YFS volume ACL. (3) afs.yfs.acl_inherited "1" if a file's ACL is inherited from its parent directory, "0" otherwise. (4) afs.yfs.acl_num_cleaned The number of of ACEs removed from the ACL by the server because the PT entries were removed from the PTS database (ie. the subject is no longer known). Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r--fs/afs/internal.h13
-rw-r--r--fs/afs/protocol_yfs.h6
-rw-r--r--fs/afs/xattr.c101
-rw-r--r--fs/afs/yfsclient.c188
4 files changed, 304 insertions, 4 deletions
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index 5269824244c6..b800b4e286d3 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -1371,6 +1371,19 @@ extern int yfs_fs_inline_bulk_status(struct afs_fs_cursor *, struct afs_net *,
1371 struct afs_callback *, unsigned int, 1371 struct afs_callback *, unsigned int,
1372 struct afs_volsync *); 1372 struct afs_volsync *);
1373 1373
1374struct yfs_acl {
1375 struct afs_acl *acl; /* Dir/file/symlink ACL */
1376 struct afs_acl *vol_acl; /* Whole volume ACL */
1377 u32 inherit_flag; /* True if ACL is inherited from parent dir */
1378 u32 num_cleaned; /* Number of ACEs removed due to subject removal */
1379 unsigned int flags;
1380#define YFS_ACL_WANT_ACL 0x01 /* Set if caller wants ->acl */
1381#define YFS_ACL_WANT_VOL_ACL 0x02 /* Set if caller wants ->vol_acl */
1382};
1383
1384extern void yfs_free_opaque_acl(struct yfs_acl *);
1385extern struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *, unsigned int);
1386
1374/* 1387/*
1375 * Miscellaneous inline functions. 1388 * Miscellaneous inline functions.
1376 */ 1389 */
diff --git a/fs/afs/protocol_yfs.h b/fs/afs/protocol_yfs.h
index d443e2bfa094..915b9d10cdf3 100644
--- a/fs/afs/protocol_yfs.h
+++ b/fs/afs/protocol_yfs.h
@@ -31,9 +31,9 @@ enum YFS_CM_Operations {
31}; 31};
32 32
33enum YFS_FS_Operations { 33enum YFS_FS_Operations {
34 YFSFETCHACL = 64131, /* YFS Fetch file ACL */ 34 YFSFETCHACL = 64131, /* YFS Fetch file AFS3 ACL */
35 YFSFETCHSTATUS = 64132, /* YFS Fetch file status */ 35 YFSFETCHSTATUS = 64132, /* YFS Fetch file status */
36 YFSSTOREACL = 64134, /* YFS Store file ACL */ 36 YFSSTOREACL = 64134, /* YFS Store file AFS3 ACL */
37 YFSSTORESTATUS = 64135, /* YFS Store file status */ 37 YFSSTORESTATUS = 64135, /* YFS Store file status */
38 YFSREMOVEFILE = 64136, /* YFS Remove a file */ 38 YFSREMOVEFILE = 64136, /* YFS Remove a file */
39 YFSCREATEFILE = 64137, /* YFS Create a file */ 39 YFSCREATEFILE = 64137, /* YFS Create a file */
@@ -49,7 +49,7 @@ enum YFS_FS_Operations {
49 YFSRELEASELOCK = 64158, /* YFS Release a file lock */ 49 YFSRELEASELOCK = 64158, /* YFS Release a file lock */
50 YFSLOOKUP = 64161, /* YFS lookup file in directory */ 50 YFSLOOKUP = 64161, /* YFS lookup file in directory */
51 YFSFLUSHCPS = 64165, 51 YFSFLUSHCPS = 64165,
52 YFSFETCHOPAQUEACL = 64168, 52 YFSFETCHOPAQUEACL = 64168, /* YFS Fetch file YFS ACL */
53 YFSWHOAMI = 64170, 53 YFSWHOAMI = 64170,
54 YFSREMOVEACL = 64171, 54 YFSREMOVEACL = 64171,
55 YFSREMOVEFILE2 = 64173, 55 YFSREMOVEFILE2 = 64173,
diff --git a/fs/afs/xattr.c b/fs/afs/xattr.c
index 31db360947a6..a5c82b0ad539 100644
--- a/fs/afs/xattr.c
+++ b/fs/afs/xattr.c
@@ -19,7 +19,11 @@ static const char afs_xattr_list[] =
19 "afs.acl\0" 19 "afs.acl\0"
20 "afs.cell\0" 20 "afs.cell\0"
21 "afs.fid\0" 21 "afs.fid\0"
22 "afs.volume"; 22 "afs.volume\0"
23 "afs.yfs.acl\0"
24 "afs.yfs.acl_inherited\0"
25 "afs.yfs.acl_num_cleaned\0"
26 "afs.yfs.vol_acl";
23 27
24/* 28/*
25 * Retrieve a list of the supported xattrs. 29 * Retrieve a list of the supported xattrs.
@@ -134,6 +138,100 @@ static const struct xattr_handler afs_xattr_afs_acl_handler = {
134}; 138};
135 139
136/* 140/*
141 * Get a file's YFS ACL.
142 */
143static int afs_xattr_get_yfs(const struct xattr_handler *handler,
144 struct dentry *dentry,
145 struct inode *inode, const char *name,
146 void *buffer, size_t size)
147{
148 struct afs_fs_cursor fc;
149 struct afs_vnode *vnode = AFS_FS_I(inode);
150 struct yfs_acl *yacl = NULL;
151 struct key *key;
152 unsigned int flags = 0;
153 char buf[16], *data;
154 int which = 0, dsize, ret;
155
156 if (strcmp(name, "acl") == 0)
157 which = 0;
158 else if (strcmp(name, "acl_inherited") == 0)
159 which = 1;
160 else if (strcmp(name, "acl_num_cleaned") == 0)
161 which = 2;
162 else if (strcmp(name, "vol_acl") == 0)
163 which = 3;
164 else
165 return -EOPNOTSUPP;
166
167 if (which == 0)
168 flags |= YFS_ACL_WANT_ACL;
169 else if (which == 3)
170 flags |= YFS_ACL_WANT_VOL_ACL;
171
172 key = afs_request_key(vnode->volume->cell);
173 if (IS_ERR(key))
174 return PTR_ERR(key);
175
176 ret = -ERESTARTSYS;
177 if (afs_begin_vnode_operation(&fc, vnode, key)) {
178 while (afs_select_fileserver(&fc)) {
179 fc.cb_break = afs_calc_vnode_cb_break(vnode);
180 yacl = yfs_fs_fetch_opaque_acl(&fc, flags);
181 }
182
183 afs_check_for_remote_deletion(&fc, fc.vnode);
184 afs_vnode_commit_status(&fc, vnode, fc.cb_break);
185 ret = afs_end_vnode_operation(&fc);
186 }
187
188 if (ret == 0) {
189 switch (which) {
190 case 0:
191 data = yacl->acl->data;
192 dsize = yacl->acl->size;
193 break;
194 case 1:
195 data = buf;
196 dsize = snprintf(buf, sizeof(buf), "%u",
197 yacl->inherit_flag);
198 break;
199 case 2:
200 data = buf;
201 dsize = snprintf(buf, sizeof(buf), "%u",
202 yacl->num_cleaned);
203 break;
204 case 3:
205 data = yacl->vol_acl->data;
206 dsize = yacl->vol_acl->size;
207 break;
208 default:
209 ret = -EOPNOTSUPP;
210 goto out;
211 }
212
213 ret = dsize;
214 if (size > 0) {
215 if (dsize > size) {
216 ret = -ERANGE;
217 goto out;
218 }
219 memcpy(buffer, data, dsize);
220 }
221 }
222
223out:
224 yfs_free_opaque_acl(yacl);
225 key_put(key);
226 return ret;
227}
228
229static const struct xattr_handler afs_xattr_yfs_handler = {
230 .prefix = "afs.yfs.",
231 .get = afs_xattr_get_yfs,
232};
233
234/*
137 * Get the name of the cell on which a file resides. 235 * Get the name of the cell on which a file resides.
138 */ 236 */
139static int afs_xattr_get_cell(const struct xattr_handler *handler, 237static int afs_xattr_get_cell(const struct xattr_handler *handler,
@@ -227,5 +325,6 @@ const struct xattr_handler *afs_xattr_handlers[] = {
227 &afs_xattr_afs_cell_handler, 325 &afs_xattr_afs_cell_handler,
228 &afs_xattr_afs_fid_handler, 326 &afs_xattr_afs_fid_handler,
229 &afs_xattr_afs_volume_handler, 327 &afs_xattr_afs_volume_handler,
328 &afs_xattr_yfs_handler, /* afs.yfs. prefix */
230 NULL 329 NULL
231}; 330};
diff --git a/fs/afs/yfsclient.c b/fs/afs/yfsclient.c
index 055840aa07f6..13eafa764d71 100644
--- a/fs/afs/yfsclient.c
+++ b/fs/afs/yfsclient.c
@@ -2204,3 +2204,191 @@ int yfs_fs_inline_bulk_status(struct afs_fs_cursor *fc,
2204 afs_make_call(&fc->ac, call, GFP_NOFS); 2204 afs_make_call(&fc->ac, call, GFP_NOFS);
2205 return afs_wait_for_call_to_complete(call, &fc->ac); 2205 return afs_wait_for_call_to_complete(call, &fc->ac);
2206} 2206}
2207
2208/*
2209 * Deliver reply data to an YFS.FetchOpaqueACL.
2210 */
2211static int yfs_deliver_fs_fetch_opaque_acl(struct afs_call *call)
2212{
2213 struct afs_volsync *volsync = call->reply[2];
2214 struct afs_vnode *vnode = call->reply[1];
2215 struct yfs_acl *yacl = call->reply[0];
2216 struct afs_acl *acl;
2217 const __be32 *bp;
2218 unsigned int size;
2219 int ret;
2220
2221 _enter("{%u}", call->unmarshall);
2222
2223 switch (call->unmarshall) {
2224 case 0:
2225 afs_extract_to_tmp(call);
2226 call->unmarshall++;
2227
2228 /* Extract the file ACL length */
2229 case 1: