ioctl.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:4k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * linux/fs/ext3/ioctl.c
  3.  *
  4.  * Copyright (C) 1993, 1994, 1995
  5.  * Remy Card (card@masi.ibp.fr)
  6.  * Laboratoire MASI - Institut Blaise Pascal
  7.  * Universite Pierre et Marie Curie (Paris VI)
  8.  */
  9. #include <linux/fs.h>
  10. #include <linux/jbd.h>
  11. #include <linux/ext3_fs.h>
  12. #include <linux/ext3_jbd.h>
  13. #include <linux/sched.h>
  14. #include <asm/uaccess.h>
  15. int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
  16. unsigned long arg)
  17. {
  18. unsigned int flags;
  19. ext3_debug ("cmd = %u, arg = %lun", cmd, arg);
  20. switch (cmd) {
  21. case EXT3_IOC_GETFLAGS:
  22. flags = inode->u.ext3_i.i_flags & EXT3_FL_USER_VISIBLE;
  23. return put_user(flags, (int *) arg);
  24. case EXT3_IOC_SETFLAGS: {
  25. handle_t *handle = NULL;
  26. int err;
  27. struct ext3_iloc iloc;
  28. unsigned int oldflags;
  29. unsigned int jflag;
  30. if (IS_RDONLY(inode))
  31. return -EROFS;
  32. if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
  33. return -EACCES;
  34. if (get_user(flags, (int *) arg))
  35. return -EFAULT;
  36. oldflags = inode->u.ext3_i.i_flags;
  37. /* The JOURNAL_DATA flag is modifiable only by root */
  38. jflag = flags & EXT3_JOURNAL_DATA_FL;
  39. /*
  40.  * The IMMUTABLE and APPEND_ONLY flags can only be changed by
  41.  * the relevant capability.
  42.  *
  43.  * This test looks nicer. Thanks to Pauline Middelink
  44.  */
  45. if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FL)) {
  46. if (!capable(CAP_LINUX_IMMUTABLE))
  47. return -EPERM;
  48. }
  49. /*
  50.  * The JOURNAL_DATA flag can only be changed by
  51.  * the relevant capability.
  52.  */
  53. if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL)) {
  54. if (!capable(CAP_SYS_RESOURCE))
  55. return -EPERM;
  56. }
  57. handle = ext3_journal_start(inode, 1);
  58. if (IS_ERR(handle))
  59. return PTR_ERR(handle);
  60. if (IS_SYNC(inode))
  61. handle->h_sync = 1;
  62. err = ext3_reserve_inode_write(handle, inode, &iloc);
  63. if (err)
  64. goto flags_err;
  65. flags = flags & EXT3_FL_USER_MODIFIABLE;
  66. flags |= oldflags & ~EXT3_FL_USER_MODIFIABLE;
  67. inode->u.ext3_i.i_flags = flags;
  68. if (flags & EXT3_SYNC_FL)
  69. inode->i_flags |= S_SYNC;
  70. else
  71. inode->i_flags &= ~S_SYNC;
  72. if (flags & EXT3_APPEND_FL)
  73. inode->i_flags |= S_APPEND;
  74. else
  75. inode->i_flags &= ~S_APPEND;
  76. if (flags & EXT3_IMMUTABLE_FL)
  77. inode->i_flags |= S_IMMUTABLE;
  78. else
  79. inode->i_flags &= ~S_IMMUTABLE;
  80. if (flags & EXT3_NOATIME_FL)
  81. inode->i_flags |= S_NOATIME;
  82. else
  83. inode->i_flags &= ~S_NOATIME;
  84. inode->i_ctime = CURRENT_TIME;
  85. err = ext3_mark_iloc_dirty(handle, inode, &iloc);
  86. flags_err:
  87. ext3_journal_stop(handle, inode);
  88. if (err)
  89. return err;
  90. if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL))
  91. err = ext3_change_inode_journal_flag(inode, jflag);
  92. return err;
  93. }
  94. case EXT3_IOC_GETVERSION:
  95. case EXT3_IOC_GETVERSION_OLD:
  96. return put_user(inode->i_generation, (int *) arg);
  97. case EXT3_IOC_SETVERSION:
  98. case EXT3_IOC_SETVERSION_OLD: {
  99. handle_t *handle;
  100. struct ext3_iloc iloc;
  101. __u32 generation;
  102. int err;
  103. if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
  104. return -EPERM;
  105. if (IS_RDONLY(inode))
  106. return -EROFS;
  107. if (get_user(generation, (int *) arg))
  108. return -EFAULT;
  109. handle = ext3_journal_start(inode, 1);
  110. if (IS_ERR(handle))
  111. return PTR_ERR(handle);
  112. err = ext3_reserve_inode_write(handle, inode, &iloc);
  113. if (err)
  114. return err;
  115. inode->i_ctime = CURRENT_TIME;
  116. inode->i_generation = generation;
  117. err = ext3_mark_iloc_dirty(handle, inode, &iloc);
  118. ext3_journal_stop(handle, inode);
  119. return err;
  120. }
  121. #ifdef CONFIG_JBD_DEBUG
  122. case EXT3_IOC_WAIT_FOR_READONLY:
  123. /*
  124.  * This is racy - by the time we're woken up and running,
  125.  * the superblock could be released.  And the module could
  126.  * have been unloaded.  So sue me.
  127.  *
  128.  * Returns 1 if it slept, else zero.
  129.  */
  130. {
  131. struct super_block *sb = inode->i_sb;
  132. DECLARE_WAITQUEUE(wait, current);
  133. int ret = 0;
  134. set_current_state(TASK_INTERRUPTIBLE);
  135. add_wait_queue(&sb->u.ext3_sb.ro_wait_queue, &wait);
  136. if (timer_pending(&sb->u.ext3_sb.turn_ro_timer)) {
  137. schedule();
  138. ret = 1;
  139. }
  140. remove_wait_queue(&sb->u.ext3_sb.ro_wait_queue, &wait);
  141. return ret;
  142. }
  143. #endif
  144. default:
  145. return -ENOTTY;
  146. }
  147. }