void APar_ShowMPEG4AACProfileInfo(TrackInfo *track_info) {
  if (track_info->descriptor_object_typeID == 1) {
    fprintf(stdout, "  MPEG-4 AAC Main Profile");
  } else if (track_info->descriptor_object_typeID == 2) {
    fprintf(
        stdout,
        "  MPEG-4 AAC Low Complexity/LC Profile"); // most files will land here
  } else if (track_info->descriptor_object_typeID == 3) {
    fprintf(stdout, "  MPEG-4 AAC Scaleable Sample Rate/SSR Profile");
  } else if (track_info->descriptor_object_typeID == 4) {
    fprintf(stdout, "  MPEG-4 AAC Long Term Prediction Profile");
  } else if (track_info->descriptor_object_typeID == 5) {
    fprintf(stdout, "  MPEG-4 AAC High Efficiency/HE Profile");
  } else if (track_info->descriptor_object_typeID == 6) {
    fprintf(stdout, "  MPEG-4 AAC Scalable Profile");
  } else if (track_info->descriptor_object_typeID == 7) {
    fprintf(stdout,
            "  MPEG-4 AAC Transform domain Weighted INterleave Vector "
            "Quantization/TwinVQ Profile");
  } else if (track_info->descriptor_object_typeID == 8) {
    fprintf(stdout, "  MPEG-4 AAC Code Excited Linear Predictive/CELP Profile");
  } else if (track_info->descriptor_object_typeID == 9) {
    fprintf(stdout, "  MPEG-4 AAC HVXC Profile");

  } else if (track_info->descriptor_object_typeID == 12) {
    fprintf(stdout, "  MPEG-4 AAC TTSI Profile");
  } else if (track_info->descriptor_object_typeID == 13) {
    fprintf(stdout, "  MPEG-4 AAC Main Synthesis Profile");
  } else if (track_info->descriptor_object_typeID == 14) {
    fprintf(stdout, "  MPEG-4 AAC Wavetable Synthesis Profile");
  } else if (track_info->descriptor_object_typeID == 15) {
    fprintf(stdout, "  MPEG-4 AAC General MIDI Profile");
  } else if (track_info->descriptor_object_typeID == 16) {
    fprintf(stdout, "  MPEG-4 AAC Algorithmic Synthesis & Audio FX Profile");
  } else if (track_info->descriptor_object_typeID == 17) {
    fprintf(stdout,
            "  MPEG-4 AAC AAC Low Complexity/LC (+error recovery) Profile");

  } else if (track_info->descriptor_object_typeID == 19) {
    fprintf(stdout,
            "  MPEG-4 AAC Long Term Prediction (+error recovery) Profile");
  } else if (track_info->descriptor_object_typeID == 20) {
    fprintf(stdout, "  MPEG-4 AAC Scalable (+error recovery) Profile");
  } else if (track_info->descriptor_object_typeID == 21) {
    fprintf(stdout,
            "  MPEG-4 AAC Transform domain Weighted INterleave Vector "
            "Quantization/TwinVQ (+error recovery) Profile");
  } else if (track_info->descriptor_object_typeID == 22) {
    fprintf(stdout,
            "  MPEG-4 AAC Bit Sliced Arithmetic Coding/BSAC (+error "
            "recovery) Profile");
  } else if (track_info->descriptor_object_typeID == 23) {
    fprintf(stdout, "  MPEG-4 AAC Low Delay/LD (+error recovery) Profile");
  } else if (track_info->descriptor_object_typeID == 24) {
    fprintf(stdout,
            "  MPEG-4 AAC Code Excited Linear Predictive/CELP (+error "
            "recovery) Profile");
  } else if (track_info->descriptor_object_typeID == 25) {
    fprintf(stdout, "  MPEG-4 AAC HXVC (+error recovery) Profile");
  } else if (track_info->descriptor_object_typeID == 26) {
    fprintf(stdout,
            "  MPEG-4 AAC Harmonic and Individual Lines plus "
            "Noise/HILN (+error recovery) Profile");
  } else if (track_info->descriptor_object_typeID == 27) {
    fprintf(stdout, "  MPEG-4 AAC Parametric (+error recovery) Profile");

  } else if (track_info->descriptor_object_typeID == 31) {
    fprintf(
        stdout,
        "  MPEG-4 ALS Audio Lossless Coding"); // I think that mp4alsRM18 writes
                                               // the channels wrong after
                                               // objectedID: 0xF880 has 0
                                               // channels; 0xF890 is 2ch
  } else {
    fprintf(stdout,
            "  MPEG-4 Unknown profile: 0x%X",
            track_info->descriptor_object_typeID);
  }
  return;
}


void APar_Extract_esds_Info(char *uint32_buffer,
                            FILE *isofile,
                            short track_level_atom,
                            TrackInfo *track_info) {
  uint64_t offset_into_stsd = 0;

  while (offset_into_stsd < parsedAtoms[track_level_atom].AtomicLength) {
    offset_into_stsd++;
    if (APar_read32(uint32_buffer,
                    isofile,
                    parsedAtoms[track_level_atom].AtomicStart +
                        offset_into_stsd) == 0x65736473) {
      track_info->contains_esds = true;

      uint64_t esds_start =
          parsedAtoms[track_level_atom].AtomicStart + offset_into_stsd - 4;
      uint64_t esds_length = APar_read32(uint32_buffer, isofile, esds_start);
      uint64_t offset_into_esds =
          12; // 4bytes length + 4 bytes name + 4bytes null

      if (APar_read8(isofile, esds_start + offset_into_esds) == 0x03) {
        offset_into_esds++;
        offset_into_esds +=
            APar_skip_filler(isofile, esds_start + offset_into_esds);
      }

      uint8_t section3_length =
          APar_read8(isofile, esds_start + offset_into_esds);
      if (section3_length <= esds_length && section3_length != 0) {
        track_info->section3_length = section3_length;
      } else {
        break;
      }

      // for whatever reason, when mp4box muxes in ogg into an mp4 container,
      // section 3 gets a 0x9D byte (which doesn't fall inline with what AP
      // considers 'filler') then again, I haven't *completely* read the ISO
      // specifications, so I could just be missing it the the ->voluminous<-
      // 14496-X specifications.
      uint8_t test_byte =
          APar_read8(isofile, esds_start + offset_into_esds + 1);
      if (test_byte != 0) {
        offset_into_esds++;
      }

      offset_into_esds += 4; // 1 bytes section 0x03 length + 2 bytes + 1 byte

      if (APar_read8(isofile, esds_start + offset_into_esds) == 0x04) {
        offset_into_esds++;
        offset_into_esds +=
            APar_skip_filler(isofile, esds_start + offset_into_esds);
      }

      uint8_t section4_length =
          APar_read8(isofile, esds_start + offset_into_esds);
      if (section4_length <= section3_length && section4_length != 0) {
        track_info->section4_length = section4_length;

        if (section4_length == 0x9D)
          offset_into_esds++; // upper limit? when gpac puts an ogg in, section
                              // 3 is 9D - so is sec4 (section 4 real length
                              // with ogg = 0x0E86)

        offset_into_esds++;
        track_info->ObjectTypeIndication =
            APar_read8(isofile, esds_start + offset_into_esds);

        // this is just so that ogg in mp4 won't have some bizarre high bitrate
        // of like 2.8megabits/sec
        uint8_t a_v_flag =
            APar_read8(isofile,
                       esds_start + offset_into_esds +
                           1); // mp4box with ogg will set this to DD,
                               // mp4a has it as 0x40, mp4v has 0x20

        if (track_info->ObjectTypeIndication < 0xC0 &&
            a_v_flag < 0xA0) { // 0xC0 marks user streams; but things below that
                               // might still be wrong (like 0x6D - png)
          offset_into_esds += 5;
          track_info->max_bitrate = APar_read32(
              uint32_buffer, isofile, esds_start + offset_into_esds);
          offset_into_esds += 4;
          track_info->avg_bitrate = APar_read32(
              uint32_buffer, isofile, esds_start + offset_into_esds);
          offset_into_esds += 4;
        }
      } else {
        break;
      }

      if (APar_read8(isofile, esds_start + offset_into_esds) == 0x05) {
        offset_into_esds++;
        offset_into_esds +=
            APar_skip_filler(isofile, esds_start + offset_into_esds);

        uint8_t section5_length =
            APar_read8(isofile, esds_start + offset_into_esds);
        if ((section5_length <= section4_length || section4_length == 1) &&
            section5_length != 0) {
          track_info->section5_length = section5_length;
          offset_into_esds += 1;

          if (track_info->type_of_track & AUDIO_TRACK) {
            uint8_t packed_objID = APar_read8(
                isofile,
                esds_start + offset_into_esds); // its packed with channel, but
                                                // channel is fetched separately
            track_info->descriptor_object_typeID = packed_objID >> 3;
            offset_into_esds += 1;

            track_info->channels = (uint16_t)APar_ExtractChannelInfo(
                isofile, esds_start + offset_into_esds);

          } else if (track_info->type_of_track & VIDEO_TRACK) {
            // technically, visual_object_sequence_start_code should be tested
            // aginst 0x000001B0
            if (APar_read16(uint32_buffer,
                            isofile,
                            esds_start + offset_into_esds + 2) == 0x01B0) {
              track_info->m4v_profile =
                  APar_read8(isofile, esds_start + offset_into_esds + 2 + 2);
            }
          }
        }
        break; // uh, I've extracted the pertinent info
      }
    }
    if (offset_into_stsd > parsedAtoms[track_level_atom].AtomicLength) {
      break;
    }
  }
  if ((track_info->section5_length == 0 &&
       track_info->type_of_track & AUDIO_TRACK) ||
      track_info->channels == 0) {
    track_info->channels = APar_read16(
        uint32_buffer, isofile, parsedAtoms[track_level_atom].AtomicStart + 40);
  }
  return;
}


char *uint32tochar4(uint32_t lnum, char *data) {
  data[0] = (lnum >> 24) & 0xff;
  data[1] = (lnum >> 16) & 0xff;
  data[2] = (lnum >> 8) & 0xff;
  data[3] = (lnum >> 0) & 0xff;
  return data;
}


void APar_ExtractBrands(char *filepath) {
  FILE *a_file = APar_OpenISOBaseMediaFile(filepath, true);
  char buffer[16] = {};
  uint32_t atom_length = 0;
  uint8_t file_type_offset = 0;
  uint32_t compatible_brand = 0;
  bool cb_V2ISOBMFF = false;

  APar_read32(buffer, a_file, 4);
  if (memcmp(buffer, "ftyp", 4) == 0) {
    atom_length = APar_read32(buffer, a_file, 0);
  } else {
    APar_readX(buffer, a_file, 0, 12);
    if (memcmp(buffer,
               "\x00\x00\x00\x0C\x6A\x50\x20\x20\x0D\x0A\x87\x0A",
               12) == 0) {
      APar_readX(buffer, a_file, 12, 12);
      if (memcmp(buffer + 4, "ftypmjp2", 8) == 0 ||
          memcmp(buffer + 4, "ftypmj2s", 8) == 0) {
        atom_length = UInt32FromBigEndian(buffer);
        file_type_offset = 12;
      }
    }
  }

  if (atom_length > 0) {
    memset(buffer, 0, 16);
    APar_readX(buffer, a_file, 8 + file_type_offset, 4);
    printBOM();
    fprintf(stdout, " Major Brand: %s", buffer);
    APar_IdentifyBrand(buffer);

    if (memcmp(buffer, "isom", 4) == 0) {
      APar_ScanAtoms(filepath); // scan_file = true;
    }

    uint32_t minor_version = APar_read32(buffer, a_file, 12 + file_type_offset);
    fprintf(stdout, "  -  version %" PRIu32 "\n", minor_version);

    fprintf(stdout, " Compatible Brands:");
    for (uint64_t i = 16 + file_type_offset; i < atom_length; i += 4) {
      APar_readX(buffer, a_file, i, 4);
      compatible_brand = UInt32FromBigEndian(buffer);
      if (compatible_brand != 0) {
        fprintf(stdout, " %s", buffer);
        if (compatible_brand == 0x6D703432 || compatible_brand == 0x69736F32) {
          cb_V2ISOBMFF = true;
        }
      }
    }
    fprintf(stdout, "\n");
  }

  APar_OpenISOBaseMediaFile(filepath, false);

  fprintf(stdout, " Tagging schemes available:\n");
  switch (metadata_style) {
  case ITUNES_STYLE: {
    fprintf(stdout, "   iTunes-style metadata allowed.\n");
    break;
  }
  case THIRD_GEN_PARTNER:
  case THIRD_GEN_PARTNER_VER1_REL6:
  case THIRD_GEN_PARTNER_VER1_REL7:
  case THIRD_GEN_PARTNER_VER2: {
    fprintf(stdout, "   3GP-style asset metadata allowed.\n");
    break;
  }
  case THIRD_GEN_PARTNER_VER2_REL_A: {
    fprintf(stdout,
            "   3GP-style asset metadata allowed [& unimplemented GAD "
            "(Geographical Area Description) asset].\n");
    break;
  }
  }
  if (cb_V2ISOBMFF || metadata_style == THIRD_GEN_PARTNER_VER1_REL7) {
    fprintf(stdout,
            "   ID3 tags on ID32 atoms @ file/movie/track level allowed.\n");
  }
  fprintf(stdout,
          "   ISO-copyright notices @ movie and/or track level "
          "allowed.\n   uuid private user extension tags allowed.\n");
}


static ssize_t port_fops_write(struct file *filp, const char __user *ubuf,
			       size_t count, loff_t *offp)
{
	struct port *port;
	struct port_buffer *buf;
	ssize_t ret;
	bool nonblock;
	struct scatterlist sg[1];

	/* Userspace could be out to fool us */
	if (!count)
		return 0;

	port = filp->private_data;

	nonblock = filp->f_flags & O_NONBLOCK;

	ret = wait_port_writable(port, nonblock);
	if (ret < 0)
		return ret;

	count = min((size_t)(32 * 1024), count);

	buf = alloc_buf(port->portdev->vdev, count, 0);
	if (!buf)
		return -ENOMEM;

	ret = copy_from_user(buf->buf, ubuf, count);
	if (ret) {
		ret = -EFAULT;
		goto free_buf;
	}

	/*
	 * We now ask send_buf() to not spin for generic ports -- we
	 * can re-use the same code path that non-blocking file
	 * descriptors take for blocking file descriptors since the
	 * wait is already done and we're certain the write will go
	 * through to the host.
	 */
	nonblock = true;
	sg_init_one(sg, buf->buf, count);
	ret = __send_to_port(port, sg, 1, count, buf, nonblock);

	if (nonblock && ret > 0)
		goto out;

free_buf:
	free_buf(buf, true);
out:
	return ret;
}


