uuid_hash(const void *x, size_t table_size)
{
  const md_uuid *a = x;

  size_t h = a->uuid[0];
  for (size_t i = 1; i < 4; i++) {
    h ^= a->uuid[i];
  }

  return h % table_size;
}

static void compile_regexps (void) __attribute__((constructor));

static void free_regexps (void) __attribute__((destructor));

static void check_architecture (guestfs_h *g, struct inspect_fs *fs);

static int add_fstab_entry (guestfs_h *g, struct inspect_fs *fs,
                            const char *mountable, const char *mp);

static char *resolve_fstab_device (guestfs_h *g, const char *spec,
                                   Hash_table *md_map);

static int inspect_with_augeas (guestfs_h *g, struct inspect_fs *fs, const char **configfiles, int (*f) (guestfs_h *, struct inspect_fs *));

static int is_partition (guestfs_h *g, const char *partition);

typedef struct md_uuid {
  uint32_t uuid[4];
  char *path;
} md_uuid;

static size_t uuid_hash(const void *x, size_t table_size);

static bool uuid_cmp(const void *x, const void *y);

static void md_uuid_free(void *x);

static int parse_uuid(const char *str, uint32_t *uuid);

static size_t mdadm_app_hash(const void *x, size_t table_size);

static bool mdadm_app_cmp(const void *x, const void *y);

static void mdadm_app_free(void *x);


is_partition (guestfs_h *g, const char *partition)
{
  CLEANUP_FREE char *device = NULL;

  guestfs_push_error_handler (g, NULL, NULL);

  if ((device = guestfs_part_to_dev (g, partition)) == NULL) {
    guestfs_pop_error_handler (g);
    return 0;
  }

  if (guestfs_device_index (g, device) == -1) {
    guestfs_pop_error_handler (g);
    return 0;
  }

  guestfs_pop_error_handler (g);

  return 1;
}

inspection: Don't segfault if /etc/SuSE-release is an empty file.

Related to CVE-2013-2124.

Thanks: Olaf Hering.

static void check_architecture (guestfs_h *g, struct inspect_fs *fs);

static int check_hostname_unix (guestfs_h *g, struct inspect_fs *fs);

static int check_hostname_redhat (guestfs_h *g, struct inspect_fs *fs);

static int check_hostname_freebsd (guestfs_h *g, struct inspect_fs *fs);

static int check_fstab (guestfs_h *g, struct inspect_fs *fs);

static int add_fstab_entry (guestfs_h *g, struct inspect_fs *fs,
                            const char *mountable, const char *mp);

static char *resolve_fstab_device (guestfs_h *g, const char *spec,
                                   Hash_table *md_map);

static int inspect_with_augeas (guestfs_h *g, struct inspect_fs *fs, const char **configfiles, int (*f) (guestfs_h *, struct inspect_fs *));

static int is_partition (guestfs_h *g, const char *partition);

typedef struct md_uuid {
  uint32_t uuid[4];
  char *path;
} md_uuid;

static size_t uuid_hash(const void *x, size_t table_size);

static bool uuid_cmp(const void *x, const void *y);

static int parse_uuid(const char *str, uint32_t *uuid);

typedef struct {
  char *mdadm;
  char *app;
} mdadm_app;

static size_t mdadm_app_hash(const void *x, size_t table_size);

static bool mdadm_app_cmp(const void *x, const void *y);

static ssize_t map_app_md_devices (guestfs_h *g, Hash_table **map);

static int map_md_devices(guestfs_h *g, Hash_table **map);


check_hostname_freebsd (guestfs_h *g, struct inspect_fs *fs)
{
  const char *filename = "/etc/rc.conf";
  int64_t size;
  CLEANUP_FREE_STRING_LIST char **lines = NULL;
  size_t i;

  /* Don't trust guestfs_read_lines not to break with very large files.
   * Check the file size is something reasonable first.
   */
  size = guestfs_filesize (g, filename);
  if (size == -1)
    /* guestfs_filesize failed and has already set error in handle */
    return -1;
  if (size > MAX_SMALL_FILE_SIZE) {
    error (g, _("size of %s is unreasonably large (%" PRIi64 " bytes)"),
           filename, size);
    return -1;
  }

  lines = guestfs_read_lines (g, filename);
  if (lines == NULL)
    return -1;

  for (i = 0; lines[i] != NULL; ++i) {
    if (STRPREFIX (lines[i], "hostname=\"") ||
        STRPREFIX (lines[i], "hostname='")) {
      size_t len = strlen (lines[i]) - 10 - 1;
      fs->hostname = safe_strndup (g, &lines[i][10], len);
      break;
    } else if (STRPREFIX (lines[i], "hostname=")) {
      size_t len = strlen (lines[i]) - 9;
      fs->hostname = safe_strndup (g, &lines[i][9], len);
      break;
    }
  }

  return 0;
}


check_hostname_unix (guestfs_h *g, struct inspect_fs *fs)
{
  switch (fs->type) {
  case OS_TYPE_LINUX:
  case OS_TYPE_HURD:
    /* Red Hat-derived would be in /etc/sysconfig/network or
     * /etc/hostname (RHEL 7+, F18+).  Debian-derived in the file
     * /etc/hostname.  Very old Debian and SUSE use /etc/HOSTNAME.
     * It's best to just look for each of these files in turn, rather
     * than try anything clever based on distro.
     */
    if (guestfs_is_file (g, "/etc/HOSTNAME")) {
      fs->hostname = guestfs___first_line_of_file (g, "/etc/HOSTNAME");
      if (fs->hostname == NULL)
        return -1;
      if (STREQ (fs->hostname, "")) {
        free (fs->hostname);
        fs->hostname = NULL;
      }
    }

    if (!fs->hostname && guestfs_is_file (g, "/etc/hostname")) {
      fs->hostname = guestfs___first_line_of_file (g, "/etc/hostname");
      if (fs->hostname == NULL)
        return -1;
      if (STREQ (fs->hostname, "")) {
        free (fs->hostname);
        fs->hostname = NULL;
      }
    }

    if (!fs->hostname && guestfs_is_file (g, "/etc/sysconfig/network")) {
      const char *configfiles[] = { "/etc/sysconfig/network", NULL };
      if (inspect_with_augeas (g, fs, configfiles,
                               check_hostname_redhat) == -1)
        return -1;
    }
    break;

  case OS_TYPE_FREEBSD:
  case OS_TYPE_NETBSD:
    /* /etc/rc.conf contains the hostname, but there is no Augeas lens
     * for this file.
     */
    if (guestfs_is_file (g, "/etc/rc.conf")) {
      if (check_hostname_freebsd (g, fs) == -1)
        return -1;
    }
    break;

  case OS_TYPE_WINDOWS: /* not here, see check_windows_system_registry */
  case OS_TYPE_DOS:
  case OS_TYPE_OPENBSD:
  case OS_TYPE_UNKNOWN:
    /* nothing */;
  }

  return 0;
}


parse_uuid (const char *str, uint32_t *uuid)
{
  size_t hit = 0; /* number of Hex digIT */
  char c;
  size_t i;
  int n;

  for (i = 0; i < 4; i++)
    uuid[i] = 0;

  while ((c = *str++)) {
    if (c >= '0' && c <= '9')
      n = c - '0';
    else if (c >= 'a' && c <= 'f')
      n = 10 + c - 'a';
    else if (c >= 'A' && c <= 'F')
      n = 10 + c - 'A';
    else if (strchr (":. -", c))
      continue;
    else
      return -1;

    if (hit < 32) {
      uuid[hit / 8] <<= 4;
      uuid[hit / 8] += n;
    }
    hit++;
  }
  if (hit == 32) return 0;

  return -1;
}

static int check_hostname_unix (guestfs_h *g, struct inspect_fs *fs);

static int check_hostname_redhat (guestfs_h *g, struct inspect_fs *fs);

static int check_hostname_freebsd (guestfs_h *g, struct inspect_fs *fs);

static int check_fstab (guestfs_h *g, struct inspect_fs *fs);

static int add_fstab_entry (guestfs_h *g, struct inspect_fs *fs,
                            const char *mountable, const char *mp);

static char *resolve_fstab_device (guestfs_h *g, const char *spec,
                                   Hash_table *md_map);

static int inspect_with_augeas (guestfs_h *g, struct inspect_fs *fs, const char **configfiles, int (*f) (guestfs_h *, struct inspect_fs *));

static int is_partition (guestfs_h *g, const char *partition);

typedef struct md_uuid {
  uint32_t uuid[4];
  char *path;
} md_uuid;

static size_t uuid_hash(const void *x, size_t table_size);

static bool uuid_cmp(const void *x, const void *y);

static int parse_uuid(const char *str, uint32_t *uuid);

typedef struct {
  char *mdadm;
  char *app;
} mdadm_app;

static size_t mdadm_app_hash(const void *x, size_t table_size);

static bool mdadm_app_cmp(const void *x, const void *y);

static int map_md_devices(guestfs_h *g, Hash_table **map);


guestfs___check_netbsd_root (guestfs_h *g, struct inspect_fs *fs)
{

  if (guestfs_exists (g, "/etc/release") > 0) {
    char *major, *minor;
    if (parse_release_file (g, fs, "/etc/release") == -1)
      return -1;

    if (match2 (g, fs->product_name, re_netbsd, &major, &minor)) {
      fs->type = OS_TYPE_NETBSD;
      fs->major_version = guestfs___parse_unsigned_int (g, major);
      free (major);
      if (fs->major_version == -1) {
        free (minor);
        return -1;
      }
      fs->minor_version = guestfs___parse_unsigned_int (g, minor);
      free (minor);
      if (fs->minor_version == -1)
        return -1;
    }
  } else {
    return -1;
  }

  /* Determine the architecture. */
  check_architecture (g, fs);

  /* We already know /etc/fstab exists because it's part of the test above. */
  const char *configfiles[] = { "/etc/fstab", NULL };
  if (inspect_with_augeas (g, fs, configfiles, check_fstab) == -1)
    return -1;

  /* Determine hostname. */
  if (check_hostname_unix (g, fs) == -1)
    return -1;

  return 0;
}

static pcre *re_netbsd;

static void check_architecture (guestfs_h *g, struct inspect_fs *fs);

static int check_hostname_unix (guestfs_h *g, struct inspect_fs *fs);

static int check_hostname_redhat (guestfs_h *g, struct inspect_fs *fs);

static int check_hostname_freebsd (guestfs_h *g, struct inspect_fs *fs);

static int check_fstab (guestfs_h *g, struct inspect_fs *fs);

static int add_fstab_entry (guestfs_h *g, struct inspect_fs *fs,
                            const char *mountable, const char *mp);

static char *resolve_fstab_device (guestfs_h *g, const char *spec,
                                   Hash_table *md_map);

static int inspect_with_augeas (guestfs_h *g, struct inspect_fs *fs, const char **configfiles, int (*f) (guestfs_h *, struct inspect_fs *));

static int is_partition (guestfs_h *g, const char *partition);

typedef struct md_uuid {
  uint32_t uuid[4];
  char *path;
} md_uuid;

static size_t uuid_hash(const void *x, size_t table_size);

static bool uuid_cmp(const void *x, const void *y);

static int parse_uuid(const char *str, uint32_t *uuid);

typedef struct {
  char *mdadm;
  char *app;
} mdadm_app;

static size_t mdadm_app_hash(const void *x, size_t table_size);

static bool mdadm_app_cmp(const void *x, const void *y);

static ssize_t map_app_md_devices (guestfs_h *g, Hash_table **map);

static int map_md_devices(guestfs_h *g, Hash_table **map);


check_architecture (guestfs_h *g, struct inspect_fs *fs)
{
  const char *binaries[] =
    { "/bin/bash", "/bin/ls", "/bin/echo", "/bin/rm", "/bin/sh" };
  size_t i;
  char *arch;

  for (i = 0; i < sizeof binaries / sizeof binaries[0]; ++i) {
    if (guestfs_is_file (g, binaries[i]) > 0) {
      /* Ignore errors from file_architecture call. */
      guestfs_push_error_handler (g, NULL, NULL);
      arch = guestfs_file_architecture (g, binaries[i]);
      guestfs_pop_error_handler (g);

      if (arch) {
        /* String will be owned by handle, freed by
         * guestfs___free_inspect_info.
         */
        fs->arch = arch;
        break;
      }
    }
  }
}


add_fstab_entry (guestfs_h *g, struct inspect_fs *fs,
                 const char *mountable, const char *mountpoint)
{
  /* Add this to the fstab entry in 'fs'.
   * Note these are further filtered by guestfs_inspect_get_mountpoints
   * and guestfs_inspect_get_filesystems.
   */
  size_t n = fs->nr_fstab + 1;
  struct inspect_fstab_entry *p;

  p = realloc (fs->fstab, n * sizeof (struct inspect_fstab_entry));
  if (p == NULL) {
    perrorf (g, "realloc");
    return -1;
  }

  fs->fstab = p;
  fs->nr_fstab = n;

  /* These are owned by the handle and freed by guestfs___free_inspect_info. */
  fs->fstab[n-1].mountable = safe_strdup (g, mountable);
  fs->fstab[n-1].mountpoint = safe_strdup (g, mountpoint);

  debug (g, "fstab: mountable=%s mountpoint=%s", mountable, mountpoint);

  return 0;
}


mdadm_app_hash(const void *x, size_t table_size)
{
  const mdadm_app *a = x;
  return hash_pjw(a->mdadm, table_size);
}

static void compile_regexps (void) __attribute__((constructor));

static void free_regexps (void) __attribute__((destructor));

static void check_architecture (guestfs_h *g, struct inspect_fs *fs);

static int add_fstab_entry (guestfs_h *g, struct inspect_fs *fs,
                            const char *mountable, const char *mp);

static char *resolve_fstab_device (guestfs_h *g, const char *spec,
                                   Hash_table *md_map);

static int inspect_with_augeas (guestfs_h *g, struct inspect_fs *fs, const char **configfiles, int (*f) (guestfs_h *, struct inspect_fs *));

static int is_partition (guestfs_h *g, const char *partition);

static size_t uuid_hash(const void *x, size_t table_size);

static bool uuid_cmp(const void *x, const void *y);

static void md_uuid_free(void *x);

static int parse_uuid(const char *str, uint32_t *uuid);

typedef struct {
  char *mdadm;
  char *app;
} mdadm_app;

static size_t mdadm_app_hash(const void *x, size_t table_size);

static bool mdadm_app_cmp(const void *x, const void *y);

static void mdadm_app_free(void *x);


map_md_devices(guestfs_h *g, Hash_table **map)
{
  CLEANUP_HASH_FREE Hash_table *app_map = NULL;
  CLEANUP_FREE_STRING_LIST char **matches = NULL;
  ssize_t n_app_md_devices;

  *map = NULL;

  /* Get a map of md device uuids to their device names in the appliance */
  n_app_md_devices = map_app_md_devices (g, &app_map);
  if (n_app_md_devices == -1) goto error;

  /* Nothing to do if there are no md devices */
  if (n_app_md_devices == 0)
    return 0;

  /* Get all arrays listed in mdadm.conf */
  matches = guestfs_aug_match(g, "/files/etc/mdadm.conf/array");
  if (!matches) goto error;

  /* Log a debug message if we've got md devices, but nothing in mdadm.conf */
  if (matches[0] == NULL) {
    debug(g, "Appliance has MD devices, but augeas returned no array matches "
             "in mdadm.conf");
    return 0;
  }

  *map = hash_initialize(16, NULL, mdadm_app_hash, mdadm_app_cmp,
                                   mdadm_app_free);
  if (!*map) g->abort_cb();

  for (char **m = matches; *m != NULL; m++) {
    /* Get device name and uuid for each array */
    CLEANUP_FREE char *dev_path = safe_asprintf (g, "%s/devicename", *m);
    char *dev = guestfs_aug_get (g, dev_path);
    if (!dev) goto error;

    CLEANUP_FREE char *uuid_path = safe_asprintf (g, "%s/uuid", *m);
    CLEANUP_FREE char *uuid = guestfs_aug_get (g, uuid_path);
    if (!uuid) {
      free (dev);
      continue;
    }

    /* Parse the uuid into an md_uuid structure so we can look it up in the
     * uuid->appliance device map */
    md_uuid mdadm;
    mdadm.path = dev;
    if (parse_uuid(uuid, mdadm.uuid) == -1) {
      /* Invalid uuid. Weird, but not fatal. */
      debug(g, "inspect-os: mdadm.conf contains invalid uuid for %s: %s",
            dev, uuid);
      free (dev);
      continue;
    }

    /* If there's a corresponding uuid in the appliance, create a new
     * entry in the transitive map */
    md_uuid *app = hash_lookup(app_map, &mdadm);
    if (app) {
      mdadm_app *entry = safe_malloc(g, sizeof(mdadm_app));
      entry->mdadm = dev;
      entry->app = safe_strdup(g, app->path);

      switch (hash_insert_if_absent(*map, entry, NULL)) {
        case -1:
          g->abort_cb();

        case 0:
          /* Duplicate uuid in for md device is weird, but not fatal. */
          debug(g, "inspect-os: mdadm.conf contains multiple entries for %s",
                app->path);
          mdadm_app_free(entry);
          continue;
      }
    } else
      free (dev);
  }

  return 0;

error:
  if (*map) hash_free (*map);

  return -1;
}

static void check_architecture (guestfs_h *g, struct inspect_fs *fs);

static int check_hostname_unix (guestfs_h *g, struct inspect_fs *fs);

static int check_hostname_redhat (guestfs_h *g, struct inspect_fs *fs);

static int check_hostname_freebsd (guestfs_h *g, struct inspect_fs *fs);

static int check_fstab (guestfs_h *g, struct inspect_fs *fs);

static int add_fstab_entry (guestfs_h *g, struct inspect_fs *fs,
                            const char *mountable, const char *mp);

static char *resolve_fstab_device (guestfs_h *g, const char *spec,
                                   Hash_table *md_map);

static int inspect_with_augeas (guestfs_h *g, struct inspect_fs *fs, const char **configfiles, int (*f) (guestfs_h *, struct inspect_fs *));

static int is_partition (guestfs_h *g, const char *partition);

typedef struct md_uuid {
  uint32_t uuid[4];
  char *path;
} md_uuid;

static int parse_uuid(const char *str, uint32_t *uuid);

typedef struct {
  char *mdadm;
  char *app;
} mdadm_app;

static size_t mdadm_app_hash(const void *x, size_t table_size);

static bool mdadm_app_cmp(const void *x, const void *y);

static void mdadm_app_free(void *x);

static ssize_t map_app_md_devices (guestfs_h *g, Hash_table **map);

static int map_md_devices(guestfs_h *g, Hash_table **map);


md_uuid_free(void *x)
{
  md_uuid *a = x;
  free(a->path);
  free(a);
}

static void compile_regexps (void) __attribute__((constructor));

static void free_regexps (void) __attribute__((destructor));

static void check_architecture (guestfs_h *g, struct inspect_fs *fs);

typedef struct md_uuid {
  uint32_t uuid[4];
  char *path;
} md_uuid;

static size_t uuid_hash(const void *x, size_t table_size);

static bool uuid_cmp(const void *x, const void *y);

static void md_uuid_free(void *x);

static size_t mdadm_app_hash(const void *x, size_t table_size);

static bool mdadm_app_cmp(const void *x, const void *y);

static void mdadm_app_free(void *x);


parse_release_file (guestfs_h *g, struct inspect_fs *fs,
                    const char *release_filename)
{
  fs->product_name = guestfs___first_line_of_file (g, release_filename);
  if (fs->product_name == NULL)
    return -1;
  if (STREQ (fs->product_name, "")) {
    free (fs->product_name);
    fs->product_name = NULL;
    error (g, _("release file %s is empty or malformed"), release_filename);
    return -1;
  }
  return 0;
}


uuid_cmp(const void *x, const void *y)
{
  const md_uuid *a = x;
  const md_uuid *b = y;

  for (size_t i = 0; i < 1; i++) {
    if (a->uuid[i] != b->uuid[i]) return 0;
  }

  return 1;
}


guestfs___check_linux_root (guestfs_h *g, struct inspect_fs *fs)
{
  int r;

  fs->type = OS_TYPE_LINUX;

  if (guestfs_exists (g, "/etc/lsb-release") > 0) {
    r = parse_lsb_release (g, fs);
    if (r == -1)        /* error */
      return -1;
    if (r == 1)         /* ok - detected the release from this file */
      goto skip_release_checks;
  }

  if (guestfs_exists (g, "/etc/redhat-release") > 0) {
    fs->distro = OS_DISTRO_REDHAT_BASED; /* Something generic Red Hat-like. */

    if (parse_release_file (g, fs, "/etc/redhat-release") == -1)
      return -1;

    char *major, *minor;
    if ((major = match1 (g, fs->product_name, re_fedora)) != NULL) {
      fs->distro = OS_DISTRO_FEDORA;
      fs->major_version = guestfs___parse_unsigned_int (g, major);
      free (major);
      if (fs->major_version == -1)
        return -1;
    }
    else if (match2 (g, fs->product_name, re_rhel_old, &major, &minor) ||
             match2 (g, fs->product_name, re_rhel, &major, &minor)) {
      fs->distro = OS_DISTRO_RHEL;
      fs->major_version = guestfs___parse_unsigned_int (g, major);
      free (major);
      if (fs->major_version == -1) {
        free (minor);
        return -1;
      }
      fs->minor_version = guestfs___parse_unsigned_int (g, minor);
      free (minor);
      if (fs->minor_version == -1)
        return -1;
    }
    else if ((major = match1 (g, fs->product_name, re_rhel_no_minor)) != NULL) {
      fs->distro = OS_DISTRO_RHEL;
      fs->major_version = guestfs___parse_unsigned_int (g, major);
      free (major);
      if (fs->major_version == -1)
        return -1;
      fs->minor_version = 0;
    }
    else if (match2 (g, fs->product_name, re_centos_old, &major, &minor) ||
             match2 (g, fs->product_name, re_centos, &major, &minor)) {
      fs->distro = OS_DISTRO_CENTOS;
      fs->major_version = guestfs___parse_unsigned_int (g, major);
      free (major);
      if (fs->major_version == -1) {
        free (minor);
        return -1;
      }
      fs->minor_version = guestfs___parse_unsigned_int (g, minor);
      free (minor);
      if (fs->minor_version == -1)
        return -1;
    }
    else if ((major = match1 (g, fs->product_name, re_centos_no_minor)) != NULL) {
      fs->distro = OS_DISTRO_CENTOS;
      fs->major_version = guestfs___parse_unsigned_int (g, major);
      free (major);
      if (fs->major_version == -1)
        return -1;
      fs->minor_version = 0;
    }
    else if (match2 (g, fs->product_name, re_scientific_linux_old, &major, &minor) ||
             match2 (g, fs->product_name, re_scientific_linux, &major, &minor)) {
      fs->distro = OS_DISTRO_SCIENTIFIC_LINUX;
      fs->major_version = guestfs___parse_unsigned_int (g, major);
      free (major);
      if (fs->major_version == -1) {
        free (minor);
        return -1;
      }
      fs->minor_version = guestfs___parse_unsigned_int (g, minor);
      free (minor);
      if (fs->minor_version == -1)
        return -1;
    }
    else if ((major = match1 (g, fs->product_name, re_scientific_linux_no_minor)) != NULL) {
      fs->distro = OS_DISTRO_SCIENTIFIC_LINUX;
      fs->major_version = guestfs___parse_unsigned_int (g, major);
      free (major);
      if (fs->major_version == -1)
        return -1;
      fs->minor_version = 0;
    }
  }
  else if (guestfs_exists (g, "/etc/debian_version") > 0) {
    fs->distro = OS_DISTRO_DEBIAN;

    if (parse_release_file (g, fs, "/etc/debian_version") == -1)
      return -1;

    if (guestfs___parse_major_minor (g, fs) == -1)
      return -1;
  }
  else if (guestfs_exists (g, "/etc/pardus-release") > 0) {
    fs->distro = OS_DISTRO_PARDUS;

    if (parse_release_file (g, fs, "/etc/pardus-release") == -1)
      return -1;

    if (guestfs___parse_major_minor (g, fs) == -1)
      return -1;
  }
  else if (guestfs_exists (g, "/etc/arch-release") > 0) {
    fs->distro = OS_DISTRO_ARCHLINUX;

    /* /etc/arch-release file is empty and I can't see a way to
     * determine the actual release or product string.
     */
  }
  else if (guestfs_exists (g, "/etc/gentoo-release") > 0) {
    fs->distro = OS_DISTRO_GENTOO;

    if (parse_release_file (g, fs, "/etc/gentoo-release") == -1)
      return -1;

    if (guestfs___parse_major_minor (g, fs) == -1)
      return -1;
  }
  else if (guestfs_exists (g, "/etc/meego-release") > 0) {
    fs->distro = OS_DISTRO_MEEGO;

    if (parse_release_file (g, fs, "/etc/meego-release") == -1)
      return -1;

    if (guestfs___parse_major_minor (g, fs) == -1)
      return -1;
  }
  else if (guestfs_exists (g, "/etc/slackware-version") > 0) {
    fs->distro = OS_DISTRO_SLACKWARE;

    if (parse_release_file (g, fs, "/etc/slackware-version") == -1)
      return -1;

    if (guestfs___parse_major_minor (g, fs) == -1)
      return -1;
  }
  else if (guestfs_exists (g, "/etc/ttylinux-target") > 0) {
    fs->distro = OS_DISTRO_TTYLINUX;

    if (parse_release_file (g, fs, "/etc/ttylinux-target") == -1)
      return -1;

    if (guestfs___parse_major_minor (g, fs) == -1)
      return -1;
  }
  else if (guestfs_exists (g, "/etc/SuSE-release") > 0) {
    fs->distro = OS_DISTRO_SUSE_BASED;

    if (parse_suse_release (g, fs, "/etc/SuSE-release") == -1)
      return -1;

  }
  /* Buildroot (http://buildroot.net) is an embedded Linux distro
   * toolkit.  It is used by specific distros such as Cirros.
   */
  else if (guestfs_exists (g, "/etc/br-version") > 0) {
    if (guestfs_exists (g, "/usr/share/cirros/logo") > 0)
      fs->distro = OS_DISTRO_CIRROS;
    else
      fs->distro = OS_DISTRO_BUILDROOT;

    /* /etc/br-version has the format YYYY.MM[-git/hg/svn release] */
    if (parse_release_file (g, fs, "/etc/br-version") == -1)
      return -1;

    if (guestfs___parse_major_minor (g, fs) == -1)
      return -1;
  }

 skip_release_checks:;

  /* Determine the architecture. */
  check_architecture (g, fs);

  /* We already know /etc/fstab exists because it's part of the test
   * for Linux root above.  We must now parse this file to determine
   * which filesystems are used by the operating system and how they
   * are mounted.
   */
  const char *configfiles[] = { "/etc/fstab", "/etc/mdadm.conf", NULL };
  if (inspect_with_augeas (g, fs, configfiles, check_fstab) == -1)
    return -1;

  /* Determine hostname. */
  if (check_hostname_unix (g, fs) == -1)
    return -1;

  return 0;
}

static pcre *re_fedora;

static pcre *re_rhel_old;

static pcre *re_rhel;

static pcre *re_rhel_no_minor;

static pcre *re_centos_old;

static pcre *re_centos;

static pcre *re_centos_no_minor;

static pcre *re_scientific_linux_old;

static pcre *re_scientific_linux;

static pcre *re_scientific_linux_no_minor;

static void check_architecture (guestfs_h *g, struct inspect_fs *fs);

static int check_hostname_unix (guestfs_h *g, struct inspect_fs *fs);

static int check_hostname_redhat (guestfs_h *g, struct inspect_fs *fs);

static int check_hostname_freebsd (guestfs_h *g, struct inspect_fs *fs);

static int check_fstab (guestfs_h *g, struct inspect_fs *fs);

static int add_fstab_entry (guestfs_h *g, struct inspect_fs *fs,
                            const char *mountable, const char *mp);

static char *resolve_fstab_device (guestfs_h *g, const char *spec,
                                   Hash_table *md_map);

static int inspect_with_augeas (guestfs_h *g, struct inspect_fs *fs, const char **configfiles, int (*f) (guestfs_h *, struct inspect_fs *));

static int is_partition (guestfs_h *g, const char *partition);

typedef struct md_uuid {
  uint32_t uuid[4];
  char *path;
} md_uuid;

static size_t uuid_hash(const void *x, size_t table_size);

static bool uuid_cmp(const void *x, const void *y);

static int parse_uuid(const char *str, uint32_t *uuid);

typedef struct {
  char *mdadm;
  char *app;
} mdadm_app;

static size_t mdadm_app_hash(const void *x, size_t table_size);

static bool mdadm_app_cmp(const void *x, const void *y);

static ssize_t map_app_md_devices (guestfs_h *g, Hash_table **map);

static int map_md_devices(guestfs_h *g, Hash_table **map);


guestfs___check_freebsd_root (guestfs_h *g, struct inspect_fs *fs)
{
  fs->type = OS_TYPE_FREEBSD;

  /* FreeBSD has no authoritative version file.  The version number is
   * in /etc/motd, which the system administrator might edit, but
   * we'll use that anyway.
   */

  if (guestfs_exists (g, "/etc/motd") > 0) {
    if (parse_release_file (g, fs, "/etc/motd") == -1)
      return -1;

    if (guestfs___parse_major_minor (g, fs) == -1)
      return -1;
  }

  /* Determine the architecture. */
  check_architecture (g, fs);

  /* We already know /etc/fstab exists because it's part of the test above. */
  const char *configfiles[] = { "/etc/fstab", NULL };
  if (inspect_with_augeas (g, fs, configfiles, check_fstab) == -1)
    return -1;

  /* Determine hostname. */
  if (check_hostname_unix (g, fs) == -1)
    return -1;

  return 0;
}


