diff -NurpP --minimal linux-2.6.19.1-vs2.3.0.4/fs/jffs2/dir.c linux-2.6.19.1-vs2.3.0.4.jffs2/fs/jffs2/dir.c --- linux-2.6.19.1-vs2.3.0.4/fs/jffs2/dir.c 2006-11-07 03:19:16 +0100 +++ linux-2.6.19.1-vs2.3.0.4.jffs2/fs/jffs2/dir.c 2006-12-16 10:07:13 +0100 @@ -37,6 +39,8 @@ static int jffs2_mknod (struct inode *,s static int jffs2_rename (struct inode *, struct dentry *, struct inode *, struct dentry *); +extern int jffs2_sync_flags(struct inode *); + const struct file_operations jffs2_dir_operations = { .read = generic_read_dir, @@ -59,6 +63,7 @@ struct inode_operations jffs2_dir_inode_ .rename = jffs2_rename, .permission = jffs2_permission, .setattr = jffs2_setattr, + .sync_flags = jffs2_sync_flags, .setxattr = jffs2_setxattr, .getxattr = jffs2_getxattr, .listxattr = jffs2_listxattr, diff -NurpP --minimal linux-2.6.19.1-vs2.3.0.4/fs/jffs2/file.c linux-2.6.19.1-vs2.3.0.4.jffs2/fs/jffs2/file.c --- linux-2.6.19.1-vs2.3.0.4/fs/jffs2/file.c 2006-11-07 03:19:16 +0100 +++ linux-2.6.19.1-vs2.3.0.4.jffs2/fs/jffs2/file.c 2006-12-16 08:50:18 +0100 @@ -27,6 +29,9 @@ static int jffs2_prepare_write (struct f unsigned start, unsigned end); static int jffs2_readpage (struct file *filp, struct page *pg); +extern int jffs2_sync_flags(struct inode *); + + int jffs2_fsync(struct file *filp, struct dentry *dentry, int datasync) { struct inode *inode = dentry->d_inode; @@ -58,6 +63,7 @@ struct inode_operations jffs2_file_inode { .permission = jffs2_permission, .setattr = jffs2_setattr, + .sync_flags = jffs2_sync_flags, .setxattr = jffs2_setxattr, .getxattr = jffs2_getxattr, .listxattr = jffs2_listxattr, @@ -165,6 +171,7 @@ static int jffs2_prepare_write (struct f ri.dsize = cpu_to_je32(pageofs - inode->i_size); ri.csize = cpu_to_je32(0); ri.compr = JFFS2_COMPR_ZERO; + ri.flags = cpu_to_je16(f->flags); ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8)); ri.data_crc = cpu_to_je32(0); @@ -252,6 +259,7 @@ static int jffs2_commit_write (struct fi ri->gid = cpu_to_je16(inode->i_gid); ri->isize = cpu_to_je32((uint32_t)inode->i_size); ri->atime = ri->ctime = ri->mtime = cpu_to_je32(get_seconds()); + ri->flags = cpu_to_je16(f->flags); /* In 2.4, it was already kmapped by generic_file_write(). Doesn't hurt to do it again. The alternative is ifdefs, which are ugly. */ diff -NurpP --minimal linux-2.6.19.1-vs2.3.0.4/fs/jffs2/fs.c linux-2.6.19.1-vs2.3.0.4.jffs2/fs/jffs2/fs.c --- linux-2.6.19.1-vs2.3.0.4/fs/jffs2/fs.c 2006-11-07 03:19:16 +0100 +++ linux-2.6.19.1-vs2.3.0.4.jffs2/fs/jffs2/fs.c 2006-12-16 09:57:37 +0100 @@ -118,6 +120,9 @@ static int jffs2_do_setattr (struct inod ri->offset = cpu_to_je32(0); ri->csize = ri->dsize = cpu_to_je32(mdatalen); ri->compr = JFFS2_COMPR_NONE; + ri->flags = cpu_to_je16(f->flags); + printk("··· do set attr flags: %04x\n", f->flags); + if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) { /* It's an extension. Make it a hole node */ ri->compr = JFFS2_COMPR_ZERO; @@ -181,6 +187,52 @@ static int jffs2_do_setattr (struct inod return 0; } +void jffs2_set_inode_flags(struct inode *inode) +{ + struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); + unsigned int flags = f->flags; + + inode->i_flags &= ~(JFFS2_INO_FLAG_IMMUTABLE | + JFFS2_INO_FLAG_IUNLINK | JFFS2_INO_FLAG_BARRIER); + + if (flags & JFFS2_INO_FLAG_IMMUTABLE) + inode->i_flags |= S_IMMUTABLE; + if (flags & JFFS2_INO_FLAG_IUNLINK) + inode->i_flags |= S_IUNLINK; + if (flags & JFFS2_INO_FLAG_BARRIER) + inode->i_flags |= S_BARRIER; + + printk("··· set %p[#%lu] flags: %04x\n", inode, inode->i_ino, flags); +} + +int jffs2_sync_flags(struct inode *inode) +{ + struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); + unsigned int oldflags, newflags; + + oldflags = f->flags; + newflags = oldflags & ~(JFFS2_INO_FLAG_IMMUTABLE | + JFFS2_INO_FLAG_IUNLINK | JFFS2_INO_FLAG_BARRIER); + + if (IS_IMMUTABLE(inode)) + newflags |= JFFS2_INO_FLAG_IMMUTABLE; + if (IS_IUNLINK(inode)) + newflags |= JFFS2_INO_FLAG_IUNLINK; + if (IS_BARRIER(inode)) + newflags |= JFFS2_INO_FLAG_BARRIER; + + if (oldflags ^ newflags) { + f->flags = newflags; + inode->i_ctime = CURRENT_TIME; + /* strange requirement, see jffs2_dirty_inode() */ + inode->i_state |= I_DIRTY_DATASYNC; + mark_inode_dirty(inode); + } + printk("··· sync %p[#%lu] flags: %04x ^ %04x\n", + inode, inode->i_ino, oldflags, newflags); + return 0; +} + int jffs2_setattr(struct dentry *dentry, struct iattr *iattr) { int rc; @@ -287,6 +339,7 @@ void jffs2_read_inode (struct inode *ino inode->i_op = &jffs2_dir_inode_operations; inode->i_fop = &jffs2_dir_operations; + f->flags = je16_to_cpu(latest_node.flags); break; } case S_IFREG: @@ -294,6 +347,7 @@ void jffs2_read_inode (struct inode *ino inode->i_fop = &jffs2_file_operations; inode->i_mapping->a_ops = &jffs2_file_address_operations; inode->i_mapping->nrpages = 0; + f->flags = je16_to_cpu(latest_node.flags); break; case S_IFBLK: @@ -330,7 +384,7 @@ void jffs2_read_inode (struct inode *ino default: printk(KERN_WARNING "jffs2_read_inode(): Bogus imode %o for ino %lu\n", inode->i_mode, (unsigned long)inode->i_ino); } - + jffs2_set_inode_flags(inode); up(&f->sem); D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n")); @@ -451,6 +505,8 @@ struct inode *jffs2_new_inode (struct in inode->i_blocks = 0; inode->i_size = 0; + f->flags = je16_to_cpu(ri->flags); + jffs2_set_inode_flags(inode); insert_inode_hash(inode); return inode; diff -NurpP --minimal linux-2.6.19.1-vs2.3.0.4/fs/jffs2/readinode.c linux-2.6.19.1-vs2.3.0.4.jffs2/fs/jffs2/readinode.c --- linux-2.6.19.1-vs2.3.0.4/fs/jffs2/readinode.c 2006-09-20 16:58:35 +0200 +++ linux-2.6.19.1-vs2.3.0.4.jffs2/fs/jffs2/readinode.c 2006-12-16 09:56:01 +0100 @@ -759,6 +759,7 @@ static int jffs2_do_read_inode_internal( latest_node->isize = cpu_to_je32(0); latest_node->gid = cpu_to_je16(0); latest_node->uid = cpu_to_je16(0); + latest_node->flags = cpu_to_je16(0); if (f->inocache->state == INO_STATE_READING) jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT); return 0; diff -NurpP --minimal linux-2.6.19.1-vs2.3.0.4/fs/jffs2/write.c linux-2.6.19.1-vs2.3.0.4.jffs2/fs/jffs2/write.c --- linux-2.6.19.1-vs2.3.0.4/fs/jffs2/write.c 2006-09-20 16:58:35 +0200 +++ linux-2.6.19.1-vs2.3.0.4.jffs2/fs/jffs2/write.c 2006-12-16 09:35:23 +0100 @@ -46,6 +48,7 @@ int jffs2_do_new_inode(struct jffs2_sb_i ri->totlen = cpu_to_je32(PAD(sizeof(*ri))); ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)); ri->mode = cpu_to_jemode(mode); + ri->flags = cpu_to_je16(0); f->highest_version = 1; ri->version = cpu_to_je32(f->highest_version); diff -NurpP --minimal linux-2.6.19.1-vs2.3.0.4/include/linux/jffs2.h linux-2.6.19.1-vs2.3.0.4.jffs2/include/linux/jffs2.h --- linux-2.6.19.1-vs2.3.0.4/include/linux/jffs2.h 2006-11-07 03:19:22 +0100 +++ linux-2.6.19.1-vs2.3.0.4.jffs2/include/linux/jffs2.h 2006-12-16 05:32:45 +0100 @@ -82,12 +82,16 @@ //#define JFFS2_NODETYPE_OPTIONS (JFFS2_FEATURE_RWCOMPAT_COPY | JFFS2_NODE_ACCURATE | 4) -#define JFFS2_INO_FLAG_PREREAD 1 /* Do read_inode() for this one at +#define JFFS2_INO_FLAG_PREREAD 0x01 /* Do read_inode() for this one at mount time, don't wait for it to happen later */ -#define JFFS2_INO_FLAG_USERCOMPR 2 /* User has requested a specific +#define JFFS2_INO_FLAG_USERCOMPR 0x02 /* User has requested a specific compression type */ +#define JFFS2_INO_FLAG_IMMUTABLE 0x10 /* immutable node */ +#define JFFS2_INO_FLAG_IUNLINK 0x20 /* immutable unlink */ +#define JFFS2_INO_FLAG_BARRIER 0x40 /* barrier */ + /* These can go once we've made sure we've caught all uses without byteswapping */