[RFC] Implement ->truncate_range() for JFFS2

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux