kernels/linux-2.4.0/fs/nfs/write.c
/*
 * Try to update any existing write request, or create one if there is none.
 * In order to match, the request's credentials must match those of
 * the calling process.
 *
 * Note: Should always be called with the Page Lock held!
 */
Try to update any existing write request, or create one if there is none.
In order to match, the request's credentials must match those of
the calling process.

Should always be called with the Page Lock held!
Try to update any existing write request or create one if there is none . In order to match the request ' s credentials must match those of the calling process . Should always be called with the Page Lock held!
static struct nfs_page *
nfs_update_request(struct file* file, struct inode *inode, struct page *page,
		   unsigned int offset, unsigned int bytes)
{
	struct nfs_page		*req, *new = NULL;
	unsigned long		rqend, end;
	end = offset + bytes;
	for (;;) {
		spin_lock(&nfs_wreq_lock);
		req = _nfs_find_request(inode, page);
		if (req) {
			if (!nfs_lock_request(req)) {
				spin_unlock(&nfs_wreq_lock);
				nfs_wait_on_request(req);
				nfs_release_request(req);
				continue;
			}
			spin_unlock(&nfs_wreq_lock);
			if (new)
				nfs_release_request(new);
			break;
		}
		req = new;
		if (req) {
			nfs_lock_request(req);
			nfs_inode_add_request(inode, req);
			spin_unlock(&nfs_wreq_lock);
			nfs_mark_request_dirty(req);
			break;
		}
		spin_unlock(&nfs_wreq_lock);
		if (inode->u.nfs_i.npages >= MAX_REQUEST_SOFT)
			nfs_wb_file(inode, file);
		new = nfs_create_request(file, inode, page, offset, bytes);
		if (!new)
			return ERR_PTR(-ENOMEM);
		if (region_locked(inode, new))
			new->wb_timeout = jiffies + NFS_WRITEBACK_LOCKDELAY;
		else
			new->wb_timeout = jiffies + NFS_WRITEBACK_DELAY;
	}
	rqend = req->wb_offset + req->wb_bytes;
	if (req->wb_file != file
	    || req->wb_page != page
	    || !nfs_dirty_request(req)
	    || offset > rqend || end < req->wb_offset) {
		nfs_unlock_request(req);
		nfs_release_request(req);
		return ERR_PTR(-EBUSY);
	}
	if (offset < req->wb_offset) {
		req->wb_offset = offset;
		req->wb_bytes = rqend - req->wb_offset;
	}
	if (end > rqend)
		req->wb_bytes = end - req->wb_offset;
	nfs_unlock_request(req);
	return req;
}
static struct nfs_page * nfs_update_request ( struct file * file , struct inode * inode , struct page * page , unsigned int offset , unsigned int bytes ) { struct nfs_page * req , * new = NULL ; unsigned long rqend , end ; end = offset + bytes ; for ( ; ; ) { spin_lock ( & nfs_wreq_lock ) ; req = _nfs_find_request ( inode , page ) ; if ( req ) { if ( ! nfs_lock_request ( req ) ) { spin_unlock ( & nfs_wreq_lock ) ; nfs_wait_on_request ( req ) ; nfs_release_request ( req ) ; continue ; } spin_unlock ( & nfs_wreq_lock ) ; if ( new ) nfs_release_request ( new ) ; break ; } req = new ; if ( req ) { nfs_lock_request ( req ) ; nfs_inode_add_request ( inode , req ) ; spin_unlock ( & nfs_wreq_lock ) ; nfs_mark_request_dirty ( req ) ; break ; } spin_unlock ( & nfs_wreq_lock ) ; if ( inode -> u . nfs_i . npages >= MAX_REQUEST_SOFT ) nfs_wb_file ( inode , file ) ; new = nfs_create_request ( file , inode , page , offset , bytes ) ; if ( ! new ) return ERR_PTR ( - ENOMEM ) ; if ( region_locked ( inode , new ) ) new -> wb_timeout = jiffies + NFS_WRITEBACK_LOCKDELAY ; else new -> wb_timeout = jiffies + NFS_WRITEBACK_DELAY ; } rqend = req -> wb_offset + req -> wb_bytes ; if ( req -> wb_file != file || req -> wb_page != page || ! nfs_dirty_request ( req ) || offset > rqend || end < req -> wb_offset ) { nfs_unlock_request ( req ) ; nfs_release_request ( req ) ; return ERR_PTR ( - EBUSY ) ; } if ( offset < req -> wb_offset ) { req -> wb_offset = offset ; req -> wb_bytes = rqend - req -> wb_offset ; } if ( end > rqend ) req -> wb_bytes = end - req -> wb_offset ; nfs_unlock_request ( req ) ; return req ; }
Try to update any existing write request, or create one if there is none.
Try to update any existing write request or create one if there is none .
/* Loop over all inode entries and see if we find
		 * A request for the page we wish to update
		 */ /*
		 * If we're over the soft limit, flush out old requests
		 */ /* If the region is locked, adjust the timeout */ /* We have a request for our page.
	 * If the creds don't match, or the
	 * page addresses don't match,
	 * tell the caller to wait on the conflicting
	 * request.
	 */ /* Okay, the request matches. Update the region */