int putchar(int c) { extern int32_t _the_console_fd; extern long xTaskGetSchedulerState( void ); extern unsigned long getNesting( void ); if ((intContext() == TRUE) || (_the_console_fd <= 0) || (getNesting() > 0)) //|| (xTaskGetSchedulerState() != 1)) { /* 在终端中或调度器未运行时直接调用底层输出保证不使用taskDelay */ if (c == '\n') { bsp_putchar('\r'); } bsp_putchar((unsigned char)c); } else { if((c) == '\n') { char ch = '\r'; dev_write(_the_console_fd, (uint8_t* )&ch, 1); } dev_write(_the_console_fd, (uint8_t* )&c, 1); } return 1; }
void echo() { static int tty = 1; char name[] = "tty*", buf[256]; Device *dev; lock(); name[3] = '0' + (tty ++); unlock(); while (1) { dev = hal_get(name); if (dev != NULL) { dev_write(dev, 0, name, 4); dev_write(dev, 0, "# ", 2); int i, nread = dev_read(dev, 0, buf, 255); buf[nread] = 0; for (i = 0; i < nread; i ++) { if (buf[i] >= 'a' && buf[i] <= 'z') { buf[i] += 'A' - 'a'; } } dev_write(dev, 0, "Got: ", 5); dev_write(dev, 0, buf, nread); dev_write(dev, 0, "\n", 1); } else { // printf("%s\n", name); } } }
void start(void) { uint16_t count; uint8_t index; buffer = (char *)mos_mem_alloc((uint16_t)BUFFER_SIZE); memset(buffer, 'X', BUFFER_SIZE); /* For safety, erase entire FLASH */ dev_ioctl(DEV_TELOS_FLASH, TELOS_FLASH_BULK_ERASE); /* Turn on the FLASH */ dev_mode(DEV_TELOS_FLASH, DEV_MODE_ON); /* Acquire lock on FLASH and preliminarly * write 64 bits of data */ dev_open(DEV_TELOS_FLASH); count = dev_write(DEV_TELOS_FLASH, "abcdefgh", 8); printf("%d bytes of data have been written to FLASH memory\n", count); dev_close(DEV_TELOS_FLASH); /* Perform experiments over R/W pointer to FLASH */ /* Experiment#1 - flash is on, lock is free; aquire lock and read * without using any SEEK function */ dev_open(DEV_TELOS_FLASH); count = dev_read(DEV_TELOS_FLASH, buffer, 1); printf("#1 : %c has been read from FLASH memory\n", buffer[0]); dev_close(DEV_TELOS_FLASH); /* Move pointer */ dev_open(DEV_TELOS_FLASH); dev_ioctl(DEV_TELOS_FLASH, DEV_SEEK, 3); dev_close(DEV_TELOS_FLASH); /* Experiment#2 - flash is on, lock is free; aquire lock, read single data, * write single data and read multiple data from it */ dev_open(DEV_TELOS_FLASH); dev_read(DEV_TELOS_FLASH, buffer, 1); printf("#2 : %c has been read\n" " : FLASH memory written\n", buffer[0]); dev_write(DEV_TELOS_FLASH, "l", 1); count = dev_read(DEV_TELOS_FLASH, buffer, 1); printf(" : %d bytes have been read from FLASH memory: ", count); for(index = 0; index < count; index++) { printf("%c ", buffer[index]); } printf("\n"); dev_close(DEV_TELOS_FLASH); /* Release lock and free resources */ dev_close(DEV_TELOS_FLASH); dev_mode(DEV_TELOS_FLASH, DEV_MODE_OFF); mos_mem_free(buffer); return; }
int bit_turn(Dev* device, int byte_addr, int offset, int (* func)(char*, int)) { char byte; dev_read(&byte, sizeof(char), byte_addr, device); func(&byte, offset); dev_write(&byte, sizeof(char), byte_addr, device); return 0; }
void i2c_write () { uint8_t i = prompt_uint8("#:"); dev_write(DEV_AVR_I2C, i, sizeof(i)); printf("Wrote: %C\n",i); }
void eep_write () { // boot control block is at addr 0, so start somewhere else uint16_t address = 100; uint8_t data[] = "mantis rocks yo"; dev_ioctl (DEV_AVR_EEPROM, DEV_SEEK, address); dev_write (DEV_AVR_EEPROM, data, sizeof (data)); }
static void click() { uint8_t arg; dev_open(DEV_MICA2_SOUNDER); arg = 1; dev_write(DEV_MICA2_SOUNDER, &arg, sizeof(arg)); mos_udelay(0xffff); mos_udelay(0xffff); arg = 0; dev_write(DEV_MICA2_SOUNDER, &arg, sizeof(arg)); dev_close(DEV_MICA2_SOUNDER); }
int ybs_set_vo(int d) { int uv_per_bit = (int)(VREF_DAC * 1e6 / (1 << 16)); d = d2uv(d) / uv_per_bit; d = (d > 0xffff) ? 0xffff : d; d = (d < 0) ? 0 : d; dev_write(ybs_fd_dac, &d, 0); return 0; }
static void clear_cb () { boot_control_block_t cb; dev_ioctl (DEV_AVR_EEPROM, DEV_SEEK, CONTROL_BLOCK_ADDR); cb.node_id = mos_node_id_get (); cb.byte_count = (uint32_t)0; cb.start_addr = (uint32_t)0; cb.reprogram = 0; dev_write (DEV_AVR_EEPROM, (uint8_t *)&cb, sizeof (cb)); }
int ybs_set_vr(int d) //set Vref { int uv_per_bit = (int)(VREF_DAC * 1e6 / (1 << 16)); d = d2uv(d) / uv_per_bit; d = (d > 0xffff) ? 0xffff : d; d = (d < 0) ? 0 : d; dev_ioctl(ybs_fd_dac, DAC_SET_CH, 0); dev_write(ybs_fd_dac, &d, 0); dev_ioctl(ybs_fd_dac, DAC_SET_CH, 1); //for fast ch1 write purpose return 0; }
void ext_flash_write() { uint32_t address = 0; //uint8_t data[] = "mantis"; uint16_t i; for (i = 0; i < sizeof (data); i++) { data[i] = (i % 10) + '0'; } dev_ioctl (DEV_ATMEL_FLASH, DEV_SEEK, address); dev_write (DEV_ATMEL_FLASH, data, sizeof (data)); }
/* Caller may need to use label_get_handler to create label struct! */ int label_write(struct device *dev, struct label *label) { #pragma pack(8) char buf[LABEL_SIZE]; //__attribute((aligned(8))); #pragma pack() struct label_header *lh = (struct label_header *) buf; int r = 1; if (!label->labeller->ops->write) { log_err("Label handler does not support label writes"); return 0; } if ((LABEL_SIZE + (label->sector << SECTOR_SHIFT)) > LABEL_SCAN_SIZE) { log_error("Label sector %" PRIu64 " beyond range (%ld)", label->sector, LABEL_SCAN_SECTORS); return 0; } memset(buf, 0, LABEL_SIZE); strncpy((char *)lh->id, LABEL_ID, sizeof(lh->id)); lh->sector_xl = xlate64(label->sector); lh->offset_xl = xlate32(sizeof(*lh)); if (!(label->labeller->ops->write)(label, buf)) { stack; return 0; } lh->crc_xl = xlate32(calc_crc(INITIAL_CRC, &lh->offset_xl, LABEL_SIZE - ((char *) &lh->offset_xl - (char *) lh))); //((void *) &lh->offset_xl - (void *) lh))); if (!dev_open(dev)) { stack; return 0; } log_info("%s: Writing label to sector %" PRIu64, dev_name(dev), label->sector); if (!dev_write(dev, label->sector << SECTOR_SHIFT, LABEL_SIZE, buf)) { log_debug("Failed to write label to %s", dev_name(dev)); r = 0; } if (!dev_close(dev)) stack; return r; }
void accel_off () { uint8_t i; dev_ioctl(DEV_AVR_I2C, I2C_SET_BRR, 50); //set speed dev_ioctl(DEV_AVR_I2C, I2C_DEST_ADDR, ADG715_PWR_ADDR); //set dest address dev_read(DEV_AVR_I2C, &i, sizeof(i)); //get current value i &= ~(1 <<5); //turn off accel dev_write(DEV_AVR_I2C, &i, sizeof(i)); //write value back printf("Weatherboard accelerometer off.\n"); }
static void reprogram() { /*boot_control_block_t cb; dev_ioctl(DEV_AVR_EEPROM, DEV_SEEK, CONTROL_BLOCK_ADDR); dev_read(DEV_AVR_EEPROM, (uint8_t *)&cb, sizeof(cb));*/ //printf ("Receiving a code image over serial\n"); //uint32_t image_size = reprogram_iface (IFACE_SERIAL, &cb, 0); mos_file* file = reprogram_iface (IFACE_SERIAL, NULL); mos_file_flush(file); boot_control_block_t cb; cb.node_id = mos_node_id_get (); cb.byte_count = file->length; cb.start_addr = file->start; cb.reprogram = 1; dev_ioctl (DEV_AVR_EEPROM, DEV_SEEK, CONTROL_BLOCK_ADDR); dev_write (DEV_AVR_EEPROM, (uint8_t *)&cb, CONTROL_BLOCK_SIZE); }
static ssize_t p_write(int index, struct file* filp, const char* buf, size_t count, loff_t* f_pos) { context *ct = filp->private_data; size_t left = count, wrt; int ret; if(RELEASE(index)) return count; while(1) { Down(index); wrt = left; ret = dev_write(&((pipes[index]).device), f_pos, buf+(count-left), &left, ct); if(ret == DEV_FAULT) {Up(index); return -EFAULT;} #ifdef __PIPE_SELECT pipes[index].r_poll = 1; #endif if(wrt) { R_ABLE(ct) = 1; if(ret == DEV_SEEK) { wake_up_interruptible_sync(&(RQ(index))); } else { wake_up_interruptible(&(RQ(index))); } } if(ret == DEV_SEEK) {Up(index); return -P_ESEEK;} if(ret == DEV_FULL) { W_ABLE(ct) = 0; Up(index); PDEBUG("<%d>: device full, sleep, left %d\n", current->pid, (int)left); Wait_Event(WQ(index), RELEASE(index)||W_ABLE(ct)); if(RELEASE(index)) return count; continue; } Up(index); if(left <= 0) break; } return count; }
void gps_off(void) { uint8_t i; // set the address from which to read/write dev_ioctl(DEV_AVR_I2C, I2C_DEST_ADDR, SWITCH_1); // read the current value dev_read(DEV_AVR_I2C, &i, sizeof(i)); // mask out the appropriate bits i &= (uint8_t)(~GPS_ENABLE_MASK); // write the value back. dev_write(DEV_AVR_I2C, &i, sizeof(i)); // verify that the bits have been cleared. do { i = 0; dev_read(DEV_AVR_I2C, &i, sizeof(i)); }while((i & (GPS_ENABLE_MASK))); }
static void set_cb () { uint32_t addr; uint32_t size; uint8_t reprogram; printf ("Start address? "); addr = prompt_longlong ("#:"); printf ("Image size? "); size = prompt_longlong ("#:"); printf ("Reprogram? "); reprogram = prompt_long ("#:"); boot_control_block_t cb; cb.node_id = mos_node_id_get (); cb.byte_count = size; cb.start_addr = addr; cb.reprogram = reprogram; dev_ioctl (DEV_AVR_EEPROM, DEV_SEEK, CONTROL_BLOCK_ADDR); dev_write (DEV_AVR_EEPROM, (uint8_t *)&cb, CONTROL_BLOCK_SIZE); }
void gps_on(void) { uint8_t i; // set speed dev_ioctl(DEV_AVR_I2C, I2C_SET_BRR, 50); // set the address from which to read/write dev_ioctl(DEV_AVR_I2C, I2C_DEST_ADDR, SWITCH_1); // read the current value dev_read(DEV_AVR_I2C, &i, sizeof(i)); // set the appropriate bits. i |= GPS_ENABLE_MASK; // write the value back dev_write(DEV_AVR_I2C, &i, sizeof(i)); // verify that the bits have been written correctly. do { i = 0; dev_read(DEV_AVR_I2C, &i, sizeof(i)); }while((i & (GPS_ENABLE_MASK)) != GPS_ENABLE_MASK); }
static int devfs_write(struct vfs_node *node, uint32_t offset, uint32_t size, uint8_t *buffer) { int rc = -1; struct dev *d; if (!node->data) { rc = EINVAL; DEBUG(DL_DBG, ("dev(%s) not open.\n", node->name)); goto out; } d = (struct dev *)node->data; rc = dev_write(d, offset, size, buffer); if (rc != 0) { DEBUG(DL_INF, ("write dev(%s) failed.\n", node->name)); goto out; } out: return rc; }
void gps_disable_bits(uint8_t mask) { uint8_t i; // set the address from which to read/write dev_ioctl(DEV_AVR_I2C, I2C_DEST_ADDR, SWITCH_2); // read the current value dev_read(DEV_AVR_I2C, &i, sizeof(i)); // clear the RX/TX bits i &= ~(mask); // write the value back dev_write(DEV_AVR_I2C, &i, sizeof(i)); // verify that the bits have been cleared. do { i = 0; dev_read(DEV_AVR_I2C, &i, sizeof(i)); }while(i & (mask)); // disable rx UCSR1B &= ~(1 << RXEN1); }
void close_filesystem(struct filsys *fs) { unsigned int i; // Release all group descriptors for (i = 0; i < fs->groupdesc_blocks; i++) release_buffer(fs->cache, fs->groupdesc_buffers[i]); free(fs->groupdesc_buffers); free(fs->groups); // Write super block if (fs->super_dirty) dev_write(fs->devno, fs->super, SECTORSIZE, 1); free(fs->super); // Flush buffer cache flush_buffers(fs->cache); // Free cache free_buffer_pool(fs->cache); // Deallocate file system free(fs); }
static void write_buffer(struct bufpool *pool, struct buf *buf) { struct thread *thread; struct thread *next; if (buf->state == BUF_STATE_DIRTY) { // Remove buffer from dirty list if (buf->chain.next) buf->chain.next->chain.prev = buf->chain.prev; if (buf->chain.prev) buf->chain.prev->chain.next = buf->chain.next; if (pool->dirty.head == buf) pool->dirty.head = buf->chain.next; if (pool->dirty.tail == buf) pool->dirty.tail = buf->chain.prev; buf->chain.next = NULL; buf->chain.prev = NULL; // Write block to device from buffer buf->state = BUF_STATE_WRITING; dev_write(pool->devno, buf->data, pool->bufsize, buf->blkno * pool->blks_per_buffer); } // Lock buffer and release all waiters buf->state = BUF_STATE_LOCKED; thread = buf->waiters; while (thread) { buf->locks++; next = thread->next_buffer_waiter; thread->next_buffer_waiter = NULL; #ifdef WIN32 SetEvent(thread->ready); #endif thread = next; } buf->waiters = NULL; }
void setup() { uint8_t i; uint8_t j; i = (1 << 5); uint8_t retval; mos_led_display(7); printf("Setting bit rate reg to 10.\n"); dev_ioctl(DEV_AVR_I2C, I2C_SET_BRR, 50); printf("Setting dest address to 72.\n"); dev_ioctl(DEV_AVR_I2C, I2C_DEST_ADDR, 72); printf("Writing %C to ADG715!\n", i); retval = dev_write(DEV_AVR_I2C, &i, sizeof(i)); printf("Wrote %C bytes.\n", retval); printf("Retrieving current value.\n"); retval = dev_read(DEV_AVR_I2C, &j, sizeof(j)); printf("retval: %C\nCurr Val: %C\n", retval, j); if(i == j) { printf("ADG715 is working properly.\n"); } else { printf("ADG715 returned incorrect value.\n"); } printf("done.\n"); mos_led_display(0); }
void gps_enable_bits(uint8_t mask) { // disable uart1 interrupt UCSR1B &= ~((1 << RXCIE1) | (1 << RXEN1)); // enable rx UCSR1B |= (1 << RXEN1); uint8_t i; // set the address from which to read/write dev_ioctl(DEV_AVR_I2C, I2C_DEST_ADDR, SWITCH_2); // read the current value dev_read(DEV_AVR_I2C, &i, sizeof(i)); // set the RX/TX bits i |= (mask); // write the value back dev_write(DEV_AVR_I2C, &i, sizeof(i)); //overwrite value // verify that the bits have been written correctly. do { i = 0; dev_read(DEV_AVR_I2C, &i, sizeof(i)); }while((i & (mask)) != (mask)); }
static int lfd_linker(void) { int fd1 = lfd_host->rmt_fd; int fd2 = lfd_host->loc_fd; register int len, fl; struct timeval tv; char *buf, *out; fd_set fdset; int maxfd, idle = 0, tmplen; if( !(buf = lfd_alloc(VTUN_FRAME_SIZE + VTUN_FRAME_OVERHEAD)) ){ vtun_syslog(LOG_ERR,"Can't allocate buffer for the linker"); return 0; } /* Delay sending of first UDP packet over broken NAT routers because we will probably be disconnected. Wait for the remote end to send us something first, and use that connection. */ if (!VTUN_USE_NAT_HACK(lfd_host)) proto_write(fd1, buf, VTUN_ECHO_REQ); maxfd = (fd1 > fd2 ? fd1 : fd2) + 1; linker_term = 0; while( !linker_term ){ errno = 0; /* Wait for data */ FD_ZERO(&fdset); FD_SET(fd1, &fdset); FD_SET(fd2, &fdset); tv.tv_sec = lfd_host->ka_interval; tv.tv_usec = 0; if( (len = select(maxfd, &fdset, NULL, NULL, &tv)) < 0 ){ if( errno != EAGAIN && errno != EINTR ) break; else continue; } if( ka_need_verify ){ if( idle > lfd_host->ka_maxfail ){ vtun_syslog(LOG_INFO,"Session %s network timeout", lfd_host->host); break; } if (idle++ > 0) { /* No input frames, check connection with ECHO */ if( proto_write(fd1, buf, VTUN_ECHO_REQ) < 0 ){ vtun_syslog(LOG_ERR,"Failed to send ECHO_REQ"); break; } } ka_need_verify = 0; } if (send_a_packet) { send_a_packet = 0; tmplen = 1; lfd_host->stat.byte_out += tmplen; if( (tmplen=lfd_run_down(tmplen,buf,&out)) == -1 ) break; if( tmplen && proto_write(fd1, out, tmplen) < 0 ) break; lfd_host->stat.comp_out += tmplen; } /* Read frames from network(fd1), decode and pass them to * the local device (fd2) */ if( FD_ISSET(fd1, &fdset) && lfd_check_up() ){ idle = 0; ka_need_verify = 0; if( (len=proto_read(fd1, buf)) <= 0 ) break; /* Handle frame flags */ fl = len & ~VTUN_FSIZE_MASK; len = len & VTUN_FSIZE_MASK; if( fl ){ if( fl==VTUN_BAD_FRAME ){ vtun_syslog(LOG_ERR, "Received bad frame"); continue; } if( fl==VTUN_ECHO_REQ ){ /* Send ECHO reply */ if( proto_write(fd1, buf, VTUN_ECHO_REP) < 0 ) break; continue; } if( fl==VTUN_ECHO_REP ){ /* Just ignore ECHO reply, ka_need_verify==0 already */ continue; } if( fl==VTUN_CONN_CLOSE ){ vtun_syslog(LOG_INFO,"Connection closed by other side"); break; } } lfd_host->stat.comp_in += len; if( (len=lfd_run_up(len,buf,&out)) == -1 ) break; if( len && dev_write(fd2,out,len) < 0 ){ if( errno != EAGAIN && errno != EINTR ) break; else continue; } lfd_host->stat.byte_in += len; } /* Read data from the local device(fd2), encode and pass it to * the network (fd1) */ if( FD_ISSET(fd2, &fdset) && lfd_check_down() ){ if( (len = dev_read(fd2, buf, VTUN_FRAME_SIZE)) < 0 ){ if( errno != EAGAIN && errno != EINTR ) break; else continue; } if( !len ) break; lfd_host->stat.byte_out += len; if( (len=lfd_run_down(len,buf,&out)) == -1 ) break; if( len && proto_write(fd1, out, len) < 0 ) break; lfd_host->stat.comp_out += len; } } if( !linker_term && errno ) vtun_syslog(LOG_INFO,"%s (%d)", strerror(errno), errno); if (linker_term == VTUN_SIG_TERM) { lfd_host->persist = 0; } /* Notify other end about our close */ proto_write(fd1, buf, VTUN_CONN_CLOSE); lfd_free(buf); return 0; }
int __attribute__ ((section (".data"))) reprogram_helper(uint32_t ex_flash_addr, int type) { uint32_t addr = ex_flash_addr; uint16_t c_checksum; uint16_t a_checksum; boolean write = (type == RP_WRITE); if (write) mos_disable_ints(); dev_open(DEV_TELOS_FLASH); dev_mode(DEV_TELOS_FLASH, DEV_MODE_ON); if (!write) printf("verifying...\n"); if (write) erase_flash(0x4000, MSP_FLASH_ERASE_ALL); dev_ioctl(DEV_TELOS_FLASH, DEV_SEEK, addr); dev_read(DEV_TELOS_FLASH, buffer, 6); uint16_t sect_count = *(uint16_t*)(buffer + 4); //printf("%d sectors to write\n", sect_count); //printf("looking for file at %x\n", (uint16_t)ex_flash_addr); uint16_t sect_size; uint16_t sect_addr; // skip past header addr += 6; dev_ioctl(DEV_TELOS_FLASH, DEV_SEEK, addr); int i; for(i = 0; i < sect_count; ++i) { // read the sector size LED_ON(i + 1); dev_ioctl(DEV_TELOS_FLASH, DEV_SEEK, addr); dev_read(DEV_TELOS_FLASH, §_size, 2); addr += 2; dev_ioctl(DEV_TELOS_FLASH, DEV_SEEK, addr); // read the sector address dev_read(DEV_TELOS_FLASH, §_addr, 2); addr += 2; // begin computing checksum; c_checksum = 0; c_checksum ^= sect_size; c_checksum ^= sect_addr; //printf("[%d] %d bytes at address %x\n", i, sect_size, sect_addr); uint16_t blocks = sect_size / MSP_FLASH_BLOCK_SIZE; uint16_t left_over = sect_size % MSP_FLASH_BLOCK_SIZE; while(blocks--) { dev_ioctl(DEV_TELOS_FLASH, DEV_SEEK, addr); dev_read(DEV_TELOS_FLASH, buffer, sizeof(buffer)); msp_flash_address = sect_addr; if (write) dev_write(DEV_MSP_FLASH, buffer, sizeof(buffer)); else { uint16_t* iter = (uint16_t*)buffer; uint16_t* iter_end = (uint16_t*)(buffer + sizeof(buffer)); for( ; iter != iter_end; ++iter) c_checksum ^= *iter; } sect_addr += sizeof(buffer); addr += sizeof(buffer); } if (left_over) { dev_ioctl(DEV_TELOS_FLASH, DEV_SEEK, addr); dev_read(DEV_TELOS_FLASH, buffer, left_over); msp_flash_address = sect_addr; if (write) dev_write(DEV_MSP_FLASH, buffer, left_over); else { uint16_t* iter = (uint16_t*)buffer; uint16_t* iter_end = (uint16_t*)(buffer + left_over); for( ; iter != iter_end; ++iter) c_checksum ^= *iter; } addr += left_over; } dev_ioctl(DEV_TELOS_FLASH, DEV_SEEK, addr); dev_read(DEV_TELOS_FLASH, &a_checksum, sizeof(a_checksum)); //printf("checksum (computed): %x\n checksum (actual): %x\n", c_checksum, a_checksum); if (!write) { if (c_checksum != a_checksum) return FALSE; } addr += 2; dev_ioctl(DEV_TELOS_FLASH, DEV_SEEK, addr); } if (write) asm volatile ("br #0x4000h\n"); // shhh //dev_close(DEV_TELOS_FLASH); return TRUE; }
int dev_write_block(void *buf, __u64 blk_addr) { return dev_write(buf, blk_addr * F2FS_BLKSIZE, F2FS_BLKSIZE); }
int dfs_write(struct file *filp, void *data, size_t size, off64_t pos) { struct inode *inode; size_t written; size_t count; char *p; unsigned int iblock; unsigned int start; blkno_t blk; struct buf *buf; int rc; inode = (struct inode *) filp->data; if (filp->flags & O_APPEND) pos = inode->desc->size; if (pos + size > DFS_MAXFILESIZE) return -EFBIG; if (S_ISDIR(inode->desc->mode)) return -EISDIR; if (pos > inode->desc->size) { rc = dfs_ftruncate(filp, pos); if (rc < 0) return rc; } written = 0; p = (char *) data; while (size > 0) { if (filp->flags & F_CLOSED) return -EINTR; iblock = (unsigned int) pos / inode->fs->blocksize; start = (unsigned int) pos % inode->fs->blocksize; count = inode->fs->blocksize - start; if (count > size) count = size; if (iblock < inode->desc->blocks) { blk = get_inode_block(inode, iblock); if (blk == NOBLOCK) return -EIO; } else if (iblock == inode->desc->blocks) { blk = expand_inode(inode); if (blk == NOBLOCK) return -ENOSPC; } else { return written; } if (filp->flags & O_DIRECT) { if (start != 0 || count != inode->fs->blocksize) return written; if (dev_write(inode->fs->devno, p, count, blk, 0) != (int) count) return written; } else { if (count == inode->fs->blocksize) { buf = alloc_buffer(inode->fs->cache, blk); } else { buf = get_buffer(inode->fs->cache, blk); } if (!buf) return -EIO; memcpy(buf->data + start, p, count); mark_buffer_updated(inode->fs->cache, buf); release_buffer(inode->fs->cache, buf); } filp->flags |= F_MODIFIED; pos += count; p += count; written += count; size -= count; if (pos > inode->desc->size) { inode->desc->size = pos; mark_inode_dirty(inode); } } return written; }
struct filsys *create_filesystem(vfs_devno_t devno, int blocksize, int inode_ratio, int quick) { struct filsys *fs; unsigned int blocks; unsigned int first_block; struct groupdesc *gd; struct buf *buf; unsigned int i, j; vfs_ino_t ino; struct inode *root; char *buffer; // Allocate file system fs = (struct filsys *) malloc(sizeof(struct filsys)); memset(fs, 0, sizeof(struct filsys)); // Allocate super block fs->super = (struct superblock *) malloc(SECTORSIZE); memset(fs->super, 0, SECTORSIZE); fs->super_dirty = 1; // Set device number and block size fs->devno = devno; fs->blocksize = blocksize; // Initialize buffer cache fs->cache = init_buffer_pool(devno, CACHEBUFFERS, fs->blocksize); // Set signature, version and block size in super block fs->super->signature = DFS_SIGNATURE; fs->super->version = DFS_VERSION; fs->super->log_block_size = bits(blocksize); // Each group has as many blocks as can be represented by the block bitmap block fs->super->blocks_per_group = fs->blocksize * 8; // Get the device size in sectors from the device and convert it to blocks fs->super->block_count = dev_getsize(fs->devno) / (fs->blocksize / SECTORSIZE); // Set cache size fs->super->cache_buffers = CACHEBUFFERS; if (fs->super->cache_buffers > fs->super->block_count) fs->super->cache_buffers = 64; // The number of inodes in a group is computed as a ratio of the size of group fs->inodes_per_block = fs->blocksize / sizeof(struct inodedesc); if (fs->super->blocks_per_group < fs->super->block_count) fs->super->inodes_per_group = fs->blocksize * fs->super->blocks_per_group / inode_ratio; else fs->super->inodes_per_group = fs->blocksize * fs->super->block_count / inode_ratio; if (fs->super->inodes_per_group > fs->blocksize * 8) fs->super->inodes_per_group = fs->blocksize * 8; fs->inode_blocks_per_group = (fs->super->inodes_per_group * sizeof(struct inodedesc) + fs->blocksize - 1) / fs->blocksize; // Calculate the number of block pointers per block directory page fs->log_blkptrs_per_block = fs->super->log_block_size - 2; // Calculate the number of group descriptors and the number of blocks to store them fs->super->group_count = (fs->super->block_count + fs->super->blocks_per_group - 1) / fs->super->blocks_per_group; fs->groupdescs_per_block = fs->blocksize / sizeof(struct groupdesc); fs->groupdesc_blocks = (fs->super->group_count * sizeof(struct groupdesc) + fs->blocksize - 1) / fs->blocksize; // The reserved blocks are allocated right after the super block fs->super->first_reserved_block = 1; if (fs->blocksize <= SECTORSIZE) fs->super->first_reserved_block++; fs->super->reserved_blocks = RESERVED_BLOCKS; // The group descriptor table starts after the superblock and reserved blocks fs->super->groupdesc_table_block = fs->super->first_reserved_block + fs->super->reserved_blocks; // If the last group is too small to hold the bitmaps and inode table skip it blocks = fs->super->block_count % fs->super->blocks_per_group; if (blocks > 0 && blocks < fs->inode_blocks_per_group + 2) fs->super->group_count--; if (fs->super->group_count == 0) panic("filesystem too small"); // Zero all blocks on disk if (!quick) { buffer = (char *) malloc(fs->blocksize); memset(buffer, 0, fs->blocksize); for (i = fs->super->groupdesc_table_block + fs->groupdesc_blocks; i < fs->super->block_count; i++) { dev_write(fs->devno, buffer, fs->blocksize, i); } free(buffer); } // Allocate group descriptors fs->groupdesc_buffers = (struct buf **) malloc(sizeof(struct buf *) * fs->groupdesc_blocks); fs->groups = (struct group *) malloc(sizeof(struct group) * fs->super->group_count); for (i = 0; i < fs->groupdesc_blocks; i++) { fs->groupdesc_buffers[i] = alloc_buffer(fs->cache, fs->super->groupdesc_table_block + i); } for (i = 0; i < fs->super->group_count; i++) { gd = (struct groupdesc *) fs->groupdesc_buffers[i / fs->groupdescs_per_block]->data; gd += (i % fs->groupdescs_per_block); fs->groups[i].desc = gd; fs->groups[i].first_free_block = 0; fs->groups[i].first_free_inode = 0; } // Reserve inode for root directory fs->super->reserved_inodes = RESERVED_INODES; // Set inode count based on group count fs->super->inode_count = fs->super->inodes_per_group * fs->super->group_count; // All blocks and inodes initially free fs->super->free_inode_count = fs->super->inode_count; fs->super->free_block_count = fs->super->block_count; // Initialize block bitmaps for (i = 0; i < fs->super->group_count; i++) { gd = fs->groups[i].desc; blocks = 0; first_block = fs->super->blocks_per_group * i; // The first group needs blocks for the super block and the group descriptors if (i == 0) blocks = fs->super->groupdesc_table_block + fs->groupdesc_blocks; // Next blocks in group are the block bitmap, inode bitmap and the inode table gd->block_bitmap_block = first_block + blocks++; gd->inode_bitmap_block = first_block + blocks++; gd->inode_table_block = first_block + blocks; blocks += fs->inode_blocks_per_group; // Update block bitmap buf = alloc_buffer(fs->cache, gd->block_bitmap_block); set_bits(buf->data, 0, blocks); mark_buffer_updated(buf); release_buffer(fs->cache, buf); // Determine the block count for the group. The last group may be truncated if (fs->super->blocks_per_group * (i + 1) > fs->super->block_count) gd->block_count = fs->super->block_count - fs->super->blocks_per_group * i; else gd->block_count = fs->super->blocks_per_group; // Set the count of free blocks and inodes for group gd->free_inode_count = fs->super->inodes_per_group; gd->free_block_count = gd->block_count - blocks; // Update super block fs->super->free_block_count -= blocks; mark_group_desc_dirty(fs, i); } // Zero out block and inode bitmaps and inode tables if (quick) { buffer = (char *) malloc(fs->blocksize); memset(buffer, 0, fs->blocksize); for (i = 0; i < fs->super->group_count; i++) { gd = fs->groups[i].desc; dev_write(fs->devno, buffer, fs->blocksize, gd->block_bitmap_block); dev_write(fs->devno, buffer, fs->blocksize, gd->inode_bitmap_block); for (j = 0; j < fs->inode_blocks_per_group; j++) { dev_write(fs->devno, buffer, fs->blocksize, gd->inode_table_block + j); } } free(buffer); } // Reserve inodes for (i = 0; i < RESERVED_INODES; i++) { ino = new_inode(fs, 0, 0); if (ino != i) panic("unexpected inode"); } // Create root directory root = get_inode(fs, DFS_INODE_ROOT); root->desc->mode = VFS_S_IFDIR | VFS_S_IRWXU | VFS_S_IRWXG | VFS_S_IRWXO; root->desc->ctime = root->desc->mtime = time(NULL); root->desc->linkcount = 1; mark_buffer_updated(root->buf); release_inode(root); return fs; }
/* FIXME Also wipe associated metadata area headers? */ int label_remove(struct device *dev) { #pragma pack(8) char buf[LABEL_SIZE]; //__attribute((aligned(8))); #pragma pack() char readbuf[LABEL_SCAN_SIZE]; //__attribute((aligned(8))); int r = 1; uint64_t sector; int wipe; struct labeller_i *li; struct label_header *lh; memset(buf, 0, LABEL_SIZE); log_very_verbose("Scanning for labels to wipe from %s", dev_name(dev)); if (!dev_open(dev)) { stack; return 0; } /* * We flush the device just in case someone is stupid * enough to be trying to import an open pv into lvm. */ dev_flush(dev); if (!dev_read(dev, UINT64_C(0), LABEL_SCAN_SIZE, readbuf)) { log_debug("%s: Failed to read label area", dev_name(dev)); goto out; } /* Scan first few sectors for anything looking like a label */ for (sector = 0; sector < LABEL_SCAN_SECTORS; sector += LABEL_SIZE >> SECTOR_SHIFT) { lh = (struct label_header *) (readbuf + (sector << SECTOR_SHIFT)); wipe = 0; if (!strncmp((char *)lh->id, LABEL_ID, sizeof(lh->id))) { if (xlate64(lh->sector_xl) == sector) wipe = 1; } else { //list_iterate_items(li, &_labellers) { list_iterate_items(li, struct labeller_i, &_labellers) { if (li->l->ops->can_handle(li->l, (char *) lh, sector)) { wipe = 1; break; } } } if (wipe) { log_info("%s: Wiping label at sector %" PRIu64, dev_name(dev), sector); if (!dev_write(dev, sector << SECTOR_SHIFT, LABEL_SIZE, buf)) { log_error("Failed to remove label from %s at " "sector %" PRIu64, dev_name(dev), sector); r = 0; } } } out: if (!dev_close(dev)) stack; return r; }