udf_bmap.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/sysmacros.h>
#include <sys/resource.h>
#include <sys/pathname.h>
#include <sys/bootconf.h>
#include <vm/seg_kmem.h>
#define ALLOC_SPACE 0x01
#define NEW_EXT 0x02
#define MEXT_BITS 30
{
ud_printf("ud_bmap_has_holes\n");
/* ICB_FLAG_ONE_AD is always continuos */
for (i = 0; i < ip->i_ext_used; i++) {
error = 1;
break;
}
}
}
}
return (error);
}
{
ud_printf("ud_bmap_read\n");
for (i = 0; i < ip->i_ext_used; i++) {
break;
}
break;
}
}
if (i == ip->i_ext_used) {
}
}
return (error);
}
/*
* Extent allocation in the inode
* Initially when the inode is allocated we
* will allocate EXT_PER_MALLOC extents and once these
* are used we allocate another 10 and copy
* the old extents and start using the others
*/
/* ARGSUSED3 */
{
ud_printf("ud_bmap_write\n");
return (EFBIG);
}
alloc_only = 0; /* make sure */
}
goto out;
}
if (error != 0) {
goto out;
}
} else {
}
/*
* Change the desc_type
*/
dtype_changed = 1;
ip->i_ext_used = 0;
ip->i_cur_max_ext --;
} else {
next = 1;
}
ip->i_ext_count =
memory_allocated = 1;
/* There will be atleast EXT_PER_MALLOC icb_ext's allocated */
icb_offset = 0;
/* Can we create a HOLE */
/*
* Allocate one block for
* old data.(cannot be more than one page)
*/
icb_offset, &count)) {
goto embedded_error;
}
}
/*
* Allocate a hole from PCEIL(ip->i_size) to PBASE(off)
*/
/*
* Allocate the rest of the space PBASE(off) to end_req
*/
} else {
/*
* If no hole can be created then allocate
* space till the end of the request
*/
}
/*
* Something error
* most probable file system is full
* we know that the file came in as a embedded file.
* undo what ever we did in this block of code
*/
if (dtype_changed) {
}
for (i = 0; i < ip->i_ext_used; i++) {
l2b);
}
}
if (memory_allocated) {
ip->i_ext_count *
sizeof (struct icb_ext));
}
}
}
return (error);
} else {
/*
* Type 4 directories being created
*/
goto one_ad_no_i_ext;
}
/*
* Read the entire icb's to memory
*/
goto out;
}
/*
* The new file size is greater
* than the old size
*/
goto one_ad_no_i_ext;
} else if (ip->i_ext_used == 0) {
goto one_ad_i_ext;
}
return (error);
} else {
/*
* File growing the new size will be less than
* iext->ib_offset + CEIL(iext->ib_count)
*/
error = 0;
goto out;
}
}
}
}
/* By this point the end of last extent is >= BASE(off) + size */
/*
* Figure out the icb_ext that has offset "off"
*/
for (i = 0; i < ip->i_ext_used; i++) {
break;
}
}
/*
* iext will have offset "off"
*/
do {
/*
* Already allocated do nothing
*/
i++;
} else {
/*
* We are in a hole.
* allocate the required space
* while trying to create smaller holes
*/
PAGESIZE)) {
/*
* Allocate space from begining of
* old hole to the begining of new hole
* We want all holes created by us
* to be MMUPAGE Aligned
*/
if ((error = ud_break_create_new_icb(
return (error);
}
goto alloc_cur_ext;
}
/*
* Create the new hole
*/
return (error);
}
i++;
continue;
}
PAGESIZE)) {
/*
* We can create a hole
* from PCEIL(end_req) - BASE(end_ext)
*/
return (error);
}
}
/*
* Allocate the current extent
*/
/*
* If the previous extent
* is allocated then try to allocate
* adjascent to the previous extent
*/
prox = 0;
if (i != 0) {
}
}
return (error);
}
if (sz == 0) {
return (ENOSPC);
}
if (alloc_only == 0) {
}
/*
* We are able to allocate adjascent to
* the previous extent. Increment the
* previous extent count if the size
* of the extent is not greater than
* max extent size
*/
/*
* and get rid of the current
* extent since we have
* allocated all of its size
* and incremented the
* previous extents count
*/
ud_remove_ext_at_index(ip, i);
} else {
/*
* reduce the count of the
* current extent by the amount
* allocated in the last extent
*/
}
} else {
if ((error = ud_break_create_new_icb(
return (error);
}
}
/*
* iext->ib_flags |= IB_UN_REC;
*/
i++;
continue;
}
}
out:
return (error);
}
/*
* using long or short allocation descriptors
*/
static void
{
struct alloc_ext_desc *aed;
int islong;
void *addr;
islong = 1;
islong = 0;
} else
return;
/*
* realloc i_ext array
*/
/*
* scan descriptors
*/
iext++;
while (ndesc--) {
if (islong)
else
if ((length & 0x3FFFFFFF) == 0)
break;
sizeof (struct icb_ext);
if (old) {
}
}
if (islong) {
} else {
}
ip->i_con_used++;
break;
}
if (islong) {
lad++;
} else {
sad++;
}
ip->i_ext_used++;
iext++;
}
}
static int32_t
{
struct alloc_ext_desc *aed;
1, &dummy);
else {
}
if (error == 0)
return (error);
}
{
ud_printf("ud_read_icb_till_off\n");
return (0);
return (EINVAL);
else if (ip->i_ext_used == 0)
/*
* supported allocation strategies are
* STRAT_TYPE4 and STRAT_TYPE4096
*/
break;
}
break;
ip->i_con_read++;
}
return (error);
}
/*
* Assumption is the off is beyond ip->i_size
* And we will have atleast one ext used
*/
{
/*
* If we are here it means the file
* is growing beyond the end of the
* current block. So round up the
* last extent
*/
/*
* Figure out if we can create
* a hole here
*/
/*
* There is space between the begining
* of the hole to be created and
* end of the last offset
* Allocate blocks for it
*/
/*
* Previous extent is a unallocated
* extent. Create a new allocated
* extent
*/
} else {
/*
* Last extent is allocated
* try to allocate adjascent to the
* last extent
*/
icb_offset, &count);
}
if (error != 0) {
return (error);
}
}
/*
* The last extent is unallocated
* Just bump the extent count
*/
} else {
/*
* Last extent is allocated
* round up the size of the extent to
* lbsize and allocate a new unallocated extent
*/
}
} else {
/*
* We cannot create any hole inbetween
* the last extent and the off so
* round up the count in the last extent
*/
}
/*
* Last extent was a unallocated extent
* create a new extent
*/
} else {
/*
* Last extent was an allocated extent
* try to allocate adjascent to the old blocks
*/
}
return (error);
}
/*
* Break up the icb_ext at index
* into two icb_ext,
* one at index ib_count "count" and
* the other at index+1 with ib_count = old_ib_count - count
*/
{
ud_printf("ud_break_create_new_icb\n");
return (error);
}
}
}
ip->i_ext_used++;
return (0);
}
void
{
int32_t i;
} else {
}
}
ip->i_ext_used --;
}
{
ud_printf("ud_bump_ext_count\n");
}
return (error);
}
/*
* If there are any old cont extents
* allocate the new one ajscant to the old one
*/
if (ip->i_con_used != 0) {
} else {
prox = 0;
}
/*
* Allocate space
*/
return (error);
}
if (sz == 0) {
return (ENOSPC);
}
sizeof (struct icb_ext);
if (old != 0) {
}
}
/*
* Bump the i_cur_max_ext according to
* the space allocated
*/
} else {
return (ENOSPC);
}
}
return (error);
}
{
if (*count == 0) {
return (0);
}
return (error);
}
if (flags & ALLOC_SPACE) {
(ip->i_ext_count == 0)) {
} else {
}
return (error);
}
if (sz == 0) {
return (ENOSPC);
}
*count = 0;
} else {
}
ip->i_ext_used ++;
} else {
} else {
}
if (blkcount == 0) {
index++;
goto begin;
}
return (error);
}
if (sz == 0) {
return (ENOSPC);
}
*count = 0;
} else {
}
} else {
!= 0) {
return (error);
}
/*
* Increment the index, since we have used
* the extent at [index+1] above.
*/
index++;
ip->i_ext_used ++;
}
}
if (alloc_only == 0) {
}
if (*count) {
index++;
goto begin;
}
} else {
} else {
*count = 0;
}
ip->i_ext_used ++;
} else {
} else {
*count = 0;
}
}
if (*count != 0) {
index++;
goto begin;
}
}
return (error);
}
{
/*
* Donot use bio routines
* since the buffer can sit
* long enough in cache for the space
* then allocated
*/
(void) bdev_strategy(bp);
}
return (error);
}