24extern u32 pfsMetaSize;
34 u32 new_dentryLen=0,dentryLen;
40 new_dentryLen = (len+8+3) &~3;
44 block_pos.inode = pfsCacheUsedAdd(clink);
45 block_pos.block_segment = 1;
46 block_pos.block_offset = 0;
47 block_pos.byte_offset = 0;
48 dentCache = pfsGetDentriesChunk(&block_pos, &result);
50 if (dentCache != NULL)
52 d2=d=dentCache->u.dentry;
53 while(*size < clink->u.inode->size)
56 if (d2 >= (
pfs_dentry_t*)((u8*)dentCache->u.inode + pfsMetaSize))
58 if (pfsInodeSync(&block_pos, pfsMetaSize, clink->u.inode->number_data))
60 pfsCacheFree(dentCache);
62 if ((dentCache=pfsGetDentriesChunk(&block_pos, &result)) == NULL)
64 d=dentCache->u.dentry;
70 aLen=(d->aLen & 0xFFF);
73 PFS_PRINTF(PFS_DRV_NAME
": Error: dentry allocated length/4 != 0\n");
76 dentryLen = (d->pLen + 8 + 3) & 0x1FC;
77 if (aLen < dentryLen){
78 PFS_PRINTF(PFS_DRV_NAME
": Error: dentry is too small\n");
82 PFS_PRINTF(PFS_DRV_NAME
": Error: dentry across sectors\n");
90 result = (len==d->pLen) && (memcmp(path, d->path, d->pLen)==0);
93 result = ((d->inode) || (aLen < new_dentryLen)) ? (aLen - dentryLen
94 >= new_dentryLen) : 1;
97 result = d->pLen && strcmp(d->path,
".") && strcmp(d->path,
"..");
106 pfsCacheFree(block_pos.inode);
112_exit: pfsCacheFree(dentCache);
114 pfsCacheFree(block_pos.inode);
125 while((len == 0) && (*position < clink->u.inode->size))
129 if (!(dcache=pfsGetDentriesChunk(blockpos, &result)))
131 PFS_PRINTF(PFS_DRV_NAME
": couldnt get dentries chunk for dread!\n");
135 dentry = (
pfs_dentry_t*)((u8*)dcache->u.data + (blockpos->byte_offset % pfsMetaSize));
138 memcpy(name, dentry->path, len);
141 bi->subpart = dentry->sub;
142 bi->number = dentry->inode;
143 pfsCacheFree(dcache);
145 *position += dentry->aLen & 0xFFF;
148 if (pfsInodeSync(blockpos, dentry->aLen & 0xFFF, clink->u.inode->number_data))
157 dentry->inode=bi->number;
158 dentry->sub=(u8)bi->subpart;
159 dentry->pLen=strlen(path1);
161 memcpy(dentry->path, path1, dentry->pLen & 0xFF);
173 dcache=pfsGetDentry(dir, filename, &dentry, &size, 1);
175 len=dentry->aLen & 0xFFF;
177 len-=(dentry->pLen + 11) & 0x1FC;
178 dentry->aLen=(dentry->aLen &
FIO_S_IFMT) | ((dentry->aLen & 0xFFF) - len);
179 dentry=(
pfs_dentry_t *)((u8*)dentry + (dentry->aLen & 0xFFF));
183 if ((*result=pfsAllocZones(dir,
sizeof(
pfs_dentry_t), 0))<0)
185 dcache=pfsGetDentriesAtPos(dir, dir->u.inode->size, &offset, result);
194 return pfsFillDentry(dcache, dentry, filename, bi, len, mode);
205 if ((c=pfsGetDentry(clink, path, &dentry, &size, 0)) != NULL){
208 val=(u8*)dentry-(u8*)c->u.dentry;
209 if (val<0) val +=511;
215 aLen = dnext->aLen & 0xFFF;
219 dlast->aLen=(dlast->aLen &
FIO_S_IFMT) | ((dlast->aLen & 0xFFF) + aLen);
224 if (size+aLen >= clink->u.inode->size)
225 clink->u.inode->size -= aLen;
243 if((dcache=pfsGetDentry(clink, NULL, &dentry, &size, 2))){
244 pfsCacheFree(dcache);
254 memset(dentry, 0, pfsMetaSize);
255 dentry->inode=self->number;
257 dentry->path[1]=
'\0';
258 dentry->sub=(u8)self->subpart;
264 dentry->inode=parent->number;
267 dentry->path[2]=
'\0';
268 dentry->sub=(u8)parent->subpart;
278 dcache=pfsGetDentriesAtPos(clink, 0, &offset, result);
282 d->sub =(u8)bi->subpart;
296 return pfsCacheUsedAdd(dirInode);
299 if ((dirInode->block ==
300 dirInode->pfsMount->root_dir.number << dirInode->pfsMount->inode_scale) &&
301 (dirInode->sub == dirInode->pfsMount->root_dir.subpart) &&
302 (strcmp(path,
"..") == 0))
303 return pfsCacheUsedAdd(dirInode);
305 if ((*result=pfsCheckAccess(dirInode, 1)) < 0)
310 if ((clink=pfsGetDentry(dirInode, path, &dentry, &size, 0))){
312 return pfsInodeGetData(dirInode->pfsMount,
313 dentry->sub, dentry->inode, result);
321 const char *name,
int *result) {
325 c=pfsInodeGetParent(pfsMount, clink, name, path, result);
329 fileInode=pfsInodeGetFileInDir(c, path, result);
340 memset(ci->u.inode, 0, pfsMetaSize);
342 ci->u.inode->magic=PFS_SEGD_MAGIC;
344 ci->u.inode->inode_block.number=bi->number;
345 ci->u.inode->inode_block.subpart=bi->subpart;
346 ci->u.inode->inode_block.count=bi->count;
348 ci->u.inode->last_segment.number=bi->number;
349 ci->u.inode->last_segment.subpart=bi->subpart;
350 ci->u.inode->last_segment.count=bi->count;
352 ci->u.inode->mode=mode;
353 ci->u.inode->uid=uid;
354 ci->u.inode->gid=gid;
357 ci->u.inode->attr=0xA0;
364 ci->u.inode->number_data=val;
365 ci->u.inode->number_blocks=val;
367 pfsGetTime(&ci->u.inode->ctime);
368 memcpy(&ci->u.inode->atime, &ci->u.inode->ctime,
sizeof(
pfs_datetime_t));
369 memcpy(&ci->u.inode->mtime, &ci->u.inode->ctime,
sizeof(
pfs_datetime_t));
371 ci->u.inode->number_segdesg=1;
372 ci->u.inode->data[0].number =bi->number;
373 ci->u.inode->data[0].subpart=bi->subpart;
374 ci->u.inode->data[0].count =bi->count;
376 ci->u.inode->subpart=bi->subpart;
378 ci->flags |= PFS_CACHE_FLAG_DIRTY;
387 char *path,
int *result)
389 static int pfsSymbolicLinks = 0;
391 char *filename2=(
char*)filename;
396 if (clink) pfsCacheFree(clink);
400 if (filename2[0] ==
'/')
405 if (clink) pfsCacheFree(clink);
406 if ((clink=pfsInodeGetData(pfsMount, pfsMount->root_dir.subpart,
407 pfsMount->root_dir.number, result))==0)
410 else if (clink==NULL)
415 if ((clink=pfsInodeGetData(pfsMount, pfsMount->current_dir.subpart,
416 pfsMount->current_dir.number, result))==0)
422 filename2=pfsSplitPath(filename2, path, result);
423 if (filename2==NULL)
return NULL;
437 inode=pfsInodeGetFileInDir(clink, path, result);
441 if (pfsSymbolicLinks >= 4)
450 link=pfsInodeGetFile(pfsMount, clink, (
char*)&inode->u.inode->data[1], result);
474 if((entry=pfsDirRemoveEntry(parent, path))!=NULL)
476 pfsInodeSetTimeParent(parent, entry);
482 pfsCacheFree(parent);
485 inode->flags&=~PFS_CACHE_FLAG_DIRTY;
486 pfsBitmapFreeInodeBlocks(inode);
488 pfsCacheFlushAllDirty(parent->pfsMount);
506 if (pfsMount->num_subs > clink->u.inode->subpart)
507 clink->u.inode->subpart++;
509 clink->u.inode->subpart=0;
511 a.subpart=clink->u.inode->subpart;
512 j= (pfsMount->zfree * (u64)100) / pfsMount->total_zones;
513 i= (pfsMount->free_zone[a.subpart] * (u64)100) /
514 (pfsMount->blockDev->getSize(pfsMount->fd, a.subpart) >> pfsMount->sector_scale);
515 if ((i < j) && ((j-i) >= 11))
516 a.subpart=pfsGetMaxIndex(pfsMount);
518 a.number=clink->u.inode->inode_block.number;
519 a.subpart=clink->u.inode->inode_block.subpart;
524 *result=pfsBitmapSearchFreeZone(pfsMount, &a, 2);
525 if (*result<0)
return 0;
526 inode=pfsCacheGetData(pfsMount, a.subpart, a.number << pfsMount->inode_scale,
527 PFS_CACHE_FLAG_SEGD | PFS_CACHE_FLAG_NOLOAD, result);
547 inode->u.inode->data[1].number=a.number;
548 inode->u.inode->data[1].subpart=a.subpart;
549 inode->u.inode->data[1].count =a.count;
559 if ((clink->pfsMount->flags & FIO_MT_RDONLY) && (flags & FIO_O_WRONLY))
563 ((clink->u.inode->mode & 0111) == 0))
567 return ((mode & flags) & 7) == flags ? 0 : -
EACCES;
570char* pfsSplitPath(
char *filename,
char *path,
int *result)
575 for (i=0; filename[i] ==
'/'; i++)
578 for (; i<1024 && filename[i] !=
'/'; i++){
579 if (filename[i] == 0)
break;
581 path[j++] = filename[i];
587 while (filename[i] ==
'/')
601 u32 max=0, maxI=0, i, v;
603 for (i=0; i < pfsMount->num_subs + 1; i++)
605 v = (pfsMount->free_zone[i] * (u64)100) /
606 (pfsMount->blockDev->getSize(pfsMount->fd, i) >> pfsMount->sector_scale);
616int pfsAllocZones(
pfs_cache_t *clink,
int msize,
int mode)
623 zsize=clink->pfsMount->zsize;
624 val=((msize-1 + zsize) & (-zsize)) / zsize;
627 if (((clink->u.inode->number_blocks-clink->u.inode->number_segdesg) *(u64)zsize)
628 >= (clink->u.inode->size + msize))
631 if((blockpos.inode = pfsBlockGetLastSegmentDescriptorInode(clink, &result)))
633 blockpos.block_offset=blockpos.byte_offset=0;
634 blockpos.block_segment=clink->u.inode->number_data-1;
635 val-=pfsBlockExpandSegment(clink, &blockpos, val);
636 while (val && ((result=pfsBlockAllocNewSegment(clink, &blockpos, val))>=0)){
640 pfsCacheFree(blockpos.inode);
651 u32 nextsegdesc = 1, limit = inode->number_data, i, j = 0, zones;
655 zones = (u32)(inode->size / pfsMount->zsize);
656 if(inode->size % pfsMount->zsize)
658 if(inode->number_segdesg + zones == inode->number_blocks)
663 clink = pfsCacheUsedAdd(pfree);
666 for (i = 1; i < limit && j; i++)
668 if(pfsFixIndex(i) == 0)
670 if ((clink = pfsBlockGetNextSegment(clink, &result)) == 0)
677 bi = &clink->u.inode->data[pfsFixIndex(i)];
682 b.subpart = bi->subpart;
684 b.number = bi->number +
687 clink->flags |= PFS_CACHE_FLAG_DIRTY;
694 pfree->u.inode->number_data = i;
695 pfree->u.inode->number_blocks = zones + nextsegdesc;
696 pfree->u.inode->number_segdesg = nextsegdesc;
697 pfree->u.inode->last_segment.number = clink->u.inode->data[0].number;
698 pfree->u.inode->last_segment.subpart= clink->u.inode->data[0].subpart;
699 pfree->u.inode->last_segment.count = clink->u.inode->data[0].count;
700 pfree->flags |= PFS_CACHE_FLAG_DIRTY;
703 pfsBitmapFreeBlockSegment(pfsMount, &b);
705 for( ; i < limit; i++)
707 if (pfsFixIndex(i) == 0)
709 if((clink = pfsBlockGetNextSegment(clink, &result)) == 0)
712 bi = &clink->u.inode->data[pfsFixIndex(i)];
713 pfsBitmapFreeBlockSegment(pfsMount, bi);
714 pfsCacheMarkClean(pfsMount, bi->subpart, bi->number<<pfsMount->inode_scale,
715 (bi->number+bi->count)<<pfsMount->inode_scale);
u32 count
start sector of fragmented bd/file