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
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. */
7 +#define BLKGETLASTSECT _IO(0x12,108) /* get last sector of block device */
8 +#define BLKSETLASTSECT _IO(0x12,109) /* get last sector of block device */
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
16 #include <asm/uaccess.h>
18 +static int set_last_sector( kdev_t dev, const void *param );
19 +static int get_last_sector( kdev_t dev, const void *param );
22 * What is the data describing a partition?
28 + case BLKGETLASTSECT:
29 + return get_last_sector(dev, (char *)(arg));
31 + case BLKSETLASTSECT:
32 + if( is_read_only(dev) )
34 + if (!capable(CAP_SYS_ADMIN))
36 + return set_last_sector(dev, (char *)(arg));
39 if (!capable(CAP_SYS_ADMIN))
44 EXPORT_SYMBOL(blk_ioctl);
46 + /*********************
49 + * Description: This function will read any inaccessible blocks at the end
51 + * Why: Normal read/write calls through the block layer will not read the
52 + * last sector of an odd-size disk.
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:
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
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.
69 + *********************/
70 +int get_last_sector( kdev_t dev, const void *param )
72 + struct buffer_head *bh;
75 + unsigned int lastlba, readlba;
76 + int orig_blksize = BLOCK_SIZE;
81 + size_t content_length;
82 + char *block_contents;
83 + } blk_ioctl_parameter;
85 + if( !dev ) return -EINVAL;
87 + if(copy_from_user(&blk_ioctl_parameter, param, sizeof(blk_ioctl_parameter)))
90 + g = get_gendisk( dev );
92 + if( !g ) return -EINVAL;
94 + lastlba = g->part[MINOR(dev)].nr_sects;
96 + if( !lastlba ) return -EINVAL;
98 + hardblocksize = get_hardsect_size(dev);
99 + if( ! hardblocksize ) hardblocksize = 512;
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)];
106 + /* validate userspace input */
107 + if( blk_ioctl_parameter.block == 0 )
110 + /* so we don't divide by zero below */
111 + if(orig_blksize == 0)
114 + if( blk_ioctl_parameter.block <= (lastlba % (orig_blksize / hardblocksize)))
120 + readlba = lastlba - blk_ioctl_parameter.block - 1;
122 + if (orig_blksize != hardblocksize)
123 + set_blocksize(dev, hardblocksize);
125 + bh = bread(dev, readlba, hardblocksize);
127 + /* We hit the end of the disk */
128 + printk(KERN_WARNING
129 + "get_last_sector ioctl: bread returned NULL.\n");
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);
139 + /* change block size back */
140 + if (orig_blksize != hardblocksize)
141 + set_blocksize(dev, orig_blksize);
146 + /*********************
147 + * set_last_sector()
149 + * Description: This function will write to any inaccessible blocks at the end
151 + * Why: Normal read/write calls through the block layer will not read the
152 + * last sector of an odd-size disk.
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:
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
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.
168 + * -ERRVAL on error.
169 + *********************/
170 +int set_last_sector( kdev_t dev, const void *param )
172 + struct buffer_head *bh;
175 + unsigned int lastlba, writelba;
176 + int orig_blksize = BLOCK_SIZE;
180 + unsigned int block;
181 + size_t content_length;
182 + char *block_contents;
183 + } blk_ioctl_parameter;
185 + if( !dev ) return -EINVAL;
187 + if(copy_from_user(&blk_ioctl_parameter, param, sizeof(blk_ioctl_parameter)))
190 + g = get_gendisk( dev );
192 + if( !g ) return -EINVAL;
194 + lastlba = g->part[MINOR(dev)].nr_sects ;
196 + if( !lastlba ) return -EINVAL;
198 + hardblocksize = get_hardsect_size(dev);
199 + if( ! hardblocksize ) hardblocksize = 512;
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)];
206 + /* validate userspace input */
207 + if( blk_ioctl_parameter.block == 0 )
210 + /* so we don't divide by zero below */
211 + if(orig_blksize == 0)
214 + if( blk_ioctl_parameter.block <= (lastlba % (orig_blksize / hardblocksize)))
220 + writelba = lastlba - blk_ioctl_parameter.block - 1;
222 + if (orig_blksize != hardblocksize)
223 + set_blocksize(dev, hardblocksize);
225 + bh = bread(dev, writelba, hardblocksize);
227 + /* We hit the end of the disk */
228 + printk(KERN_WARNING
229 + "get_last_sector ioctl: getblk returned NULL.\n");
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);
237 + mark_buffer_dirty(bh);
238 + ll_rw_block (WRITE, 1, &bh);
239 + wait_on_buffer (bh);
240 + if (!buffer_uptodate(bh))
245 + /* change block size back */
246 + if (orig_blksize != hardblocksize)
247 + set_blocksize(dev, orig_blksize);
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
257 + case BLKGETLASTSECT:
258 + case BLKSETLASTSECT:
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 @@
268 + case BLKGETLASTSECT:
269 + case BLKSETLASTSECT: