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