Merge tag 'xfs-for-linus-4.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / fs / buffer.c
index 228288a7de388b8fe97f73814853a9ab04ebb5fe..9c8eb9b6db6aace3ef93edc5c8369ba48ecfb4f4 100644 (file)
@@ -46,7 +46,7 @@
 #include <trace/events/block.h>
 
 static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
 #include <trace/events/block.h>
 
 static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
-static int submit_bh_wbc(int rw, struct buffer_head *bh,
+static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh,
                         unsigned long bio_flags,
                         struct writeback_control *wbc);
 
                         unsigned long bio_flags,
                         struct writeback_control *wbc);
 
@@ -154,7 +154,7 @@ static void __end_buffer_read_notouch(struct buffer_head *bh, int uptodate)
        if (uptodate) {
                set_buffer_uptodate(bh);
        } else {
        if (uptodate) {
                set_buffer_uptodate(bh);
        } else {
-               /* This happens, due to failed READA attempts. */
+               /* This happens, due to failed read-ahead attempts. */
                clear_buffer_uptodate(bh);
        }
        unlock_buffer(bh);
                clear_buffer_uptodate(bh);
        }
        unlock_buffer(bh);
@@ -589,7 +589,7 @@ void write_boundary_block(struct block_device *bdev,
        struct buffer_head *bh = __find_get_block(bdev, bblock + 1, blocksize);
        if (bh) {
                if (buffer_dirty(bh))
        struct buffer_head *bh = __find_get_block(bdev, bblock + 1, blocksize);
        if (bh) {
                if (buffer_dirty(bh))
-                       ll_rw_block(WRITE, 1, &bh);
+                       ll_rw_block(REQ_OP_WRITE, 0, 1, &bh);
                put_bh(bh);
        }
 }
                put_bh(bh);
        }
 }
