aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/jffs2/dir.c12
-rw-r--r--fs/jffs2/fs.c25
-rw-r--r--fs/jffs2/gc.c7
-rw-r--r--fs/jffs2/nodelist.h11
-rw-r--r--fs/jffs2/os-linux.h4
-rw-r--r--include/linux/jffs2.h6
6 files changed, 43 insertions, 22 deletions
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index 1c8e8c0f6cea..a6c11cef1b73 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -591,12 +591,12 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
591 struct jffs2_full_dnode *fn; 591 struct jffs2_full_dnode *fn;
592 struct jffs2_full_dirent *fd; 592 struct jffs2_full_dirent *fd;
593 int namelen; 593 int namelen;
594 jint16_t dev; 594 union jffs2_device_node dev;
595 int devlen = 0; 595 int devlen = 0;
596 uint32_t alloclen, phys_ofs; 596 uint32_t alloclen, phys_ofs;
597 int ret; 597 int ret;
598 598
599 if (!old_valid_dev(rdev)) 599 if (!new_valid_dev(rdev))
600 return -EINVAL; 600 return -EINVAL;
601 601
602 ri = jffs2_alloc_raw_inode(); 602 ri = jffs2_alloc_raw_inode();
@@ -605,17 +605,15 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
605 605
606 c = JFFS2_SB_INFO(dir_i->i_sb); 606 c = JFFS2_SB_INFO(dir_i->i_sb);
607 607
608 if (S_ISBLK(mode) || S_ISCHR(mode)) { 608 if (S_ISBLK(mode) || S_ISCHR(mode))
609 dev = cpu_to_je16(old_encode_dev(rdev)); 609 devlen = jffs2_encode_dev(&dev, rdev);
610 devlen = sizeof(dev);
611 }
612 610
613 /* Try to reserve enough space for both node and dirent. 611 /* Try to reserve enough space for both node and dirent.
614 * Just the node will do for now, though 612 * Just the node will do for now, though
615 */ 613 */
616 namelen = dentry->d_name.len; 614 namelen = dentry->d_name.len;
617 ret = jffs2_reserve_space(c, sizeof(*ri) + devlen, &phys_ofs, &alloclen, 615 ret = jffs2_reserve_space(c, sizeof(*ri) + devlen, &phys_ofs, &alloclen,
618 ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); 616 ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
619 617
620 if (ret) { 618 if (ret) {
621 jffs2_free_raw_inode(ri); 619 jffs2_free_raw_inode(ri);
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index ea1f37d4fc58..24cb4c688efc 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -33,7 +33,7 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
33 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); 33 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
34 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); 34 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
35 struct jffs2_raw_inode *ri; 35 struct jffs2_raw_inode *ri;
36 unsigned short dev; 36 union jffs2_device_node dev;
37 unsigned char *mdata = NULL; 37 unsigned char *mdata = NULL;
38 int mdatalen = 0; 38 int mdatalen = 0;
39 unsigned int ivalid; 39 unsigned int ivalid;
@@ -51,9 +51,8 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
51 it out again with the appropriate data attached */ 51 it out again with the appropriate data attached */
52 if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { 52 if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
53 /* For these, we don't actually need to read the old node */ 53 /* For these, we don't actually need to read the old node */
54 dev = old_encode_dev(inode->i_rdev); 54 mdatalen = jffs2_encode_dev(&dev, inode->i_rdev);
55 mdata = (char *)&dev; 55 mdata = (char *)&dev;
56 mdatalen = sizeof(dev);
57 D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of kdev_t\n", mdatalen)); 56 D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of kdev_t\n", mdatalen));
58 } else if (S_ISLNK(inode->i_mode)) { 57 } else if (S_ISLNK(inode->i_mode)) {
59 down(&f->sem); 58 down(&f->sem);
@@ -232,6 +231,8 @@ void jffs2_read_inode (struct inode *inode)
232 struct jffs2_inode_info *f; 231 struct jffs2_inode_info *f;
233 struct jffs2_sb_info *c; 232 struct jffs2_sb_info *c;
234 struct jffs2_raw_inode latest_node; 233 struct jffs2_raw_inode latest_node;
234 union jffs2_device_node jdev;
235 dev_t rdev = 0;
235 int ret; 236 int ret;
236 237
237 D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino)); 238 D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino));
@@ -263,7 +264,6 @@ void jffs2_read_inode (struct inode *inode)
263 inode->i_blocks = (inode->i_size + 511) >> 9; 264 inode->i_blocks = (inode->i_size + 511) >> 9;
264 265
265 switch (inode->i_mode & S_IFMT) { 266 switch (inode->i_mode & S_IFMT) {
266 jint16_t rdev;
267 267
268 case S_IFLNK: 268 case S_IFLNK:
269 inode->i_op = &jffs2_symlink_inode_operations; 269 inode->i_op = &jffs2_symlink_inode_operations;
@@ -297,8 +297,16 @@ void jffs2_read_inode (struct inode *inode)
297 case S_IFBLK: 297 case S_IFBLK:
298 case S_IFCHR: 298 case S_IFCHR:
299 /* Read the device numbers from the media */ 299 /* Read the device numbers from the media */
300 if (f->metadata->size != sizeof(jdev.old) &&
301 f->metadata->size != sizeof(jdev.new)) {
302 printk(KERN_NOTICE "Device node has strange size %d\n", f->metadata->size);
303 up(&f->sem);
304 jffs2_do_clear_inode(c, f);
305 make_bad_inode(inode);
306 return;
307 }
300 D1(printk(KERN_DEBUG "Reading device numbers from flash\n")); 308 D1(printk(KERN_DEBUG "Reading device numbers from flash\n"));
301 if (jffs2_read_dnode(c, f, f->metadata, (char *)&rdev, 0, sizeof(rdev)) < 0) { 309 if (jffs2_read_dnode(c, f, f->metadata, (char *)&jdev, 0, f->metadata->size) < 0) {
302 /* Eep */ 310 /* Eep */
303 printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino); 311 printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino);
304 up(&f->sem); 312 up(&f->sem);
@@ -306,12 +314,15 @@ void jffs2_read_inode (struct inode *inode)
306 make_bad_inode(inode); 314 make_bad_inode(inode);
307 return; 315 return;
308 } 316 }
317 if (f->metadata->size == sizeof(jdev.old))
318 rdev = old_decode_dev(je16_to_cpu(jdev.old));
319 else
320 rdev = new_decode_dev(je32_to_cpu(jdev.new));
309 321
310 case S_IFSOCK: 322 case S_IFSOCK:
311 case S_IFIFO: 323 case S_IFIFO:
312 inode->i_op = &jffs2_file_inode_operations; 324 inode->i_op = &jffs2_file_inode_operations;
313 init_special_inode(inode, inode->i_mode, 325 init_special_inode(inode, inode->i_mode, rdev);
314 old_decode_dev((je16_to_cpu(rdev))));
315 break; 326 break;
316 327
317 default: 328 default:
diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c
index 967fb2cf8e21..77d30707de56 100644
--- a/fs/jffs2/gc.c
+++ b/fs/jffs2/gc.c
@@ -679,7 +679,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
679 struct jffs2_full_dnode *new_fn; 679 struct jffs2_full_dnode *new_fn;
680 struct jffs2_raw_inode ri; 680 struct jffs2_raw_inode ri;
681 struct jffs2_node_frag *last_frag; 681 struct jffs2_node_frag *last_frag;
682 jint16_t dev; 682 union jffs2_device_node dev;
683 char *mdata = NULL, mdatalen = 0; 683 char *mdata = NULL, mdatalen = 0;
684 uint32_t alloclen, phys_ofs, ilen; 684 uint32_t alloclen, phys_ofs, ilen;
685 int ret; 685 int ret;
@@ -687,11 +687,8 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
687 if (S_ISBLK(JFFS2_F_I_MODE(f)) || 687 if (S_ISBLK(JFFS2_F_I_MODE(f)) ||
688 S_ISCHR(JFFS2_F_I_MODE(f)) ) { 688 S_ISCHR(JFFS2_F_I_MODE(f)) ) {
689 /* For these, we don't actually need to read the old node */ 689 /* For these, we don't actually need to read the old node */
690 /* FIXME: for minor or major > 255. */ 690 mdatalen = jffs2_encode_dev(&dev, JFFS2_F_I_RDEV(f));
691 dev = cpu_to_je16(((JFFS2_F_I_RDEV_MAJ(f) << 8) |
692 JFFS2_F_I_RDEV_MIN(f)));
693 mdata = (char *)&dev; 691 mdata = (char *)&dev;
694 mdatalen = sizeof(dev);
695 D1(printk(KERN_DEBUG "jffs2_garbage_collect_metadata(): Writing %d bytes of kdev_t\n", mdatalen)); 692 D1(printk(KERN_DEBUG "jffs2_garbage_collect_metadata(): Writing %d bytes of kdev_t\n", mdatalen));
696 } else if (S_ISLNK(JFFS2_F_I_MODE(f))) { 693 } else if (S_ISLNK(JFFS2_F_I_MODE(f))) {
697 mdatalen = fn->size; 694 mdatalen = fn->size;
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
index f6645afe88e4..24e0f28a8bac 100644
--- a/fs/jffs2/nodelist.h
+++ b/fs/jffs2/nodelist.h
@@ -268,6 +268,17 @@ static inline uint32_t ref_totlen(struct jffs2_sb_info *c,
268 268
269#define PAD(x) (((x)+3)&~3) 269#define PAD(x) (((x)+3)&~3)
270 270
271static inline int jffs2_encode_dev(union jffs2_device_node *jdev, dev_t rdev)
272{
273 if (old_valid_dev(rdev)) {
274 jdev->old = cpu_to_je16(old_encode_dev(rdev));
275 return sizeof(jdev->old);
276 } else {
277 jdev->new = cpu_to_je32(new_encode_dev(rdev));
278 return sizeof(jdev->new);
279 }
280}
281
271static inline struct jffs2_inode_cache *jffs2_raw_ref_to_ic(struct jffs2_raw_node_ref *raw) 282static inline struct jffs2_inode_cache *jffs2_raw_ref_to_ic(struct jffs2_raw_node_ref *raw)
272{ 283{
273 while(raw->next_in_ino) { 284 while(raw->next_in_ino) {
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index d307cf548625..a10eb03ac95b 100644
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -31,9 +31,7 @@ struct kvec;
31#define JFFS2_F_I_MODE(f) (OFNI_EDONI_2SFFJ(f)->i_mode) 31#define JFFS2_F_I_MODE(f) (OFNI_EDONI_2SFFJ(f)->i_mode)
32#define JFFS2_F_I_UID(f) (OFNI_EDONI_2SFFJ(f)->i_uid) 32#define JFFS2_F_I_UID(f) (OFNI_EDONI_2SFFJ(f)->i_uid)
33#define JFFS2_F_I_GID(f) (OFNI_EDONI_2SFFJ(f)->i_gid) 33#define JFFS2_F_I_GID(f) (OFNI_EDONI_2SFFJ(f)->i_gid)
34 34#define JFFS2_F_I_RDEV(f) (OFNI_EDONI_2SFFJ(f)->i_rdev)
35#define JFFS2_F_I_RDEV_MIN(f) (iminor(OFNI_EDONI_2SFFJ(f)))
36#define JFFS2_F_I_RDEV_MAJ(f) (imajor(OFNI_EDONI_2SFFJ(f)))
37 35
38#define ITIME(sec) ((struct timespec){sec, 0}) 36#define ITIME(sec) ((struct timespec){sec, 0})
39#define I_SEC(tv) ((tv).tv_sec) 37#define I_SEC(tv) ((tv).tv_sec)
diff --git a/include/linux/jffs2.h b/include/linux/jffs2.h
index a26fbd498c79..007d76d290cb 100644
--- a/include/linux/jffs2.h
+++ b/include/linux/jffs2.h
@@ -173,4 +173,10 @@ union jffs2_node_union
173 struct jffs2_unknown_node u; 173 struct jffs2_unknown_node u;
174}; 174};
175 175
176/* Data payload for device nodes. */
177union jffs2_device_node {
178 jint16_t old;
179 jint32_t new;
180};
181
176#endif /* __LINUX_JFFS2_H__ */ 182#endif /* __LINUX_JFFS2_H__ */