Merge branch 'urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6
[pandora-kernel.git] / fs / nilfs2 / btnode.c
index 0a6834b..f78ab10 100644 (file)
@@ -96,7 +96,8 @@ nilfs_btnode_create_block(struct address_space *btnc, __u64 blocknr)
 }
 
 int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
-                             sector_t pblocknr, struct buffer_head **pbh)
+                             sector_t pblocknr, int mode,
+                             struct buffer_head **pbh, sector_t *submit_ptr)
 {
        struct buffer_head *bh;
        struct inode *inode = NILFS_BTNC_I(btnc);
@@ -127,7 +128,16 @@ int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
                        }
                }
        }
-       lock_buffer(bh);
+
+       if (mode == READA) {
+               if (pblocknr != *submit_ptr + 1 || !trylock_buffer(bh)) {
+                       err = -EBUSY; /* internal code */
+                       brelse(bh);
+                       goto out_locked;
+               }
+       } else { /* mode == READ */
+               lock_buffer(bh);
+       }
        if (buffer_uptodate(bh)) {
                unlock_buffer(bh);
                err = -EEXIST; /* internal code */
@@ -138,8 +148,9 @@ int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
        bh->b_blocknr = pblocknr; /* set block address for read */
        bh->b_end_io = end_buffer_read_sync;
        get_bh(bh);
-       submit_bh(READ, bh);
+       submit_bh(mode, bh);
        bh->b_blocknr = blocknr; /* set back to the given block address */
+       *submit_ptr = pblocknr;
        err = 0;
 found:
        *pbh = bh;