Skip to content

Commit

Permalink
cifs: make cifs_readdata_alloc take a work_func_t arg
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jeff Layton authored and Steve French committed May 17, 2012
1 parent 0e93b4b commit 0471ca3
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 53 deletions.
2 changes: 0 additions & 2 deletions fs/cifs/cifsproto.h
Original file line number Diff line number Diff line change
Expand Up @@ -476,8 +476,6 @@ struct cifs_readdata {
struct kvec iov[1];
};

struct cifs_readdata *cifs_readdata_alloc(unsigned int nr_pages);
void cifs_readdata_free(struct cifs_readdata *rdata);
int cifs_async_readv(struct cifs_readdata *rdata);

/* asynchronous write support */
Expand Down
50 changes: 0 additions & 50 deletions fs/cifs/cifssmb.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ static struct {
#endif /* CIFS_POSIX */

/* Forward declarations */
static void cifs_readv_complete(struct work_struct *work);

/* Mark as invalid, all open files on tree connections since they
were closed when session to server was lost */
Expand Down Expand Up @@ -1385,28 +1384,6 @@ CIFSSMBOpen(const int xid, struct cifs_tcon *tcon,
return rc;
}

struct cifs_readdata *
cifs_readdata_alloc(unsigned int nr_pages)
{
struct cifs_readdata *rdata;

/* readdata + 1 kvec for each page */
rdata = kzalloc(sizeof(*rdata) +
sizeof(struct kvec) * nr_pages, GFP_KERNEL);
if (rdata != NULL) {
INIT_WORK(&rdata->work, cifs_readv_complete);
INIT_LIST_HEAD(&rdata->pages);
}
return rdata;
}

void
cifs_readdata_free(struct cifs_readdata *rdata)
{
cifsFileInfo_put(rdata->cfile);
kfree(rdata);
}

/*
* Discard any remaining data in the current SMB. To do this, we borrow the
* current bigbuf.
Expand Down Expand Up @@ -1631,33 +1608,6 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
return length;
}

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 void
cifs_readv_callback(struct mid_q_entry *mid)
{
Expand Down
50 changes: 49 additions & 1 deletion fs/cifs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 0471ca3

Please sign in to comment.