parse_lsb_release (guestfs_h *g, struct inspect_fs *fs)
{
  const char *filename = "/etc/lsb-release";
  int64_t size;
  CLEANUP_FREE_STRING_LIST char **lines = NULL;
  size_t i;
  int r = 0;

  /* Don't trust guestfs_head_n not to break with very large files.
   * Check the file size is something reasonable first.
   */
  size = guestfs_filesize (g, filename);
  if (size == -1)
    /* guestfs_filesize failed and has already set error in handle */
    return -1;
  if (size > MAX_SMALL_FILE_SIZE) {
    error (g, _("size of %s is unreasonably large (%" PRIi64 " bytes)"),
           filename, size);
    return -1;
  }

  lines = guestfs_head_n (g, 10, filename);
  if (lines == NULL)
    return -1;

  for (i = 0; lines[i] != NULL; ++i) {
    if (fs->distro == 0 &&
        STREQ (lines[i], "DISTRIB_ID=Ubuntu")) {
      fs->distro = OS_DISTRO_UBUNTU;
      r = 1;
    }
    else if (fs->distro == 0 &&
             STREQ (lines[i], "DISTRIB_ID=LinuxMint")) {
      fs->distro = OS_DISTRO_LINUX_MINT;
      r = 1;
    }
    else if (fs->distro == 0 &&
             STREQ (lines[i], "DISTRIB_ID=MandrivaLinux")) {
      fs->distro = OS_DISTRO_MANDRIVA;
      r = 1;
    }
    else if (fs->distro == 0 &&
             STREQ (lines[i], "DISTRIB_ID=\"Mageia\"")) {
      fs->distro = OS_DISTRO_MAGEIA;
      r = 1;
    }
    else if (STRPREFIX (lines[i], "DISTRIB_RELEASE=")) {
      char *major, *minor;
      if (match2 (g, &lines[i][16], re_major_minor, &major, &minor)) {
        fs->major_version = guestfs___parse_unsigned_int (g, major);
        free (major);
        if (fs->major_version == -1) {
          free (minor);
          return -1;
        }
        fs->minor_version = guestfs___parse_unsigned_int (g, minor);
        free (minor);
        if (fs->minor_version == -1)
          return -1;
      }
    }
    else if (fs->product_name == NULL &&
             (STRPREFIX (lines[i], "DISTRIB_DESCRIPTION=\"") ||
              STRPREFIX (lines[i], "DISTRIB_DESCRIPTION='"))) {
      size_t len = strlen (lines[i]) - 21 - 1;
      fs->product_name = safe_strndup (g, &lines[i][21], len);
      r = 1;
    }
    else if (fs->product_name == NULL &&
             STRPREFIX (lines[i], "DISTRIB_DESCRIPTION=")) {
      size_t len = strlen (lines[i]) - 20;
      fs->product_name = safe_strndup (g, &lines[i][20], len);
      r = 1;
    }
  }

  /* The unnecessary construct in the next line is required to
   * workaround -Wstrict-overflow warning in gcc 4.5.1.
   */
  return r ? 1 : 0;
}

static pcre *re_major_minor;

static void check_architecture (guestfs_h *g, struct inspect_fs *fs);

static int check_hostname_unix (guestfs_h *g, struct inspect_fs *fs);

static int check_hostname_redhat (guestfs_h *g, struct inspect_fs *fs);

static int check_hostname_freebsd (guestfs_h *g, struct inspect_fs *fs);

static int check_fstab (guestfs_h *g, struct inspect_fs *fs);

static int add_fstab_entry (guestfs_h *g, struct inspect_fs *fs,
                            const char *mountable, const char *mp);

static char *resolve_fstab_device (guestfs_h *g, const char *spec,
                                   Hash_table *md_map);

static int inspect_with_augeas (guestfs_h *g, struct inspect_fs *fs, const char **configfiles, int (*f) (guestfs_h *, struct inspect_fs *));

static int is_partition (guestfs_h *g, const char *partition);

typedef struct md_uuid {
  uint32_t uuid[4];
  char *path;
} md_uuid;

static size_t uuid_hash(const void *x, size_t table_size);

static bool uuid_cmp(const void *x, const void *y);

static int parse_uuid(const char *str, uint32_t *uuid);

typedef struct {
  char *mdadm;
  char *app;
} mdadm_app;

static size_t mdadm_app_hash(const void *x, size_t table_size);

static bool mdadm_app_cmp(const void *x, const void *y);

static ssize_t map_app_md_devices (guestfs_h *g, Hash_table **map);

static int map_md_devices(guestfs_h *g, Hash_table **map);


guestfs___check_hurd_root (guestfs_h *g, struct inspect_fs *fs)
{
  fs->type = OS_TYPE_HURD;

  if (guestfs_exists (g, "/etc/debian_version") > 0) {
    fs->distro = OS_DISTRO_DEBIAN;

    if (parse_release_file (g, fs, "/etc/debian_version") == -1)
      return -1;

    if (guestfs___parse_major_minor (g, fs) == -1)
      return -1;
  }

  /* Arch Hurd also exists, but inconveniently it doesn't have
   * the normal /etc/arch-release file.  XXX
   */

  /* Determine the architecture. */
  check_architecture (g, fs);

  /* XXX Check for /etc/fstab. */

  /* Determine hostname. */
  if (check_hostname_unix (g, fs) == -1)
    return -1;

  return 0;
}

static void check_architecture (guestfs_h *g, struct inspect_fs *fs);

static int check_hostname_unix (guestfs_h *g, struct inspect_fs *fs);

static int check_hostname_redhat (guestfs_h *g, struct inspect_fs *fs);

static int check_hostname_freebsd (guestfs_h *g, struct inspect_fs *fs);

static int check_fstab (guestfs_h *g, struct inspect_fs *fs);

static int add_fstab_entry (guestfs_h *g, struct inspect_fs *fs,
                            const char *mountable, const char *mp);

static char *resolve_fstab_device (guestfs_h *g, const char *spec,
                                   Hash_table *md_map);

static int inspect_with_augeas (guestfs_h *g, struct inspect_fs *fs, const char **configfiles, int (*f) (guestfs_h *, struct inspect_fs *));

static int is_partition (guestfs_h *g, const char *partition);

typedef struct md_uuid {
  uint32_t uuid[4];
  char *path;
} md_uuid;

typedef struct {
  char *mdadm;
  char *app;
} mdadm_app;

static ssize_t map_app_md_devices (guestfs_h *g, Hash_table **map);

static int map_md_devices(guestfs_h *g, Hash_table **map);


resolve_fstab_device_diskbyid (guestfs_h *g, const char *part,
                               char **device_ret)
{
  int nr_devices;
  char *device;

  /* For /dev/disk/by-id there is a limit to what we can do because
   * original SCSI ID information has likely been lost.  This
   * heuristic will only work for guests that have a single block
   * device.
   *
   * So the main task here is to make sure the assumptions above are
   * true.
   *
   * XXX Use hints from virt-p2v if available.
   * See also: https://bugzilla.redhat.com/show_bug.cgi?id=836573#c3
   */

  nr_devices = guestfs_nr_devices (g);
  if (nr_devices == -1)
    return -1;

  /* If #devices isn't 1, give up trying to translate this fstab entry. */
  if (nr_devices != 1)
    return 0;

  /* Make the partition name and check it exists. */
  device = safe_asprintf (g, "/dev/sda%s", part);
  if (!is_partition (g, device)) {
    free (device);
    return 0;
  }

  *device_ret = device;
  return 0;
}


resolve_fstab_device_cciss (guestfs_h *g, const char *disk, const char *part,
                            char **device_ret)
{
  char *device;
  CLEANUP_FREE_STRING_LIST char **devices = NULL;
  size_t i;
  struct drive *drv;

  /* disk: (cciss/c\d+d\d+)
   * part: (\d+)?
   */

  devices = guestfs_list_devices (g);
  if (devices == NULL)
    return -1;

  /* Check any hints we were passed for a non-heuristic mapping */
  ITER_DRIVES (g, i, drv) {
    if (drv->name && STREQ (drv->name, disk)) {
      if (part) {
        device = safe_asprintf (g, "%s%s", devices[i], part);
        if (!is_partition (g, device)) {
          free (device);
          return 0;
        }
        *device_ret = device;
      }
      else
        *device_ret = safe_strdup (g, devices[i]);
      break;
    }
  }

  /* We don't try to guess mappings for cciss devices */
  return 0;
}


void __cleanup_sighand(struct sighand_struct *sighand)
{
	if (refcount_dec_and_test(&sighand->count)) {
		signalfd_cleanup(sighand);
		/*
		 * sighand_cachep is SLAB_TYPESAFE_BY_RCU so we can free it
		 * without an RCU grace period, see __lock_task_sighand().
		 */
		kmem_cache_free(sighand_cachep, sighand);
	}
}

fork: fix copy_process(CLONE_PARENT) race with the exiting ->real_parent

current->group_leader->exit_signal may change during copy_process() if
current->real_parent exits.

Move the assignment inside tasklist_lock to avoid the race.

Signed-off-by: Eddy Wu <eddy_wu@trendmicro.com>
Acked-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

#define free_mm(mm)	(kmem_cache_free(mm_cachep, (mm)))

void __init

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


static void set_max_threads(unsigned int max_threads_suggested)
{
	u64 threads;
	unsigned long nr_pages = totalram_pages();

	/*
	 * The number of threads shall be limited such that the thread
	 * structures may only consume a small part of the available memory.
	 */
	if (fls64(nr_pages) + fls64(PAGE_SIZE) > 64)
		threads = MAX_THREADS;
	else
		threads = div64_u64((u64) nr_pages * (u64) PAGE_SIZE,
				    (u64) THREAD_SIZE * 8UL);

	if (threads > max_threads_suggested)
		threads = max_threads_suggested;

	max_threads = clamp_t(u64, threads, MIN_THREADS, MAX_THREADS);
}

#define MIN_THREADS 20

#define MAX_THREADS FUTEX_TID_MASK

unsigned long total_forks;

int nr_threads;

static int max_threads;

static const char * const resident_page_types[] = {
	NAMED_ARRAY_INDEX(MM_FILEPAGES),
	NAMED_ARRAY_INDEX(MM_ANONPAGES),
	NAMED_ARRAY_INDEX(MM_SWAPENTS),
	NAMED_ARRAY_INDEX(MM_SHMEMPAGES),
};

DEFINE_PER_CPU(unsigned long, process_counts) = 0;

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

void __init

int arch_task_struct_size

static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;

static __latent_entropy struct


SYSCALL_DEFINE2(clone3, struct clone_args __user *, uargs, size_t, size)
{
	int err;

	struct kernel_clone_args kargs;
	pid_t set_tid[MAX_PID_NS_LEVEL];

	kargs.set_tid = set_tid;

	err = copy_clone_args_from_user(&kargs, uargs, size);
	if (err)
		return err;

	if (!clone3_args_valid(&kargs))
		return -EINVAL;

	return kernel_clone(&kargs);
}

int nr_threads;

static int max_threads;

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

int arch_task_struct_size

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


