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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
  3.  */
  4. #include <linux/fs.h>
  5. #include <linux/reiserfs_fs.h>
  6. #include <linux/sched.h>
  7. #include <asm/uaccess.h>
  8. #include <linux/smp_lock.h>
  9. #include <linux/locks.h>
  10. /*
  11. ** reiserfs_ioctl - handler for ioctl for inode
  12. ** supported commands:
  13. **  1) REISERFS_IOC_UNPACK - try to unpack tail from direct item into indirect
  14. **                           and prevent packing file (argument arg has to be non-zero)
  15. **  2) That's all for a while ...
  16. */
  17. int reiserfs_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
  18. unsigned long arg)
  19. {
  20. switch (cmd) {
  21.     case REISERFS_IOC_UNPACK:
  22. if (arg)
  23.     return reiserfs_unpack (inode, filp);
  24.     default:
  25. return -ENOTTY;
  26. }
  27. }
  28. /*
  29. ** reiserfs_unpack
  30. ** Function try to convert tail from direct item into indirect.
  31. ** It set up nopack attribute in the inode.u.reiserfs_i.nopack
  32. */
  33. int reiserfs_unpack (struct inode * inode, struct file * filp)
  34. {
  35.     int retval = 0;
  36.     int index ;
  37.     struct page *page ;
  38.     unsigned long write_from ;
  39.     unsigned long blocksize = inode->i_sb->s_blocksize ;
  40.     
  41.     if (inode->i_size == 0) {
  42.         return -EINVAL ;
  43.     }
  44.     /* ioctl already done */
  45.     if (inode->u.reiserfs_i.i_flags & i_nopack_mask) {
  46.         return 0 ;
  47.     }
  48.     lock_kernel();
  49.     /* we need to make sure nobody is changing the file size beneath
  50.     ** us
  51.     */
  52.     down(&inode->i_sem) ;
  53.     write_from = inode->i_size & (blocksize - 1) ;
  54.     /* if we are on a block boundary, we are already unpacked.  */
  55.     if ( write_from == 0) {
  56. inode->u.reiserfs_i.i_flags |= i_nopack_mask;
  57. goto out ;
  58.     }
  59.     /* we unpack by finding the page with the tail, and calling
  60.     ** reiserfs_prepare_write on that page.  This will force a 
  61.     ** reiserfs_get_block to unpack the tail for us.
  62.     */
  63.     index = inode->i_size >> PAGE_CACHE_SHIFT ;
  64.     page = grab_cache_page(inode->i_mapping, index) ;
  65.     retval = -ENOMEM;
  66.     if (!page) {
  67.         goto out ;
  68.     }
  69.     retval = reiserfs_prepare_write(NULL, page, write_from, blocksize) ;
  70.     if (retval)
  71.         goto out_unlock ;
  72.     /* conversion can change page contents, must flush */
  73.     flush_dcache_page(page) ;
  74.     inode->u.reiserfs_i.i_flags |= i_nopack_mask;
  75.     kunmap(page) ; /* mapped by prepare_write */
  76. out_unlock:
  77.     UnlockPage(page) ;
  78.     page_cache_release(page) ;
  79. out:
  80.     up(&inode->i_sem) ;
  81.     unlock_kernel();    
  82.     return retval;
  83. }