static int virtcons_freeze(struct virtio_device *vdev)
{
	struct ports_device *portdev;
	struct port *port;

	portdev = vdev->priv;

	vdev->config->reset(vdev);

	if (use_multiport(portdev))
		virtqueue_disable_cb(portdev->c_ivq);
	cancel_work_sync(&portdev->control_work);
	cancel_work_sync(&portdev->config_work);
	/*
	 * Once more: if control_work_handler() was running, it would
	 * enable the cb as the last step.
	 */
	if (use_multiport(portdev))
		virtqueue_disable_cb(portdev->c_ivq);

	list_for_each_entry(port, &portdev->ports, list) {
		virtqueue_disable_cb(port->in_vq);
		virtqueue_disable_cb(port->out_vq);
		/*
		 * We'll ask the host later if the new invocation has
		 * the port opened or closed.
		 */
		port->host_connected = false;
		remove_port_data(port);
	}
	remove_vqs(portdev);

	return 0;
}


static int __init init(void)
{
	int err;

	pdrvdata.class = class_create(THIS_MODULE, "virtio-ports");
	if (IS_ERR(pdrvdata.class)) {
		err = PTR_ERR(pdrvdata.class);
		pr_err("Error %d creating virtio-ports class\n", err);
		return err;
	}

	pdrvdata.debugfs_dir = debugfs_create_dir("virtio-ports", NULL);
	INIT_LIST_HEAD(&pdrvdata.consoles);
	INIT_LIST_HEAD(&pdrvdata.portdevs);

	err = register_virtio_driver(&virtio_console);
	if (err < 0) {
		pr_err("Error %d registering virtio driver\n", err);
		goto free;
	}
	err = register_virtio_driver(&virtio_rproc_serial);
	if (err < 0) {
		pr_err("Error %d registering virtio rproc serial driver\n",
		       err);
		goto unregister;
	}
	return 0;
unregister:
	unregister_virtio_driver(&virtio_console);
free:
	debugfs_remove_recursive(pdrvdata.debugfs_dir);
	class_destroy(pdrvdata.class);
	return err;
}


static void control_work_handler(struct work_struct *work)
{
	struct ports_device *portdev;
	struct virtqueue *vq;
	struct port_buffer *buf;
	unsigned int len;

	portdev = container_of(work, struct ports_device, control_work);
	vq = portdev->c_ivq;

	spin_lock(&portdev->c_ivq_lock);
	while ((buf = virtqueue_get_buf(vq, &len))) {
		spin_unlock(&portdev->c_ivq_lock);

		buf->len = min_t(size_t, len, buf->size);
		buf->offset = 0;

		handle_control_message(vq->vdev, portdev, buf);

		spin_lock(&portdev->c_ivq_lock);
		if (add_inbuf(portdev->c_ivq, buf) < 0) {
			dev_warn(&portdev->vdev->dev,
				 "Error adding buffer to queue\n");
			free_buf(buf, false);
		}
	}
	spin_unlock(&portdev->c_ivq_lock);
}


ds_fgetstr (FILE *f, dynamic_string *s, char eos)
{
  int next_ch;

  /* Initialize.  */
  s->ds_idx = 0;

  /* Read the input string.  */
  while ((next_ch = getc (f)) != eos && next_ch != EOF)
    {
      ds_resize (s);
      s->ds_string[s->ds_idx++] = next_ch;
    }
  ds_resize (s);
  s->ds_string[s->ds_idx] = '\0';

  if (s->ds_idx == 0 && next_ch == EOF)
    return NULL;
  else
    return s->ds_string;
}


write_out_header (struct cpio_file_stat *file_hdr, int out_des)
{
  dev_t dev;
  dev_t rdev;

  switch (archive_format)
    {
    case arf_newascii:
      return write_out_new_ascii_header ("070701", file_hdr, out_des);

    case arf_crcascii:
      return write_out_new_ascii_header ("070702", file_hdr, out_des);

    case arf_oldascii:
      return write_out_old_ascii_header (makedev (file_hdr->c_dev_maj,
						  file_hdr->c_dev_min),
					 makedev (file_hdr->c_rdev_maj,
						  file_hdr->c_rdev_min),
					 file_hdr, out_des);

    case arf_hpoldascii:
      hp_compute_dev (file_hdr, &dev, &rdev);
      return write_out_old_ascii_header (dev, rdev, file_hdr, out_des);

    case arf_tar:
    case arf_ustar:
      if (is_tar_filename_too_long (file_hdr->c_name))
	{
	  error (0, 0, _("%s: file name too long"), file_hdr->c_name);
	  return 1;
	}
      return write_out_tar_header (file_hdr, out_des);

    case arf_binary:
      return write_out_binary_header (makedev (file_hdr->c_rdev_maj,
					       file_hdr->c_rdev_min),
				      file_hdr, out_des);

    case arf_hpbinary:
      hp_compute_dev (file_hdr, &dev, &rdev);
      /* FIXME: dev ignored. Should it be? */
      return write_out_binary_header (rdev, file_hdr, out_des);

    default:
      abort ();
    }
}


ds_fgetname (FILE *f, dynamic_string *s)
{
  return ds_fgetstr (f, s, '\0');
}


static bool FNAME(is_bad_mt_xwr)(struct rsvd_bits_validate *rsvd_check, u64 gpte)
{
#if PTTYPE != PTTYPE_EPT
	return false;
#else
	return __is_bad_mt_xwr(rsvd_check, gpte);
#endif
}


static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
			      u64 *spte, const void *pte)
{
	pt_element_t gpte = *(const pt_element_t *)pte;

	FNAME(prefetch_gpte)(vcpu, sp, spte, gpte, false);
}


nfs4_free_ds_server(struct nfs4_ds_server *dss)
{
	rpc_release_client(dss->rpc_clnt);
	kfree(dss);
}


nfs4_add_ds_client(struct nfs_client *ds_clp, rpc_authflavor_t flavor,
			   struct nfs4_ds_server *new)
{
	struct nfs4_ds_server *dss;

	spin_lock(&ds_clp->cl_lock);
	list_for_each_entry(dss, &ds_clp->cl_ds_clients, list) {
		if (dss->rpc_clnt->cl_auth->au_flavor != flavor)
			continue;
		goto out;
	}
	if (new)
		list_add_rcu(&new->list, &ds_clp->cl_ds_clients);
	dss = new;
out:
	spin_unlock(&ds_clp->cl_lock); /* need some lock to protect list */
	return dss;
}


int nfs41_walk_client_list(struct nfs_client *new,
			   struct nfs_client **result,
			   const struct cred *cred)
{
	struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id);
	struct nfs_client *pos, *prev = NULL;
	int status = -NFS4ERR_STALE_CLIENTID;

	spin_lock(&nn->nfs_client_lock);
	list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) {

		if (pos == new)
			goto found;

		status = nfs4_match_client(pos, new, &prev, nn);
		if (status < 0)
			goto out;
		if (status != 0)
			continue;

		/*
		 * Note that session trunking is just a special subcase of
		 * client id trunking. In either case, we want to fall back
		 * to using the existing nfs_client.
		 */
		if (!nfs4_check_serverowner_major_id(pos->cl_serverowner,
						     new->cl_serverowner))
			continue;

found:
		refcount_inc(&pos->cl_count);
		*result = pos;
		status = 0;
		break;
	}

out:
	spin_unlock(&nn->nfs_client_lock);
	nfs_put_client(prev);
	return status;
}


static inline u32 perf_get_misc_flags(struct pt_regs *regs)
{
	bool use_siar = regs_use_siar(regs);
	unsigned long mmcra = regs->dsisr;
	int marked = mmcra & MMCRA_SAMPLE_ENABLE;

	if (!use_siar)
		return perf_flags_from_msr(regs);

	/*
	 * Check the address in SIAR to identify the
	 * privilege levels since the SIER[MSR_HV, MSR_PR]
	 * bits are not set for marked events in power10
	 * DD1.
	 */
	if (marked && (ppmu->flags & PPMU_P10_DD1)) {
		unsigned long siar = mfspr(SPRN_SIAR);
		if (siar) {
			if (is_kernel_addr(siar))
				return PERF_RECORD_MISC_KERNEL;
			return PERF_RECORD_MISC_USER;
		} else {
			if (is_kernel_addr(regs->nip))
				return PERF_RECORD_MISC_KERNEL;
			return PERF_RECORD_MISC_USER;
		}
	}

	/*
	 * If we don't have flags in MMCRA, rather than using
	 * the MSR, we intuit the flags from the address in
	 * SIAR which should give slightly more reliable
	 * results
	 */
	if (ppmu->flags & PPMU_NO_SIPR) {
		unsigned long siar = mfspr(SPRN_SIAR);
		if (is_kernel_addr(siar))
			return PERF_RECORD_MISC_KERNEL;
		return PERF_RECORD_MISC_USER;
	}

	/* PR has priority over HV, so order below is important */
	if (regs_sipr(regs))
		return PERF_RECORD_MISC_USER;

	if (regs_sihv(regs) && (freeze_events_kernel != MMCR0_FCHV))
		return PERF_RECORD_MISC_HYPERVISOR;

	return PERF_RECORD_MISC_KERNEL;
}


static void perf_event_interrupt(struct pt_regs *regs)
{
	u64 start_clock = sched_clock();

	__perf_event_interrupt(regs);
	perf_sample_event_took(sched_clock() - start_clock);
}


static bool is_event_blacklisted(u64 ev)
{
	int i;

	for (i=0; i < ppmu->n_blacklist_ev; i++) {
		if (ppmu->blacklist_ev[i] == ev)
			return true;
	}

	return false;
}


static int ebb_event_check(struct perf_event *event)
{
	struct perf_event *leader = event->group_leader;

	/* Event and group leader must agree on EBB */
	if (is_ebb_event(leader) != is_ebb_event(event))
		return -EINVAL;

	if (is_ebb_event(event)) {
		if (!(event->attach_state & PERF_ATTACH_TASK))
			return -EINVAL;

		if (!leader->attr.pinned || !leader->attr.exclusive)
			return -EINVAL;

		if (event->attr.freq ||
		    event->attr.inherit ||
		    event->attr.sample_type ||
		    event->attr.sample_period ||
		    event->attr.enable_on_exec)
			return -EINVAL;
	}

	return 0;
}


int xdr_encode_word(const struct xdr_buf *buf, unsigned int base, u32 obj)
{
	__be32	raw = cpu_to_be32(obj);

	return write_bytes_to_xdr_buf(buf, base, &raw, sizeof(obj));
}


_copy_to_pages(struct page **pages, size_t pgbase, const char *p, size_t len)
{
	struct page **pgto;
	char *vto;
	size_t copy;

	if (!len)
		return;

	pgto = pages + (pgbase >> PAGE_SHIFT);
	pgbase &= ~PAGE_MASK;

	for (;;) {
		copy = PAGE_SIZE - pgbase;
		if (copy > len)
			copy = len;

		vto = kmap_atomic(*pgto);
		memcpy(vto + pgbase, p, copy);
		kunmap_atomic(vto);

		len -= copy;
		if (len == 0)
			break;

		pgbase += copy;
		if (pgbase == PAGE_SIZE) {
			flush_dcache_page(*pgto);
			pgbase = 0;
			pgto++;
		}
		p += copy;
	}
	flush_dcache_page(*pgto);
}


ssize_t xdr_stream_decode_opaque_dup(struct xdr_stream *xdr, void **ptr,
		size_t maxlen, gfp_t gfp_flags)
{
	ssize_t ret;
	void *p;

	ret = xdr_stream_decode_opaque_inline(xdr, &p, maxlen);
	if (ret > 0) {
		*ptr = kmemdup(p, ret, gfp_flags);
		if (*ptr != NULL)
			return ret;
		ret = -ENOMEM;
	}
	*ptr = NULL;
	return ret;
}


void xdr_terminate_string(const struct xdr_buf *buf, const u32 len)
{
	char *kaddr;

	kaddr = kmap_atomic(buf->pages[0]);
	kaddr[buf->page_base + len] = '\0';
	kunmap_atomic(kaddr);
}


static void xdr_realign_pages(struct xdr_stream *xdr)
{
	struct xdr_buf *buf = xdr->buf;
	struct kvec *iov = buf->head;
	unsigned int cur = xdr_stream_pos(xdr);
	unsigned int copied;

	/* Realign pages to current pointer position */
	if (iov->iov_len > cur) {
		copied = xdr_shrink_bufhead(buf, cur);
		trace_rpc_xdr_alignment(xdr, cur, copied);
		xdr_set_page(xdr, 0, buf->page_len);
	}
}


int xdr_encode_array2(const struct xdr_buf *buf, unsigned int base,
		      struct xdr_array2_desc *desc)
{
	if ((unsigned long) base + 4 + desc->array_len * desc->elem_size >
	    buf->head->iov_len + buf->page_len + buf->tail->iov_len)
		return -EINVAL;

	return xdr_xcode_array2(buf, base, desc, 1);
}


static void xdr_buf_iov_zero(const struct kvec *iov, unsigned int base,
			     unsigned int len)
{
	if (base >= iov->iov_len)
		return;
	if (len > iov->iov_len - base)
		len = iov->iov_len - base;
	memset(iov->iov_base + base, 0, len);
}


static __be32 *xdr_copy_to_scratch(struct xdr_stream *xdr, size_t nbytes)
{
	__be32 *p;
	char *cpdest = xdr->scratch.iov_base;
	size_t cplen = (char *)xdr->end - (char *)xdr->p;

	if (nbytes > xdr->scratch.iov_len)
		goto out_overflow;
	p = __xdr_inline_decode(xdr, cplen);
	if (p == NULL)
		return NULL;
	memcpy(cpdest, p, cplen);
	if (!xdr_set_next_buffer(xdr))
		goto out_overflow;
	cpdest += cplen;
	nbytes -= cplen;
	p = __xdr_inline_decode(xdr, nbytes);
	if (p == NULL)
		return NULL;
	memcpy(cpdest, p, nbytes);
	return xdr->scratch.iov_base;
out_overflow:
	trace_rpc_xdr_overflow(xdr, nbytes);
	return NULL;
}


int xdr_decode_array2(const struct xdr_buf *buf, unsigned int base,
		      struct xdr_array2_desc *desc)
{
	if (base >= buf->len)
		return -EINVAL;

	return xdr_xcode_array2(buf, base, desc, 0);
}


int btrfs_wait_block_group_cache_done(struct btrfs_block_group *cache)
{
	struct btrfs_caching_control *caching_ctl;
	int ret = 0;

	caching_ctl = btrfs_get_caching_control(cache);
	if (!caching_ctl)
		return (cache->cached == BTRFS_CACHE_ERROR) ? -EIO : 0;

	wait_event(caching_ctl->wait, btrfs_block_group_done(cache));
	if (cache->cached == BTRFS_CACHE_ERROR)
		ret = -EIO;
	btrfs_put_caching_control(caching_ctl);
	return ret;
}


