(root)/
util-linux-2.39/
libblkid/
src/
superblocks/
nvidia_raid.c
       1  /*
       2   * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
       3   * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
       4   *
       5   * Inspired by libvolume_id by
       6   *     Kay Sievers <kay.sievers@vrfy.org>
       7   *
       8   * This file may be redistributed under the terms of the
       9   * GNU Lesser General Public License.
      10   */
      11  #include <stdio.h>
      12  #include <stdlib.h>
      13  #include <unistd.h>
      14  #include <string.h>
      15  #include <stdint.h>
      16  
      17  #include "superblocks.h"
      18  
      19  struct nv_metadata {
      20  	uint8_t		vendor[8];
      21  	uint32_t	size;
      22  	uint32_t	chksum;
      23  	uint16_t	version;
      24  } __attribute__((packed));
      25  
      26  #define NVIDIA_SIGNATURE		"NVIDIA  "
      27  #define NVIDIA_SUPERBLOCK_SIZE		120
      28  
      29  
      30  static int nvraid_verify_checksum(blkid_probe pr, const struct nv_metadata *nv)
      31  {
      32  	uint32_t csum = le32_to_cpu(nv->chksum);
      33  	for (size_t i = 0; i < le32_to_cpu(nv->size); i++)
      34  		csum += le32_to_cpu(((uint32_t *) nv)[i]);
      35  	return blkid_probe_verify_csum(pr, csum, le32_to_cpu(nv->chksum));
      36  }
      37  
      38  static int probe_nvraid(blkid_probe pr,
      39  		const struct blkid_idmag *mag __attribute__((__unused__)))
      40  {
      41  	uint64_t off;
      42  	struct nv_metadata *nv;
      43  
      44  	if (pr->size < 0x10000)
      45  		return 1;
      46  	if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr))
      47  		return 1;
      48  
      49  	off = ((pr->size / 0x200) - 2) * 0x200;
      50  	nv = (struct nv_metadata *)
      51  		blkid_probe_get_buffer(pr,
      52  				off,
      53  				NVIDIA_SUPERBLOCK_SIZE);
      54  	if (!nv)
      55  		return errno ? -errno : 1;
      56  
      57  	if (memcmp(nv->vendor, NVIDIA_SIGNATURE, sizeof(NVIDIA_SIGNATURE)-1) != 0)
      58  		return 1;
      59  	if (le32_to_cpu(nv->size) * 4 != NVIDIA_SUPERBLOCK_SIZE)
      60  		return 1;
      61  	if (!nvraid_verify_checksum(pr, nv))
      62  		return 1;
      63  	if (blkid_probe_sprintf_version(pr, "%u", le16_to_cpu(nv->version)) != 0)
      64  		return 1;
      65  	if (blkid_probe_set_magic(pr, off, sizeof(nv->vendor),
      66  				(unsigned char *) nv->vendor))
      67  		return 1;
      68  	return 0;
      69  }
      70  
      71  const struct blkid_idinfo nvraid_idinfo = {
      72  	.name		= "nvidia_raid_member",
      73  	.usage		= BLKID_USAGE_RAID,
      74  	.probefunc	= probe_nvraid,
      75  	.magics		= BLKID_NONE_MAGIC
      76  };
      77  
      78