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