static u64 btrfs_reduce_alloc_profile(struct btrfs_fs_info *fs_info, u64 flags)
{
	u64 num_devices = fs_info->fs_devices->rw_devices;
	u64 target;
	u64 raid_type;
	u64 allowed = 0;

	/*
	 * See if restripe for this chunk_type is in progress, if so try to
	 * reduce to the target profile
	 */
	spin_lock(&fs_info->balance_lock);
	target = get_restripe_target(fs_info, flags);
	if (target) {
		spin_unlock(&fs_info->balance_lock);
		return extended_to_chunk(target);
	}
	spin_unlock(&fs_info->balance_lock);

	/* First, mask out the RAID levels which aren't possible */
	for (raid_type = 0; raid_type < BTRFS_NR_RAID_TYPES; raid_type++) {
		if (num_devices >= btrfs_raid_array[raid_type].devs_min)
			allowed |= btrfs_raid_array[raid_type].bg_flag;
	}
	allowed &= flags;

	if (allowed & BTRFS_BLOCK_GROUP_RAID6)
		allowed = BTRFS_BLOCK_GROUP_RAID6;
	else if (allowed & BTRFS_BLOCK_GROUP_RAID5)
		allowed = BTRFS_BLOCK_GROUP_RAID5;
	else if (allowed & BTRFS_BLOCK_GROUP_RAID10)
		allowed = BTRFS_BLOCK_GROUP_RAID10;
	else if (allowed & BTRFS_BLOCK_GROUP_RAID1)
		allowed = BTRFS_BLOCK_GROUP_RAID1;
	else if (allowed & BTRFS_BLOCK_GROUP_RAID0)
		allowed = BTRFS_BLOCK_GROUP_RAID0;

	flags &= ~BTRFS_BLOCK_GROUP_PROFILE_MASK;

	return extended_to_chunk(flags | allowed);
}


int btrfs_record_root_in_trans(struct btrfs_trans_handle *trans,
			       struct btrfs_root *root)
{
	struct btrfs_fs_info *fs_info = root->fs_info;
	int ret;

	if (!test_bit(BTRFS_ROOT_SHAREABLE, &root->state))
		return 0;

	/*
	 * see record_root_in_trans for comments about IN_TRANS_SETUP usage
	 * and barriers
	 */
	smp_rmb();
	if (root->last_trans == trans->transid &&
	    !test_bit(BTRFS_ROOT_IN_TRANS_SETUP, &root->state))
		return 0;

	mutex_lock(&fs_info->reloc_mutex);
	ret = record_root_in_trans(trans, root, 0);
	mutex_unlock(&fs_info->reloc_mutex);

	return ret;
}


int btrfs_chunk_alloc(struct btrfs_trans_handle *trans, u64 flags,
		      enum btrfs_chunk_alloc_enum force)
{
	struct btrfs_fs_info *fs_info = trans->fs_info;
	struct btrfs_space_info *space_info;
	bool wait_for_alloc = false;
	bool should_alloc = false;
	int ret = 0;

	/* Don't re-enter if we're already allocating a chunk */
	if (trans->allocating_chunk)
		return -ENOSPC;

	space_info = btrfs_find_space_info(fs_info, flags);
	ASSERT(space_info);

	do {
		spin_lock(&space_info->lock);
		if (force < space_info->force_alloc)
			force = space_info->force_alloc;
		should_alloc = should_alloc_chunk(fs_info, space_info, force);
		if (space_info->full) {
			/* No more free physical space */
			if (should_alloc)
				ret = -ENOSPC;
			else
				ret = 0;
			spin_unlock(&space_info->lock);
			return ret;
		} else if (!should_alloc) {
			spin_unlock(&space_info->lock);
			return 0;
		} else if (space_info->chunk_alloc) {
			/*
			 * Someone is already allocating, so we need to block
			 * until this someone is finished and then loop to
			 * recheck if we should continue with our allocation
			 * attempt.
			 */
			wait_for_alloc = true;
			spin_unlock(&space_info->lock);
			mutex_lock(&fs_info->chunk_mutex);
			mutex_unlock(&fs_info->chunk_mutex);
		} else {
			/* Proceed with allocation */
			space_info->chunk_alloc = 1;
			wait_for_alloc = false;
			spin_unlock(&space_info->lock);
		}

		cond_resched();
	} while (wait_for_alloc);

	mutex_lock(&fs_info->chunk_mutex);
	trans->allocating_chunk = true;

	/*
	 * If we have mixed data/metadata chunks we want to make sure we keep
	 * allocating mixed chunks instead of individual chunks.
	 */
	if (btrfs_mixed_space_info(space_info))
		flags |= (BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_METADATA);

	/*
	 * if we're doing a data chunk, go ahead and make sure that
	 * we keep a reasonable number of metadata chunks allocated in the
	 * FS as well.
	 */
	if (flags & BTRFS_BLOCK_GROUP_DATA && fs_info->metadata_ratio) {
		fs_info->data_chunk_allocations++;
		if (!(fs_info->data_chunk_allocations %
		      fs_info->metadata_ratio))
			force_metadata_allocation(fs_info);
	}

	/*
	 * Check if we have enough space in SYSTEM chunk because we may need
	 * to update devices.
	 */
	check_system_chunk(trans, flags);

	ret = btrfs_alloc_chunk(trans, flags);
	trans->allocating_chunk = false;

	spin_lock(&space_info->lock);
	if (ret < 0) {
		if (ret == -ENOSPC)
			space_info->full = 1;
		else
			goto out;
	} else {
		ret = 1;
		space_info->max_extent_size = 0;
	}

	space_info->force_alloc = CHUNK_ALLOC_NO_FORCE;
out:
	space_info->chunk_alloc = 0;
	spin_unlock(&space_info->lock);
	mutex_unlock(&fs_info->chunk_mutex);
	/*
	 * When we allocate a new chunk we reserve space in the chunk block
	 * reserve to make sure we can COW nodes/leafs in the chunk tree or
	 * add new nodes/leafs to it if we end up needing to do it when
	 * inserting the chunk item and updating device items as part of the
	 * second phase of chunk allocation, performed by
	 * btrfs_finish_chunk_alloc(). So make sure we don't accumulate a
	 * large number of new block groups to create in our transaction
	 * handle's new_bgs list to avoid exhausting the chunk block reserve
	 * in extreme cases - like having a single transaction create many new
	 * block groups when starting to write out the free space caches of all
	 * the block groups that were made dirty during the lifetime of the
	 * transaction.
	 */
	if (trans->chunk_bytes_reserved >= (u64)SZ_2M)
		btrfs_create_pending_block_groups(trans);

	return ret;
}


void btrfs_wait_block_group_cache_progress(struct btrfs_block_group *cache,
					   u64 num_bytes)
{
	struct btrfs_caching_control *caching_ctl;

	caching_ctl = btrfs_get_caching_control(cache);
	if (!caching_ctl)
		return;

	wait_event(caching_ctl->wait, btrfs_block_group_done(cache) ||
		   (cache->free_space_ctl->free_space >= num_bytes));

	btrfs_put_caching_control(caching_ctl);
}


static int read_one_block_group(struct btrfs_fs_info *info,
				struct btrfs_block_group_item *bgi,
				const struct btrfs_key *key,
				int need_clear)
{
	struct btrfs_block_group *cache;
	struct btrfs_space_info *space_info;
	const bool mixed = btrfs_fs_incompat(info, MIXED_GROUPS);
	int ret;

	ASSERT(key->type == BTRFS_BLOCK_GROUP_ITEM_KEY);

	cache = btrfs_create_block_group_cache(info, key->objectid);
	if (!cache)
		return -ENOMEM;

	cache->length = key->offset;
	cache->used = btrfs_stack_block_group_used(bgi);
	cache->flags = btrfs_stack_block_group_flags(bgi);

	set_free_space_tree_thresholds(cache);

	if (need_clear) {
		/*
		 * When we mount with old space cache, we need to
		 * set BTRFS_DC_CLEAR and set dirty flag.
		 *
		 * a) Setting 'BTRFS_DC_CLEAR' makes sure that we
		 *    truncate the old free space cache inode and
		 *    setup a new one.
		 * b) Setting 'dirty flag' makes sure that we flush
		 *    the new space cache info onto disk.
		 */
		if (btrfs_test_opt(info, SPACE_CACHE))
			cache->disk_cache_state = BTRFS_DC_CLEAR;
	}
	if (!mixed && ((cache->flags & BTRFS_BLOCK_GROUP_METADATA) &&
	    (cache->flags & BTRFS_BLOCK_GROUP_DATA))) {
			btrfs_err(info,
"bg %llu is a mixed block group but filesystem hasn't enabled mixed block groups",
				  cache->start);
			ret = -EINVAL;
			goto error;
	}

	ret = btrfs_load_block_group_zone_info(cache, false);
	if (ret) {
		btrfs_err(info, "zoned: failed to load zone info of bg %llu",
			  cache->start);
		goto error;
	}

	/*
	 * We need to exclude the super stripes now so that the space info has
	 * super bytes accounted for, otherwise we'll think we have more space
	 * than we actually do.
	 */
	ret = exclude_super_stripes(cache);
	if (ret) {
		/* We may have excluded something, so call this just in case. */
		btrfs_free_excluded_extents(cache);
		goto error;
	}

	/*
	 * For zoned filesystem, space after the allocation offset is the only
	 * free space for a block group. So, we don't need any caching work.
	 * btrfs_calc_zone_unusable() will set the amount of free space and
	 * zone_unusable space.
	 *
	 * For regular filesystem, check for two cases, either we are full, and
	 * therefore don't need to bother with the caching work since we won't
	 * find any space, or we are empty, and we can just add all the space
	 * in and be done with it.  This saves us _a_lot_ of time, particularly
	 * in the full case.
	 */
	if (btrfs_is_zoned(info)) {
		btrfs_calc_zone_unusable(cache);
	} else if (cache->length == cache->used) {
		cache->last_byte_to_unpin = (u64)-1;
		cache->cached = BTRFS_CACHE_FINISHED;
		btrfs_free_excluded_extents(cache);
	} else if (cache->used == 0) {
		cache->last_byte_to_unpin = (u64)-1;
		cache->cached = BTRFS_CACHE_FINISHED;
		add_new_free_space(cache, cache->start,
				   cache->start + cache->length);
		btrfs_free_excluded_extents(cache);
	}

	ret = btrfs_add_block_group_cache(info, cache);
	if (ret) {
		btrfs_remove_free_space_cache(cache);
		goto error;
	}
	trace_btrfs_add_block_group(info, cache, 0);
	btrfs_update_space_info(info, cache->flags, cache->length,
				cache->used, cache->bytes_super,
				cache->zone_unusable, &space_info);

	cache->space_info = space_info;

	link_block_group(cache);

	set_avail_alloc_bits(info, cache->flags);
	if (btrfs_chunk_readonly(info, cache->start)) {
		inc_block_group_ro(cache, 1);
	} else if (cache->used == 0) {
		ASSERT(list_empty(&cache->bg_list));
		if (btrfs_test_opt(info, DISCARD_ASYNC))
			btrfs_discard_queue_work(&info->discard_ctl, cache);
		else
			btrfs_mark_bg_unused(cache);
	}
	return 0;
error:
	btrfs_put_block_group(cache);
	return ret;
}


int btrfs_rmap_block(struct btrfs_fs_info *fs_info, u64 chunk_start,
		     struct block_device *bdev, u64 physical, u64 **logical,
		     int *naddrs, int *stripe_len)
{
	struct extent_map *em;
	struct map_lookup *map;
	u64 *buf;
	u64 bytenr;
	u64 data_stripe_length;
	u64 io_stripe_size;
	int i, nr = 0;
	int ret = 0;

	em = btrfs_get_chunk_map(fs_info, chunk_start, 1);
	if (IS_ERR(em))
		return -EIO;

	map = em->map_lookup;
	data_stripe_length = em->orig_block_len;
	io_stripe_size = map->stripe_len;
	chunk_start = em->start;

	/* For RAID5/6 adjust to a full IO stripe length */
	if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK)
		io_stripe_size = map->stripe_len * nr_data_stripes(map);

	buf = kcalloc(map->num_stripes, sizeof(u64), GFP_NOFS);
	if (!buf) {
		ret = -ENOMEM;
		goto out;
	}

	for (i = 0; i < map->num_stripes; i++) {
		bool already_inserted = false;
		u64 stripe_nr;
		u64 offset;
		int j;

		if (!in_range(physical, map->stripes[i].physical,
			      data_stripe_length))
			continue;

		if (bdev && map->stripes[i].dev->bdev != bdev)
			continue;

		stripe_nr = physical - map->stripes[i].physical;
		stripe_nr = div64_u64_rem(stripe_nr, map->stripe_len, &offset);

		if (map->type & BTRFS_BLOCK_GROUP_RAID10) {
			stripe_nr = stripe_nr * map->num_stripes + i;
			stripe_nr = div_u64(stripe_nr, map->sub_stripes);
		} else if (map->type & BTRFS_BLOCK_GROUP_RAID0) {
			stripe_nr = stripe_nr * map->num_stripes + i;
		}
		/*
		 * The remaining case would be for RAID56, multiply by
		 * nr_data_stripes().  Alternatively, just use rmap_len below
		 * instead of map->stripe_len
		 */

		bytenr = chunk_start + stripe_nr * io_stripe_size + offset;

		/* Ensure we don't add duplicate addresses */
		for (j = 0; j < nr; j++) {
			if (buf[j] == bytenr) {
				already_inserted = true;
				break;
			}
		}

		if (!already_inserted)
			buf[nr++] = bytenr;
	}

	*logical = buf;
	*naddrs = nr;
	*stripe_len = io_stripe_size;
out:
	free_extent_map(em);
	return ret;
}


void btrfs_dec_block_group_reservations(struct btrfs_fs_info *fs_info,
					const u64 start)
{
	struct btrfs_block_group *bg;

	bg = btrfs_lookup_block_group(fs_info, start);
	ASSERT(bg);
	if (atomic_dec_and_test(&bg->reservations))
		wake_up_var(&bg->reservations);
	btrfs_put_block_group(bg);
}


void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans)
{
	struct btrfs_fs_info *fs_info = trans->fs_info;
	struct btrfs_block_group *block_group;
	int ret = 0;

	if (!trans->can_flush_pending_bgs)
		return;

	while (!list_empty(&trans->new_bgs)) {
		int index;

		block_group = list_first_entry(&trans->new_bgs,
					       struct btrfs_block_group,
					       bg_list);
		if (ret)
			goto next;

		index = btrfs_bg_flags_to_raid_index(block_group->flags);

		ret = insert_block_group_item(trans, block_group);
		if (ret)
			btrfs_abort_transaction(trans, ret);
		ret = btrfs_finish_chunk_alloc(trans, block_group->start,
					block_group->length);
		if (ret)
			btrfs_abort_transaction(trans, ret);
		add_block_group_free_space(trans, block_group);

		/*
		 * If we restriped during balance, we may have added a new raid
		 * type, so now add the sysfs entries when it is safe to do so.
		 * We don't have to worry about locking here as it's handled in
		 * btrfs_sysfs_add_block_group_type.
		 */
		if (block_group->space_info->block_group_kobjs[index] == NULL)
			btrfs_sysfs_add_block_group_type(block_group);

		/* Already aborted the transaction if it failed. */
next:
		btrfs_delayed_refs_rsv_release(fs_info, 1);
		list_del_init(&block_group->bg_list);
	}
	btrfs_trans_release_chunk_metadata(trans);
}


