static int bloom_check_add(struct bloom *bloom, void *buffer, int len, int add) { if (bloom->ready == 0) { fprintf(stderr, "bloom is not initialized!\n"); return -1; } int hits = 0; unsigned int digest[DIGEST_LEN_MAX / sizeof(unsigned int)]; BUILD_BUG_ON(DIGEST_LEN_MAX % sizeof(unsigned int)); checksum_block(buffer, len, (unsigned char *)digest); register unsigned int a = digest[0]; register unsigned int b = digest[1]; register unsigned int x; register unsigned int i; register unsigned int byte; register unsigned int mask; register unsigned char c; /* * We are using another way to reduce hashing * See http://www.eecs.harvard.edu/~kirsch/pubs/bbbf/esa06.pdf */ for (i = 0; i < bloom->hashes; i++) { x = (a + i*b) % bloom->bits; byte = x >> 3; c = bloom->bf[byte]; mask = 1 << (x % 8); if (c & mask) { hits++; } else { if (add) bloom->bf[byte] = c | mask; } } /* element already in (or collision) */ if (hits == bloom->hashes) return 1; return 0; }
int amiga_partition(struct parsed_partitions *state) { Sector sect; unsigned char *data; struct RigidDiskBlock *rdb; struct PartitionBlock *pb; int start_sect, nr_sects, blk, part, res = 0; int blksize = 1; /* Multiplier for disk block size */ int slot = 1; char b[BDEVNAME_SIZE]; for (blk = 0; ; blk++, put_dev_sector(sect)) { if (blk == RDB_ALLOCATION_LIMIT) goto rdb_done; data = read_part_sector(state, blk, §); if (!data) { if (warn_no_part) printk("Dev %s: unable to read RDB block %d\n", bdevname(state->bdev, b), blk); res = -1; goto rdb_done; } if (*(__be32 *)data != cpu_to_be32(IDNAME_RIGIDDISK)) continue; rdb = (struct RigidDiskBlock *)data; if (checksum_block((__be32 *)data, be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F) == 0) break; /* Try again with 0xdc..0xdf zeroed, Windows might have * trashed it. */ *(__be32 *)(data+0xdc) = 0; if (checksum_block((__be32 *)data, be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F)==0) { printk("Warning: Trashed word at 0xd0 in block %d " "ignored in checksum calculation\n",blk); break; } printk("Dev %s: RDB in block %d has bad checksum\n", bdevname(state->bdev, b), blk); } /* blksize is blocks per 512 byte standard block */ blksize = be32_to_cpu( rdb->rdb_BlockBytes ) / 512; { char tmp[7 + 10 + 1 + 1]; /* Be more informative */ snprintf(tmp, sizeof(tmp), " RDSK (%d)", blksize * 512); strlcat(state->pp_buf, tmp, PAGE_SIZE); } blk = be32_to_cpu(rdb->rdb_PartitionList); put_dev_sector(sect); for (part = 1; blk>0 && part<=16; part++, put_dev_sector(sect)) { blk *= blksize; /* Read in terms partition table understands */ data = read_part_sector(state, blk, §); if (!data) { if (warn_no_part) printk("Dev %s: unable to read partition block %d\n", bdevname(state->bdev, b), blk); res = -1; goto rdb_done; } pb = (struct PartitionBlock *)data; blk = be32_to_cpu(pb->pb_Next); if (pb->pb_ID != cpu_to_be32(IDNAME_PARTITION)) continue; if (checksum_block((__be32 *)pb, be32_to_cpu(pb->pb_SummedLongs) & 0x7F) != 0 ) continue; /* Tell Kernel about it */ nr_sects = (be32_to_cpu(pb->pb_Environment[10]) + 1 - be32_to_cpu(pb->pb_Environment[9])) * be32_to_cpu(pb->pb_Environment[3]) * be32_to_cpu(pb->pb_Environment[5]) * blksize; if (!nr_sects) continue; start_sect = be32_to_cpu(pb->pb_Environment[9]) * be32_to_cpu(pb->pb_Environment[3]) * be32_to_cpu(pb->pb_Environment[5]) * blksize; put_partition(state,slot++,start_sect,nr_sects); { /* Be even more informative to aid mounting */ char dostype[4]; char tmp[42]; __be32 *dt = (__be32 *)dostype; *dt = pb->pb_Environment[16]; if (dostype[3] < ' ') snprintf(tmp, sizeof(tmp), " (%c%c%c^%c)", dostype[0], dostype[1], dostype[2], dostype[3] + '@' ); else snprintf(tmp, sizeof(tmp), " (%c%c%c%c)", dostype[0], dostype[1], dostype[2], dostype[3]); strlcat(state->pp_buf, tmp, PAGE_SIZE); snprintf(tmp, sizeof(tmp), "(res %d spb %d)", be32_to_cpu(pb->pb_Environment[6]), be32_to_cpu(pb->pb_Environment[4])); strlcat(state->pp_buf, tmp, PAGE_SIZE); } res = 1; } strlcat(state->pp_buf, "\n", PAGE_SIZE); rdb_done: return res; }
int amiga_partition(struct parsed_partitions *state, struct block_device *bdev) { Sector sect; unsigned char *data; struct RigidDiskBlock *rdb; struct PartitionBlock *pb; int start_sect, nr_sects, blk, part, res = 0; int slot = 1; char b[BDEVNAME_SIZE]; for (blk = 0; ; blk++, put_dev_sector(sect)) { if (blk == RDB_ALLOCATION_LIMIT) goto rdb_done; data = read_dev_sector(bdev, blk, §); if (!data) { if (warn_no_part) printk("Dev %s: unable to read RDB block %d\n", bdevname(bdev, b), blk); goto rdb_done; } if (*(u32 *)data != cpu_to_be32(IDNAME_RIGIDDISK)) continue; rdb = (struct RigidDiskBlock *)data; if (checksum_block((u32 *)data, be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F) == 0) break; /* Try again with 0xdc..0xdf zeroed, Windows might have * trashed it. */ *(u32 *)(data+0xdc) = 0; if (checksum_block((u32 *)data, be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F)==0) { printk("Warning: Trashed word at 0xd0 in block %d " "ignored in checksum calculation\n",blk); break; } printk("Dev %s: RDB in block %d has bad checksum\n", bdevname(bdev, b), blk); } printk(" RDSK"); blk = be32_to_cpu(rdb->rdb_PartitionList); put_dev_sector(sect); for (part = 1; blk>0 && part<=16; part++, put_dev_sector(sect)) { data = read_dev_sector(bdev, blk, §); if (!data) { if (warn_no_part) printk("Dev %s: unable to read partition block %d\n", bdevname(bdev, b), blk); goto rdb_done; } pb = (struct PartitionBlock *)data; blk = be32_to_cpu(pb->pb_Next); if (pb->pb_ID != cpu_to_be32(IDNAME_PARTITION)) continue; if (checksum_block((u32 *)pb, be32_to_cpu(pb->pb_SummedLongs) & 0x7F) != 0 ) continue; /* Tell Kernel about it */ nr_sects = (be32_to_cpu(pb->pb_Environment[10]) + 1 - be32_to_cpu(pb->pb_Environment[9])) * be32_to_cpu(pb->pb_Environment[3]) * be32_to_cpu(pb->pb_Environment[5]); if (!nr_sects) continue; start_sect = be32_to_cpu(pb->pb_Environment[9]) * be32_to_cpu(pb->pb_Environment[3]) * be32_to_cpu(pb->pb_Environment[5]); put_partition(state,slot++,start_sect,nr_sects); res = 1; } printk("\n"); rdb_done: return res; }
static int amiga_partition(struct gendisk *hd, unsigned int dev, unsigned long first_sector) { struct buffer_head *bh; struct RigidDiskBlock *rdb; struct PartitionBlock *pb; int start_sect; int nr_sects; int blk; int part, res; set_blocksize(dev,512); res = 0; for (blk = 0; blk < RDB_ALLOCATION_LIMIT; blk++) { if(!(bh = bread(dev,blk,512))) { printk("Dev %d: unable to read RDB block %d\n",dev,blk); goto rdb_done; } if (*(__u32 *)bh->b_data == htonl(IDNAME_RIGIDDISK)) { rdb = (struct RigidDiskBlock *)bh->b_data; if (checksum_block((__u32 *)bh->b_data,htonl(rdb->rdb_SummedLongs) & 0x7F)) { printk("Dev %d: RDB in block %d has bad checksum\n",dev,blk); brelse(bh); continue; } printk(" RDSK"); blk = htonl(rdb->rdb_PartitionList); brelse(bh); for (part = 1; blk > 0 && part <= 16; part++) { if (!(bh = bread(dev,blk,512))) { printk("Dev %d: unable to read partition block %d\n", dev,blk); goto rdb_done; } pb = (struct PartitionBlock *)bh->b_data; blk = htonl(pb->pb_Next); if (pb->pb_ID == htonl(IDNAME_PARTITION) && checksum_block( (__u32 *)pb,htonl(pb->pb_SummedLongs) & 0x7F) == 0 ) { /* Tell Kernel about it */ if (!(nr_sects = (htonl(pb->pb_Environment[10]) + 1 - htonl(pb->pb_Environment[9])) * htonl(pb->pb_Environment[3]) * htonl(pb->pb_Environment[5]))) { continue; } start_sect = htonl(pb->pb_Environment[9]) * htonl(pb->pb_Environment[3]) * htonl(pb->pb_Environment[5]); add_partition(hd,current_minor,start_sect,nr_sects); current_minor++; res = 1; } brelse(bh); } printk("\n"); break; } } rdb_done: set_blocksize(dev,BLOCK_SIZE); return res; }
int main(int argc, char **argv) { char *fname = NULL; int fd, ret; ssize_t len; struct stat s; struct running_checksum *csum; ret = parse_opts(argc, argv, &fname); if (ret) { fprintf(stderr, "Usage: %s [-b buflen] [--hash=hash_type] filename\n", argv[0]); return 1; } ret = init_csum_module(user_hash); if (ret) return ret; buf = malloc(buf_len); if (buf == NULL) return ENOMEM; fd = open(fname, O_RDONLY); if (fd < 0) return errno; /* * If the test file size is less than BUF_LEN we'll exercise * the one-shot function. Otherwise, do a running checksum. */ ret = fstat(fd, &s); if (ret) return errno; if (s.st_size == 0) return 0; if (s.st_size <= buf_len) { printf("File size is smaller than buffer, using one shot\n"); len = read(fd, buf, buf_len); if (len < 0) return errno; if (len == 0) return 1; checksum_block((char *)buf, len, digest); } else { printf("File size is larger than buffer, using running " "checksum\n"); csum = start_running_checksum(); while (1) { len = read(fd, buf, buf_len); if (len < 0) return errno; if (len) { add_to_running_checksum(csum, len, buf); } else break; /* EOF */ } finish_running_checksum(csum, digest); } debug_print_digest(stdout, digest); printf(" %s\n", fname); return 0; }