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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/fs/ufs/truncate.c
  3.  *
  4.  * Copyright (C) 1998
  5.  * Daniel Pirkl <daniel.pirkl@email.cz>
  6.  * Charles University, Faculty of Mathematics and Physics
  7.  *
  8.  *  from
  9.  *
  10.  *  linux/fs/ext2/truncate.c
  11.  *
  12.  * Copyright (C) 1992, 1993, 1994, 1995
  13.  * Remy Card (card@masi.ibp.fr)
  14.  * Laboratoire MASI - Institut Blaise Pascal
  15.  * Universite Pierre et Marie Curie (Paris VI)
  16.  *
  17.  *  from
  18.  *
  19.  *  linux/fs/minix/truncate.c
  20.  *
  21.  *  Copyright (C) 1991, 1992  Linus Torvalds
  22.  *
  23.  *  Big-endian to little-endian byte-swapping/bitmaps by
  24.  *        David S. Miller (davem@caip.rutgers.edu), 1995
  25.  */
  26. /*
  27.  * Real random numbers for secure rm added 94/02/18
  28.  * Idea from Pierre del Perugia <delperug@gla.ecoledoc.ibp.fr>
  29.  */
  30. #include <linux/errno.h>
  31. #include <linux/fs.h>
  32. #include <linux/ufs_fs.h>
  33. #include <linux/fcntl.h>
  34. #include <linux/sched.h>
  35. #include <linux/stat.h>
  36. #include <linux/locks.h>
  37. #include <linux/string.h>
  38. #include "swab.h"
  39. #include "util.h"
  40. #undef UFS_TRUNCATE_DEBUG
  41. #ifdef UFS_TRUNCATE_DEBUG
  42. #define UFSD(x) printk("(%s, %d), %s: ", __FILE__, __LINE__, __FUNCTION__); printk x;
  43. #else
  44. #define UFSD(x)
  45. #endif
  46.  
  47. /*
  48.  * Secure deletion currently doesn't work. It interacts very badly
  49.  * with buffers shared with memory mappings, and for that reason
  50.  * can't be done in the truncate() routines. It should instead be
  51.  * done separately in "release()" before calling the truncate routines
  52.  * that will release the actual file blocks.
  53.  *
  54.  * Linus
  55.  */
  56. #define DIRECT_BLOCK ((inode->i_size + uspi->s_bsize - 1) >> uspi->s_bshift)
  57. #define DIRECT_FRAGMENT ((inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift)
  58. #define DATA_BUFFER_USED(bh) 
  59. (atomic_read(&bh->b_count)>1 || buffer_locked(bh))
  60. static int ufs_trunc_direct (struct inode * inode)
  61. {
  62. struct super_block * sb;
  63. struct ufs_sb_private_info * uspi;
  64. struct buffer_head * bh;
  65. u32 * p;
  66. unsigned frag1, frag2, frag3, frag4, block1, block2;
  67. unsigned frag_to_free, free_count;
  68. unsigned i, j, tmp;
  69. int retry;
  70. UFSD(("ENTERn"))
  71. sb = inode->i_sb;
  72. uspi = sb->u.ufs_sb.s_uspi;
  73. frag_to_free = 0;
  74. free_count = 0;
  75. retry = 0;
  76. frag1 = DIRECT_FRAGMENT;
  77. frag4 = min_t(u32, UFS_NDIR_FRAGMENT, inode->u.ufs_i.i_lastfrag);
  78. frag2 = ((frag1 & uspi->s_fpbmask) ? ((frag1 | uspi->s_fpbmask) + 1) : frag1);
  79. frag3 = frag4 & ~uspi->s_fpbmask;
  80. block1 = block2 = 0;
  81. if (frag2 > frag3) {
  82. frag2 = frag4;
  83. frag3 = frag4 = 0;
  84. }
  85. else if (frag2 < frag3) {
  86. block1 = ufs_fragstoblks (frag2);
  87. block2 = ufs_fragstoblks (frag3);
  88. }
  89. UFSD(("frag1 %u, frag2 %u, block1 %u, block2 %u, frag3 %u, frag4 %un", frag1, frag2, block1, block2, frag3, frag4))
  90. if (frag1 >= frag2)
  91. goto next1;
  92. /*
  93.  * Free first free fragments
  94.  */
  95. p = inode->u.ufs_i.i_u1.i_data + ufs_fragstoblks (frag1);
  96. tmp = fs32_to_cpu(sb, *p);
  97. if (!tmp )
  98. ufs_panic (sb, "ufs_trunc_direct", "internal error");
  99. frag1 = ufs_fragnum (frag1);
  100. frag2 = ufs_fragnum (frag2);
  101. for (j = frag1; j < frag2; j++) {
  102. bh = sb_get_hash_table (sb, tmp + j);
  103. if ((bh && DATA_BUFFER_USED(bh)) || tmp != fs32_to_cpu(sb, *p)) {
  104. retry = 1;
  105. brelse (bh);
  106. goto next1;
  107. }
  108. bforget (bh);
  109. }
  110. inode->i_blocks -= (frag2-frag1) << uspi->s_nspfshift;
  111. mark_inode_dirty(inode);
  112. ufs_free_fragments (inode, tmp + frag1, frag2 - frag1);
  113. frag_to_free = tmp + frag1;
  114. next1:
  115. /*
  116.  * Free whole blocks
  117.  */
  118. for (i = block1 ; i < block2; i++) {
  119. p = inode->u.ufs_i.i_u1.i_data + i;
  120. tmp = fs32_to_cpu(sb, *p);
  121. if (!tmp)
  122. continue;
  123. for (j = 0; j < uspi->s_fpb; j++) {
  124. bh = sb_get_hash_table(sb, tmp + j);
  125. if ((bh && DATA_BUFFER_USED(bh)) || tmp != fs32_to_cpu(sb, *p)) {
  126. retry = 1;
  127. brelse (bh);
  128. goto next2;
  129. }
  130. bforget (bh);
  131. }
  132. *p = 0;
  133. inode->i_blocks -= uspi->s_nspb;
  134. mark_inode_dirty(inode);
  135. if (free_count == 0) {
  136. frag_to_free = tmp;
  137. free_count = uspi->s_fpb;
  138. } else if (free_count > 0 && frag_to_free == tmp - free_count)
  139. free_count += uspi->s_fpb;
  140. else {
  141. ufs_free_blocks (inode, frag_to_free, free_count);
  142. frag_to_free = tmp;
  143. free_count = uspi->s_fpb;
  144. }
  145. next2:;
  146. }
  147. if (free_count > 0)
  148. ufs_free_blocks (inode, frag_to_free, free_count);
  149. if (frag3 >= frag4)
  150. goto next3;
  151. /*
  152.  * Free last free fragments
  153.  */
  154. p = inode->u.ufs_i.i_u1.i_data + ufs_fragstoblks (frag3);
  155. tmp = fs32_to_cpu(sb, *p);
  156. if (!tmp )
  157. ufs_panic(sb, "ufs_truncate_direct", "internal error");
  158. frag4 = ufs_fragnum (frag4);
  159. for (j = 0; j < frag4; j++) {
  160. bh = sb_get_hash_table (sb, tmp + j);
  161. if ((bh && DATA_BUFFER_USED(bh)) || tmp != fs32_to_cpu(sb, *p)) {
  162. retry = 1;
  163. brelse (bh);
  164. goto next1;
  165. }
  166. bforget (bh);
  167. }
  168. *p = 0;
  169. inode->i_blocks -= frag4 << uspi->s_nspfshift;
  170. mark_inode_dirty(inode);
  171. ufs_free_fragments (inode, tmp, frag4);
  172.  next3:
  173. UFSD(("EXITn"))
  174. return retry;
  175. }
  176. static int ufs_trunc_indirect (struct inode * inode, unsigned offset, u32 * p)
  177. {
  178. struct super_block * sb;
  179. struct ufs_sb_private_info * uspi;
  180. struct ufs_buffer_head * ind_ubh;
  181. struct buffer_head * bh;
  182. u32 * ind;
  183. unsigned indirect_block, i, j, tmp;
  184. unsigned frag_to_free, free_count;
  185. int retry;
  186. UFSD(("ENTERn"))
  187. sb = inode->i_sb;
  188. uspi = sb->u.ufs_sb.s_uspi;
  189. frag_to_free = 0;
  190. free_count = 0;
  191. retry = 0;
  192. tmp = fs32_to_cpu(sb, *p);
  193. if (!tmp)
  194. return 0;
  195. ind_ubh = ubh_bread(sb, tmp, uspi->s_bsize);
  196. if (tmp != fs32_to_cpu(sb, *p)) {
  197. ubh_brelse (ind_ubh);
  198. return 1;
  199. }
  200. if (!ind_ubh) {
  201. *p = 0;
  202. return 0;
  203. }
  204. indirect_block = (DIRECT_BLOCK > offset) ? (DIRECT_BLOCK - offset) : 0;
  205. for (i = indirect_block; i < uspi->s_apb; i++) {
  206. ind = ubh_get_addr32 (ind_ubh, i);
  207. tmp = fs32_to_cpu(sb, *ind);
  208. if (!tmp)
  209. continue;
  210. for (j = 0; j < uspi->s_fpb; j++) {
  211. bh = sb_get_hash_table(sb, tmp + j);
  212. if ((bh && DATA_BUFFER_USED(bh)) || tmp != fs32_to_cpu(sb, *ind)) {
  213. retry = 1;
  214. brelse (bh);
  215. goto next;
  216. }
  217. bforget (bh);
  218. }
  219. *ind = 0;
  220. ubh_mark_buffer_dirty(ind_ubh);
  221. if (free_count == 0) {
  222. frag_to_free = tmp;
  223. free_count = uspi->s_fpb;
  224. } else if (free_count > 0 && frag_to_free == tmp - free_count)
  225. free_count += uspi->s_fpb;
  226. else {
  227. ufs_free_blocks (inode, frag_to_free, free_count);
  228. frag_to_free = tmp;
  229. free_count = uspi->s_fpb;
  230. }
  231. inode->i_blocks -= uspi->s_nspb;
  232. mark_inode_dirty(inode);
  233. next:;
  234. }
  235. if (free_count > 0) {
  236. ufs_free_blocks (inode, frag_to_free, free_count);
  237. }
  238. for (i = 0; i < uspi->s_apb; i++)
  239. if (*ubh_get_addr32(ind_ubh,i))
  240. break;
  241. if (i >= uspi->s_apb) {
  242. if (ubh_max_bcount(ind_ubh) != 1) {
  243. retry = 1;
  244. }
  245. else {
  246. tmp = fs32_to_cpu(sb, *p);
  247. *p = 0;
  248. inode->i_blocks -= uspi->s_nspb;
  249. mark_inode_dirty(inode);
  250. ufs_free_blocks (inode, tmp, uspi->s_fpb);
  251. ubh_bforget(ind_ubh);
  252. ind_ubh = NULL;
  253. }
  254. }
  255. if (IS_SYNC(inode) && ind_ubh && ubh_buffer_dirty(ind_ubh)) {
  256. ubh_ll_rw_block (WRITE, 1, &ind_ubh);
  257. ubh_wait_on_buffer (ind_ubh);
  258. }
  259. ubh_brelse (ind_ubh);
  260. UFSD(("EXITn"))
  261. return retry;
  262. }
  263. static int ufs_trunc_dindirect (struct inode * inode, unsigned offset, u32 * p)
  264. {
  265. struct super_block * sb;
  266. struct ufs_sb_private_info * uspi;
  267. struct ufs_buffer_head * dind_bh;
  268. unsigned i, tmp, dindirect_block;
  269. u32 * dind;
  270. int retry = 0;
  271. UFSD(("ENTERn"))
  272. sb = inode->i_sb;
  273. uspi = sb->u.ufs_sb.s_uspi;
  274. dindirect_block = (DIRECT_BLOCK > offset) 
  275. ? ((DIRECT_BLOCK - offset) >> uspi->s_apbshift) : 0;
  276. retry = 0;
  277. tmp = fs32_to_cpu(sb, *p);
  278. if (!tmp)
  279. return 0;
  280. dind_bh = ubh_bread(sb, tmp, uspi->s_bsize);
  281. if (tmp != fs32_to_cpu(sb, *p)) {
  282. ubh_brelse (dind_bh);
  283. return 1;
  284. }
  285. if (!dind_bh) {
  286. *p = 0;
  287. return 0;
  288. }
  289. for (i = dindirect_block ; i < uspi->s_apb ; i++) {
  290. dind = ubh_get_addr32 (dind_bh, i);
  291. tmp = fs32_to_cpu(sb, *dind);
  292. if (!tmp)
  293. continue;
  294. retry |= ufs_trunc_indirect (inode, offset + (i << uspi->s_apbshift), dind);
  295. ubh_mark_buffer_dirty(dind_bh);
  296. }
  297. for (i = 0; i < uspi->s_apb; i++)
  298. if (*ubh_get_addr32 (dind_bh, i))
  299. break;
  300. if (i >= uspi->s_apb) {
  301. if (ubh_max_bcount(dind_bh) != 1)
  302. retry = 1;
  303. else {
  304. tmp = fs32_to_cpu(sb, *p);
  305. *p = 0;
  306. inode->i_blocks -= uspi->s_nspb;
  307. mark_inode_dirty(inode);
  308. ufs_free_blocks (inode, tmp, uspi->s_fpb);
  309. ubh_bforget(dind_bh);
  310. dind_bh = NULL;
  311. }
  312. }
  313. if (IS_SYNC(inode) && dind_bh && ubh_buffer_dirty(dind_bh)) {
  314. ubh_ll_rw_block (WRITE, 1, &dind_bh);
  315. ubh_wait_on_buffer (dind_bh);
  316. }
  317. ubh_brelse (dind_bh);
  318. UFSD(("EXITn"))
  319. return retry;
  320. }
  321. static int ufs_trunc_tindirect (struct inode * inode)
  322. {
  323. struct super_block * sb;
  324. struct ufs_sb_private_info * uspi;
  325. struct ufs_buffer_head * tind_bh;
  326. unsigned tindirect_block, tmp, i;
  327. u32 * tind, * p;
  328. int retry;
  329. UFSD(("ENTERn"))
  330. sb = inode->i_sb;
  331. uspi = sb->u.ufs_sb.s_uspi;
  332. retry = 0;
  333. tindirect_block = (DIRECT_BLOCK > (UFS_NDADDR + uspi->s_apb + uspi->s_2apb))
  334. ? ((DIRECT_BLOCK - UFS_NDADDR - uspi->s_apb - uspi->s_2apb) >> uspi->s_2apbshift) : 0;
  335. p = inode->u.ufs_i.i_u1.i_data + UFS_TIND_BLOCK;
  336. if (!(tmp = fs32_to_cpu(sb, *p)))
  337. return 0;
  338. tind_bh = ubh_bread (sb, tmp, uspi->s_bsize);
  339. if (tmp != fs32_to_cpu(sb, *p)) {
  340. ubh_brelse (tind_bh);
  341. return 1;
  342. }
  343. if (!tind_bh) {
  344. *p = 0;
  345. return 0;
  346. }
  347. for (i = tindirect_block ; i < uspi->s_apb ; i++) {
  348. tind = ubh_get_addr32 (tind_bh, i);
  349. retry |= ufs_trunc_dindirect(inode, UFS_NDADDR + 
  350. uspi->s_apb + ((i + 1) << uspi->s_2apbshift), tind);
  351. ubh_mark_buffer_dirty(tind_bh);
  352. }
  353. for (i = 0; i < uspi->s_apb; i++)
  354. if (*ubh_get_addr32 (tind_bh, i))
  355. break;
  356. if (i >= uspi->s_apb) {
  357. if (ubh_max_bcount(tind_bh) != 1)
  358. retry = 1;
  359. else {
  360. tmp = fs32_to_cpu(sb, *p);
  361. *p = 0;
  362. inode->i_blocks -= uspi->s_nspb;
  363. mark_inode_dirty(inode);
  364. ufs_free_blocks (inode, tmp, uspi->s_fpb);
  365. ubh_bforget(tind_bh);
  366. tind_bh = NULL;
  367. }
  368. }
  369. if (IS_SYNC(inode) && tind_bh && ubh_buffer_dirty(tind_bh)) {
  370. ubh_ll_rw_block (WRITE, 1, &tind_bh);
  371. ubh_wait_on_buffer (tind_bh);
  372. }
  373. ubh_brelse (tind_bh);
  374. UFSD(("EXITn"))
  375. return retry;
  376. }
  377. void ufs_truncate (struct inode * inode)
  378. {
  379. struct super_block * sb;
  380. struct ufs_sb_private_info * uspi;
  381. struct buffer_head * bh;
  382. unsigned offset;
  383. int err, retry;
  384. UFSD(("ENTERn"))
  385. sb = inode->i_sb;
  386. uspi = sb->u.ufs_sb.s_uspi;
  387. if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)))
  388. return;
  389. if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
  390. return;
  391. while (1) {
  392. retry = ufs_trunc_direct(inode);
  393. retry |= ufs_trunc_indirect (inode, UFS_IND_BLOCK,
  394. (u32 *) &inode->u.ufs_i.i_u1.i_data[UFS_IND_BLOCK]);
  395. retry |= ufs_trunc_dindirect (inode, UFS_IND_BLOCK + uspi->s_apb,
  396. (u32 *) &inode->u.ufs_i.i_u1.i_data[UFS_DIND_BLOCK]);
  397. retry |= ufs_trunc_tindirect (inode);
  398. if (!retry)
  399. break;
  400. if (IS_SYNC(inode) && (inode->i_state & I_DIRTY))
  401. ufs_sync_inode (inode);
  402. run_task_queue(&tq_disk);
  403. current->policy |= SCHED_YIELD;
  404. schedule ();
  405. }
  406. offset = inode->i_size & uspi->s_fshift;
  407. if (offset) {
  408. bh = ufs_bread (inode, inode->i_size >> uspi->s_fshift, 0, &err);
  409. if (bh) {
  410. memset (bh->b_data + offset, 0, uspi->s_fsize - offset);
  411. mark_buffer_dirty (bh);
  412. brelse (bh);
  413. }
  414. }
  415. inode->i_mtime = inode->i_ctime = CURRENT_TIME;
  416. inode->u.ufs_i.i_lastfrag = DIRECT_FRAGMENT;
  417. mark_inode_dirty(inode);
  418. UFSD(("EXITn"))
  419. }