In fact, I expected yes for the first abbility and no for the second :) Now code looks like: bh = sb_bread(sb, oldblock); if (!bh) goto err; bh->b_blocknr = newblk; mark_buffer_dirty (bh); unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr); Let's suppose such test case: after situation, which I described in the first email, user resize file and new size 5 blocks, and there are no free blocks except 2 blocks which we deallocated in the frist email, so we have to allocate them. When I reproduced this test case, I got such messages from kernel: __find_get_block_slow failed block=oldblock... So as I can see I missed something in "art of changing b_blocknr". Error in __find_get_block_slow may happen only if all buffers on page mapped. May be this is because of buffer_head change b_blocknr, but didn't change b_this_page? On 1/20/06, Anton Altaparmakov <aia21@xxxxxxxxx> wrote: > On Fri, 2006-01-20 at 14:47 +0300, Jan Koss wrote: > > Hello. > > > > Let's suppose that we have file which consist of two blocks > > and user resizing file and now we need 4 blocks. > > > > Near this two blocks there are no 2 free blocks, > > and instead of allocating 2 additional blocks somewhere, > > I want allocate chunk of 4 blocks. > > > > The main problem is choose way of invalidate "old" blocks and copy > > data to new buffers, > > > > how it possible on linux? > > > > something like > > struct buffer_head *oldbh, *newbh; > > memcpy(newbh->b_data, oldbh->b_data); > > block_invalidatepage(oldbh->b_this_page,...) > > No need to invalidate or copy anything as long as you are working inside > a file system driver and those buffers are attached to page cache of a > file. > > > or it is possible just change b_blocknr? > > Yes, just change b_blocknr, and mark the buffer dirty so it gets written > out to the new location or indeed you can do the write (or submission > thereof) yourself if you want. > > Note since you are effectively "allocating" the buffer(s), after you > have done the block allocation on your file system and updated > bh->b_blocknr, you need to call unmap_underlying_metadata(bh->b_dev, > bh->b_blocknr); for each block before you write it out or your write > could get trampled on by a different write. > > And of course do not forget to deallocate the two blocks you just freed > in your fs... (-: > > 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/ > > -- Kernelnewbies: Help each other learn about the Linux kernel. Archive: http://mail.nl.linux.org/kernelnewbies/ FAQ: http://kernelnewbies.org/faq/