Linux Audio
Check our new training course
Embedded Linux Audio
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
#include <linux/gfp.h> #include <linux/pagemap.h> #include <linux/highmem.h> #include "pagelist.h" int ceph_pagelist_release(struct ceph_pagelist *pl) { if (pl->mapped_tail) kunmap(pl->mapped_tail); while (!list_empty(&pl->head)) { struct page *page = list_first_entry(&pl->head, struct page, lru); list_del(&page->lru); __free_page(page); } return 0; } static int ceph_pagelist_addpage(struct ceph_pagelist *pl) { struct page *page = __page_cache_alloc(GFP_NOFS); if (!page) return -ENOMEM; pl->room += PAGE_SIZE; list_add_tail(&page->lru, &pl->head); if (pl->mapped_tail) kunmap(pl->mapped_tail); pl->mapped_tail = kmap(page); return 0; } int ceph_pagelist_append(struct ceph_pagelist *pl, void *buf, size_t len) { while (pl->room < len) { size_t bit = pl->room; int ret; memcpy(pl->mapped_tail + (pl->length & ~PAGE_CACHE_MASK), buf, bit); pl->length += bit; pl->room -= bit; buf += bit; len -= bit; ret = ceph_pagelist_addpage(pl); if (ret) return ret; } memcpy(pl->mapped_tail + (pl->length & ~PAGE_CACHE_MASK), buf, len); pl->length += len; pl->room -= len; return 0; }