int btrfs_clean_one_deleted_snapshot(struct btrfs_root *root)
{
	int ret;
	struct btrfs_fs_info *fs_info = root->fs_info;

	spin_lock(&fs_info->trans_lock);
	if (list_empty(&fs_info->dead_roots)) {
		spin_unlock(&fs_info->trans_lock);
		return 0;
	}
	root = list_first_entry(&fs_info->dead_roots,
			struct btrfs_root, root_list);
	list_del_init(&root->root_list);
	spin_unlock(&fs_info->trans_lock);

	btrfs_debug(fs_info, "cleaner removing %llu", root->root_key.objectid);

	btrfs_kill_all_delayed_nodes(root);

	if (btrfs_header_backref_rev(root->node) <
			BTRFS_MIXED_BACKREF_REV)
		ret = btrfs_drop_snapshot(root, 0, 0);
	else
		ret = btrfs_drop_snapshot(root, 1, 0);

	btrfs_put_root(root);
	return (ret < 0) ? 0 : 1;
}


static void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans)

{
	struct btrfs_fs_info *fs_info = trans->fs_info;

	if (!trans->block_rsv) {
		ASSERT(!trans->bytes_reserved);
		return;
	}

	if (!trans->bytes_reserved)
		return;

	ASSERT(trans->block_rsv == &fs_info->trans_block_rsv);
	trace_btrfs_space_reservation(fs_info, "transaction",
				      trans->transid, trans->bytes_reserved, 0);
	btrfs_block_rsv_release(fs_info, trans->block_rsv,
				trans->bytes_reserved, NULL);
	trans->bytes_reserved = 0;
}


struct btrfs_block_group *btrfs_next_block_group(
		struct btrfs_block_group *cache)
{
	struct btrfs_fs_info *fs_info = cache->fs_info;
	struct rb_node *node;

	spin_lock(&fs_info->block_group_cache_lock);

	/* If our block group was removed, we need a full search. */
	if (RB_EMPTY_NODE(&cache->cache_node)) {
		const u64 next_bytenr = cache->start + cache->length;

		spin_unlock(&fs_info->block_group_cache_lock);
		btrfs_put_block_group(cache);
		cache = btrfs_lookup_first_block_group(fs_info, next_bytenr); return cache;
	}
	node = rb_next(&cache->cache_node);
	btrfs_put_block_group(cache);
	if (node) {
		cache = rb_entry(node, struct btrfs_block_group, cache_node);
		btrfs_get_block_group(cache);
	} else
		cache = NULL;
	spin_unlock(&fs_info->block_group_cache_lock);
	return cache;
}


void btrfs_wait_nocow_writers(struct btrfs_block_group *bg)
{
	wait_var_event(&bg->nocow_writers, !atomic_read(&bg->nocow_writers));
}


int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans)
{
	return __btrfs_end_transaction(trans, 1);
}


static int update_block_group_item(struct btrfs_trans_handle *trans,
				   struct btrfs_path *path,
				   struct btrfs_block_group *cache)
{
	struct btrfs_fs_info *fs_info = trans->fs_info;
	int ret;
	struct btrfs_root *root = fs_info->extent_root;
	unsigned long bi;
	struct extent_buffer *leaf;
	struct btrfs_block_group_item bgi;
	struct btrfs_key key;

	key.objectid = cache->start;
	key.type = BTRFS_BLOCK_GROUP_ITEM_KEY;
	key.offset = cache->length;

	ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
	if (ret) {
		if (ret > 0)
			ret = -ENOENT;
		goto fail;
	}

	leaf = path->nodes[0];
	bi = btrfs_item_ptr_offset(leaf, path->slots[0]);
	btrfs_set_stack_block_group_used(&bgi, cache->used);
	btrfs_set_stack_block_group_chunk_objectid(&bgi,
			BTRFS_FIRST_CHUNK_TREE_OBJECTID);
	btrfs_set_stack_block_group_flags(&bgi, cache->flags);
	write_extent_buffer(leaf, &bgi, bi, sizeof(bgi));
	btrfs_mark_buffer_dirty(leaf);
fail:
	btrfs_release_path(path);
	return ret;

}


static u64 get_restripe_target(struct btrfs_fs_info *fs_info, u64 flags)
{
	struct btrfs_balance_control *bctl = fs_info->balance_ctl;
	u64 target = 0;

	if (!bctl)
		return 0;

	if (flags & BTRFS_BLOCK_GROUP_DATA &&
	    bctl->data.flags & BTRFS_BALANCE_ARGS_CONVERT) {
		target = BTRFS_BLOCK_GROUP_DATA | bctl->data.target;
	} else if (flags & BTRFS_BLOCK_GROUP_SYSTEM &&
		   bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT) {
		target = BTRFS_BLOCK_GROUP_SYSTEM | bctl->sys.target;
	} else if (flags & BTRFS_BLOCK_GROUP_METADATA &&
		   bctl->meta.flags & BTRFS_BALANCE_ARGS_CONVERT) {
		target = BTRFS_BLOCK_GROUP_METADATA | bctl->meta.target;
	}

	return target;
}


static struct btrfs_block_group *btrfs_create_block_group_cache(
		struct btrfs_fs_info *fs_info, u64 start)
{
	struct btrfs_block_group *cache;

	cache = kzalloc(sizeof(*cache), GFP_NOFS);
	if (!cache)
		return NULL;

	cache->free_space_ctl = kzalloc(sizeof(*cache->free_space_ctl),
					GFP_NOFS);
	if (!cache->free_space_ctl) {
		kfree(cache);
		return NULL;
	}

	cache->start = start;

	cache->fs_info = fs_info;
	cache->full_stripe_len = btrfs_full_stripe_len(fs_info, start);

	cache->discard_index = BTRFS_DISCARD_INDEX_UNUSED;

	refcount_set(&cache->refs, 1);
	spin_lock_init(&cache->lock);
	init_rwsem(&cache->data_rwsem);
	INIT_LIST_HEAD(&cache->list);
	INIT_LIST_HEAD(&cache->cluster_list);
	INIT_LIST_HEAD(&cache->bg_list);
	INIT_LIST_HEAD(&cache->ro_list);
	INIT_LIST_HEAD(&cache->discard_list);
	INIT_LIST_HEAD(&cache->dirty_list);
	INIT_LIST_HEAD(&cache->io_list);
	btrfs_init_free_space_ctl(cache, cache->free_space_ctl);
	atomic_set(&cache->frozen, 0);
	mutex_init(&cache->free_space_lock);
	btrfs_init_full_stripe_locks_tree(&cache->full_stripe_locks_root);

	return cache;
}


struct btrfs_caching_control *btrfs_get_caching_control(
		struct btrfs_block_group *cache)
{
	struct btrfs_caching_control *ctl;

	spin_lock(&cache->lock);
	if (!cache->caching_ctl) {
		spin_unlock(&cache->lock);
		return NULL;
	}

	ctl = cache->caching_ctl;
	refcount_inc(&ctl->count);
	spin_unlock(&cache->lock);
	return ctl;
}


static void clear_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags)
{
	u64 extra_flags = chunk_to_extended(flags) &
				BTRFS_EXTENDED_PROFILE_MASK;

	write_seqlock(&fs_info->profiles_lock);
	if (flags & BTRFS_BLOCK_GROUP_DATA)
		fs_info->avail_data_alloc_bits &= ~extra_flags;
	if (flags & BTRFS_BLOCK_GROUP_METADATA)
		fs_info->avail_metadata_alloc_bits &= ~extra_flags;
	if (flags & BTRFS_BLOCK_GROUP_SYSTEM)
		fs_info->avail_system_alloc_bits &= ~extra_flags;
	write_sequnlock(&fs_info->profiles_lock);
}


static int update_cowonly_root(struct btrfs_trans_handle *trans,
			       struct btrfs_root *root)
{
	int ret;
	u64 old_root_bytenr;
	u64 old_root_used;
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct btrfs_root *tree_root = fs_info->tree_root;

	old_root_used = btrfs_root_used(&root->root_item);

	while (1) {
		old_root_bytenr = btrfs_root_bytenr(&root->root_item);
		if (old_root_bytenr == root->node->start &&
		    old_root_used == btrfs_root_used(&root->root_item))
			break;

		btrfs_set_root_node(&root->root_item, root->node);
		ret = btrfs_update_root(trans, tree_root,
					&root->root_key,
					&root->root_item);
		if (ret)
			return ret;

		old_root_used = btrfs_root_used(&root->root_item);
	}

	return 0;
}


max3421_transfer_in(struct usb_hcd *hcd, struct urb *urb)
{
	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
	int epnum = usb_pipeendpoint(urb->pipe);

	max3421_hcd->curr_len = 0;
	max3421_hcd->hien |= BIT(MAX3421_HI_RCVDAV_BIT);
	return MAX3421_HXFR_BULK_IN(epnum);
}


max3421_set_address(struct usb_hcd *hcd, struct usb_device *dev, int epnum)
{
	int rcvtog, sndtog;
	u8 hctl;

	/* setup new endpoint's toggle bits: */
	rcvtog = usb_gettoggle(dev, epnum, 0);
	sndtog = usb_gettoggle(dev, epnum, 1);
	hctl = (BIT(rcvtog + MAX3421_HCTL_RCVTOG0_BIT) |
		BIT(sndtog + MAX3421_HCTL_SNDTOG0_BIT));

	spi_wr8(hcd, MAX3421_REG_HCTL, hctl);

	/*
	 * Note: devnum for one and the same device can change during
	 * address-assignment so it's best to just always load the
	 * address whenever the end-point changed/was forced.
	 */
	spi_wr8(hcd, MAX3421_REG_PERADDR, dev->devnum);
}


max3421_to_hcd(struct max3421_hcd *max3421_hcd)
{
	return container_of((void *) max3421_hcd, struct usb_hcd, hcd_priv);
}


max3421_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
{
	struct spi_device *spi = to_spi_device(hcd->self.controller);
	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
	struct max3421_ep *max3421_ep;
	unsigned long flags;
	int retval;

	switch (usb_pipetype(urb->pipe)) {
	case PIPE_INTERRUPT:
	case PIPE_ISOCHRONOUS:
		if (urb->interval < 0) {
			dev_err(&spi->dev,
			  "%s: interval=%d for intr-/iso-pipe; expected > 0\n",
				__func__, urb->interval);
			return -EINVAL;
		}
		break;
	default:
		break;
	}

	spin_lock_irqsave(&max3421_hcd->lock, flags);

	max3421_ep = urb->ep->hcpriv;
	if (!max3421_ep) {
		/* gets freed in max3421_endpoint_disable: */
		max3421_ep = kzalloc(sizeof(struct max3421_ep), GFP_ATOMIC);
		if (!max3421_ep) {
			retval = -ENOMEM;
			goto out;
		}
		max3421_ep->ep = urb->ep;
		max3421_ep->last_active = max3421_hcd->frame_number;
		urb->ep->hcpriv = max3421_ep;

		list_add_tail(&max3421_ep->ep_list, &max3421_hcd->ep_list);
	}

	retval = usb_hcd_link_urb_to_ep(hcd, urb);
	if (retval == 0) {
		/* Since we added to the queue, restart scheduling: */
		max3421_hcd->sched_pass = SCHED_PASS_PERIODIC;
		wake_up_process(max3421_hcd->spi_thread);
	}

out:
	spin_unlock_irqrestore(&max3421_hcd->lock, flags);
	return retval;
}


max3421_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
{
	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
	unsigned long flags;

	spin_lock_irqsave(&max3421_hcd->lock, flags);

	if (ep->hcpriv) {
		struct max3421_ep *max3421_ep = ep->hcpriv;

		/* remove myself from the ep_list: */
		if (!list_empty(&max3421_ep->ep_list))
			list_del(&max3421_ep->ep_list);
		kfree(max3421_ep);
		ep->hcpriv = NULL;
	}

	spin_unlock_irqrestore(&max3421_hcd->lock, flags);
}


max3421_of_vbus_en_pin(struct device *dev, struct max3421_hcd_platform_data *pdata)
{
	int retval;
	uint32_t value[2];

	if (!pdata)
		return -EINVAL;

	retval = of_property_read_u32_array(dev->of_node, "maxim,vbus-en-pin", value, 2);
	if (retval) {
		dev_err(dev, "device tree node property 'maxim,vbus-en-pin' is missing\n");
		return retval;
	}
	dev_info(dev, "property 'maxim,vbus-en-pin' value is <%d %d>\n", value[0], value[1]);

	pdata->vbus_gpout = value[0];
	pdata->vbus_active_level = value[1];

	return 0;
}


spi_rd8(struct usb_hcd *hcd, unsigned int reg)
{
	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
	struct spi_device *spi = to_spi_device(hcd->self.controller);
	struct spi_transfer transfer;
	struct spi_message msg;

	memset(&transfer, 0, sizeof(transfer));

	spi_message_init(&msg);

	max3421_hcd->tx->data[0] =
		(field(reg, MAX3421_SPI_REG_SHIFT) |
		 field(MAX3421_SPI_DIR_RD, MAX3421_SPI_DIR_SHIFT));

	transfer.tx_buf = max3421_hcd->tx->data;
	transfer.rx_buf = max3421_hcd->rx->data;
	transfer.len = 2;

	spi_message_add_tail(&transfer, &msg);
	spi_sync(spi, &msg);

	return max3421_hcd->rx->data[1];
}


static void xemaclite_aligned_write(void *src_ptr, u32 *dest_ptr,
				    unsigned length)
{
	u32 align_buffer;
	u32 *to_u32_ptr;
	u16 *from_u16_ptr, *to_u16_ptr;

	to_u32_ptr = dest_ptr;
	from_u16_ptr = src_ptr;
	align_buffer = 0;

	for (; length > 3; length -= 4) {
		to_u16_ptr = (u16 *)&align_buffer;
		*to_u16_ptr++ = *from_u16_ptr++;
		*to_u16_ptr++ = *from_u16_ptr++;

		/* This barrier resolves occasional issues seen around
		 * cases where the data is not properly flushed out
		 * from the processor store buffers to the destination
		 * memory locations.
		 */
		wmb();

		/* Output a word */
		*to_u32_ptr++ = align_buffer;
	}
	if (length) {
		u8 *from_u8_ptr, *to_u8_ptr;

		/* Set up to output the remaining data */
		align_buffer = 0;
		to_u8_ptr = (u8 *)&align_buffer;
		from_u8_ptr = (u8 *)from_u16_ptr;

		/* Output the remaining data */
		for (; length > 0; length--)
			*to_u8_ptr++ = *from_u8_ptr++;

		/* This barrier resolves occasional issues seen around
		 * cases where the data is not properly flushed out
		 * from the processor store buffers to the destination
		 * memory locations.
		 */
		wmb();
		*to_u32_ptr = align_buffer;
	}
}


static int xemaclite_close(struct net_device *dev)
{
	struct net_local *lp = netdev_priv(dev);

	netif_stop_queue(dev);
	xemaclite_disable_interrupts(lp);
	free_irq(dev->irq, dev);

	if (lp->phy_dev)
		phy_disconnect(lp->phy_dev);
	lp->phy_dev = NULL;

	return 0;
}


