Skip to content

Commit 185f0c7

Browse files
committed
afs: Wrap page->private manipulations in inline functions
The afs filesystem uses page->private to store the dirty range within a page such that in the event of a conflicting 3rd-party write to the server, we write back just the bits that got changed locally. However, there are a couple of problems with this: (1) I need a bit to note if the page might be mapped so that partial invalidation doesn't shrink the range. (2) There aren't necessarily sufficient bits to store the entire range of data altered (say it's a 32-bit system with 64KiB pages or transparent huge pages are in use). So wrap the accesses in inline functions so that future commits can change how this works. Also move them out of the tracing header into the in-directory header. There's not really any need for them to be in the tracing header. Signed-off-by: David Howells <[email protected]>
1 parent f792e3a commit 185f0c7

File tree

3 files changed

+44
-34
lines changed

3 files changed

+44
-34
lines changed

fs/afs/internal.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,34 @@ struct afs_vnode_cache_aux {
858858
u64 data_version;
859859
} __packed;
860860

861+
/*
862+
* We use page->private to hold the amount of the page that we've written to,
863+
* splitting the field into two parts. However, we need to represent a range
864+
* 0...PAGE_SIZE inclusive, so we can't support 64K pages on a 32-bit system.
865+
*/
866+
#if PAGE_SIZE > 32768
867+
#define __AFS_PAGE_PRIV_MASK 0xffffffffUL
868+
#define __AFS_PAGE_PRIV_SHIFT 32
869+
#else
870+
#define __AFS_PAGE_PRIV_MASK 0xffffUL
871+
#define __AFS_PAGE_PRIV_SHIFT 16
872+
#endif
873+
874+
static inline size_t afs_page_dirty_from(unsigned long priv)
875+
{
876+
return priv & __AFS_PAGE_PRIV_MASK;
877+
}
878+
879+
static inline size_t afs_page_dirty_to(unsigned long priv)
880+
{
881+
return (priv >> __AFS_PAGE_PRIV_SHIFT) & __AFS_PAGE_PRIV_MASK;
882+
}
883+
884+
static inline unsigned long afs_page_dirty(size_t from, size_t to)
885+
{
886+
return ((unsigned long)to << __AFS_PAGE_PRIV_SHIFT) | from;
887+
}
888+
861889
#include <trace/events/afs.h>
862890

863891
/*****************************************************************************/

fs/afs/write.c

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ int afs_write_begin(struct file *file, struct address_space *mapping,
117117
t = f = 0;
118118
if (PagePrivate(page)) {
119119
priv = page_private(page);
120-
f = priv & AFS_PRIV_MAX;
121-
t = priv >> AFS_PRIV_SHIFT;
120+
f = afs_page_dirty_from(priv);
121+
t = afs_page_dirty_to(priv);
122122
ASSERTCMP(f, <=, t);
123123
}
124124

@@ -206,22 +206,18 @@ int afs_write_end(struct file *file, struct address_space *mapping,
206206

207207
if (PagePrivate(page)) {
208208
priv = page_private(page);
209-
f = priv & AFS_PRIV_MAX;
210-
t = priv >> AFS_PRIV_SHIFT;
209+
f = afs_page_dirty_from(priv);
210+
t = afs_page_dirty_to(priv);
211211
if (from < f)
212212
f = from;
213213
if (to > t)
214214
t = to;
215-
priv = (unsigned long)t << AFS_PRIV_SHIFT;
216-
priv |= f;
215+
priv = afs_page_dirty(f, t);
217216
set_page_private(page, priv);
218217
trace_afs_page_dirty(vnode, tracepoint_string("dirty+"),
219218
page->index, priv);
220219
} else {
221-
f = from;
222-
t = to;
223-
priv = (unsigned long)t << AFS_PRIV_SHIFT;
224-
priv |= f;
220+
priv = afs_page_dirty(from, to);
225221
attach_page_private(page, (void *)priv);
226222
trace_afs_page_dirty(vnode, tracepoint_string("dirty"),
227223
page->index, priv);
@@ -522,8 +518,8 @@ static int afs_write_back_from_locked_page(struct address_space *mapping,
522518
*/
523519
start = primary_page->index;
524520
priv = page_private(primary_page);
525-
offset = priv & AFS_PRIV_MAX;
526-
to = priv >> AFS_PRIV_SHIFT;
521+
offset = afs_page_dirty_from(priv);
522+
to = afs_page_dirty_to(priv);
527523
trace_afs_page_dirty(vnode, tracepoint_string("store"),
528524
primary_page->index, priv);
529525

@@ -568,8 +564,8 @@ static int afs_write_back_from_locked_page(struct address_space *mapping,
568564
}
569565

570566
priv = page_private(page);
571-
f = priv & AFS_PRIV_MAX;
572-
t = priv >> AFS_PRIV_SHIFT;
567+
f = afs_page_dirty_from(priv);
568+
t = afs_page_dirty_to(priv);
573569
if (f != 0 &&
574570
!test_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags)) {
575571
unlock_page(page);
@@ -870,8 +866,7 @@ vm_fault_t afs_page_mkwrite(struct vm_fault *vmf)
870866
*/
871867
wait_on_page_writeback(vmf->page);
872868

873-
priv = (unsigned long)PAGE_SIZE << AFS_PRIV_SHIFT; /* To */
874-
priv |= 0; /* From */
869+
priv = afs_page_dirty(0, PAGE_SIZE);
875870
trace_afs_page_dirty(vnode, tracepoint_string("mkwrite"),
876871
vmf->page->index, priv);
877872
if (PagePrivate(vmf->page))
@@ -930,8 +925,8 @@ int afs_launder_page(struct page *page)
930925
f = 0;
931926
t = PAGE_SIZE;
932927
if (PagePrivate(page)) {
933-
f = priv & AFS_PRIV_MAX;
934-
t = priv >> AFS_PRIV_SHIFT;
928+
f = afs_page_dirty_from(priv);
929+
t = afs_page_dirty_to(priv);
935930
}
936931

937932
trace_afs_page_dirty(vnode, tracepoint_string("launder"),

include/trace/events/afs.h

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -966,19 +966,6 @@ TRACE_EVENT(afs_dir_check_failed,
966966
__entry->vnode, __entry->off, __entry->i_size)
967967
);
968968

969-
/*
970-
* We use page->private to hold the amount of the page that we've written to,
971-
* splitting the field into two parts. However, we need to represent a range
972-
* 0...PAGE_SIZE inclusive, so we can't support 64K pages on a 32-bit system.
973-
*/
974-
#if PAGE_SIZE > 32768
975-
#define AFS_PRIV_MAX 0xffffffff
976-
#define AFS_PRIV_SHIFT 32
977-
#else
978-
#define AFS_PRIV_MAX 0xffff
979-
#define AFS_PRIV_SHIFT 16
980-
#endif
981-
982969
TRACE_EVENT(afs_page_dirty,
983970
TP_PROTO(struct afs_vnode *vnode, const char *where,
984971
pgoff_t page, unsigned long priv),
@@ -999,10 +986,10 @@ TRACE_EVENT(afs_page_dirty,
999986
__entry->priv = priv;
1000987
),
1001988

1002-
TP_printk("vn=%p %lx %s %lu-%lu",
989+
TP_printk("vn=%p %lx %s %zx-%zx",
1003990
__entry->vnode, __entry->page, __entry->where,
1004-
__entry->priv & AFS_PRIV_MAX,
1005-
__entry->priv >> AFS_PRIV_SHIFT)
991+
afs_page_dirty_from(__entry->priv),
992+
afs_page_dirty_to(__entry->priv))
1006993
);
1007994

1008995
TRACE_EVENT(afs_call_state,

0 commit comments

Comments
 (0)