diff options
Diffstat (limited to 'fs/jffs2/fs.c')
-rw-r--r-- | fs/jffs2/fs.c | 63 |
1 files changed, 38 insertions, 25 deletions
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index 09e5d10b8840..7b6c24b14f85 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c | |||
@@ -33,11 +33,11 @@ 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; |
40 | uint32_t phys_ofs, alloclen; | 40 | uint32_t alloclen; |
41 | int ret; | 41 | int ret; |
42 | D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino)); | 42 | D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino)); |
43 | ret = inode_change_ok(inode, iattr); | 43 | ret = inode_change_ok(inode, iattr); |
@@ -51,20 +51,24 @@ 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)) { |
58 | down(&f->sem); | ||
59 | mdatalen = f->metadata->size; | 59 | mdatalen = f->metadata->size; |
60 | mdata = kmalloc(f->metadata->size, GFP_USER); | 60 | mdata = kmalloc(f->metadata->size, GFP_USER); |
61 | if (!mdata) | 61 | if (!mdata) { |
62 | up(&f->sem); | ||
62 | return -ENOMEM; | 63 | return -ENOMEM; |
64 | } | ||
63 | ret = jffs2_read_dnode(c, f, f->metadata, mdata, 0, mdatalen); | 65 | ret = jffs2_read_dnode(c, f, f->metadata, mdata, 0, mdatalen); |
64 | if (ret) { | 66 | if (ret) { |
67 | up(&f->sem); | ||
65 | kfree(mdata); | 68 | kfree(mdata); |
66 | return ret; | 69 | return ret; |
67 | } | 70 | } |
71 | up(&f->sem); | ||
68 | D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of symlink target\n", mdatalen)); | 72 | D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of symlink target\n", mdatalen)); |
69 | } | 73 | } |
70 | 74 | ||
@@ -75,8 +79,8 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) | |||
75 | return -ENOMEM; | 79 | return -ENOMEM; |
76 | } | 80 | } |
77 | 81 | ||
78 | ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen, | 82 | ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &alloclen, |
79 | ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); | 83 | ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); |
80 | if (ret) { | 84 | if (ret) { |
81 | jffs2_free_raw_inode(ri); | 85 | jffs2_free_raw_inode(ri); |
82 | if (S_ISLNK(inode->i_mode & S_IFMT)) | 86 | if (S_ISLNK(inode->i_mode & S_IFMT)) |
@@ -127,7 +131,7 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) | |||
127 | else | 131 | else |
128 | ri->data_crc = cpu_to_je32(0); | 132 | ri->data_crc = cpu_to_je32(0); |
129 | 133 | ||
130 | new_metadata = jffs2_write_dnode(c, f, ri, mdata, mdatalen, phys_ofs, ALLOC_NORMAL); | 134 | new_metadata = jffs2_write_dnode(c, f, ri, mdata, mdatalen, ALLOC_NORMAL); |
131 | if (S_ISLNK(inode->i_mode)) | 135 | if (S_ISLNK(inode->i_mode)) |
132 | kfree(mdata); | 136 | kfree(mdata); |
133 | 137 | ||
@@ -180,7 +184,12 @@ static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) | |||
180 | 184 | ||
181 | int jffs2_setattr(struct dentry *dentry, struct iattr *iattr) | 185 | int jffs2_setattr(struct dentry *dentry, struct iattr *iattr) |
182 | { | 186 | { |
183 | return jffs2_do_setattr(dentry->d_inode, iattr); | 187 | int rc; |
188 | |||
189 | rc = jffs2_do_setattr(dentry->d_inode, iattr); | ||
190 | if (!rc && (iattr->ia_valid & ATTR_MODE)) | ||
191 | rc = jffs2_acl_chmod(dentry->d_inode); | ||
192 | return rc; | ||
184 | } | 193 | } |
185 | 194 | ||
186 | int jffs2_statfs(struct super_block *sb, struct kstatfs *buf) | 195 | int jffs2_statfs(struct super_block *sb, struct kstatfs *buf) |
@@ -219,6 +228,7 @@ void jffs2_clear_inode (struct inode *inode) | |||
219 | 228 | ||
220 | D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode)); | 229 | D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode)); |
221 | 230 | ||
231 | jffs2_xattr_delete_inode(c, f->inocache); | ||
222 | jffs2_do_clear_inode(c, f); | 232 | jffs2_do_clear_inode(c, f); |
223 | } | 233 | } |
224 | 234 | ||
@@ -227,6 +237,8 @@ void jffs2_read_inode (struct inode *inode) | |||
227 | struct jffs2_inode_info *f; | 237 | struct jffs2_inode_info *f; |
228 | struct jffs2_sb_info *c; | 238 | struct jffs2_sb_info *c; |
229 | struct jffs2_raw_inode latest_node; | 239 | struct jffs2_raw_inode latest_node; |
240 | union jffs2_device_node jdev; | ||
241 | dev_t rdev = 0; | ||
230 | int ret; | 242 | int ret; |
231 | 243 | ||
232 | D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino)); | 244 | D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino)); |
@@ -258,7 +270,6 @@ void jffs2_read_inode (struct inode *inode) | |||
258 | inode->i_blocks = (inode->i_size + 511) >> 9; | 270 | inode->i_blocks = (inode->i_size + 511) >> 9; |
259 | 271 | ||
260 | switch (inode->i_mode & S_IFMT) { | 272 | switch (inode->i_mode & S_IFMT) { |
261 | jint16_t rdev; | ||
262 | 273 | ||
263 | case S_IFLNK: | 274 | case S_IFLNK: |
264 | inode->i_op = &jffs2_symlink_inode_operations; | 275 | inode->i_op = &jffs2_symlink_inode_operations; |
@@ -292,8 +303,16 @@ void jffs2_read_inode (struct inode *inode) | |||
292 | case S_IFBLK: | 303 | case S_IFBLK: |
293 | case S_IFCHR: | 304 | case S_IFCHR: |
294 | /* Read the device numbers from the media */ | 305 | /* Read the device numbers from the media */ |
306 | if (f->metadata->size != sizeof(jdev.old) && | ||
307 | f->metadata->size != sizeof(jdev.new)) { | ||
308 | printk(KERN_NOTICE "Device node has strange size %d\n", f->metadata->size); | ||
309 | up(&f->sem); | ||
310 | jffs2_do_clear_inode(c, f); | ||
311 | make_bad_inode(inode); | ||
312 | return; | ||
313 | } | ||
295 | D1(printk(KERN_DEBUG "Reading device numbers from flash\n")); | 314 | D1(printk(KERN_DEBUG "Reading device numbers from flash\n")); |
296 | if (jffs2_read_dnode(c, f, f->metadata, (char *)&rdev, 0, sizeof(rdev)) < 0) { | 315 | if (jffs2_read_dnode(c, f, f->metadata, (char *)&jdev, 0, f->metadata->size) < 0) { |
297 | /* Eep */ | 316 | /* Eep */ |
298 | printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino); | 317 | printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino); |
299 | up(&f->sem); | 318 | up(&f->sem); |
@@ -301,12 +320,15 @@ void jffs2_read_inode (struct inode *inode) | |||
301 | make_bad_inode(inode); | 320 | make_bad_inode(inode); |
302 | return; | 321 | return; |
303 | } | 322 | } |
323 | if (f->metadata->size == sizeof(jdev.old)) | ||
324 | rdev = old_decode_dev(je16_to_cpu(jdev.old)); | ||
325 | else | ||
326 | rdev = new_decode_dev(je32_to_cpu(jdev.new)); | ||
304 | 327 | ||
305 | case S_IFSOCK: | 328 | case S_IFSOCK: |
306 | case S_IFIFO: | 329 | case S_IFIFO: |
307 | inode->i_op = &jffs2_file_inode_operations; | 330 | inode->i_op = &jffs2_file_inode_operations; |
308 | init_special_inode(inode, inode->i_mode, | 331 | init_special_inode(inode, inode->i_mode, rdev); |
309 | old_decode_dev((je16_to_cpu(rdev)))); | ||
310 | break; | 332 | break; |
311 | 333 | ||
312 | default: | 334 | default: |
@@ -492,6 +514,8 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent) | |||
492 | } | 514 | } |
493 | memset(c->inocache_list, 0, INOCACHE_HASHSIZE * sizeof(struct jffs2_inode_cache *)); | 515 | memset(c->inocache_list, 0, INOCACHE_HASHSIZE * sizeof(struct jffs2_inode_cache *)); |
494 | 516 | ||
517 | jffs2_init_xattr_subsystem(c); | ||
518 | |||
495 | if ((ret = jffs2_do_mount_fs(c))) | 519 | if ((ret = jffs2_do_mount_fs(c))) |
496 | goto out_inohash; | 520 | goto out_inohash; |
497 | 521 | ||
@@ -526,6 +550,7 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent) | |||
526 | else | 550 | else |
527 | kfree(c->blocks); | 551 | kfree(c->blocks); |
528 | out_inohash: | 552 | out_inohash: |
553 | jffs2_clear_xattr_subsystem(c); | ||
529 | kfree(c->inocache_list); | 554 | kfree(c->inocache_list); |
530 | out_wbuf: | 555 | out_wbuf: |
531 | jffs2_flash_cleanup(c); | 556 | jffs2_flash_cleanup(c); |
@@ -639,13 +664,6 @@ static int jffs2_flash_setup(struct jffs2_sb_info *c) { | |||
639 | return ret; | 664 | return ret; |
640 | } | 665 | } |
641 | 666 | ||
642 | /* add setups for other bizarre flashes here... */ | ||
643 | if (jffs2_nor_ecc(c)) { | ||
644 | ret = jffs2_nor_ecc_flash_setup(c); | ||
645 | if (ret) | ||
646 | return ret; | ||
647 | } | ||
648 | |||
649 | /* and Dataflash */ | 667 | /* and Dataflash */ |
650 | if (jffs2_dataflash(c)) { | 668 | if (jffs2_dataflash(c)) { |
651 | ret = jffs2_dataflash_setup(c); | 669 | ret = jffs2_dataflash_setup(c); |
@@ -669,11 +687,6 @@ void jffs2_flash_cleanup(struct jffs2_sb_info *c) { | |||
669 | jffs2_nand_flash_cleanup(c); | 687 | jffs2_nand_flash_cleanup(c); |
670 | } | 688 | } |
671 | 689 | ||
672 | /* add cleanups for other bizarre flashes here... */ | ||
673 | if (jffs2_nor_ecc(c)) { | ||
674 | jffs2_nor_ecc_flash_cleanup(c); | ||
675 | } | ||
676 | |||
677 | /* and DataFlash */ | 690 | /* and DataFlash */ |
678 | if (jffs2_dataflash(c)) { | 691 | if (jffs2_dataflash(c)) { |
679 | jffs2_dataflash_cleanup(c); | 692 | jffs2_dataflash_cleanup(c); |