--- fs/proc/page.c | 88 +++++++++++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 32 deletions(-) --- mm.orig/fs/proc/page.c +++ mm/fs/proc/page.c @@ -68,19 +68,60 @@ static const struct file_operations proc /* These macros are used to decouple internal flags from exported ones */ -#define KPF_LOCKED 0 -#define KPF_ERROR 1 -#define KPF_REFERENCED 2 -#define KPF_UPTODATE 3 -#define KPF_DIRTY 4 -#define KPF_LRU 5 -#define KPF_ACTIVE 6 -#define KPF_SLAB 7 -#define KPF_WRITEBACK 8 -#define KPF_RECLAIM 9 -#define KPF_BUDDY 10 +enum { + KPF_LOCKED, /* 0 */ + KPF_ERROR, /* 1 */ + KPF_REFERENCED, /* 2 */ + KPF_UPTODATE, /* 3 */ + KPF_DIRTY, /* 4 */ + KPF_LRU, /* 5 */ + KPF_ACTIVE, /* 6 */ + KPF_SLAB, /* 7 */ + KPF_WRITEBACK, /* 8 */ + KPF_RECLAIM, /* 9 */ + KPF_BUDDY, /* 10 */ + KPF_RESERVED, /* 11 */ + KPF_SWAPCACHE, /* 12 */ + KPF_SWAPBACKED, /* 13 */ + KPF_PRIVATE, /* 14 */ + KPF_PRIVATE2, /* 15 */ + KPF_NOPAGE, /* 16 */ + KPF_NOFLAGS, /* 17 */ + KPF_NUM +}; + +#define PAGE_FLAGS_MASK ((1 << __NR_PAGEFLAGS) - 1) + +#define kpf_copy_bit(flags, dstpos, srcpos) (((flags >> srcpos) & 1) << dstpos) -#define kpf_copy_bit(flags, srcpos, dstpos) (((flags >> srcpos) & 1) << dstpos) +u64 get_uflags(struct page *page) +{ + unsigned long kflags; + + if (!page) + return (1 << KPF_NOPAGE); + + kflags = page->flags; + if ((kflags & PAGE_FLAGS_MASK) == 0) + return (1 << KPF_NOFLAGS); + + return kpf_copy_bit(kflags, KPF_LOCKED, PG_locked) | + kpf_copy_bit(kflags, KPF_ERROR, PG_error) | + kpf_copy_bit(kflags, KPF_REFERENCED, PG_referenced) | + kpf_copy_bit(kflags, KPF_UPTODATE, PG_uptodate) | + kpf_copy_bit(kflags, KPF_DIRTY, PG_dirty) | + kpf_copy_bit(kflags, KPF_LRU, PG_lru) | + kpf_copy_bit(kflags, KPF_ACTIVE, PG_active) | + kpf_copy_bit(kflags, KPF_SLAB, PG_slab) | + kpf_copy_bit(kflags, KPF_WRITEBACK, PG_writeback) | + kpf_copy_bit(kflags, KPF_RECLAIM, PG_reclaim) | + kpf_copy_bit(kflags, KPF_BUDDY, PG_buddy) | + kpf_copy_bit(kflags, KPF_SWAPCACHE, PG_swapcache) | + kpf_copy_bit(kflags, KPF_SWAPBACKED, PG_swapbacked) | + kpf_copy_bit(kflags, KPF_PRIVATE, PG_private) | + kpf_copy_bit(kflags, KPF_PRIVATE2, PG_private_2) | + kpf_copy_bit(kflags, KPF_RESERVED, PG_reserved); +}; static ssize_t kpageflags_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) @@ -90,7 +131,6 @@ static ssize_t kpageflags_read(struct fi unsigned long src = *ppos; unsigned long pfn; ssize_t ret = 0; - u64 kflags, uflags; pfn = src / KPMSIZE; count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src); @@ -98,32 +138,16 @@ static ssize_t kpageflags_read(struct fi return -EINVAL; while (count > 0) { - ppage = NULL; if (pfn_valid(pfn)) ppage = pfn_to_page(pfn); - pfn++; - if (!ppage) - kflags = 0; else - kflags = ppage->flags; - - uflags = kpf_copy_bit(kflags, KPF_LOCKED, PG_locked) | - kpf_copy_bit(kflags, KPF_ERROR, PG_error) | - kpf_copy_bit(kflags, KPF_REFERENCED, PG_referenced) | - kpf_copy_bit(kflags, KPF_UPTODATE, PG_uptodate) | - kpf_copy_bit(kflags, KPF_DIRTY, PG_dirty) | - kpf_copy_bit(kflags, KPF_LRU, PG_lru) | - kpf_copy_bit(kflags, KPF_ACTIVE, PG_active) | - kpf_copy_bit(kflags, KPF_SLAB, PG_slab) | - kpf_copy_bit(kflags, KPF_WRITEBACK, PG_writeback) | - kpf_copy_bit(kflags, KPF_RECLAIM, PG_reclaim) | - kpf_copy_bit(kflags, KPF_BUDDY, PG_buddy); + ppage = NULL; + pfn++; - if (put_user(uflags, out++)) { + if (put_user(get_uflags(ppage), out++)) { ret = -EFAULT; break; } - count -= KPMSIZE; }