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 {