aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/afs/internal.h1
-rw-r--r--fs/afs/xattr.c49
-rw-r--r--fs/afs/yfsclient.c67
3 files changed, 112 insertions, 5 deletions
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index b800b4e286d3..b3cd6e8ad59d 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -1383,6 +1383,7 @@ struct yfs_acl {
1383 1383
1384extern void yfs_free_opaque_acl(struct yfs_acl *); 1384extern void yfs_free_opaque_acl(struct yfs_acl *);
1385extern struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *, unsigned int); 1385extern struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *, unsigned int);
1386extern int yfs_fs_store_opaque_acl2(struct afs_fs_cursor *, const struct afs_acl *);
1386 1387
1387/* 1388/*
1388 * Miscellaneous inline functions. 1389 * Miscellaneous inline functions.
diff --git a/fs/afs/xattr.c b/fs/afs/xattr.c
index a5c82b0ad539..c81f85003fc7 100644
--- a/fs/afs/xattr.c
+++ b/fs/afs/xattr.c
@@ -226,9 +226,58 @@ out:
226 return ret; 226 return ret;
227} 227}
228 228
229/*
230 * Set a file's YFS ACL.
231 */
232static 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
229static const struct xattr_handler afs_xattr_yfs_handler = { 277static const struct xattr_handler afs_xattr_yfs_handler = {
230 .prefix = "afs.yfs.", 278 .prefix = "afs.yfs.",
231 .get = afs_xattr_get_yfs, 279 .get = afs_xattr_get_yfs,
280 .set = afs_xattr_set_yfs,
232}; 281};
233 282
234/* 283/*
diff --git a/fs/afs/yfsclient.c b/fs/afs/yfsclient.c
index 13eafa764d71..6d5af09e3f19 100644
--- a/fs/afs/yfsclient.c
+++ b/fs/afs/yfsclient.c
@@ -1768,9 +1768,10 @@ int yfs_fs_get_volume_status(struct afs_fs_cursor *fc,
1768} 1768}
1769 1769
1770/* 1770/*
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.
1772 */ 1773 */
1773static int yfs_deliver_fs_xxxx_lock(struct afs_call *call) 1774static int yfs_deliver_status_and_volsync(struct afs_call *call)
1774{ 1775{
1775 struct afs_vnode *vnode = call->reply[0]; 1776 struct afs_vnode *vnode = call->reply[0];
1776 const __be32 *bp; 1777 const __be32 *bp;
@@ -1800,7 +1801,7 @@ static int yfs_deliver_fs_xxxx_lock(struct afs_call *call)
1800static const struct afs_call_type yfs_RXYFSSetLock = { 1801static const struct afs_call_type yfs_RXYFSSetLock = {
1801 .name = "YFS.SetLock", 1802 .name = "YFS.SetLock",
1802 .op = yfs_FS_SetLock, 1803 .op = yfs_FS_SetLock,
1803 .deliver = yfs_deliver_fs_xxxx_lock, 1804 .deliver = yfs_deliver_status_and_volsync,
1804 .done = afs_lock_op_done, 1805 .done = afs_lock_op_done,
1805 .destructor = afs_flat_call_destructor, 1806 .destructor = afs_flat_call_destructor,
1806}; 1807};
@@ -1811,7 +1812,7 @@ static const struct afs_call_type yfs_RXYFSSetLock = {
1811static const struct afs_call_type yfs_RXYFSExtendLock = { 1812static const struct afs_call_type yfs_RXYFSExtendLock = {
1812 .name = "YFS.ExtendLock", 1813 .name = "YFS.ExtendLock",
1813 .op = yfs_FS_ExtendLock, 1814 .op = yfs_FS_ExtendLock,
1814 .deliver = yfs_deliver_fs_xxxx_lock, 1815 .deliver = yfs_deliver_status_and_volsync,
1815 .done = afs_lock_op_done, 1816 .done = afs_lock_op_done,
1816 .destructor = afs_flat_call_destructor, 1817 .destructor = afs_flat_call_destructor,
1817}; 1818};
@@ -1822,7 +1823,7 @@ static const struct afs_call_type yfs_RXYFSExtendLock = {
1822static const struct afs_call_type yfs_RXYFSReleaseLock = { 1823static const struct afs_call_type yfs_RXYFSReleaseLock = {
1823 .name = "YFS.ReleaseLock", 1824 .name = "YFS.ReleaseLock",
1824 .op = yfs_FS_ReleaseLock, 1825 .op = yfs_FS_ReleaseLock,
1825 .deliver = yfs_deliver_fs_xxxx_lock, 1826 .deliver = yfs_deliver_status_and_volsync,
1826 .destructor = afs_flat_call_destructor, 1827 .destructor = afs_flat_call_destructor,
1827}; 1828};
1828 1829
@@ -2392,3 +2393,59 @@ nomem:
2392 fc->ac.error = -ENOMEM; 2393 fc->ac.error = -ENOMEM;
2393 return ERR_PTR(-ENOMEM); 2394 return ERR_PTR(-ENOMEM);
2394} 2395}
2396
2397/*
2398 * YFS.StoreOpaqueACL2 operation type
2399 */
2400static 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 */
2410int 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}