afs: Alter dirty range encoding in page->private
Currently, page->private on an afs page is used to store the range of
dirtied data within the page, where the range includes the lower bound, but
excludes the upper bound (e.g. 0-1 is a range covering a single byte).
This, however, requires a superfluous bit for the last-byte bound so that
on a 4KiB page, it can say 0-4096 to indicate the whole page, the idea
being that having both numbers the same would indicate an empty range.
This is unnecessary as the PG_private bit is clear if it's an empty range
(as is PG_dirty).
Alter the way the dirty range is encoded in page->private such that the
upper bound is reduced by 1 (e.g. 0-0 is then specified the same single
byte range mentioned above).
Applying this to both bounds frees up two bits, one of which can be used in
a future commit.
This allows the afs filesystem to be compiled on ppc32 with 64K pages;
without this, the following warnings are seen:
../fs/afs/internal.h: In function 'afs_page_dirty_to':
../fs/afs/internal.h:881:15: warning: right shift count >= width of type [-Wshift-count-overflow]
881 | return (priv >> __AFS_PAGE_PRIV_SHIFT) & __AFS_PAGE_PRIV_MASK;
| ^~
../fs/afs/internal.h: In function 'afs_page_dirty':
../fs/afs/internal.h:886:28: warning: left shift count >= width of type [-Wshift-count-overflow]
886 | return ((unsigned long)to << __AFS_PAGE_PRIV_SHIFT) | from;
| ^~
Fixes: 4343d00872
("afs: Get rid of the afs_writeback record")
Signed-off-by: David Howells <dhowells@redhat.com>
This commit is contained in:
Родитель
185f0c7073
Коммит
65dd2d6072
|
@ -863,7 +863,7 @@ struct afs_vnode_cache_aux {
|
||||||
* splitting the field into two parts. However, we need to represent a range
|
* splitting the field into two parts. However, we need to represent a range
|
||||||
* 0...PAGE_SIZE inclusive, so we can't support 64K pages on a 32-bit system.
|
* 0...PAGE_SIZE inclusive, so we can't support 64K pages on a 32-bit system.
|
||||||
*/
|
*/
|
||||||
#if PAGE_SIZE > 32768
|
#ifdef CONFIG_64BIT
|
||||||
#define __AFS_PAGE_PRIV_MASK 0xffffffffUL
|
#define __AFS_PAGE_PRIV_MASK 0xffffffffUL
|
||||||
#define __AFS_PAGE_PRIV_SHIFT 32
|
#define __AFS_PAGE_PRIV_SHIFT 32
|
||||||
#else
|
#else
|
||||||
|
@ -878,12 +878,12 @@ static inline size_t afs_page_dirty_from(unsigned long priv)
|
||||||
|
|
||||||
static inline size_t afs_page_dirty_to(unsigned long priv)
|
static inline size_t afs_page_dirty_to(unsigned long priv)
|
||||||
{
|
{
|
||||||
return (priv >> __AFS_PAGE_PRIV_SHIFT) & __AFS_PAGE_PRIV_MASK;
|
return ((priv >> __AFS_PAGE_PRIV_SHIFT) & __AFS_PAGE_PRIV_MASK) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned long afs_page_dirty(size_t from, size_t to)
|
static inline unsigned long afs_page_dirty(size_t from, size_t to)
|
||||||
{
|
{
|
||||||
return ((unsigned long)to << __AFS_PAGE_PRIV_SHIFT) | from;
|
return ((unsigned long)(to - 1) << __AFS_PAGE_PRIV_SHIFT) | from;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <trace/events/afs.h>
|
#include <trace/events/afs.h>
|
||||||
|
|
|
@ -93,7 +93,7 @@ int afs_write_begin(struct file *file, struct address_space *mapping,
|
||||||
/* We want to store information about how much of a page is altered in
|
/* We want to store information about how much of a page is altered in
|
||||||
* page->private.
|
* page->private.
|
||||||
*/
|
*/
|
||||||
BUILD_BUG_ON(PAGE_SIZE > 32768 && sizeof(page->private) < 8);
|
BUILD_BUG_ON(PAGE_SIZE - 1 > __AFS_PAGE_PRIV_MASK && sizeof(page->private) < 8);
|
||||||
|
|
||||||
page = grab_cache_page_write_begin(mapping, index, flags);
|
page = grab_cache_page_write_begin(mapping, index, flags);
|
||||||
if (!page)
|
if (!page)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче