int fat_directory_expand(fat_directory_t *di)
{
	int rc;
	fat_cluster_t mcl, lcl;

	if (!FAT_IS_FAT32(di->bs) && di->nodep->firstc == FAT_CLST_ROOT) {
		/* Can't grow the root directory on FAT12/16. */
		return ENOSPC;
	}
	rc = fat_alloc_clusters(di->bs, di->nodep->idx->service_id, 1, &mcl,
	    &lcl);
	if (rc != EOK)
		return rc;
	rc = fat_zero_cluster(di->bs, di->nodep->idx->service_id, mcl);
	if (rc != EOK) {
		(void) fat_free_clusters(di->bs, di->nodep->idx->service_id,
		    mcl);
		return rc;
	}
	rc = fat_append_clusters(di->bs, di->nodep, mcl, lcl);
	if (rc != EOK) {
		(void) fat_free_clusters(di->bs, di->nodep->idx->service_id,
		    mcl);
		return rc;
	}
	di->nodep->size += BPS(di->bs) * SPC(di->bs);
	di->nodep->dirty = true;		/* need to sync node */
	di->blocks = di->nodep->size / BPS(di->bs);
	
	return EOK;
}
static long fat_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
{      
	int err = 0;
	struct inode *inode = file->f_mapping->host;
	int cluster, nr_cluster, fclus, dclus, free_bytes, nr_bytes;
	struct super_block *sb = inode->i_sb;
	struct msdos_sb_info *sbi = MSDOS_SB(sb);
	if (mode & ~FALLOC_FL_KEEP_SIZE)
		return -EOPNOTSUPP;
	if ((offset + len) <= MSDOS_I(inode)->mmu_private) {
		fat_msg(sb, KERN_ERR,
				"fat_fallocate():Blocks already allocated");
		return -EINVAL;
	}
	if ((mode & FALLOC_FL_KEEP_SIZE)) {
		if (inode->i_size > 0) {
			err = fat_get_cluster(inode, FAT_ENT_EOF,
					&fclus, &dclus);
			if (err < 0) {
				fat_msg(sb, KERN_ERR,
						"fat_fallocate():fat_get_cluster() error");
				return err;
			}
			free_bytes = ((fclus+1) << sbi->cluster_bits) -
				(inode->i_size);
			nr_bytes = (offset + len - inode->i_size) - free_bytes;
		} else
			nr_bytes = (offset + len - inode->i_size);
		nr_cluster = (nr_bytes + (sbi->cluster_size - 1)) >>
			sbi->cluster_bits;
		mutex_lock(&inode->i_mutex);
		while (nr_cluster-- > 0) {
			err = fat_alloc_clusters(inode, &cluster, 1);
			if (err) {
				fat_msg(sb, KERN_ERR,
						"fat_fallocate():fat_alloc_clusters() error");
				goto error;
			}
			err = fat_chain_add(inode, cluster, 1);
			if (err) {
				fat_free_clusters(inode, cluster);
				goto error;
			}
		}
		err = fat_get_cluster(inode, FAT_ENT_EOF, &fclus, &dclus);
		if (err < 0) {
			fat_msg(sb, KERN_ERR,
					"fat_fallocate():fat_get_cluster() error");
			goto error;
		}
		MSDOS_I(inode)->mmu_private = (fclus + 1) << sbi->cluster_bits;
	} else {