nbd.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:13k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Network block device - make block devices work over TCP
  3.  *
  4.  * Note that you can not swap over this thing, yet. Seems to work but
  5.  * deadlocks sometimes - you can not swap over TCP in general.
  6.  * 
  7.  * Copyright 1997-2000 Pavel Machek <pavel@ucw.cz>
  8.  * Parts copyright 2001 Steven Whitehouse <steve@chygwyn.com>
  9.  *
  10.  * (part of code stolen from loop.c)
  11.  *
  12.  * 97-3-25 compiled 0-th version, not yet tested it 
  13.  *   (it did not work, BTW) (later that day) HEY! it works!
  14.  *   (bit later) hmm, not that much... 2:00am next day:
  15.  *   yes, it works, but it gives something like 50kB/sec
  16.  * 97-4-01 complete rewrite to make it possible for many requests at 
  17.  *   once to be processed
  18.  * 97-4-11 Making protocol independent of endianity etc.
  19.  * 97-9-13 Cosmetic changes
  20.  * 98-5-13 Attempt to make 64-bit-clean on 64-bit machines
  21.  * 99-1-11 Attempt to make 64-bit-clean on 32-bit machines <ankry@mif.pg.gda.pl>
  22.  * 01-2-27 Fix to store proper blockcount for kernel (calculated using
  23.  *   BLOCK_SIZE_BITS, not device blocksize) <aga@permonline.ru>
  24.  * 01-3-11 Make nbd work with new Linux block layer code. It now supports
  25.  *   plugging like all the other block devices. Also added in MSG_MORE to
  26.  *   reduce number of partial TCP segments sent. <steve@chygwyn.com>
  27.  *
  28.  * possible FIXME: make set_sock / set_blksize / set_size / do_it one syscall
  29.  * why not: would need verify_area and friends, would share yet another 
  30.  *          structure with userland
  31.  */
  32. #define PARANOIA
  33. #include <linux/major.h>
  34. #include <linux/module.h>
  35. #include <linux/init.h>
  36. #include <linux/sched.h>
  37. #include <linux/fs.h>
  38. #include <linux/stat.h>
  39. #include <linux/errno.h>
  40. #include <linux/file.h>
  41. #include <linux/ioctl.h>
  42. #include <net/sock.h>
  43. #include <linux/devfs_fs_kernel.h>
  44. #include <asm/uaccess.h>
  45. #include <asm/types.h>
  46. #define MAJOR_NR NBD_MAJOR
  47. #include <linux/nbd.h>
  48. #define LO_MAGIC 0x68797548
  49. static int nbd_blksizes[MAX_NBD];
  50. static int nbd_blksize_bits[MAX_NBD];
  51. static int nbd_sizes[MAX_NBD];
  52. static u64 nbd_bytesizes[MAX_NBD];
  53. static struct nbd_device nbd_dev[MAX_NBD];
  54. static devfs_handle_t devfs_handle;
  55. #define DEBUG( s )
  56. /* #define DEBUG( s ) printk( s ) 
  57.  */
  58. #ifdef PARANOIA
  59. static int requests_in;
  60. static int requests_out;
  61. #endif
  62. static int nbd_open(struct inode *inode, struct file *file)
  63. {
  64. int dev;
  65. if (!inode)
  66. return -EINVAL;
  67. dev = MINOR(inode->i_rdev);
  68. if (dev >= MAX_NBD)
  69. return -ENODEV;
  70. nbd_dev[dev].refcnt++;
  71. return 0;
  72. }
  73. /*
  74.  *  Send or receive packet.
  75.  */
  76. static int nbd_xmit(int send, struct socket *sock, char *buf, int size, int msg_flags)
  77. {
  78. mm_segment_t oldfs;
  79. int result;
  80. struct msghdr msg;
  81. struct iovec iov;
  82. unsigned long flags;
  83. sigset_t oldset;
  84. oldfs = get_fs();
  85. set_fs(get_ds());
  86. spin_lock_irqsave(&current->sigmask_lock, flags);
  87. oldset = current->blocked;
  88. sigfillset(&current->blocked);
  89. recalc_sigpending(current);
  90. spin_unlock_irqrestore(&current->sigmask_lock, flags);
  91. do {
  92. sock->sk->allocation = GFP_NOIO;
  93. iov.iov_base = buf;
  94. iov.iov_len = size;
  95. msg.msg_name = NULL;
  96. msg.msg_namelen = 0;
  97. msg.msg_iov = &iov;
  98. msg.msg_iovlen = 1;
  99. msg.msg_control = NULL;
  100. msg.msg_controllen = 0;
  101. msg.msg_namelen = 0;
  102. msg.msg_flags = msg_flags | MSG_NOSIGNAL;
  103. if (send)
  104. result = sock_sendmsg(sock, &msg, size);
  105. else
  106. result = sock_recvmsg(sock, &msg, size, 0);
  107. if (result <= 0) {
  108. #ifdef PARANOIA
  109. printk(KERN_ERR "NBD: %s - sock=%ld at buf=%ld, size=%d returned %d.n",
  110.        send ? "send" : "receive", (long) sock, (long) buf, size, result);
  111. #endif
  112. break;
  113. }
  114. size -= result;
  115. buf += result;
  116. } while (size > 0);
  117. spin_lock_irqsave(&current->sigmask_lock, flags);
  118. current->blocked = oldset;
  119. recalc_sigpending(current);
  120. spin_unlock_irqrestore(&current->sigmask_lock, flags);
  121. set_fs(oldfs);
  122. return result;
  123. }
  124. #define FAIL( s ) { printk( KERN_ERR "NBD: " s "(result %d)n", result ); goto error_out; }
  125. void nbd_send_req(struct socket *sock, struct request *req)
  126. {
  127. int result;
  128. struct nbd_request request;
  129. unsigned long size = req->nr_sectors << 9;
  130. DEBUG("NBD: sending control, ");
  131. request.magic = htonl(NBD_REQUEST_MAGIC);
  132. request.type = htonl(req->cmd);
  133. request.from = cpu_to_be64( (u64) req->sector << 9);
  134. request.len = htonl(size);
  135. memcpy(request.handle, &req, sizeof(req));
  136. result = nbd_xmit(1, sock, (char *) &request, sizeof(request), req->cmd == WRITE ? MSG_MORE : 0);
  137. if (result <= 0)
  138. FAIL("Sendmsg failed for control.");
  139. if (req->cmd == WRITE) {
  140. struct buffer_head *bh = req->bh;
  141. DEBUG("data, ");
  142. do {
  143. result = nbd_xmit(1, sock, bh->b_data, bh->b_size, bh->b_reqnext == NULL ? 0 : MSG_MORE);
  144. if (result <= 0)
  145. FAIL("Send data failed.");
  146. bh = bh->b_reqnext;
  147. } while(bh);
  148. }
  149. return;
  150.       error_out:
  151. req->errors++;
  152. }
  153. #define HARDFAIL( s ) { printk( KERN_ERR "NBD: " s "(result %d)n", result ); lo->harderror = result; return NULL; }
  154. struct request *nbd_read_stat(struct nbd_device *lo)
  155. /* NULL returned = something went wrong, inform userspace       */ 
  156. {
  157. int result;
  158. struct nbd_reply reply;
  159. struct request *xreq, *req;
  160. DEBUG("reading control, ");
  161. reply.magic = 0;
  162. result = nbd_xmit(0, lo->sock, (char *) &reply, sizeof(reply), MSG_WAITALL);
  163. if (result <= 0)
  164. HARDFAIL("Recv control failed.");
  165. memcpy(&xreq, reply.handle, sizeof(xreq));
  166. req = blkdev_entry_prev_request(&lo->queue_head);
  167. if (xreq != req)
  168. FAIL("Unexpected handle received.n");
  169. DEBUG("ok, ");
  170. if (ntohl(reply.magic) != NBD_REPLY_MAGIC)
  171. HARDFAIL("Not enough magic.");
  172. if (ntohl(reply.error))
  173. FAIL("Other side returned error.");
  174. if (req->cmd == READ) {
  175. struct buffer_head *bh = req->bh;
  176. DEBUG("data, ");
  177. do {
  178. result = nbd_xmit(0, lo->sock, bh->b_data, bh->b_size, MSG_WAITALL);
  179. if (result <= 0)
  180. HARDFAIL("Recv data failed.");
  181. bh = bh->b_reqnext;
  182. } while(bh);
  183. }
  184. DEBUG("done.n");
  185. return req;
  186. /* Can we get here? Yes, if other side returns error */
  187.       error_out:
  188. req->errors++;
  189. return req;
  190. }
  191. void nbd_do_it(struct nbd_device *lo)
  192. {
  193. struct request *req;
  194. down (&lo->queue_lock);
  195. while (1) {
  196. up (&lo->queue_lock);
  197. req = nbd_read_stat(lo);
  198. down (&lo->queue_lock);
  199. if (!req) {
  200. printk(KERN_ALERT "req should never be nulln" );
  201. goto out;
  202. }
  203. #ifdef PARANOIA
  204. if (req != blkdev_entry_prev_request(&lo->queue_head)) {
  205. printk(KERN_ALERT "NBD: I have problem...n");
  206. }
  207. if (lo != &nbd_dev[MINOR(req->rq_dev)]) {
  208. printk(KERN_ALERT "NBD: request corrupted!n");
  209. continue;
  210. }
  211. if (lo->magic != LO_MAGIC) {
  212. printk(KERN_ALERT "NBD: nbd_dev[] corrupted: Not enough magicn");
  213. goto out;
  214. }
  215. #endif
  216. list_del(&req->queue);
  217. up (&lo->queue_lock);
  218. nbd_end_request(req);
  219. down (&lo->queue_lock);
  220. }
  221.  out:
  222. up (&lo->queue_lock);
  223. }
  224. void nbd_clear_que(struct nbd_device *lo)
  225. {
  226. struct request *req;
  227. #ifdef PARANOIA
  228. if (lo->magic != LO_MAGIC) {
  229. printk(KERN_ERR "NBD: nbd_dev[] corrupted: Not enough magic when clearing!n");
  230. return;
  231. }
  232. #endif
  233. while (!list_empty(&lo->queue_head)) {
  234. req = blkdev_entry_prev_request(&lo->queue_head);
  235. #ifdef PARANOIA
  236. if (!req) {
  237. printk( KERN_ALERT "NBD: panic, panic, panicn" );
  238. break;
  239. }
  240. if (lo != &nbd_dev[MINOR(req->rq_dev)]) {
  241. printk(KERN_ALERT "NBD: request corrupted when clearing!n");
  242. continue;
  243. }
  244. #endif
  245. req->errors++;
  246. list_del(&req->queue);
  247. up(&lo->queue_lock);
  248. nbd_end_request(req);
  249. down(&lo->queue_lock);
  250. }
  251. }
  252. /*
  253.  * We always wait for result of write, for now. It would be nice to make it optional
  254.  * in future
  255.  * if ((req->cmd == WRITE) && (lo->flags & NBD_WRITE_NOCHK)) 
  256.  *   { printk( "Warning: Ignoring result!n"); nbd_end_request( req ); }
  257.  */
  258. #undef FAIL
  259. #define FAIL( s ) { printk( KERN_ERR "NBD, minor %d: " s "n", dev ); goto error_out; }
  260. static void do_nbd_request(request_queue_t * q)
  261. {
  262. struct request *req;
  263. int dev = 0;
  264. struct nbd_device *lo;
  265. while (!QUEUE_EMPTY) {
  266. req = CURRENT;
  267. #ifdef PARANOIA
  268. if (!req)
  269. FAIL("que not empty but no request?");
  270. #endif
  271. dev = MINOR(req->rq_dev);
  272. #ifdef PARANOIA
  273. if (dev >= MAX_NBD)
  274. FAIL("Minor too big."); /* Probably can not happen */
  275. #endif
  276. lo = &nbd_dev[dev];
  277. if (!lo->file)
  278. FAIL("Request when not-ready.");
  279. if ((req->cmd == WRITE) && (lo->flags & NBD_READ_ONLY))
  280. FAIL("Write on read-only");
  281. #ifdef PARANOIA
  282. if (lo->magic != LO_MAGIC)
  283. FAIL("nbd[] is not magical!");
  284. requests_in++;
  285. #endif
  286. req->errors = 0;
  287. blkdev_dequeue_request(req);
  288. spin_unlock_irq(&io_request_lock);
  289. down (&lo->queue_lock);
  290. list_add(&req->queue, &lo->queue_head);
  291. nbd_send_req(lo->sock, req); /* Why does this block?         */
  292. up (&lo->queue_lock);
  293. spin_lock_irq(&io_request_lock);
  294. continue;
  295.       error_out:
  296. req->errors++;
  297. blkdev_dequeue_request(req);
  298. spin_unlock(&io_request_lock);
  299. nbd_end_request(req);
  300. spin_lock(&io_request_lock);
  301. }
  302. return;
  303. }
  304. static int nbd_ioctl(struct inode *inode, struct file *file,
  305.      unsigned int cmd, unsigned long arg)
  306. {
  307. struct nbd_device *lo;
  308. int dev, error, temp;
  309. struct request sreq ;
  310. /* Anyone capable of this syscall can do *real bad* things */
  311. if (!capable(CAP_SYS_ADMIN))
  312. return -EPERM;
  313. if (!inode)
  314. return -EINVAL;
  315. dev = MINOR(inode->i_rdev);
  316. if (dev >= MAX_NBD)
  317. return -ENODEV;
  318. lo = &nbd_dev[dev];
  319. switch (cmd) {
  320. case NBD_DISCONNECT:
  321.         printk("NBD_DISCONNECTn") ;
  322.                 sreq.cmd=2 ; /* shutdown command */
  323.                 if (!lo->sock) return -EINVAL ;
  324.                 nbd_send_req(lo->sock,&sreq) ;
  325.                 return 0 ;
  326.  
  327. case NBD_CLEAR_SOCK:
  328. down(&lo->queue_lock);
  329. nbd_clear_que(lo);
  330. if (!list_empty(&lo->queue_head)) {
  331. up(&lo->queue_lock);
  332. printk(KERN_ERR "nbd: Some requests are in progress -> can not turn off.n");
  333. return -EBUSY;
  334. }
  335. up(&lo->queue_lock);
  336. file = lo->file;
  337. if (!file)
  338. return -EINVAL;
  339. lo->file = NULL;
  340. lo->sock = NULL;
  341. fput(file);
  342. return 0;
  343. case NBD_SET_SOCK:
  344. if (lo->file)
  345. return -EBUSY;
  346. error = -EINVAL;
  347. file = fget(arg);
  348. if (file) {
  349. inode = file->f_dentry->d_inode;
  350. /* N.B. Should verify that it's a socket */
  351. lo->file = file;
  352. lo->sock = &inode->u.socket_i;
  353. error = 0;
  354. }
  355. return error;
  356. case NBD_SET_BLKSIZE:
  357. if ((arg & (arg-1)) || (arg < 512) || (arg > PAGE_SIZE))
  358. return -EINVAL;
  359. nbd_blksizes[dev] = arg;
  360. temp = arg >> 9;
  361. nbd_blksize_bits[dev] = 9;
  362. while (temp > 1) {
  363. nbd_blksize_bits[dev]++;
  364. temp >>= 1;
  365. }
  366. nbd_bytesizes[dev] &= ~(nbd_blksizes[dev]-1); 
  367. nbd_sizes[dev] = nbd_bytesizes[dev] >> BLOCK_SIZE_BITS;
  368. return 0;
  369. case NBD_SET_SIZE:
  370. nbd_bytesizes[dev] = arg & ~(nbd_blksizes[dev]-1); 
  371. nbd_sizes[dev] = nbd_bytesizes[dev] >> BLOCK_SIZE_BITS;
  372. return 0;
  373. case NBD_SET_SIZE_BLOCKS:
  374. nbd_bytesizes[dev] = ((u64) arg) << nbd_blksize_bits[dev]; 
  375. nbd_sizes[dev] = nbd_bytesizes[dev] >> BLOCK_SIZE_BITS;
  376. return 0;
  377. case NBD_DO_IT:
  378. if (!lo->file)
  379. return -EINVAL;
  380. nbd_do_it(lo);
  381. return lo->harderror;
  382. case NBD_CLEAR_QUE:
  383. nbd_clear_que(lo);
  384. return 0;
  385. #ifdef PARANOIA
  386. case NBD_PRINT_DEBUG:
  387. printk(KERN_INFO "NBD device %d: next = %p, prev = %p. Global: in %d, out %dn",
  388.        dev, lo->queue_head.next, lo->queue_head.prev, requests_in, requests_out);
  389. return 0;
  390. #endif
  391. case BLKGETSIZE:
  392. return put_user(nbd_bytesizes[dev] >> 9, (unsigned long *) arg);
  393. case BLKGETSIZE64:
  394. return put_user((u64)nbd_bytesizes[dev], (u64 *) arg);
  395. }
  396. return -EINVAL;
  397. }
  398. static int nbd_release(struct inode *inode, struct file *file)
  399. {
  400. struct nbd_device *lo;
  401. int dev;
  402. if (!inode)
  403. return -ENODEV;
  404. dev = MINOR(inode->i_rdev);
  405. if (dev >= MAX_NBD)
  406. return -ENODEV;
  407. lo = &nbd_dev[dev];
  408. if (lo->refcnt <= 0)
  409. printk(KERN_ALERT "nbd_release: refcount(%d) <= 0n", lo->refcnt);
  410. lo->refcnt--;
  411. /* N.B. Doesn't lo->file need an fput?? */
  412. return 0;
  413. }
  414. static struct block_device_operations nbd_fops =
  415. {
  416. owner: THIS_MODULE,
  417. open: nbd_open,
  418. release: nbd_release,
  419. ioctl: nbd_ioctl,
  420. };
  421. /*
  422.  * And here should be modules and kernel interface 
  423.  *  (Just smiley confuses emacs :-)
  424.  */
  425. static int __init nbd_init(void)
  426. {
  427. int i;
  428. if (sizeof(struct nbd_request) != 28) {
  429. printk(KERN_CRIT "Sizeof nbd_request needs to be 28 in order to work!n" );
  430. return -EIO;
  431. }
  432. if (register_blkdev(MAJOR_NR, "nbd", &nbd_fops)) {
  433. printk("Unable to get major number %d for NBDn",
  434.        MAJOR_NR);
  435. return -EIO;
  436. }
  437. #ifdef MODULE
  438. printk("nbd: registered device at major %dn", MAJOR_NR);
  439. #endif
  440. blksize_size[MAJOR_NR] = nbd_blksizes;
  441. blk_size[MAJOR_NR] = nbd_sizes;
  442. blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_nbd_request);
  443. blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0);
  444. for (i = 0; i < MAX_NBD; i++) {
  445. nbd_dev[i].refcnt = 0;
  446. nbd_dev[i].file = NULL;
  447. nbd_dev[i].magic = LO_MAGIC;
  448. nbd_dev[i].flags = 0;
  449. INIT_LIST_HEAD(&nbd_dev[i].queue_head);
  450. init_MUTEX(&nbd_dev[i].queue_lock);
  451. nbd_blksizes[i] = 1024;
  452. nbd_blksize_bits[i] = 10;
  453. nbd_bytesizes[i] = 0x7ffffc00; /* 2GB */
  454. nbd_sizes[i] = nbd_bytesizes[i] >> BLOCK_SIZE_BITS;
  455. register_disk(NULL, MKDEV(MAJOR_NR,i), 1, &nbd_fops,
  456. nbd_bytesizes[i]>>9);
  457. }
  458. devfs_handle = devfs_mk_dir (NULL, "nbd", NULL);
  459. devfs_register_series (devfs_handle, "%u", MAX_NBD,
  460.        DEVFS_FL_DEFAULT, MAJOR_NR, 0,
  461.        S_IFBLK | S_IRUSR | S_IWUSR,
  462.        &nbd_fops, NULL);
  463. return 0;
  464. }
  465. static void __exit nbd_cleanup(void)
  466. {
  467. devfs_unregister (devfs_handle);
  468. blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
  469. if (unregister_blkdev(MAJOR_NR, "nbd") != 0)
  470. printk("nbd: cleanup_module failedn");
  471. else
  472. printk("nbd: module cleaned up.n");
  473. }
  474. module_init(nbd_init);
  475. module_exit(nbd_cleanup);
  476. MODULE_DESCRIPTION("Network Block Device");
  477. MODULE_LICENSE("GPL");