void jffs_swap_inode(struct jffs_raw_inode *i) { i->magic = LONG_SWAP(i->magic); i->ino = LONG_SWAP(i->ino); i->pino = LONG_SWAP(i->pino); i->version = LONG_SWAP(i->version); i->mode = LONG_SWAP(i->mode); i->uid = WORD_SWAP(i->uid); i->gid = WORD_SWAP(i->gid); i->atime = LONG_SWAP(i->atime); i->mtime = LONG_SWAP(i->mtime); i->ctime = LONG_SWAP(i->ctime); i->offset = LONG_SWAP(i->offset); i->dsize = LONG_SWAP(i->dsize); i->rsize = LONG_SWAP(i->rsize); i->nsize = BYTE_SWAP(i->nsize); i->nlink = BYTE_SWAP(i->nlink); #if 0 /* damn bit fields, lucky its a byte */ i->spare = BYTE_SWAP(i->spare : 6); i->rename = BYTE_SWAP(i->rename : 1); i->deleted = BYTE_SWAP(i->deleted : 1); #endif i->accurate = BYTE_SWAP(i->accurate); i->dchksum = LONG_SWAP(i->dchksum); i->nchksum = WORD_SWAP(i->nchksum); i->chksum = WORD_SWAP(i->chksum); }
static int read_inode_bitmap (struct super_block * sb, unsigned long block_group, unsigned int bitmap_nr) { struct ext2_group_desc * gdp; struct buffer_head * bh; int retval = 0; int bs = BYTE_SWAP(sb->u.ext2_sb.s_byte_swapped); gdp = get_group_desc (sb, block_group, NULL); bh = bread (sb->s_dev, e_swab (bs, gdp->bg_inode_bitmap), sb->s_blocksize); if (!bh) { ext2_error (sb, "read_inode_bitmap", "Cannot read inode bitmap - " "block_group = %lu, inode_bitmap = %lu", block_group, (unsigned long) e_swab (bs, gdp->bg_inode_bitmap)); retval = -EIO; } /* * On IO error, just leave a zero in the superblock's block pointer for * this group. The IO will be retried next time. */ sb->u.ext2_sb.s_inode_bitmap_number[bitmap_nr] = block_group; sb->u.ext2_sb.s_inode_bitmap[bitmap_nr] = bh; return retval; }
static void do_byteswap(unsigned char *buf, int len) { unsigned short wVal, *ptr; int i=0; while (len > 0) { len -= 2; ptr = (unsigned short *)&buf[2*i]; wVal = *ptr; *ptr = BYTE_SWAP( wVal ); i++; } }
unsigned long ext2_count_free_inodes (struct super_block * sb) { #ifdef EXT2FS_DEBUG struct ext2_super_block * es; unsigned long desc_count, bitmap_count, x; int bitmap_nr; struct ext2_group_desc * gdp; int i, bs; lock_super (sb); es = sb->u.ext2_sb.s_es; bs = BYTE_SWAP(sb->u.ext2_sb.s_byte_swapped); desc_count = 0; bitmap_count = 0; gdp = NULL; for (i = 0; i < sb->u.ext2_sb.s_groups_count; i++) { gdp = get_group_desc (sb, i, NULL); desc_count += e_swab (bs, gdp->bg_free_inodes_count); bitmap_nr = load_inode_bitmap (sb, i); if (bitmap_nr < 0) continue; x = ext2_count_free (sb->u.ext2_sb.s_inode_bitmap[bitmap_nr], EXT2_INODES_PER_GROUP(sb) / 8); printk ("group %d: stored = %d, counted = %lu\n", i, e_swab (bs, gdp->bg_free_inodes_count), x); bitmap_count += x; } printk("ext2_count_free_inodes: stored = %lu, computed = %lu, %lu\n", e_swab (bs, es->s_free_inodes_count), desc_count, bitmap_count); unlock_super (sb); return desc_count; #else return e_swab (BYTE_SWAP(sb->u.ext2_sb.s_byte_swapped), sb->u.ext2_sb.s_es->s_free_inodes_count); #endif }
static int nmi_wlan_parse_info_frame(uint8_t *info, int size) { nmi_mac_cfg_t *pd = (nmi_mac_cfg_t *)&g_mac; uint32_t wid, len; int type = NMI_CFG_RSP_STATUS; wid = info[0] | (info[1] << 8); #if 0 #ifdef BIG_ENDIAN wid = BYTE_SWAP(wid); #endif #endif len = info[2]; PRINT_INFO(GENERIC_DBG,"Status Len = %d Id= %d\n",len,wid); if ((len == 1) && (wid == WID_STATUS)) { pd->mac_status = info[3]; type = NMI_CFG_RSP_STATUS; } return type; }
void ext2_check_inodes_bitmap (struct super_block * sb) { struct ext2_super_block * es; unsigned long desc_count, bitmap_count, x; int bitmap_nr; struct ext2_group_desc * gdp; int i, bs; lock_super (sb); bs = BYTE_SWAP(sb->u.ext2_sb.s_byte_swapped); es = sb->u.ext2_sb.s_es; desc_count = 0; bitmap_count = 0; gdp = NULL; for (i = 0; i < sb->u.ext2_sb.s_groups_count; i++) { gdp = get_group_desc (sb, i, NULL); desc_count += e_swab (bs, gdp->bg_free_inodes_count); bitmap_nr = load_inode_bitmap (sb, i); if (bitmap_nr < 0) continue; x = ext2_count_free (sb->u.ext2_sb.s_inode_bitmap[bitmap_nr], EXT2_INODES_PER_GROUP(sb) / 8); if (e_swab (bs, gdp->bg_free_inodes_count) != x) ext2_error (sb, "ext2_check_inodes_bitmap", "Wrong free inodes count in group %d, " "stored = %d, counted = %lu", i, e_swab (bs, gdp->bg_free_inodes_count), x); bitmap_count += x; } if (e_swab (bs, es->s_free_inodes_count) != bitmap_count) ext2_error (sb, "ext2_check_inodes_bitmap", "Wrong free inodes count in super block, " "stored = %lu, counted = %lu", (unsigned long) e_swab (bs, es->s_free_inodes_count), bitmap_count); unlock_super (sb); }
int main(int argc , char *argv[]) { // bitmap file and header information bitmap* bmp = new_bitmap(); // RGB pixel data bitmap_pixel pixel; // current column out of all possible columns in output uint32_t current_output_column = 0; // current row out of all possible rows in output uint32_t current_output_row = 0; // current read position of the source line; should // only vary from 0 to number of columns in row. uint32_t source_row_x = 0; // starting output position of the bitmap pixel data uint32_t file_offset = bmp->bitmap_file_header.fileoffset_to_pixelarray; // value read from input source int16_t read_value; #ifdef DEBUG int16_t min_read = 0; int16_t max_read = 0; print_bitmap_info(bmp); printf("OUTPUT_ROW_BYTES: %u\n", OUTPUT_ROW_BYTES); printf("OUTPUT_ROW_BYTES_WITHOUT_PADDING: %u\n", OUTPUT_ROW_BYTES_WITHOUT_PADDING); printf("OUTPUT_RAW_SINGLE_UNITS: %u\n", OUTPUT_RAW_SINGLE_UNITS); #endif FILE* output_file = fopen(OUTPUT_FILE_PATH,"wb+"); FILE* input_file = fopen(INPUT_FILE_PATH, "r"); // Done with the bitmap information, write that to output. All remaining // pixel data comes afterwards which doesn't depend on any of the header // information. fwrite(bmp, 1, sizeof(bitmap), output_file); free(bmp); // for each output that needs to be written ... int i=0; while(i < OUTPUT_RAW_SINGLE_UNITS) { // If this is the end of the row, write the bitmap padding, // advance the row, and reset the column position. Additionally, // since no data was read from the source, don't increment counter. if (current_output_column + PIXEL_BYTES > OUTPUT_ROW_BYTES_WITHOUT_PADDING) { write_bitmap_row_padding(output_file); current_output_column = 0; current_output_row += INVERSE_SCALE; source_row_x = 0; continue; } // seek to next altimetry reading fseek(input_file, (current_output_row * NLON) + source_row_x, 0); // read value fread(&read_value, 1, 2, input_file); // fix endieness read_value = BYTE_SWAP(read_value); // convert to RGB value z_to_pixel(read_value, &pixel); // write to output bitmap_write_pixel(output_file, pixel); // increment counters source_row_x += INVERSE_SCALE; current_output_column += PIXEL_BYTES; i++; #ifdef DEBUG if (read_value < min_read) { min_read = read_value; } if (read_value > max_read) { max_read = read_value; } #endif } // write last padding pixels (if necessary) if (current_output_column > OUTPUT_ROW_BYTES_WITHOUT_PADDING) { write_bitmap_row_padding(output_file); } fclose(output_file); fclose(input_file); #ifdef DEBUG printf("min value read: %d\n", min_read); printf("max value read: %d\n", max_read); #endif return 0; }
byte *gltLoadTGA(const char *file, int *iWidth, int *iHeight, int *iComponents, int *eFormat) { FILE *pFile; // File pointer TGAHEADER tgaHeader; // TGA file header unsigned long lImageSize; // Size in bytes of image short sDepth; // Pixel depth; byte *pBits; // Pointer to bits // Default/Failed values *iWidth = 0; *iHeight = 0; #ifndef DIRECTX *eFormat = GL_BGR_EXT; *iComponents = GL_RGB8; #endif // Attempt to open the file pFile = fopen(file, "rb"); if(pFile == NULL) return NULL; // Read in header (binary) fread(&tgaHeader, 18/* sizeof(TGAHEADER)*/, 1, pFile); // Do byte swap for big vs little endian #ifdef __APPLE__ BYTE_SWAP(tgaHeader.colorMapStart); BYTE_SWAP(tgaHeader.colorMapLength); BYTE_SWAP(tgaHeader.xstart); BYTE_SWAP(tgaHeader.ystart); BYTE_SWAP(tgaHeader.width); BYTE_SWAP(tgaHeader.height); #endif // Get width, height, and depth of texture *iWidth = tgaHeader.width; *iHeight = tgaHeader.height; sDepth = tgaHeader.bits / 8; if(tgaHeader.bits != 8 && tgaHeader.bits != 24 && tgaHeader.bits != 32) return NULL; lImageSize = tgaHeader.width * tgaHeader.height * sDepth; pBits = new byte [lImageSize * sizeof(byte)]; if(pBits == NULL) return NULL; if(fread(pBits, lImageSize, 1, pFile) != 1) { delete [] pBits; return NULL; } fclose(pFile); // Set OpenGL format expected #ifndef DIRECTX switch(sDepth) { case 3: // Most likely case *eFormat = GL_BGR_EXT; *iComponents = GL_RGB8; break; case 4: *eFormat = GL_BGRA_EXT; *iComponents = GL_RGBA8; break; case 1: *eFormat = GL_LUMINANCE; *iComponents = GL_LUMINANCE8; break; }; #else switch(sDepth) { case 3: *eFormat = 3; *iComponents = 3; break; case 4: *eFormat = 4; *iComponents = 4; break; case 1: *eFormat = 1; *iComponents = 1; break; }; //directx does not support 24 bit bitmaps conver to 32bit if (*eFormat == 3) { byte *pNewBits; *eFormat = 4; *iComponents = 4; pNewBits = tga_24to32(tgaHeader.width, tgaHeader.height, pBits); delete [] pBits; return pNewBits; } #endif return pBits; }
// Loads the texture from the specified file and stores it in iTexture. Note // that we're using the GLAUX library here, which is generally discouraged, // but in this case spares us having to write a bitmap loading routine. void LoadTexture(char *filename, GLuint &texture) { #pragma pack(1) struct TGAHEADER { GLbyte identsize; // Size of ID field that follows header (0) GLbyte colorMapType; // 0 = None, 1 = paletted GLbyte imageType; // 0 = none, 1 = indexed, 2 = rgb, 3 = grey, +8=rle unsigned short colorMapStart; // First colour map entry unsigned short colorMapLength; // Number of colors unsigned char colorMapBits; // bits per palette entry unsigned short xstart; // image x origin unsigned short ystart; // image y origin unsigned short width; // width in pixels unsigned short height; // height in pixels GLbyte bits; // bits per pixel (8 16, 24, 32) GLbyte descriptor; // image descriptor }; #pragma pack(8) #define BYTE_SWAP(x) x = ((x) >> 8) + ((x) << 8) FILE *pFile; // File pointer TGAHEADER tgaHeader; // TGA file header unsigned lImageSize; // Size in bytes of image short sDepth; // Pixel depth; GLbyte *pBits = NULL; // Pointer to bits char fullPathName[256]; GLint iWidth; GLint iHeight; GLint iComponents; GLenum eFormat; // Default/Failed values eFormat = GL_RGBA; iComponents = GL_RGB8; texture = 0; #ifdef _MSC_VER sprintf (fullPathName, "%s", filename); #else sprintf (fullPathName, "../../../%s", filename); #endif // Attempt to open the fil pFile = fopen(fullPathName, "rb"); if(pFile == NULL) { return; } _ASSERTE (sizeof (TGAHEADER) == 18); // Read in header (binary) // sizeof(TGAHEADER) = 18 fread(&tgaHeader, 18, 1, pFile); // Do byte swap for big vs little endian #ifndef _M_IX86 BYTE_SWAP(tgaHeader.colorMapStart); BYTE_SWAP(tgaHeader.colorMapLength); BYTE_SWAP(tgaHeader.xstart); BYTE_SWAP(tgaHeader.ystart); BYTE_SWAP(tgaHeader.width); BYTE_SWAP(tgaHeader.height); #endif // Get width, height, and depth of texture iWidth = tgaHeader.width; iHeight = tgaHeader.height; sDepth = tgaHeader.bits / 8; // Put some validity checks here. Very simply, I only understand // or care about 8, 24, or 32 bit targa's. if(tgaHeader.bits != 8 && tgaHeader.bits != 24 && tgaHeader.bits != 32) { fclose(pFile); return; } // Calculate size of image buffer lImageSize = tgaHeader.width * tgaHeader.height * sDepth; // Allocate memory and check for success pBits = (GLbyte *)malloc(lImageSize * sizeof(GLbyte)); if(pBits == NULL) { fclose(pFile); return; } // Read in the bits // Check for read error. This should catch RLE or other // weird formats that I don't want to recognize if(fread(pBits, lImageSize, 1, pFile) != 1) { fclose(pFile); free(pBits); return; } // Set OpenGL format expected #ifdef _M_IX86 switch(sDepth) { case 3: // Most likely case eFormat = GL_RGB; iComponents = GL_RGB8; break; case 4: eFormat = GL_BGRA_EXT; iComponents = GL_RGBA8; break; case 1: eFormat = GL_LUMINANCE; iComponents = GL_LUMINANCE8; break; }; #else switch(sDepth) { case 3: // Most likely case eFormat = GL_RGBA; iComponents = GL_RGB8; break; case 4: eFormat = GL_BGRA; iComponents = GL_RGBA8; break; case 1: eFormat = GL_LUMINANCE; iComponents = GL_LUMINANCE8; break; }; #endif glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBits); // Done with File fclose(pFile); free(pBits); }
static void nmi_wlan_parse_response_frame(uint8_t *info, int size) { uint32_t wid, len=0, i; static int seq = 0; while (size>0) { i = 0; wid = info[0] | (info[1] << 8); #ifdef BIG_ENDIAN wid = BYTE_SWAP(wid); #endif PRINT_INFO(GENERIC_DBG,"Processing response for %d seq %d\n",wid,seq++); switch ((wid >> 12) & 0x7) { case WID_CHAR: do { if (g_cfg_byte[i].id == WID_NIL) break; if (g_cfg_byte[i].id == wid) { g_cfg_byte[i].val = info[3]; break; } i++; } while (1); len = 2; break; case WID_SHORT: do { if (g_cfg_hword[i].id == WID_NIL) break; if (g_cfg_hword[i].id == wid) { #ifdef BIG_ENDIAN g_cfg_hword[i].val = (info[3]<<8)|(info[4]); #else g_cfg_hword[i].val = info[3]|(info[4]<<8); #endif break; } i++; } while (1); len = 3; break; case WID_INT: do { if (g_cfg_word[i].id == WID_NIL) break; if (g_cfg_word[i].id == wid) { #ifdef BIG_ENDIAN g_cfg_word[i].val = (info[3]<<24)|(info[4]<<16)|(info[5]<<8)|(info[6]); #else g_cfg_word[i].val = info[3]|(info[4]<<8)|(info[5]<<16)|(info[6]<<24); #endif break; } i++; } while (1); len = 5; break; case WID_STR: do { if (g_cfg_str[i].id == WID_NIL) break; if (g_cfg_str[i].id == wid) { if(wid == WID_SITE_SURVEY_RESULTS) { static int toggle = 0; PRINT_INFO(GENERIC_DBG,"Site survey results received[%d]\n", size); PRINT_INFO(GENERIC_DBG,"Site survey results value[%d]toggle[%d]\n",size,toggle); i += toggle; toggle ^= 1; } memcpy(g_cfg_str[i].str, &info[2], (info[2]+1)); break; } i++; } while (1); len = 1+info[2]; break; default: break; } size -= (2 + len); info += (2 + len); } return; }
//////////////////////////////////////////////////////////////////// // Allocate memory and load targa bits. Returns pointer to new buffer, // height, and width of texture, and the OpenGL format of data. // Call free() on buffer when finished! // This only works on pretty vanilla targas... 8, 24, or 32 bit color // only, no palettes, no RLE encoding. GLbyte *gltLoadTGA(const char *szFileName, GLint *iWidth, GLint *iHeight, GLint *iComponents, GLenum *eFormat) { FILE *pFile; // File pointer TGAHEADER tgaHeader; // TGA file header unsigned long lImageSize; // Size in bytes of image short sDepth; // Pixel depth; GLbyte *pBits = NULL; // Pointer to bits // Default/Failed values *iWidth = 0; *iHeight = 0; *eFormat = GL_BGR_EXT; *iComponents = GL_RGB8; // Attempt to open the fil pFile = fopen(szFileName, "rb"); if (pFile == NULL) return NULL; // Read in header (binary) fread(&tgaHeader, 18/* sizeof(TGAHEADER)*/, 1, pFile); // Do byte swap for big vs little endian #ifdef __APPLE__ BYTE_SWAP(tgaHeader.colorMapStart); BYTE_SWAP(tgaHeader.colorMapLength); BYTE_SWAP(tgaHeader.xstart); BYTE_SWAP(tgaHeader.ystart); BYTE_SWAP(tgaHeader.width); BYTE_SWAP(tgaHeader.height); #endif // Get width, height, and depth of texture *iWidth = tgaHeader.width; *iHeight = tgaHeader.height; sDepth = tgaHeader.bits / 8; // Put some validity checks here. Very simply, I only understand // or care about 8, 24, or 32 bit targa's. if (tgaHeader.bits != 8 && tgaHeader.bits != 24 && tgaHeader.bits != 32) return NULL; // Calculate size of image buffer lImageSize = tgaHeader.width * tgaHeader.height * sDepth; // Allocate memory and check for success pBits = malloc(lImageSize * sizeof(GLbyte)); if (pBits == NULL) return NULL; // Read in the bits // Check for read error. This should catch RLE or other // weird formats that I don't want to recognize if (fread(pBits, lImageSize, 1, pFile) != 1) { free(pBits); return NULL; } // Set OpenGL format expected switch (sDepth) { case 3: // Most likely case *eFormat = GL_BGR_EXT; *iComponents = GL_RGB8; break; case 4: *eFormat = GL_BGRA_EXT; *iComponents = GL_RGBA8; break; case 1: *eFormat = GL_LUMINANCE; *iComponents = GL_LUMINANCE8; break; }; // Done with File fclose(pFile); // Return pointer to image data return pBits; }
//////////////////////////////////////////////////////////////////// // Capture the current viewport and save it as a targa file. // Be sure and call SwapBuffers for double buffered contexts or // glFinish for single buffered contexts before calling this function. // Returns 0 if an error occurs, or 1 on success. GLint gltWriteTGA(const char *szFileName) { FILE *pFile; // File pointer TGAHEADER tgaHeader; // TGA file header unsigned long lImageSize; // Size in bytes of image GLbyte *pBits = NULL; // Pointer to bits GLint iViewport[4]; // Viewport in pixels GLint lastBuffer; // Storage for the current read buffer setting // Get the viewport dimensions glGetIntegerv(GL_VIEWPORT, iViewport); // How big is the image going to be (targas are tightly packed) lImageSize = iViewport[2] * 3 * iViewport[3]; // Allocate block. If this doesn't work, go home pBits = (GLbyte *)malloc(lImageSize); if(pBits == NULL) return 0; // Read bits from color buffer glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ROW_LENGTH, 0); glPixelStorei(GL_PACK_SKIP_ROWS, 0); glPixelStorei(GL_PACK_SKIP_PIXELS, 0); // Get the current read buffer setting and save it. Switch to // the front buffer and do the read operation. Finally, restore // the read buffer state glGetIntegerv(GL_READ_BUFFER, &lastBuffer); glReadBuffer(GL_FRONT); glReadPixels(0, 0, iViewport[2], iViewport[3], GL_BGR_EXT, GL_UNSIGNED_BYTE, pBits); glReadBuffer(lastBuffer); // Initialize the Targa header tgaHeader.identsize = 0; tgaHeader.colorMapType = 0; tgaHeader.imageType = 2; tgaHeader.colorMapStart = 0; tgaHeader.colorMapLength = 0; tgaHeader.colorMapBits = 0; tgaHeader.xstart = 0; tgaHeader.ystart = 0; tgaHeader.width = iViewport[2]; tgaHeader.height = iViewport[3]; tgaHeader.bits = 24; tgaHeader.descriptor = 0; // Do byte swap for big vs little endian #ifdef __APPLE__ BYTE_SWAP(tgaHeader.colorMapStart); BYTE_SWAP(tgaHeader.colorMapLength); BYTE_SWAP(tgaHeader.xstart); BYTE_SWAP(tgaHeader.ystart); BYTE_SWAP(tgaHeader.width); BYTE_SWAP(tgaHeader.height); #endif // Attempt to open the file pFile = fopen(szFileName, "wb"); if(pFile == NULL) { free(pBits); // Free buffer and return error return 0; } // Write the header fwrite(&tgaHeader, sizeof(TGAHEADER), 1, pFile); // Write the image data fwrite(pBits, lImageSize, 1, pFile); // Free temporary buffer and close the file free(pBits); fclose(pFile); // Success! return 1; }
/* * There are two policies for allocating an inode. If the new inode is * a directory, then a forward search is made for a block group with both * free space and a low directory-to-inode ratio; if that fails, then of * the groups with above-average free space, that group with the fewest * directories already is chosen. * * For other inodes, search forward from the parent directory\'s block * group to find a free inode. */ struct inode * ext2_new_inode (const struct inode * dir, int mode, int * err) { struct super_block * sb; struct buffer_head * bh; struct buffer_head * bh2; int i, j, avefreei; struct inode * inode; int bitmap_nr; int bs; struct ext2_group_desc * gdp; struct ext2_group_desc * tmp; struct ext2_super_block * es; if (!dir || !(inode = get_empty_inode ())) { *err=-ENOMEM; return NULL; } sb = dir->i_sb; inode->i_sb = sb; inode->i_flags = sb->s_flags; lock_super (sb); bs = BYTE_SWAP(sb->u.ext2_sb.s_byte_swapped); es = sb->u.ext2_sb.s_es; repeat: gdp = NULL; i=0; *err = -ENOSPC; if (S_ISDIR(mode)) { avefreei = e_swab (bs, es->s_free_inodes_count) / sb->u.ext2_sb.s_groups_count; /* I am not yet convinced that this next bit is necessary. i = dir->u.ext2_i.i_block_group; for (j = 0; j < sb->u.ext2_sb.s_groups_count; j++) { tmp = get_group_desc (sb, i, &bh2); if ((e_swab (bs, tmp->bg_used_dirs_count) << 8) < e_swab (bs, tmp->bg_free_inodes_count)) { gdp = tmp; break; } else i = ++i % sb->u.ext2_sb.s_groups_count; } */ if (!gdp) { for (j = 0; j < sb->u.ext2_sb.s_groups_count; j++) { tmp = get_group_desc (sb, j, &bh2); if (e_swab (bs, tmp->bg_free_inodes_count) && e_swab (bs, tmp->bg_free_inodes_count) >= avefreei) { if (!gdp || (e_swab (bs, tmp->bg_free_blocks_count) > e_swab (bs, gdp->bg_free_blocks_count))) { i = j; gdp = tmp; } } } } } else { /* * Try to place the inode in its parent directory */ i = dir->u.ext2_i.i_block_group; tmp = get_group_desc (sb, i, &bh2); if (tmp->bg_free_inodes_count) gdp = tmp; else { /* * Use a quadratic hash to find a group with a * free inode */ for (j = 1; j < sb->u.ext2_sb.s_groups_count; j <<= 1) { i += j; if (i >= sb->u.ext2_sb.s_groups_count) i -= sb->u.ext2_sb.s_groups_count; tmp = get_group_desc (sb, i, &bh2); if (tmp->bg_free_inodes_count) { gdp = tmp; break; } } } if (!gdp) { /* * That failed: try linear search for a free inode */ i = dir->u.ext2_i.i_block_group + 1; for (j = 2; j < sb->u.ext2_sb.s_groups_count; j++) { if (++i >= sb->u.ext2_sb.s_groups_count) i = 0; tmp = get_group_desc (sb, i, &bh2); if (tmp->bg_free_inodes_count) { gdp = tmp; break; } } } } if (!gdp) { unlock_super (sb); iput(inode); return NULL; } bitmap_nr = load_inode_bitmap (sb, i); if (bitmap_nr < 0) { unlock_super (sb); iput(inode); *err = -EIO; return NULL; } bh = sb->u.ext2_sb.s_inode_bitmap[bitmap_nr]; if ((j = ext2_find_first_zero_bit ((unsigned long *) bh->b_data, EXT2_INODES_PER_GROUP(sb))) < EXT2_INODES_PER_GROUP(sb)) { if (ext2_set_bit (j, bh->b_data)) { ext2_warning (sb, "ext2_new_inode", "bit already set for inode %d", j); goto repeat; } mark_buffer_dirty(bh, 1); if (sb->s_flags & MS_SYNCHRONOUS) { ll_rw_block (WRITE, 1, &bh); wait_on_buffer (bh); } } else { if (gdp->bg_free_inodes_count != 0) { ext2_error (sb, "ext2_new_inode", "Free inodes count corrupted in group %d", i); unlock_super (sb); iput (inode); return NULL; } goto repeat; } j += i * EXT2_INODES_PER_GROUP(sb) + 1; if (j < EXT2_FIRST_INO(sb) || j > e_swab (bs, es->s_inodes_count)) { ext2_error (sb, "ext2_new_inode", "reserved inode or inode > inodes count - " "block_group = %d,inode=%d", i, j); unlock_super (sb); iput (inode); return NULL; } e_set_swab (bs, gdp->bg_free_inodes_count, e_swab (bs, gdp->bg_free_inodes_count) - 1); if (S_ISDIR(mode)) e_set_swab (bs, gdp->bg_used_dirs_count, e_swab (bs, gdp->bg_used_dirs_count) + 1); mark_buffer_dirty(bh2, 1); e_set_swab (bs, es->s_free_inodes_count, e_swab (bs, es->s_free_inodes_count) - 1); mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1); sb->s_dirt = 1; inode->i_mode = mode; inode->i_sb = sb; inode->i_count = 1; inode->i_nlink = 1; inode->i_dev = sb->s_dev; inode->i_uid = current->fsuid; if (test_opt (sb, GRPID)) inode->i_gid = dir->i_gid; else if (dir->i_mode & S_ISGID) { inode->i_gid = dir->i_gid; if (S_ISDIR(mode)) mode |= S_ISGID; } else inode->i_gid = current->fsgid; inode->i_dirt = 1; inode->i_ino = j; inode->i_blksize = PAGE_SIZE; /* This is the optimal IO size (for stat), not the fs block size */ inode->i_blocks = 0; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->u.ext2_i.i_new_inode = 1; inode->u.ext2_i.i_flags = dir->u.ext2_i.i_flags; if (S_ISLNK(mode)) inode->u.ext2_i.i_flags &= ~(EXT2_IMMUTABLE_FL | EXT2_APPEND_FL); inode->u.ext2_i.i_faddr = 0; inode->u.ext2_i.i_frag_no = 0; inode->u.ext2_i.i_frag_size = 0; inode->u.ext2_i.i_file_acl = 0; inode->u.ext2_i.i_dir_acl = 0; inode->u.ext2_i.i_dtime = 0; inode->u.ext2_i.i_block_group = i; inode->i_op = NULL; if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL) inode->i_flags |= MS_SYNCHRONOUS; insert_inode_hash(inode); inc_inode_version (inode, gdp, mode); unlock_super (sb); if (sb->dq_op) { sb->dq_op->initialize (inode, -1); if (sb->dq_op->alloc_inode (inode, 1)) { sb->dq_op->drop (inode); inode->i_nlink = 0; iput (inode); *err = -EDQUOT; return NULL; } inode->i_flags |= S_WRITE; } ext2_debug ("allocating inode %lu\n", inode->i_ino); *err = 0; return inode; }
void ext2_free_inode (struct inode * inode) { struct super_block * sb; struct buffer_head * bh; struct buffer_head * bh2; unsigned long block_group; unsigned long bit; int bitmap_nr; int bs; struct ext2_group_desc * gdp; struct ext2_super_block * es; if (!inode) return; if (!inode->i_dev) { printk ("ext2_free_inode: inode has no device\n"); return; } if (inode->i_count > 1) { printk ("ext2_free_inode: inode has count=%ld\n", inode->i_count); return; } if (inode->i_nlink) { printk ("ext2_free_inode: inode has nlink=%d\n", inode->i_nlink); return; } sb = inode->i_sb; if (!sb) { printk("ext2_free_inode: inode on nonexistent device\n"); return; } ext2_debug ("freeing inode %lu\n", inode->i_ino); /* We need to kill quota references now, before grabbing the * superblock lock because writing the quota out to disk * may need to lock the superblock as well. * * It is safe to do this early instead of the original * places because we cannot be here in ext2_free_inode * if any other references to this inode exist at all. * * Based upon a 2.1.x fix by Bill Hawes. --DaveM */ if (sb->dq_op) { sb->dq_op->free_inode (inode, 1); if (IS_WRITABLE (inode)) sb->dq_op->drop(inode); } lock_super (sb); bs = BYTE_SWAP(inode->i_sb->u.ext2_sb.s_byte_swapped); if (inode->i_ino < EXT2_FIRST_INO(sb) || inode->i_ino > e_swab (bs, sb->u.ext2_sb.s_es->s_inodes_count)) { ext2_error (sb, "free_inode", "reserved inode or nonexistent inode"); unlock_super (sb); return; } es = sb->u.ext2_sb.s_es; block_group = (inode->i_ino - 1) / EXT2_INODES_PER_GROUP(sb); bit = (inode->i_ino - 1) % EXT2_INODES_PER_GROUP(sb); bitmap_nr = load_inode_bitmap (sb, block_group); if (bitmap_nr < 0) { unlock_super (sb); return; } bh = sb->u.ext2_sb.s_inode_bitmap[bitmap_nr]; if (!ext2_clear_bit (bit, bh->b_data)) ext2_warning (sb, "ext2_free_inode", "bit already cleared for inode %lu", inode->i_ino); else { gdp = get_group_desc (sb, block_group, &bh2); e_set_swab (bs, gdp->bg_free_inodes_count, e_swab (bs, gdp->bg_free_inodes_count) + 1); if (S_ISDIR(inode->i_mode)) e_set_swab (bs, gdp->bg_used_dirs_count, e_swab (bs, gdp->bg_used_dirs_count) - 1); mark_buffer_dirty(bh2, 1); e_set_swab (bs, es->s_free_inodes_count, e_swab (bs, es->s_free_inodes_count) + 1); mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1); inode->i_dirt = 0; } mark_buffer_dirty(bh, 1); if (sb->s_flags & MS_SYNCHRONOUS) { ll_rw_block (WRITE, 1, &bh); wait_on_buffer (bh); } sb->s_dirt = 1; clear_inode (inode); unlock_super (sb); }