Merge tag 'afs-next-20171113' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 16 Nov 2017 19:41:22 +0000 (11:41 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 16 Nov 2017 19:41:22 +0000 (11:41 -0800)
Pull AFS updates from David Howells:
 "kAFS filesystem driver overhaul.

  The major points of the overhaul are:

   (1) Preliminary groundwork is laid for supporting network-namespacing
       of kAFS. The remainder of the namespacing work requires some way
       to pass namespace information to submounts triggered by an
       automount. This requires something like the mount overhaul that's
       in progress.

   (2) sockaddr_rxrpc is used in preference to in_addr for holding
       addresses internally and add support for talking to the YFS VL
       server. With this, kAFS can do everything over IPv6 as well as
       IPv4 if it's talking to servers that support it.

   (3) Callback handling is overhauled to be generally passive rather
       than active. 'Callbacks' are promises by the server to tell us
       about data and metadata changes. Callbacks are now checked when
       we next touch an inode rather than actively going and looking for
       it where possible.

   (4) File access permit caching is overhauled to store the caching
       information per-inode rather than per-directory, shared over
       subordinate files. Whilst older AFS servers only allow ACLs on
       directories (shared to the files in that directory), newer AFS
       servers break that restriction.

       To improve memory usage and to make it easier to do mass-key
       removal, permit combinations are cached and shared.

   (5) Cell database management is overhauled to allow lighter locks to
       be used and to make cell records autonomous state machines that
       look after getting their own DNS records and cleaning themselves
       up, in particular preventing races in acquiring and relinquishing
       the fscache token for the cell.

   (6) Volume caching is overhauled. The afs_vlocation record is got rid
       of to simplify things and the superblock is now keyed on the cell
       and the numeric volume ID only. The volume record is tied to a
       superblock and normal superblock management is used to mediate
       the lifetime of the volume fscache token.

   (7) File server record caching is overhauled to make server records
       independent of cells and volumes. A server can be in multiple
       cells (in such a case, the administrator must make sure that the
       VL services for all cells correctly reflect the volumes shared
       between those cells).

       Server records are now indexed using the UUID of the server
       rather than the address since a server can have multiple
       addresses.

   (8) File server rotation is overhauled to handle VMOVED, VBUSY (and
       similar), VOFFLINE and VNOVOL indications and to handle rotation
       both of servers and addresses of those servers. The rotation will
       also wait and retry if the server says it is busy.

   (9) Data writeback is overhauled. Each inode no longer stores a list
       of modified sections tagged with the key that authorised it in
       favour of noting the modified region of a page in page->private
       and storing a list of keys that made modifications in the inode.

       This simplifies things and allows other keys to be used to
       actually write to the server if a key that made a modification
       becomes useless.

  (10) Writable mmap() is implemented. This allows a kernel to be build
       entirely on AFS.

  Note that Pre AFS-3.4 servers are no longer supported, though this can
  be added back if necessary (AFS-3.4 was released in 1998)"

* tag 'afs-next-20171113' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs: (35 commits)
  afs: Protect call->state changes against signals
  afs: Trace page dirty/clean
  afs: Implement shared-writeable mmap
  afs: Get rid of the afs_writeback record
  afs: Introduce a file-private data record
  afs: Use a dynamic port if 7001 is in use
  afs: Fix directory read/modify race
  afs: Trace the sending of pages
  afs: Trace the initiation and completion of client calls
  afs: Fix documentation on # vs % prefix in mount source specification
  afs: Fix total-length calculation for multiple-page send
  afs: Only progress call state at end of Tx phase from rxrpc callback
  afs: Make use of the YFS service upgrade to fully support IPv6
  afs: Overhaul volume and server record caching and fileserver rotation
  afs: Move server rotation code into its own file
  afs: Add an address list concept
  afs: Overhaul cell database management
  afs: Overhaul permit caching
  afs: Overhaul the callback handling
  afs: Rename struct afs_call server member to cm_server
  ...

1  2 
drivers/media/platform/qcom/venus/hfi.c
fs/afs/write.c
fs/btrfs/extent-tree.c
mm/filemap.c

diff --cc fs/afs/write.c
@@@ -338,15 -249,136 +249,136 @@@ static void afs_kill_pages(struct addre
  }
  
  /*
-  * synchronously write back the locked page and any subsequent non-locked dirty
-  * pages also covered by the same writeback record
+  * Redirty all the pages in a given range.
+  */
+ static void afs_redirty_pages(struct writeback_control *wbc,
+                             struct address_space *mapping,
+                             pgoff_t first, pgoff_t last)
+ {
+       struct afs_vnode *vnode = AFS_FS_I(mapping->host);
+       struct pagevec pv;
+       unsigned count, loop;
+       _enter("{%x:%u},%lx-%lx",
+              vnode->fid.vid, vnode->fid.vnode, first, last);
 -      pagevec_init(&pv, 0);
++      pagevec_init(&pv);
+       do {
+               _debug("redirty %lx-%lx", first, last);
+               count = last - first + 1;
+               if (count > PAGEVEC_SIZE)
+                       count = PAGEVEC_SIZE;
+               pv.nr = find_get_pages_contig(mapping, first, count, pv.pages);
+               ASSERTCMP(pv.nr, ==, count);
+               for (loop = 0; loop < count; loop++) {
+                       struct page *page = pv.pages[loop];
+                       redirty_page_for_writepage(wbc, page);
+                       end_page_writeback(page);
+                       if (page->index >= first)
+                               first = page->index + 1;
+               }
+               __pagevec_release(&pv);
+       } while (first <= last);
+       _leave("");
+ }
+ /*
+  * write to a file
+  */
+ static int afs_store_data(struct address_space *mapping,
+                         pgoff_t first, pgoff_t last,
+                         unsigned offset, unsigned to)
+ {
+       struct afs_vnode *vnode = AFS_FS_I(mapping->host);
+       struct afs_fs_cursor fc;
+       struct afs_wb_key *wbk = NULL;
+       struct list_head *p;
+       int ret = -ENOKEY, ret2;
+       _enter("%s{%x:%u.%u},%lx,%lx,%x,%x",
+              vnode->volume->name,
+              vnode->fid.vid,
+              vnode->fid.vnode,
+              vnode->fid.unique,
+              first, last, offset, to);
+       spin_lock(&vnode->wb_lock);
+       p = vnode->wb_keys.next;
+       /* Iterate through the list looking for a valid key to use. */
+ try_next_key:
+       while (p != &vnode->wb_keys) {
+               wbk = list_entry(p, struct afs_wb_key, vnode_link);
+               _debug("wbk %u", key_serial(wbk->key));
+               ret2 = key_validate(wbk->key);
+               if (ret2 == 0)
+                       goto found_key;
+               if (ret == -ENOKEY)
+                       ret = ret2;
+               p = p->next;
+       }
+       spin_unlock(&vnode->wb_lock);
+       afs_put_wb_key(wbk);
+       _leave(" = %d [no keys]", ret);
+       return ret;
+ found_key:
+       refcount_inc(&wbk->usage);
+       spin_unlock(&vnode->wb_lock);
+       _debug("USE WB KEY %u", key_serial(wbk->key));
+       ret = -ERESTARTSYS;
+       if (afs_begin_vnode_operation(&fc, vnode, wbk->key)) {
+               while (afs_select_fileserver(&fc)) {
+                       fc.cb_break = vnode->cb_break + vnode->cb_s_break;
+                       afs_fs_store_data(&fc, mapping, first, last, offset, to);
+               }
+               afs_check_for_remote_deletion(&fc, fc.vnode);
+               afs_vnode_commit_status(&fc, vnode, fc.cb_break);
+               ret = afs_end_vnode_operation(&fc);
+       }
+       switch (ret) {
+       case -EACCES:
+       case -EPERM:
+       case -ENOKEY:
+       case -EKEYEXPIRED:
+       case -EKEYREJECTED:
+       case -EKEYREVOKED:
+               _debug("next");
+               spin_lock(&vnode->wb_lock);
+               p = wbk->vnode_link.next;
+               afs_put_wb_key(wbk);
+               goto try_next_key;
+       }
+       afs_put_wb_key(wbk);
+       _leave(" = %d", ret);
+       return ret;
+ }
+ /*
+  * Synchronously write back the locked page and any subsequent non-locked dirty
+  * pages.
   */
- static int afs_write_back_from_locked_page(struct afs_writeback *wb,
-                                          struct page *primary_page)
+ static int afs_write_back_from_locked_page(struct address_space *mapping,
+                                          struct writeback_control *wbc,
+                                          struct page *primary_page,
+                                          pgoff_t final_page)
  {
+       struct afs_vnode *vnode = AFS_FS_I(mapping->host);
        struct page *pages[8], *page;
-       unsigned long count;
-       unsigned n, offset, to;
+       unsigned long count, priv;
+       unsigned n, offset, to, f, t;
        pgoff_t start, first, last;
        int loop, ret;
  
@@@ -600,9 -662,7 +655,7 @@@ void afs_pages_written_back(struct afs_
        _enter("{%x:%u},{%lx-%lx}",
               vnode->fid.vid, vnode->fid.vnode, first, last);
  
-       ASSERT(wb != NULL);
 -      pagevec_init(&pv, 0);
 +      pagevec_init(&pv);
  
        do {
                _debug("done %lx-%lx", first, last);
Simple merge
diff --cc mm/filemap.c
Simple merge