static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data, int maxlen)
{
	void __iomem *addr;
	u16 length, proto_type;
	u32 reg_data;

	/* Determine the expected buffer address */
	addr = (drvdata->base_addr + drvdata->next_rx_buf_to_use);

	/* Verify which buffer has valid data */
	reg_data = xemaclite_readl(addr + XEL_RSR_OFFSET);

	if ((reg_data & XEL_RSR_RECV_DONE_MASK) == XEL_RSR_RECV_DONE_MASK) {
		if (drvdata->rx_ping_pong != 0)
			drvdata->next_rx_buf_to_use ^= XEL_BUFFER_OFFSET;
	} else {
		/* The instance is out of sync, try other buffer if other
		 * buffer is configured, return 0 otherwise. If the instance is
		 * out of sync, do not update the 'next_rx_buf_to_use' since it
		 * will correct on subsequent calls
		 */
		if (drvdata->rx_ping_pong != 0)
			addr = (void __iomem __force *)
				((uintptr_t __force)addr ^
				 XEL_BUFFER_OFFSET);
		else
			return 0;	/* No data was available */

		/* Verify that buffer has valid data */
		reg_data = xemaclite_readl(addr + XEL_RSR_OFFSET);
		if ((reg_data & XEL_RSR_RECV_DONE_MASK) !=
		     XEL_RSR_RECV_DONE_MASK)
			return 0;	/* No data was available */
	}

	/* Get the protocol type of the ethernet frame that arrived
	 */
	proto_type = ((ntohl(xemaclite_readl(addr + XEL_HEADER_OFFSET +
			XEL_RXBUFF_OFFSET)) >> XEL_HEADER_SHIFT) &
			XEL_RPLR_LENGTH_MASK);

	/* Check if received ethernet frame is a raw ethernet frame
	 * or an IP packet or an ARP packet
	 */
	if (proto_type > ETH_DATA_LEN) {

		if (proto_type == ETH_P_IP) {
			length = ((ntohl(xemaclite_readl(addr +
					XEL_HEADER_IP_LENGTH_OFFSET +
					XEL_RXBUFF_OFFSET)) >>
					XEL_HEADER_SHIFT) &
					XEL_RPLR_LENGTH_MASK);
			length = min_t(u16, length, ETH_DATA_LEN);
			length += ETH_HLEN + ETH_FCS_LEN;

		} else if (proto_type == ETH_P_ARP)
			length = XEL_ARP_PACKET_SIZE + ETH_HLEN + ETH_FCS_LEN;
		else
			/* Field contains type other than IP or ARP, use max
			 * frame size and let user parse it
			 */
			length = ETH_FRAME_LEN + ETH_FCS_LEN;
	} else
		/* Use the length in the frame, plus the header and trailer */
		length = proto_type + ETH_HLEN + ETH_FCS_LEN;

	if (WARN_ON(length > maxlen))
		length = maxlen;

	/* Read from the EmacLite device */
	xemaclite_aligned_read((u32 __force *)(addr + XEL_RXBUFF_OFFSET),
				data, length);

	/* Acknowledge the frame */
	reg_data = xemaclite_readl(addr + XEL_RSR_OFFSET);
	reg_data &= ~XEL_RSR_RECV_DONE_MASK;
	xemaclite_writel(reg_data, addr + XEL_RSR_OFFSET);

	return length;
}


static void xemaclite_tx_timeout(struct net_device *dev, unsigned int txqueue)
{
	struct net_local *lp = netdev_priv(dev);
	unsigned long flags;

	dev_err(&lp->ndev->dev, "Exceeded transmit timeout of %lu ms\n",
		TX_TIMEOUT * 1000UL / HZ);

	dev->stats.tx_errors++;

	/* Reset the device */
	spin_lock_irqsave(&lp->reset_lock, flags);

	/* Shouldn't really be necessary, but shouldn't hurt */
	netif_stop_queue(dev);

	xemaclite_disable_interrupts(lp);
	xemaclite_enable_interrupts(lp);

	if (lp->deferred_skb) {
		dev_kfree_skb(lp->deferred_skb);
		lp->deferred_skb = NULL;
		dev->stats.tx_errors++;
	}

	/* To exclude tx timeout */
	netif_trans_update(dev); /* prevent tx timeout */

	/* We're all ready to go. Start the queue */
	netif_wake_queue(dev);
	spin_unlock_irqrestore(&lp->reset_lock, flags);
}


ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx)
{
	struct sk_buff *skb;
	struct ieee80211_hdr *hdr;
	int next_len;
	bool group_addr;

	skb_queue_walk(&tx->skbs, skb) {
		hdr = (void *) skb->data;
		if (unlikely(ieee80211_is_pspoll(hdr->frame_control)))
			break; /* must not overwrite AID */
		if (!skb_queue_is_last(&tx->skbs, skb)) {
			struct sk_buff *next = skb_queue_next(&tx->skbs, skb);
			next_len = next->len;
		} else
			next_len = 0;
		group_addr = is_multicast_ether_addr(hdr->addr1);

		hdr->duration_id =
			ieee80211_duration(tx, skb, group_addr, next_len);
	}

	return TX_CONTINUE;
}


static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata,
				      struct sta_info *sta,
				      struct ieee80211_fast_tx *fast_tx,
				      struct sk_buff *skb)
{
	struct ieee80211_local *local = sdata->local;
	struct fq *fq = &local->fq;
	struct fq_tin *tin;
	struct fq_flow *flow;
	u8 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
	struct ieee80211_txq *txq = sta->sta.txq[tid];
	struct txq_info *txqi;
	struct sk_buff **frag_tail, *head;
	int subframe_len = skb->len - ETH_ALEN;
	u8 max_subframes = sta->sta.max_amsdu_subframes;
	int max_frags = local->hw.max_tx_fragments;
	int max_amsdu_len = sta->sta.max_amsdu_len;
	int orig_truesize;
	u32 flow_idx;
	__be16 len;
	void *data;
	bool ret = false;
	unsigned int orig_len;
	int n = 2, nfrags, pad = 0;
	u16 hdrlen;

	if (!ieee80211_hw_check(&local->hw, TX_AMSDU))
		return false;

	if (skb_is_gso(skb))
		return false;

	if (!txq)
		return false;

	txqi = to_txq_info(txq);
	if (test_bit(IEEE80211_TXQ_NO_AMSDU, &txqi->flags))
		return false;

	if (sta->sta.max_rc_amsdu_len)
		max_amsdu_len = min_t(int, max_amsdu_len,
				      sta->sta.max_rc_amsdu_len);

	if (sta->sta.max_tid_amsdu_len[tid])
		max_amsdu_len = min_t(int, max_amsdu_len,
				      sta->sta.max_tid_amsdu_len[tid]);

	flow_idx = fq_flow_idx(fq, skb);

	spin_lock_bh(&fq->lock);

	/* TODO: Ideally aggregation should be done on dequeue to remain
	 * responsive to environment changes.
	 */

	tin = &txqi->tin;
	flow = fq_flow_classify(fq, tin, flow_idx, skb);
	head = skb_peek_tail(&flow->queue);
	if (!head || skb_is_gso(head))
		goto out;

	orig_truesize = head->truesize;
	orig_len = head->len;

	if (skb->len + head->len > max_amsdu_len)
		goto out;

	nfrags = 1 + skb_shinfo(skb)->nr_frags;
	nfrags += 1 + skb_shinfo(head)->nr_frags;
	frag_tail = &skb_shinfo(head)->frag_list;
	while (*frag_tail) {
		nfrags += 1 + skb_shinfo(*frag_tail)->nr_frags;
		frag_tail = &(*frag_tail)->next;
		n++;
	}

	if (max_subframes && n > max_subframes)
		goto out;

	if (max_frags && nfrags > max_frags)
		goto out;

	if (!drv_can_aggregate_in_amsdu(local, head, skb))
		goto out;

	if (!ieee80211_amsdu_prepare_head(sdata, fast_tx, head))
		goto out;

	/*
	 * Pad out the previous subframe to a multiple of 4 by adding the
	 * padding to the next one, that's being added. Note that head->len
	 * is the length of the full A-MSDU, but that works since each time
	 * we add a new subframe we pad out the previous one to a multiple
	 * of 4 and thus it no longer matters in the next round.
	 */
	hdrlen = fast_tx->hdr_len - sizeof(rfc1042_header);
	if ((head->len - hdrlen) & 3)
		pad = 4 - ((head->len - hdrlen) & 3);

	if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(rfc1042_header) +
						     2 + pad))
		goto out_recalc;

	ret = true;
	data = skb_push(skb, ETH_ALEN + 2);
	memmove(data, data + ETH_ALEN + 2, 2 * ETH_ALEN);

	data += 2 * ETH_ALEN;
	len = cpu_to_be16(subframe_len);
	memcpy(data, &len, 2);
	memcpy(data + 2, rfc1042_header, sizeof(rfc1042_header));

	memset(skb_push(skb, pad), 0, pad);

	head->len += skb->len;
	head->data_len += skb->len;
	*frag_tail = skb;

out_recalc:
	fq->memory_usage += head->truesize - orig_truesize;
	if (head->len != orig_len) {
		flow->backlog += head->len - orig_len;
		tin->backlog_bytes += head->len - orig_len;
	}
out:
	spin_unlock_bh(&fq->lock);

	return ret;
}


ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
{
	struct ieee80211_key *key;
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;

	if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) {
		tx->key = NULL;
		return TX_CONTINUE;
	}

	if (tx->sta &&
	    (key = rcu_dereference(tx->sta->ptk[tx->sta->ptk_idx])))
		tx->key = key;
	else if (ieee80211_is_group_privacy_action(tx->skb) &&
		(key = rcu_dereference(tx->sdata->default_multicast_key)))
		tx->key = key;
	else if (ieee80211_is_mgmt(hdr->frame_control) &&
		 is_multicast_ether_addr(hdr->addr1) &&
		 ieee80211_is_robust_mgmt_frame(tx->skb) &&
		 (key = rcu_dereference(tx->sdata->default_mgmt_key)))
		tx->key = key;
	else if (is_multicast_ether_addr(hdr->addr1) &&
		 (key = rcu_dereference(tx->sdata->default_multicast_key)))
		tx->key = key;
	else if (!is_multicast_ether_addr(hdr->addr1) &&
		 (key = rcu_dereference(tx->sdata->default_unicast_key)))
		tx->key = key;
	else
		tx->key = NULL;

	if (tx->key) {
		bool skip_hw = false;

		/* TODO: add threshold stuff again */

		switch (tx->key->conf.cipher) {
		case WLAN_CIPHER_SUITE_WEP40:
		case WLAN_CIPHER_SUITE_WEP104:
		case WLAN_CIPHER_SUITE_TKIP:
			if (!ieee80211_is_data_present(hdr->frame_control))
				tx->key = NULL;
			break;
		case WLAN_CIPHER_SUITE_CCMP:
		case WLAN_CIPHER_SUITE_CCMP_256:
		case WLAN_CIPHER_SUITE_GCMP:
		case WLAN_CIPHER_SUITE_GCMP_256:
			if (!ieee80211_is_data_present(hdr->frame_control) &&
			    !ieee80211_use_mfp(hdr->frame_control, tx->sta,
					       tx->skb) &&
			    !ieee80211_is_group_privacy_action(tx->skb))
				tx->key = NULL;
			else
				skip_hw = (tx->key->conf.flags &
					   IEEE80211_KEY_FLAG_SW_MGMT_TX) &&
					ieee80211_is_mgmt(hdr->frame_control);
			break;
		case WLAN_CIPHER_SUITE_AES_CMAC:
		case WLAN_CIPHER_SUITE_BIP_CMAC_256:
		case WLAN_CIPHER_SUITE_BIP_GMAC_128:
		case WLAN_CIPHER_SUITE_BIP_GMAC_256:
			if (!ieee80211_is_mgmt(hdr->frame_control))
				tx->key = NULL;
			break;
		}

		if (unlikely(tx->key && tx->key->flags & KEY_FLAG_TAINTED &&
			     !ieee80211_is_deauth(hdr->frame_control)))
			return TX_DROP;

		if (!skip_hw && tx->key &&
		    tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
			info->control.hw_key = &tx->key->conf;
	} else if (ieee80211_is_data_present(hdr->frame_control) && tx->sta &&
		   test_sta_flag(tx->sta, WLAN_STA_USES_ENCRYPTION)) {
		return TX_DROP;
	}

	return TX_CONTINUE;
}


netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb,
					    struct net_device *dev)
{
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
	struct ethhdr *ehdr = (struct ethhdr *)skb->data;
	struct ieee80211_key *key;
	struct sta_info *sta;

	if (unlikely(skb->len < ETH_HLEN)) {
		kfree_skb(skb);
		return NETDEV_TX_OK;
	}

	rcu_read_lock();

	if (ieee80211_lookup_ra_sta(sdata, skb, &sta)) {
		kfree_skb(skb);
		goto out;
	}

	if (unlikely(IS_ERR_OR_NULL(sta) || !sta->uploaded ||
	    !test_sta_flag(sta, WLAN_STA_AUTHORIZED) ||
	    sdata->control_port_protocol == ehdr->h_proto))
		goto skip_offload;

	key = rcu_dereference(sta->ptk[sta->ptk_idx]);
	if (!key)
		key = rcu_dereference(sdata->default_unicast_key);

	if (key && (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) ||
		    key->conf.cipher == WLAN_CIPHER_SUITE_TKIP))
		goto skip_offload;

	ieee80211_8023_xmit(sdata, dev, sta, key, skb);
	goto out;

skip_offload:
	ieee80211_subif_start_xmit(skb, dev);
out:
	rcu_read_unlock();

	return NETDEV_TX_OK;
}


int ieee80211_lookup_ra_sta(struct ieee80211_sub_if_data *sdata,
			    struct sk_buff *skb,
			    struct sta_info **sta_out)
{
	struct sta_info *sta;

	switch (sdata->vif.type) {
	case NL80211_IFTYPE_AP_VLAN:
		sta = rcu_dereference(sdata->u.vlan.sta);
		if (sta) {
			*sta_out = sta;
			return 0;
		} else if (sdata->wdev.use_4addr) {
			return -ENOLINK;
		}
		fallthrough;
	case NL80211_IFTYPE_AP:
	case NL80211_IFTYPE_OCB:
	case NL80211_IFTYPE_ADHOC:
		if (is_multicast_ether_addr(skb->data)) {
			*sta_out = ERR_PTR(-ENOENT);
			return 0;
		}
		sta = sta_info_get_bss(sdata, skb->data);
		break;
#ifdef CONFIG_MAC80211_MESH
	case NL80211_IFTYPE_MESH_POINT:
		/* determined much later */
		*sta_out = NULL;
		return 0;
#endif
	case NL80211_IFTYPE_STATION:
		if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) {
			sta = sta_info_get(sdata, skb->data);
			if (sta && test_sta_flag(sta, WLAN_STA_TDLS_PEER)) {
				if (test_sta_flag(sta,
						  WLAN_STA_TDLS_PEER_AUTH)) {
					*sta_out = sta;
					return 0;
				}

				/*
				 * TDLS link during setup - throw out frames to
				 * peer. Allow TDLS-setup frames to unauthorized
				 * peers for the special case of a link teardown
				 * after a TDLS sta is removed due to being
				 * unreachable.
				 */
				if (!ieee80211_is_tdls_setup(skb))
					return -EINVAL;
			}

		}

