Hi
I wondered if someone could explain what is happening in
generic_file_read:
More generically, I'd like to understand how in a file system I can
"get" a page and use it to copy date into/out of it. How do I then put
the page away?
There seem to be several patterns, but I can't figure them out:
- functions modifying a page tend to lock the page, and unlock them
understandbly
- functions reading the page do a page_get -- but there is no page_put
(?)
Below in the snippet from generic_page read, the normal path does:
get_page(page)
if all is well copy the data from the page
page_cache_release(page)
But the latter is in fact __free_page(page) which is defined in
page_alloc.c and is very appropriately labeled as "You really aren't
expected to understand this".
- What does that function do with the page?
- Who sets back the page count, which was increased by get_page?
Surely I'm totally confused, can someone explain what I'm missing?
- Peter -
>From generic_file_read :
page = __find_page_nolock(inode, pos & PAGE_CACHE_MASK, *hash);
if (!page)
goto no_cached_page;
found_page:
get_page(page);
spin_unlock(&pagecache_lock);
if (!Page_Uptodate(page))
goto page_not_up_to_date;
page_ok:
/*
* Ok, we have the page, and it's up-to-date, so
* now we can copy it to user space...
*/
{
unsigned long offset, nr;
offset = pos & ~PAGE_CACHE_MASK;
nr = PAGE_CACHE_SIZE - offset;
if (nr > inode->i_size - pos)
nr = inode->i_size - pos;
/*
* The actor routine returns how many bytes were actually used..
* NOTE! This may not be the same as how much of a user buffer
* we filled up (we may be padding etc), so we can only update
* "pos" here (the actor routine has to update the user buffer
* pointers and the remaining count).
*/
nr = actor(desc, (const char *) (page_address(page) + offset), nr);
pos += nr;
page_cache_release(page);
if (nr && desc->count)
continue;
break;
}