aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/fs.c
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2006-05-18 19:28:49 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2006-05-18 19:28:49 -0400
commitaef9ab47841af45888d950baa6448072cc70bdd5 (patch)
tree79545ddc225f64bc38fa04525ac4125c86202cb8 /fs/jffs2/fs.c
parentf6a673b3f4f93c1c50e1b18f29254b0531b722a8 (diff)
[JFFS2] Support new device nodes
Device node major/minor numbers are just stored in the payload of a single data node. Just extend that to 4 bytes and use new_encode_dev() for it. We only use the 4-byte format if we _need_ to, if !old_valid_dev(foo). This preserves backwards compatibility with older code as much as possible. If we do make devices with major or minor numbers above 255, and then mount the file system with the old code, it'll just read the first two bytes and get the numbers wrong. If it comes to garbage-collect it, it'll then write back those wrong numbers. But that's about the best we can expect. Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'fs/jffs2/fs.c')
-rw-r--r--fs/jffs2/fs.c25
1 files changed, 18 insertions, 7 deletions
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: