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