[PATCH] mark struct inode_operations const 1
[deliverable/linux.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;
ec2e203c 126 struct inode *inode = filp->f_path.dentry->d_inode;
1da177e4
LT
127 struct jffs2_full_dirent *fd;
128 unsigned long offset, curofs;
129
ec2e203c 130 D1(printk(KERN_DEBUG "jffs2_readdir() for dir_i #%lu\n", filp->f_path.dentry->d_inode->i_ino));
1da177e4
LT
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) {
ec2e203c 144 unsigned long pino = parent_ino(filp->f_path.dentry);
1da177e4
LT
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;
9fe4854c 311 uint32_t alloclen;
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;
9fe4854c
DW
330 ret = jffs2_reserve_space(c, sizeof(*ri) + targetlen, &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
9fe4854c 359 fn = jffs2_write_dnode(c, f, ri, target, targetlen, 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
9fe4854c
DW
403 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &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
9fe4854c 436 fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, ALLOC_NORMAL);
1da177e4
LT
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;
9fe4854c 474 uint32_t alloclen;
1da177e4
LT
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;
9fe4854c
DW
489 ret = jffs2_reserve_space(c, sizeof(*ri), &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
9fe4854c 515 fn = jffs2_write_dnode(c, f, ri, NULL, 0, ALLOC_NORMAL);
1da177e4
LT
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
9fe4854c
DW
545 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &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
9fe4854c 578 fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, 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));
d8c76e6f 591 inc_nlink(dir_i);
1da177e4
LT
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)
9a53c3a7 618 drop_nlink(dir_i);
1da177e4
LT
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;
aef9ab47 632 union jffs2_device_node dev;
1da177e4 633 int devlen = 0;
9fe4854c 634 uint32_t alloclen;
1da177e4
LT
635 int ret;
636
aef9ab47 637 if (!new_valid_dev(rdev))
1da177e4
LT
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
aef9ab47
DW
646 if (S_ISBLK(mode) || S_ISCHR(mode))
647 devlen = jffs2_encode_dev(&dev, rdev);
182ec4ee
TG
648
649 /* Try to reserve enough space for both node and dirent.
650 * Just the node will do for now, though
1da177e4
LT
651 */
652 namelen = dentry->d_name.len;
9fe4854c 653 ret = jffs2_reserve_space(c, sizeof(*ri) + devlen, &alloclen,
aef9ab47 654 ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
1da177e4
LT
655
656 if (ret) {
657 jffs2_free_raw_inode(ri);
658 return ret;
659 }
660
661 inode = jffs2_new_inode(dir_i, mode, ri);
662
663 if (IS_ERR(inode)) {
664 jffs2_free_raw_inode(ri);
665 jffs2_complete_reservation(c);
666 return PTR_ERR(inode);
667 }
668 inode->i_op = &jffs2_file_inode_operations;
669 init_special_inode(inode, inode->i_mode, rdev);
670
671 f = JFFS2_INODE_INFO(inode);
672
673 ri->dsize = ri->csize = cpu_to_je32(devlen);
674 ri->totlen = cpu_to_je32(sizeof(*ri) + devlen);
675 ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
676
677 ri->compr = JFFS2_COMPR_NONE;
678 ri->data_crc = cpu_to_je32(crc32(0, &dev, devlen));
679 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
182ec4ee 680
9fe4854c 681 fn = jffs2_write_dnode(c, f, ri, (char *)&dev, devlen, ALLOC_NORMAL);
1da177e4
LT
682
683 jffs2_free_raw_inode(ri);
684
685 if (IS_ERR(fn)) {
686 /* Eeek. Wave bye bye */
687 up(&f->sem);
688 jffs2_complete_reservation(c);
689 jffs2_clear_inode(inode);
690 return PTR_ERR(fn);
691 }
182ec4ee 692 /* No data here. Only a metadata node, which will be
1da177e4
LT
693 obsoleted by the first data write
694 */
695 f->metadata = fn;
696 up(&f->sem);
697
698 jffs2_complete_reservation(c);
aa98d7cf
KK
699
700 ret = jffs2_init_security(inode, dir_i);
701 if (ret) {
702 jffs2_clear_inode(inode);
703 return ret;
704 }
705 ret = jffs2_init_acl(inode, dir_i);
706 if (ret) {
707 jffs2_clear_inode(inode);
708 return ret;
709 }
710
9fe4854c
DW
711 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
712 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
1da177e4
LT
713 if (ret) {
714 /* Eep. */
715 jffs2_clear_inode(inode);
716 return ret;
717 }
718
719 rd = jffs2_alloc_raw_dirent();
720 if (!rd) {
721 /* Argh. Now we treat it like a normal delete */
722 jffs2_complete_reservation(c);
723 jffs2_clear_inode(inode);
724 return -ENOMEM;
725 }
726
727 dir_f = JFFS2_INODE_INFO(dir_i);
728 down(&dir_f->sem);
729
730 rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
731 rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
732 rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
733 rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
734
735 rd->pino = cpu_to_je32(dir_i->i_ino);
736 rd->version = cpu_to_je32(++dir_f->highest_version);
737 rd->ino = cpu_to_je32(inode->i_ino);
738 rd->mctime = cpu_to_je32(get_seconds());
739 rd->nsize = namelen;
740
741 /* XXX: This is ugly. */
742 rd->type = (mode & S_IFMT) >> 12;
743
744 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
745 rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen));
746
9fe4854c 747 fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, ALLOC_NORMAL);
182ec4ee 748
1da177e4 749 if (IS_ERR(fd)) {
182ec4ee 750 /* dirent failed to write. Delete the inode normally
1da177e4
LT
751 as if it were the final unlink() */
752 jffs2_complete_reservation(c);
753 jffs2_free_raw_dirent(rd);
754 up(&dir_f->sem);
755 jffs2_clear_inode(inode);
756 return PTR_ERR(fd);
757 }
758
759 dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime));
760
761 jffs2_free_raw_dirent(rd);
762
763 /* Link the fd into the inode's list, obsoleting an old
764 one if necessary. */
765 jffs2_add_fd_to_list(c, fd, &dir_f->dents);
766
767 up(&dir_f->sem);
768 jffs2_complete_reservation(c);
769
770 d_instantiate(dentry, inode);
771
772 return 0;
773}
774
775static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
776 struct inode *new_dir_i, struct dentry *new_dentry)
777{
778 int ret;
779 struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb);
780 struct jffs2_inode_info *victim_f = NULL;
781 uint8_t type;
3a69e0cd 782 uint32_t now;
1da177e4 783
182ec4ee 784 /* The VFS will check for us and prevent trying to rename a
1da177e4
LT
785 * file over a directory and vice versa, but if it's a directory,
786 * the VFS can't check whether the victim is empty. The filesystem
787 * needs to do that for itself.
788 */
789 if (new_dentry->d_inode) {
790 victim_f = JFFS2_INODE_INFO(new_dentry->d_inode);
791 if (S_ISDIR(new_dentry->d_inode->i_mode)) {
792 struct jffs2_full_dirent *fd;
793
794 down(&victim_f->sem);
795 for (fd = victim_f->dents; fd; fd = fd->next) {
796 if (fd->ino) {
797 up(&victim_f->sem);
798 return -ENOTEMPTY;
799 }
800 }
801 up(&victim_f->sem);
802 }
803 }
804
805 /* XXX: We probably ought to alloc enough space for
182ec4ee 806 both nodes at the same time. Writing the new link,
1da177e4
LT
807 then getting -ENOSPC, is quite bad :)
808 */
809
810 /* Make a hard link */
182ec4ee 811
1da177e4
LT
812 /* XXX: This is ugly */
813 type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12;
814 if (!type) type = DT_REG;
815
3a69e0cd 816 now = get_seconds();
182ec4ee 817 ret = jffs2_do_link(c, JFFS2_INODE_INFO(new_dir_i),
1da177e4 818 old_dentry->d_inode->i_ino, type,
3a69e0cd 819 new_dentry->d_name.name, new_dentry->d_name.len, now);
1da177e4
LT
820
821 if (ret)
822 return ret;
823
824 if (victim_f) {
825 /* There was a victim. Kill it off nicely */
9a53c3a7 826 drop_nlink(new_dentry->d_inode);
1da177e4
LT
827 /* Don't oops if the victim was a dirent pointing to an
828 inode which didn't exist. */
829 if (victim_f->inocache) {
830 down(&victim_f->sem);
831 victim_f->inocache->nlink--;
832 up(&victim_f->sem);
833 }
834 }
835
182ec4ee 836 /* If it was a directory we moved, and there was no victim,
1da177e4
LT
837 increase i_nlink on its new parent */
838 if (S_ISDIR(old_dentry->d_inode->i_mode) && !victim_f)
d8c76e6f 839 inc_nlink(new_dir_i);
1da177e4
LT
840
841 /* Unlink the original */
182ec4ee 842 ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
3a69e0cd 843 old_dentry->d_name.name, old_dentry->d_name.len, NULL, now);
1da177e4
LT
844
845 /* We don't touch inode->i_nlink */
846
847 if (ret) {
848 /* Oh shit. We really ought to make a single node which can do both atomically */
849 struct jffs2_inode_info *f = JFFS2_INODE_INFO(old_dentry->d_inode);
850 down(&f->sem);
d8c76e6f 851 inc_nlink(old_dentry->d_inode);
1da177e4
LT
852 if (f->inocache)
853 f->inocache->nlink++;
854 up(&f->sem);
855
856 printk(KERN_NOTICE "jffs2_rename(): Link succeeded, unlink failed (err %d). You now have a hard link\n", ret);
857 /* Might as well let the VFS know */
858 d_instantiate(new_dentry, old_dentry->d_inode);
859 atomic_inc(&old_dentry->d_inode->i_count);
3a69e0cd 860 new_dir_i->i_mtime = new_dir_i->i_ctime = ITIME(now);
1da177e4
LT
861 return ret;
862 }
863
864 if (S_ISDIR(old_dentry->d_inode->i_mode))
9a53c3a7 865 drop_nlink(old_dir_i);
1da177e4 866
3a69e0cd
AB
867 new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = ITIME(now);
868
1da177e4
LT
869 return 0;
870}
871
This page took 0.188123 seconds and 5 git commands to generate.