@@ -1226,7 +1226,7 @@ static struct buffer_head *__bread_slow(struct buffer_head *bh)
        } else {
                get_bh(bh);
                bh->b_end_io = end_buffer_read_sync;
        } else {
                get_bh(bh);
                bh->b_end_io = end_buffer_read_sync;
-               submit_bh(READ, bh);
+               submit_bh(REQ_OP_READ, 0, bh);
                wait_on_buffer(bh);
                if (buffer_uptodate(bh))
                        return bh;
                wait_on_buffer(bh);
                if (buffer_uptodate(bh))
                        return bh;
@@ -1396,7 +1396,7 @@ void __breadahead(struct block_device *bdev, sector_t block, unsigned size)
 {
        struct buffer_head *bh = __getblk(bdev, block, size);
        if (likely(bh)) {
 {
        struct buffer_head *bh = __getblk(bdev, block, size);
        if (likely(bh)) {
-               ll_rw_block(READA, 1, &bh);
+               ll_rw_block(REQ_OP_READ, REQ_RAHEAD, 1, &bh);
                brelse(bh);
        }
 }
                brelse(bh);
        }
 }
@@ -1688,7 +1688,7 @@ static struct buffer_head *create_page_buffers(struct page *page, struct inode *
  * WB_SYNC_ALL, the writes are posted using WRITE_SYNC; this
  * causes the writes to be flagged as synchronous writes.
  */
  * WB_SYNC_ALL, the writes are posted using WRITE_SYNC; this
  * causes the writes to be flagged as synchronous writes.
  */
-static int __block_write_full_page(struct inode *inode, struct page *page,
+int __block_write_full_page(struct inode *inode, struct page *page,
                        get_block_t *get_block, struct writeback_control *wbc,
                        bh_end_io_t *handler)
 {
                        get_block_t *get_block, struct writeback_control *wbc,
                        bh_end_io_t *handler)
 {
@@ -1698,7 +1698,7 @@ static int __block_write_full_page(struct inode *inode, struct page *page,
        struct buffer_head *bh, *head;
        unsigned int blocksize, bbits;
        int nr_underway = 0;
        struct buffer_head *bh, *head;
        unsigned int blocksize, bbits;
        int nr_underway = 0;
-       int write_op = (wbc->sync_mode == WB_SYNC_ALL ? WRITE_SYNC : WRITE);
+       int write_flags = (wbc->sync_mode == WB_SYNC_ALL ? WRITE_SYNC : 0);
 
        head = create_page_buffers(page, inode,
                                        (1 << BH_Dirty)|(1 << BH_Uptodate));
 
        head = create_page_buffers(page, inode,
                                        (1 << BH_Dirty)|(1 << BH_Uptodate));
@@ -1787,7 +1787,7 @@ static int __block_write_full_page(struct inode *inode, struct page *page,
        do {
                struct buffer_head *next = bh->b_this_page;
                if (buffer_async_write(bh)) {
        do {
                struct buffer_head *next = bh->b_this_page;
                if (buffer_async_write(bh)) {
-                       submit_bh_wbc(write_op, bh, 0, wbc);
+                       submit_bh_wbc(REQ_OP_WRITE, write_flags, bh, 0, wbc);
                        nr_underway++;
                }
                bh = next;
                        nr_underway++;
                }
                bh = next;
@@ -1841,7 +1841,7 @@ recover:
                struct buffer_head *next = bh->b_this_page;
                if (buffer_async_write(bh)) {
                        clear_buffer_dirty(bh);
                struct buffer_head *next = bh->b_this_page;
                if (buffer_async_write(bh)) {
                        clear_buffer_dirty(bh);
-                       submit_bh_wbc(write_op, bh, 0, wbc);
+                       submit_bh_wbc(REQ_OP_WRITE, write_flags, bh, 0, wbc);
                        nr_underway++;
                }
                bh = next;
                        nr_underway++;
                }
                bh = next;
@@ -1849,6 +1849,7 @@ recover:
        unlock_page(page);
        goto done;
 }
        unlock_page(page);
        goto done;
 }
+EXPORT_SYMBOL(__block_write_full_page);
 
 /*
  * If a page has any new buffers, zero them out here, and mark them uptodate
 
 /*
  * If a page has any new buffers, zero them out here, and mark them uptodate
@@ -2015,7 +2016,7 @@ int __block_write_begin_int(struct page *page, loff_t pos, unsigned len,
                if (!buffer_uptodate(bh) && !buffer_delay(bh) &&
                    !buffer_unwritten(bh) &&
                     (block_start < from || block_end > to)) {
                if (!buffer_uptodate(bh) && !buffer_delay(bh) &&
                    !buffer_unwritten(bh) &&
                     (block_start < from || block_end > to)) {
-                       ll_rw_block(READ, 1, &bh);
+                       ll_rw_block(REQ_OP_READ, 0, 1, &bh);
                        *wait_bh++=bh;
                }
        }
                        *wait_bh++=bh;
                }
        }
@@ -2314,7 +2315,7 @@ int block_read_full_page(struct page *page, get_block_t *get_block)
                if (buffer_uptodate(bh))
                        end_buffer_async_read(bh, 1);
                else
                if (buffer_uptodate(bh))
                        end_buffer_async_read(bh, 1);
                else
-                       submit_bh(READ, bh);
+                       submit_bh(REQ_OP_READ, 0, bh);
        }
        return 0;
 }
        }
        return 0;
 }
@@ -2648,7 +2649,7 @@ int nobh_write_begin(struct address_space *mapping,
                if (block_start < from || block_end > to) {
                        lock_buffer(bh);
                        bh->b_end_io = end_buffer_read_nobh;
                if (block_start < from || block_end > to) {
                        lock_buffer(bh);
                        bh->b_end_io = end_buffer_read_nobh;
-                       submit_bh(READ, bh);
+                       submit_bh(REQ_OP_READ, 0, bh);
                        nr_reads++;
                }
        }
                        nr_reads++;
                }
        }
@@ -2918,7 +2919,7 @@ int block_truncate_page(struct address_space *mapping,
 
        if (!buffer_uptodate(bh) && !buffer_delay(bh) && !buffer_unwritten(bh)) {
                err = -EIO;
 
        if (!buffer_uptodate(bh) && !buffer_delay(bh) && !buffer_unwritten(bh)) {
                err = -EIO;
-               ll_rw_block(READ, 1, &bh);
+               ll_rw_block(REQ_OP_READ, 0, 1, &bh);
                wait_on_buffer(bh);
                /* Uhhuh. Read error. Complain and punt. */
                if (!buffer_uptodate(bh))
                wait_on_buffer(bh);
                /* Uhhuh. Read error. Complain and punt. */
                if (!buffer_uptodate(bh))
@@ -3015,7 +3016,7 @@ static void end_bio_bh_io_sync(struct bio *bio)
  * errors, this only handles the "we need to be able to
  * do IO at the final sector" case.
  */
  * errors, this only handles the "we need to be able to
  * do IO at the final sector" case.
  */
-void guard_bio_eod(int rw, struct bio *bio)
+void guard_bio_eod(int op, struct bio *bio)
 {
        sector_t maxsector;
        struct bio_vec *bvec = &bio->bi_io_vec[bio->bi_vcnt - 1];
 {
        sector_t maxsector;
        struct bio_vec *bvec = &bio->bi_io_vec[bio->bi_vcnt - 1];
@@ -3045,13 +3046,13 @@ void guard_bio_eod(int rw, struct bio *bio)
        bvec->bv_len -= truncated_bytes;
 
        /* ..and clear the end of the buffer for reads */
        bvec->bv_len -= truncated_bytes;
 
        /* ..and clear the end of the buffer for reads */
-       if ((rw & RW_MASK) == READ) {
+       if (op == REQ_OP_READ) {
                zero_user(bvec->bv_page, bvec->bv_offset + bvec->bv_len,
                                truncated_bytes);
        }
 }
 
                zero_user(bvec->bv_page, bvec->bv_offset + bvec->bv_len,
                                truncated_bytes);
        }
 }
 
-static int submit_bh_wbc(int rw, struct buffer_head *bh,
+static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh,
                         unsigned long bio_flags, struct writeback_control *wbc)
 {
        struct bio *bio;
                         unsigned long bio_flags, struct writeback_control *wbc)
 {
        struct bio *bio;
@@ -3065,7 +3066,7 @@ static int submit_bh_wbc(int rw, struct buffer_head *bh,
        /*
         * Only clear out a write error when rewriting
         */
        /*
         * Only clear out a write error when rewriting
         */
-       if (test_set_buffer_req(bh) && (rw & WRITE))
+       if (test_set_buffer_req(bh) && (op == REQ_OP_WRITE))
                clear_buffer_write_io_error(bh);
 
        /*
                clear_buffer_write_io_error(bh);
 
        /*
@@ -3090,39 +3091,42 @@ static int submit_bh_wbc(int rw, struct buffer_head *bh,
        bio->bi_flags |= bio_flags;
 
        /* Take care of bh's that straddle the end of the device */
        bio->bi_flags |= bio_flags;
 
        /* Take care of bh's that straddle the end of the device */
-       guard_bio_eod(rw, bio);
+       guard_bio_eod(op, bio);
 
        if (buffer_meta(bh))
 
        if (buffer_meta(bh))
-               rw |= REQ_META;
+               op_flags |= REQ_META;
        if (buffer_prio(bh))
        if (buffer_prio(bh))
-               rw |= REQ_PRIO;
+               op_flags |= REQ_PRIO;
+       bio_set_op_attrs(bio, op, op_flags);
 
 
-       submit_bio(rw, bio);
+       submit_bio(bio);
        return 0;
 }
 
        return 0;
 }
 
-int _submit_bh(int rw, struct buffer_head *bh, unsigned long bio_flags)
+int _submit_bh(int op, int op_flags, struct buffer_head *bh,
+              unsigned long bio_flags)
 {
 {
-       return submit_bh_wbc(rw, bh, bio_flags, NULL);
+       return submit_bh_wbc(op, op_flags, bh, bio_flags, NULL);
 }
 EXPORT_SYMBOL_GPL(_submit_bh);
 
 }
 EXPORT_SYMBOL_GPL(_submit_bh);
 
-int submit_bh(int rw, struct buffer_head *bh)
+int submit_bh(int op, int op_flags,  struct buffer_head *bh)
 {
 {
-       return submit_bh_wbc(rw, bh, 0, NULL);
+       return submit_bh_wbc(op, op_flags, bh, 0, NULL);
 }
 EXPORT_SYMBOL(submit_bh);
 
 /**
  * ll_rw_block: low-level access to block devices (DEPRECATED)
 }
 EXPORT_SYMBOL(submit_bh);
 
 /**
  * ll_rw_block: low-level access to block devices (DEPRECATED)
- * @rw: whether to %READ or %WRITE or maybe %READA (readahead)
+ * @op: whether to %READ or %WRITE
+ * @op_flags: rq_flag_bits
  * @nr: number of &struct buffer_heads in the array
  * @bhs: array of pointers to &struct buffer_head
  *
  * ll_rw_block() takes an array of pointers to &struct buffer_heads, and
  * @nr: number of &struct buffer_heads in the array
  * @bhs: array of pointers to &struct buffer_head
  *
  * ll_rw_block() takes an array of pointers to &struct buffer_heads, and
- * requests an I/O operation on them, either a %READ or a %WRITE.  The third
- * %READA option is described in the documentation for generic_make_request()
- * which ll_rw_block() calls.
+ * requests an I/O operation on them, either a %REQ_OP_READ or a %REQ_OP_WRITE.
+ * @op_flags contains flags modifying the detailed I/O behavior, most notably
+ * %REQ_RAHEAD.
  *
  * This function drops any buffer that it cannot get a lock on (with the
  * BH_Lock state bit), any buffer that appears to be clean when doing a write
  *
  * This function drops any buffer that it cannot get a lock on (with the
  * BH_Lock state bit), any buffer that appears to be clean when doing a write
@@ -3138,7 +3142,7 @@ EXPORT_SYMBOL(submit_bh);
  * All of the buffers must be for the same device, and must also be a
  * multiple of the current approved size for the device.
  */
  * All of the buffers must be for the same device, and must also be a
  * multiple of the current approved size for the device.
  */
-void ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
+void ll_rw_block(int op, int op_flags,  int nr, struct buffer_head *bhs[])
 {
        int i;
 
 {
        int i;
 
@@ -3147,18 +3151,18 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
 
                if (!trylock_buffer(bh))
                        continue;
 
                if (!trylock_buffer(bh))
                        continue;
-               if (rw == WRITE) {
+               if (op == WRITE) {
                        if (test_clear_buffer_dirty(bh)) {
                                bh->b_end_io = end_buffer_write_sync;
                                get_bh(bh);
                        if (test_clear_buffer_dirty(bh)) {
                                bh->b_end_io = end_buffer_write_sync;
                                get_bh(bh);
-                               submit_bh(WRITE, bh);
+                               submit_bh(op, op_flags, bh);
                                continue;
                        }
                } else {
                        if (!buffer_uptodate(bh)) {
                                bh->b_end_io = end_buffer_read_sync;
                                get_bh(bh);
                                continue;
                        }
                } else {
                        if (!buffer_uptodate(bh)) {
                                bh->b_end_io = end_buffer_read_sync;
                                get_bh(bh);
-                               submit_bh(rw, bh);
+                               submit_bh(op, op_flags, bh);
                                continue;
                        }
                }
                                continue;
                        }
                }
@@ -3167,7 +3171,7 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
 }
 EXPORT_SYMBOL(ll_rw_block);
 
 }
 EXPORT_SYMBOL(ll_rw_block);
 
-void write_dirty_buffer(struct buffer_head *bh, int rw)
+void write_dirty_buffer(struct buffer_head *bh, int op_flags)
 {
        lock_buffer(bh);
        if (!test_clear_buffer_dirty(bh)) {
 {
        lock_buffer(bh);
        if (!test_clear_buffer_dirty(bh)) {
@@ -3176,7 +3180,7 @@ void write_dirty_buffer(struct buffer_head *bh, int rw)
        }
        bh->b_end_io = end_buffer_write_sync;
        get_bh(bh);
        }
        bh->b_end_io = end_buffer_write_sync;
        get_bh(bh);
-       submit_bh(rw, bh);
+       submit_bh(REQ_OP_WRITE, op_flags, bh);
 }
 EXPORT_SYMBOL(write_dirty_buffer);
 
 }
 EXPORT_SYMBOL(write_dirty_buffer);
 
@@ -3185,7 +3189,7 @@ EXPORT_SYMBOL(write_dirty_buffer);
  * and then start new I/O and then wait upon it.  The caller must have a ref on
  * the buffer_head.
  */
  * and then start new I/O and then wait upon it.  The caller must have a ref on
  * the buffer_head.
  */
-int __sync_dirty_buffer(struct buffer_head *bh, int rw)
+int __sync_dirty_buffer(struct buffer_head *bh, int op_flags)
 {
        int ret = 0;
 
 {
        int ret = 0;
 
@@ -3194,7 +3198,7 @@ int __sync_dirty_buffer(struct buffer_head *bh, int rw)
        if (test_clear_buffer_dirty(bh)) {
                get_bh(bh);
                bh->b_end_io = end_buffer_write_sync;
        if (test_clear_buffer_dirty(bh)) {
                get_bh(bh);
                bh->b_end_io = end_buffer_write_sync;
-               ret = submit_bh(rw, bh);
+               ret = submit_bh(REQ_OP_WRITE, op_flags, bh);
                wait_on_buffer(bh);
                if (!ret && !buffer_uptodate(bh))
                        ret = -EIO;
                wait_on_buffer(bh);
                if (!ret && !buffer_uptodate(bh))
                        ret = -EIO;
@@ -3457,7 +3461,7 @@ int bh_submit_read(struct buffer_head *bh)
 
        get_bh(bh);
        bh->b_end_io = end_buffer_read_sync;
 
        get_bh(bh);
        bh->b_end_io = end_buffer_read_sync;
-       submit_bh(READ, bh);
+       submit_bh(REQ_OP_READ, 0, bh);
        wait_on_buffer(bh);
        if (buffer_uptodate(bh))
                return 0;
        wait_on_buffer(bh);
        if (buffer_uptodate(bh))
                return 0;