static int ext2_valid_block_bitmap(struct super_block *sb, struct ext2_group_desc *desc, unsigned int block_group, struct buffer_head *bh) { ext2_grpblk_t offset; ext2_grpblk_t next_zero_bit; ext2_fsblk_t bitmap_blk; ext2_fsblk_t group_first_block; group_first_block = ext2_group_first_block_no(sb, block_group); /* check whether block bitmap block number is set */ bitmap_blk = le32_to_cpu(desc->bg_block_bitmap); offset = bitmap_blk - group_first_block; if (!ext2_test_bit(offset, bh->b_data)) /* bad block bitmap */ goto err_out; /* check whether the inode bitmap block number is set */ bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap); offset = bitmap_blk - group_first_block; if (!ext2_test_bit(offset, bh->b_data)) /* bad block bitmap */ goto err_out; /* check whether the inode table block number is set */ bitmap_blk = le32_to_cpu(desc->bg_inode_table); offset = bitmap_blk - group_first_block; next_zero_bit = ext2_find_next_zero_bit(bh->b_data, offset + EXT2_SB(sb)->s_itb_per_group, offset); if (next_zero_bit >= offset + EXT2_SB(sb)->s_itb_per_group) /* good bitmap for inode tables */ return 1; err_out: ext2_error(sb, __func__, "Invalid block bitmap - " "block_group = %d, block = %lu", block_group, bitmap_blk); return 0; }
static int core_get_resync_work(struct dm_dirty_log *log, region_t *region) { struct log_c *lc = (struct log_c *) log->context; if (lc->sync_search >= lc->region_count) return 0; do { *region = ext2_find_next_zero_bit( (unsigned long *) lc->sync_bits, lc->region_count, lc->sync_search); lc->sync_search = *region + 1; if (*region >= lc->region_count) return 0; } while (log_test_bit(lc->recovering_bits, *region)); log_set_bit(lc, lc->recovering_bits, *region); return 1; }
static void TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len) { __be16 proto; __be16 *s; int i; if (dest != TftpOurPort) { #ifdef CONFIG_MCAST_TFTP if (Multicast && (!Mcast_port || (dest != Mcast_port))) #endif return; } if (TftpState != STATE_SEND_RRQ && src != TftpRemotePort && TftpState != STATE_RECV_WRQ && TftpState != STATE_SEND_WRQ) return; if (len < 2) return; len -= 2; /* warning: don't use increment (++) in ntohs() macros!! */ s = (__be16 *)pkt; proto = *s++; pkt = (uchar *)s; switch (ntohs(proto)) { case TFTP_RRQ: break; case TFTP_ACK: #ifdef CONFIG_CMD_TFTPPUT if (TftpWriting) { if (TftpFinalBlock) { tftp_complete(); } else { /* * Move to the next block. We want our block * count to wrap just like the other end! */ int block = ntohs(*s); int ack_ok = (TftpBlock == block); TftpBlock = (unsigned short)(block + 1); update_block_number(); if (ack_ok) TftpSend(); /* Send next data block */ } } #endif break; default: break; #ifdef CONFIG_CMD_TFTPSRV case TFTP_WRQ: debug("Got WRQ\n"); TftpRemoteIP = sip; TftpRemotePort = src; TftpOurPort = 1024 + (get_timer(0) % 3072); new_transfer(); TftpSend(); /* Send ACK(0) */ break; #endif case TFTP_OACK: debug("Got OACK: %s %s\n", pkt, pkt + strlen((char *)pkt) + 1); TftpState = STATE_OACK; TftpRemotePort = src; /* * Check for 'blksize' option. * Careful: "i" is signed, "len" is unsigned, thus * something like "len-8" may give a *huge* number */ for (i = 0; i+8 < len; i++) { if (strcmp((char *)pkt+i, "blksize") == 0) { TftpBlkSize = (unsigned short) simple_strtoul((char *)pkt+i+8, NULL, 10); debug("Blocksize ack: %s, %d\n", (char *)pkt+i+8, TftpBlkSize); } #ifdef CONFIG_TFTP_TSIZE if (strcmp((char *)pkt+i, "tsize") == 0) { TftpTsize = simple_strtoul((char *)pkt+i+6, NULL, 10); debug("size = %s, %d\n", (char *)pkt+i+6, TftpTsize); } #endif } #ifdef CONFIG_MCAST_TFTP parse_multicast_oack((char *)pkt, len-1); if ((Multicast) && (!MasterClient)) TftpState = STATE_DATA; /* passive.. */ else #endif #ifdef CONFIG_CMD_TFTPPUT if (TftpWriting) { /* Get ready to send the first block */ TftpState = STATE_DATA; TftpBlock++; } #endif TftpSend(); /* Send ACK or first data block */ break; case TFTP_DATA: if (len < 2) return; len -= 2; TftpBlock = ntohs(*(__be16 *)pkt); update_block_number(); if (TftpState == STATE_SEND_RRQ) debug("Server did not acknowledge timeout option!\n"); if (TftpState == STATE_SEND_RRQ || TftpState == STATE_OACK || TftpState == STATE_RECV_WRQ) { /* first block received */ TftpState = STATE_DATA; TftpRemotePort = src; new_transfer(); #ifdef CONFIG_MCAST_TFTP if (Multicast) { /* start!=1 common if mcast */ TftpLastBlock = TftpBlock - 1; } else #endif if (TftpBlock != 1) { /* Assertion */ printf("\nTFTP error: " "First block is not block 1 (%ld)\n" "Starting again\n\n", TftpBlock); NetStartAgain(); break; } } if (TftpBlock == TftpLastBlock) { /* * Same block again; ignore it. */ break; } TftpLastBlock = TftpBlock; TftpTimeoutCountMax = TIMEOUT_COUNT; NetSetTimeout(TftpTimeoutMSecs, TftpTimeout); store_block(TftpBlock - 1, pkt + 2, len); /* * Acknowledge the block just received, which will prompt * the remote for the next one. */ #ifdef CONFIG_MCAST_TFTP /* if I am the MasterClient, actively calculate what my next * needed block is; else I'm passive; not ACKING */ if (Multicast) { if (len < TftpBlkSize) { TftpEndingBlock = TftpBlock; } else if (MasterClient) { TftpBlock = PrevBitmapHole = ext2_find_next_zero_bit( Bitmap, (Mapsize*8), PrevBitmapHole); if (TftpBlock > ((Mapsize*8) - 1)) { printf("tftpfile too big\n"); /* try to double it and retry */ Mapsize <<= 1; mcast_cleanup(); NetStartAgain(); return; } TftpLastBlock = TftpBlock; } } #endif TftpSend(); #ifdef CONFIG_MCAST_TFTP if (Multicast) { if (MasterClient && (TftpBlock >= TftpEndingBlock)) { puts("\nMulticast tftp done\n"); mcast_cleanup(); net_set_state(NETLOOP_SUCCESS); } } else #endif if (len < TftpBlkSize) tftp_complete(); break; case TFTP_ERROR: printf("\nTFTP error: '%s' (%d)\n", pkt + 2, ntohs(*(__be16 *)pkt)); switch (ntohs(*(__be16 *)pkt)) { case TFTP_ERR_FILE_NOT_FOUND: case TFTP_ERR_ACCESS_DENIED: puts("Not retrying...\n"); eth_halt(); net_set_state(NETLOOP_FAIL); break; case TFTP_ERR_UNDEFINED: case TFTP_ERR_DISK_FULL: case TFTP_ERR_UNEXPECTED_OPCODE: case TFTP_ERR_UNKNOWN_TRANSFER_ID: case TFTP_ERR_FILE_ALREADY_EXISTS: default: puts("Starting again\n\n"); #ifdef CONFIG_MCAST_TFTP mcast_cleanup(); #endif NetStartAgain(); break; } break; } }
static void TftpSend(void) { uchar *pkt; uchar *xp; int len = 0; ushort *s; #ifdef CONFIG_MCAST_TFTP /* Multicast TFTP.. non-MasterClients do not ACK data. */ if (Multicast && (TftpState == STATE_DATA) && (MasterClient == 0)) return; #endif /* * We will always be sending some sort of packet, so * cobble together the packet headers now. */ pkt = NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE; switch (TftpState) { case STATE_SEND_RRQ: case STATE_SEND_WRQ: xp = pkt; s = (ushort *)pkt; #ifdef CONFIG_CMD_TFTPPUT *s++ = htons(TftpState == STATE_SEND_RRQ ? TFTP_RRQ : TFTP_WRQ); #else *s++ = htons(TFTP_RRQ); #endif pkt = (uchar *)s; strcpy((char *)pkt, tftp_filename); pkt += strlen(tftp_filename) + 1; strcpy((char *)pkt, "octet"); pkt += 5 /*strlen("octet")*/ + 1; strcpy((char *)pkt, "timeout"); pkt += 7 /*strlen("timeout")*/ + 1; sprintf((char *)pkt, "%lu", TftpTimeoutMSecs / 1000); debug("send option \"timeout %s\"\n", (char *)pkt); pkt += strlen((char *)pkt) + 1; #ifdef CONFIG_TFTP_TSIZE pkt += sprintf((char *)pkt, "tsize%c%lu%c", 0, NetBootFileXferSize, 0); #endif /* try for more effic. blk size */ pkt += sprintf((char *)pkt, "blksize%c%d%c", 0, TftpBlkSizeOption, 0); #ifdef CONFIG_MCAST_TFTP /* Check all preconditions before even trying the option */ if (!ProhibitMcast) { Bitmap = malloc(Mapsize); if (Bitmap && eth_get_dev()->mcast) { free(Bitmap); Bitmap = NULL; pkt += sprintf((char *)pkt, "multicast%c%c", 0, 0); } } #endif /* CONFIG_MCAST_TFTP */ len = pkt - xp; break; case STATE_OACK: #ifdef CONFIG_MCAST_TFTP /* My turn! Start at where I need blocks I missed.*/ if (Multicast) TftpBlock = ext2_find_next_zero_bit(Bitmap, (Mapsize*8), 0); /*..falling..*/ #endif case STATE_RECV_WRQ: case STATE_DATA: xp = pkt; s = (ushort *)pkt; s[0] = htons(TFTP_ACK); s[1] = htons(TftpBlock); pkt = (uchar *)(s + 2); #ifdef CONFIG_CMD_TFTPPUT if (TftpWriting) { int toload = TftpBlkSize; int loaded = load_block(TftpBlock, pkt, toload); s[0] = htons(TFTP_DATA); pkt += loaded; TftpFinalBlock = (loaded < toload); } #endif len = pkt - xp; break; case STATE_TOO_LARGE: xp = pkt; s = (ushort *)pkt; *s++ = htons(TFTP_ERROR); *s++ = htons(3); pkt = (uchar *)s; strcpy((char *)pkt, "File too large"); pkt += 14 /*strlen("File too large")*/ + 1; len = pkt - xp; break; case STATE_BAD_MAGIC: xp = pkt; s = (ushort *)pkt; *s++ = htons(TFTP_ERROR); *s++ = htons(2); pkt = (uchar *)s; strcpy((char *)pkt, "File has bad magic"); pkt += 18 /*strlen("File has bad magic")*/ + 1; len = pkt - xp; break; } NetSendUDPPacket(NetServerEther, TftpRemoteIP, TftpRemotePort, TftpOurPort, len); }
static void TftpSend (void) { volatile uchar * pkt; volatile uchar * xp; int len = 0; volatile ushort *s; #ifdef CONFIG_MCAST_TFTP /* Multicast TFTP.. non-MasterClients do not ACK data. */ if (Multicast && (TftpState == STATE_DATA) && (MasterClient == 0)) return; #endif /* * We will always be sending some sort of packet, so * cobble together the packet headers now. */ pkt = NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE; switch (TftpState) { case STATE_RRQ: xp = pkt; s = (ushort *)pkt; *s++ = htons(TFTP_RRQ); pkt = (uchar *)s; strcpy ((char *)pkt, tftp_filename); pkt += strlen(tftp_filename) + 1; strcpy ((char *)pkt, "octet"); pkt += 5 /*strlen("octet")*/ + 1; strcpy ((char *)pkt, "timeout"); pkt += 7 /*strlen("timeout")*/ + 1; sprintf((char *)pkt, "%lu", TIMEOUT / 1000); debug("send option \"timeout %s\"\n", (char *)pkt); pkt += strlen((char *)pkt) + 1; /* try for more effic. blk size */ pkt += sprintf((char *)pkt,"blksize%c%d%c", 0,TftpBlkSizeOption,0); #ifdef CONFIG_MCAST_TFTP /* Check all preconditions before even trying the option */ if (!ProhibitMcast && (Bitmap=malloc(Mapsize)) && eth_get_dev()->mcast) { free(Bitmap); Bitmap=NULL; pkt += sprintf((char *)pkt,"multicast%c%c",0,0); } #endif /* CONFIG_MCAST_TFTP */ len = pkt - xp; break; case STATE_OACK: #ifdef CONFIG_MCAST_TFTP /* My turn! Start at where I need blocks I missed.*/ if (Multicast) TftpBlock=ext2_find_next_zero_bit(Bitmap,(Mapsize*8),0); /*..falling..*/ #endif case STATE_DATA: xp = pkt; s = (ushort *)pkt; *s++ = htons(TFTP_ACK); *s++ = htons(TftpBlock); pkt = (uchar *)s; len = pkt - xp; break; case STATE_TOO_LARGE: xp = pkt; s = (ushort *)pkt; *s++ = htons(TFTP_ERROR); *s++ = htons(3); pkt = (uchar *)s; strcpy ((char *)pkt, "File too large"); pkt += 14 /*strlen("File too large")*/ + 1; len = pkt - xp; break; case STATE_BAD_MAGIC: xp = pkt; s = (ushort *)pkt; *s++ = htons(TFTP_ERROR); *s++ = htons(2); pkt = (uchar *)s; strcpy ((char *)pkt, "File has bad magic"); pkt += 18 /*strlen("File has bad magic")*/ + 1; len = pkt - xp; break; } NetSendUDPPacket(NetServerEther, TftpServerIP, TftpServerPort, TftpOurPort, len); }