static void check_mm(struct mm_struct *mm)
{
	int i;

	BUILD_BUG_ON_MSG(ARRAY_SIZE(resident_page_types) != NR_MM_COUNTERS,
			 "Please make sure 'struct resident_page_types[]' is updated as well");

	for (i = 0; i < NR_MM_COUNTERS; i++) {
		long x = atomic_long_read(&mm->rss_stat.count[i]);

		if (unlikely(x))
			pr_alert("BUG: Bad rss-counter state mm:%p type:%s val:%ld\n",
				 mm, resident_page_types[i], x);
	}

	if (mm_pgtables_bytes(mm))
		pr_alert("BUG: non-zero pgtables_bytes on freeing mm: %ld\n",
				mm_pgtables_bytes(mm));

#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !USE_SPLIT_PMD_PTLOCKS
	VM_BUG_ON_MM(mm->pmd_huge_pte, mm);
#endif
}

unsigned long total_forks;

int nr_threads;

static int max_threads;

static const char * const resident_page_types[] = {
	NAMED_ARRAY_INDEX(MM_FILEPAGES),
	NAMED_ARRAY_INDEX(MM_ANONPAGES),
	NAMED_ARRAY_INDEX(MM_SWAPENTS),
	NAMED_ARRAY_INDEX(MM_SHMEMPAGES),
};

DEFINE_PER_CPU(unsigned long, process_counts) = 0;

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

void __init

int arch_task_struct_size

static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


static int __init coredump_filter_setup(char *s)
{
	default_dump_filter =
		(simple_strtoul(s, NULL, 0) << MMF_DUMP_FILTER_SHIFT) &
		MMF_DUMP_FILTER_MASK;
	return 1;
}

int nr_threads;

static int max_threads;

static const char * const resident_page_types[] = {
	NAMED_ARRAY_INDEX(MM_FILEPAGES),
	NAMED_ARRAY_INDEX(MM_ANONPAGES),
	NAMED_ARRAY_INDEX(MM_SWAPENTS),
	NAMED_ARRAY_INDEX(MM_SHMEMPAGES),
};

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

void __init

int arch_task_struct_size

static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;

static __latent_entropy struct


SYSCALL_DEFINE0(fork)
{
#ifdef CONFIG_MMU
	struct kernel_clone_args args = {
		.exit_signal = SIGCHLD,
	};

	return kernel_clone(&args);
#else
	/* can not support in nommu mode */
	return -EINVAL;
#endif
}

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
{
	struct task_struct *tsk;
	unsigned long *stack;
	struct vm_struct *stack_vm_area __maybe_unused;
	int err;

	if (node == NUMA_NO_NODE)
		node = tsk_fork_get_node(orig);
	tsk = alloc_task_struct_node(node);
	if (!tsk)
		return NULL;

	stack = alloc_thread_stack_node(tsk, node);
	if (!stack)
		goto free_tsk;

	if (memcg_charge_kernel_stack(tsk))
		goto free_stack;

	stack_vm_area = task_stack_vm_area(tsk);

	err = arch_dup_task_struct(tsk, orig);

	/*
	 * arch_dup_task_struct() clobbers the stack-related fields.  Make
	 * sure they're properly initialized before using any stack-related
	 * functions again.
	 */
	tsk->stack = stack;
#ifdef CONFIG_VMAP_STACK
	tsk->stack_vm_area = stack_vm_area;
#endif
#ifdef CONFIG_THREAD_INFO_IN_TASK
	refcount_set(&tsk->stack_refcount, 1);
#endif

	if (err)
		goto free_stack;

	err = scs_prepare(tsk, node);
	if (err)
		goto free_stack;

#ifdef CONFIG_SECCOMP
	/*
	 * We must handle setting up seccomp filters once we're under
	 * the sighand lock in case orig has changed between now and
	 * then. Until then, filter must be NULL to avoid messing up
	 * the usage counts on the error path calling free_task.
	 */
	tsk->seccomp.filter = NULL;
#endif

	setup_thread_stack(tsk, orig);
	clear_user_return_notifier(tsk);
	clear_tsk_need_resched(tsk);
	set_task_stack_end_magic(tsk);

#ifdef CONFIG_STACKPROTECTOR
	tsk->stack_canary = get_random_canary();
#endif
	if (orig->cpus_ptr == &orig->cpus_mask)
		tsk->cpus_ptr = &tsk->cpus_mask;

	/*
	 * One for the user space visible state that goes away when reaped.
	 * One for the scheduler.
	 */
	refcount_set(&tsk->rcu_users, 2);
	/* One for the rcu users */
	refcount_set(&tsk->usage, 1);
#ifdef CONFIG_BLK_DEV_IO_TRACE
	tsk->btrace_seq = 0;
#endif
	tsk->splice_pipe = NULL;
	tsk->task_frag.page = NULL;
	tsk->wake_q.next = NULL;

	account_kernel_stack(tsk, 1);

	kcov_task_init(tsk);

#ifdef CONFIG_FAULT_INJECTION
	tsk->fail_nth = 0;
#endif

#ifdef CONFIG_BLK_CGROUP
	tsk->throttle_queue = NULL;
	tsk->use_memdelay = 0;
#endif

#ifdef CONFIG_MEMCG
	tsk->active_memcg = NULL;
#endif
	return tsk;

free_stack:
	free_thread_stack(tsk);
free_tsk:
	free_task_struct(tsk);
	return NULL;
}

unsigned long total_forks;

int nr_threads;

static int max_threads;

static const char * const resident_page_types[] = {
	NAMED_ARRAY_INDEX(MM_FILEPAGES),
	NAMED_ARRAY_INDEX(MM_ANONPAGES),
	NAMED_ARRAY_INDEX(MM_SWAPENTS),
	NAMED_ARRAY_INDEX(MM_SHMEMPAGES),
};

DEFINE_PER_CPU(unsigned long, process_counts) = 0;

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

int arch_task_struct_size

static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


static void __delayed_free_task(struct rcu_head *rhp)
{
	struct task_struct *tsk = container_of(rhp, struct task_struct, rcu);

	free_task(tsk);
}

static int max_threads;

static const char * const resident_page_types[] = {
	NAMED_ARRAY_INDEX(MM_FILEPAGES),
	NAMED_ARRAY_INDEX(MM_ANONPAGES),
	NAMED_ARRAY_INDEX(MM_SWAPENTS),
	NAMED_ARRAY_INDEX(MM_SHMEMPAGES),
};

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

void __init

static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


void __mmdrop(struct mm_struct *mm)
{
	BUG_ON(mm == &init_mm);
	WARN_ON_ONCE(mm == current->mm);
	WARN_ON_ONCE(mm == current->active_mm);
	mm_free_pgd(mm);
	destroy_context(mm);
	mmu_notifier_subscriptions_destroy(mm);
	check_mm(mm);
	put_user_ns(mm->user_ns);
	free_mm(mm);
}

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

#define mm_free_pgd(mm)

#define free_mm(mm)	(kmem_cache_free(mm_cachep, (mm)))

void __init

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


static bool clone3_args_valid(struct kernel_clone_args *kargs)
{
	/* Verify that no unknown flags are passed along. */
	if (kargs->flags &
	    ~(CLONE_LEGACY_FLAGS | CLONE_CLEAR_SIGHAND | CLONE_INTO_CGROUP))
		return false;

	/*
	 * - make the CLONE_DETACHED bit reuseable for clone3
	 * - make the CSIGNAL bits reuseable for clone3
	 */
	if (kargs->flags & (CLONE_DETACHED | CSIGNAL))
		return false;

	if ((kargs->flags & (CLONE_SIGHAND | CLONE_CLEAR_SIGHAND)) ==
	    (CLONE_SIGHAND | CLONE_CLEAR_SIGHAND))
		return false;

	if ((kargs->flags & (CLONE_THREAD | CLONE_PARENT)) &&
	    kargs->exit_signal)
		return false;

	if (!clone3_stack_valid(kargs))
		return false;

	return true;
}

static int max_threads;

static const char * const resident_page_types[] = {
	NAMED_ARRAY_INDEX(MM_FILEPAGES),
	NAMED_ARRAY_INDEX(MM_ANONPAGES),
	NAMED_ARRAY_INDEX(MM_SWAPENTS),
	NAMED_ARRAY_INDEX(MM_SHMEMPAGES),
};

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk)
{
	struct sighand_struct *sig;

	if (clone_flags & CLONE_SIGHAND) {
		refcount_inc(&current->sighand->count);
		return 0;
	}
	sig = kmem_cache_alloc(sighand_cachep, GFP_KERNEL);
	RCU_INIT_POINTER(tsk->sighand, sig);
	if (!sig)
		return -ENOMEM;

	refcount_set(&sig->count, 1);
	spin_lock_irq(&current->sighand->siglock);
	memcpy(sig->action, current->sighand->action, sizeof(sig->action));
	spin_unlock_irq(&current->sighand->siglock);

	/* Reset all signal handler not set to SIG_IGN to SIG_DFL. */
	if (clone_flags & CLONE_CLEAR_SIGHAND)
		flush_signal_handlers(tsk, 0);

	return 0;
}

unsigned long total_forks;

int nr_threads;

static int max_threads;

static const char * const resident_page_types[] = {
	NAMED_ARRAY_INDEX(MM_FILEPAGES),
	NAMED_ARRAY_INDEX(MM_ANONPAGES),
	NAMED_ARRAY_INDEX(MM_SWAPENTS),
	NAMED_ARRAY_INDEX(MM_SHMEMPAGES),
};

DEFINE_PER_CPU(unsigned long, process_counts) = 0;

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

#define allocate_mm()	(kmem_cache_alloc(mm_cachep, GFP_KERNEL))

int arch_task_struct_size

static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


static void copy_oom_score_adj(u64 clone_flags, struct task_struct *tsk)
{
	/* Skip if kernel thread */
	if (!tsk->mm)
		return;

	/* Skip if spawning a thread or using vfork */
	if ((clone_flags & (CLONE_VM | CLONE_THREAD | CLONE_VFORK)) != CLONE_VM)
		return;

	/* We need to synchronize with __set_oom_adj */
	mutex_lock(&oom_adj_mutex);
	set_bit(MMF_MULTIPROCESS, &tsk->mm->flags);
	/* Update the values in case they were changed after copy_signal */
	tsk->signal->oom_score_adj = current->signal->oom_score_adj;
	tsk->signal->oom_score_adj_min = current->signal->oom_score_adj_min;
	mutex_unlock(&oom_adj_mutex);
}