		sta = sta_info_get(sdata, sdata->u.mgd.bssid);
		if (!sta)
			return -ENOLINK;
		break;
	default:
		return -EINVAL;
	}

	*sta_out = sta ?: ERR_PTR(-ENOENT);
	return 0;
}


static int ieee80211_use_mfp(__le16 fc, struct sta_info *sta,
			     struct sk_buff *skb)
{
	if (!ieee80211_is_mgmt(fc))
		return 0;

	if (sta == NULL || !test_sta_flag(sta, WLAN_STA_MFP))
		return 0;

	if (!ieee80211_is_robust_mgmt_frame(skb))
		return 0;

	return 1;
}


int temac_indirect_busywait(struct temac_local *lp)
{
	ktime_t timeout = ktime_add_ns(ktime_get(), HARD_ACS_RDY_POLL_NS);

	spin_until_cond(hard_acs_rdy_or_timeout(lp, timeout));
	if (WARN_ON(!hard_acs_rdy(lp)))
		return -ETIMEDOUT;
	else
		return 0;
}


static int temac_init_mac_address(struct net_device *ndev, const void *address)
{
	memcpy(ndev->dev_addr, address, ETH_ALEN);
	if (!is_valid_ether_addr(ndev->dev_addr))
		eth_hw_addr_random(ndev);
	temac_do_set_mac_address(ndev);
	return 0;
}


static int ll_temac_ethtools_set_coalesce(struct net_device *ndev,
					  struct ethtool_coalesce *ec)
{
	struct temac_local *lp = netdev_priv(ndev);

	if (netif_running(ndev)) {
		netdev_err(ndev,
			   "Please stop netif before applying configuration\n");
		return -EFAULT;
	}

	if (ec->rx_max_coalesced_frames)
		lp->coalesce_count_rx = ec->rx_max_coalesced_frames;
	if (ec->tx_max_coalesced_frames)
		lp->coalesce_count_tx = ec->tx_max_coalesced_frames;
	/* With typical LocalLink clock speed of 200 MHz and
	 * C_PRESCALAR=1023, each delay count corresponds to 5.12 us.
	 */
	if (ec->rx_coalesce_usecs)
		lp->coalesce_delay_rx =
			min(255U, (ec->rx_coalesce_usecs * 100) / 512);
	if (ec->tx_coalesce_usecs)
		lp->coalesce_delay_tx =
			min(255U, (ec->tx_coalesce_usecs * 100) / 512);

	return 0;
}


static int ct_seq_show(struct seq_file *s, void *v)
{
	struct nf_conntrack_tuple_hash *hash = v;
	struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(hash);
	const struct nf_conntrack_l4proto *l4proto;
	struct net *net = seq_file_net(s);
	int ret = 0;

	WARN_ON(!ct);
	if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use)))
		return 0;

	if (nf_ct_should_gc(ct)) {
		nf_ct_kill(ct);
		goto release;
	}

	/* we only want to print DIR_ORIGINAL */
	if (NF_CT_DIRECTION(hash))
		goto release;

	if (!net_eq(nf_ct_net(ct), net))
		goto release;

	l4proto = nf_ct_l4proto_find(nf_ct_protonum(ct));

	ret = -ENOSPC;
	seq_printf(s, "%-8s %u %-8s %u ",
		   l3proto_name(nf_ct_l3num(ct)), nf_ct_l3num(ct),
		   l4proto_name(l4proto->l4proto), nf_ct_protonum(ct));

	if (!test_bit(IPS_OFFLOAD_BIT, &ct->status))
		seq_printf(s, "%ld ", nf_ct_expires(ct)  / HZ);

	if (l4proto->print_conntrack)
		l4proto->print_conntrack(s, ct);

	print_tuple(s, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
		    l4proto);

	ct_show_zone(s, ct, NF_CT_ZONE_DIR_ORIG);

	if (seq_has_overflowed(s))
		goto release;

	if (seq_print_acct(s, ct, IP_CT_DIR_ORIGINAL))
		goto release;

	if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status)))
		seq_puts(s, "[UNREPLIED] ");

	print_tuple(s, &ct->tuplehash[IP_CT_DIR_REPLY].tuple, l4proto);

	ct_show_zone(s, ct, NF_CT_ZONE_DIR_REPL);

	if (seq_print_acct(s, ct, IP_CT_DIR_REPLY))
		goto release;

	if (test_bit(IPS_HW_OFFLOAD_BIT, &ct->status))
		seq_puts(s, "[HW_OFFLOAD] ");
	else if (test_bit(IPS_OFFLOAD_BIT, &ct->status))
		seq_puts(s, "[OFFLOAD] ");
	else if (test_bit(IPS_ASSURED_BIT, &ct->status))
		seq_puts(s, "[ASSURED] ");

	if (seq_has_overflowed(s))
		goto release;

#if defined(CONFIG_NF_CONNTRACK_MARK)
	seq_printf(s, "mark=%u ", ct->mark);
#endif

	ct_show_secctx(s, ct);
	ct_show_zone(s, ct, NF_CT_DEFAULT_ZONE_DIR);
	ct_show_delta_time(s, ct);

	seq_printf(s, "use=%u\n", atomic_read(&ct->ct_general.use));

	if (seq_has_overflowed(s))
		goto release;

	ret = 0;
release:
	nf_ct_put(ct);
	return ret;
}


static int nf_conntrack_standalone_init_sysctl(struct net *net)
{
	struct nf_conntrack_net *cnet = net_generic(net, nf_conntrack_net_id);
	struct nf_udp_net *un = nf_udp_pernet(net);
	struct ctl_table *table;

	BUILD_BUG_ON(ARRAY_SIZE(nf_ct_sysctl_table) != NF_SYSCTL_CT_LAST_SYSCTL);

	table = kmemdup(nf_ct_sysctl_table, sizeof(nf_ct_sysctl_table),
			GFP_KERNEL);
	if (!table)
		return -ENOMEM;

	table[NF_SYSCTL_CT_COUNT].data = &net->ct.count;
	table[NF_SYSCTL_CT_CHECKSUM].data = &net->ct.sysctl_checksum;
	table[NF_SYSCTL_CT_LOG_INVALID].data = &net->ct.sysctl_log_invalid;
	table[NF_SYSCTL_CT_ACCT].data = &net->ct.sysctl_acct;
	table[NF_SYSCTL_CT_HELPER].data = &net->ct.sysctl_auto_assign_helper;
#ifdef CONFIG_NF_CONNTRACK_EVENTS
	table[NF_SYSCTL_CT_EVENTS].data = &net->ct.sysctl_events;
#endif
#ifdef CONFIG_NF_CONNTRACK_TIMESTAMP
	table[NF_SYSCTL_CT_TIMESTAMP].data = &net->ct.sysctl_tstamp;
#endif
	table[NF_SYSCTL_CT_PROTO_TIMEOUT_GENERIC].data = &nf_generic_pernet(net)->timeout;
	table[NF_SYSCTL_CT_PROTO_TIMEOUT_ICMP].data = &nf_icmp_pernet(net)->timeout;
	table[NF_SYSCTL_CT_PROTO_TIMEOUT_ICMPV6].data = &nf_icmpv6_pernet(net)->timeout;
	table[NF_SYSCTL_CT_PROTO_TIMEOUT_UDP].data = &un->timeouts[UDP_CT_UNREPLIED];
	table[NF_SYSCTL_CT_PROTO_TIMEOUT_UDP_STREAM].data = &un->timeouts[UDP_CT_REPLIED];

	nf_conntrack_standalone_init_tcp_sysctl(net, table);
	nf_conntrack_standalone_init_sctp_sysctl(net, table);
	nf_conntrack_standalone_init_dccp_sysctl(net, table);
	nf_conntrack_standalone_init_gre_sysctl(net, table);

	/* Don't allow non-init_net ns to alter global sysctls */
	if (!net_eq(&init_net, net)) {
		table[NF_SYSCTL_CT_MAX].mode = 0444;
		table[NF_SYSCTL_CT_EXPECT_MAX].mode = 0444;
		table[NF_SYSCTL_CT_BUCKETS].mode = 0444;
	}

	cnet->sysctl_header = register_net_sysctl(net, "net/netfilter", table);
	if (!cnet->sysctl_header)
		goto out_unregister_netfilter;

	return 0;

out_unregister_netfilter:
	kfree(table);
	return -ENOMEM;
}


static void nf_conntrack_pernet_exit(struct list_head *net_exit_list)
{
	struct net *net;

	list_for_each_entry(net, net_exit_list, exit_list)
		nf_conntrack_fini_net(net);

	nf_conntrack_cleanup_net_list(net_exit_list);
}


static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct)
{
	int ret;
	u32 len;
	char *secctx;

	ret = security_secid_to_secctx(ct->secmark, &secctx, &len);
	if (ret)
		return;

	seq_printf(s, "secctx=%s ", secctx);

	security_release_secctx(secctx, len);
}


void usbredirparser_destroy(struct usbredirparser *parser_pub)
{
    struct usbredirparser_priv *parser =
        (struct usbredirparser_priv *)parser_pub;
    struct usbredirparser_buf *wbuf, *next_wbuf;

    free(parser->data);
    parser->data = NULL;

    wbuf = parser->write_buf;
    while (wbuf) {
        next_wbuf = wbuf->next;
        free(wbuf->buf);
        free(wbuf);
        wbuf = next_wbuf;
    }

    if (parser->lock)
        parser->callb.free_lock_func(parser->lock);

    free(parser);
}


void usbredirparser_send_bulk_receiving_status(struct usbredirparser *parser,
    uint64_t id,
    struct usb_redir_bulk_receiving_status_header *bulk_receiving_status)
{
    usbredirparser_queue(parser, usb_redir_bulk_receiving_status, id,
                         bulk_receiving_status, NULL, 0);
}


void usbredirparser_send_reset(struct usbredirparser *parser)
{
    usbredirparser_queue(parser, usb_redir_reset, 0, NULL, NULL, 0);
}


static int unserialize_data(struct usbredirparser_priv *parser,
                            uint8_t **pos, uint32_t *remain,
                            uint8_t **data, uint32_t *len_in_out,
                            const char *desc)
{
    uint32_t len;

    if (*remain < sizeof(uint32_t)) {
        ERROR("error buffer underrun while unserializing state");
        return -1;
    }
    memcpy(&len, *pos, sizeof(uint32_t));
    *pos += sizeof(uint32_t);
    *remain -= sizeof(uint32_t);

    if (*remain < len) {
        ERROR("error buffer underrun while unserializing state");
        return -1;
    }
    if (*data == NULL && len > 0) {
        *data = malloc(len);
        if (!*data) {
            ERROR("Out of memory allocating unserialize buffer");
            return -1;
        }
    } else {
        if (*len_in_out < len) {
            ERROR("error buffer overrun while unserializing state");
            return -1;
        }
    }

    memcpy(*data, *pos, len);
    *pos += len;
    *remain -= len;
    *len_in_out = len;

    DEBUG("unserialized %d bytes of %s data", len, desc);
    if (len >= 8)
        DEBUG("First 8 bytes of %s: %02x %02x %02x %02x %02x %02x %02x %02x",
              desc, (*data)[0], (*data)[1], (*data)[2], (*data)[3],
              (*data)[4], (*data)[5], (*data)[6], (*data)[7]);

    return 0;
}


void usbredirparser_send_set_configuration(struct usbredirparser *parser,
    uint64_t id,
    struct usb_redir_set_configuration_header *set_configuration)
{
    usbredirparser_queue(parser, usb_redir_set_configuration, id,
                         set_configuration, NULL, 0);
}


static void usbredirparser_verify_caps(struct usbredirparser_priv *parser,
    uint32_t *caps, const char *desc)
{
    if (usbredirparser_caps_get_cap(parser, caps,
                                    usb_redir_cap_bulk_streams) &&
        !usbredirparser_caps_get_cap(parser, caps,
                                     usb_redir_cap_ep_info_max_packet_size)) {
        ERROR("error %s caps contains cap_bulk_streams without"
              "cap_ep_info_max_packet_size", desc);
        caps[0] &= ~(1 << usb_redir_cap_bulk_streams);
    }
}


void usbredirparser_send_configuration_status(struct usbredirparser *parser,
    uint64_t id,
    struct usb_redir_configuration_status_header *configuration_status)
{
    usbredirparser_queue(parser, usb_redir_configuration_status, id,
                         configuration_status, NULL, 0);
}


int usbredirparser_have_cap(struct usbredirparser *parser_pub, int cap)
{
    struct usbredirparser_priv *parser =
        (struct usbredirparser_priv *)parser_pub;
    return usbredirparser_caps_get_cap(parser, parser->our_caps, cap);
}


static int htab_percpu_map_update_elem(struct bpf_map *map, void *key,
				       void *value, u64 map_flags)
{
	return __htab_percpu_map_update_elem(map, key, value, map_flags, false);
}


static void htab_free_elems(struct bpf_htab *htab)
{
	int i;

	if (!htab_is_percpu(htab))
		goto free_elems;

	for (i = 0; i < htab->map.max_entries; i++) {
		void __percpu *pptr;

		pptr = htab_elem_get_ptr(get_htab_elem(htab, i),
					 htab->map.key_size);
		free_percpu(pptr);
		cond_resched();
	}
free_elems:
	bpf_map_area_free(htab->elems);
}


htab_percpu_map_lookup_batch(struct bpf_map *map, const union bpf_attr *attr,
			     union bpf_attr __user *uattr)
{
	return __htab_map_lookup_and_delete_batch(map, attr, uattr, false,
						  false, true);
}


static int __bpf_hash_map_seq_show(struct seq_file *seq, struct htab_elem *elem)
{
	struct bpf_iter_seq_hash_map_info *info = seq->private;
	u32 roundup_key_size, roundup_value_size;
	struct bpf_iter__bpf_map_elem ctx = {};
	struct bpf_map *map = info->map;
	struct bpf_iter_meta meta;
	int ret = 0, off = 0, cpu;
	struct bpf_prog *prog;
	void __percpu *pptr;

	meta.seq = seq;
	prog = bpf_iter_get_info(&meta, elem == NULL);
	if (prog) {
		ctx.meta = &meta;
		ctx.map = info->map;
		if (elem) {
			roundup_key_size = round_up(map->key_size, 8);
			ctx.key = elem->key;
			if (!info->percpu_value_buf) {
				ctx.value = elem->key + roundup_key_size;
			} else {
				roundup_value_size = round_up(map->value_size, 8);
				pptr = htab_elem_get_ptr(elem, map->key_size);
				for_each_possible_cpu(cpu) {
					bpf_long_memcpy(info->percpu_value_buf + off,
							per_cpu_ptr(pptr, cpu),
							roundup_value_size);
					off += roundup_value_size;
				}
				ctx.value = info->percpu_value_buf;
			}
		}
		ret = bpf_iter_run_prog(prog, &ctx);
	}

	return ret;
}


static int htab_lru_map_lookup_and_delete_elem(struct bpf_map *map, void *key,
					       void *value, u64 flags)
{
	return __htab_map_lookup_and_delete_elem(map, key, value, true, false,
						 flags);
}


