+int
+coalition_ledger(__unused proc_t p, __unused struct coalition_ledger_args *uap, __unused int32_t *retval)
+{
+ user_addr_t cidp = uap->cid;
+ user_addr_t buffer = uap->buffer;
+ user_addr_t bufsizep = uap->bufsize;
+ user_size_t bufsize;
+ uint32_t operation = uap->operation;
+ int error;
+ uint64_t cid;
+ coalition_t coal = COALITION_NULL;
+
+ if (!kauth_cred_issuser(kauth_cred_get())) {
+ error = EPERM;
+ goto out;
+ }
+
+ error = copyin(cidp, &cid, sizeof(cid));
+ if (error) {
+ goto out;
+ }
+
+ coal = coalition_find_by_id(cid);
+ if (coal == COALITION_NULL) {
+ error = ESRCH;
+ goto out;
+ }
+
+ if (IS_64BIT_PROCESS(p)) {
+ user64_size_t size64;
+ error = copyin(bufsizep, &size64, sizeof(size64));
+ bufsize = (user_size_t)size64;
+ } else {
+ user32_size_t size32;
+ error = copyin(bufsizep, &size32, sizeof(size32));
+ bufsize = (user_size_t)size32;
+ }
+ if (error) {
+ goto out;
+ }
+
+ switch (operation) {
+ case COALITION_LEDGER_SET_LOGICAL_WRITES_LIMIT:
+ error = coalition_ledger_logical_writes_limit(coal, buffer, bufsize);
+ break;
+ default:
+ error = EINVAL;
+ }
+out:
+ if (coal != COALITION_NULL) {
+ coalition_release(coal);
+ }
+ return error;
+}