cifs: make cifs_readdata_alloc take a work_func_t arg
We'll need different completion routines for an uncached read. Allow the caller to set the one he needs at allocation time. Also, move most of these functions to file.c so we can make more of them static. Signed-off-by: Jeff Layton <jlayton@redhat.com>
此提交包含在:
@@ -2339,6 +2339,27 @@ ssize_t cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov,
|
||||
return cifs_user_writev(iocb, iov, nr_segs, pos);
|
||||
}
|
||||
|
||||
static struct cifs_readdata *
|
||||
cifs_readdata_alloc(unsigned int nr_vecs, work_func_t complete)
|
||||
{
|
||||
struct cifs_readdata *rdata;
|
||||
|
||||
rdata = kzalloc(sizeof(*rdata) +
|
||||
sizeof(struct kvec) * nr_vecs, GFP_KERNEL);
|
||||
if (rdata != NULL) {
|
||||
INIT_WORK(&rdata->work, complete);
|
||||
INIT_LIST_HEAD(&rdata->pages);
|
||||
}
|
||||
return rdata;
|
||||
}
|
||||
|
||||
static void
|
||||
cifs_readdata_free(struct cifs_readdata *rdata)
|
||||
{
|
||||
cifsFileInfo_put(rdata->cfile);
|
||||
kfree(rdata);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
cifs_iovec_read(struct file *file, const struct iovec *iov,
|
||||
unsigned long nr_segs, loff_t *poffset)
|
||||
@@ -2606,6 +2627,33 @@ int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void
|
||||
cifs_readv_complete(struct work_struct *work)
|
||||
{
|
||||
struct cifs_readdata *rdata = container_of(work,
|
||||
struct cifs_readdata, work);
|
||||
struct page *page, *tpage;
|
||||
|
||||
list_for_each_entry_safe(page, tpage, &rdata->pages, lru) {
|
||||
list_del(&page->lru);
|
||||
lru_cache_add_file(page);
|
||||
|
||||
if (rdata->result == 0) {
|
||||
kunmap(page);
|
||||
flush_dcache_page(page);
|
||||
SetPageUptodate(page);
|
||||
}
|
||||
|
||||
unlock_page(page);
|
||||
|
||||
if (rdata->result == 0)
|
||||
cifs_readpage_to_fscache(rdata->mapping->host, page);
|
||||
|
||||
page_cache_release(page);
|
||||
}
|
||||
cifs_readdata_free(rdata);
|
||||
}
|
||||
|
||||
static int cifs_readpages(struct file *file, struct address_space *mapping,
|
||||
struct list_head *page_list, unsigned num_pages)
|
||||
{
|
||||
@@ -2708,7 +2756,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
|
||||
nr_pages++;
|
||||
}
|
||||
|
||||
rdata = cifs_readdata_alloc(nr_pages);
|
||||
rdata = cifs_readdata_alloc(nr_pages, cifs_readv_complete);
|
||||
if (!rdata) {
|
||||
/* best to give up if we're out of mem */
|
||||
list_for_each_entry_safe(page, tpage, &tmplist, lru) {
|
||||
|
新增問題並參考
封鎖使用者