cifs: Add some helper functions
authorDavid Howells <dhowells@redhat.com>
Wed, 6 Apr 2022 18:41:28 +0000 (19:41 +0100)
committerSteve French <stfrench@microsoft.com>
Tue, 14 Feb 2023 23:03:36 +0000 (17:03 -0600)
Add some helper functions to manipulate the folio marks by iterating
through a list of folios held in an xarray rather than using a page list.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Steve French <sfrench@samba.org>
cc: Shyam Prasad N <nspmangalore@gmail.com>
cc: Rohith Surabattula <rohiths.msft@gmail.com>
cc: Jeff Layton <jlayton@kernel.org>
cc: linux-cifs@vger.kernel.org

Link: https://lore.kernel.org/r/164928616583.457102.15157033997163988344.stgit@warthog.procyon.org.uk/
Link: https://lore.kernel.org/r/165211418840.3154751.3090684430628501879.stgit@warthog.procyon.org.uk/
Link: https://lore.kernel.org/r/165348878940.2106726.204291614267188735.stgit@warthog.procyon.org.uk/
Link: https://lore.kernel.org/r/165364825674.3334034.3356201708659748648.stgit@warthog.procyon.org.uk/
Link: https://lore.kernel.org/r/166126394799.708021.10637797063862600488.stgit@warthog.procyon.org.uk/
Link: https://lore.kernel.org/r/166697258147.61150.9940790486999562110.stgit@warthog.procyon.org.uk/
Link: https://lore.kernel.org/r/166732030314.3186319.9209944805565413627.stgit@warthog.procyon.org.uk/
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/cifs/cifsfs.h
fs/cifs/file.c

index 25decebbc478c89a63d7de9b5dd96e59e9c8acaf..ea628da503c68f98e697a37f179f225cce2b23ac 100644 (file)
@@ -113,6 +113,9 @@ extern int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma);
 extern const struct file_operations cifs_dir_ops;
 extern int cifs_dir_open(struct inode *inode, struct file *file);
 extern int cifs_readdir(struct file *file, struct dir_context *ctx);
+extern void cifs_pages_written_back(struct inode *inode, loff_t start, unsigned int len);
+extern void cifs_pages_write_failed(struct inode *inode, loff_t start, unsigned int len);
+extern void cifs_pages_write_redirty(struct inode *inode, loff_t start, unsigned int len);
 
 /* Functions related to dir entries */
 extern const struct dentry_operations cifs_dentry_ops;
index ddf6f572af81edc806466e5996721357f5965b37..09240b8b018a38d02985bea6a0692ac46e8d6bd1 100644 (file)
 #include "cifs_ioctl.h"
 #include "cached_dir.h"
 
+/*
+ * Completion of write to server.
+ */
+void cifs_pages_written_back(struct inode *inode, loff_t start, unsigned int len)
+{
+       struct address_space *mapping = inode->i_mapping;
+       struct folio *folio;
+       pgoff_t end;
+
+       XA_STATE(xas, &mapping->i_pages, start / PAGE_SIZE);
+
+       if (!len)
+               return;
+
+       rcu_read_lock();
+
+       end = (start + len - 1) / PAGE_SIZE;
+       xas_for_each(&xas, folio, end) {
+               if (!folio_test_writeback(folio)) {
+                       WARN_ONCE(1, "bad %x @%llx page %lx %lx\n",
+                                 len, start, folio_index(folio), end);
+                       continue;
+               }
+
+               folio_detach_private(folio);
+               folio_end_writeback(folio);
+       }
+
+       rcu_read_unlock();
+}
+
+/*
+ * Failure of write to server.
+ */
+void cifs_pages_write_failed(struct inode *inode, loff_t start, unsigned int len)
+{
+       struct address_space *mapping = inode->i_mapping;
+       struct folio *folio;
+       pgoff_t end;
+
+       XA_STATE(xas, &mapping->i_pages, start / PAGE_SIZE);
+
+       if (!len)
+               return;
+
+       rcu_read_lock();
+
+       end = (start + len - 1) / PAGE_SIZE;
+       xas_for_each(&xas, folio, end) {
+               if (!folio_test_writeback(folio)) {
+                       WARN_ONCE(1, "bad %x @%llx page %lx %lx\n",
+                                 len, start, folio_index(folio), end);
+                       continue;
+               }
+
+               folio_set_error(folio);
+               folio_end_writeback(folio);
+       }
+
+       rcu_read_unlock();
+}
+
+/*
+ * Redirty pages after a temporary failure.
+ */
+void cifs_pages_write_redirty(struct inode *inode, loff_t start, unsigned int len)
+{
+       struct address_space *mapping = inode->i_mapping;
+       struct folio *folio;
+       pgoff_t end;
+
+       XA_STATE(xas, &mapping->i_pages, start / PAGE_SIZE);
+
+       if (!len)
+               return;
+
+       rcu_read_lock();
+
+       end = (start + len - 1) / PAGE_SIZE;
+       xas_for_each(&xas, folio, end) {
+               if (!folio_test_writeback(folio)) {
+                       WARN_ONCE(1, "bad %x @%llx page %lx %lx\n",
+                                 len, start, folio_index(folio), end);
+                       continue;
+               }
+
+               filemap_dirty_folio(folio->mapping, folio);
+               folio_end_writeback(folio);
+       }
+
+       rcu_read_unlock();
+}
+
 /*
  * Mark as invalid, all open files on tree connections since they
  * were closed when session to server was lost.