Any particular reason why I shouldn't do this? Other than the fact that you need shared writeable mmap (which JFFS2 doesn't support) in order to use it, that is -- but I'll get to that. diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c index 5a98aa8..a8e4727 100644 --- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c @@ -25,7 +25,8 @@ static int jffs2_write_end(struct file *filp, struct address_space *mapping, static int jffs2_write_begin(struct file *filp, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata); -static int jffs2_readpage (struct file *filp, struct page *pg); +static int jffs2_readpage(struct file *filp, struct page *pg); +static void jffs2_truncate_range(struct inode *inode, loff_t start, loff_t end); int jffs2_fsync(struct file *filp, struct dentry *dentry, int datasync) { @@ -56,6 +57,7 @@ const struct file_operations jffs2_file_operations = const struct inode_operations jffs2_file_inode_operations = { + .truncate_range=jffs2_truncate_range, .permission = jffs2_permission, .setattr = jffs2_setattr, .setxattr = jffs2_setxattr, @@ -319,3 +321,81 @@ static int jffs2_write_end(struct file *filp, struct address_space *mapping, page_cache_release(pg); return writtenlen > 0 ? writtenlen : ret; } + +static void jffs2_truncate_range(struct inode *inode, loff_t start, loff_t end) +{ + struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); + struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); + struct jffs2_raw_inode *ri; + struct jffs2_full_dnode *fn; + uint32_t alloclen; + uint32_t len; + int alloc_type = ALLOC_NORMAL; + int ret; + + if (end >= inode->i_size) + end = inode->i_size - 1; + + len = end - start + 1; + + if (len >= PAGE_SIZE) + alloc_type = ALLOC_DELETION; + + ri = jffs2_alloc_raw_inode(); + if (!ri) { + ret = -ENOMEM; + goto out; + } + + ret = jffs2_reserve_space(c, sizeof(ri), &alloclen, + alloc_type, JFFS2_SUMMARY_INODE_SIZE); + if (ret) + goto out_free; + + mutex_lock(&f->sem); + + ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); + ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); + ri->totlen = cpu_to_je32(sizeof(*ri)); + ri->hdr_crc = cpu_to_je32(crc32(0, ri, + sizeof(struct jffs2_unknown_node) - 4)); + + ri->ino = cpu_to_je32(inode->i_ino); + ri->mode = cpu_to_jemode(inode->i_mode); + ri->uid = cpu_to_je16(inode->i_uid); + 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->version = cpu_to_je32(++f->highest_version); + ri->offset = cpu_to_je32(start); + ri->csize = cpu_to_je32(0); + ri->dsize = cpu_to_je32(len); + ri->compr = JFFS2_COMPR_ZERO; + ri->usercompr = 0; + ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); + ri->data_crc = cpu_to_je32(0); + + fn = jffs2_write_dnode(c, f, ri, NULL, 0, alloc_type); + + if (IS_ERR(fn)) { + ret = PTR_ERR(fn); + goto out_unlock; + } + + ret = jffs2_add_full_dnode_to_inode(c, f, fn); + if (ret) { + printk(KERN_WARNING "jffs2_add_full_dnode.. failed in %s: %d\n", + __func__, ret); + jffs2_mark_node_obsolete(c, fn->raw); + goto out; + } + + out_unlock: + mutex_unlock(&f->sem); + jffs2_complete_reservation(c); + out_free: + jffs2_free_raw_inode(ri); + out: + /* return ret; */ ; +} -- David Woodhouse Open Source Technology Centre David.Woodhouse@xxxxxxxxx Intel Corporation -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html