v2.4.9.9 -> v2.4.9.10
[opensuse:kernel.git] / fs / jffs2 / dir.c
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.42 2001/05/24 22:24:39 dwmw2 Exp $
35  *
36  */
37
38 #include <linux/kernel.h>
39 #include <linux/slab.h>
40 #include <linux/fs.h>
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
47 static int jffs2_readdir (struct file *, void *, filldir_t);
48
49 static int jffs2_create (struct inode *,struct dentry *,int);
50 static struct dentry *jffs2_lookup (struct inode *,struct dentry *);
51 static int jffs2_link (struct dentry *,struct inode *,struct dentry *);
52 static int jffs2_unlink (struct inode *,struct dentry *);
53 static int jffs2_symlink (struct inode *,struct dentry *,const char *);
54 static int jffs2_mkdir (struct inode *,struct dentry *,int);
55 static int jffs2_rmdir (struct inode *,struct dentry *);
56 static int jffs2_mknod (struct inode *,struct dentry *,int,int);
57 static int jffs2_rename (struct inode *, struct dentry *,
58                         struct inode *, struct dentry *);
59
60 struct file_operations jffs2_dir_operations =
61 {
62         read:           generic_read_dir,
63         readdir:        jffs2_readdir,
64         ioctl:          jffs2_ioctl,
65         fsync:          jffs2_null_fsync
66 };
67
68
69 struct inode_operations jffs2_dir_inode_operations =
70 {
71         create:         jffs2_create,
72         lookup:         jffs2_lookup,
73         link:           jffs2_link,
74         unlink:         jffs2_unlink,
75         symlink:        jffs2_symlink,
76         mkdir:          jffs2_mkdir,
77         rmdir:          jffs2_rmdir,
78         mknod:          jffs2_mknod,
79         rename:         jffs2_rename,
80         setattr:        jffs2_setattr,
81 };
82
83 /***********************************************************************/
84
85
86 /* We keep the dirent list sorted in increasing order of name hash,
87    and we use the same hash function as the dentries. Makes this 
88    nice and simple
89 */
90 static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target)
91 {
92         struct jffs2_inode_info *dir_f;
93         struct jffs2_sb_info *c;
94         struct jffs2_full_dirent *fd = NULL, *fd_list;
95         __u32 ino = 0;
96         struct inode *inode = NULL;
97
98         D1(printk(KERN_DEBUG "jffs2_lookup()\n"));
99
100         dir_f = JFFS2_INODE_INFO(dir_i);
101         c = JFFS2_SB_INFO(dir_i->i_sb);
102
103         down(&dir_f->sem);
104
105         /* NB: The 2.2 backport will need to explicitly check for '.' and '..' here */
106         for (fd_list = dir_f->dents; fd_list && fd_list->nhash <= target->d_name.hash; fd_list = fd_list->next) {
107                 if (fd_list->nhash == target->d_name.hash && 
108                     (!fd || fd_list->version > fd->version) &&
109                     strlen(fd_list->name) == target->d_name.len &&
110                     !strncmp(fd_list->name, target->d_name.name, target->d_name.len)) {
111                         fd = fd_list;
112                 }
113         }
114         if (fd)
115                 ino = fd->ino;
116         up(&dir_f->sem);
117         if (ino) {
118                 inode = iget(dir_i->i_sb, ino);
119                 if (!inode) {
120                         printk(KERN_WARNING "iget() failed for ino #%u\n", ino);
121                         return (ERR_PTR(-EIO));
122                 }
123         }
124
125         d_add(target, inode);
126
127         return NULL;
128 }
129
130 /***********************************************************************/
131
132
133 static int jffs2_readdir(struct file *filp, void *dirent, filldir_t filldir)
134 {
135         struct jffs2_inode_info *f;
136         struct jffs2_sb_info *c;
137         struct inode *inode = filp->f_dentry->d_inode;
138         struct jffs2_full_dirent *fd;
139         unsigned long offset, curofs;
140
141         D1(printk(KERN_DEBUG "jffs2_readdir() for dir_i #%lu\n", filp->f_dentry->d_inode->i_ino));
142
143         f = JFFS2_INODE_INFO(inode);
144         c = JFFS2_SB_INFO(inode->i_sb);
145
146         offset = filp->f_pos;
147
148         if (offset == 0) {
149                 D1(printk(KERN_DEBUG "Dirent 0: \".\", ino #%lu\n", inode->i_ino));
150                 if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
151                         goto out;
152                 offset++;
153         }
154         if (offset == 1) {
155                 D1(printk(KERN_DEBUG "Dirent 1: \"..\", ino #%lu\n", filp->f_dentry->d_parent->d_inode->i_ino));
156                 if (filldir(dirent, "..", 2, 1, filp->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)
157                         goto out;
158                 offset++;
159         }
160
161         curofs=1;
162         down(&f->sem);
163         for (fd = f->dents; fd; fd = fd->next) {
164
165                 curofs++;
166                 /* First loop: curofs = 2; offset = 2 */
167                 if (curofs < offset) {
168                         D2(printk(KERN_DEBUG "Skipping dirent: \"%s\", ino #%u, type %d, because curofs %ld < offset %ld\n", 
169                                   fd->name, fd->ino, fd->type, curofs, offset));
170                         continue;
171                 }
172                 if (!fd->ino) {
173                         D2(printk(KERN_DEBUG "Skipping deletion dirent \"%s\"\n", fd->name));
174                         offset++;
175                         continue;
176                 }
177                 D2(printk(KERN_DEBUG "Dirent %ld: \"%s\", ino #%u, type %d\n", offset, fd->name, fd->ino, fd->type));
178                 if (filldir(dirent, fd->name, strlen(fd->name), offset, fd->ino, fd->type) < 0)
179                         goto out;
180                 offset++;
181         }
182  out:
183         up(&f->sem);
184         filp->f_pos = offset;
185         return 0;
186 }
187
188 /***********************************************************************/
189
190 static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode)
191 {
192         struct jffs2_inode_info *f, *dir_f;
193         struct jffs2_sb_info *c;
194         struct inode *inode;
195         struct jffs2_raw_inode *ri;
196         struct jffs2_raw_dirent *rd;
197         struct jffs2_full_dnode *fn;
198         struct jffs2_full_dirent *fd;
199         int namelen;
200         __u32 alloclen, phys_ofs;
201         __u32 writtenlen;
202         int ret;
203
204         ri = jffs2_alloc_raw_inode();
205         if (!ri)
206                 return -ENOMEM;
207         
208         c = JFFS2_SB_INFO(dir_i->i_sb);
209
210         D1(printk(KERN_DEBUG "jffs2_create()\n"));
211
212         /* Try to reserve enough space for both node and dirent. 
213          * Just the node will do for now, though 
214          */
215         namelen = dentry->d_name.len;
216         ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL);
217         D1(printk(KERN_DEBUG "jffs2_create(): reserved 0x%x bytes\n", alloclen));
218         if (ret) {
219                 jffs2_free_raw_inode(ri);
220                 return ret;
221         }
222
223         inode = jffs2_new_inode(dir_i, mode, ri);
224
225         if (IS_ERR(inode)) {
226                 D1(printk(KERN_DEBUG "jffs2_new_inode() failed\n"));
227                 jffs2_free_raw_inode(ri);
228                 jffs2_complete_reservation(c);
229                 return PTR_ERR(inode);
230         }
231
232         inode->i_op = &jffs2_file_inode_operations;
233         inode->i_fop = &jffs2_file_operations;
234         inode->i_mapping->a_ops = &jffs2_file_address_operations;
235         inode->i_mapping->nrpages = 0;
236
237         f = JFFS2_INODE_INFO(inode);
238
239         ri->data_crc = 0;
240         ri->node_crc = crc32(0, ri, sizeof(*ri)-8);
241
242         fn = jffs2_write_dnode(inode, ri, NULL, 0, phys_ofs, &writtenlen);
243         D1(printk(KERN_DEBUG "jffs2_create created file with mode 0x%x\n", ri->mode));
244         jffs2_free_raw_inode(ri);
245
246         if (IS_ERR(fn)) {
247                 D1(printk(KERN_DEBUG "jffs2_write_dnode() failed\n"));
248                 /* Eeek. Wave bye bye */
249                 up(&f->sem);
250                 jffs2_complete_reservation(c);
251                 jffs2_clear_inode(inode);
252                 return PTR_ERR(fn);
253         }
254         /* No data here. Only a metadata node, which will be 
255            obsoleted by the first data write
256         */
257         f->metadata = fn;
258
259         /* Work out where to put the dirent node now. */
260         writtenlen = PAD(writtenlen);
261         phys_ofs += writtenlen;
262         alloclen -= writtenlen;
263         up(&f->sem);
264
265         if (alloclen < sizeof(*rd)+namelen) {
266                 /* Not enough space left in this chunk. Get some more */
267                 jffs2_complete_reservation(c);
268                 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
269                 
270                 if (ret) {
271                         /* Eep. */
272                         D1(printk(KERN_DEBUG "jffs2_reserve_space() for dirent failed\n"));
273                         jffs2_clear_inode(inode);
274                         return ret;
275                 }
276         }
277
278         rd = jffs2_alloc_raw_dirent();
279         if (!rd) {
280                 /* Argh. Now we treat it like a normal delete */
281                 jffs2_complete_reservation(c);
282                 jffs2_clear_inode(inode);
283                 return -ENOMEM;
284         }
285
286         dir_f = JFFS2_INODE_INFO(dir_i);
287         down(&dir_f->sem);
288
289         rd->magic = JFFS2_MAGIC_BITMASK;
290         rd->nodetype = JFFS2_NODETYPE_DIRENT;
291         rd->totlen = sizeof(*rd) + namelen;
292         rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
293
294         rd->pino = dir_i->i_ino;
295         rd->version = dir_f->highest_version++;
296         rd->ino = inode->i_ino;
297         rd->mctime = CURRENT_TIME;
298         rd->nsize = namelen;
299         rd->type = DT_REG;
300         rd->node_crc = crc32(0, rd, sizeof(*rd)-8);
301         rd->name_crc = crc32(0, dentry->d_name.name, namelen);
302
303         fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, namelen, phys_ofs, &writtenlen);
304
305         jffs2_complete_reservation(c);
306         jffs2_free_raw_dirent(rd);
307         
308         if (IS_ERR(fd)) {
309                 /* dirent failed to write. Delete the inode normally 
310                    as if it were the final unlink() */
311                 up(&dir_f->sem);
312                 jffs2_clear_inode(inode);
313                 return PTR_ERR(fd);
314         }
315
316         /* Link the fd into the inode's list, obsoleting an old
317            one if necessary. */
318         jffs2_add_fd_to_list(c, fd, &dir_f->dents);
319         up(&dir_f->sem);
320
321         d_instantiate(dentry, inode);
322
323         D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n",
324                   inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->nlink, inode->i_mapping->nrpages));
325         return 0;
326 }
327
328 /***********************************************************************/
329
330 static int jffs2_do_unlink(struct inode *dir_i, struct dentry *dentry, int rename)
331 {
332         struct jffs2_inode_info *dir_f, *f;
333         struct jffs2_sb_info *c;
334         struct jffs2_raw_dirent *rd;
335         struct jffs2_full_dirent *fd;
336         __u32 alloclen, phys_ofs;
337         int ret;
338
339         c = JFFS2_SB_INFO(dir_i->i_sb);
340
341         rd = jffs2_alloc_raw_dirent();
342         if (!rd)
343                 return -ENOMEM;
344
345         ret = jffs2_reserve_space(c, sizeof(*rd)+dentry->d_name.len, &phys_ofs, &alloclen, ALLOC_DELETION);
346         if (ret) {
347                 jffs2_free_raw_dirent(rd);
348                 return ret;
349         }
350
351         dir_f = JFFS2_INODE_INFO(dir_i);
352         down(&dir_f->sem);
353
354         /* Build a deletion node */
355         rd->magic = JFFS2_MAGIC_BITMASK;
356         rd->nodetype = JFFS2_NODETYPE_DIRENT;
357         rd->totlen = sizeof(*rd) + dentry->d_name.len;
358         rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
359
360         rd->pino = dir_i->i_ino;
361         rd->version = dir_f->highest_version++;
362         rd->ino = 0;
363         rd->mctime = CURRENT_TIME;
364         rd->nsize = dentry->d_name.len;
365         rd->type = DT_UNKNOWN;
366         rd->node_crc = crc32(0, rd, sizeof(*rd)-8);
367         rd->name_crc = crc32(0, dentry->d_name.name, dentry->d_name.len);
368
369         fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, dentry->d_name.len, phys_ofs, NULL);
370         
371         jffs2_complete_reservation(c);
372         jffs2_free_raw_dirent(rd);
373
374         if (IS_ERR(fd)) {
375                 up(&dir_f->sem);
376                 return PTR_ERR(fd);
377         }
378
379         /* File it. This will mark the old one obsolete. */
380         jffs2_add_fd_to_list(c, fd, &dir_f->dents);
381         up(&dir_f->sem);
382         
383         if (!rename) {
384                 f = JFFS2_INODE_INFO(dentry->d_inode);
385                 down(&f->sem);
386
387                 while (f->dents) {
388                         /* There can be only deleted ones */
389                         fd = f->dents;
390                         
391                         f->dents = fd->next;
392                         
393                         if (fd->ino) {
394                                 printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n",
395                                        f->inocache->ino, fd->name, fd->ino);
396                         } else {
397                                 D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n", fd->name, f->inocache->ino));
398                         }
399                         jffs2_mark_node_obsolete(c, fd->raw);
400                         jffs2_free_full_dirent(fd);
401                 }
402
403                 f->inocache->nlink--;
404                 dentry->d_inode->i_nlink--;
405                 up(&f->sem);
406         }
407
408         return 0;
409 }
410
411 static int jffs2_unlink(struct inode *dir_i, struct dentry *dentry)
412 {
413         return jffs2_do_unlink(dir_i, dentry, 0);
414 }
415 /***********************************************************************/
416
417 static int jffs2_do_link (struct dentry *old_dentry, struct inode *dir_i, struct dentry *dentry, int rename)
418 {
419         struct jffs2_inode_info *dir_f, *f;
420         struct jffs2_sb_info *c;
421         struct jffs2_raw_dirent *rd;
422         struct jffs2_full_dirent *fd;
423         __u32 alloclen, phys_ofs;
424         int ret;
425
426         c = JFFS2_SB_INFO(dir_i->i_sb);
427
428         rd = jffs2_alloc_raw_dirent();
429         if (!rd)
430                 return -ENOMEM;
431
432         ret = jffs2_reserve_space(c, sizeof(*rd)+dentry->d_name.len, &phys_ofs, &alloclen, ALLOC_NORMAL);
433         if (ret) {
434                 jffs2_free_raw_dirent(rd);
435                 return ret;
436         }
437         
438         dir_f = JFFS2_INODE_INFO(dir_i);
439         down(&dir_f->sem);
440
441         /* Build a deletion node */
442         rd->magic = JFFS2_MAGIC_BITMASK;
443         rd->nodetype = JFFS2_NODETYPE_DIRENT;
444         rd->totlen = sizeof(*rd) + dentry->d_name.len;
445         rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
446
447         rd->pino = dir_i->i_ino;
448         rd->version = dir_f->highest_version++;
449         rd->ino = old_dentry->d_inode->i_ino;
450         rd->mctime = CURRENT_TIME;
451         rd->nsize = dentry->d_name.len;
452
453         /* XXX: This is ugly. */
454         rd->type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12;
455         if (!rd->type) rd->type = DT_REG;
456
457         rd->node_crc = crc32(0, rd, sizeof(*rd)-8);
458         rd->name_crc = crc32(0, dentry->d_name.name, dentry->d_name.len);
459
460         fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, dentry->d_name.len, phys_ofs, NULL);
461         
462         jffs2_complete_reservation(c);
463         jffs2_free_raw_dirent(rd);
464
465         if (IS_ERR(fd)) {
466                 up(&dir_f->sem);
467                 return PTR_ERR(fd);
468         }
469
470         /* File it. This will mark the old one obsolete. */
471         jffs2_add_fd_to_list(c, fd, &dir_f->dents);
472         up(&dir_f->sem);
473
474         if (!rename) {
475                 f = JFFS2_INODE_INFO(old_dentry->d_inode);
476                 down(&f->sem);
477                 old_dentry->d_inode->i_nlink = ++f->inocache->nlink;
478                 up(&f->sem);
479         }
480         return 0;
481 }
482
483 static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct dentry *dentry)
484 {
485         int ret = jffs2_do_link(old_dentry, dir_i, dentry, 0);
486         if (!ret) {
487                 d_instantiate(dentry, old_dentry->d_inode);
488                 atomic_inc(&old_dentry->d_inode->i_count);
489         }
490         return ret;
491 }
492
493 /***********************************************************************/
494
495 static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char *target)
496 {
497         struct jffs2_inode_info *f, *dir_f;
498         struct jffs2_sb_info *c;
499         struct inode *inode;
500         struct jffs2_raw_inode *ri;
501         struct jffs2_raw_dirent *rd;
502         struct jffs2_full_dnode *fn;
503         struct jffs2_full_dirent *fd;
504         int namelen;
505         __u32 alloclen, phys_ofs;
506         __u32 writtenlen;
507         int ret;
508
509         /* FIXME: If you care. We'd need to use frags for the target
510            if it grows much more than this */
511         if (strlen(target) > 254)
512                 return -EINVAL;
513
514         ri = jffs2_alloc_raw_inode();
515
516         if (!ri)
517                 return -ENOMEM;
518         
519         c = JFFS2_SB_INFO(dir_i->i_sb);
520         
521         /* Try to reserve enough space for both node and dirent. 
522          * Just the node will do for now, though 
523          */
524         namelen = dentry->d_name.len;
525         ret = jffs2_reserve_space(c, sizeof(*ri) + strlen(target), &phys_ofs, &alloclen, ALLOC_NORMAL);
526
527         if (ret) {
528                 jffs2_free_raw_inode(ri);
529                 return ret;
530         }
531
532         inode = jffs2_new_inode(dir_i, S_IFLNK | S_IRWXUGO, ri);
533
534         if (IS_ERR(inode)) {
535                 jffs2_free_raw_inode(ri);
536                 jffs2_complete_reservation(c);
537                 return PTR_ERR(inode);
538         }
539
540         inode->i_op = &jffs2_symlink_inode_operations;
541
542         f = JFFS2_INODE_INFO(inode);
543
544         ri->dsize = ri->csize = strlen(target);
545         ri->totlen = sizeof(*ri) + ri->dsize;
546         ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4);
547
548         ri->compr = JFFS2_COMPR_NONE;
549         ri->data_crc = crc32(0, target, strlen(target));
550         ri->node_crc = crc32(0, ri, sizeof(*ri)-8);
551         
552         fn = jffs2_write_dnode(inode, ri, target, strlen(target), phys_ofs, &writtenlen);
553
554         jffs2_free_raw_inode(ri);
555
556         if (IS_ERR(fn)) {
557                 /* Eeek. Wave bye bye */
558                 up(&f->sem);
559                 jffs2_complete_reservation(c);
560                 jffs2_clear_inode(inode);
561                 return PTR_ERR(fn);
562         }
563         /* No data here. Only a metadata node, which will be 
564            obsoleted by the first data write
565         */
566         f->metadata = fn;
567         up(&f->sem);
568
569         /* Work out where to put the dirent node now. */
570         writtenlen = (writtenlen+3)&~3;
571         phys_ofs += writtenlen;
572         alloclen -= writtenlen;
573
574         if (alloclen < sizeof(*rd)+namelen) {
575                 /* Not enough space left in this chunk. Get some more */
576                 jffs2_complete_reservation(c);
577                 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
578                 if (ret) {
579                         /* Eep. */
580                         jffs2_clear_inode(inode);
581                         return ret;
582                 }
583         }
584
585         rd = jffs2_alloc_raw_dirent();
586         if (!rd) {
587                 /* Argh. Now we treat it like a normal delete */
588                 jffs2_complete_reservation(c);
589                 jffs2_clear_inode(inode);
590                 return -ENOMEM;
591         }
592
593         dir_f = JFFS2_INODE_INFO(dir_i);
594         down(&dir_f->sem);
595
596         rd->magic = JFFS2_MAGIC_BITMASK;
597         rd->nodetype = JFFS2_NODETYPE_DIRENT;
598         rd->totlen = sizeof(*rd) + namelen;
599         rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
600
601         rd->pino = dir_i->i_ino;
602         rd->version = dir_f->highest_version++;
603         rd->ino = inode->i_ino;
604         rd->mctime = CURRENT_TIME;
605         rd->nsize = namelen;
606         rd->type = DT_LNK;
607         rd->node_crc = crc32(0, rd, sizeof(*rd)-8);
608         rd->name_crc = crc32(0, dentry->d_name.name, namelen);
609
610         fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, namelen, phys_ofs, &writtenlen);
611         
612         jffs2_complete_reservation(c);
613         jffs2_free_raw_dirent(rd);
614         
615         if (IS_ERR(fd)) {
616                 /* dirent failed to write. Delete the inode normally 
617                    as if it were the final unlink() */
618                 up(&dir_f->sem);
619                 jffs2_clear_inode(inode);
620                 return PTR_ERR(fd);
621         }
622
623         /* Link the fd into the inode's list, obsoleting an old
624            one if necessary. */
625         jffs2_add_fd_to_list(c, fd, &dir_f->dents);
626         up(&dir_f->sem);
627
628         d_instantiate(dentry, inode);
629         return 0;
630 }
631
632
633 static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
634 {
635         struct jffs2_inode_info *f, *dir_f;
636         struct jffs2_sb_info *c;
637         struct inode *inode;
638         struct jffs2_raw_inode *ri;
639         struct jffs2_raw_dirent *rd;
640         struct jffs2_full_dnode *fn;
641         struct jffs2_full_dirent *fd;
642         int namelen;
643         __u32 alloclen, phys_ofs;
644         __u32 writtenlen;
645         int ret;
646
647         mode |= S_IFDIR;
648
649         ri = jffs2_alloc_raw_inode();
650         if (!ri)
651                 return -ENOMEM;
652         
653         c = JFFS2_SB_INFO(dir_i->i_sb);
654
655         /* Try to reserve enough space for both node and dirent. 
656          * Just the node will do for now, though 
657          */
658         namelen = dentry->d_name.len;
659         ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL);
660
661         if (ret) {
662                 jffs2_free_raw_inode(ri);
663                 return ret;
664         }
665
666         inode = jffs2_new_inode(dir_i, mode, ri);
667
668         if (IS_ERR(inode)) {
669                 jffs2_free_raw_inode(ri);
670                 jffs2_complete_reservation(c);
671                 return PTR_ERR(inode);
672         }
673
674         inode->i_op = &jffs2_dir_inode_operations;
675         inode->i_fop = &jffs2_dir_operations;
676
677         f = JFFS2_INODE_INFO(inode);
678
679         ri->data_crc = 0;
680         ri->node_crc = crc32(0, ri, sizeof(*ri)-8);
681         
682         fn = jffs2_write_dnode(inode, ri, NULL, 0, phys_ofs, &writtenlen);
683
684         jffs2_free_raw_inode(ri);
685
686         if (IS_ERR(fn)) {
687                 /* Eeek. Wave bye bye */
688                 up(&f->sem);
689                 jffs2_complete_reservation(c);
690                 jffs2_clear_inode(inode);
691                 return PTR_ERR(fn);
692         }
693         /* No data here. Only a metadata node, which will be 
694            obsoleted by the first data write
695         */
696         f->metadata = fn;
697         up(&f->sem);
698
699         /* Work out where to put the dirent node now. */
700         writtenlen = PAD(writtenlen);
701         phys_ofs += writtenlen;
702         alloclen -= writtenlen;
703
704         if (alloclen < sizeof(*rd)+namelen) {
705                 /* Not enough space left in this chunk. Get some more */
706                 jffs2_complete_reservation(c);
707                 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
708                 if (ret) {
709                         /* Eep. */
710                         jffs2_clear_inode(inode);
711                         return ret;
712                 }
713         }
714         
715         rd = jffs2_alloc_raw_dirent();
716         if (!rd) {
717                 /* Argh. Now we treat it like a normal delete */
718                 jffs2_complete_reservation(c);
719                 jffs2_clear_inode(inode);
720                 return -ENOMEM;
721         }
722
723         dir_f = JFFS2_INODE_INFO(dir_i);
724         down(&dir_f->sem);
725
726         rd->magic = JFFS2_MAGIC_BITMASK;
727         rd->nodetype = JFFS2_NODETYPE_DIRENT;
728         rd->totlen = sizeof(*rd) + namelen;
729         rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
730
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         rd->type = DT_DIR;
737         rd->node_crc = crc32(0, rd, sizeof(*rd)-8);
738         rd->name_crc = crc32(0, dentry->d_name.name, namelen);
739
740         fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, namelen, phys_ofs, &writtenlen);
741         
742         jffs2_complete_reservation(c);
743         jffs2_free_raw_dirent(rd);
744         
745         if (IS_ERR(fd)) {
746                 /* dirent failed to write. Delete the inode normally 
747                    as if it were the final unlink() */
748                 up(&dir_f->sem);
749                 jffs2_clear_inode(inode);
750                 return PTR_ERR(fd);
751         }
752
753         /* Link the fd into the inode's list, obsoleting an old
754            one if necessary. */
755         jffs2_add_fd_to_list(c, fd, &dir_f->dents);
756         up(&dir_f->sem);
757
758         d_instantiate(dentry, inode);
759         return 0;
760 }
761
762 static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry)
763 {
764         struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode);
765         struct jffs2_full_dirent *fd;
766
767         for (fd = f->dents ; fd; fd = fd->next) {
768                 if (fd->ino)
769                         return -ENOTEMPTY;
770         }
771         return jffs2_unlink(dir_i, dentry);
772 }
773
774 static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, int rdev)
775 {
776         struct jffs2_inode_info *f, *dir_f;
777         struct jffs2_sb_info *c;
778         struct inode *inode;
779         struct jffs2_raw_inode *ri;
780         struct jffs2_raw_dirent *rd;
781         struct jffs2_full_dnode *fn;
782         struct jffs2_full_dirent *fd;
783         int namelen;
784         unsigned short dev;
785         int devlen = 0;
786         __u32 alloclen, phys_ofs;
787         __u32 writtenlen;
788         int ret;
789
790         ri = jffs2_alloc_raw_inode();
791         if (!ri)
792                 return -ENOMEM;
793         
794         c = JFFS2_SB_INFO(dir_i->i_sb);
795         
796         if ((mode & S_IFMT) == S_IFBLK ||
797             (mode & S_IFMT) == S_IFCHR) {
798                 dev = (MAJOR(to_kdev_t(rdev)) << 8) | MINOR(to_kdev_t(rdev));
799                 devlen = sizeof(dev);
800         }
801         
802         /* Try to reserve enough space for both node and dirent. 
803          * Just the node will do for now, though 
804          */
805         namelen = dentry->d_name.len;
806         ret = jffs2_reserve_space(c, sizeof(*ri) + devlen, &phys_ofs, &alloclen, ALLOC_NORMAL);
807
808         if (ret) {
809                 jffs2_free_raw_inode(ri);
810                 return ret;
811         }
812
813         inode = jffs2_new_inode(dir_i, mode, ri);
814
815         if (IS_ERR(inode)) {
816                 jffs2_free_raw_inode(ri);
817                 jffs2_complete_reservation(c);
818                 return PTR_ERR(inode);
819         }
820         inode->i_op = &jffs2_file_inode_operations;
821         init_special_inode(inode, inode->i_mode, rdev);
822
823         f = JFFS2_INODE_INFO(inode);
824
825         ri->dsize = ri->csize = devlen;
826         ri->totlen = sizeof(*ri) + ri->csize;
827         ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4);
828
829         ri->compr = JFFS2_COMPR_NONE;
830         ri->data_crc = crc32(0, &dev, devlen);
831         ri->node_crc = crc32(0, ri, sizeof(*ri)-8);
832         
833         fn = jffs2_write_dnode(inode, ri, (char *)&dev, devlen, phys_ofs, &writtenlen);
834
835         jffs2_free_raw_inode(ri);
836
837         if (IS_ERR(fn)) {
838                 /* Eeek. Wave bye bye */
839                 up(&f->sem);
840                 jffs2_complete_reservation(c);
841                 jffs2_clear_inode(inode);
842                 return PTR_ERR(fn);
843         }
844         /* No data here. Only a metadata node, which will be 
845            obsoleted by the first data write
846         */
847         f->metadata = fn;
848         up(&f->sem);
849
850         /* Work out where to put the dirent node now. */
851         writtenlen = (writtenlen+3)&~3;
852         phys_ofs += writtenlen;
853         alloclen -= writtenlen;
854
855         if (alloclen < sizeof(*rd)+namelen) {
856                 /* Not enough space left in this chunk. Get some more */
857                 jffs2_complete_reservation(c);
858                 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
859                 if (ret) {
860                         /* Eep. */
861                         jffs2_clear_inode(inode);
862                         return ret;
863                 }
864         }
865
866         rd = jffs2_alloc_raw_dirent();
867         if (!rd) {
868                 /* Argh. Now we treat it like a normal delete */
869                 jffs2_complete_reservation(c);
870                 jffs2_clear_inode(inode);
871                 return -ENOMEM;
872         }
873
874         dir_f = JFFS2_INODE_INFO(dir_i);
875         down(&dir_f->sem);
876
877         rd->magic = JFFS2_MAGIC_BITMASK;
878         rd->nodetype = JFFS2_NODETYPE_DIRENT;
879         rd->totlen = sizeof(*rd) + namelen;
880         rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
881
882         rd->pino = dir_i->i_ino;
883         rd->version = dir_f->highest_version++;
884         rd->ino = inode->i_ino;
885         rd->mctime = CURRENT_TIME;
886         rd->nsize = namelen;
887
888         /* XXX: This is ugly. */
889         rd->type = (mode & S_IFMT) >> 12;
890
891         rd->node_crc = crc32(0, rd, sizeof(*rd)-8);
892         rd->name_crc = crc32(0, dentry->d_name.name, namelen);
893
894         fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, namelen, phys_ofs, &writtenlen);
895         
896         jffs2_complete_reservation(c);
897         jffs2_free_raw_dirent(rd);
898         
899         if (IS_ERR(fd)) {
900                 /* dirent failed to write. Delete the inode normally 
901                    as if it were the final unlink() */
902                 up(&dir_f->sem);
903                 jffs2_clear_inode(inode);
904                 return PTR_ERR(fd);
905         }
906
907         /* Link the fd into the inode's list, obsoleting an old
908            one if necessary. */
909         jffs2_add_fd_to_list(c, fd, &dir_f->dents);
910         up(&dir_f->sem);
911
912         d_instantiate(dentry, inode);
913         return 0;
914 }
915
916 static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
917                         struct inode *new_dir_i, struct dentry *new_dentry)
918 {
919         int ret;
920         /* XXX: We probably ought to alloc enough space for
921            both nodes at the same time. Writing the new link, 
922            then getting -ENOSPC, is quite bad :)
923         */
924
925         /* Make a hard link */
926         ret = jffs2_do_link(old_dentry, new_dir_i, new_dentry, 1);
927         if (ret)
928                 return ret;
929
930         /* Unlink the original */
931         ret = jffs2_do_unlink(old_dir_i, old_dentry, 1);
932         
933         if (ret) {
934                 /* Try to delete the _new_ link to return a clean failure */
935                 int ret2 = jffs2_do_unlink(new_dir_i, new_dentry, 1);
936                 if (ret2) {
937                         struct jffs2_inode_info *f = JFFS2_INODE_INFO(old_dentry->d_inode);
938                         down(&f->sem);
939                         old_dentry->d_inode->i_nlink = f->inocache->nlink++;
940                         up(&f->sem);
941                        
942                         printk(KERN_NOTICE "jffs2_rename(): Link succeeded, unlink failed (old err %d, new err %d). You now have a hard link\n", ret, ret2);
943                         /* Might as well let the VFS know */
944                         d_instantiate(new_dentry, old_dentry->d_inode);
945                         atomic_inc(&old_dentry->d_inode->i_count);
946                 }
947                 
948         }
949         return ret;
950 }
951