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;
        }

Reply via email to