dio->i_size = i_size_read(inode); 
direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode, 	const struct iovec *iov, loff_t offset, unsigned long nr_segs, 	unsigned blkbits, get_blocks_t get_blocks, dio_iodone_t end_io,	struct dio *dio){	unsigned long user_addr; 	int seg;	ssize_t ret = 0;	ssize_t ret2;	size_t bytes;	dio->bio = NULL;	dio->inode = inode;	dio->rw = rw;	dio->blkbits = blkbits;	dio->blkfactor = inode->i_blkbits - blkbits;	dio->start_zero_done = 0;	dio->size = 0;	dio->block_in_file = offset >> blkbits;	dio->blocks_available = 0;	dio->cur_page = NULL;	dio->boundary = 0;	dio->reap_counter = 0;	dio->get_blocks = get_blocks;	dio->end_io = end_io;	dio->map_bh.b_private = NULL;	dio->final_block_in_bio = -1;	dio->next_block_for_io = -1;	dio->page_errors = 0;	dio->result = 0;	dio->iocb = iocb;	/*	 * BIO completion state.	 *	 * ->bio_count starts out at one, and we decrement it to zero after all	 * BIOs are submitted.  This to avoid the situation where a really fast	 * (or synchronous) device could take the count to zero while we're	 * still submitting BIOs.	 */	dio->bio_count = 1;	dio->bios_in_flight = 0;	spin_lock_init(&dio->bio_lock);	dio->bio_list = NULL;	dio->waiter = NULL;	/*	 * In case of non-aligned buffers, we may need 2 more	 * pages since we need to zero out first and last block.	 */	if (unlikely(dio->blkfactor))		dio->pages_in_io = 2;	else		dio->pages_in_io = 0;	for (seg = 0; seg < nr_segs; seg++) {		user_addr = (unsigned long)iov[seg].iov_base;		dio->pages_in_io +=			((user_addr+iov[seg].iov_len +PAGE_SIZE-1)/PAGE_SIZE				- user_addr/PAGE_SIZE);	}	for (seg = 0; seg < nr_segs; seg++) {		user_addr = (unsigned long)iov[seg].iov_base;		dio->size += bytes = iov[seg].iov_len;		/* Index into the first page of the first block */		dio->first_block_in_page = (user_addr & ~PAGE_MASK) >> blkbits;		dio->final_block_in_request = dio->block_in_file +						(bytes >> blkbits);		/* Page fetching state */		dio->head = 0;		dio->tail = 0;		dio->curr_page = 0;		dio->total_pages = 0;		if (user_addr & (PAGE_SIZE-1)) {			dio->total_pages++;			bytes -= PAGE_SIZE - (user_addr & (PAGE_SIZE - 1));		}		dio->total_pages += (bytes + PAGE_SIZE - 1) / PAGE_SIZE;		dio->curr_user_address = user_addr;			ret = do_direct_IO(dio);		dio->result += iov[seg].iov_len -			((dio->final_block_in_request - dio->block_in_file) <<					blkbits);		if (ret) {			dio_cleanup(dio);			break;		}	} /* end iovec loop */	if (ret == -ENOTBLK && rw == WRITE) {		/*		 * The remaining part of the request will be		 * be handled by buffered I/O when we return		 */		ret = 0;	}	/*	 * There may be some unwritten disk at the end of a part-written	 * fs-block-sized block.  Go zero that now.	 */	dio_zero_block(dio, 1);	if (dio->cur_page) {		ret2 = dio_send_cur_page(dio);		if (ret == 0)			ret = ret2;		page_cache_release(dio->cur_page);		dio->cur_page = NULL;	}	if (dio->bio)		dio_bio_submit(dio);	/*	 * It is possible that, we return short IO due to end of file.	 * In that case, we need to release all the pages we got hold on.	 */	dio_cleanup(dio);	/*	 * All block lookups have been performed. For READ requests	 * we can let i_sem go now that its achieved its purpose	 * of protecting us from looking up uninitialized blocks.	 */	if ((rw == READ) && (dio->lock_type == DIO_LOCKING))		up(&dio->inode->i_sem);	/*	 * OK, all BIOs are submitted, so we can decrement bio_count to truly	 * reflect the number of to-be-processed BIOs.	 */	if (dio->is_async) {		int should_wait = 0;		if (dio->result < dio->size && rw == WRITE) {			dio->waiter = current;			should_wait = 1;		}		if (ret == 0)			ret = dio->result;		finished_one_bio(dio);		/* This can free the dio */		blk_run_address_space(inode->i_mapping);		if (should_wait) {			unsigned long flags;			/*			 * Wait for already issued I/O to drain out and			 * release its references to user-space pages			 * before returning to fallback on buffered I/O			 */			spin_lock_irqsave(&dio->bio_lock, flags);			set_current_state(TASK_UNINTERRUPTIBLE);			while (dio->bio_count) {				spin_unlock_irqrestore(&dio->bio_lock, flags);				io_schedule();				spin_lock_irqsave(&dio->bio_lock, flags);				set_current_state(TASK_UNINTERRUPTIBLE);			}			spin_unlock_irqrestore(&dio->bio_lock, flags);			set_current_state(TASK_RUNNING);			kfree(dio);		}	} else {		ssize_t transferred = 0;		finished_one_bio(dio);		ret2 = dio_await_completion(dio);		if (ret == 0)			ret = ret2;		if (ret == 0)			ret = dio->page_errors;		if (dio->result) {			loff_t i_size = i_size_read(inode);			transferred = dio->result;			/*			 * Adjust the return value if the read crossed a			 * non-block-aligned EOF.			 */			if (rw == READ && (offset + transferred > i_size))				transferred = i_size - offset;		}		dio_complete(dio, offset, transferred);		if (ret == 0)			ret = transferred;		/* We could have also come here on an AIO file extend */		if (!is_sync_kiocb(iocb) && rw == WRITE &&		    ret >= 0 && dio->result == dio->size)			/*			 * For AIO writes where we have completed the			 * i/o, we have to mark the the aio complete.			 */			aio_complete(iocb, ret, 0);		kfree(dio);	}	return ret;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/29504ff3be784372c4e2f7e31681a3e0292c4d9a/direct-io.c/buggy/fs/direct-io.c