linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Steve French" <smfrench@gmail.com>
To: "Christoph Hellwig" <hch@infradead.org>
Cc: "Jeff Layton" <jlayton@redhat.com>,
	linux-cifs-client@lists.samba.org, linux-fsdevel@vger.kernel.org,
	linux-kernel@vger.kernel.org, npiggin@suse.de
Subject: Re: [PATCH] cifs: Convert cifs to new aops.
Date: Wed, 24 Sep 2008 14:34:44 -0500	[thread overview]
Message-ID: <524f69650809241234h427c79f8lac19ff069da9aac4@mail.gmail.com> (raw)
In-Reply-To: <20080924175426.GA12155@infradead.org>

I have reviewed the patch and merged into cifs-2.6.git tree.

Will do some additional testing (with fsx and other test tools) while
at SDC plugfest this week.

On Wed, Sep 24, 2008 at 12:54 PM, Christoph Hellwig <hch@infradead.org> wrote:
> Might be worth Ccing Nick as he's started on finishing the last aops
> conversions again at Kernel Summit.
>
> On Wed, Sep 24, 2008 at 01:39:13PM -0400, Jeff Layton wrote:
>> This patch is based on the one originally posted by Nick Piggin. His
>> patch was very close, but had a couple of small bugs. Nick's original
>> comments follow:
>>
>> ---------------[snip]--------------
>>
>> This is another relatively naive conversion. Always do the read upfront
>> when the page is not uptodate (unless we're in the writethrough path).
>>
>> Fix an uninitialized data exposure where SetPageUptodate was called
>> before the page was uptodate.
>>
>> SetPageUptodate and switch to writeback mode in the case that the full
>> page was dirtied.
>>
>> Signed-off-by: Jeff Layton <jlayton@redhat.com>
>> Reviewed-by: Badari Pulavarty <pbadari@us.ibm.com>
>> Acked-by: Dave Kleikamp <shaggy@linux.vnet.ibm.com>
>> Cc: Steve French <smfrench@gmail.com>
>> Cc: Nick Piggin <npiggin@suse.de>
>> ---
>>  fs/cifs/file.c |  120 +++++++++++++++++++++++++++----------------------------
>>  1 files changed, 59 insertions(+), 61 deletions(-)
>>
>> diff --git a/fs/cifs/file.c b/fs/cifs/file.c
>> index d39e852..c4a8a06 100644
>> --- a/fs/cifs/file.c
>> +++ b/fs/cifs/file.c
>> @@ -107,7 +107,7 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file,
>>
>>       /* want handles we can use to read with first
>>          in the list so we do not have to walk the
>> -        list to search for one in prepare_write */
>> +        list to search for one in write_begin */
>>       if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
>>               list_add_tail(&pCifsFile->flist,
>>                             &pCifsInode->openFileList);
>> @@ -915,7 +915,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
>>  }
>>
>>  static ssize_t cifs_write(struct file *file, const char *write_data,
>> -     size_t write_size, loff_t *poffset)
>> +                       size_t write_size, loff_t *poffset)
>>  {
>>       int rc = 0;
>>       unsigned int bytes_written = 0;
>> @@ -1455,49 +1455,52 @@ static int cifs_writepage(struct page *page, struct writeback_control *wbc)
>>       return rc;
>>  }
>>
>> -static int cifs_commit_write(struct file *file, struct page *page,
>> -     unsigned offset, unsigned to)
>> +static int cifs_write_end(struct file *file, struct address_space *mapping,
>> +                     loff_t pos, unsigned len, unsigned copied,
>> +                     struct page *page, void *fsdata)
>>  {
>> -     int xid;
>> -     int rc = 0;
>> -     struct inode *inode = page->mapping->host;
>> -     loff_t position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
>> -     char *page_data;
>> +     int rc;
>> +     struct inode *inode = mapping->host;
>>
>> -     xid = GetXid();
>> -     cFYI(1, ("commit write for page %p up to position %lld for %d",
>> -              page, position, to));
>> -     spin_lock(&inode->i_lock);
>> -     if (position > inode->i_size)
>> -             i_size_write(inode, position);
>> +     cFYI(1, ("write_end for page %p from pos %lld with %d bytes",
>> +              page, pos, copied));
>> +
>> +     if (!PageUptodate(page) && copied == PAGE_CACHE_SIZE)
>> +             SetPageUptodate(page);
>>
>> -     spin_unlock(&inode->i_lock);
>>       if (!PageUptodate(page)) {
>> -             position =  ((loff_t)page->index << PAGE_CACHE_SHIFT) + offset;
>> -             /* can not rely on (or let) writepage write this data */
>> -             if (to < offset) {
>> -                     cFYI(1, ("Illegal offsets, can not copy from %d to %d",
>> -                             offset, to));
>> -                     FreeXid(xid);
>> -                     return rc;
>> -             }
>> +             char *page_data;
>> +             unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
>> +             int xid;
>> +
>> +             xid = GetXid();
>>               /* this is probably better than directly calling
>>                  partialpage_write since in this function the file handle is
>>                  known which we might as well leverage */
>>               /* BB check if anything else missing out of ppw
>>                  such as updating last write time */
>>               page_data = kmap(page);
>> -             rc = cifs_write(file, page_data + offset, to-offset,
>> -                             &position);
>> -             if (rc > 0)
>> -                     rc = 0;
>> -             /* else if (rc < 0) should we set writebehind rc? */
>> +             rc = cifs_write(file, page_data + offset, copied, &pos);
>> +             /* if (rc < 0) should we set writebehind rc? */
>>               kunmap(page);
>> +
>> +             FreeXid(xid);
>>       } else {
>> +             rc = copied;
>> +             pos += copied;
>>               set_page_dirty(page);
>>       }
>>
>> -     FreeXid(xid);
>> +     if (rc > 0) {
>> +             spin_lock(&inode->i_lock);
>> +             if (pos > inode->i_size)
>> +                     i_size_write(inode, pos);
>> +             spin_unlock(&inode->i_lock);
>> +     }
>> +
>> +     unlock_page(page);
>> +     page_cache_release(page);
>> +
>>       return rc;
>>  }
>>
>> @@ -2043,49 +2046,44 @@ bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file)
>>               return true;
>>  }
>>
>> -static int cifs_prepare_write(struct file *file, struct page *page,
>> -     unsigned from, unsigned to)
>> +static int cifs_write_begin(struct file *file, struct address_space *mapping,
>> +                     loff_t pos, unsigned len, unsigned flags,
>> +                     struct page **pagep, void **fsdata)
>>  {
>> -     int rc = 0;
>> -     loff_t i_size;
>> -     loff_t offset;
>> +     pgoff_t index = pos >> PAGE_CACHE_SHIFT;
>> +     loff_t offset = pos & (PAGE_CACHE_SIZE - 1);
>> +
>> +     cFYI(1, ("write_begin from %lld len %d", (long long)pos, len));
>> +
>> +     *pagep = __grab_cache_page(mapping, index);
>> +     if (!*pagep)
>> +             return -ENOMEM;
>>
>> -     cFYI(1, ("prepare write for page %p from %d to %d", page, from, to));
>> -     if (PageUptodate(page))
>> +     if (PageUptodate(*pagep))
>>               return 0;
>>
>>       /* If we are writing a full page it will be up to date,
>>          no need to read from the server */
>> -     if ((to == PAGE_CACHE_SIZE) && (from == 0)) {
>> -             SetPageUptodate(page);
>> +     if (len == PAGE_CACHE_SIZE && flags & AOP_FLAG_UNINTERRUPTIBLE)
>>               return 0;
>> -     }
>>
>> -     offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
>> -     i_size = i_size_read(page->mapping->host);
>> +     if ((file->f_flags & O_ACCMODE) != O_WRONLY) {
>> +             int rc;
>>
>> -     if ((offset >= i_size) ||
>> -         ((from == 0) && (offset + to) >= i_size)) {
>> -             /*
>> -              * We don't need to read data beyond the end of the file.
>> -              * zero it, and set the page uptodate
>> -              */
>> -             simple_prepare_write(file, page, from, to);
>> -             SetPageUptodate(page);
>> -     } else if ((file->f_flags & O_ACCMODE) != O_WRONLY) {
>>               /* might as well read a page, it is fast enough */
>> -             rc = cifs_readpage_worker(file, page, &offset);
>> +             rc = cifs_readpage_worker(file, *pagep, &offset);
>> +
>> +             /* we do not need to pass errors back
>> +                e.g. if we do not have read access to the file
>> +                because cifs_write_end will attempt synchronous writes
>> +                -- shaggy */
>>       } else {
>>               /* we could try using another file handle if there is one -
>>                  but how would we lock it to prevent close of that handle
>>                  racing with this read? In any case
>> -                this will be written out by commit_write so is fine */
>> +                this will be written out by write_end so is fine */
>>       }
>>
>> -     /* we do not need to pass errors back
>> -        e.g. if we do not have read access to the file
>> -        because cifs_commit_write will do the right thing.  -- shaggy */
>> -
>>       return 0;
>>  }
>>
>> @@ -2094,8 +2092,8 @@ const struct address_space_operations cifs_addr_ops = {
>>       .readpages = cifs_readpages,
>>       .writepage = cifs_writepage,
>>       .writepages = cifs_writepages,
>> -     .prepare_write = cifs_prepare_write,
>> -     .commit_write = cifs_commit_write,
>> +     .write_begin = cifs_write_begin,
>> +     .write_end = cifs_write_end,
>>       .set_page_dirty = __set_page_dirty_nobuffers,
>>       /* .sync_page = cifs_sync_page, */
>>       /* .direct_IO = */
>> @@ -2110,8 +2108,8 @@ const struct address_space_operations cifs_addr_ops_smallbuf = {
>>       .readpage = cifs_readpage,
>>       .writepage = cifs_writepage,
>>       .writepages = cifs_writepages,
>> -     .prepare_write = cifs_prepare_write,
>> -     .commit_write = cifs_commit_write,
>> +     .write_begin = cifs_write_begin,
>> +     .write_end = cifs_write_end,
>>       .set_page_dirty = __set_page_dirty_nobuffers,
>>       /* .sync_page = cifs_sync_page, */
>>       /* .direct_IO = */
>> --
>> 1.5.5.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at  http://www.tux.org/lkml/
> ---end quoted text---
>



-- 
Thanks,

Steve

  reply	other threads:[~2008-09-24 19:34 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-09-24 17:39 [PATCH] cifs: Convert cifs to new aops Jeff Layton
2008-09-24 17:54 ` Christoph Hellwig
2008-09-24 19:34   ` Steve French [this message]
2008-09-24 22:15   ` Badari Pulavarty

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=524f69650809241234h427c79f8lac19ff069da9aac4@mail.gmail.com \
    --to=smfrench@gmail.com \
    --cc=hch@infradead.org \
    --cc=jlayton@redhat.com \
    --cc=linux-cifs-client@lists.samba.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=npiggin@suse.de \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).