Messages in this thread Patch in this message | | | Date | Fri, 29 Oct 2004 15:28:37 +0100 (BST) | From | Anton Altaparmakov <> | Subject | RFC: Changes to fs/buffer.c? |
| |
Hi Andrew, hi Linus,
I would like to use create_buffers() and __set_page_buffers() in ntfs but both are static functions in fs/buffer.c. Is it ok to export create_buffers() and to make __set_page_buffers() static inline and move it to include/linux/buffer.h? In other words, is the below patch acceptable?
If you are curious why I need these, it is because mark_ntfs_record_dirty() needs to create buffers if they are not present so that it can set only some of them dirty and create_empty_buffers() sets all buffers dirty which is not useful. Also create_empty_buffers() relies on the page being locked which is not necessarily the case when mark_ntfs_record_dirty() is called. This allows me to only mark parts of a page as dirty which means ->writepage() does not need to write the whole page but only the dirty ntfs records in the page. The function I am talking about is at the end of this email if you want to see it.
Thanks a lot in advance.
Best regards,
Anton -- Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @) Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/
--- ntfs-2.6-devel/include/linux/buffer_head.h.old 2004-10-29 14:38:11.543109318 +0100 +++ ntfs-2.6-devel/include/linux/buffer_head.h 2004-10-29 14:38:48.718192623 +0100 @@ -10,6 +10,7 @@ #include <linux/types.h> #include <linux/fs.h> #include <linux/linkage.h> +#include <linux/pagemap.h> #include <linux/wait.h> #include <asm/atomic.h> @@ -136,6 +137,8 @@ void init_buffer(struct buffer_head *, b void set_bh_page(struct buffer_head *bh, struct page *page, unsigned long offset); int try_to_free_buffers(struct page *); +struct buffer_head *create_buffers(struct page *page, unsigned long size, + int retry); void create_empty_buffers(struct page *, unsigned long, unsigned long b_state); void end_buffer_read_sync(struct buffer_head *bh, int uptodate); @@ -205,6 +208,14 @@ int nobh_truncate_page(struct address_sp * inline definitions */ +static inline void __set_page_buffers(struct page *page, + struct buffer_head *head) +{ + page_cache_get(page); + SetPagePrivate(page); + page->private = (unsigned long)head; +} + static inline void get_bh(struct buffer_head *bh) { atomic_inc(&bh->b_count); --- ntfs-2.6-devel/fs/buffer.c.old 2004-10-29 12:50:57.271105103 +0100 +++ ntfs-2.6-devel/fs/buffer.c 2004-10-29 14:35:29.254207332 +0100 @@ -91,14 +91,6 @@ void __wait_on_buffer(struct buffer_head } static void -__set_page_buffers(struct page *page, struct buffer_head *head) -{ - page_cache_get(page); - SetPagePrivate(page); - page->private = (unsigned long)head; -} - -static void __clear_page_buffers(struct page *page) { ClearPagePrivate(page); @@ -1013,8 +1005,8 @@ int remove_inode_buffers(struct inode *i * The retry flag is used to differentiate async IO (paging, swapping) * which may not fail from ordinary buffer allocations. */ -static struct buffer_head * -create_buffers(struct page * page, unsigned long size, int retry) +struct buffer_head *create_buffers(struct page *page, unsigned long size, + int retry) { struct buffer_head *bh, *head; long offset; @@ -1072,6 +1064,7 @@ no_grow: free_more_memory(); goto try_again; } +EXPORT_SYMBOL(create_buffers); static inline void link_dev_buffers(struct page *page, struct buffer_head *head)
------------- this is mark_ntfs_record_dirty() -------------- /** * mark_ntfs_record_dirty - mark an ntfs record dirty * @page: page containing the ntfs record to mark dirty * @ofs: byte offset within @page at which the ntfs record begins * * Set the buffers and the page in which the ntfs record is located dirty. * * The latter also marks the vfs inode the ntfs record belongs to dirty * (I_DIRTY_PAGES only). * * If the page does not have buffers, we create them and set them uptodate. * The page may not be locked which is why we need to handle the buffers under * the mapping->private_lock. Once the buffers are marked dirty we no longer * need the lock since try_to_free_buffers() does not free dirty buffers. */ void mark_ntfs_record_dirty(struct page *page, const unsigned int ofs) { struct address_space *mapping = page->mapping; ntfs_inode *ni = NTFS_I(mapping->host); struct buffer_head *bh, *head, *buffers_to_free = NULL; unsigned int end, bh_size, bh_ofs; BUG_ON(!PageUptodate(page)); end = ofs + ni->itype.index.block_size; bh_size = 1 << VFS_I(ni)->i_blkbits; spin_lock(&mapping->private_lock); if (unlikely(!page_has_buffers(page))) { spin_unlock(&mapping->private_lock); bh = head = create_buffers(page, bh_size, 1); spin_lock(&mapping->private_lock); if (likely(!page_has_buffers(page))) { struct buffer_head *tail; do { set_buffer_uptodate(bh); tail = bh; bh = bh->b_this_page; } while (bh); tail->b_this_page = head; __set_page_buffers(page, head); } else buffers_to_free = bh; } bh = head = page_buffers(page); do { bh_ofs = bh_offset(bh); if (bh_ofs + bh_size <= ofs) continue; if (unlikely(bh_ofs >= end)) break; set_buffer_dirty(bh); } while ((bh = bh->b_this_page) != head); spin_unlock(&mapping->private_lock); __set_page_dirty_nobuffers(page); if (unlikely(buffers_to_free)) { do { bh = buffers_to_free->b_this_page; free_buffer_head(buffers_to_free); buffers_to_free = bh; } while (buffers_to_free); } } - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |