]> git.pld-linux.org Git - packages/kernel.git/blob - linux-2.4.2-blkioctl-sector.patch
- obsolete
[packages/kernel.git] / linux-2.4.2-blkioctl-sector.patch
1 --- linux/include/linux/fs.h.sector     Mon Feb 26 23:48:46 2001
2 +++ linux/include/linux/fs.h    Mon Feb 26 23:53:57 2001
3 @@ -187,6 +187,8 @@
4  /* This was here just to show that the number is taken -
5     probably all these _IO(0x12,*) ioctls should be moved to blkpg.h. */
6  #endif
7 +#define BLKGETLASTSECT  _IO(0x12,108) /* get last sector of block device */
8 +#define BLKSETLASTSECT  _IO(0x12,109) /* get last sector of block device */
9  
10  
11  #define BMAP_IOCTL 1           /* obsolete - kept for compatibility */
12 --- linux/drivers/block/blkpg.c.sector  Fri Oct 27 02:35:47 2000
13 +++ linux/drivers/block/blkpg.c Mon Feb 26 23:53:57 2001
14 @@ -39,6 +39,9 @@
15  
16  #include <asm/uaccess.h>
17  
18 +static int set_last_sector( kdev_t dev, const void *param );
19 +static int get_last_sector( kdev_t dev, const void *param );
20 +
21  /*
22   * What is the data describing a partition?
23   *
24 @@ -210,6 +213,16 @@
25         int intval;
26  
27         switch (cmd) {
28 +               case BLKGETLASTSECT:
29 +                       return get_last_sector(dev, (char *)(arg));
30 +
31 +               case BLKSETLASTSECT:
32 +                       if( is_read_only(dev) )
33 +                               return -EACCES;
34 +                       if (!capable(CAP_SYS_ADMIN))
35 +                               return -EACCES;
36 +                       return set_last_sector(dev, (char *)(arg));
37 +
38                 case BLKROSET:
39                         if (!capable(CAP_SYS_ADMIN))
40                                 return -EACCES;
41 @@ -281,3 +294,209 @@
42  }
43  
44  EXPORT_SYMBOL(blk_ioctl);
45 +
46 + /*********************
47 +  * get_last_sector()
48 +  *  
49 +  * Description: This function will read any inaccessible blocks at the end
50 +  *    of a device
51 +  * Why: Normal read/write calls through the block layer will not read the 
52 +  *      last sector of an odd-size disk. 
53 +  * parameters: 
54 +  *    dev: kdev_t -- which device to read
55 +  *    param: a pointer to a userspace struct. The struct has these members: 
56 +  *    block:  an int which denotes which block to return:
57 +  *            0 == Last block
58 +  *            1 == Last block - 1
59 +  *            n == Last block - n
60 +  *            This is validated so that only values of 
61 +  *              <= ((total_sects + 1) % logical_block_size)  ||  0
62 +  *              are allowed.
63 +  *    block_contents: a pointer to userspace char*, this is where we write 
64 +  *     returned blocks to.
65 +  *    content_length: How big the userspace buffer is.
66 +  * return: 
67 +  *    0 on success
68 +  *   -ERRVAL on error.
69 +  *********************/
70 +int get_last_sector( kdev_t dev, const void *param )
71 +{   
72 +        struct buffer_head *bh;
73 +        struct gendisk *g;
74 +        int rc = 0;
75 +        unsigned int lastlba, readlba;
76 +        int orig_blksize = BLOCK_SIZE;
77 +        int hardblocksize;
78 +
79 +       struct {
80 +               unsigned int block;
81 +               size_t content_length;
82 +               char *block_contents;
83 +       } blk_ioctl_parameter;
84 +
85 +        if( !dev ) return -EINVAL;
86 +
87 +        if(copy_from_user(&blk_ioctl_parameter, param, sizeof(blk_ioctl_parameter)))
88 +               return -EFAULT;
89 +
90 +        g = get_gendisk( dev );
91 +
92 +        if( !g ) return -EINVAL;
93 +
94 +        lastlba = g->part[MINOR(dev)].nr_sects;
95 +
96 +        if( !lastlba ) return -EINVAL;
97 +
98 +        hardblocksize = get_hardsect_size(dev);
99 +        if( ! hardblocksize ) hardblocksize = 512;
100 +
101 +         /* Need to change the block size that the block layer uses */
102 +        if (blksize_size[MAJOR(dev)]){
103 +                orig_blksize = blksize_size[MAJOR(dev)][MINOR(dev)];
104 +        }
105 +
106 +         /* validate userspace input */
107 +        if( blk_ioctl_parameter.block == 0 )
108 +               goto good_params;
109 +
110 +       /* so we don't divide by zero below */  
111 +       if(orig_blksize == 0) 
112 +               return -EINVAL; 
113 +
114 +        if( blk_ioctl_parameter.block <= (lastlba % (orig_blksize / hardblocksize)))
115 +               goto good_params;
116 +
117 +       return -EINVAL; 
118 +
119 +good_params:
120 +        readlba = lastlba - blk_ioctl_parameter.block - 1;
121 +
122 +        if (orig_blksize != hardblocksize)
123 +                   set_blocksize(dev, hardblocksize);
124 +
125 +        bh =  bread(dev, readlba, hardblocksize);
126 +        if (!bh) {
127 +               /* We hit the end of the disk */
128 +               printk(KERN_WARNING
129 +                       "get_last_sector ioctl: bread returned NULL.\n");
130 +               return -1;
131 +        }
132 +
133 +        rc = copy_to_user(blk_ioctl_parameter.block_contents, bh->b_data, 
134 +               (bh->b_size > blk_ioctl_parameter.content_length) ? 
135 +               blk_ioctl_parameter.content_length : bh->b_size);
136 +
137 +        brelse(bh);
138 +
139 +        /* change block size back */
140 +        if (orig_blksize != hardblocksize)
141 +                   set_blocksize(dev, orig_blksize);
142 +   
143 +        return rc;
144 +}
145 +
146 + /*********************
147 +  * set_last_sector()
148 +  *  
149 +  * Description: This function will write to any inaccessible blocks at the end
150 +  *    of a device
151 +  * Why: Normal read/write calls through the block layer will not read the 
152 +  *      last sector of an odd-size disk. 
153 +  * parameters: 
154 +  *    dev: kdev_t -- which device to read
155 +  *    sect: a pointer to a userspace struct. The struct has these members: 
156 +  *    block:  an int which denotes which block to return:
157 +  *            0 == Last block
158 +  *            1 == Last block - 1
159 +  *            n == Last block - n
160 +  *            This is validated so that only values of 
161 +  *              <= ((total_sects + 1) % logical_block_size)  ||  0
162 +  *              are allowed.
163 +  *    block_contents: a pointer to userspace char*, this is where we write 
164 +  *     returned blocks to.
165 +  *    content_length: How big the userspace buffer is.
166 +  * return: 
167 +  *    0 on success
168 +  *   -ERRVAL on error.
169 +  *********************/
170 +int set_last_sector( kdev_t dev, const void *param ) 
171 +{
172 +        struct buffer_head *bh;
173 +        struct gendisk *g;
174 +        int rc = 0;
175 +        unsigned int lastlba, writelba;
176 +        int orig_blksize = BLOCK_SIZE;
177 +        int hardblocksize;
178 +
179 +       struct {
180 +               unsigned int block;
181 +               size_t content_length;
182 +               char *block_contents;
183 +       } blk_ioctl_parameter;
184 +
185 +        if( !dev ) return -EINVAL;
186 +
187 +       if(copy_from_user(&blk_ioctl_parameter, param, sizeof(blk_ioctl_parameter)))
188 +               return -EFAULT;
189 +
190 +        g = get_gendisk( dev );
191 +
192 +        if( !g ) return -EINVAL;
193 +    
194 +        lastlba = g->part[MINOR(dev)].nr_sects ;
195 +    
196 +        if( !lastlba ) return -EINVAL;
197 +    
198 +        hardblocksize = get_hardsect_size(dev);
199 +        if( ! hardblocksize ) hardblocksize = 512;
200 +    
201 +         /* Need to change the block size that the block layer uses */
202 +        if (blksize_size[MAJOR(dev)]){
203 +                orig_blksize = blksize_size[MAJOR(dev)][MINOR(dev)];
204 +        }
205 +
206 +         /* validate userspace input */
207 +        if( blk_ioctl_parameter.block == 0 )
208 +               goto good_params;
209 +
210 +       /* so we don't divide by zero below */  
211 +       if(orig_blksize == 0) 
212 +               return -EINVAL; 
213 +
214 +        if( blk_ioctl_parameter.block <= (lastlba % (orig_blksize / hardblocksize)))
215 +               goto good_params;
216 +
217 +       return -EINVAL; 
218 +
219 +good_params:
220 +        writelba = lastlba - blk_ioctl_parameter.block - 1;
221 +
222 +        if (orig_blksize != hardblocksize)
223 +                 set_blocksize(dev, hardblocksize);
224 +    
225 +        bh =  bread(dev, writelba, hardblocksize);
226 +        if (!bh) {
227 +               /* We hit the end of the disk */
228 +               printk(KERN_WARNING
229 +                       "get_last_sector ioctl: getblk returned NULL.\n");
230 +               return -1;
231 +        }
232 +    
233 +        copy_from_user(bh->b_data, blk_ioctl_parameter.block_contents, 
234 +               (bh->b_size > blk_ioctl_parameter.content_length) ? 
235 +               blk_ioctl_parameter.content_length : bh->b_size);
236 +    
237 +        mark_buffer_dirty(bh);
238 +        ll_rw_block (WRITE, 1, &bh);
239 +        wait_on_buffer (bh);
240 +        if (!buffer_uptodate(bh))
241 +          rc=-1; 
242 +    
243 +        brelse(bh);
244 +    
245 +        /* change block size back */
246 +        if (orig_blksize != hardblocksize)
247 +                 set_blocksize(dev, orig_blksize);
248 +       
249 +       return rc;
250 +}
251 --- linux/drivers/scsi/sd.c.sector      Mon Feb 26 23:48:45 2001
252 +++ linux/drivers/scsi/sd.c     Mon Feb 26 23:53:57 2001
253 @@ -228,6 +228,8 @@
254                 }
255                 case BLKGETSIZE:
256                 case BLKGETSIZE64:
257 +               case BLKGETLASTSECT:
258 +               case BLKSETLASTSECT:
259                 case BLKROSET:
260                 case BLKROGET:
261                 case BLKRASET:
262 --- linux/drivers/ide/ide.c.sector      Mon Feb 26 23:48:49 2001
263 +++ linux/drivers/ide/ide.c     Mon Feb 26 23:53:57 2001
264 @@ -2664,6 +2664,8 @@
265                         }
266                         return 0;
267                 }
268 +               case BLKGETLASTSECT:
269 +               case BLKSETLASTSECT:
270                 case BLKROSET:
271                 case BLKROGET:
272                 case BLKFLSBUF:
This page took 0.051656 seconds and 3 git commands to generate.