ioctl.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /*
  2. * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
  3. */
  4. #include <linux/capability.h>
  5. #include <linux/fs.h>
  6. #include <linux/mount.h>
  7. #include <linux/reiserfs_fs.h>
  8. #include <linux/time.h>
  9. #include <asm/uaccess.h>
  10. #include <linux/pagemap.h>
  11. #include <linux/smp_lock.h>
  12. #include <linux/compat.h>
  13. static int reiserfs_unpack(struct inode *inode, struct file *filp);
  14. /*
  15. ** reiserfs_ioctl - handler for ioctl for inode
  16. ** supported commands:
  17. ** 1) REISERFS_IOC_UNPACK - try to unpack tail from direct item into indirect
  18. ** and prevent packing file (argument arg has to be non-zero)
  19. ** 2) REISERFS_IOC_[GS]ETFLAGS, REISERFS_IOC_[GS]ETVERSION
  20. ** 3) That's all for a while ...
  21. */
  22. int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
  23. unsigned long arg)
  24. {
  25. unsigned int flags;
  26. int err = 0;
  27. switch (cmd) {
  28. case REISERFS_IOC_UNPACK:
  29. if (S_ISREG(inode->i_mode)) {
  30. if (arg)
  31. return reiserfs_unpack(inode, filp);
  32. else
  33. return 0;
  34. } else
  35. return -ENOTTY;
  36. /* following two cases are taken from fs/ext2/ioctl.c by Remy
  37. Card (card@masi.ibp.fr) */
  38. case REISERFS_IOC_GETFLAGS:
  39. if (!reiserfs_attrs(inode->i_sb))
  40. return -ENOTTY;
  41. flags = REISERFS_I(inode)->i_attrs;
  42. i_attrs_to_sd_attrs(inode, (__u16 *) & flags);
  43. return put_user(flags, (int __user *)arg);
  44. case REISERFS_IOC_SETFLAGS:{
  45. if (!reiserfs_attrs(inode->i_sb))
  46. return -ENOTTY;
  47. err = mnt_want_write(filp->f_path.mnt);
  48. if (err)
  49. return err;
  50. if (!is_owner_or_cap(inode)) {
  51. err = -EPERM;
  52. goto setflags_out;
  53. }
  54. if (get_user(flags, (int __user *)arg)) {
  55. err = -EFAULT;
  56. goto setflags_out;
  57. }
  58. /*
  59. * Is it quota file? Do not allow user to mess with it
  60. */
  61. if (IS_NOQUOTA(inode)) {
  62. err = -EPERM;
  63. goto setflags_out;
  64. }
  65. if (((flags ^ REISERFS_I(inode)->
  66. i_attrs) & (REISERFS_IMMUTABLE_FL |
  67. REISERFS_APPEND_FL))
  68. && !capable(CAP_LINUX_IMMUTABLE)) {
  69. err = -EPERM;
  70. goto setflags_out;
  71. }
  72. if ((flags & REISERFS_NOTAIL_FL) &&
  73. S_ISREG(inode->i_mode)) {
  74. int result;
  75. result = reiserfs_unpack(inode, filp);
  76. if (result) {
  77. err = result;
  78. goto setflags_out;
  79. }
  80. }
  81. sd_attrs_to_i_attrs(flags, inode);
  82. REISERFS_I(inode)->i_attrs = flags;
  83. inode->i_ctime = CURRENT_TIME_SEC;
  84. mark_inode_dirty(inode);
  85. setflags_out:
  86. mnt_drop_write(filp->f_path.mnt);
  87. return err;
  88. }
  89. case REISERFS_IOC_GETVERSION:
  90. return put_user(inode->i_generation, (int __user *)arg);
  91. case REISERFS_IOC_SETVERSION:
  92. if (!is_owner_or_cap(inode))
  93. return -EPERM;
  94. err = mnt_want_write(filp->f_path.mnt);
  95. if (err)
  96. return err;
  97. if (get_user(inode->i_generation, (int __user *)arg)) {
  98. err = -EFAULT;
  99. goto setversion_out;
  100. }
  101. inode->i_ctime = CURRENT_TIME_SEC;
  102. mark_inode_dirty(inode);
  103. setversion_out:
  104. mnt_drop_write(filp->f_path.mnt);
  105. return err;
  106. default:
  107. return -ENOTTY;
  108. }
  109. }
  110. #ifdef CONFIG_COMPAT
  111. long reiserfs_compat_ioctl(struct file *file, unsigned int cmd,
  112. unsigned long arg)
  113. {
  114. struct inode *inode = file->f_path.dentry->d_inode;
  115. int ret;
  116. /* These are just misnamed, they actually get/put from/to user an int */
  117. switch (cmd) {
  118. case REISERFS_IOC32_UNPACK:
  119. cmd = REISERFS_IOC_UNPACK;
  120. break;
  121. case REISERFS_IOC32_GETFLAGS:
  122. cmd = REISERFS_IOC_GETFLAGS;
  123. break;
  124. case REISERFS_IOC32_SETFLAGS:
  125. cmd = REISERFS_IOC_SETFLAGS;
  126. break;
  127. case REISERFS_IOC32_GETVERSION:
  128. cmd = REISERFS_IOC_GETVERSION;
  129. break;
  130. case REISERFS_IOC32_SETVERSION:
  131. cmd = REISERFS_IOC_SETVERSION;
  132. break;
  133. default:
  134. return -ENOIOCTLCMD;
  135. }
  136. lock_kernel();
  137. ret = reiserfs_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg));
  138. unlock_kernel();
  139. return ret;
  140. }
  141. #endif
  142. int reiserfs_commit_write(struct file *f, struct page *page,
  143. unsigned from, unsigned to);
  144. int reiserfs_prepare_write(struct file *f, struct page *page,
  145. unsigned from, unsigned to);
  146. /*
  147. ** reiserfs_unpack
  148. ** Function try to convert tail from direct item into indirect.
  149. ** It set up nopack attribute in the REISERFS_I(inode)->nopack
  150. */
  151. static int reiserfs_unpack(struct inode *inode, struct file *filp)
  152. {
  153. int retval = 0;
  154. int index;
  155. struct page *page;
  156. struct address_space *mapping;
  157. unsigned long write_from;
  158. unsigned long blocksize = inode->i_sb->s_blocksize;
  159. if (inode->i_size == 0) {
  160. REISERFS_I(inode)->i_flags |= i_nopack_mask;
  161. return 0;
  162. }
  163. /* ioctl already done */
  164. if (REISERFS_I(inode)->i_flags & i_nopack_mask) {
  165. return 0;
  166. }
  167. /* we need to make sure nobody is changing the file size beneath
  168. ** us
  169. */
  170. mutex_lock(&inode->i_mutex);
  171. reiserfs_write_lock(inode->i_sb);
  172. write_from = inode->i_size & (blocksize - 1);
  173. /* if we are on a block boundary, we are already unpacked. */
  174. if (write_from == 0) {
  175. REISERFS_I(inode)->i_flags |= i_nopack_mask;
  176. goto out;
  177. }
  178. /* we unpack by finding the page with the tail, and calling
  179. ** reiserfs_prepare_write on that page. This will force a
  180. ** reiserfs_get_block to unpack the tail for us.
  181. */
  182. index = inode->i_size >> PAGE_CACHE_SHIFT;
  183. mapping = inode->i_mapping;
  184. page = grab_cache_page(mapping, index);
  185. retval = -ENOMEM;
  186. if (!page) {
  187. goto out;
  188. }
  189. retval = reiserfs_prepare_write(NULL, page, write_from, write_from);
  190. if (retval)
  191. goto out_unlock;
  192. /* conversion can change page contents, must flush */
  193. flush_dcache_page(page);
  194. retval = reiserfs_commit_write(NULL, page, write_from, write_from);
  195. REISERFS_I(inode)->i_flags |= i_nopack_mask;
  196. out_unlock:
  197. unlock_page(page);
  198. page_cache_release(page);
  199. out:
  200. mutex_unlock(&inode->i_mutex);
  201. reiserfs_write_unlock(inode->i_sb);
  202. return retval;
  203. }