aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/fs.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jffs2/fs.c')
-rw-r--r--fs/jffs2/fs.c63
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
181int jffs2_setattr(struct dentry *dentry, struct iattr *iattr) 185int 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
186int jffs2_statfs(struct super_block *sb, struct kstatfs *buf) 195int 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);