Skip to content

Commit f5e4546

Browse files
committed
afs: Implement YFS ACL setting
Implement the setting of YFS ACLs in AFS through the interface of setting the afs.yfs.acl extended attribute on the file. Signed-off-by: David Howells <[email protected]>
1 parent ae46578 commit f5e4546

File tree

3 files changed

+112
-5
lines changed

3 files changed

+112
-5
lines changed

fs/afs/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1383,6 +1383,7 @@ struct yfs_acl {
13831383

13841384
extern void yfs_free_opaque_acl(struct yfs_acl *);
13851385
extern struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *, unsigned int);
1386+
extern int yfs_fs_store_opaque_acl2(struct afs_fs_cursor *, const struct afs_acl *);
13861387

13871388
/*
13881389
* Miscellaneous inline functions.

fs/afs/xattr.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,58 @@ static int afs_xattr_get_yfs(const struct xattr_handler *handler,
226226
return ret;
227227
}
228228

229+
/*
230+
* Set a file's YFS ACL.
231+
*/
232+
static int afs_xattr_set_yfs(const struct xattr_handler *handler,
233+
struct dentry *dentry,
234+
struct inode *inode, const char *name,
235+
const void *buffer, size_t size, int flags)
236+
{
237+
struct afs_fs_cursor fc;
238+
struct afs_vnode *vnode = AFS_FS_I(inode);
239+
struct afs_acl *acl = NULL;
240+
struct key *key;
241+
int ret;
242+
243+
if (flags == XATTR_CREATE ||
244+
strcmp(name, "acl") != 0)
245+
return -EINVAL;
246+
247+
key = afs_request_key(vnode->volume->cell);
248+
if (IS_ERR(key))
249+
return PTR_ERR(key);
250+
251+
acl = kmalloc(sizeof(*acl) + size, GFP_KERNEL);
252+
if (!acl) {
253+
key_put(key);
254+
return -ENOMEM;
255+
}
256+
257+
acl->size = size;
258+
memcpy(acl->data, buffer, size);
259+
260+
ret = -ERESTARTSYS;
261+
if (afs_begin_vnode_operation(&fc, vnode, key)) {
262+
while (afs_select_fileserver(&fc)) {
263+
fc.cb_break = afs_calc_vnode_cb_break(vnode);
264+
yfs_fs_store_opaque_acl2(&fc, acl);
265+
}
266+
267+
afs_check_for_remote_deletion(&fc, fc.vnode);
268+
afs_vnode_commit_status(&fc, vnode, fc.cb_break);
269+
ret = afs_end_vnode_operation(&fc);
270+
}
271+
272+
kfree(acl);
273+
key_put(key);
274+
return ret;
275+
}
276+
229277
static const struct xattr_handler afs_xattr_yfs_handler = {
230278
.prefix = "afs.yfs.",
231279
.get = afs_xattr_get_yfs,
280+
.set = afs_xattr_set_yfs,
232281
};
233282

234283
/*

fs/afs/yfsclient.c

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1768,9 +1768,10 @@ int yfs_fs_get_volume_status(struct afs_fs_cursor *fc,
17681768
}
17691769

17701770
/*
1771-
* Deliver reply data to an YFS.SetLock, YFS.ExtendLock or YFS.ReleaseLock
1771+
* Deliver reply data to operations that just return a file status and a volume
1772+
* sync record.
17721773
*/
1773-
static int yfs_deliver_fs_xxxx_lock(struct afs_call *call)
1774+
static int yfs_deliver_status_and_volsync(struct afs_call *call)
17741775
{
17751776
struct afs_vnode *vnode = call->reply[0];
17761777
const __be32 *bp;
@@ -1800,7 +1801,7 @@ static int yfs_deliver_fs_xxxx_lock(struct afs_call *call)
18001801
static const struct afs_call_type yfs_RXYFSSetLock = {
18011802
.name = "YFS.SetLock",
18021803
.op = yfs_FS_SetLock,
1803-
.deliver = yfs_deliver_fs_xxxx_lock,
1804+
.deliver = yfs_deliver_status_and_volsync,
18041805
.done = afs_lock_op_done,
18051806
.destructor = afs_flat_call_destructor,
18061807
};
@@ -1811,7 +1812,7 @@ static const struct afs_call_type yfs_RXYFSSetLock = {
18111812
static const struct afs_call_type yfs_RXYFSExtendLock = {
18121813
.name = "YFS.ExtendLock",
18131814
.op = yfs_FS_ExtendLock,
1814-
.deliver = yfs_deliver_fs_xxxx_lock,
1815+
.deliver = yfs_deliver_status_and_volsync,
18151816
.done = afs_lock_op_done,
18161817
.destructor = afs_flat_call_destructor,
18171818
};
@@ -1822,7 +1823,7 @@ static const struct afs_call_type yfs_RXYFSExtendLock = {
18221823
static const struct afs_call_type yfs_RXYFSReleaseLock = {
18231824
.name = "YFS.ReleaseLock",
18241825
.op = yfs_FS_ReleaseLock,
1825-
.deliver = yfs_deliver_fs_xxxx_lock,
1826+
.deliver = yfs_deliver_status_and_volsync,
18261827
.destructor = afs_flat_call_destructor,
18271828
};
18281829

@@ -2392,3 +2393,59 @@ struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *fc,
23922393
fc->ac.error = -ENOMEM;
23932394
return ERR_PTR(-ENOMEM);
23942395
}
2396+
2397+
/*
2398+
* YFS.StoreOpaqueACL2 operation type
2399+
*/
2400+
static const struct afs_call_type yfs_RXYFSStoreOpaqueACL2 = {
2401+
.name = "YFS.StoreOpaqueACL2",
2402+
.op = yfs_FS_StoreOpaqueACL2,
2403+
.deliver = yfs_deliver_status_and_volsync,
2404+
.destructor = afs_flat_call_destructor,
2405+
};
2406+
2407+
/*
2408+
* Fetch the YFS ACL for a file.
2409+
*/
2410+
int yfs_fs_store_opaque_acl2(struct afs_fs_cursor *fc, const struct afs_acl *acl)
2411+
{
2412+
struct afs_vnode *vnode = fc->vnode;
2413+
struct afs_call *call;
2414+
struct afs_net *net = afs_v2net(vnode);
2415+
size_t size;
2416+
__be32 *bp;
2417+
2418+
_enter(",%x,{%llx:%llu},,",
2419+
key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
2420+
2421+
size = round_up(acl->size, 4);
2422+
call = afs_alloc_flat_call(net, &yfs_RXYFSStoreStatus,
2423+
sizeof(__be32) * 2 +
2424+
sizeof(struct yfs_xdr_YFSFid) +
2425+
sizeof(__be32) + size,
2426+
sizeof(struct yfs_xdr_YFSFetchStatus) +
2427+
sizeof(struct yfs_xdr_YFSVolSync));
2428+
if (!call) {
2429+
fc->ac.error = -ENOMEM;
2430+
return -ENOMEM;
2431+
}
2432+
2433+
call->key = fc->key;
2434+
call->reply[0] = vnode;
2435+
call->reply[2] = NULL; /* volsync */
2436+
2437+
/* marshall the parameters */
2438+
bp = call->request;
2439+
bp = xdr_encode_u32(bp, YFSSTOREOPAQUEACL2);
2440+
bp = xdr_encode_u32(bp, 0); /* RPC flags */
2441+
bp = xdr_encode_YFSFid(bp, &vnode->fid);
2442+
bp = xdr_encode_u32(bp, acl->size);
2443+
memcpy(bp, acl->data, acl->size);
2444+
if (acl->size != size)
2445+
memset((void *)bp + acl->size, 0, size - acl->size);
2446+
yfs_check_req(call, bp);
2447+
2448+
trace_afs_make_fs_call(call, &vnode->fid);
2449+
afs_make_call(&fc->ac, call, GFP_KERNEL);
2450+
return afs_wait_for_call_to_complete(call, &fc->ac);
2451+
}

0 commit comments

Comments
 (0)