static struct htab_elem *lookup_nulls_elem_raw(struct hlist_nulls_head *head,
					       u32 hash, void *key,
					       u32 key_size, u32 n_buckets)
{
	struct hlist_nulls_node *n;
	struct htab_elem *l;

again:
	hlist_nulls_for_each_entry_rcu(l, n, head, hash_node)
		if (l->hash == hash && !memcmp(&l->key, key, key_size))
			return l;

	if (unlikely(get_nulls_value(n) != (hash & (n_buckets - 1))))
		goto again;

	return NULL;
}


static int check_flags(struct bpf_htab *htab, struct htab_elem *l_old,
		       u64 map_flags)
{
	if (l_old && (map_flags & ~BPF_F_LOCK) == BPF_NOEXIST)
		/* elem already exists */
		return -EEXIST;

	if (!l_old && (map_flags & ~BPF_F_LOCK) == BPF_EXIST)
		/* elem doesn't exist, cannot update it */
		return -ENOENT;

	return 0;
}


static int htab_lru_percpu_map_lookup_and_delete_elem(struct bpf_map *map,
						      void *key, void *value,
						      u64 flags)
{
	return __htab_map_lookup_and_delete_elem(map, key, value, true, true,
						 flags);
}


route4_set_fastmap(struct route4_head *head, u32 id, int iif,
		   struct route4_filter *f)
{
	int h = route4_fastmap_hash(id, iif);

	/* fastmap updates must look atomic to aling id, iff, filter */
	spin_lock_bh(&fastmap_lock);
	head->fastmap[h].id = id;
	head->fastmap[h].iif = iif;
	head->fastmap[h].filter = f;
	spin_unlock_bh(&fastmap_lock);
}


static int route4_dump(struct net *net, struct tcf_proto *tp, void *fh,
		       struct sk_buff *skb, struct tcmsg *t, bool rtnl_held)
{
	struct route4_filter *f = fh;
	struct nlattr *nest;
	u32 id;

	if (f == NULL)
		return skb->len;

	t->tcm_handle = f->handle;

	nest = nla_nest_start_noflag(skb, TCA_OPTIONS);
	if (nest == NULL)
		goto nla_put_failure;

	if (!(f->handle & 0x8000)) {
		id = f->id & 0xFF;
		if (nla_put_u32(skb, TCA_ROUTE4_TO, id))
			goto nla_put_failure;
	}
	if (f->handle & 0x80000000) {
		if ((f->handle >> 16) != 0xFFFF &&
		    nla_put_u32(skb, TCA_ROUTE4_IIF, f->iif))
			goto nla_put_failure;
	} else {
		id = f->id >> 16;
		if (nla_put_u32(skb, TCA_ROUTE4_FROM, id))
			goto nla_put_failure;
	}
	if (f->res.classid &&
	    nla_put_u32(skb, TCA_ROUTE4_CLASSID, f->res.classid))
		goto nla_put_failure;

	if (tcf_exts_dump(skb, &f->exts) < 0)
		goto nla_put_failure;

	nla_nest_end(skb, nest);

	if (tcf_exts_dump_stats(skb, &f->exts) < 0)
		goto nla_put_failure;

	return skb->len;

nla_put_failure:
	nla_nest_cancel(skb, nest);
	return -1;
}


static void route4_delete_filter_work(struct work_struct *work)
{
	struct route4_filter *f = container_of(to_rcu_work(work),
					       struct route4_filter,
					       rwork);
	rtnl_lock();
	__route4_delete_filter(f);
	rtnl_unlock();
}


send_newstyle_option_reply_info_str (uint32_t option, uint32_t reply,
                                     uint16_t info, const char *str,
                                     size_t len)
{
  GET_CONN;
  struct nbd_fixed_new_option_reply fixed_new_option_reply;
  struct nbd_fixed_new_option_reply_info_name_or_desc name;

  if (len == -1)
    len = strlen (str);
  assert (len <= NBD_MAX_STRING);

  fixed_new_option_reply.magic = htobe64 (NBD_REP_MAGIC);
  fixed_new_option_reply.option = htobe32 (option);
  fixed_new_option_reply.reply = htobe32 (reply);
  fixed_new_option_reply.replylen = htobe32 (sizeof info + len);
  name.info = htobe16 (info);

  if (conn->send (&fixed_new_option_reply,
                  sizeof fixed_new_option_reply, SEND_MORE) == -1 ||
      conn->send (&name, sizeof name, SEND_MORE) == -1 ||
      conn->send (str, len, 0) == -1) {
    nbdkit_error ("write: %s: %m", name_of_nbd_opt (option));
    return -1;
  }

  return 0;
}


send_newstyle_option_reply_info_export (uint32_t option, uint32_t reply,
                                        uint16_t info, uint64_t exportsize)
{
  GET_CONN;
  struct nbd_fixed_new_option_reply fixed_new_option_reply;
  struct nbd_fixed_new_option_reply_info_export export;

  fixed_new_option_reply.magic = htobe64 (NBD_REP_MAGIC);
  fixed_new_option_reply.option = htobe32 (option);
  fixed_new_option_reply.reply = htobe32 (reply);
  fixed_new_option_reply.replylen = htobe32 (sizeof export);
  export.info = htobe16 (info);
  export.exportsize = htobe64 (exportsize);
  export.eflags = htobe16 (conn->eflags);

  if (conn->send (&fixed_new_option_reply,
                  sizeof fixed_new_option_reply, SEND_MORE) == -1 ||
      conn->send (&export, sizeof export, 0) == -1) {
    nbdkit_error ("write: %s: %m", name_of_nbd_opt (option));
    return -1;
  }

  return 0;
}


void QPaintEngineEx::drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius,
                                     Qt::SizeMode mode)
{
    qreal x1 = rect.left();
    qreal x2 = rect.right();
    qreal y1 = rect.top();
    qreal y2 = rect.bottom();

    if (mode == Qt::RelativeSize) {
        xRadius = xRadius * rect.width() / 200.;
        yRadius = yRadius * rect.height() / 200.;
    }

    xRadius = qMin(xRadius, rect.width() / 2);
    yRadius = qMin(yRadius, rect.height() / 2);

    qreal pts[] = {
        x1 + xRadius, y1,                   // MoveTo
        x2 - xRadius, y1,                   // LineTo
        x2 - (1 - KAPPA) * xRadius, y1,     // CurveTo
        x2, y1 + (1 - KAPPA) * yRadius,
        x2, y1 + yRadius,
        x2, y2 - yRadius,                   // LineTo
        x2, y2 - (1 - KAPPA) * yRadius,     // CurveTo
        x2 - (1 - KAPPA) * xRadius, y2,
        x2 - xRadius, y2,
        x1 + xRadius, y2,                   // LineTo
        x1 + (1 - KAPPA) * xRadius, y2,           // CurveTo
        x1, y2 - (1 - KAPPA) * yRadius,
        x1, y2 - yRadius,
        x1, y1 + yRadius,                   // LineTo
        x1, y1 + (1 - KAPPA) * yRadius,           // CurveTo
        x1 + (1 - KAPPA) * xRadius, y1,
        x1 + xRadius, y1
    };

    QVectorPath path(pts, 17, qpaintengineex_roundedrect_types, QVectorPath::RoundedRectHint);
    draw(path);
}


const QVectorPath &qtVectorPathForPath(const QPainterPath &path)
{
    Q_ASSERT(path.d_func());
    return path.d_func()->vectorPath();
}


void QPaintEngineEx::drawPoints(const QPointF *points, int pointCount)
{
    QPen pen = state()->pen;
    if (pen.capStyle() == Qt::FlatCap)
        pen.setCapStyle(Qt::SquareCap);

    if (pen.brush().isOpaque()) {
        while (pointCount > 0) {
            int count = qMin(pointCount, 16);
            qreal pts[64];
            int oset = -1;
            for (int i=0; i<count; ++i) {
                pts[++oset] = points[i].x();
                pts[++oset] = points[i].y();
                pts[++oset] = points[i].x() + 1/63.;
                pts[++oset] = points[i].y();
            }
            QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::LinesHint);
            stroke(path, pen);
            pointCount -= 16;
            points += 16;
        }
    } else {
        for (int i=0; i<pointCount; ++i) {
            qreal pts[] = { points[i].x(), points[i].y(), points[i].x() + qreal(1/63.), points[i].y() };
            QVectorPath path(pts, 2, nullptr);
            stroke(path, pen);
        }
    }
}


bool QPaintEngineExPrivate::hasClipOperations() const
{
    Q_Q(const QPaintEngineEx);

    QPainter *p = q->painter();
    if (!p || !p->d_ptr)
        return false;

    return !p->d_ptr->state->clipInfo.isEmpty();
}


void QPaintEngineEx::drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount,
                                         const QPixmap &pixmap, QPainter::PixmapFragmentHints /*hints*/)
{
    if (pixmap.isNull())
        return;

    qreal oldOpacity = state()->opacity;
    QTransform oldTransform = state()->matrix;

    for (int i = 0; i < fragmentCount; ++i) {
        QTransform transform = oldTransform;
        transform.translate(fragments[i].x, fragments[i].y);
        transform.rotate(fragments[i].rotation);
        state()->opacity = oldOpacity * fragments[i].opacity;
        state()->matrix = transform;
        opacityChanged();
        transformChanged();

        qreal w = fragments[i].scaleX * fragments[i].width;
        qreal h = fragments[i].scaleY * fragments[i].height;
        QRectF sourceRect(fragments[i].sourceLeft, fragments[i].sourceTop,
                          fragments[i].width, fragments[i].height);
        drawPixmap(QRectF(-0.5 * w, -0.5 * h, w, h), pixmap, sourceRect);
    }

    state()->opacity = oldOpacity;
    state()->matrix = oldTransform;
    opacityChanged();
    transformChanged();
}


static void nested_svm_nmi(struct vcpu_svm *svm)
{
	svm->vmcb->control.exit_code = SVM_EXIT_NMI;
	svm->vmcb->control.exit_info_1 = 0;
	svm->vmcb->control.exit_info_2 = 0;

	nested_svm_vmexit(svm);
}


static void nested_svm_init_mmu_context(struct kvm_vcpu *vcpu)
{
	struct vcpu_svm *svm = to_svm(vcpu);
	struct vmcb *hsave = svm->nested.hsave;

	WARN_ON(mmu_is_nested(vcpu));

	vcpu->arch.mmu = &vcpu->arch.guest_mmu;
	kvm_init_shadow_npt_mmu(vcpu, X86_CR0_PG, hsave->save.cr4, hsave->save.efer,
				svm->nested.ctl.nested_cr3);
	vcpu->arch.mmu->get_guest_pgd     = nested_svm_get_tdp_cr3;
	vcpu->arch.mmu->get_pdptr         = nested_svm_get_tdp_pdptr;
	vcpu->arch.mmu->inject_page_fault = nested_svm_inject_npf_exit;
	reset_shadow_zero_bits_mask(vcpu, vcpu->arch.mmu);
	vcpu->arch.walk_mmu              = &vcpu->arch.nested_mmu;
}


bool legitimize_mnt(struct vfsmount *bastard, unsigned seq)
{
	int res = __legitimize_mnt(bastard, seq);
	if (likely(!res))
		return true;
	if (unlikely(res < 0)) {
		rcu_read_unlock();
		mntput(bastard);
		rcu_read_lock();
	}
	return false;
}


static void put_mountpoint(struct mountpoint *mp)
{
	__put_mountpoint(mp, &ex_mountpoints);
}


static int can_idmap_mount(const struct mount_kattr *kattr, struct mount *mnt)
{
	struct vfsmount *m = &mnt->mnt;

	if (!kattr->mnt_userns)
		return 0;

	/*
	 * Once a mount has been idmapped we don't allow it to change its
	 * mapping. It makes things simpler and callers can just create
	 * another bind-mount they can idmap if they want to.
	 */
	if (mnt_user_ns(m) != &init_user_ns)
		return -EPERM;

	/* The underlying filesystem doesn't support idmapped mounts yet. */
	if (!(m->mnt_sb->s_type->fs_flags & FS_ALLOW_IDMAP))
		return -EINVAL;

	/* Don't yet support filesystem mountable in user namespaces. */
	if (m->mnt_sb->s_user_ns != &init_user_ns)
		return -EINVAL;

	/* We're not controlling the superblock. */
	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	/* Mount has already been visible in the filesystem hierarchy. */
	if (!is_anon_ns(mnt->mnt_ns))
		return -EINVAL;

	return 0;
}


struct vfsmount *kern_mount(struct file_system_type *type)
{
	struct vfsmount *mnt;
	mnt = vfs_kern_mount(type, SB_KERNMOUNT, type->name, NULL);
	if (!IS_ERR(mnt)) {
		/*
		 * it is a longterm mount, don't release mnt until
		 * we unmount before file sys is unregistered
		*/
		real_mount(mnt)->mnt_ns = MNT_NS_INTERNAL;
	}
	return mnt;
}


struct dentry *mount_subtree(struct vfsmount *m, const char *name)
{
	struct mount *mnt = real_mount(m);
	struct mnt_namespace *ns;
	struct super_block *s;
	struct path path;
	int err;

	ns = alloc_mnt_ns(&init_user_ns, true);
	if (IS_ERR(ns)) {
		mntput(m);
		return ERR_CAST(ns);
	}
	mnt->mnt_ns = ns;
	ns->root = mnt;
	ns->mounts++;
	list_add(&mnt->mnt_list, &ns->list);

	err = vfs_path_lookup(m->mnt_root, m,
			name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &path);

	put_mnt_ns(ns);

	if (err)
		return ERR_PTR(err);

	/* trade a vfsmount reference for active sb one */
	s = path.mnt->mnt_sb;
	atomic_inc(&s->s_active);
	mntput(path.mnt);
	/* lock the sucker */
	down_write(&s->s_umount);
	/* ... and return the root of (sub)tree on it */
	return path.dentry;
}


void __mnt_drop_write_file(struct file *file)
{
	if (!(file->f_mode & FMODE_WRITER))
		__mnt_drop_write(file->f_path.mnt);
}


static void *m_next(struct seq_file *m, void *v, loff_t *pos)
{
	struct proc_mounts *p = m->private;
	struct mount *mnt = v;

	++*pos;
	return mnt_list_next(p->ns, &mnt->mnt_list);
}


static void *m_start(struct seq_file *m, loff_t *pos)
{
	struct proc_mounts *p = m->private;
	struct list_head *prev;

	down_read(&namespace_sem);
	if (!*pos) {
		prev = &p->ns->list;
	} else {
		prev = &p->cursor.mnt_list;

		/* Read after we'd reached the end? */
		if (list_empty(prev))
			return NULL;
	}

	return mnt_list_next(p->ns, prev);
}


struct vfsmount *vfs_kern_mount(struct file_system_type *type,
				int flags, const char *name,
				void *data)
{
	struct fs_context *fc;
	struct vfsmount *mnt;
	int ret = 0;

	if (!type)
		return ERR_PTR(-EINVAL);

	fc = fs_context_for_mount(type, flags);
	if (IS_ERR(fc))
		return ERR_CAST(fc);

	if (name)
		ret = vfs_parse_fs_string(fc, "source",
					  name, strlen(name));
	if (!ret)
		ret = parse_monolithic_mount_data(fc, data);
	if (!ret)
		mnt = fc_mount(fc);
	else
		mnt = ERR_PTR(ret);

	put_fs_context(fc);
	return mnt;
}


