/** * nfs_create_request - Create an NFS read/write request. * @ctx: open context to use * @inode: inode to which the request is attached * @page: page to write * @offset: starting offset within the page for the write * @count: number of bytes to read/write * * The page must be locked by the caller. This makes sure we never * create two different requests for the same page. * User should ensure it is safe to sleep in this function. */ struct nfs_page * nfs_create_request(struct nfs_open_context *ctx, struct inode *inode, struct page *page, unsigned int offset, unsigned int count) { struct nfs_page *req; struct nfs_lock_context *l_ctx; /* try to allocate the request struct */ req = nfs_page_alloc(); if (req == NULL) return ERR_PTR(-ENOMEM); /* get lock context early so we can deal with alloc failures */ l_ctx = nfs_get_lock_context(ctx); if (IS_ERR(l_ctx)) { nfs_page_free(req); return ERR_CAST(l_ctx); } req->wb_lock_context = l_ctx; /* Initialize the request struct. Initially, we assume a * long write-back delay. This will be adjusted in * update_nfs_request below if the region is not locked. */ req->wb_page = page; req->wb_index = page_file_index(page); page_cache_get(page); req->wb_offset = offset; req->wb_pgbase = offset; req->wb_bytes = count; req->wb_context = get_nfs_open_context(ctx); kref_init(&req->wb_kref); return req; }
/** * nfs_release_request - Release the count on an NFS read/write request * @req: request to release * * Note: Should never be called with the spinlock held! */ static void nfs_free_request(struct kref *kref) { struct nfs_page *req = container_of(kref, struct nfs_page, wb_kref); /* Release struct file and open context */ nfs_clear_request(req); nfs_page_free(req); }
/** * nfs_release_request - Release the count on an NFS read/write request * @req: request to release * * Note: Should never be called with the spinlock held! */ static void nfs_free_request(struct kref *kref) { struct nfs_page *req = container_of(kref, struct nfs_page, wb_kref); /* Release struct file or cached credential */ nfs_clear_request(req); put_nfs_open_context(req->wb_context); nfs_page_free(req); }
/** * nfs_release_request - Release the count on an NFS read/write request * @req: request to release * * Note: Should never be called with the spinlock held! */ void nfs_free_request(struct nfs_page *req) { WARN_ON_ONCE(req->wb_this_page != req); /* extra debug: make sure no sync bits are still set */ WARN_ON_ONCE(test_bit(PG_TEARDOWN, &req->wb_flags)); WARN_ON_ONCE(test_bit(PG_UNLOCKPAGE, &req->wb_flags)); WARN_ON_ONCE(test_bit(PG_UPTODATE, &req->wb_flags)); WARN_ON_ONCE(test_bit(PG_WB_END, &req->wb_flags)); WARN_ON_ONCE(test_bit(PG_REMOVE, &req->wb_flags)); /* Release struct file and open context */ nfs_clear_request(req); nfs_page_free(req); }
/** * nfs_release_request - Release the count on an NFS read/write request * @req: request to release * * Note: Should never be called with the spinlock held! */ void nfs_release_request(struct nfs_page *req) { if (!atomic_dec_and_test(&req->wb_count)) return; #ifdef NFS_PARANOIA BUG_ON (!list_empty(&req->wb_list)); BUG_ON (NFS_WBACK_BUSY(req)); #endif /* Release struct file or cached credential */ nfs_clear_request(req); put_nfs_open_context(req->wb_context); nfs_page_free(req); }
/** * nfs_create_request - Create an NFS read/write request. * @file: file descriptor to use * @inode: inode to which the request is attached * @page: page to write * @offset: starting offset within the page for the write * @count: number of bytes to read/write * * The page must be locked by the caller. This makes sure we never * create two different requests for the same page. * User should ensure it is safe to sleep in this function. */ struct nfs_page * nfs_create_request(struct nfs_open_context *ctx, struct inode *inode, struct page *page, unsigned int offset, unsigned int count) { struct nfs_page *req; /* try to allocate the request struct */ req = nfs_page_alloc(); if (req == NULL) return ERR_PTR(-ENOMEM); /* get lock context early so we can deal with alloc failures */ req->wb_lock_context = nfs_get_lock_context(ctx); if (req->wb_lock_context == NULL) { nfs_page_free(req); return ERR_PTR(-ENOMEM); } /* Initialize the request struct. Initially, we assume a * long write-back delay. This will be adjusted in * update_nfs_request below if the region is not locked. */ req->wb_page = page; atomic_set(&req->wb_complete, 0); req->wb_index = page->index; page_cache_get(page); BUG_ON(PagePrivate(page)); BUG_ON(!PageLocked(page)); BUG_ON(page->mapping->host != inode); req->wb_offset = offset; req->wb_pgbase = offset; req->wb_bytes = count; req->wb_context = get_nfs_open_context(ctx); kref_init(&req->wb_kref); return req; }