Loading fs/afs/internal.h +1 −0 Original line number Diff line number Diff line Loading @@ -1383,6 +1383,7 @@ struct yfs_acl { extern void yfs_free_opaque_acl(struct yfs_acl *); extern struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *, unsigned int); extern int yfs_fs_store_opaque_acl2(struct afs_fs_cursor *, const struct afs_acl *); /* * Miscellaneous inline functions. Loading fs/afs/xattr.c +49 −0 Original line number Diff line number Diff line Loading @@ -226,9 +226,58 @@ static int afs_xattr_get_yfs(const struct xattr_handler *handler, return ret; } /* * Set a file's YFS ACL. */ static int afs_xattr_set_yfs(const struct xattr_handler *handler, struct dentry *dentry, struct inode *inode, const char *name, const void *buffer, size_t size, int flags) { struct afs_fs_cursor fc; struct afs_vnode *vnode = AFS_FS_I(inode); struct afs_acl *acl = NULL; struct key *key; int ret; if (flags == XATTR_CREATE || strcmp(name, "acl") != 0) return -EINVAL; key = afs_request_key(vnode->volume->cell); if (IS_ERR(key)) return PTR_ERR(key); acl = kmalloc(sizeof(*acl) + size, GFP_KERNEL); if (!acl) { key_put(key); return -ENOMEM; } acl->size = size; memcpy(acl->data, buffer, size); ret = -ERESTARTSYS; if (afs_begin_vnode_operation(&fc, vnode, key)) { while (afs_select_fileserver(&fc)) { fc.cb_break = afs_calc_vnode_cb_break(vnode); yfs_fs_store_opaque_acl2(&fc, acl); } afs_check_for_remote_deletion(&fc, fc.vnode); afs_vnode_commit_status(&fc, vnode, fc.cb_break); ret = afs_end_vnode_operation(&fc); } kfree(acl); key_put(key); return ret; } static const struct xattr_handler afs_xattr_yfs_handler = { .prefix = "afs.yfs.", .get = afs_xattr_get_yfs, .set = afs_xattr_set_yfs, }; /* Loading fs/afs/yfsclient.c +62 −5 Original line number Diff line number Diff line Loading @@ -1768,9 +1768,10 @@ int yfs_fs_get_volume_status(struct afs_fs_cursor *fc, } /* * Deliver reply data to an YFS.SetLock, YFS.ExtendLock or YFS.ReleaseLock * Deliver reply data to operations that just return a file status and a volume * sync record. */ static int yfs_deliver_fs_xxxx_lock(struct afs_call *call) static int yfs_deliver_status_and_volsync(struct afs_call *call) { struct afs_vnode *vnode = call->reply[0]; const __be32 *bp; Loading Loading @@ -1800,7 +1801,7 @@ static int yfs_deliver_fs_xxxx_lock(struct afs_call *call) static const struct afs_call_type yfs_RXYFSSetLock = { .name = "YFS.SetLock", .op = yfs_FS_SetLock, .deliver = yfs_deliver_fs_xxxx_lock, .deliver = yfs_deliver_status_and_volsync, .done = afs_lock_op_done, .destructor = afs_flat_call_destructor, }; Loading @@ -1811,7 +1812,7 @@ static const struct afs_call_type yfs_RXYFSSetLock = { static const struct afs_call_type yfs_RXYFSExtendLock = { .name = "YFS.ExtendLock", .op = yfs_FS_ExtendLock, .deliver = yfs_deliver_fs_xxxx_lock, .deliver = yfs_deliver_status_and_volsync, .done = afs_lock_op_done, .destructor = afs_flat_call_destructor, }; Loading @@ -1822,7 +1823,7 @@ static const struct afs_call_type yfs_RXYFSExtendLock = { static const struct afs_call_type yfs_RXYFSReleaseLock = { .name = "YFS.ReleaseLock", .op = yfs_FS_ReleaseLock, .deliver = yfs_deliver_fs_xxxx_lock, .deliver = yfs_deliver_status_and_volsync, .destructor = afs_flat_call_destructor, }; Loading Loading @@ -2392,3 +2393,59 @@ struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *fc, fc->ac.error = -ENOMEM; return ERR_PTR(-ENOMEM); } /* * YFS.StoreOpaqueACL2 operation type */ static const struct afs_call_type yfs_RXYFSStoreOpaqueACL2 = { .name = "YFS.StoreOpaqueACL2", .op = yfs_FS_StoreOpaqueACL2, .deliver = yfs_deliver_status_and_volsync, .destructor = afs_flat_call_destructor, }; /* * Fetch the YFS ACL for a file. */ int yfs_fs_store_opaque_acl2(struct afs_fs_cursor *fc, const struct afs_acl *acl) { struct afs_vnode *vnode = fc->vnode; struct afs_call *call; struct afs_net *net = afs_v2net(vnode); size_t size; __be32 *bp; _enter(",%x,{%llx:%llu},,", key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); size = round_up(acl->size, 4); call = afs_alloc_flat_call(net, &yfs_RXYFSStoreStatus, sizeof(__be32) * 2 + sizeof(struct yfs_xdr_YFSFid) + sizeof(__be32) + size, sizeof(struct yfs_xdr_YFSFetchStatus) + sizeof(struct yfs_xdr_YFSVolSync)); if (!call) { fc->ac.error = -ENOMEM; return -ENOMEM; } call->key = fc->key; call->reply[0] = vnode; call->reply[2] = NULL; /* volsync */ /* marshall the parameters */ bp = call->request; bp = xdr_encode_u32(bp, YFSSTOREOPAQUEACL2); bp = xdr_encode_u32(bp, 0); /* RPC flags */ bp = xdr_encode_YFSFid(bp, &vnode->fid); bp = xdr_encode_u32(bp, acl->size); memcpy(bp, acl->data, acl->size); if (acl->size != size) memset((void *)bp + acl->size, 0, size - acl->size); yfs_check_req(call, bp); trace_afs_make_fs_call(call, &vnode->fid); afs_make_call(&fc->ac, call, GFP_KERNEL); return afs_wait_for_call_to_complete(call, &fc->ac); } Loading
fs/afs/internal.h +1 −0 Original line number Diff line number Diff line Loading @@ -1383,6 +1383,7 @@ struct yfs_acl { extern void yfs_free_opaque_acl(struct yfs_acl *); extern struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *, unsigned int); extern int yfs_fs_store_opaque_acl2(struct afs_fs_cursor *, const struct afs_acl *); /* * Miscellaneous inline functions. Loading
fs/afs/xattr.c +49 −0 Original line number Diff line number Diff line Loading @@ -226,9 +226,58 @@ static int afs_xattr_get_yfs(const struct xattr_handler *handler, return ret; } /* * Set a file's YFS ACL. */ static int afs_xattr_set_yfs(const struct xattr_handler *handler, struct dentry *dentry, struct inode *inode, const char *name, const void *buffer, size_t size, int flags) { struct afs_fs_cursor fc; struct afs_vnode *vnode = AFS_FS_I(inode); struct afs_acl *acl = NULL; struct key *key; int ret; if (flags == XATTR_CREATE || strcmp(name, "acl") != 0) return -EINVAL; key = afs_request_key(vnode->volume->cell); if (IS_ERR(key)) return PTR_ERR(key); acl = kmalloc(sizeof(*acl) + size, GFP_KERNEL); if (!acl) { key_put(key); return -ENOMEM; } acl->size = size; memcpy(acl->data, buffer, size); ret = -ERESTARTSYS; if (afs_begin_vnode_operation(&fc, vnode, key)) { while (afs_select_fileserver(&fc)) { fc.cb_break = afs_calc_vnode_cb_break(vnode); yfs_fs_store_opaque_acl2(&fc, acl); } afs_check_for_remote_deletion(&fc, fc.vnode); afs_vnode_commit_status(&fc, vnode, fc.cb_break); ret = afs_end_vnode_operation(&fc); } kfree(acl); key_put(key); return ret; } static const struct xattr_handler afs_xattr_yfs_handler = { .prefix = "afs.yfs.", .get = afs_xattr_get_yfs, .set = afs_xattr_set_yfs, }; /* Loading
fs/afs/yfsclient.c +62 −5 Original line number Diff line number Diff line Loading @@ -1768,9 +1768,10 @@ int yfs_fs_get_volume_status(struct afs_fs_cursor *fc, } /* * Deliver reply data to an YFS.SetLock, YFS.ExtendLock or YFS.ReleaseLock * Deliver reply data to operations that just return a file status and a volume * sync record. */ static int yfs_deliver_fs_xxxx_lock(struct afs_call *call) static int yfs_deliver_status_and_volsync(struct afs_call *call) { struct afs_vnode *vnode = call->reply[0]; const __be32 *bp; Loading Loading @@ -1800,7 +1801,7 @@ static int yfs_deliver_fs_xxxx_lock(struct afs_call *call) static const struct afs_call_type yfs_RXYFSSetLock = { .name = "YFS.SetLock", .op = yfs_FS_SetLock, .deliver = yfs_deliver_fs_xxxx_lock, .deliver = yfs_deliver_status_and_volsync, .done = afs_lock_op_done, .destructor = afs_flat_call_destructor, }; Loading @@ -1811,7 +1812,7 @@ static const struct afs_call_type yfs_RXYFSSetLock = { static const struct afs_call_type yfs_RXYFSExtendLock = { .name = "YFS.ExtendLock", .op = yfs_FS_ExtendLock, .deliver = yfs_deliver_fs_xxxx_lock, .deliver = yfs_deliver_status_and_volsync, .done = afs_lock_op_done, .destructor = afs_flat_call_destructor, }; Loading @@ -1822,7 +1823,7 @@ static const struct afs_call_type yfs_RXYFSExtendLock = { static const struct afs_call_type yfs_RXYFSReleaseLock = { .name = "YFS.ReleaseLock", .op = yfs_FS_ReleaseLock, .deliver = yfs_deliver_fs_xxxx_lock, .deliver = yfs_deliver_status_and_volsync, .destructor = afs_flat_call_destructor, }; Loading Loading @@ -2392,3 +2393,59 @@ struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *fc, fc->ac.error = -ENOMEM; return ERR_PTR(-ENOMEM); } /* * YFS.StoreOpaqueACL2 operation type */ static const struct afs_call_type yfs_RXYFSStoreOpaqueACL2 = { .name = "YFS.StoreOpaqueACL2", .op = yfs_FS_StoreOpaqueACL2, .deliver = yfs_deliver_status_and_volsync, .destructor = afs_flat_call_destructor, }; /* * Fetch the YFS ACL for a file. */ int yfs_fs_store_opaque_acl2(struct afs_fs_cursor *fc, const struct afs_acl *acl) { struct afs_vnode *vnode = fc->vnode; struct afs_call *call; struct afs_net *net = afs_v2net(vnode); size_t size; __be32 *bp; _enter(",%x,{%llx:%llu},,", key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); size = round_up(acl->size, 4); call = afs_alloc_flat_call(net, &yfs_RXYFSStoreStatus, sizeof(__be32) * 2 + sizeof(struct yfs_xdr_YFSFid) + sizeof(__be32) + size, sizeof(struct yfs_xdr_YFSFetchStatus) + sizeof(struct yfs_xdr_YFSVolSync)); if (!call) { fc->ac.error = -ENOMEM; return -ENOMEM; } call->key = fc->key; call->reply[0] = vnode; call->reply[2] = NULL; /* volsync */ /* marshall the parameters */ bp = call->request; bp = xdr_encode_u32(bp, YFSSTOREOPAQUEACL2); bp = xdr_encode_u32(bp, 0); /* RPC flags */ bp = xdr_encode_YFSFid(bp, &vnode->fid); bp = xdr_encode_u32(bp, acl->size); memcpy(bp, acl->data, acl->size); if (acl->size != size) memset((void *)bp + acl->size, 0, size - acl->size); yfs_check_req(call, bp); trace_afs_make_fs_call(call, &vnode->fid); afs_make_call(&fc->ac, call, GFP_KERNEL); return afs_wait_for_call_to_complete(call, &fc->ac); }