static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
{
	mmap_write_lock(oldmm);
	RCU_INIT_POINTER(mm->exe_file, get_mm_exe_file(oldmm));
	mmap_write_unlock(oldmm);
	return 0;
}

int nr_threads;

static int max_threads;

static const char * const resident_page_types[] = {
	NAMED_ARRAY_INDEX(MM_FILEPAGES),
	NAMED_ARRAY_INDEX(MM_ANONPAGES),
	NAMED_ARRAY_INDEX(MM_SWAPENTS),
	NAMED_ARRAY_INDEX(MM_SHMEMPAGES),
};

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

int arch_task_struct_size

static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


static void rt_mutex_init_task(struct task_struct *p)
{
	raw_spin_lock_init(&p->pi_lock);
#ifdef CONFIG_RT_MUTEXES
	p->pi_waiters = RB_ROOT_CACHED;
	p->pi_top_task = NULL;
	p->pi_blocked_on = NULL;
#endif
}


static void task_struct_whitelist(unsigned long *offset, unsigned long *size)
{
	/* Fetch thread_struct whitelist for the architecture. */
	arch_thread_struct_whitelist(offset, size);

	/*
	 * Handle zero-sized whitelist or empty thread_struct, otherwise
	 * adjust offset to position of thread_struct in task_struct.
	 */
	if (unlikely(*size == 0))
		*offset = 0;
	else
		*offset += offsetof(struct task_struct, thread);
}

unsigned long total_forks;

static int max_threads;

static const char * const resident_page_types[] = {
	NAMED_ARRAY_INDEX(MM_FILEPAGES),
	NAMED_ARRAY_INDEX(MM_ANONPAGES),
	NAMED_ARRAY_INDEX(MM_SWAPENTS),
	NAMED_ARRAY_INDEX(MM_SHMEMPAGES),
};

DEFINE_PER_CPU(unsigned long, process_counts) = 0;

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

void __init

static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
{
	struct fs_struct *fs = current->fs;

	if (!(unshare_flags & CLONE_FS) || !fs)
		return 0;

	/* don't need lock here; in the worst case we'll do useless copy */
	if (fs->users == 1)
		return 0;

	*new_fsp = copy_fs_struct(fs);
	if (!*new_fsp)
		return -ENOMEM;

	return 0;
}


static int free_vm_stack_cache(unsigned int cpu)
{
	struct vm_struct **cached_vm_stacks = per_cpu_ptr(cached_stacks, cpu);
	int i;

	for (i = 0; i < NR_CACHED_STACKS; i++) {
		struct vm_struct *vm_stack = cached_vm_stacks[i];

		if (!vm_stack)
			continue;

		vfree(vm_stack->addr);
		cached_vm_stacks[i] = NULL;
	}

	return 0;
}


SYSCALL_DEFINE1(set_tid_address, int __user *, tidptr)
{
	current->clear_child_tid = tidptr;

	return task_pid_vnr(current);
}

int nr_threads;

static int max_threads;

int arch_task_struct_size


int unshare_files(struct files_struct **displaced)
{
	struct task_struct *task = current;
	struct files_struct *copy = NULL;
	int error;

	error = unshare_fd(CLONE_FILES, NR_OPEN_MAX, &copy);
	if (error || !copy) {
		*displaced = NULL;
		return error;
	}
	*displaced = task->files;
	task_lock(task);
	task->files = copy;
	task_unlock(task);
	return 0;
}


void vm_area_free(struct vm_area_struct *vma)
{
	kmem_cache_free(vm_area_cachep, vma);
}


static unsigned long *alloc_thread_stack_node(struct task_struct *tsk,
						  int node)
{
	unsigned long *stack;
	stack = kmem_cache_alloc_node(thread_stack_cache, THREADINFO_GFP, node);
	stack = kasan_reset_tag(stack);
	tsk->stack = stack;
	return stack;
}


struct vm_area_struct *vm_area_dup(struct vm_area_struct *orig)
{
	struct vm_area_struct *new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);

	if (new) {
		ASSERT_EXCLUSIVE_WRITER(orig->vm_flags);
		ASSERT_EXCLUSIVE_WRITER(orig->vm_file);
		/*
		 * orig->shared.rb may be modified concurrently, but the clone
		 * will be reinitialized.
		 */
		*new = data_race(*orig);
		INIT_LIST_HEAD(&new->anon_vma_chain);
		new->vm_next = new->vm_prev = NULL;
	}
	return new;
}

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

#define allocate_mm()	(kmem_cache_alloc(mm_cachep, GFP_KERNEL))

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


static void mm_init_uprobes_state(struct mm_struct *mm)
{
#ifdef CONFIG_UPROBES
	mm->uprobes_state.xol_area = NULL;
#endif
}


SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
		 int __user *, parent_tidptr,
		 int __user *, child_tidptr,
		 unsigned long, tls)
#endif
{
	struct kernel_clone_args args = {
		.flags		= (lower_32_bits(clone_flags) & ~CSIGNAL),
		.pidfd		= parent_tidptr,
		.child_tid	= child_tidptr,
		.parent_tid	= parent_tidptr,
		.exit_signal	= (lower_32_bits(clone_flags) & CSIGNAL),
		.stack		= newsp,
		.tls		= tls,
	};

	return kernel_clone(&args);
}

unsigned long total_forks;

int nr_threads;

static int max_threads;

DEFINE_PER_CPU(unsigned long, process_counts) = 0;

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

int arch_task_struct_size

static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


void exec_mm_release(struct task_struct *tsk, struct mm_struct *mm)
{
	futex_exec_release(tsk);
	mm_release(tsk, mm);
}

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

void __init

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


static int check_unshare_flags(unsigned long unshare_flags)
{
	if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND|
				CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|
				CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWNET|
				CLONE_NEWUSER|CLONE_NEWPID|CLONE_NEWCGROUP|
				CLONE_NEWTIME))
		return -EINVAL;
	/*
	 * Not implemented, but pretend it works if there is nothing
	 * to unshare.  Note that unsharing the address space or the
	 * signal handlers also need to unshare the signal queues (aka
	 * CLONE_THREAD).
	 */
	if (unshare_flags & (CLONE_THREAD | CLONE_SIGHAND | CLONE_VM)) {
		if (!thread_group_empty(current))
			return -EINVAL;
	}
	if (unshare_flags & (CLONE_SIGHAND | CLONE_VM)) {
		if (refcount_read(&current->sighand->count) > 1)
			return -EINVAL;
	}
	if (unshare_flags & CLONE_VM) {
		if (!current_is_single_threaded())
			return -EINVAL;
	}

	return 0;
}

unsigned long total_forks;

int nr_threads;

static int max_threads;

static const char * const resident_page_types[] = {
	NAMED_ARRAY_INDEX(MM_FILEPAGES),
	NAMED_ARRAY_INDEX(MM_ANONPAGES),
	NAMED_ARRAY_INDEX(MM_SWAPENTS),
	NAMED_ARRAY_INDEX(MM_SHMEMPAGES),
};

DEFINE_PER_CPU(unsigned long, process_counts) = 0;

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

int arch_task_struct_size

static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;

static __latent_entropy struct


struct task_struct *fork_idle(int cpu)
{
	struct task_struct *task;
	struct kernel_clone_args args = {
		.flags = CLONE_VM,
	};

	task = copy_process(&init_struct_pid, 0, cpu_to_node(cpu), &args);
	if (!IS_ERR(task)) {
		init_idle_pids(task);
		init_idle(task, cpu);
	}

	return task;
}


static inline void free_signal_struct(struct signal_struct *sig)
{
	taskstats_tgid_free(sig);
	sched_autogroup_exit(sig);
	/*
	 * __mmdrop is not safe to call from softirq context on x86 due to
	 * pgd_dtor so postpone it to the async context
	 */
	if (sig->oom_mm)
		mmdrop_async(sig->oom_mm);
	kmem_cache_free(signal_cachep, sig);
}


static void free_thread_stack(struct task_struct *tsk)
{
	kmem_cache_free(thread_stack_cache, tsk->stack);
}


void mmput(struct mm_struct *mm)
{
	might_sleep();

	if (atomic_dec_and_test(&mm->mm_users))
		__mmput(mm);
}


void __init fork_init(void)
{
	int i;
#ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR
#ifndef ARCH_MIN_TASKALIGN
#define ARCH_MIN_TASKALIGN	0
#endif
	int align = max_t(int, L1_CACHE_BYTES, ARCH_MIN_TASKALIGN);
	unsigned long useroffset, usersize;

	/* create a slab on which task_structs can be allocated */
	task_struct_whitelist(&useroffset, &usersize);
	task_struct_cachep = kmem_cache_create_usercopy("task_struct",
			arch_task_struct_size, align,
			SLAB_PANIC|SLAB_ACCOUNT,
			useroffset, usersize, NULL);
#endif

	/* do the arch specific task caches init */
	arch_task_cache_init();

	set_max_threads(MAX_THREADS);

	init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2;
	init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2;
	init_task.signal->rlim[RLIMIT_SIGPENDING] =
		init_task.signal->rlim[RLIMIT_NPROC];

	for (i = 0; i < UCOUNT_COUNTS; i++) {
		init_user_ns.ucount_max[i] = max_threads/2;
	}

#ifdef CONFIG_VMAP_STACK
	cpuhp_setup_state(CPUHP_BP_PREPARE_DYN, "fork:vm_stack_cache",
			  NULL, free_vm_stack_cache);
#endif

	scs_init();

	lockdep_init_task(&init_task);
	uprobes_init();
}

#define CREATE_TRACE_POINTS

#define MIN_THREADS 20

#define MAX_THREADS FUTEX_TID_MASK

unsigned long total_forks;

int nr_threads;

static int max_threads;

#define NAMED_ARRAY_INDEX(x)	[x] = __stringify(x)

DEFINE_PER_CPU(unsigned long, process_counts) = 0;

static struct kmem_cache *task_struct_cachep;

#define NR_CACHED_STACKS 2

#define mm_alloc_pgd(mm)	(0)

#define mm_free_pgd(mm)

#define allocate_mm()	(kmem_cache_alloc(mm_cachep, GFP_KERNEL))

#define free_mm(mm)	(kmem_cache_free(mm_cachep, (mm)))

void __init

int arch_task_struct_size

static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

