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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * JFFS2 -- Journalling Flash File System, Version 2.
  3.  *
  4.  * Copyright (C) 2001 Red Hat, Inc.
  5.  *
  6.  * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
  7.  *
  8.  * The original JFFS, from which the design for JFFS2 was derived,
  9.  * was designed and implemented by Axis Communications AB.
  10.  *
  11.  * The contents of this file are subject to the Red Hat eCos Public
  12.  * License Version 1.1 (the "Licence"); you may not use this file
  13.  * except in compliance with the Licence.  You may obtain a copy of
  14.  * the Licence at http://www.redhat.com/
  15.  *
  16.  * Software distributed under the Licence is distributed on an "AS IS"
  17.  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
  18.  * See the Licence for the specific language governing rights and
  19.  * limitations under the Licence.
  20.  *
  21.  * The Original Code is JFFS2 - Journalling Flash File System, version 2
  22.  *
  23.  * Alternatively, the contents of this file may be used under the
  24.  * terms of the GNU General Public License version 2 (the "GPL"), in
  25.  * which case the provisions of the GPL are applicable instead of the
  26.  * above.  If you wish to allow the use of your version of this file
  27.  * only under the terms of the GPL and not to allow others to use your
  28.  * version of this file under the RHEPL, indicate your decision by
  29.  * deleting the provisions above and replace them with the notice and
  30.  * other provisions required by the GPL.  If you do not delete the
  31.  * provisions above, a recipient may use your version of this file
  32.  * under either the RHEPL or the GPL.
  33.  *
  34.  * $Id: dir.c,v 1.45.2.6 2002/06/20 23:54:48 dwmw2 Exp $
  35.  *
  36.  */
  37. #include <linux/kernel.h>
  38. #include <linux/slab.h>
  39. #include <linux/fs.h>
  40. #include <linux/mtd/compatmac.h> /* For completion */
  41. #include <linux/jffs2.h>
  42. #include <linux/jffs2_fs_i.h>
  43. #include <linux/jffs2_fs_sb.h>
  44. #include "nodelist.h"
  45. #include "crc32.h"
  46. static int jffs2_readdir (struct file *, void *, filldir_t);
  47. static int jffs2_create (struct inode *,struct dentry *,int);
  48. static struct dentry *jffs2_lookup (struct inode *,struct dentry *);
  49. static int jffs2_link (struct dentry *,struct inode *,struct dentry *);
  50. static int jffs2_unlink (struct inode *,struct dentry *);
  51. static int jffs2_symlink (struct inode *,struct dentry *,const char *);
  52. static int jffs2_mkdir (struct inode *,struct dentry *,int);
  53. static int jffs2_rmdir (struct inode *,struct dentry *);
  54. static int jffs2_mknod (struct inode *,struct dentry *,int,int);
  55. static int jffs2_rename (struct inode *, struct dentry *,
  56.                         struct inode *, struct dentry *);
  57. struct file_operations jffs2_dir_operations =
  58. {
  59. read: generic_read_dir,
  60. readdir: jffs2_readdir,
  61. ioctl: jffs2_ioctl,
  62. fsync: jffs2_null_fsync
  63. };
  64. struct inode_operations jffs2_dir_inode_operations =
  65. {
  66. create: jffs2_create,
  67. lookup: jffs2_lookup,
  68. link: jffs2_link,
  69. unlink: jffs2_unlink,
  70. symlink: jffs2_symlink,
  71. mkdir: jffs2_mkdir,
  72. rmdir: jffs2_rmdir,
  73. mknod: jffs2_mknod,
  74. rename: jffs2_rename,
  75. setattr: jffs2_setattr,
  76. };
  77. /***********************************************************************/
  78. /* We keep the dirent list sorted in increasing order of name hash,
  79.    and we use the same hash function as the dentries. Makes this 
  80.    nice and simple
  81. */
  82. static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target)
  83. {
  84. struct jffs2_inode_info *dir_f;
  85. struct jffs2_sb_info *c;
  86. struct jffs2_full_dirent *fd = NULL, *fd_list;
  87. __u32 ino = 0;
  88. struct inode *inode = NULL;
  89. D1(printk(KERN_DEBUG "jffs2_lookup()n"));
  90. dir_f = JFFS2_INODE_INFO(dir_i);
  91. c = JFFS2_SB_INFO(dir_i->i_sb);
  92. down(&dir_f->sem);
  93. /* NB: The 2.2 backport will need to explicitly check for '.' and '..' here */
  94. for (fd_list = dir_f->dents; fd_list && fd_list->nhash <= target->d_name.hash; fd_list = fd_list->next) {
  95. if (fd_list->nhash == target->d_name.hash && 
  96.     (!fd || fd_list->version > fd->version) &&
  97.     strlen(fd_list->name) == target->d_name.len &&
  98.     !strncmp(fd_list->name, target->d_name.name, target->d_name.len)) {
  99. fd = fd_list;
  100. }
  101. }
  102. if (fd)
  103. ino = fd->ino;
  104. up(&dir_f->sem);
  105. if (ino) {
  106. inode = iget(dir_i->i_sb, ino);
  107. if (!inode) {
  108. printk(KERN_WARNING "iget() failed for ino #%un", ino);
  109. return (ERR_PTR(-EIO));
  110. }
  111. }
  112. d_add(target, inode);
  113. return NULL;
  114. }
  115. /***********************************************************************/
  116. static int jffs2_readdir(struct file *filp, void *dirent, filldir_t filldir)
  117. {
  118. struct jffs2_inode_info *f;
  119. struct jffs2_sb_info *c;
  120. struct inode *inode = filp->f_dentry->d_inode;
  121. struct jffs2_full_dirent *fd;
  122. unsigned long offset, curofs;
  123. D1(printk(KERN_DEBUG "jffs2_readdir() for dir_i #%lun", filp->f_dentry->d_inode->i_ino));
  124. f = JFFS2_INODE_INFO(inode);
  125. c = JFFS2_SB_INFO(inode->i_sb);
  126. offset = filp->f_pos;
  127. if (offset == 0) {
  128. D1(printk(KERN_DEBUG "Dirent 0: ".", ino #%lun", inode->i_ino));
  129. if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
  130. goto out;
  131. offset++;
  132. }
  133. if (offset == 1) {
  134. D1(printk(KERN_DEBUG "Dirent 1: "..", ino #%lun", filp->f_dentry->d_parent->d_inode->i_ino));
  135. if (filldir(dirent, "..", 2, 1, filp->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)
  136. goto out;
  137. offset++;
  138. }
  139. curofs=1;
  140. down(&f->sem);
  141. for (fd = f->dents; fd; fd = fd->next) {
  142. curofs++;
  143. /* First loop: curofs = 2; offset = 2 */
  144. if (curofs < offset) {
  145. D2(printk(KERN_DEBUG "Skipping dirent: "%s", ino #%u, type %d, because curofs %ld < offset %ldn", 
  146.   fd->name, fd->ino, fd->type, curofs, offset));
  147. continue;
  148. }
  149. if (!fd->ino) {
  150. D2(printk(KERN_DEBUG "Skipping deletion dirent "%s"n", fd->name));
  151. offset++;
  152. continue;
  153. }
  154. D2(printk(KERN_DEBUG "Dirent %ld: "%s", ino #%u, type %dn", offset, fd->name, fd->ino, fd->type));
  155. if (filldir(dirent, fd->name, strlen(fd->name), offset, fd->ino, fd->type) < 0)
  156. break;
  157. offset++;
  158. }
  159. up(&f->sem);
  160.  out:
  161. filp->f_pos = offset;
  162. return 0;
  163. }
  164. /***********************************************************************/
  165. static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode)
  166. {
  167. struct jffs2_inode_info *f, *dir_f;
  168. struct jffs2_sb_info *c;
  169. struct inode *inode;
  170. struct jffs2_raw_inode *ri;
  171. struct jffs2_raw_dirent *rd;
  172. struct jffs2_full_dnode *fn;
  173. struct jffs2_full_dirent *fd;
  174. int namelen;
  175. __u32 alloclen, phys_ofs;
  176. __u32 writtenlen;
  177. int ret;
  178. ri = jffs2_alloc_raw_inode();
  179. if (!ri)
  180. return -ENOMEM;
  181. c = JFFS2_SB_INFO(dir_i->i_sb);
  182. D1(printk(KERN_DEBUG "jffs2_create()n"));
  183. /* Try to reserve enough space for both node and dirent. 
  184.  * Just the node will do for now, though 
  185.  */
  186. namelen = dentry->d_name.len;
  187. ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL);
  188. D1(printk(KERN_DEBUG "jffs2_create(): reserved 0x%x bytesn", alloclen));
  189. if (ret) {
  190. jffs2_free_raw_inode(ri);
  191. return ret;
  192. }
  193. inode = jffs2_new_inode(dir_i, mode, ri);
  194. if (IS_ERR(inode)) {
  195. D1(printk(KERN_DEBUG "jffs2_new_inode() failedn"));
  196. jffs2_free_raw_inode(ri);
  197. jffs2_complete_reservation(c);
  198. return PTR_ERR(inode);
  199. }
  200. inode->i_op = &jffs2_file_inode_operations;
  201. inode->i_fop = &jffs2_file_operations;
  202. inode->i_mapping->a_ops = &jffs2_file_address_operations;
  203. inode->i_mapping->nrpages = 0;
  204. f = JFFS2_INODE_INFO(inode);
  205. ri->data_crc = 0;
  206. ri->node_crc = crc32(0, ri, sizeof(*ri)-8);
  207. fn = jffs2_write_dnode(inode, ri, NULL, 0, phys_ofs, &writtenlen);
  208. D1(printk(KERN_DEBUG "jffs2_create created file with mode 0x%xn", ri->mode));
  209. jffs2_free_raw_inode(ri);
  210. if (IS_ERR(fn)) {
  211. D1(printk(KERN_DEBUG "jffs2_write_dnode() failedn"));
  212. /* Eeek. Wave bye bye */
  213. up(&f->sem);
  214. jffs2_complete_reservation(c);
  215. jffs2_clear_inode(inode);
  216. return PTR_ERR(fn);
  217. }
  218. /* No data here. Only a metadata node, which will be 
  219.    obsoleted by the first data write
  220. */
  221. f->metadata = fn;
  222. /* Work out where to put the dirent node now. */
  223. writtenlen = PAD(writtenlen);
  224. phys_ofs += writtenlen;
  225. alloclen -= writtenlen;
  226. up(&f->sem);
  227. if (alloclen < sizeof(*rd)+namelen) {
  228. /* Not enough space left in this chunk. Get some more */
  229. jffs2_complete_reservation(c);
  230. ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
  231. if (ret) {
  232. /* Eep. */
  233. D1(printk(KERN_DEBUG "jffs2_reserve_space() for dirent failedn"));
  234. jffs2_clear_inode(inode);
  235. return ret;
  236. }
  237. }
  238. rd = jffs2_alloc_raw_dirent();
  239. if (!rd) {
  240. /* Argh. Now we treat it like a normal delete */
  241. jffs2_complete_reservation(c);
  242. jffs2_clear_inode(inode);
  243. return -ENOMEM;
  244. }
  245. dir_f = JFFS2_INODE_INFO(dir_i);
  246. down(&dir_f->sem);
  247. rd->magic = JFFS2_MAGIC_BITMASK;
  248. rd->nodetype = JFFS2_NODETYPE_DIRENT;
  249. rd->totlen = sizeof(*rd) + namelen;
  250. rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
  251. rd->pino = dir_i->i_ino;
  252. rd->version = ++dir_f->highest_version;
  253. rd->ino = inode->i_ino;
  254. rd->mctime = CURRENT_TIME;
  255. rd->nsize = namelen;
  256. rd->type = DT_REG;
  257. rd->node_crc = crc32(0, rd, sizeof(*rd)-8);
  258. rd->name_crc = crc32(0, dentry->d_name.name, namelen);
  259. fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, namelen, phys_ofs, &writtenlen);
  260. jffs2_complete_reservation(c);
  261. if (IS_ERR(fd)) {
  262. /* dirent failed to write. Delete the inode normally 
  263.    as if it were the final unlink() */
  264. jffs2_free_raw_dirent(rd);
  265. up(&dir_f->sem);
  266. jffs2_clear_inode(inode);
  267. return PTR_ERR(fd);
  268. }
  269. dir_i->i_mtime = dir_i->i_ctime = rd->mctime;
  270. jffs2_free_raw_dirent(rd);
  271. /* Link the fd into the inode's list, obsoleting an old
  272.    one if necessary. */
  273. jffs2_add_fd_to_list(c, fd, &dir_f->dents);
  274. up(&dir_f->sem);
  275. d_instantiate(dentry, inode);
  276. D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ldn",
  277.   inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->nlink, inode->i_mapping->nrpages));
  278. return 0;
  279. }
  280. /***********************************************************************/
  281. static int jffs2_do_unlink(struct inode *dir_i, struct dentry *dentry, int rename)
  282. {
  283. struct jffs2_inode_info *dir_f, *f;
  284. struct jffs2_sb_info *c;
  285. struct jffs2_raw_dirent *rd;
  286. struct jffs2_full_dirent *fd;
  287. __u32 alloclen, phys_ofs;
  288. int ret;
  289. c = JFFS2_SB_INFO(dir_i->i_sb);
  290. rd = jffs2_alloc_raw_dirent();
  291. if (!rd)
  292. return -ENOMEM;
  293. ret = jffs2_reserve_space(c, sizeof(*rd)+dentry->d_name.len, &phys_ofs, &alloclen, ALLOC_DELETION);
  294. if (ret) {
  295. jffs2_free_raw_dirent(rd);
  296. return ret;
  297. }
  298. dir_f = JFFS2_INODE_INFO(dir_i);
  299. down(&dir_f->sem);
  300. /* Build a deletion node */
  301. rd->magic = JFFS2_MAGIC_BITMASK;
  302. rd->nodetype = JFFS2_NODETYPE_DIRENT;
  303. rd->totlen = sizeof(*rd) + dentry->d_name.len;
  304. rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
  305. rd->pino = dir_i->i_ino;
  306. rd->version = ++dir_f->highest_version;
  307. rd->ino = 0;
  308. rd->mctime = CURRENT_TIME;
  309. rd->nsize = dentry->d_name.len;
  310. rd->type = DT_UNKNOWN;
  311. rd->node_crc = crc32(0, rd, sizeof(*rd)-8);
  312. rd->name_crc = crc32(0, dentry->d_name.name, dentry->d_name.len);
  313. fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, dentry->d_name.len, phys_ofs, NULL);
  314. jffs2_complete_reservation(c);
  315. jffs2_free_raw_dirent(rd);
  316. if (IS_ERR(fd)) {
  317. up(&dir_f->sem);
  318. return PTR_ERR(fd);
  319. }
  320. /* File it. This will mark the old one obsolete. */
  321. jffs2_add_fd_to_list(c, fd, &dir_f->dents);
  322. up(&dir_f->sem);
  323. if (!rename) {
  324. f = JFFS2_INODE_INFO(dentry->d_inode);
  325. down(&f->sem);
  326. while (f->dents) {
  327. /* There can be only deleted ones */
  328. fd = f->dents;
  329. f->dents = fd->next;
  330. if (fd->ino) {
  331. printk(KERN_WARNING "Deleting inode #%u with active dentry "%s"->ino #%un",
  332.        f->inocache->ino, fd->name, fd->ino);
  333. } else {
  334. D1(printk(KERN_DEBUG "Removing deletion dirent for "%s" from dir ino #%un", fd->name, f->inocache->ino));
  335. }
  336. jffs2_mark_node_obsolete(c, fd->raw);
  337. jffs2_free_full_dirent(fd);
  338. }
  339. f->inocache->nlink--;
  340. dentry->d_inode->i_nlink--;
  341. up(&f->sem);
  342. }
  343. return 0;
  344. }
  345. static int jffs2_unlink(struct inode *dir_i, struct dentry *dentry)
  346. {
  347. return jffs2_do_unlink(dir_i, dentry, 0);
  348. }
  349. /***********************************************************************/
  350. static int jffs2_do_link (struct dentry *old_dentry, struct inode *dir_i, struct dentry *dentry, int rename)
  351. {
  352. struct jffs2_inode_info *dir_f, *f;
  353. struct jffs2_sb_info *c;
  354. struct jffs2_raw_dirent *rd;
  355. struct jffs2_full_dirent *fd;
  356. __u32 alloclen, phys_ofs;
  357. int ret;
  358. c = JFFS2_SB_INFO(dir_i->i_sb);
  359. rd = jffs2_alloc_raw_dirent();
  360. if (!rd)
  361. return -ENOMEM;
  362. ret = jffs2_reserve_space(c, sizeof(*rd)+dentry->d_name.len, &phys_ofs, &alloclen, ALLOC_NORMAL);
  363. if (ret) {
  364. jffs2_free_raw_dirent(rd);
  365. return ret;
  366. }
  367. dir_f = JFFS2_INODE_INFO(dir_i);
  368. down(&dir_f->sem);
  369. /* Build a deletion node */
  370. rd->magic = JFFS2_MAGIC_BITMASK;
  371. rd->nodetype = JFFS2_NODETYPE_DIRENT;
  372. rd->totlen = sizeof(*rd) + dentry->d_name.len;
  373. rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
  374. rd->pino = dir_i->i_ino;
  375. rd->version = ++dir_f->highest_version;
  376. rd->ino = old_dentry->d_inode->i_ino;
  377. rd->mctime = CURRENT_TIME;
  378. rd->nsize = dentry->d_name.len;
  379. /* XXX: This is ugly. */
  380. rd->type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12;
  381. if (!rd->type) rd->type = DT_REG;
  382. rd->node_crc = crc32(0, rd, sizeof(*rd)-8);
  383. rd->name_crc = crc32(0, dentry->d_name.name, dentry->d_name.len);
  384. fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, dentry->d_name.len, phys_ofs, NULL);
  385. jffs2_complete_reservation(c);
  386. jffs2_free_raw_dirent(rd);
  387. if (IS_ERR(fd)) {
  388. up(&dir_f->sem);
  389. return PTR_ERR(fd);
  390. }
  391. /* File it. This will mark the old one obsolete. */
  392. jffs2_add_fd_to_list(c, fd, &dir_f->dents);
  393. up(&dir_f->sem);
  394. if (!rename) {
  395. f = JFFS2_INODE_INFO(old_dentry->d_inode);
  396. down(&f->sem);
  397. old_dentry->d_inode->i_nlink = ++f->inocache->nlink;
  398. up(&f->sem);
  399. }
  400. return 0;
  401. }
  402. static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct dentry *dentry)
  403. {
  404. int ret;
  405. if (S_ISDIR(old_dentry->d_inode->i_mode))
  406. return -EPERM;
  407. ret = jffs2_do_link(old_dentry, dir_i, dentry, 0);
  408. if (!ret) {
  409. d_instantiate(dentry, old_dentry->d_inode);
  410. atomic_inc(&old_dentry->d_inode->i_count);
  411. }
  412. return ret;
  413. }
  414. /***********************************************************************/
  415. static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char *target)
  416. {
  417. struct jffs2_inode_info *f, *dir_f;
  418. struct jffs2_sb_info *c;
  419. struct inode *inode;
  420. struct jffs2_raw_inode *ri;
  421. struct jffs2_raw_dirent *rd;
  422. struct jffs2_full_dnode *fn;
  423. struct jffs2_full_dirent *fd;
  424. int namelen;
  425. __u32 alloclen, phys_ofs;
  426. __u32 writtenlen;
  427. int ret;
  428. /* FIXME: If you care. We'd need to use frags for the target
  429.    if it grows much more than this */
  430. if (strlen(target) > 254)
  431. return -EINVAL;
  432. ri = jffs2_alloc_raw_inode();
  433. if (!ri)
  434. return -ENOMEM;
  435. c = JFFS2_SB_INFO(dir_i->i_sb);
  436. /* Try to reserve enough space for both node and dirent. 
  437.  * Just the node will do for now, though 
  438.  */
  439. namelen = dentry->d_name.len;
  440. ret = jffs2_reserve_space(c, sizeof(*ri) + strlen(target), &phys_ofs, &alloclen, ALLOC_NORMAL);
  441. if (ret) {
  442. jffs2_free_raw_inode(ri);
  443. return ret;
  444. }
  445. inode = jffs2_new_inode(dir_i, S_IFLNK | S_IRWXUGO, ri);
  446. if (IS_ERR(inode)) {
  447. jffs2_free_raw_inode(ri);
  448. jffs2_complete_reservation(c);
  449. return PTR_ERR(inode);
  450. }
  451. inode->i_op = &jffs2_symlink_inode_operations;
  452. f = JFFS2_INODE_INFO(inode);
  453. inode->i_size = ri->isize = ri->dsize = ri->csize = strlen(target);
  454. ri->totlen = sizeof(*ri) + ri->dsize;
  455. ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4);
  456. ri->compr = JFFS2_COMPR_NONE;
  457. ri->data_crc = crc32(0, target, strlen(target));
  458. ri->node_crc = crc32(0, ri, sizeof(*ri)-8);
  459. fn = jffs2_write_dnode(inode, ri, target, strlen(target), phys_ofs, &writtenlen);
  460. jffs2_free_raw_inode(ri);
  461. if (IS_ERR(fn)) {
  462. /* Eeek. Wave bye bye */
  463. up(&f->sem);
  464. jffs2_complete_reservation(c);
  465. jffs2_clear_inode(inode);
  466. return PTR_ERR(fn);
  467. }
  468. /* No data here. Only a metadata node, which will be 
  469.    obsoleted by the first data write
  470. */
  471. f->metadata = fn;
  472. up(&f->sem);
  473. /* Work out where to put the dirent node now. */
  474. writtenlen = (writtenlen+3)&~3;
  475. phys_ofs += writtenlen;
  476. alloclen -= writtenlen;
  477. if (alloclen < sizeof(*rd)+namelen) {
  478. /* Not enough space left in this chunk. Get some more */
  479. jffs2_complete_reservation(c);
  480. ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
  481. if (ret) {
  482. /* Eep. */
  483. jffs2_clear_inode(inode);
  484. return ret;
  485. }
  486. }
  487. rd = jffs2_alloc_raw_dirent();
  488. if (!rd) {
  489. /* Argh. Now we treat it like a normal delete */
  490. jffs2_complete_reservation(c);
  491. jffs2_clear_inode(inode);
  492. return -ENOMEM;
  493. }
  494. dir_f = JFFS2_INODE_INFO(dir_i);
  495. down(&dir_f->sem);
  496. rd->magic = JFFS2_MAGIC_BITMASK;
  497. rd->nodetype = JFFS2_NODETYPE_DIRENT;
  498. rd->totlen = sizeof(*rd) + namelen;
  499. rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
  500. rd->pino = dir_i->i_ino;
  501. rd->version = ++dir_f->highest_version;
  502. rd->ino = inode->i_ino;
  503. rd->mctime = CURRENT_TIME;
  504. rd->nsize = namelen;
  505. rd->type = DT_LNK;
  506. rd->node_crc = crc32(0, rd, sizeof(*rd)-8);
  507. rd->name_crc = crc32(0, dentry->d_name.name, namelen);
  508. fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, namelen, phys_ofs, &writtenlen);
  509. jffs2_complete_reservation(c);
  510. if (IS_ERR(fd)) {
  511. /* dirent failed to write. Delete the inode normally 
  512.    as if it were the final unlink() */
  513. jffs2_free_raw_dirent(rd);
  514. up(&dir_f->sem);
  515. jffs2_clear_inode(inode);
  516. return PTR_ERR(fd);
  517. }
  518. dir_i->i_mtime = dir_i->i_ctime = rd->mctime;
  519. jffs2_free_raw_dirent(rd);
  520. /* Link the fd into the inode's list, obsoleting an old
  521.    one if necessary. */
  522. jffs2_add_fd_to_list(c, fd, &dir_f->dents);
  523. up(&dir_f->sem);
  524. d_instantiate(dentry, inode);
  525. return 0;
  526. }
  527. static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
  528. {
  529. struct jffs2_inode_info *f, *dir_f;
  530. struct jffs2_sb_info *c;
  531. struct inode *inode;
  532. struct jffs2_raw_inode *ri;
  533. struct jffs2_raw_dirent *rd;
  534. struct jffs2_full_dnode *fn;
  535. struct jffs2_full_dirent *fd;
  536. int namelen;
  537. __u32 alloclen, phys_ofs;
  538. __u32 writtenlen;
  539. int ret;
  540. mode |= S_IFDIR;
  541. ri = jffs2_alloc_raw_inode();
  542. if (!ri)
  543. return -ENOMEM;
  544. c = JFFS2_SB_INFO(dir_i->i_sb);
  545. /* Try to reserve enough space for both node and dirent. 
  546.  * Just the node will do for now, though 
  547.  */
  548. namelen = dentry->d_name.len;
  549. ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL);
  550. if (ret) {
  551. jffs2_free_raw_inode(ri);
  552. return ret;
  553. }
  554. inode = jffs2_new_inode(dir_i, mode, ri);
  555. if (IS_ERR(inode)) {
  556. jffs2_free_raw_inode(ri);
  557. jffs2_complete_reservation(c);
  558. return PTR_ERR(inode);
  559. }
  560. inode->i_op = &jffs2_dir_inode_operations;
  561. inode->i_fop = &jffs2_dir_operations;
  562. f = JFFS2_INODE_INFO(inode);
  563. ri->data_crc = 0;
  564. ri->node_crc = crc32(0, ri, sizeof(*ri)-8);
  565. fn = jffs2_write_dnode(inode, ri, NULL, 0, phys_ofs, &writtenlen);
  566. jffs2_free_raw_inode(ri);
  567. if (IS_ERR(fn)) {
  568. /* Eeek. Wave bye bye */
  569. up(&f->sem);
  570. jffs2_complete_reservation(c);
  571. jffs2_clear_inode(inode);
  572. return PTR_ERR(fn);
  573. }
  574. /* No data here. Only a metadata node, which will be 
  575.    obsoleted by the first data write
  576. */
  577. f->metadata = fn;
  578. up(&f->sem);
  579. /* Work out where to put the dirent node now. */
  580. writtenlen = PAD(writtenlen);
  581. phys_ofs += writtenlen;
  582. alloclen -= writtenlen;
  583. if (alloclen < sizeof(*rd)+namelen) {
  584. /* Not enough space left in this chunk. Get some more */
  585. jffs2_complete_reservation(c);
  586. ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
  587. if (ret) {
  588. /* Eep. */
  589. jffs2_clear_inode(inode);
  590. return ret;
  591. }
  592. }
  593. rd = jffs2_alloc_raw_dirent();
  594. if (!rd) {
  595. /* Argh. Now we treat it like a normal delete */
  596. jffs2_complete_reservation(c);
  597. jffs2_clear_inode(inode);
  598. return -ENOMEM;
  599. }
  600. dir_f = JFFS2_INODE_INFO(dir_i);
  601. down(&dir_f->sem);
  602. rd->magic = JFFS2_MAGIC_BITMASK;
  603. rd->nodetype = JFFS2_NODETYPE_DIRENT;
  604. rd->totlen = sizeof(*rd) + namelen;
  605. rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
  606. rd->pino = dir_i->i_ino;
  607. rd->version = ++dir_f->highest_version;
  608. rd->ino = inode->i_ino;
  609. rd->mctime = CURRENT_TIME;
  610. rd->nsize = namelen;
  611. rd->type = DT_DIR;
  612. rd->node_crc = crc32(0, rd, sizeof(*rd)-8);
  613. rd->name_crc = crc32(0, dentry->d_name.name, namelen);
  614. fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, namelen, phys_ofs, &writtenlen);
  615. jffs2_complete_reservation(c);
  616. if (IS_ERR(fd)) {
  617. /* dirent failed to write. Delete the inode normally 
  618.    as if it were the final unlink() */
  619. jffs2_free_raw_dirent(rd);
  620. up(&dir_f->sem);
  621. jffs2_clear_inode(inode);
  622. return PTR_ERR(fd);
  623. }
  624. dir_i->i_mtime = dir_i->i_ctime = rd->mctime;
  625. jffs2_free_raw_dirent(rd);
  626. /* Link the fd into the inode's list, obsoleting an old
  627.    one if necessary. */
  628. jffs2_add_fd_to_list(c, fd, &dir_f->dents);
  629. up(&dir_f->sem);
  630. d_instantiate(dentry, inode);
  631. return 0;
  632. }
  633. static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry)
  634. {
  635. struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode);
  636. struct jffs2_full_dirent *fd;
  637. for (fd = f->dents ; fd; fd = fd->next) {
  638. if (fd->ino)
  639. return -ENOTEMPTY;
  640. }
  641. return jffs2_unlink(dir_i, dentry);
  642. }
  643. static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, int rdev)
  644. {
  645. struct jffs2_inode_info *f, *dir_f;
  646. struct jffs2_sb_info *c;
  647. struct inode *inode;
  648. struct jffs2_raw_inode *ri;
  649. struct jffs2_raw_dirent *rd;
  650. struct jffs2_full_dnode *fn;
  651. struct jffs2_full_dirent *fd;
  652. int namelen;
  653. unsigned short dev;
  654. int devlen = 0;
  655. __u32 alloclen, phys_ofs;
  656. __u32 writtenlen;
  657. int ret;
  658. ri = jffs2_alloc_raw_inode();
  659. if (!ri)
  660. return -ENOMEM;
  661. c = JFFS2_SB_INFO(dir_i->i_sb);
  662. if (S_ISBLK(mode) || S_ISCHR(mode)) {
  663. dev = (MAJOR(to_kdev_t(rdev)) << 8) | MINOR(to_kdev_t(rdev));
  664. devlen = sizeof(dev);
  665. }
  666. /* Try to reserve enough space for both node and dirent. 
  667.  * Just the node will do for now, though 
  668.  */
  669. namelen = dentry->d_name.len;
  670. ret = jffs2_reserve_space(c, sizeof(*ri) + devlen, &phys_ofs, &alloclen, ALLOC_NORMAL);
  671. if (ret) {
  672. jffs2_free_raw_inode(ri);
  673. return ret;
  674. }
  675. inode = jffs2_new_inode(dir_i, mode, ri);
  676. if (IS_ERR(inode)) {
  677. jffs2_free_raw_inode(ri);
  678. jffs2_complete_reservation(c);
  679. return PTR_ERR(inode);
  680. }
  681. inode->i_op = &jffs2_file_inode_operations;
  682. init_special_inode(inode, inode->i_mode, rdev);
  683. f = JFFS2_INODE_INFO(inode);
  684. ri->dsize = ri->csize = devlen;
  685. ri->totlen = sizeof(*ri) + ri->csize;
  686. ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4);
  687. ri->compr = JFFS2_COMPR_NONE;
  688. ri->data_crc = crc32(0, &dev, devlen);
  689. ri->node_crc = crc32(0, ri, sizeof(*ri)-8);
  690. fn = jffs2_write_dnode(inode, ri, (char *)&dev, devlen, phys_ofs, &writtenlen);
  691. jffs2_free_raw_inode(ri);
  692. if (IS_ERR(fn)) {
  693. /* Eeek. Wave bye bye */
  694. up(&f->sem);
  695. jffs2_complete_reservation(c);
  696. jffs2_clear_inode(inode);
  697. return PTR_ERR(fn);
  698. }
  699. /* No data here. Only a metadata node, which will be 
  700.    obsoleted by the first data write
  701. */
  702. f->metadata = fn;
  703. up(&f->sem);
  704. /* Work out where to put the dirent node now. */
  705. writtenlen = (writtenlen+3)&~3;
  706. phys_ofs += writtenlen;
  707. alloclen -= writtenlen;
  708. if (alloclen < sizeof(*rd)+namelen) {
  709. /* Not enough space left in this chunk. Get some more */
  710. jffs2_complete_reservation(c);
  711. ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
  712. if (ret) {
  713. /* Eep. */
  714. jffs2_clear_inode(inode);
  715. return ret;
  716. }
  717. }
  718. rd = jffs2_alloc_raw_dirent();
  719. if (!rd) {
  720. /* Argh. Now we treat it like a normal delete */
  721. jffs2_complete_reservation(c);
  722. jffs2_clear_inode(inode);
  723. return -ENOMEM;
  724. }
  725. dir_f = JFFS2_INODE_INFO(dir_i);
  726. down(&dir_f->sem);
  727. rd->magic = JFFS2_MAGIC_BITMASK;
  728. rd->nodetype = JFFS2_NODETYPE_DIRENT;
  729. rd->totlen = sizeof(*rd) + namelen;
  730. rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
  731. rd->pino = dir_i->i_ino;
  732. rd->version = ++dir_f->highest_version;
  733. rd->ino = inode->i_ino;
  734. rd->mctime = CURRENT_TIME;
  735. rd->nsize = namelen;
  736. /* XXX: This is ugly. */
  737. rd->type = (mode & S_IFMT) >> 12;
  738. rd->node_crc = crc32(0, rd, sizeof(*rd)-8);
  739. rd->name_crc = crc32(0, dentry->d_name.name, namelen);
  740. fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, namelen, phys_ofs, &writtenlen);
  741. jffs2_complete_reservation(c);
  742. if (IS_ERR(fd)) {
  743. /* dirent failed to write. Delete the inode normally 
  744.    as if it were the final unlink() */
  745. jffs2_free_raw_dirent(rd);
  746. up(&dir_f->sem);
  747. jffs2_clear_inode(inode);
  748. return PTR_ERR(fd);
  749. }
  750. dir_i->i_mtime = dir_i->i_ctime = rd->mctime;
  751. jffs2_free_raw_dirent(rd);
  752. /* Link the fd into the inode's list, obsoleting an old
  753.    one if necessary. */
  754. jffs2_add_fd_to_list(c, fd, &dir_f->dents);
  755. up(&dir_f->sem);
  756. d_instantiate(dentry, inode);
  757. return 0;
  758. }
  759. static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
  760.                         struct inode *new_dir_i, struct dentry *new_dentry)
  761. {
  762. int ret;
  763. struct jffs2_inode_info *victim_f = NULL;
  764. /* The VFS will check for us and prevent trying to rename a 
  765.  * file over a directory and vice versa, but if it's a directory,
  766.  * the VFS can't check whether the victim is empty. The filesystem
  767.  * needs to do that for itself.
  768.  */
  769. if (new_dentry->d_inode) {
  770. victim_f = JFFS2_INODE_INFO(new_dentry->d_inode);
  771. if (S_ISDIR(new_dentry->d_inode->i_mode)) {
  772. struct jffs2_full_dirent *fd;
  773. down(&victim_f->sem);
  774. for (fd = victim_f->dents; fd; fd = fd->next) {
  775. if (fd->ino) {
  776. up(&victim_f->sem);
  777. return -ENOTEMPTY;
  778. }
  779. }
  780. up(&victim_f->sem);
  781. }
  782. }
  783. /* XXX: We probably ought to alloc enough space for
  784.    both nodes at the same time. Writing the new link, 
  785.    then getting -ENOSPC, is quite bad :)
  786. */
  787. /* Make a hard link */
  788. ret = jffs2_do_link(old_dentry, new_dir_i, new_dentry, 1);
  789. if (ret)
  790. return ret;
  791. if (victim_f) {
  792. /* There was a victim. Kill it off nicely */
  793. new_dentry->d_inode->i_nlink--;
  794. /* Don't oops if the victim was a dirent pointing to an
  795.    inode which didn't exist. */
  796. if (victim_f->inocache) {
  797. down(&victim_f->sem);
  798. victim_f->inocache->nlink--;
  799. up(&victim_f->sem);
  800. }
  801. }
  802. /* Unlink the original */
  803. ret = jffs2_do_unlink(old_dir_i, old_dentry, 1);
  804. if (ret) {
  805. /* Oh shit. We really ought to make a single node which can do both atomically */
  806. struct jffs2_inode_info *f = JFFS2_INODE_INFO(old_dentry->d_inode);
  807. down(&f->sem);
  808. old_dentry->d_inode->i_nlink = f->inocache->nlink++;
  809. up(&f->sem);
  810.        
  811. printk(KERN_NOTICE "jffs2_rename(): Link succeeded, unlink failed (err %d). You now have a hard linkn", ret);
  812. /* Might as well let the VFS know */
  813. d_instantiate(new_dentry, old_dentry->d_inode);
  814. atomic_inc(&old_dentry->d_inode->i_count);
  815. }
  816. return ret;
  817. }