aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/tree-defrag.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/tree-defrag.c')
-rw-r--r--fs/btrfs/tree-defrag.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/fs/btrfs/tree-defrag.c b/fs/btrfs/tree-defrag.c
index daf019afa0a1..3feac2f28628 100644
--- a/fs/btrfs/tree-defrag.c
+++ b/fs/btrfs/tree-defrag.c
@@ -27,13 +27,15 @@ static void reada_defrag(struct btrfs_root *root,
27{ 27{
28 int i; 28 int i;
29 u32 nritems; 29 u32 nritems;
30 u64 blocknr; 30 u64 bytenr;
31 u32 blocksize;
31 int ret; 32 int ret;
32 33
34 blocksize = btrfs_level_size(root, btrfs_header_level(node) - 1);
33 nritems = btrfs_header_nritems(node); 35 nritems = btrfs_header_nritems(node);
34 for (i = 0; i < nritems; i++) { 36 for (i = 0; i < nritems; i++) {
35 blocknr = btrfs_node_blockptr(node, i); 37 bytenr = btrfs_node_blockptr(node, i);
36 ret = readahead_tree_block(root, blocknr); 38 ret = readahead_tree_block(root, bytenr, blocksize);
37 if (ret) 39 if (ret)
38 break; 40 break;
39 } 41 }
@@ -46,7 +48,7 @@ static int defrag_walk_down(struct btrfs_trans_handle *trans,
46{ 48{
47 struct extent_buffer *next; 49 struct extent_buffer *next;
48 struct extent_buffer *cur; 50 struct extent_buffer *cur;
49 u64 blocknr; 51 u64 bytenr;
50 int ret = 0; 52 int ret = 0;
51 int is_extent = 0; 53 int is_extent = 0;
52 54
@@ -80,10 +82,11 @@ static int defrag_walk_down(struct btrfs_trans_handle *trans,
80 82
81 break; 83 break;
82 } 84 }
83 blocknr = btrfs_node_blockptr(cur, path->slots[*level]); 85 bytenr = btrfs_node_blockptr(cur, path->slots[*level]);
84 86
85 if (cache_only) { 87 if (cache_only) {
86 next = btrfs_find_tree_block(root, blocknr); 88 next = btrfs_find_tree_block(root, bytenr,
89 btrfs_level_size(root, *level - 1));
87 /* FIXME, test for defrag */ 90 /* FIXME, test for defrag */
88 if (!next || !btrfs_buffer_uptodate(next)) { 91 if (!next || !btrfs_buffer_uptodate(next)) {
89 free_extent_buffer(next); 92 free_extent_buffer(next);
@@ -91,7 +94,8 @@ static int defrag_walk_down(struct btrfs_trans_handle *trans,
91 continue; 94 continue;
92 } 95 }
93 } else { 96 } else {
94 next = read_tree_block(root, blocknr); 97 next = read_tree_block(root, bytenr,
98 btrfs_level_size(root, *level - 1));
95 } 99 }
96 ret = btrfs_cow_block(trans, root, next, path->nodes[*level], 100 ret = btrfs_cow_block(trans, root, next, path->nodes[*level],
97 path->slots[*level], &next); 101 path->slots[*level], &next);


                                                                  












                                                                            

                                                                           



                                                                            
                                                                    

                                                                      

                                                                   























































































































































                                                                               
                                
                                                                         



                                                                           














































































                                                                              
#ifndef _SCSI_GENERIC_H
#define _SCSI_GENERIC_H

#include <linux/compiler.h>

/*
   History:
    Started: Aug 9 by Lawrence Foard (entropy@world.std.com), to allow user
     process control of SCSI devices.
    Development Sponsored by Killy Corp. NY NY
Original driver (sg.h):
*       Copyright (C) 1992 Lawrence Foard
Version 2 and 3 extensions to driver:
*       Copyright (C) 1998 - 2006 Douglas Gilbert

    Version: 3.5.34 (20060920)
    This version is for 2.6 series kernels.

    For a full changelog see http://www.torque.net/sg

Map of SG verions to the Linux kernels in which they appear:
       ----------        ----------------------------------
       original          all kernels < 2.2.6
       2.1.40            2.2.20
       3.0.x             optional version 3 sg driver for 2.2 series
       3.1.17++          2.4.0++
       3.5.30++          2.6.0++

Major new features in SG 3.x driver (cf SG 2.x drivers)
	- SG_IO ioctl() combines function if write() and read()
	- new interface (sg_io_hdr_t) but still supports old interface
	- scatter/gather in user space, direct IO, and mmap supported

 The normal action of this driver is to use the adapter (HBA) driver to DMA
 data into kernel buffers and then use the CPU to copy the data into the 
 user space (vice versa for writes). That is called "indirect" IO due to 
 the double handling of data. There are two methods offered to remove the
 redundant copy: 1) direct IO and 2) using the mmap() system call to map
 the reserve buffer (this driver has one reserve buffer per fd) into the
 user space. Both have their advantages.
 In terms of absolute speed mmap() is faster. If speed is not a concern, 
 indirect IO should be fine. Read the documentation for more information.

 ** N.B. To use direct IO 'echo 1 > /proc/scsi/sg/allow_dio' or
         'echo 1 > /sys/module/sg/parameters/allow_dio' is needed.
         That attribute is 0 by default. **
 
 Historical note: this SCSI pass-through driver has been known as "sg" for 
 a decade. In broader kernel discussions "sg" is used to refer to scatter
 gather techniques. The context should clarify which "sg" is referred to.

 Documentation
 =============
 A web site for the SG device driver can be found at:
	http://www.torque.net/sg  [alternatively check the MAINTAINERS file]
 The documentation for the sg version 3 driver can be found at:
 	http://www.torque.net/sg/p/sg_v3_ho.html
 This is a rendering from DocBook source [change the extension to "sgml"
 or "xml"]. There are renderings in "ps", "pdf", "rtf" and "txt" (soon).
 The SG_IO ioctl is now found in other parts kernel (e.g. the block layer).
 For more information see http://www.torque.net/sg/sg_io.html

 The older, version 2 documents discuss the original sg interface in detail:
	http://www.torque.net/sg/p/scsi-generic.txt
	http://www.torque.net/sg/p/scsi-generic_long.txt
 Also available: <kernel_source>/Documentation/scsi/scsi-generic.txt

 Utility and test programs are available at the sg web site. They are 
 packaged as sg3_utils (for the lk 2.4 and 2.6 series) and sg_utils
 (for the lk 2.2 series).
*/


/* New interface introduced in the 3.x SG drivers follows */

typedef struct sg_iovec /* same structure as used by readv() Linux system */
{                       /* call. It defines one scatter-gather element. */
    void __user *iov_base;      /* Starting address  */
    size_t iov_len;             /* Length in bytes  */
} sg_iovec_t;


typedef struct sg_io_hdr
{
    int interface_id;           /* [i] 'S' for SCSI generic (required) */
    int dxfer_direction;        /* [i] data transfer direction  */
    unsigned char cmd_len;      /* [i] SCSI command length ( <= 16 bytes) */
    unsigned char mx_sb_len;    /* [i] max length to write to sbp */
    unsigned short iovec_count; /* [i] 0 implies no scatter gather */
    unsigned int dxfer_len;     /* [i] byte count of data transfer */
    void __user *dxferp;	/* [i], [*io] points to data transfer memory
					      or scatter gather list */
    unsigned char __user *cmdp; /* [i], [*i] points to command to perform */
    void __user *sbp;		/* [i], [*o] points to sense_buffer memory */
    unsigned int timeout;       /* [i] MAX_UINT->no timeout (unit: millisec) */
    unsigned int flags;         /* [i] 0 -> default, see SG_FLAG... */
    int pack_id;                /* [i->o] unused internally (normally) */
    void __user * usr_ptr;      /* [i->o] unused internally */
    unsigned char status;       /* [o] scsi status */
    unsigned char masked_status;/* [o] shifted, masked scsi status */
    unsigned char msg_status;   /* [o] messaging level data (optional) */
    unsigned char sb_len_wr;    /* [o] byte count actually written to sbp */
    unsigned short host_status; /* [o] errors from host adapter */
    unsigned short driver_status;/* [o] errors from software driver */
    int resid;                  /* [o] dxfer_len - actual_transferred */
    unsigned int duration;      /* [o] time taken by cmd (unit: millisec) */
    unsigned int info;          /* [o] auxiliary information */
} sg_io_hdr_t;  /* 64 bytes long (on i386) */

#define SG_INTERFACE_ID_ORIG 'S'

/* Use negative values to flag difference from original sg_header structure */
#define SG_DXFER_NONE (-1)      /* e.g. a SCSI Test Unit Ready command */
#define SG_DXFER_TO_DEV (-2)    /* e.g. a SCSI WRITE command */
#define SG_DXFER_FROM_DEV (-3)  /* e.g. a SCSI READ command */
#define SG_DXFER_TO_FROM_DEV (-4) /* treated like SG_DXFER_FROM_DEV with the
				   additional property than during indirect
				   IO the user buffer is copied into the
				   kernel buffers before the transfer */
#define SG_DXFER_UNKNOWN (-5)   /* Unknown data direction */

/* following flag values can be "or"-ed together */
#define SG_FLAG_DIRECT_IO 1     /* default is indirect IO */
#define SG_FLAG_UNUSED_LUN_INHIBIT 2   /* default is overwrite lun in SCSI */
				/* command block (when <= SCSI_2) */
#define SG_FLAG_MMAP_IO 4       /* request memory mapped IO */
#define SG_FLAG_NO_DXFER 0x10000 /* no transfer of kernel buffers to/from */
				/* user space (debug indirect IO) */

/* following 'info' values are "or"-ed together */
#define SG_INFO_OK_MASK 0x1
#define SG_INFO_OK 0x0          /* no sense, host nor driver "noise" */
#define SG_INFO_CHECK 0x1       /* something abnormal happened */

#define SG_INFO_DIRECT_IO_MASK 0x6
#define SG_INFO_INDIRECT_IO 0x0 /* data xfer via kernel buffers (or no xfer) */
#define SG_INFO_DIRECT_IO 0x2   /* direct IO requested and performed */
#define SG_INFO_MIXED_IO 0x4    /* part direct, part indirect IO */


typedef struct sg_scsi_id { /* used by SG_GET_SCSI_ID ioctl() */
    int host_no;        /* as in "scsi<n>" where 'n' is one of 0, 1, 2 etc */
    int channel;
    int scsi_id;        /* scsi id of target device */
    int lun;
    int scsi_type;      /* TYPE_... defined in scsi/scsi.h */
    short h_cmd_per_lun;/* host (adapter) maximum commands per lun */
    short d_queue_depth;/* device (or adapter) maximum queue length */
    int unused[2];      /* probably find a good use, set 0 for now */
} sg_scsi_id_t; /* 32 bytes long on i386 */

typedef struct sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */
    char req_state;     /* 0 -> not used, 1 -> written, 2 -> ready to read */
    char orphan;        /* 0 -> normal request, 1 -> from interruped SG_IO */