All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pavel Shilovsky <piastryyy-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
To: Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Cc: smfrench-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
	linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [PATCH 2/5] cifs: add cifs_async_readv
Date: Tue, 11 Oct 2011 14:51:56 +0400	[thread overview]
Message-ID: <CAKywueSoKaAQhZ8Ru0HnxyMbuRHT4a4eiUnrh3-da0idT5w-Bg@mail.gmail.com> (raw)
In-Reply-To: <20111011062617.25376724-9yPaYZwiELC+kQycOl6kW4xkIHaj4LzF@public.gmane.org>

2011/10/11 Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>:
> On Tue, 11 Oct 2011 13:30:14 +0400
> Pavel Shilovsky <piastryyy-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
>> 2011/9/6 Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>:
>> > ...which will allow cifs to do an asynchronous read call to the server.
>> > The caller will allocate and set up cifs_readdata for each READ_AND_X
>> > call that should be issued on the wire. The pages passed in are added
>> > to the pagecache, but not placed on the LRU list yet (as we need the
>> > page->lru to keep the pages on the list in the readdata).
>> >
>> > When cifsd identifies the mid, it will see that there is a special
>> > receive handler for the call, and use that to receive the rest of the
>> > frame. cifs_readv_receive will then marshal up a kvec array with
>> > kmapped pages from the pagecache, which eliminates one copy of the
>> > data. Once the data is received, the pages are added to the LRU list,
>> > set uptodate, and unlocked.
>> >
>> > Signed-off-by: Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>> > ---
>> >  fs/cifs/cifsproto.h |   24 ++++
>> >  fs/cifs/cifssmb.c   |  356 +++++++++++++++++++++++++++++++++++++++++++++++++++
>> >  fs/cifs/connect.c   |   26 ++--
>> >  3 files changed, 393 insertions(+), 13 deletions(-)
>> >
>> > diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
>> > index 51c0ebc..38406e5 100644
>> > --- a/fs/cifs/cifsproto.h
>> > +++ b/fs/cifs/cifsproto.h
>> > @@ -152,6 +152,12 @@ extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *,
>> >  extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *,
>> >                                const char *);
>> >
>> > +extern void dequeue_mid(struct mid_q_entry *mid, bool malformed);
>> > +extern int cifs_read_from_socket(struct TCP_Server_Info *server, char *buf,
>> > +                    unsigned int to_read);
>> > +extern int cifs_readv_from_socket(struct TCP_Server_Info *server,
>> > +               struct kvec *iov_orig, unsigned int nr_segs,
>> > +               unsigned int to_read);
>> >  extern void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
>> >                               struct cifs_sb_info *cifs_sb);
>> >  extern int cifs_match_super(struct super_block *, void *);
>> > @@ -441,6 +447,24 @@ extern int E_md4hash(const unsigned char *passwd, unsigned char *p16);
>> >  extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8,
>> >                        unsigned char *p24);
>> >
>> > +/* asynchronous read support */
>> > +struct cifs_readdata {
>> > +       struct cifsFileInfo             *cfile;
>> > +       struct address_space            *mapping;
>> > +       __u64                           offset;
>> > +       unsigned int                    bytes;
>> > +       pid_t                           pid;
>> > +       int                             result;
>> > +       struct list_head                pages;
>> > +       struct work_struct              work;
>> > +       unsigned int                    nr_iov;
>> > +       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 */
>> >  struct cifs_writedata {
>> >        struct kref                     refcount;
>> > diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
>> > index ae1ce01..ac72f28 100644
>> > --- a/fs/cifs/cifssmb.c
>> > +++ b/fs/cifs/cifssmb.c
>> > @@ -33,6 +33,8 @@
>> >  #include <linux/slab.h>
>> >  #include <linux/posix_acl_xattr.h>
>> >  #include <linux/pagemap.h>
>> > +#include <linux/swap.h>
>> > +#include <linux/task_io_accounting_ops.h>
>> >  #include <asm/uaccess.h>
>> >  #include "cifspdu.h"
>> >  #include "cifsglob.h"
>> > @@ -40,6 +42,7 @@
>> >  #include "cifsproto.h"
>> >  #include "cifs_unicode.h"
>> >  #include "cifs_debug.h"
>> > +#include "fscache.h"
>> >
>> >  #ifdef CONFIG_CIFS_POSIX
>> >  static struct {
>> > @@ -83,6 +86,9 @@ static struct {
>> >  #endif /* CONFIG_CIFS_WEAK_PW_HASH */
>> >  #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 */
>> >  static void mark_open_files_invalid(struct cifs_tcon *pTcon)
>> > @@ -1375,6 +1381,356 @@ openRetry:
>> >        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.
>> > + */
>> > +static int
>> > +cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
>> > +{
>> > +       READ_RSP *rsp = (READ_RSP *)server->smallbuf;
>> > +       unsigned int rfclen = be32_to_cpu(rsp->hdr.smb_buf_length);
>> > +       int remaining = rfclen + 4 - server->total_read;
>> > +       struct cifs_readdata *rdata = mid->callback_data;
>> > +
>> > +       while (remaining > 0) {
>> > +               int length;
>> > +
>> > +               length = cifs_read_from_socket(server, server->bigbuf,
>> > +                               min_t(unsigned int, remaining,
>> > +                                       CIFSMaxBufSize + MAX_CIFS_HDR_SIZE));
>> > +               if (length < 0)
>> > +                       return length;
>> > +               server->total_read += length;
>> > +               remaining -= length;
>> > +       }
>> > +
>> > +       dequeue_mid(mid, rdata->result);
>> > +       return 0;
>> > +}
>> > +
>> > +static int
>> > +cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
>> > +{
>> > +       int length, len;
>> > +       unsigned int data_offset, remaining, data_len;
>> > +       struct cifs_readdata *rdata = mid->callback_data;
>> > +       READ_RSP *rsp = (READ_RSP *)server->smallbuf;
>> > +       unsigned int rfclen = be32_to_cpu(rsp->hdr.smb_buf_length) + 4;
>> > +       u64 eof;
>> > +       pgoff_t eof_index;
>> > +       struct page *page, *tpage;
>> > +
>> > +       cFYI(1, "%s: mid=%u offset=%llu bytes=%u", __func__,
>> > +               mid->mid, rdata->offset, rdata->bytes);
>> > +
>> > +       /*
>> > +        * read the rest of READ_RSP header (sans Data array), or whatever we
>> > +        * can if there's not enough data. At this point, we've read down to
>> > +        * the Mid.
>> > +        */
>> > +       len = min_t(unsigned int, rfclen, sizeof(*rsp)) -
>> > +                       sizeof(struct smb_hdr) + 1;
>> > +
>> > +       rdata->iov[0].iov_base = server->smallbuf + sizeof(struct smb_hdr) - 1;
>> > +       rdata->iov[0].iov_len = len;
>> > +
>> > +       length = cifs_readv_from_socket(server, rdata->iov, 1, len);
>> > +       if (length < 0)
>> > +               return length;
>> > +       server->total_read += length;
>> > +
>> > +       /* Was the SMB read successful? */
>> > +       rdata->result = map_smb_to_linux_error(&rsp->hdr, false);
>> > +       if (rdata->result != 0) {
>> > +               cFYI(1, "%s: server returned error %d", __func__,
>> > +                       rdata->result);
>> > +               return cifs_readv_discard(server, mid);
>> > +       }
>> > +
>> > +       /* Is there enough to get to the rest of the READ_RSP header? */
>> > +       if (server->total_read < sizeof(READ_RSP)) {
>> > +               cFYI(1, "%s: server returned short header. got=%u expected=%lu",
>> > +                       __func__, server->total_read, sizeof(READ_RSP));
>>
>> sizeof should be casted to unsigned long to prevent compiler warnings.
>>
>
> Actually...I think what I need to do here and in the other places you
> pointed out is to use "%z". I'll fix and respin.
>
> Thanks for the review...
> --
> Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>

No problem. Yes, %z is ok too.

-- 
Best regards,
Pavel Shilovsky.

  parent reply	other threads:[~2011-10-11 10:51 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-09-06 14:27 [PATCH 0/5] cifs: allow cifs to do readpages larger and asynchronously (try #5) Jeff Layton
     [not found] ` <1315319241-21637-1-git-send-email-jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2011-09-06 14:27   ` [PATCH 1/5] cifs: fix protocol definition for READ_RSP Jeff Layton
2011-09-06 14:27   ` [PATCH 2/5] cifs: add cifs_async_readv Jeff Layton
     [not found]     ` <1315319241-21637-3-git-send-email-jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2011-10-11  9:30       ` Pavel Shilovsky
     [not found]         ` <CAKywueRSTX8BT3BJymT+PdCEkVbzCEd+mV=UZa0e3-PZLej7qw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-10-11 10:26           ` Jeff Layton
     [not found]             ` <20111011062617.25376724-9yPaYZwiELC+kQycOl6kW4xkIHaj4LzF@public.gmane.org>
2011-10-11 10:51               ` Pavel Shilovsky [this message]
2011-09-06 14:27   ` [PATCH 3/5] cifs: convert cifs_readpages to use async reads Jeff Layton
2011-09-06 14:27   ` [PATCH 4/5] cifs: allow for larger rsize= options and change defaults Jeff Layton
     [not found]     ` <1315319241-21637-5-git-send-email-jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2011-10-11  9:17       ` Pavel Shilovsky
     [not found]         ` <CAKywueTHW1mR1gpO27Kxhxuy++bpMu4R8V=inr4-+gtDWa3ceQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-10-11 10:20           ` Jeff Layton
2011-09-06 14:27   ` [PATCH 5/5] cifs: tune bdi.ra_pages in accordance with the rsize Jeff Layton
  -- strict thread matches above, loose matches on Subject: below --
2011-10-19 13:24 [PATCH 0/5] cifs: allow cifs to do readpages larger and asynchronously (try #7) Jeff Layton
     [not found] ` <1319030695-4115-1-git-send-email-jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2011-10-19 13:24   ` [PATCH 2/5] cifs: add cifs_async_readv Jeff Layton
2011-10-11 12:35 [PATCH 0/5] cifs: allow cifs to do readpages larger and asynchronously (try #6) Jeff Layton
     [not found] ` <1318336527-13648-1-git-send-email-jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2011-10-11 12:35   ` [PATCH 2/5] cifs: add cifs_async_readv Jeff Layton
     [not found]     ` <1318336527-13648-3-git-send-email-jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2011-10-19 10:01       ` Pavel Shilovsky
     [not found]         ` <CAKywueR=sXusGdOuAvJHTk1FGURHuDXjj6gz4iJRYeu=Zgkfpg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-10-19 10:59           ` Jeff Layton
2011-09-01 21:29 [PATCH 0/5] cifs: allow cifs to do readpages larger and asynchronously (try #4) Jeff Layton
     [not found] ` <1314912588-20435-1-git-send-email-jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2011-09-01 21:29   ` [PATCH 2/5] cifs: add cifs_async_readv Jeff Layton
2011-08-30 14:46 [PATCH 0/5] cifs: allow cifs to do readpages larger and asynchronously (try #3) Jeff Layton
     [not found] ` <1314715574-23431-1-git-send-email-jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2011-08-30 14:46   ` [PATCH 2/5] cifs: add cifs_async_readv Jeff Layton
2011-08-26 19:18 [PATCH 0/5] cifs: allow cifs to do readpages larger and asynchronously Jeff Layton
     [not found] ` <1314386298-27424-1-git-send-email-jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2011-08-26 19:18   ` [PATCH 2/5] cifs: add cifs_async_readv Jeff Layton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAKywueSoKaAQhZ8Ru0HnxyMbuRHT4a4eiUnrh3-da0idT5w-Bg@mail.gmail.com \
    --to=piastryyy-re5jqeeqqe8avxtiumwx3w@public.gmane.org \
    --cc=jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
    --cc=linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=smfrench-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.