* [PATCH 1/9] orangefs: Do not truncate file size
2025-02-24 18:05 [PATCH 0/9] Orangefs fixes for 6.15 Matthew Wilcox (Oracle)
@ 2025-02-24 18:05 ` Matthew Wilcox (Oracle)
2025-02-24 18:05 ` [PATCH 2/9] orangefs: Move s_kmod_keyword_mask_map to orangefs-debugfs.c Matthew Wilcox (Oracle)
` (8 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Matthew Wilcox (Oracle) @ 2025-02-24 18:05 UTC (permalink / raw)
To: Mike Marshall
Cc: Matthew Wilcox (Oracle), Martin Brandenburg, devel, linux-fsdevel
'len' is used to store the result of i_size_read(), so making 'len'
a size_t results in truncation to 4GiB on 32-bit systems.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/orangefs/inode.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c
index aae6d2b8767d..63d7c1ca0dfd 100644
--- a/fs/orangefs/inode.c
+++ b/fs/orangefs/inode.c
@@ -23,9 +23,9 @@ static int orangefs_writepage_locked(struct page *page,
struct orangefs_write_range *wr = NULL;
struct iov_iter iter;
struct bio_vec bv;
- size_t len, wlen;
+ size_t wlen;
ssize_t ret;
- loff_t off;
+ loff_t len, off;
set_page_writeback(page);
@@ -91,8 +91,7 @@ static int orangefs_writepages_work(struct orangefs_writepages *ow,
struct orangefs_write_range *wrp, wr;
struct iov_iter iter;
ssize_t ret;
- size_t len;
- loff_t off;
+ loff_t len, off;
int i;
len = i_size_read(inode);
--
2.47.2
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 2/9] orangefs: Move s_kmod_keyword_mask_map to orangefs-debugfs.c
2025-02-24 18:05 [PATCH 0/9] Orangefs fixes for 6.15 Matthew Wilcox (Oracle)
2025-02-24 18:05 ` [PATCH 1/9] orangefs: Do not truncate file size Matthew Wilcox (Oracle)
@ 2025-02-24 18:05 ` Matthew Wilcox (Oracle)
2025-02-24 18:05 ` [PATCH 3/9] orangefs: make open_for_read and open_for_write boolean Matthew Wilcox (Oracle)
` (7 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Matthew Wilcox (Oracle) @ 2025-02-24 18:05 UTC (permalink / raw)
To: Mike Marshall
Cc: Matthew Wilcox (Oracle), Martin Brandenburg, devel, linux-fsdevel
Attempting to build orangefs with W=1 currently reports errors like:
In file included from ../fs/orangefs/protocol.h:287,
from ../fs/orangefs/waitqueue.c:16:
../fs/orangefs/orangefs-debug.h:86:18: error: ‘num_kmod_keyword_mask_map’ defined but not used [-Werror=unused-const-variable=]
Move num_kmod_keyword_mask_map, s_kmod_keyword_mask_map and
struct __keyword_mask_s to orangefs-debugfs.c which is the only file
they're used in.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/orangefs/orangefs-debug.h | 43 ----------------------------------
fs/orangefs/orangefs-debugfs.c | 43 ++++++++++++++++++++++++++++++++++
2 files changed, 43 insertions(+), 43 deletions(-)
diff --git a/fs/orangefs/orangefs-debug.h b/fs/orangefs/orangefs-debug.h
index 6e079d4230d0..d4463534cec6 100644
--- a/fs/orangefs/orangefs-debug.h
+++ b/fs/orangefs/orangefs-debug.h
@@ -43,47 +43,4 @@
#define GOSSIP_MAX_NR 16
#define GOSSIP_MAX_DEBUG (((__u64)1 << GOSSIP_MAX_NR) - 1)
-/* a private internal type */
-struct __keyword_mask_s {
- const char *keyword;
- __u64 mask_val;
-};
-
-/*
- * Map all kmod keywords to kmod debug masks here. Keep this
- * structure "packed":
- *
- * "all" is always last...
- *
- * keyword mask_val index
- * foo 1 0
- * bar 2 1
- * baz 4 2
- * qux 8 3
- * . . .
- */
-static struct __keyword_mask_s s_kmod_keyword_mask_map[] = {
- {"super", GOSSIP_SUPER_DEBUG},
- {"inode", GOSSIP_INODE_DEBUG},
- {"file", GOSSIP_FILE_DEBUG},
- {"dir", GOSSIP_DIR_DEBUG},
- {"utils", GOSSIP_UTILS_DEBUG},
- {"wait", GOSSIP_WAIT_DEBUG},
- {"acl", GOSSIP_ACL_DEBUG},
- {"dcache", GOSSIP_DCACHE_DEBUG},
- {"dev", GOSSIP_DEV_DEBUG},
- {"name", GOSSIP_NAME_DEBUG},
- {"bufmap", GOSSIP_BUFMAP_DEBUG},
- {"cache", GOSSIP_CACHE_DEBUG},
- {"debugfs", GOSSIP_DEBUGFS_DEBUG},
- {"xattr", GOSSIP_XATTR_DEBUG},
- {"init", GOSSIP_INIT_DEBUG},
- {"sysfs", GOSSIP_SYSFS_DEBUG},
- {"none", GOSSIP_NO_DEBUG},
- {"all", GOSSIP_MAX_DEBUG}
-};
-
-static const int num_kmod_keyword_mask_map = (int)
- (ARRAY_SIZE(s_kmod_keyword_mask_map));
-
#endif /* __ORANGEFS_DEBUG_H */
diff --git a/fs/orangefs/orangefs-debugfs.c b/fs/orangefs/orangefs-debugfs.c
index f52073022fae..f7095c91660c 100644
--- a/fs/orangefs/orangefs-debugfs.c
+++ b/fs/orangefs/orangefs-debugfs.c
@@ -44,6 +44,49 @@
#include "protocol.h"
#include "orangefs-kernel.h"
+/* a private internal type */
+struct __keyword_mask_s {
+ const char *keyword;
+ __u64 mask_val;
+};
+
+/*
+ * Map all kmod keywords to kmod debug masks here. Keep this
+ * structure "packed":
+ *
+ * "all" is always last...
+ *
+ * keyword mask_val index
+ * foo 1 0
+ * bar 2 1
+ * baz 4 2
+ * qux 8 3
+ * . . .
+ */
+static struct __keyword_mask_s s_kmod_keyword_mask_map[] = {
+ {"super", GOSSIP_SUPER_DEBUG},
+ {"inode", GOSSIP_INODE_DEBUG},
+ {"file", GOSSIP_FILE_DEBUG},
+ {"dir", GOSSIP_DIR_DEBUG},
+ {"utils", GOSSIP_UTILS_DEBUG},
+ {"wait", GOSSIP_WAIT_DEBUG},
+ {"acl", GOSSIP_ACL_DEBUG},
+ {"dcache", GOSSIP_DCACHE_DEBUG},
+ {"dev", GOSSIP_DEV_DEBUG},
+ {"name", GOSSIP_NAME_DEBUG},
+ {"bufmap", GOSSIP_BUFMAP_DEBUG},
+ {"cache", GOSSIP_CACHE_DEBUG},
+ {"debugfs", GOSSIP_DEBUGFS_DEBUG},
+ {"xattr", GOSSIP_XATTR_DEBUG},
+ {"init", GOSSIP_INIT_DEBUG},
+ {"sysfs", GOSSIP_SYSFS_DEBUG},
+ {"none", GOSSIP_NO_DEBUG},
+ {"all", GOSSIP_MAX_DEBUG}
+};
+
+static const int num_kmod_keyword_mask_map = (int)
+ (ARRAY_SIZE(s_kmod_keyword_mask_map));
+
#define DEBUG_HELP_STRING_SIZE 4096
#define HELP_STRING_UNINITIALIZED \
"Client Debug Keywords are unknown until the first time\n" \
--
2.47.2
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 3/9] orangefs: make open_for_read and open_for_write boolean
2025-02-24 18:05 [PATCH 0/9] Orangefs fixes for 6.15 Matthew Wilcox (Oracle)
2025-02-24 18:05 ` [PATCH 1/9] orangefs: Do not truncate file size Matthew Wilcox (Oracle)
2025-02-24 18:05 ` [PATCH 2/9] orangefs: Move s_kmod_keyword_mask_map to orangefs-debugfs.c Matthew Wilcox (Oracle)
@ 2025-02-24 18:05 ` Matthew Wilcox (Oracle)
2025-02-26 15:50 ` Matthew Wilcox
2025-02-24 18:05 ` [PATCH 4/9] orangefs: Remove orangefs_writepage() Matthew Wilcox (Oracle)
` (6 subsequent siblings)
9 siblings, 1 reply; 13+ messages in thread
From: Matthew Wilcox (Oracle) @ 2025-02-24 18:05 UTC (permalink / raw)
To: Mike Marshall
Cc: Matthew Wilcox (Oracle), Martin Brandenburg, devel, linux-fsdevel
sparse currently warns:
fs/orangefs/file.c:119:32: warning: incorrect type in assignment (different base types)
fs/orangefs/file.c:119:32: expected int open_for_write
fs/orangefs/file.c:119:32: got restricted fmode_t
Turning open_for_write and open_for_read into booleans (which is how
they're used) removes this warning.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/orangefs/file.c | 4 ++--
include/linux/mm_types.h | 6 +++---
include/linux/nfs_page.h | 2 +-
include/linux/page-flags.h | 6 +++---
4 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c
index d68372241b30..90c49c0de243 100644
--- a/fs/orangefs/file.c
+++ b/fs/orangefs/file.c
@@ -57,8 +57,8 @@ ssize_t wait_for_direct_io(enum ORANGEFS_io_type type, struct inode *inode,
int buffer_index;
ssize_t ret;
size_t copy_amount;
- int open_for_read;
- int open_for_write;
+ bool open_for_read;
+ bool open_for_write;
new_op = op_alloc(ORANGEFS_VFS_OP_FILE_IO);
if (!new_op)
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index e1f23c3429c9..0ca9feec67b8 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -101,7 +101,7 @@ struct page {
struct list_head pcp_list;
};
/* See page-flags.h for PAGE_MAPPING_FLAGS */
- struct address_space *mapping;
+ struct address_space *__folio_mapping;
union {
pgoff_t __folio_index; /* Our offset within mapping. */
unsigned long share; /* share count for fsdax */
@@ -403,7 +403,7 @@ struct folio {
static_assert(offsetof(struct page, pg) == offsetof(struct folio, fl))
FOLIO_MATCH(flags, flags);
FOLIO_MATCH(lru, lru);
-FOLIO_MATCH(mapping, mapping);
+FOLIO_MATCH(__folio_mapping, mapping);
FOLIO_MATCH(compound_head, lru);
FOLIO_MATCH(__folio_index, index);
FOLIO_MATCH(private, private);
@@ -499,7 +499,7 @@ struct ptdesc {
TABLE_MATCH(flags, __page_flags);
TABLE_MATCH(compound_head, pt_list);
TABLE_MATCH(compound_head, _pt_pad_1);
-TABLE_MATCH(mapping, __page_mapping);
+TABLE_MATCH(__folio_mapping, __page_mapping);
TABLE_MATCH(__folio_index, pt_index);
TABLE_MATCH(rcu_head, pt_rcu_head);
TABLE_MATCH(page_type, __page_type);
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index 169b4ae30ff4..0db50ce065cb 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -205,7 +205,7 @@ static inline struct inode *nfs_page_to_inode(const struct nfs_page *req)
struct folio *folio = nfs_page_to_folio(req);
if (folio == NULL)
- return req->wb_page->mapping->host;
+ return req->wb_folio->mapping->host;
return folio->mapping->host;
}
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 36d283552f80..796fabeae46f 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -675,7 +675,7 @@ PAGEFLAG_FALSE(VmemmapSelfHosted, vmemmap_self_hosted)
/*
* Different with flags above, this flag is used only for fsdax mode. It
- * indicates that this page->mapping is now under reflink case.
+ * indicates that this folio->mapping is now under reflink case.
*/
#define PAGE_MAPPING_DAX_SHARED ((void *)0x1)
@@ -686,7 +686,7 @@ static __always_inline bool folio_mapping_flags(const struct folio *folio)
static __always_inline bool PageMappingFlags(const struct page *page)
{
- return ((unsigned long)page->mapping & PAGE_MAPPING_FLAGS) != 0;
+ return ((unsigned long)page->__folio_mapping & PAGE_MAPPING_FLAGS) != 0;
}
static __always_inline bool folio_test_anon(const struct folio *folio)
@@ -714,7 +714,7 @@ static __always_inline bool __folio_test_movable(const struct folio *folio)
static __always_inline bool __PageMovable(const struct page *page)
{
- return ((unsigned long)page->mapping & PAGE_MAPPING_FLAGS) ==
+ return ((unsigned long)page->__folio_mapping & PAGE_MAPPING_FLAGS) ==
PAGE_MAPPING_MOVABLE;
}
--
2.47.2
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 4/9] orangefs: Remove orangefs_writepage()
2025-02-24 18:05 [PATCH 0/9] Orangefs fixes for 6.15 Matthew Wilcox (Oracle)
` (2 preceding siblings ...)
2025-02-24 18:05 ` [PATCH 3/9] orangefs: make open_for_read and open_for_write boolean Matthew Wilcox (Oracle)
@ 2025-02-24 18:05 ` Matthew Wilcox (Oracle)
2025-02-24 18:05 ` [PATCH 5/9] orangefs: Convert orangefs_writepage_locked() to take a folio Matthew Wilcox (Oracle)
` (5 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Matthew Wilcox (Oracle) @ 2025-02-24 18:05 UTC (permalink / raw)
To: Mike Marshall
Cc: Matthew Wilcox (Oracle), Martin Brandenburg, devel, linux-fsdevel
If we add a migrate_folio operation, we can remove orangefs_writepage
(as there is already a writepages operation). filemap_migrate_folio()
will do fine as struct orangefs_write_range does not need to be adjusted
when the folio is migrated.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/orangefs/inode.c | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c
index 63d7c1ca0dfd..4ad049d5cc9c 100644
--- a/fs/orangefs/inode.c
+++ b/fs/orangefs/inode.c
@@ -64,15 +64,6 @@ static int orangefs_writepage_locked(struct page *page,
return ret;
}
-static int orangefs_writepage(struct page *page, struct writeback_control *wbc)
-{
- int ret;
- ret = orangefs_writepage_locked(page, wbc);
- unlock_page(page);
- end_page_writeback(page);
- return ret;
-}
-
struct orangefs_writepages {
loff_t off;
size_t len;
@@ -605,7 +596,6 @@ static ssize_t orangefs_direct_IO(struct kiocb *iocb,
/** ORANGEFS2 implementation of address space operations */
static const struct address_space_operations orangefs_address_operations = {
- .writepage = orangefs_writepage,
.readahead = orangefs_readahead,
.read_folio = orangefs_read_folio,
.writepages = orangefs_writepages,
@@ -615,6 +605,7 @@ static const struct address_space_operations orangefs_address_operations = {
.invalidate_folio = orangefs_invalidate_folio,
.release_folio = orangefs_release_folio,
.free_folio = orangefs_free_folio,
+ .migrate_folio = filemap_migrate_folio,
.launder_folio = orangefs_launder_folio,
.direct_IO = orangefs_direct_IO,
};
--
2.47.2
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 5/9] orangefs: Convert orangefs_writepage_locked() to take a folio
2025-02-24 18:05 [PATCH 0/9] Orangefs fixes for 6.15 Matthew Wilcox (Oracle)
` (3 preceding siblings ...)
2025-02-24 18:05 ` [PATCH 4/9] orangefs: Remove orangefs_writepage() Matthew Wilcox (Oracle)
@ 2025-02-24 18:05 ` Matthew Wilcox (Oracle)
2025-02-24 18:05 ` [PATCH 6/9] orangefs: Pass mapping to orangefs_writepages_work() Matthew Wilcox (Oracle)
` (4 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Matthew Wilcox (Oracle) @ 2025-02-24 18:05 UTC (permalink / raw)
To: Mike Marshall
Cc: Matthew Wilcox (Oracle), Martin Brandenburg, devel, linux-fsdevel
Both callers have a folio, pass it in and use it inside
orangefs_writepage_locked(). Removes a few hidden calls to
compound_head() and accesses to page->mapping.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/orangefs/inode.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c
index 4ad049d5cc9c..90db1d705fe8 100644
--- a/fs/orangefs/inode.c
+++ b/fs/orangefs/inode.c
@@ -16,10 +16,10 @@
#include "orangefs-kernel.h"
#include "orangefs-bufmap.h"
-static int orangefs_writepage_locked(struct page *page,
- struct writeback_control *wbc)
+static int orangefs_writepage_locked(struct folio *folio,
+ struct writeback_control *wbc)
{
- struct inode *inode = page->mapping->host;
+ struct inode *inode = folio->mapping->host;
struct orangefs_write_range *wr = NULL;
struct iov_iter iter;
struct bio_vec bv;
@@ -27,11 +27,11 @@ static int orangefs_writepage_locked(struct page *page,
ssize_t ret;
loff_t len, off;
- set_page_writeback(page);
+ folio_start_writeback(folio);
len = i_size_read(inode);
- if (PagePrivate(page)) {
- wr = (struct orangefs_write_range *)page_private(page);
+ if (folio->private) {
+ wr = folio->private;
WARN_ON(wr->pos >= len);
off = wr->pos;
if (off + wr->len > len)
@@ -40,27 +40,27 @@ static int orangefs_writepage_locked(struct page *page,
wlen = wr->len;
} else {
WARN_ON(1);
- off = page_offset(page);
- if (off + PAGE_SIZE > len)
+ off = folio_pos(folio);
+ wlen = folio_size(folio);
+
+ if (wlen > len - off)
wlen = len - off;
- else
- wlen = PAGE_SIZE;
}
/* Should've been handled in orangefs_invalidate_folio. */
WARN_ON(off == len || off + wlen > len);
WARN_ON(wlen == 0);
- bvec_set_page(&bv, page, wlen, off % PAGE_SIZE);
+ bvec_set_folio(&bv, folio, wlen, offset_in_folio(folio, off));
iov_iter_bvec(&iter, ITER_SOURCE, &bv, 1, wlen);
ret = wait_for_direct_io(ORANGEFS_IO_WRITE, inode, &off, &iter, wlen,
len, wr, NULL, NULL);
if (ret < 0) {
- mapping_set_error(page->mapping, ret);
+ mapping_set_error(folio->mapping, ret);
} else {
ret = 0;
}
- kfree(detach_page_private(page));
+ kfree(folio_detach_private(folio));
return ret;
}
@@ -179,7 +179,7 @@ static int orangefs_writepages_callback(struct folio *folio,
orangefs_writepages_work(ow, wbc);
ow->npages = 0;
}
- ret = orangefs_writepage_locked(&folio->page, wbc);
+ ret = orangefs_writepage_locked(folio, wbc);
mapping_set_error(folio->mapping, ret);
folio_unlock(folio);
folio_end_writeback(folio);
@@ -474,7 +474,7 @@ static int orangefs_launder_folio(struct folio *folio)
};
folio_wait_writeback(folio);
if (folio_clear_dirty_for_io(folio)) {
- r = orangefs_writepage_locked(&folio->page, &wbc);
+ r = orangefs_writepage_locked(folio, &wbc);
folio_end_writeback(folio);
}
return r;
--
2.47.2
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 6/9] orangefs: Pass mapping to orangefs_writepages_work()
2025-02-24 18:05 [PATCH 0/9] Orangefs fixes for 6.15 Matthew Wilcox (Oracle)
` (4 preceding siblings ...)
2025-02-24 18:05 ` [PATCH 5/9] orangefs: Convert orangefs_writepage_locked() to take a folio Matthew Wilcox (Oracle)
@ 2025-02-24 18:05 ` Matthew Wilcox (Oracle)
2025-02-24 18:05 ` [PATCH 7/9] orangefs: Unify error & success paths in orangefs_writepages_work() Matthew Wilcox (Oracle)
` (3 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Matthew Wilcox (Oracle) @ 2025-02-24 18:05 UTC (permalink / raw)
To: Mike Marshall
Cc: Matthew Wilcox (Oracle), Martin Brandenburg, devel, linux-fsdevel
Remove two accesses to page->mapping by passing the mapping from
orangefs_writepages() to orangefs_writepages_callback() and then
orangefs_writepages_work(). That makes it obvious that all folios come
from the same mapping, so we can hoist the call to mapping_set_error()
outside the loop. While I'm here, switch from write_cache_pages()
to writeback_iter() which removes an indirect function call.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/orangefs/inode.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c
index 90db1d705fe8..879d96c11b1c 100644
--- a/fs/orangefs/inode.c
+++ b/fs/orangefs/inode.c
@@ -71,14 +71,15 @@ struct orangefs_writepages {
kgid_t gid;
int maxpages;
int npages;
+ struct address_space *mapping;
struct page **pages;
struct bio_vec *bv;
};
static int orangefs_writepages_work(struct orangefs_writepages *ow,
- struct writeback_control *wbc)
+ struct writeback_control *wbc)
{
- struct inode *inode = ow->pages[0]->mapping->host;
+ struct inode *inode = ow->mapping->host;
struct orangefs_write_range *wrp, wr;
struct iov_iter iter;
ssize_t ret;
@@ -107,8 +108,8 @@ static int orangefs_writepages_work(struct orangefs_writepages *ow,
ret = wait_for_direct_io(ORANGEFS_IO_WRITE, inode, &off, &iter, ow->len,
0, &wr, NULL, NULL);
if (ret < 0) {
+ mapping_set_error(ow->mapping, ret);
for (i = 0; i < ow->npages; i++) {
- mapping_set_error(ow->pages[i]->mapping, ret);
if (PagePrivate(ow->pages[i])) {
wrp = (struct orangefs_write_range *)
page_private(ow->pages[i]);
@@ -137,9 +138,8 @@ static int orangefs_writepages_work(struct orangefs_writepages *ow,
}
static int orangefs_writepages_callback(struct folio *folio,
- struct writeback_control *wbc, void *data)
+ struct writeback_control *wbc, struct orangefs_writepages *ow)
{
- struct orangefs_writepages *ow = data;
struct orangefs_write_range *wr = folio->private;
int ret;
@@ -197,7 +197,9 @@ static int orangefs_writepages(struct address_space *mapping,
{
struct orangefs_writepages *ow;
struct blk_plug plug;
- int ret;
+ int error;
+ struct folio *folio = NULL;
+
ow = kzalloc(sizeof(struct orangefs_writepages), GFP_KERNEL);
if (!ow)
return -ENOMEM;
@@ -213,15 +215,17 @@ static int orangefs_writepages(struct address_space *mapping,
kfree(ow);
return -ENOMEM;
}
+ ow->mapping = mapping;
blk_start_plug(&plug);
- ret = write_cache_pages(mapping, wbc, orangefs_writepages_callback, ow);
+ while ((folio = writeback_iter(mapping, wbc, folio, &error)))
+ error = orangefs_writepages_callback(folio, wbc, ow);
if (ow->npages)
- ret = orangefs_writepages_work(ow, wbc);
+ error = orangefs_writepages_work(ow, wbc);
blk_finish_plug(&plug);
kfree(ow->pages);
kfree(ow->bv);
kfree(ow);
- return ret;
+ return error;
}
static int orangefs_launder_folio(struct folio *);
--
2.47.2
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 7/9] orangefs: Unify error & success paths in orangefs_writepages_work()
2025-02-24 18:05 [PATCH 0/9] Orangefs fixes for 6.15 Matthew Wilcox (Oracle)
` (5 preceding siblings ...)
2025-02-24 18:05 ` [PATCH 6/9] orangefs: Pass mapping to orangefs_writepages_work() Matthew Wilcox (Oracle)
@ 2025-02-24 18:05 ` Matthew Wilcox (Oracle)
2025-02-24 18:05 ` [PATCH 8/9] orangefs: Simplify bvec setup " Matthew Wilcox (Oracle)
` (2 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Matthew Wilcox (Oracle) @ 2025-02-24 18:05 UTC (permalink / raw)
To: Mike Marshall
Cc: Matthew Wilcox (Oracle), Martin Brandenburg, devel, linux-fsdevel
Both arms of this conditional now have the same loop, so sink it out
of the conditional.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/orangefs/inode.c | 36 +++++++++++++-----------------------
1 file changed, 13 insertions(+), 23 deletions(-)
diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c
index 879d96c11b1c..927c2829976c 100644
--- a/fs/orangefs/inode.c
+++ b/fs/orangefs/inode.c
@@ -107,33 +107,23 @@ static int orangefs_writepages_work(struct orangefs_writepages *ow,
wr.gid = ow->gid;
ret = wait_for_direct_io(ORANGEFS_IO_WRITE, inode, &off, &iter, ow->len,
0, &wr, NULL, NULL);
- if (ret < 0) {
+ if (ret < 0)
mapping_set_error(ow->mapping, ret);
- for (i = 0; i < ow->npages; i++) {
- if (PagePrivate(ow->pages[i])) {
- wrp = (struct orangefs_write_range *)
- page_private(ow->pages[i]);
- ClearPagePrivate(ow->pages[i]);
- put_page(ow->pages[i]);
- kfree(wrp);
- }
- end_page_writeback(ow->pages[i]);
- unlock_page(ow->pages[i]);
- }
- } else {
+ else
ret = 0;
- for (i = 0; i < ow->npages; i++) {
- if (PagePrivate(ow->pages[i])) {
- wrp = (struct orangefs_write_range *)
- page_private(ow->pages[i]);
- ClearPagePrivate(ow->pages[i]);
- put_page(ow->pages[i]);
- kfree(wrp);
- }
- end_page_writeback(ow->pages[i]);
- unlock_page(ow->pages[i]);
+
+ for (i = 0; i < ow->npages; i++) {
+ if (PagePrivate(ow->pages[i])) {
+ wrp = (struct orangefs_write_range *)
+ page_private(ow->pages[i]);
+ ClearPagePrivate(ow->pages[i]);
+ put_page(ow->pages[i]);
+ kfree(wrp);
}
+ end_page_writeback(ow->pages[i]);
+ unlock_page(ow->pages[i]);
}
+
return ret;
}
--
2.47.2
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 8/9] orangefs: Simplify bvec setup in orangefs_writepages_work()
2025-02-24 18:05 [PATCH 0/9] Orangefs fixes for 6.15 Matthew Wilcox (Oracle)
` (6 preceding siblings ...)
2025-02-24 18:05 ` [PATCH 7/9] orangefs: Unify error & success paths in orangefs_writepages_work() Matthew Wilcox (Oracle)
@ 2025-02-24 18:05 ` Matthew Wilcox (Oracle)
2025-02-24 18:05 ` [PATCH 9/9] orangefs: Convert orangefs_writepages to contain an array of folios Matthew Wilcox (Oracle)
2025-02-27 20:18 ` [PATCH 0/9] Orangefs fixes for 6.15 Mike Marshall
9 siblings, 0 replies; 13+ messages in thread
From: Matthew Wilcox (Oracle) @ 2025-02-24 18:05 UTC (permalink / raw)
To: Mike Marshall
Cc: Matthew Wilcox (Oracle), Martin Brandenburg, devel, linux-fsdevel
This produces a bvec which is slightly different as the last page is added
in its entirety rather than only the portion which is being written back.
However we don't use this information anywhere; the iovec has its own
length parameter.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/orangefs/inode.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c
index 927c2829976c..7b5272931e3b 100644
--- a/fs/orangefs/inode.c
+++ b/fs/orangefs/inode.c
@@ -83,18 +83,18 @@ static int orangefs_writepages_work(struct orangefs_writepages *ow,
struct orangefs_write_range *wrp, wr;
struct iov_iter iter;
ssize_t ret;
+ size_t start;
loff_t len, off;
int i;
len = i_size_read(inode);
+ start = offset_in_page(ow->off);
for (i = 0; i < ow->npages; i++) {
set_page_writeback(ow->pages[i]);
- bvec_set_page(&ow->bv[i], ow->pages[i],
- min(page_offset(ow->pages[i]) + PAGE_SIZE,
- ow->off + ow->len) -
- max(ow->off, page_offset(ow->pages[i])),
- i == 0 ? ow->off - page_offset(ow->pages[i]) : 0);
+ bvec_set_page(&ow->bv[i], ow->pages[i], PAGE_SIZE - start,
+ start);
+ start = 0;
}
iov_iter_bvec(&iter, ITER_SOURCE, ow->bv, ow->npages, ow->len);
--
2.47.2
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 9/9] orangefs: Convert orangefs_writepages to contain an array of folios
2025-02-24 18:05 [PATCH 0/9] Orangefs fixes for 6.15 Matthew Wilcox (Oracle)
` (7 preceding siblings ...)
2025-02-24 18:05 ` [PATCH 8/9] orangefs: Simplify bvec setup " Matthew Wilcox (Oracle)
@ 2025-02-24 18:05 ` Matthew Wilcox (Oracle)
2025-02-27 20:18 ` [PATCH 0/9] Orangefs fixes for 6.15 Mike Marshall
9 siblings, 0 replies; 13+ messages in thread
From: Matthew Wilcox (Oracle) @ 2025-02-24 18:05 UTC (permalink / raw)
To: Mike Marshall
Cc: Matthew Wilcox (Oracle), Martin Brandenburg, devel, linux-fsdevel
The pages being passed in are always folios (since they come from the
page cache). This eliminates several hidden calls to compound_head(),
and uses of legacy APIs.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
fs/orangefs/inode.c | 57 +++++++++++++++++++++------------------------
1 file changed, 26 insertions(+), 31 deletions(-)
diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c
index 7b5272931e3b..5ac743c6bc2e 100644
--- a/fs/orangefs/inode.c
+++ b/fs/orangefs/inode.c
@@ -70,9 +70,9 @@ struct orangefs_writepages {
kuid_t uid;
kgid_t gid;
int maxpages;
- int npages;
+ int nfolios;
struct address_space *mapping;
- struct page **pages;
+ struct folio **folios;
struct bio_vec *bv;
};
@@ -89,14 +89,14 @@ static int orangefs_writepages_work(struct orangefs_writepages *ow,
len = i_size_read(inode);
- start = offset_in_page(ow->off);
- for (i = 0; i < ow->npages; i++) {
- set_page_writeback(ow->pages[i]);
- bvec_set_page(&ow->bv[i], ow->pages[i], PAGE_SIZE - start,
- start);
+ start = offset_in_folio(ow->folios[0], ow->off);
+ for (i = 0; i < ow->nfolios; i++) {
+ folio_start_writeback(ow->folios[i]);
+ bvec_set_folio(&ow->bv[i], ow->folios[i],
+ folio_size(ow->folios[i]) - start, start);
start = 0;
}
- iov_iter_bvec(&iter, ITER_SOURCE, ow->bv, ow->npages, ow->len);
+ iov_iter_bvec(&iter, ITER_SOURCE, ow->bv, ow->nfolios, ow->len);
WARN_ON(ow->off >= len);
if (ow->off + ow->len > len)
@@ -112,16 +112,11 @@ static int orangefs_writepages_work(struct orangefs_writepages *ow,
else
ret = 0;
- for (i = 0; i < ow->npages; i++) {
- if (PagePrivate(ow->pages[i])) {
- wrp = (struct orangefs_write_range *)
- page_private(ow->pages[i]);
- ClearPagePrivate(ow->pages[i]);
- put_page(ow->pages[i]);
- kfree(wrp);
- }
- end_page_writeback(ow->pages[i]);
- unlock_page(ow->pages[i]);
+ for (i = 0; i < ow->nfolios; i++) {
+ wrp = folio_detach_private(ow->folios[i]);
+ kfree(wrp);
+ folio_end_writeback(ow->folios[i]);
+ folio_unlock(ow->folios[i]);
}
return ret;
@@ -142,41 +137,41 @@ static int orangefs_writepages_callback(struct folio *folio,
}
ret = -1;
- if (ow->npages == 0) {
+ if (ow->nfolios == 0) {
ow->off = wr->pos;
ow->len = wr->len;
ow->uid = wr->uid;
ow->gid = wr->gid;
- ow->pages[ow->npages++] = &folio->page;
+ ow->folios[ow->nfolios++] = folio;
ret = 0;
goto done;
}
if (!uid_eq(ow->uid, wr->uid) || !gid_eq(ow->gid, wr->gid)) {
orangefs_writepages_work(ow, wbc);
- ow->npages = 0;
+ ow->nfolios = 0;
ret = -1;
goto done;
}
if (ow->off + ow->len == wr->pos) {
ow->len += wr->len;
- ow->pages[ow->npages++] = &folio->page;
+ ow->folios[ow->nfolios++] = folio;
ret = 0;
goto done;
}
done:
if (ret == -1) {
- if (ow->npages) {
+ if (ow->nfolios) {
orangefs_writepages_work(ow, wbc);
- ow->npages = 0;
+ ow->nfolios = 0;
}
ret = orangefs_writepage_locked(folio, wbc);
mapping_set_error(folio->mapping, ret);
folio_unlock(folio);
folio_end_writeback(folio);
} else {
- if (ow->npages == ow->maxpages) {
+ if (ow->nfolios == ow->maxpages) {
orangefs_writepages_work(ow, wbc);
- ow->npages = 0;
+ ow->nfolios = 0;
}
}
return ret;
@@ -194,14 +189,14 @@ static int orangefs_writepages(struct address_space *mapping,
if (!ow)
return -ENOMEM;
ow->maxpages = orangefs_bufmap_size_query()/PAGE_SIZE;
- ow->pages = kcalloc(ow->maxpages, sizeof(struct page *), GFP_KERNEL);
- if (!ow->pages) {
+ ow->folios = kcalloc(ow->maxpages, sizeof(struct folio *), GFP_KERNEL);
+ if (!ow->folios) {
kfree(ow);
return -ENOMEM;
}
ow->bv = kcalloc(ow->maxpages, sizeof(struct bio_vec), GFP_KERNEL);
if (!ow->bv) {
- kfree(ow->pages);
+ kfree(ow->folios);
kfree(ow);
return -ENOMEM;
}
@@ -209,10 +204,10 @@ static int orangefs_writepages(struct address_space *mapping,
blk_start_plug(&plug);
while ((folio = writeback_iter(mapping, wbc, folio, &error)))
error = orangefs_writepages_callback(folio, wbc, ow);
- if (ow->npages)
+ if (ow->nfolios)
error = orangefs_writepages_work(ow, wbc);
blk_finish_plug(&plug);
- kfree(ow->pages);
+ kfree(ow->folios);
kfree(ow->bv);
kfree(ow);
return error;
--
2.47.2
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH 0/9] Orangefs fixes for 6.15
2025-02-24 18:05 [PATCH 0/9] Orangefs fixes for 6.15 Matthew Wilcox (Oracle)
` (8 preceding siblings ...)
2025-02-24 18:05 ` [PATCH 9/9] orangefs: Convert orangefs_writepages to contain an array of folios Matthew Wilcox (Oracle)
@ 2025-02-27 20:18 ` Mike Marshall
2025-03-01 14:34 ` Mike Marshall
9 siblings, 1 reply; 13+ messages in thread
From: Mike Marshall @ 2025-02-27 20:18 UTC (permalink / raw)
To: Matthew Wilcox (Oracle)
Cc: Martin Brandenburg, devel, linux-fsdevel, Mike Marshall
Howdy Matthew... I got your patch and deciphered the note
about leaving out the include files. It is compiling on top of
Linux 6.14-rc4 now, and I'll let you know how testing goes...
-Mike
On Mon, Feb 24, 2025 at 1:05 PM Matthew Wilcox (Oracle)
<willy@infradead.org> wrote:
>
> The start of this was the removal of orangefs_writepage(), but it
> quickly spiralled out of hand. The first patch is an actual bug fix.
> I haven't tagged it for backport, as I don't think we really care about
> 32-bit systems any more, but feel free to add a cc to stable.
>
> Patches 2 and 3 are compilation fixes for warnings which aren't enabled
> by default.
>
> Patches 4-9 are improvements which simplify orangefs or convert it
> from pages to folios. There is still a little use of 'struct page'
> in orangefs, but it's not in the areas that deal with the page cache.
>
> Matthew Wilcox (Oracle) (9):
> orangefs: Do not truncate file size
> orangefs: Move s_kmod_keyword_mask_map to orangefs-debugfs.c
> orangefs: make open_for_read and open_for_write boolean
> orangefs: Remove orangefs_writepage()
> orangefs: Convert orangefs_writepage_locked() to take a folio
> orangefs: Pass mapping to orangefs_writepages_work()
> orangefs: Unify error & success paths in orangefs_writepages_work()
> orangefs: Simplify bvec setup in orangefs_writepages_work()
> orangefs: Convert orangefs_writepages to contain an array of folios
>
> fs/orangefs/file.c | 4 +-
> fs/orangefs/inode.c | 149 ++++++++++++++-------------------
> fs/orangefs/orangefs-debug.h | 43 ----------
> fs/orangefs/orangefs-debugfs.c | 43 ++++++++++
> include/linux/mm_types.h | 6 +-
> include/linux/nfs_page.h | 2 +-
> include/linux/page-flags.h | 6 +-
> 7 files changed, 116 insertions(+), 137 deletions(-)
>
> --
> 2.47.2
>
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH 0/9] Orangefs fixes for 6.15
2025-02-27 20:18 ` [PATCH 0/9] Orangefs fixes for 6.15 Mike Marshall
@ 2025-03-01 14:34 ` Mike Marshall
0 siblings, 0 replies; 13+ messages in thread
From: Mike Marshall @ 2025-03-01 14:34 UTC (permalink / raw)
To: Matthew Wilcox (Oracle); +Cc: devel, linux-fsdevel, Mike Marshall
Matthew... Thanks for the patch. I get no xfstests regressions
with it...
-Mike
On Thu, Feb 27, 2025 at 3:18 PM Mike Marshall <hubcap@omnibond.com> wrote:
>
> Howdy Matthew... I got your patch and deciphered the note
> about leaving out the include files. It is compiling on top of
> Linux 6.14-rc4 now, and I'll let you know how testing goes...
>
> -Mike
>
> On Mon, Feb 24, 2025 at 1:05 PM Matthew Wilcox (Oracle)
> <willy@infradead.org> wrote:
> >
> > The start of this was the removal of orangefs_writepage(), but it
> > quickly spiralled out of hand. The first patch is an actual bug fix.
> > I haven't tagged it for backport, as I don't think we really care about
> > 32-bit systems any more, but feel free to add a cc to stable.
> >
> > Patches 2 and 3 are compilation fixes for warnings which aren't enabled
> > by default.
> >
> > Patches 4-9 are improvements which simplify orangefs or convert it
> > from pages to folios. There is still a little use of 'struct page'
> > in orangefs, but it's not in the areas that deal with the page cache.
> >
> > Matthew Wilcox (Oracle) (9):
> > orangefs: Do not truncate file size
> > orangefs: Move s_kmod_keyword_mask_map to orangefs-debugfs.c
> > orangefs: make open_for_read and open_for_write boolean
> > orangefs: Remove orangefs_writepage()
> > orangefs: Convert orangefs_writepage_locked() to take a folio
> > orangefs: Pass mapping to orangefs_writepages_work()
> > orangefs: Unify error & success paths in orangefs_writepages_work()
> > orangefs: Simplify bvec setup in orangefs_writepages_work()
> > orangefs: Convert orangefs_writepages to contain an array of folios
> >
> > fs/orangefs/file.c | 4 +-
> > fs/orangefs/inode.c | 149 ++++++++++++++-------------------
> > fs/orangefs/orangefs-debug.h | 43 ----------
> > fs/orangefs/orangefs-debugfs.c | 43 ++++++++++
> > include/linux/mm_types.h | 6 +-
> > include/linux/nfs_page.h | 2 +-
> > include/linux/page-flags.h | 6 +-
> > 7 files changed, 116 insertions(+), 137 deletions(-)
> >
> > --
> > 2.47.2
> >
^ permalink raw reply [flat|nested] 13+ messages in thread