/* * osprd_process_request(d, req) * Called when the user reads or writes a sector. * Should perform the read or write, as appropriate. */ static void osprd_process_request(osprd_info_t *d, struct request *req) { if (!blk_fs_request(req)) { end_request(req, 0); return; } // EXERCISE: Perform the read or write request by copying data between // our data array and the request's buffer. // Hint: The 'struct request' argument tells you what kind of request // this is, and which sectors are being read or written. // Read about 'struct request' in <linux/blkdev.h>. // Consider the 'req->sector', 'req->current_nr_sectors', and // 'req->buffer' members, and the rq_data_dir() function. // Your code here. long int sector_offset = req->sector * SECTOR_SIZE; long int request_size = req->current_nr_sectors * SECTOR_SIZE; if (rq_data_dir(req) == READ) { memcpy(req->buffer, d->data + sector_offset, request_size); } else { memcpy(d->data + sector_offset, req->buffer, request_size); } // eprintk("Should process request...\n"); end_request(req, 1); }
static void simpleblkdrv_do_request(struct request_queue *q) { struct request *req; while ((req = elv_next_request(q)) != NULL) { if ((req->sector + req->current_nr_sectors) << 9 > BLK_BYTES) { printk(KERN_ERR"request error!\n"); end_request(req, 0);/*transfer fail*/ continue; } switch (rq_data_dir(req)) { case READ: memcpy(req->buffer, blkdev_data + (req->sector << 9), req->current_nr_sectors << 9); end_request(req, 1);/*transfer ok*/ break; case WRITE: memcpy(blkdev_data + (req->sector << 9), req->buffer, req->current_nr_sectors << 9); end_request(req, 1);/*transfer ok*/ break; default: /* No default because rq_data_dir(req) is 1 bit */ break; } } }
/* * osprd_process_request(d, req) * Called when the user reads or writes a sector. * Should perform the read or write, as appropriate. */ static void osprd_process_request(osprd_info_t *d, struct request *req) { if (!blk_fs_request(req)) { end_request(req, 0); return; } // EXERCISE: Perform the read or write request by copying data between // our data array and the request's buffer. // Hint: The 'struct request' argument tells you what kind of request // this is, and which sectors are being read or written. // Read about 'struct request' in <linux/blkdev.h>. // Consider the 'req->sector', 'req->current_nr_sectors', and // 'req->buffer' members, and the rq_data_dir() function. // Your code here. unsigned request_type; uint8_t *data_ptr; request_type = rq_data_dir(req); data_ptr = d->data + req->sector * SECTOR_SIZE; //eprintk("passwd_hash: %d\n", d->passwd_hash); if (request_type == READ) { memcpy((void*)req->buffer, (void*)data_ptr, req->current_nr_sectors * SECTOR_SIZE); } else if (request_type == WRITE) { memcpy((void*)data_ptr, (void*)req->buffer, req->current_nr_sectors * SECTOR_SIZE); } //eprintk("Should process request...\n"); end_request(req, 1); }
/* * osprd_process_request(d, req) * Called when the user reads or writes a sector. * Should perform the read or write, as appropriate. */ static void osprd_process_request(osprd_info_t *d, struct request *req) { sector_t offset = req->sector * SECTOR_SIZE; if (!blk_fs_request(req)) { end_request(req, 0); return; } // EXERCISE: Perform the read or write request by copying data between // our data array and the request's buffer. // Hint: The 'struct request' argument tells you what kind of request // this is, and which sectors are being read or written. // Read about 'struct request' in <linux/blkdev.h>. // Consider the 'req->sector', 'req->current_nr_sectors', and // 'req->buffer' members, and the rq_data_dir() function. // Your code here. // Calculate offset per ramdisk if(rq_data_dir(req)==WRITE){ // Write - copy contents of req to d memcpy(&(d->data[offset]), req->buffer, req->current_nr_sectors * SECTOR_SIZE); } else { // Read - copy contents of d to req memcpy(req->buffer, &(d->data[offset]), req->current_nr_sectors * SECTOR_SIZE); } end_request(req, 1); }
static void do_mcd_request(request_queue_t * q) { test2(printk(" do_mcd_request(%ld+%ld)\n", CURRENT->sector, CURRENT->nr_sectors)); mcd_transfer_is_active = 1; while (current_valid()) { mcd_transfer(); if (CURRENT->nr_sectors == 0) { end_request(CURRENT, 1); } else { mcd_buf_out = -1; /* Want to read a block not in buffer */ if (mcd_state == MCD_S_IDLE) { if (!tocUpToDate) { if (updateToc() < 0) { while (current_valid()) end_request(CURRENT, 0); break; } } mcd_state = MCD_S_START; McdTries = 5; mcd_timer.function = mcd_poll; mod_timer(&mcd_timer, jiffies + 1); } break; } } mcd_transfer_is_active = 0; test2(printk(" do_mcd_request ends\n")); }
static void do_pd_write_done( void ) { int unit = pd_unit; long saved_flags; if (pd_wait_for(unit,STAT_READY,"do_pd_write_done") & STAT_ERR) { pi_disconnect(PI); if (pd_retries < PD_MAX_RETRIES) { pd_retries++; pi_do_claimed(PI,do_pd_write_start); return; } spin_lock_irqsave(&io_request_lock,saved_flags); end_request(0); pd_busy = 0; do_pd_request(NULL); spin_unlock_irqrestore(&io_request_lock,saved_flags); return; } pi_disconnect(PI); spin_lock_irqsave(&io_request_lock,saved_flags); end_request(1); pd_busy = 0; do_pd_request(NULL); spin_unlock_irqrestore(&io_request_lock,saved_flags); }
static void Virtual_blkdev_do_request(struct request_queue *q) { struct request *req; while ((req = elv_next_request(q)) != NULL) { if ((req->sector + req->current_nr_sectors) << 9> VIRTUAL_BLKDEV_BYTES) { printk(KERN_ERR VIRTUAL_BLKDEV_DISKNAME": bad request: block=%llu, count=%u\n", (unsigned long long)req->sector, req->current_nr_sectors); end_request(req, 0); continue; }/*endif*/ switch (rq_data_dir(req)) { case READ: memcpy(req->buffer,Virtual_blkdev_data + (req->sector << 9), req->current_nr_sectors << 9); end_request(req, 1); break; case WRITE: memcpy(Virtual_blkdev_data + (req->sector << 9), req->buffer, req->current_nr_sectors << 9); end_request(req, 1); break; default: /* No default because rq_data_dir(req) is 1 bit */ break; } }/*endwhile*/ }
void partition_resolver_simple::handle_pending_requests(std::deque<request_context_ptr>& reqs, error_code err) { for (auto& req : reqs) { if (err == ERR_OK) { rpc_address addr; err = get_address(req->partition_index, addr); if (err == ERR_OK) { end_request(std::move(req), err, addr); } else { call(std::move(req), true); } } else if (err == ERR_HANDLER_NOT_FOUND) { end_request(std::move(req), err, rpc_address()); } else { call(std::move(req), true); } } reqs.clear(); }
/* * osprd_process_request(d, req) * Called when the user reads or writes a sector. * Should perform the read or write, as appropriate. */ static void osprd_process_request(osprd_info_t *d, struct request *req) { void *data_offset; unsigned int data_length; if (!blk_fs_request(req)) { end_request(req, 0); return; } // EXERCISE: Perform the read or write request by copying data between // our data array and the request's buffer. // Hint: The 'struct request' argument tells you what kind of request // this is, and which sectors are being read or written. // Read about 'struct request' in <linux/blkdev.h>. // Consider the 'req->sector', 'req->current_nr_sectors', and // 'req->buffer' members, and the rq_data_dir() function. data_offset = d->data + (SECTOR_SIZE * req->sector); data_length = req->current_nr_sectors * SECTOR_SIZE; // TODO: include a test for out-of-range read/writes if (rq_data_dir(req) == WRITE) memcpy(data_offset, req->buffer, data_length); else if (rq_data_dir(req) == READ) memcpy(req->buffer, data_offset, data_length); else { eprintk("Unrecognized command.\n"); end_request(req, 0); } end_request(req, 1); }
static void request_exemple(request_queue_t * rqueue) { unsigned long secteur_debut; unsigned long nb_secteurs; struct request * rq; while ((rq = elv_next_request(rqueue)) != NULL) { if (! blk_fs_request(rq)) { end_request(rq, 0); continue; } /* * Les numeros de secteurs pour le transfert correspondent * a des secteurs de 512 octets... -> convertir. */ secteur_debut = rq->sector * 512 / lg_sect_exemple; nb_secteurs = rq->current_nr_sectors * 512 / lg_sect_exemple; if (secteur_debut + nb_secteurs > nb_sect_exemple) { end_request(rq,1); continue; } if (rq_data_dir(rq)) /* write */ memmove(& data_exemple[secteur_debut * lg_sect_exemple], rq->buffer, nb_secteurs * lg_sect_exemple); else /* read */ memmove(rq->buffer, & data_exemple[secteur_debut * lg_sect_exemple], nb_secteurs * lg_sect_exemple); end_request(rq, 1); } }
static void mem_block_requeut_fn(struct request_queue* q) { struct request* req = NULL; while(NULL != (req = elv_next_request(q))) { if(req -> sector + req -> current_nr_sectors > get_capacity(req->rq_disk)) { end_request(req,0); // return 0; LogPath(); continue; } // Log("sector:%d,current_nr_sectors:%d",req->sector,req->current_nr_sectors); switch(rq_data_dir(req)) { case READ: { memcpy(req->buffer,g_mem_buf + (req->sector << 9),req->current_nr_sectors << 9); end_request(req,1); break; } case WRITE: { memcpy(g_mem_buf + (req->sector << 9), req->buffer,req->current_nr_sectors << 9); end_request(req,1); break; } default: Log("[Error] Unknown request..."); break; // return 0; } } }
static void do_mbd_request(request_queue_t * q) { int result = 0; struct request *req; while ((req = elv_next_request(q)) != NULL) { int minor = req->rq_disk->first_minor; switch (rq_data_dir(req)) { case READ: result = MamboBogusDiskRead(minor, req->buffer, req->sector, req->current_nr_sectors); break; case WRITE: result = MamboBogusDiskWrite(minor, req->buffer, req->sector, req->current_nr_sectors); }; if (result) end_request(req, 0); /* failure */ else end_request(req, 1); /* success */ } }
static void do_pd_read_drq( void ) { int unit = pd_unit; long saved_flags; while (1) { if (pd_wait_for(unit,STAT_DRQ,"do_pd_read_drq") & STAT_ERR) { pi_disconnect(PI); if (pd_retries < PD_MAX_RETRIES) { pd_retries++; pi_do_claimed(PI,do_pd_read_start); return; } spin_lock_irqsave(&io_request_lock,saved_flags); end_request(0); pd_busy = 0; do_pd_request(NULL); spin_unlock_irqrestore(&io_request_lock,saved_flags); return; } pi_read_block(PI,pd_buf,512); pd_count--; pd_run--; pd_buf += 512; pd_block++; if (!pd_run) break; if (!pd_count) pd_next_buf(unit); } pi_disconnect(PI); spin_lock_irqsave(&io_request_lock,saved_flags); end_request(1); pd_busy = 0; do_pd_request(NULL); spin_unlock_irqrestore(&io_request_lock,saved_flags); }
static void do_z2_request(struct request_queue *q) { struct request *req; while ((req = elv_next_request(q)) != NULL) { unsigned long start = req->sector << 9; unsigned long len = req->current_nr_sectors << 9; if (start + len > z2ram_size) { printk( KERN_ERR DEVICE_NAME ": bad access: block=%lu, count=%u\n", req->sector, req->current_nr_sectors); end_request(req, 0); continue; } while (len) { unsigned long addr = start & Z2RAM_CHUNKMASK; unsigned long size = Z2RAM_CHUNKSIZE - addr; if (len < size) size = len; addr += z2ram_map[ start >> Z2RAM_CHUNKSHIFT ]; if (rq_data_dir(req) == READ) memcpy(req->buffer, (char *)addr, size); else memcpy((char *)addr, req->buffer, size); start += size; len -= size; } end_request(req, 1); } }
static void do_pd_request (request_queue_t * q) { int unit; if (pd_busy) return; repeat: if (QUEUE_EMPTY || (CURRENT->rq_status == RQ_INACTIVE)) return; INIT_REQUEST; pd_dev = minor(CURRENT->rq_dev); pd_unit = unit = DEVICE_NR(CURRENT->rq_dev); pd_block = CURRENT->sector; pd_run = CURRENT->nr_sectors; pd_count = CURRENT->current_nr_sectors; if ((pd_dev >= PD_DEVS) || ((pd_block+pd_count) > pd_hd[pd_dev].nr_sects)) { end_request(0); goto repeat; } pd_cmd = rq_data_dir(CURRENT); pd_buf = CURRENT->buffer; pd_retries = 0; pd_busy = 1; if (pd_cmd == READ) pi_do_claimed(PI,do_pd_read); else if (pd_cmd == WRITE) pi_do_claimed(PI,do_pd_write); else { pd_busy = 0; end_request(0); goto repeat; } }
/* * osprd_process_request(d, req) * Called when the user reads or writes a sector. * Should perform the read or write, as appropriate. */ static void osprd_process_request(osprd_info_t *d, struct request *req) { if (!blk_fs_request(req)) { end_request(req, 0); return; } // EXERCISE: Perform the read or write request by copying data between // our data array and the request's buffer. // Hint: The 'struct request' argument tells you what kind of request // this is, and which sectors are being read or written. // Read about 'struct request' in <linux/blkdev.h>. // Consider the 'req->sector', 'req->current_nr_sectors', and // 'req->buffer' members, and the rq_data_dir() function. // Your code here. int offset = req->sector * SECTOR_SIZE; int bytes = req->current_nr_sectors * SECTOR_SIZE; // current_nr_sectors = number of sectors that is requested // rq_data_dir will tell if its a read or write if (rq_data_dir(req) == WRITE) memcpy(d->data + offset, req->buffer, bytes); else if (rq_data_dir(req) == READ) memcpy(req->buffer, d->data + offset, bytes); else eprintk("Must be read or written"); end_request(req, 1); }
/* * osprd_process_request(d, req) * Called when the user reads or writes a sector. * Should perform the read or write, as appropriate. */ static void osprd_process_request(osprd_info_t *d, struct request *req) { if (!blk_fs_request(req)) { end_request(req, 0); return; } // DONE EXERCISE: Perform the read or write request by copying data between // our data array and the request's buffer. // Hint: The 'struct request' argument tells you what kind of request // this is, and which sectors are being read or written. // Read about 'struct request' in <linux/blkdev.h>. // Consider the 'req->sector', 'req->current_nr_sectors', and // 'req->buffer' members, and the rq_data_dir() function. // Your code here. // compute the offset, set pointer to correct region uint8_t *dataPtr = d->data + (req->sector) * SECTOR_SIZE; // check if it's read or write and copy data unsigned int requestType = rq_data_dir(req); if(requestType == READ) memcpy((void*) req->buffer, (void*)dataPtr, req->current_nr_sectors * SECTOR_SIZE); else if (requestType == WRITE) memcpy((void*)dataPtr, (void*) req->buffer, req->current_nr_sectors * SECTOR_SIZE); //eprintk("Should process request...\n"); end_request(req, 1); }
static void virtualblockdevice_do_request(struct request_queue *q) { struct request *req; // printk(KERN_ALERT "VirtualBlockDevice: Entry virtualblockdevice_do_request !\n"); while( NULL != ( req = elv_next_request( q ) ) ) { if( ( ( req->sector + req->current_nr_sectors ) << 9 ) > VIRTUALBLOCKDEVICE_DISK_CAPACITY ) { printk(KERN_ALERT "VirtualBlockDevice: bad request: start sector: = %llu\t sector count: = %lu \n", (unsigned long long) req->sector, (unsigned long)req->current_nr_sectors); end_request( req, 0 ); continue; } printk(KERN_ALERT "VirtualBlockDevice: request: start sector: = %llu\t sector count: = %lu \n", (unsigned long long) req->sector, (unsigned long)req->current_nr_sectors); switch( rq_data_dir( req ) ) { case READ: memcpy( req->buffer, (virtualblockdevice_data + (req->sector << 9)), (req->current_nr_sectors << 9) ); end_request( req, 1 ); break; case WRITE: memcpy( (virtualblockdevice_data + (req->sector << 9)), req->buffer, (req->current_nr_sectors << 9) ); end_request( req, 1 ); break; default: printk(KERN_ALERT "VirtualBlockDevice: Unknown data direction !\n"); break; } } }
/* * osprd_process_request(d, req) * Called when the user reads or writes a sector. * Should perform the read or write, as appropriate. */ static void osprd_process_request(osprd_info_t *d, struct request *req) { size_t offset; size_t num_bytes; if (!blk_fs_request(req)) { end_request(req, 0); return; } // EXERCISE: Perform the read or write request by copying data between // our data array and the request's buffer. // Hint: The 'struct request' argument tells you what kind of request // this is, and which sectors are being read or written. // Read about 'struct request' in <linux/blkdev.h>. // Consider the 'req->sector', 'req->current_nr_sectors', and // 'req->buffer' members, and the rq_data_dir() function. if (req->sector < 0 || req->sector >= nsectors) { // sector_t is defined as an unsigned long in <linux/types.h> eprintk("Invalid sector requested: [%lu]. max sectors: [%i]\n", (unsigned long)req->sector, nsectors); end_request(req, 0); } offset = req->sector * SECTOR_SIZE; // If the number of requested sectors would reach the end of the disk // use as many sectors as possible until the end is reached if(req->sector + req->current_nr_sectors > nsectors) { num_bytes = (nsectors - req->sector) * SECTOR_SIZE; eprintk("Requested sector [%lu] with [%u] additional sectors.\n", (unsigned long)req->sector, req->current_nr_sectors); eprintk("Using [%u] additional sectors instead.\n", num_bytes / SECTOR_SIZE); } else { num_bytes = req->current_nr_sectors * SECTOR_SIZE; } // According to http://www.makelinux.net/ldd3/chp-16-sect-3 // it is save to dereference req->buffer and write to it. // Note from @ipetkov: I'm not sure if req->buffer needs to // be resized at all, I'm assuming linux will allocate the // memory before the request is sent. No issues are apparent // from the first 8 default test cases. spin_lock(&d->mutex); if(rq_data_dir(req) == READ) memcpy(req->buffer, d->data + offset, num_bytes); else // WRITE memcpy(d->data + offset, req->buffer, num_bytes); spin_unlock(&d->mutex); end_request(req, 1); }
static void start_request(struct floppy_state *fs) { struct request *req; unsigned long x; if (fs->state == idle && fs->wanted) { fs->state = available; wake_up(&fs->wait); return; } while (fs->state == idle && (req = elv_next_request(swim3_queue))) { #if 0 printk("do_fd_req: dev=%s cmd=%d sec=%ld nr_sec=%ld buf=%p\n", req->rq_disk->disk_name, req->cmd, (long)req->sector, req->nr_sectors, req->buffer); printk(" rq_status=%d errors=%d current_nr_sectors=%ld\n", req->rq_status, req->errors, req->current_nr_sectors); #endif if (req->sector < 0 || req->sector >= fs->total_secs) { end_request(req, 0); continue; } if (req->current_nr_sectors == 0) { end_request(req, 1); continue; } if (fs->ejected) { end_request(req, 0); continue; } if (rq_data_dir(req) == WRITE) { if (fs->write_prot < 0) fs->write_prot = swim3_readbit(fs, WRITE_PROT); if (fs->write_prot) { end_request(req, 0); continue; } } /* Do not remove the cast. req->sector is now a sector_t and * can be 64 bits, but it will never go past 32 bits for this * driver anyway, so we can safely cast it down and not have * to do a 64/32 division */ fs->req_cyl = ((long)req->sector) / fs->secpercyl; x = ((long)req->sector) % fs->secpercyl; fs->head = x / fs->secpertrack; fs->req_sector = x % fs->secpertrack + 1; fd_req = req; fs->state = do_transfer; fs->retries = 0; act(fs); } }
static void do_rd_request(void) { register char *buff; rd_sector_t start; /* absolute offset from start of device */ seg_t segnum; /* segment index; segment = rd_segment[segnum].segment */ segext_t offset; /* relative offset (from start of segment) */ int target; while (1) { if (!CURRENT || CURRENT->rq_dev < 0) return; INIT_REQUEST; if (CURRENT == NULL || CURRENT->rq_sector == (sector_t) - 1) return; if (rd_initialised != 1) { end_request(0, CURRENT->rq_dev); continue; } start = (rd_sector_t) CURRENT->rq_sector; buff = CURRENT->rq_buffer; target = DEVICE_NR(CURRENT->rq_dev); debug2("RD: request target: %d, start: %ld\n", target, (long) start); if ((rd_info[target].flags != RD_BUSY) || (start >= rd_info[target].size)) { debug4("RD: bad request on ram%d, flags: %d, size: %d, start: %d\n", target, rd_info[target].flags, rd_info[target].size, start); end_request(0, CURRENT->rq_dev); continue; } offset = start; /* offset from segment start */ segnum = rd_info[target].index; /* we want to know our starting index nr. */ debug1("RD: request index = %d\n", segnum); while (offset > rd_segment[segnum].seg_size) { offset -= rd_segment[segnum].seg_size; /* recalculate offset */ segnum = rd_segment[segnum].next; /* point to next segment in linked list */ } debug5("RD: request entry = %d, segment = 0x%x, offset = %d (%x %x)\n", segnum, rd_segment[segnum].segment, offset, CURRENT->rq_seg, buff); if (CURRENT->rq_cmd == WRITE) { debug1("RD: request writing to %ld\n", (long) start); fmemcpy(rd_segment[segnum].segment, offset * SECTOR_SIZE, CURRENT->rq_seg, buff, 1024); } if (CURRENT->rq_cmd == READ) { debug1("RD_REQUEST reading from %ld\n", start); fmemcpy(CURRENT->rq_seg, buff, rd_segment[segnum].segment, offset * SECTOR_SIZE, 1024); } end_request(1, CURRENT->rq_dev); } }
/* * osprd_process_request(d, req) * Called when the user reads or writes a sector. * Should perform the read or write, as appropriate. */ static void osprd_process_request(osprd_info_t *d, struct request *req) { //BEGIN TUAN unsigned int requestType; uint8_t* dataPtr; //END TUAN /* TUAN: a nonzero return value from blk_fs_request() macro says this is a normal filesystem request. Other types of requests (i.e. packet-mode or device-specific diagnostic operations) are not something that sbd supports, so it simply fails any such request. <linux/blkdev.h> */ if (!blk_fs_request(req)) { end_request(req, 0); return; } // EXERCISE: Perform the read or write request by copying data between // our data array and the request's buffer. // Hint: The 'struct request' argument tells you what kind of request // this is, and which sectors are being read or written. // Read about 'struct request' in <linux/blkdev.h>. // Consider the 'req->sector', 'req->current_nr_sectors', and // 'req->buffer' members, and the rq_data_dir() function. //BEGIN TUAN /* We first need to determine if this is a read or write request The macro rq_data_dir(rq) will tell us whether this is a read or write request */ requestType = rq_data_dir(req); //get pointer to data on disk requested by the user //TUAN: req->sector => next sector to read from or write to // (req->sector)*SECTOR_SIZE => This computes the offset dataPtr = d->data + (req->sector)*SECTOR_SIZE; if (requestType == READ) { //copy contents of data buffer into request's buffer memcpy ((void*)req->buffer, (void*) dataPtr, req->current_nr_sectors * SECTOR_SIZE); } else if (requestType == WRITE) { //copy contents of request buffer into data buffer memcpy((void*) dataPtr, (void*)req->buffer, req->current_nr_sectors * SECTOR_SIZE); } //END TUAN end_request(req, 1); }
/* * osprd_process_request(d, req) * Called when the user reads or writes a sector. * Should perform the read or write, as appropriate. */ static void osprd_process_request(osprd_info_t *d, struct request *req) { // Declare variables at the beginning // Calculate where to starta and the amount of data needed to copy int data_size = req->current_nr_sectors * SECTOR_SIZE; int data_offset = req->sector * SECTOR_SIZE; // Check for a bad request if (!blk_fs_request(req)) { end_request(req, 0); return; } // EXERCISE: Perform the read or write request by copying data between // our data array and the request's buffer. // Hint: The 'struct request' argument tells you what kind of request // this is, and which sectors are being read or written. // Read about 'struct request' in <linux/blkdev.h>. // Consider the 'req->sector', 'req->current_nr_sectors', and // 'req->buffer' members, and the rq_data_dir() function. // Your code here: // Check to see if we are trying to write to nonexistant sectors if(req->sector + req->current_nr_sectors > nsectors) { eprintk("Trying to write to nonexistant sectors\n"); end_request(req, 0); } // Read from the RAMDISK // Copy the data in the requested sectors into the buffer if(rq_data_dir(req) == READ) { memcpy(req->buffer, d->data + data_offset, data_size); } // Write to the RAMDISK // Copy the data in the buffer into the requested sectors else if(rq_data_dir(req) == WRITE) { memcpy(d->data + data_offset, req->buffer, data_size); } // Trying to perform an invalid action else { eprintk("Neither a read nor a write\n"); end_request(req,0); } end_request(req, 1); }
static void start_request(struct floppy_state *fs) { struct request *req; unsigned long x; if (fs->state == idle && fs->wanted) { fs->state = available; wake_up(&fs->wait); return; } while (fs->state == idle && (req = elv_next_request(swim3_queue))) { #if 0 printk("do_fd_req: dev=%s cmd=%d sec=%ld nr_sec=%ld buf=%p\n", req->rq_disk->disk_name, req->cmd, req->sector, req->nr_sectors, req->buffer); printk(" rq_status=%d errors=%d current_nr_sectors=%ld\n", req->rq_status, req->errors, req->current_nr_sectors); #endif if (req->sector < 0 || req->sector >= fs->total_secs) { end_request(req, 0); continue; } if (req->current_nr_sectors == 0) { end_request(req, 1); continue; } if (fs->ejected) { end_request(req, 0); continue; } if (rq_data_dir(req) == WRITE) { if (fs->write_prot < 0) fs->write_prot = swim3_readbit(fs, WRITE_PROT); if (fs->write_prot) { end_request(req, 0); continue; } } fs->req_cyl = req->sector / fs->secpercyl; x = req->sector % fs->secpercyl; fs->head = x / fs->secpertrack; fs->req_sector = x % fs->secpertrack + 1; fd_req = req; fs->state = do_transfer; fs->retries = 0; act(fs); } }
/* * osprd_process_request(d, req) * Called when the user reads or writes a sector. * Should perform the read or write, as appropriate. */ static void osprd_process_request(osprd_info_t *d, struct request *req) { if (!blk_fs_request(req)) { end_request(req, 0); return; } // EXERCISE: Perform the read or write request by copying data between // our data array and the request's buffer. // Hint: The 'struct request' argument tells you what kind of request // this is, and which sectors are being read or written. // Read about 'struct request' in <linux/blkdev.h>. // Consider the 'req->sector', 'req->current_nr_sectors', and // 'req->buffer' members, and the rq_data_dir() function. // // req->sector == Target location // req->current_nr_sectors == Number of sectors in first segment of request // req->buffer == Map of first segment // rq_data_dir() == macro to get data direction(READ or WRITE) // Your code here. int sector = (int)(req->sector); uint8_t *ptr = d->data + (sector * SECTOR_SIZE); int size = (int)(req->current_nr_sectors * SECTOR_SIZE); // DEBUG: just prints that request was received //check that the ptr didn't go "off the end" if (ptr + size > d->data + SECTOR_SIZE*nsectors) { printk(KERN_WARNING "request past the end of the device!\n"); end_request(req, 0); } //just copy the memory from the osprd_info struct to the request (it's a read) switch (rq_data_dir(req)) { case READ: osp_spin_lock(&d->mutex); memcpy(req->buffer, ptr, size); osp_spin_unlock(&d->mutex); break; case WRITE: osp_spin_lock(&d->mutex); memcpy(ptr, req->buffer, size); osp_spin_unlock(&d->mutex); break; default: //error break; } end_request(req, 1); }
static void do_z2_request( request_queue_t * q ) { u_long start, len, addr, size; while ( TRUE ) { INIT_REQUEST; start = CURRENT->sector << 9; len = CURRENT->current_nr_sectors << 9; if ( ( start + len ) > z2ram_size ) { printk( KERN_ERR DEVICE_NAME ": bad access: block=%ld, count=%ld\n", CURRENT->sector, CURRENT->current_nr_sectors); end_request( FALSE ); continue; } if ( ( CURRENT->cmd != READ ) && ( CURRENT->cmd != WRITE ) ) { printk( KERN_ERR DEVICE_NAME ": bad command: %d\n", CURRENT->cmd ); end_request( FALSE ); continue; } while ( len ) { addr = start & Z2RAM_CHUNKMASK; size = Z2RAM_CHUNKSIZE - addr; if ( len < size ) size = len; addr += z2ram_map[ start >> Z2RAM_CHUNKSHIFT ]; if ( CURRENT->cmd == READ ) memcpy( CURRENT->buffer, (char *)addr, size ); else memcpy( (char *)addr, CURRENT->buffer, size ); start += size; len -= size; } end_request( TRUE ); } }
/* * osprd_process_request(d, req) * Called when the user reads or writes a sector. * Should perform the read or write, as appropriate. */ static void osprd_process_request(osprd_info_t *d, struct request *req) { int i; char* data_loc; unsigned long rwsize; data_loc = d->data + req->sector*SECTOR_SIZE; rwsize = req->current_nr_sectors * SECTOR_SIZE; if (!blk_fs_request(req)) { end_request(req, 0); return; } // EXERCISE: Perform the read or write request by copying data between // our data array and the request's buffer. // Hint: The 'struct request' argument tells you what kind of request // this is, and which sectors are being read or written. // Read about 'struct request' in <linux/blkdev.h>. // Consider the 'req->sector', 'req->current_nr_sectors', and // 'req->buffer' members, and the rq_data_dir() function. // Your code here. if(!req->buffer || !data_loc) { end_request(req, 0); return; } if(rq_data_dir(req) == READ) { for(i=0; i < rwsize; i++) { req->buffer[i] = data_loc[i]; } } else if(rq_data_dir(req) == WRITE) { for(i=0; i < rwsize; i++) { data_loc[i] = req->buffer[i]; } } else end_request(req,0); end_request(req, 1); }
static void __do_gscd_request (unsigned long dummy) { unsigned int block,dev; unsigned int nsect; repeat: if (QUEUE_EMPTY || CURRENT->rq_status == RQ_INACTIVE) goto out; INIT_REQUEST; dev = MINOR(CURRENT->rq_dev); block = CURRENT->sector; nsect = CURRENT->nr_sectors; if (QUEUE_EMPTY || CURRENT -> sector == -1) goto out; if (CURRENT -> cmd != READ) { printk("GSCD: bad cmd %d\n", CURRENT -> cmd); end_request(0); goto repeat; } if (MINOR(CURRENT -> rq_dev) != 0) { printk("GSCD: this version supports only one device\n"); end_request(0); goto repeat; } gscd_transfer(); /* if we satisfied the request from the buffer, we're done. */ if (CURRENT -> nr_sectors == 0) { end_request(1); goto repeat; } #ifdef GSCD_DEBUG printk ("GSCD: dev %d, block %d, nsect %d\n", dev, block, nsect ); #endif gscd_read_cmd (); out: return; }
static void do_ramblock_request(request_queue_t * q) { static int r_cnt = 0; static int w_cnt = 0; struct request *req; //printk("do_ramblock_request %d\n", ++cnt); while ((req = elv_next_request(q)) != NULL) { /* 数据传输三要素: 源,目的,长度 */ /* 源/目的: */ unsigned long offset = req->sector * 512; /* 目的/源: */ // req->buffer /* 长度: */ unsigned long len = req->current_nr_sectors * 512; if (rq_data_dir(req) == READ) { //printk("do_ramblock_request read %d\n", ++r_cnt); memcpy(req->buffer, ramblock_buf+offset, len); } else { //printk("do_ramblock_request write %d\n", ++w_cnt); memcpy(ramblock_buf+offset, req->buffer, len); } end_request(req, 1); } }
int send_http_request(int sockfd,const char *hostname,ushort port,const char *filename) { struct http_request_header *request; int ret; request = create_http_header(); init_get_request(request,filename); add_host_header(request,hostname,port); add_request(request,"Accept: ","*/*"); add_request(request,"Connection: ","Close"); end_request(request); ret = socket_sendnbuf(sockfd,request->request_buf,request->offset); if(ret < 0){ close(sockfd); release_http_header(request); return -1; } release_http_header(request); return 0; }