#define ARCH_MIN_MMSTRUCT_ALIGN 0


int nr_processes(void)
{
	int cpu;
	int total = 0;

	for_each_possible_cpu(cpu)
		total += per_cpu(process_counts, cpu);

	return total;
}

int nr_threads;

static int max_threads;

DEFINE_PER_CPU(unsigned long, process_counts) = 0;

void __init

int arch_task_struct_size


static inline void put_signal_struct(struct signal_struct *sig)
{
	if (refcount_dec_and_test(&sig->sigcnt))
		free_signal_struct(sig);
}


void __put_task_struct(struct task_struct *tsk)
{
	WARN_ON(!tsk->exit_state);
	WARN_ON(refcount_read(&tsk->usage));
	WARN_ON(tsk == current);

	io_uring_free(tsk);
	cgroup_free(tsk);
	task_numa_free(tsk, true);
	security_task_free(tsk);
	exit_creds(tsk);
	delayacct_tsk_free(tsk);
	put_signal_struct(tsk->signal);

	if (!profile_handoff_task(tsk))
		free_task(tsk);
}


static __poll_t pidfd_poll(struct file *file, struct poll_table_struct *pts)
{
	struct pid *pid = file->private_data;
	__poll_t poll_flags = 0;

	poll_wait(file, &pid->wait_pidfd, pts);

	/*
	 * Inform pollers only when the whole thread group exits.
	 * If the thread group leader exits before all other threads in the
	 * group, then poll(2) should block, similar to the wait(2) family.
	 */
	if (thread_group_exited(pid))
		poll_flags = EPOLLIN | EPOLLRDNORM;

	return poll_flags;
}


static void mm_init_aio(struct mm_struct *mm)
{
#ifdef CONFIG_AIO
	spin_lock_init(&mm->ioctx_lock);
	mm->ioctx_table = NULL;
#endif
}


static inline void init_task_pid_links(struct task_struct *task)
{
	enum pid_type type;

	for (type = PIDTYPE_PID; type < PIDTYPE_MAX; ++type) {
		INIT_HLIST_NODE(&task->pid_links[type]);
	}
}


static void mmdrop_async(struct mm_struct *mm)
{
	if (unlikely(atomic_dec_and_test(&mm->mm_count))) {
		INIT_WORK(&mm->async_put_work, mmdrop_async_fn);
		schedule_work(&mm->async_put_work);
	}
}


void walk_process_tree(struct task_struct *top, proc_visitor visitor, void *data)
{
	struct task_struct *leader, *parent, *child;
	int res;

	read_lock(&tasklist_lock);
	leader = top = top->group_leader;
down:
	for_each_thread(leader, parent) {
		list_for_each_entry(child, &parent->children, sibling) {
			res = visitor(child, data);
			if (res) {
				if (res < 0)
					goto out;
				leader = child;
				goto down;
			}
up:
			;
		}
	}

	if (leader != top) {
		child = leader;
		parent = child->real_parent;
		leader = parent->group_leader;
		goto up;
	}
out:
	read_unlock(&tasklist_lock);
}


struct vm_area_struct *vm_area_alloc(struct mm_struct *mm)
{
	struct vm_area_struct *vma;

	vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
	if (vma)
		vma_init(vma, mm);
	return vma;
}


struct mm_struct *get_task_mm(struct task_struct *task)
{
	struct mm_struct *mm;

	task_lock(task);
	mm = task->mm;
	if (mm) {
		if (task->flags & PF_KTHREAD)
			mm = NULL;
		else
			mmget(mm);
	}
	task_unlock(task);
	return mm;
}


static __always_inline void delayed_free_task(struct task_struct *tsk)
{
	if (IS_ENABLED(CONFIG_MEMCG))
		call_rcu(&tsk->rcu, __delayed_free_task);
	else
		free_task(tsk);
}


static inline void free_task_struct(struct task_struct *tsk)
{
	kmem_cache_free(task_struct_cachep, tsk);
}

static int max_threads;

static const char * const resident_page_types[] = {
	NAMED_ARRAY_INDEX(MM_FILEPAGES),
	NAMED_ARRAY_INDEX(MM_ANONPAGES),
	NAMED_ARRAY_INDEX(MM_SWAPENTS),
	NAMED_ARRAY_INDEX(MM_SHMEMPAGES),
};

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

#define free_mm(mm)	(kmem_cache_free(mm_cachep, (mm)))

void __init

static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
{
	return ksys_unshare(unshare_flags);
}

unsigned long total_forks;

DEFINE_PER_CPU(unsigned long, process_counts) = 0;

static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;


static void mm_release(struct task_struct *tsk, struct mm_struct *mm)
{
	uprobe_free_utask(tsk);

	/* Get rid of any cached register state */
	deactivate_mm(tsk, mm);

	/*
	 * Signal userspace if we're not exiting with a core dump
	 * because we want to leave the value intact for debugging
	 * purposes.
	 */
	if (tsk->clear_child_tid) {
		if (!(tsk->signal->flags & SIGNAL_GROUP_COREDUMP) &&
		    atomic_read(&mm->mm_users) > 1) {
			/*
			 * We don't check the error code - if userspace has
			 * not set up a proper pointer then tough luck.
			 */
			put_user(0, tsk->clear_child_tid);
			do_futex(tsk->clear_child_tid, FUTEX_WAKE,
					1, NULL, NULL, 0, 0);
		}
		tsk->clear_child_tid = NULL;
	}

	/*
	 * All done, finally we can wake up parent and return this mm to him.
	 * Also kthread_stop() uses this completion for synchronization.
	 */
	if (tsk->vfork_done)
		complete_vfork_done(tsk);
}


static int memcg_charge_kernel_stack(struct task_struct *tsk)
{
#ifdef CONFIG_VMAP_STACK
	struct vm_struct *vm = task_stack_vm_area(tsk);
	int ret;

	BUILD_BUG_ON(IS_ENABLED(CONFIG_VMAP_STACK) && PAGE_SIZE % 1024 != 0);

	if (vm) {
		int i;

		BUG_ON(vm->nr_pages != THREAD_SIZE / PAGE_SIZE);

		for (i = 0; i < THREAD_SIZE / PAGE_SIZE; i++) {
			/*
			 * If memcg_kmem_charge_page() fails, page->mem_cgroup
			 * pointer is NULL, and memcg_kmem_uncharge_page() in
			 * free_thread_stack() will ignore this page.
			 */
			ret = memcg_kmem_charge_page(vm->pages[i], GFP_KERNEL,
						     0);
			if (ret)
				return ret;
		}
	}
#endif
	return 0;
}

int nr_threads;

static int max_threads;

static const char * const resident_page_types[] = {
	NAMED_ARRAY_INDEX(MM_FILEPAGES),
	NAMED_ARRAY_INDEX(MM_ANONPAGES),
	NAMED_ARRAY_INDEX(MM_SWAPENTS),
	NAMED_ARRAY_INDEX(MM_SHMEMPAGES),
};

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

#define allocate_mm()	(kmem_cache_alloc(mm_cachep, GFP_KERNEL))

int arch_task_struct_size

static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


int sysctl_max_threads(struct ctl_table *table, int write,
		       void *buffer, size_t *lenp, loff_t *ppos)
{
	struct ctl_table t;
	int ret;
	int threads = max_threads;
	int min = 1;
	int max = MAX_THREADS;

	t = *table;
	t.data = &threads;
	t.extra1 = &min;
	t.extra2 = &max;

	ret = proc_dointvec_minmax(&t, write, buffer, lenp, ppos);
	if (ret || !write)
		return ret;

	max_threads = threads;

	return 0;
}

#define MAX_THREADS FUTEX_TID_MASK

int nr_threads;

static int max_threads;

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

void __init

int arch_task_struct_size

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)
{
	struct mm_struct *mm;
	int err;

	err =  mutex_lock_killable(&task->signal->exec_update_mutex);
	if (err)
		return ERR_PTR(err);

	mm = get_task_mm(task);
	if (mm && mm != current->mm &&
			!ptrace_may_access(task, mode)) {
		mmput(mm);
		mm = ERR_PTR(-EACCES);
	}
	mutex_unlock(&task->signal->exec_update_mutex);

	return mm;
}


static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p,
	struct user_namespace *user_ns)
{
	mm->mmap = NULL;
	mm->mm_rb = RB_ROOT;
	mm->vmacache_seqnum = 0;
	atomic_set(&mm->mm_users, 1);
	atomic_set(&mm->mm_count, 1);
	mmap_init_lock(mm);
	INIT_LIST_HEAD(&mm->mmlist);
	mm->core_state = NULL;
	mm_pgtables_bytes_init(mm);
	mm->map_count = 0;
	mm->locked_vm = 0;
	atomic_set(&mm->has_pinned, 0);
	atomic64_set(&mm->pinned_vm, 0);
	memset(&mm->rss_stat, 0, sizeof(mm->rss_stat));
	spin_lock_init(&mm->page_table_lock);
	spin_lock_init(&mm->arg_lock);
	mm_init_cpumask(mm);
	mm_init_aio(mm);
	mm_init_owner(mm, p);
	RCU_INIT_POINTER(mm->exe_file, NULL);
	mmu_notifier_subscriptions_init(mm);
	init_tlb_flush_pending(mm);
#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !USE_SPLIT_PMD_PTLOCKS
	mm->pmd_huge_pte = NULL;
#endif
	mm_init_uprobes_state(mm);

	if (current->mm) {
		mm->flags = current->mm->flags & MMF_INIT_MASK;
		mm->def_flags = current->mm->def_flags & VM_INIT_DEF_MASK;
	} else {
		mm->flags = default_dump_filter;
		mm->def_flags = 0;
	}

	if (mm_alloc_pgd(mm))
		goto fail_nopgd;

	if (init_new_context(p, mm))
		goto fail_nocontext;

	mm->user_ns = get_user_ns(user_ns);
	return mm;

fail_nocontext:
	mm_free_pgd(mm);
fail_nopgd:
	free_mm(mm);
	return NULL;
}

static int max_threads;

static const char * const resident_page_types[] = {
	NAMED_ARRAY_INDEX(MM_FILEPAGES),
	NAMED_ARRAY_INDEX(MM_ANONPAGES),
	NAMED_ARRAY_INDEX(MM_SWAPENTS),
	NAMED_ARRAY_INDEX(MM_SHMEMPAGES),
};

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

#define mm_alloc_pgd(mm)	(0)

