diff options
| -rw-r--r-- | fs/afs/internal.h | 1 | ||||
| -rw-r--r-- | fs/afs/xattr.c | 49 | ||||
| -rw-r--r-- | fs/afs/yfsclient.c | 67 |
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 | ||
| 1384 | extern void yfs_free_opaque_acl(struct yfs_acl *); | 1384 | extern void yfs_free_opaque_acl(struct yfs_acl *); |
| 1385 | extern struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *, unsigned int); | 1385 | 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 *); | ||
| 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 | */ | ||
| 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 | |||
| 229 | static const struct xattr_handler afs_xattr_yfs_handler = { | 277 | static 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 | */ |
| 1773 | static int yfs_deliver_fs_xxxx_lock(struct afs_call *call) | 1774 | static 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) | |||
| 1800 | static const struct afs_call_type yfs_RXYFSSetLock = { | 1801 | static 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 = { | |||
| 1811 | static const struct afs_call_type yfs_RXYFSExtendLock = { | 1812 | static 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 = { | |||
| 1822 | static const struct afs_call_type yfs_RXYFSReleaseLock = { | 1823 | static 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 | */ | ||
| 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 | } | ||