static void finish_mount_kattr(struct mount_kattr *kattr)
{
	put_user_ns(kattr->mnt_userns);
	kattr->mnt_userns = NULL;
}


int __mnt_want_write_file(struct file *file)
{
	if (file->f_mode & FMODE_WRITER) {
		/*
		 * Superblock may have become readonly while there are still
		 * writable fd's, e.g. due to a fs error with errors=remount-ro
		 */
		if (__mnt_is_readonly(file->f_path.mnt))
			return -EROFS;
		return 0;
	}
	return __mnt_want_write(file->f_path.mnt);
}


ns_client_logv(ns_client_t *client, isc_logcategory_t *category,
	       isc_logmodule_t *module, int level, const char *fmt,
	       va_list ap) {
	char msgbuf[4096];
	char signerbuf[DNS_NAME_FORMATSIZE], qnamebuf[DNS_NAME_FORMATSIZE];
	char peerbuf[ISC_SOCKADDR_FORMATSIZE];
	const char *viewname = "";
	const char *sep1 = "", *sep2 = "", *sep3 = "", *sep4 = "";
	const char *signer = "", *qname = "";
	dns_name_t *q = NULL;

	REQUIRE(client != NULL);

	vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);

	if (client->signer != NULL) {
		dns_name_format(client->signer, signerbuf, sizeof(signerbuf));
		sep1 = "/key ";
		signer = signerbuf;
	}

	q = client->query.origqname != NULL ? client->query.origqname
					    : client->query.qname;
	if (q != NULL) {
		dns_name_format(q, qnamebuf, sizeof(qnamebuf));
		sep2 = " (";
		sep3 = ")";
		qname = qnamebuf;
	}

	if (client->view != NULL && strcmp(client->view->name, "_bind") != 0 &&
	    strcmp(client->view->name, "_default") != 0)
	{
		sep4 = ": view ";
		viewname = client->view->name;
	}

	if (client->peeraddr_valid) {
		isc_sockaddr_format(&client->peeraddr, peerbuf,
				    sizeof(peerbuf));
	} else {
		snprintf(peerbuf, sizeof(peerbuf), "(no-peer)");
	}

	isc_log_write(ns_lctx, category, module, level,
		      "client @%p %s%s%s%s%s%s%s%s: %s", client, peerbuf, sep1,
		      signer, sep2, qname, sep3, sep4, viewname, msgbuf);
}


ns_client_sendraw(ns_client_t *client, dns_message_t *message) {
	isc_result_t result;
	unsigned char *data;
	isc_buffer_t buffer;
	isc_region_t r;
	isc_region_t *mr;

	REQUIRE(NS_CLIENT_VALID(client));

	CTRACE("sendraw");

	mr = dns_message_getrawmessage(message);
	if (mr == NULL) {
		result = ISC_R_UNEXPECTEDEND;
		goto done;
	}

	client_allocsendbuf(client, &buffer, &data);

	if (mr->length > isc_buffer_length(&buffer)) {
		result = ISC_R_NOSPACE;
		goto done;
	}

	/*
	 * Copy message to buffer and fixup id.
	 */
	isc_buffer_availableregion(&buffer, &r);
	result = isc_buffer_copyregion(&buffer, mr);
	if (result != ISC_R_SUCCESS) {
		goto done;
	}
	r.base[0] = (client->message->id >> 8) & 0xff;
	r.base[1] = client->message->id & 0xff;

#ifdef HAVE_DNSTAP
	if (client->view != NULL) {
		bool tcp = TCP_CLIENT(client);
		dns_dtmsgtype_t dtmsgtype;
		if (client->message->opcode == dns_opcode_update) {
			dtmsgtype = DNS_DTTYPE_UR;
		} else if ((client->message->flags & DNS_MESSAGEFLAG_RD) != 0) {
			dtmsgtype = DNS_DTTYPE_CR;
		} else {
			dtmsgtype = DNS_DTTYPE_AR;
		}
		dns_dt_send(client->view, dtmsgtype, &client->peeraddr,
			    &client->destsockaddr, tcp, NULL,
			    &client->requesttime, NULL, &buffer);
	}
#endif

	client_sendpkg(client, &buffer);

	return;
done:
	if (client->tcpbuf != NULL) {
		isc_mem_put(client->mctx, client->tcpbuf,
			    NS_CLIENT_TCP_BUFFER_SIZE);
		client->tcpbuf = NULL;
	}

	ns_client_drop(client, result);
}


ns_client_newnamebuf(ns_client_t *client) {
	isc_buffer_t *dbuf = NULL;

	CTRACE("ns_client_newnamebuf");

	isc_buffer_allocate(client->mctx, &dbuf, 1024);
	ISC_LIST_APPEND(client->query.namebufs, dbuf, link);

	CTRACE("ns_client_newnamebuf: done");
	return (ISC_R_SUCCESS);
}


ns__client_setup(ns_client_t *client, ns_clientmgr_t *mgr, bool new) {
	isc_result_t result;

	/*
	 * Caller must be holding the manager lock.
	 *
	 * Note: creating a client does not add the client to the
	 * manager's client list or set the client's manager pointer.
	 * The caller is responsible for that.
	 */

	REQUIRE(NS_CLIENT_VALID(client) || (new &&client != NULL));
	REQUIRE(VALID_MANAGER(mgr) || !new);

	if (new) {
		*client = (ns_client_t){ .magic = 0 };

		get_clientmctx(mgr, &client->mctx);
		clientmgr_attach(mgr, &client->manager);
		ns_server_attach(mgr->sctx, &client->sctx);
		get_clienttask(mgr, &client->task);

		dns_message_create(client->mctx, DNS_MESSAGE_INTENTPARSE,
				   &client->message);

		client->sendbuf = isc_mem_get(client->mctx,
					      NS_CLIENT_SEND_BUFFER_SIZE);
		/*
		 * Set magic earlier than usual because ns_query_init()
		 * and the functions it calls will require it.
		 */
		client->magic = NS_CLIENT_MAGIC;
		result = ns_query_init(client);
		if (result != ISC_R_SUCCESS) {
			goto cleanup;
		}
	} else {
		ns_clientmgr_t *oldmgr = client->manager;
		ns_server_t *sctx = client->sctx;
		isc_task_t *task = client->task;
		unsigned char *sendbuf = client->sendbuf;
		dns_message_t *message = client->message;
		isc_mem_t *oldmctx = client->mctx;
		ns_query_t query = client->query;

		/*
		 * Retain these values from the existing client, but
		 * zero every thing else.
		 */
		*client = (ns_client_t){ .magic = 0,
					 .mctx = oldmctx,
					 .manager = oldmgr,
					 .sctx = sctx,
					 .task = task,
					 .sendbuf = sendbuf,
					 .message = message,
					 .query = query };
	}

	client->query.attributes &= ~NS_QUERYATTR_ANSWERED;
	client->state = NS_CLIENTSTATE_INACTIVE;
	client->udpsize = 512;
	client->ednsversion = -1;
	dns_name_init(&client->signername, NULL);
	dns_ecs_init(&client->ecs);
	isc_sockaddr_any(&client->formerrcache.addr);
	client->formerrcache.time = 0;
	client->formerrcache.id = 0;
	ISC_LINK_INIT(client, rlink);
	client->rcode_override = -1; /* not set */

	client->magic = NS_CLIENT_MAGIC;

	CTRACE("client_setup");

	return (ISC_R_SUCCESS);

cleanup:
	if (client->sendbuf != NULL) {
		isc_mem_put(client->mctx, client->sendbuf,
			    NS_CLIENT_SEND_BUFFER_SIZE);
	}

	if (client->message != NULL) {
		dns_message_detach(&client->message);
	}

	if (client->task != NULL) {
		isc_task_detach(&client->task);
	}

	if (client->manager != NULL) {
		clientmgr_detach(&client->manager);
	}
	if (client->mctx != NULL) {
		isc_mem_detach(&client->mctx);
	}
	if (client->sctx != NULL) {
		ns_server_detach(&client->sctx);
	}

	return (result);
}


ns_client_findversion(ns_client_t *client, dns_db_t *db) {
	ns_dbversion_t *dbversion;

	for (dbversion = ISC_LIST_HEAD(client->query.activeversions);
	     dbversion != NULL; dbversion = ISC_LIST_NEXT(dbversion, link))
	{
		if (dbversion->db == db) {
			break;
		}
	}

	if (dbversion == NULL) {
		/*
		 * This is a new zone for this query.  Add it to
		 * the active list.
		 */
		dbversion = client_getdbversion(client);
		if (dbversion == NULL) {
			return (NULL);
		}
		dns_db_attach(db, &dbversion->db);
		dns_db_currentversion(db, &dbversion->version);
		dbversion->acl_checked = false;
		dbversion->queryok = false;
		ISC_LIST_APPEND(client->query.activeversions, dbversion, link);
	}

	return (dbversion);
}


process_cookie(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
	ns_altsecret_t *altsecret;
	unsigned char dbuf[COOKIE_SIZE];
	unsigned char *old;
	isc_stdtime_t now;
	uint32_t when;
	uint32_t nonce;
	isc_buffer_t db;

	/*
	 * If we have already seen a cookie option skip this cookie option.
	 */
	if ((!client->sctx->answercookie) ||
	    (client->attributes & NS_CLIENTATTR_WANTCOOKIE) != 0)
	{
		isc_buffer_forward(buf, (unsigned int)optlen);
		return;
	}

	client->attributes |= NS_CLIENTATTR_WANTCOOKIE;

	ns_stats_increment(client->sctx->nsstats, ns_statscounter_cookiein);

	if (optlen != COOKIE_SIZE) {
		/*
		 * Not our token.
		 */
		INSIST(optlen >= 8U);
		memmove(client->cookie, isc_buffer_current(buf), 8);
		isc_buffer_forward(buf, (unsigned int)optlen);

		if (optlen == 8U) {
			ns_stats_increment(client->sctx->nsstats,
					   ns_statscounter_cookienew);
		} else {
			ns_stats_increment(client->sctx->nsstats,
					   ns_statscounter_cookiebadsize);
		}
		return;
	}

	/*
	 * Process all of the incoming buffer.
	 */
	old = isc_buffer_current(buf);
	memmove(client->cookie, old, 8);
	isc_buffer_forward(buf, 8);
	nonce = isc_buffer_getuint32(buf);
	when = isc_buffer_getuint32(buf);
	isc_buffer_forward(buf, 8);

	/*
	 * Allow for a 5 minute clock skew between servers sharing a secret.
	 * Only accept COOKIE if we have talked to the client in the last hour.
	 */
	isc_stdtime_get(&now);
	if (isc_serial_gt(when, (now + 300)) || /* In the future. */
	    isc_serial_lt(when, (now - 3600)))
	{ /* In the past. */
		ns_stats_increment(client->sctx->nsstats,
				   ns_statscounter_cookiebadtime);
		return;
	}

	isc_buffer_init(&db, dbuf, sizeof(dbuf));
	compute_cookie(client, when, nonce, client->sctx->secret, &db);

	if (isc_safe_memequal(old, dbuf, COOKIE_SIZE)) {
		ns_stats_increment(client->sctx->nsstats,
				   ns_statscounter_cookiematch);
		client->attributes |= NS_CLIENTATTR_HAVECOOKIE;
		return;
	}

	for (altsecret = ISC_LIST_HEAD(client->sctx->altsecrets);
	     altsecret != NULL; altsecret = ISC_LIST_NEXT(altsecret, link))
	{
		isc_buffer_init(&db, dbuf, sizeof(dbuf));
		compute_cookie(client, when, nonce, altsecret->secret, &db);
		if (isc_safe_memequal(old, dbuf, COOKIE_SIZE)) {
			ns_stats_increment(client->sctx->nsstats,
					   ns_statscounter_cookiematch);
			client->attributes |= NS_CLIENTATTR_HAVECOOKIE;
			return;
		}
	}

	ns_stats_increment(client->sctx->nsstats,
			   ns_statscounter_cookienomatch);
}


ns_client_dropport(in_port_t port) {
	switch (port) {
	case 7:	 /* echo */
	case 13: /* daytime */
	case 19: /* chargen */
	case 37: /* time */
		return (DROPPORT_REQUEST);
	case 464: /* kpasswd */
		return (DROPPORT_RESPONSE);
	}
	return (DROPPORT_NO);
}


static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb,
			      int type, struct sockaddr_qrtr *from,
			      struct sockaddr_qrtr *to)
{
	struct qrtr_sock *ipc;
	struct qrtr_cb *cb;

	ipc = qrtr_port_lookup(to->sq_port);
	if (!ipc || &ipc->sk == skb->sk) { /* do not send to self */
		if (ipc)
			qrtr_port_put(ipc);
		kfree_skb(skb);
		return -ENODEV;
	}

	cb = (struct qrtr_cb *)skb->cb;
	cb->src_node = from->sq_node;
	cb->src_port = from->sq_port;

	if (sock_queue_rcv_skb(&ipc->sk, skb)) {
		qrtr_port_put(ipc);
		kfree_skb(skb);
		return -ENOSPC;
	}

	qrtr_port_put(ipc);

	return 0;
}


PublicMarshalAndComputeName(
			    TPMT_PUBLIC     *publicArea,    // IN: public area of an object
			    TPM2B_NAME      *name           // OUT: name of the object
			    )
{
    // Will marshal a public area into a template. This is because the internal
    // format for a TPM2B_PUBLIC is a structure and not a simple BYTE buffer.
    TPM2B_TEMPLATE       marshaled;     // this is big enough to hold a
    //  marshaled TPMT_PUBLIC
    BYTE                *buffer = (BYTE *)&marshaled.t.buffer;
    // if the nameAlg is NULL then there is no name.
    if(publicArea->nameAlg == TPM_ALG_NULL)
	name->t.size = 0;
    else
	{
	    // Marshal the public area into its canonical form
	    marshaled.t.size = TPMT_PUBLIC_Marshal(publicArea, &buffer, NULL);
	    // and compute the name
	    ObjectComputeName(marshaled.t.size, marshaled.t.buffer,
			      publicArea->nameAlg, name);
	}
    return name;
}


ObjectCreateHashSequence(
			 TPMI_ALG_HASH    hashAlg,       // IN: hash algorithm
			 TPM2B_AUTH      *auth,          // IN: authValue
			 TPMI_DH_OBJECT  *newHandle      // OUT: sequence object handle
			 )
{
    HASH_OBJECT         *hashObject = AllocateSequenceSlot(newHandle, auth);
    // See if slot allocated
    if(hashObject == NULL)
	return TPM_RC_OBJECT_MEMORY;
    // Set hash sequence bit
    hashObject->attributes.hashSeq = SET;
    // Start hash for hash sequence
    CryptHashStart(&hashObject->state.hashState[0], hashAlg);
    return TPM_RC_SUCCESS;
}