#define mm_free_pgd(mm)

#define free_mm(mm)	(kmem_cache_free(mm_cachep, (mm)))

static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


struct pid *pidfd_pid(const struct file *file)
{
	if (file->f_op == &pidfd_fops)
		return file->private_data;

	return ERR_PTR(-EBADF);
}

static const char * const resident_page_types[] = {
	NAMED_ARRAY_INDEX(MM_FILEPAGES),
	NAMED_ARRAY_INDEX(MM_ANONPAGES),
	NAMED_ARRAY_INDEX(MM_SWAPENTS),
	NAMED_ARRAY_INDEX(MM_SHMEMPAGES),
};

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


static int copy_files(unsigned long clone_flags, struct task_struct *tsk)
{
	struct files_struct *oldf, *newf;
	int error = 0;

	/*
	 * A background process may not have any files ...
	 */
	oldf = current->files;
	if (!oldf)
		goto out;

	if (clone_flags & CLONE_FILES) {
		atomic_inc(&oldf->count);
		goto out;
	}

	newf = dup_fd(oldf, NR_OPEN_MAX, &error);
	if (!newf)
		goto out;

	tsk->files = newf;
	error = 0;
out:
	return error;
}

unsigned long total_forks;

int nr_threads;

static int max_threads;

static const char * const resident_page_types[] = {
	NAMED_ARRAY_INDEX(MM_FILEPAGES),
	NAMED_ARRAY_INDEX(MM_ANONPAGES),
	NAMED_ARRAY_INDEX(MM_SWAPENTS),
	NAMED_ARRAY_INDEX(MM_SHMEMPAGES),
};

DEFINE_PER_CPU(unsigned long, process_counts) = 0;

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

int arch_task_struct_size

static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


SYSCALL_DEFINE0(vfork)
{
	struct kernel_clone_args args = {
		.flags		= CLONE_VFORK | CLONE_VM,
		.exit_signal	= SIGCHLD,
	};

	return kernel_clone(&args);
}

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


static inline void __mmput(struct mm_struct *mm)
{
	VM_BUG_ON(atomic_read(&mm->mm_users));

	uprobe_clear_state(mm);
	exit_aio(mm);
	ksm_exit(mm);
	khugepaged_exit(mm); /* must run before exit_mmap */
	exit_mmap(mm);
	mm_put_huge_zero_page(mm);
	set_mm_exe_file(mm, NULL);
	if (!list_empty(&mm->mmlist)) {
		spin_lock(&mmlist_lock);
		list_del(&mm->mmlist);
		spin_unlock(&mmlist_lock);
	}
	if (mm->binfmt)
		module_put(mm->binfmt->module);
	mmdrop(mm);
}

static int max_threads;

static const char * const resident_page_types[] = {
	NAMED_ARRAY_INDEX(MM_FILEPAGES),
	NAMED_ARRAY_INDEX(MM_ANONPAGES),
	NAMED_ARRAY_INDEX(MM_SWAPENTS),
	NAMED_ARRAY_INDEX(MM_SHMEMPAGES),
};

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

void __init

__cacheline_aligned_in_smp DEFINE_SPINLOCK(mmlist_lock);

static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


static int pidfd_release(struct inode *inode, struct file *file)
{
	struct pid *pid = file->private_data;

	file->private_data = NULL;
	put_pid(pid);
	return 0;
}

int nr_threads;

static int max_threads;

static const char * const resident_page_types[] = {
	NAMED_ARRAY_INDEX(MM_FILEPAGES),
	NAMED_ARRAY_INDEX(MM_ANONPAGES),
	NAMED_ARRAY_INDEX(MM_SWAPENTS),
	NAMED_ARRAY_INDEX(MM_SHMEMPAGES),
};

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

int arch_task_struct_size

static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


static inline void mm_free_pgd(struct mm_struct *mm)
{
	pgd_free(mm, mm->pgd);
}


static void account_kernel_stack(struct task_struct *tsk, int account)
{
	void *stack = task_stack_page(tsk);
	struct vm_struct *vm = task_stack_vm_area(tsk);

	/* All stack pages are in the same node. */
	if (vm)
		mod_lruvec_page_state(vm->pages[0], NR_KERNEL_STACK_KB,
				      account * (THREAD_SIZE / 1024));
	else
		mod_lruvec_slab_state(stack, NR_KERNEL_STACK_KB,
				      account * (THREAD_SIZE / 1024));
}

int nr_threads;

static int max_threads;

static const char * const resident_page_types[] = {
	NAMED_ARRAY_INDEX(MM_FILEPAGES),
	NAMED_ARRAY_INDEX(MM_ANONPAGES),
	NAMED_ARRAY_INDEX(MM_SWAPENTS),
	NAMED_ARRAY_INDEX(MM_SHMEMPAGES),
};

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

void __init

int arch_task_struct_size

static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


static void sighand_ctor(void *data)
{
	struct sighand_struct *sighand = data;

	spin_lock_init(&sighand->siglock);
	init_waitqueue_head(&sighand->signalfd_wqh);
}

static int max_threads;

static const char * const resident_page_types[] = {
	NAMED_ARRAY_INDEX(MM_FILEPAGES),
	NAMED_ARRAY_INDEX(MM_ANONPAGES),
	NAMED_ARRAY_INDEX(MM_SWAPENTS),
	NAMED_ARRAY_INDEX(MM_SHMEMPAGES),
};

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

void __init

static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


static inline int mm_alloc_pgd(struct mm_struct *mm)
{
	mm->pgd = pgd_alloc(mm);
	if (unlikely(!mm->pgd))
		return -ENOMEM;
	return 0;
}


static int copy_fs(unsigned long clone_flags, struct task_struct *tsk)
{
	struct fs_struct *fs = current->fs;
	if (clone_flags & CLONE_FS) {
		/* tsk->fs is already what we want */
		spin_lock(&fs->lock);
		if (fs->in_exec) {
			spin_unlock(&fs->lock);
			return -EAGAIN;
		}
		fs->users++;
		spin_unlock(&fs->lock);
		return 0;
	}
	tsk->fs = copy_fs_struct(fs);
	if (!tsk->fs)
		return -ENOMEM;
	return 0;
}


static int copy_io(unsigned long clone_flags, struct task_struct *tsk)
{
#ifdef CONFIG_BLOCK
	struct io_context *ioc = current->io_context;
	struct io_context *new_ioc;

	if (!ioc)
		return 0;
	/*
	 * Share io context with parent, if CLONE_IO is set
	 */
	if (clone_flags & CLONE_IO) {
		ioc_task_link(ioc);
		tsk->io_context = ioc;
	} else if (ioprio_valid(ioc->ioprio)) {
		new_ioc = get_task_io_context(tsk, GFP_KERNEL, NUMA_NO_NODE);
		if (unlikely(!new_ioc))
			return -ENOMEM;

		new_ioc->ioprio = ioc->ioprio;
		put_io_context(new_ioc);
	}
#endif
	return 0;
}

unsigned long total_forks;

int nr_threads;

static int max_threads;

static const char * const resident_page_types[] = {
	NAMED_ARRAY_INDEX(MM_FILEPAGES),
	NAMED_ARRAY_INDEX(MM_ANONPAGES),
	NAMED_ARRAY_INDEX(MM_SWAPENTS),
	NAMED_ARRAY_INDEX(MM_SHMEMPAGES),
};

DEFINE_PER_CPU(unsigned long, process_counts) = 0;

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

#define allocate_mm()	(kmem_cache_alloc(mm_cachep, GFP_KERNEL))

int arch_task_struct_size

static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
{
	struct kernel_clone_args args = {
		.flags		= ((lower_32_bits(flags) | CLONE_VM |
				    CLONE_UNTRACED) & ~CSIGNAL),
		.exit_signal	= (lower_32_bits(flags) & CSIGNAL),
		.stack		= (unsigned long)fn,
		.stack_size	= (unsigned long)arg,
	};

	return kernel_clone(&args);
}

unsigned long total_forks;

int nr_threads;

static int max_threads;

DEFINE_PER_CPU(unsigned long, process_counts) = 0;

static struct kmem_cache *task_struct_cachep;

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

void __init

int arch_task_struct_size

static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct


int __weak arch_dup_task_struct(struct task_struct *dst,
					       struct task_struct *src)
{
	*dst = *src;
	return 0;
}


static void complete_vfork_done(struct task_struct *tsk)
{
	struct completion *vfork;

	task_lock(tsk);
	vfork = tsk->vfork_done;
	if (likely(vfork)) {
		tsk->vfork_done = NULL;
		complete(vfork);
	}
	task_unlock(tsk);
}


static inline void free_thread_stack(struct task_struct *tsk)
{
#ifdef CONFIG_VMAP_STACK
	struct vm_struct *vm = task_stack_vm_area(tsk);

	if (vm) {
		int i;

		for (i = 0; i < THREAD_SIZE / PAGE_SIZE; i++)
			memcg_kmem_uncharge_page(vm->pages[i], 0);

		for (i = 0; i < NR_CACHED_STACKS; i++) {
			if (this_cpu_cmpxchg(cached_stacks[i],
					NULL, tsk->stack_vm_area) != NULL)
				continue;

			return;
		}

		vfree_atomic(tsk->stack);
		return;
	}
#endif

	__free_pages(virt_to_page(tsk->stack), THREAD_SIZE_ORDER);
}

int nr_threads;

static int max_threads;

static const char * const resident_page_types[] = {
	NAMED_ARRAY_INDEX(MM_FILEPAGES),
	NAMED_ARRAY_INDEX(MM_ANONPAGES),
	NAMED_ARRAY_INDEX(MM_SWAPENTS),
	NAMED_ARRAY_INDEX(MM_SHMEMPAGES),
};

static struct kmem_cache *task_struct_cachep;

#define NR_CACHED_STACKS 2

static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);

static struct kmem_cache *thread_stack_cache;

static struct kmem_cache *signal_cachep;

struct kmem_cache *sighand_cachep;

struct kmem_cache *files_cachep;

struct kmem_cache *fs_cachep;

static struct kmem_cache *vm_area_cachep;

static struct kmem_cache *mm_cachep;

void __init

int arch_task_struct_size

static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;

const struct file_operations pidfd_fops = {
	.release = pidfd_release,
	.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
	.show_fdinfo = pidfd_show_fdinfo,
#endif
};

static __latent_entropy struct