XV6 se bloque lors de la tentative d’implémentation sortingple indirection dans le système d’exploitation xv6

Le système d’exploitation d’origine xv6-rev7 contient:
12 blocs dirigés
1 blcok indirect (points à 128 blocs)

Cela signifie que nous avons 140 blocs.
La taille de chaque bloc est de 512 Ko ==> 512 * 140 = 71 680 ~ = 70 Ko est la limite de la taille du fichier en xv6.

Je souhaite implémenter un access sortingple indirect en xv6 afin de prendre en charge des fichiers d’une taille de 40 Mo.

Pour ce faire, je devrai mettre en œuvre le double indirect avant le sortingple indirect.
J’ai donc pris 2 blocs dirigés sur les 12 que j’avais.
1 pour le double indirect et l’autre pour le sortingple indirect.
C’est ce que j’ai en ce moment:
Direct: 10 pâtés de maisons
Simple indirect: 128
Double indirecte: 128 * 128
Triple indirect: 4 * 128 * 128 (J’utilise 4 au lieu de 128 car cela suffit pour 40 Mo)

C’est pourquoi #define NDIRECT 10 et uint addrs[NDIRECT+3];

La limite de taille du fichier = (10 + 128 + 128 * 128 + 4 * 128 * 128) * 512 Ko = 42 013 696 ~ = 42 Mo

Alors je comprends le concept. L’implémentation de la sortingple indirection est dans la fonction bmap du fichier fs.c
Voici à quoi ça ressemble:
entrez la description de l'image ici

Pour une raison quelconque, lorsque j’essaie de créer un fichier de 8,5 Mo, il échoue: entrez la description de l'image ici
J’utilise l’émulateur de bochs

Je ne suis pas sûr non plus des valeurs à modifier dans mkfs.c:

 int nblocks = 20985; int nlog = LOGSIZE; int ninodes = 200; int size = 21029; 

fs.h:

 // On-disk file system format. // Both the kernel and user programs use this header file. // Block 0 is unused. // Block 1 is super block. // Blocks 2 through sb.ninodes/IPB hold inodes. // Then free bitmap blocks holding sb.size bits. // Then sb.nblocks data blocks. // Then sb.nlog log blocks. #define ROOTINO 1 // root i-number #define BSIZE 512 // block size // File system super block struct superblock { uint size; // Size of file system image (blocks) uint nblocks; // Number of data blocks uint ninodes; // Number of inodes. uint nlog; // Number of log blocks }; #define NDIRECT 10 #define NINDIRECT (BSIZE / sizeof(uint)) #define MAXFILE (NDIRECT + NINDIRECT + NINDIRECT*NINDIRECT + 4*NINDIRECT*NINDIRECT) // On-disk inode structure struct dinode { short type; // File type short major; // Major device number (T_DEV only) short minor; // Minor device number (T_DEV only) short nlink; // Number of links to inode in file system uint size; // Size of file (bytes) uint addrs[NDIRECT+3]; // Data block addresses }; // Inodes per block. #define IPB (BSIZE / sizeof(struct dinode)) // Block containing inode i #define IBLOCK(i) ((i) / IPB + 2) // Bitmap bits per block #define BPB (BSIZE*8) // Block containing bit for block b #define BBLOCK(b, ninodes) (b/BPB + (ninodes)/IPB + 3) // Directory is a file containing a sequence of dirent structures. #define DIRSIZ 14 struct dirent { ushort inum; char name[DIRSIZ]; }; 

fs.c:

 // Return the disk block address of the nth block in inode ip. // If there is no such block, bmap allocates one. static uint bmap(struct inode *ip, uint bn) { uint addr, *a; struct buf *bp; if(bn addrs[bn]) == 0) ip->addrs[bn] = addr = balloc(ip->dev); return addr; } bn -= NDIRECT; if(bn addrs[NDIRECT]) == 0) ip->addrs[NDIRECT] = addr = balloc(ip->dev); bp = bread(ip->dev, addr); a = (uint*)bp->data; if((addr = a[bn]) == 0){ a[bn] = addr = balloc(ip->dev); log_write(bp); } brelse(bp); return addr; } /* Double indirect */ bn -= NINDIRECT; if(bn addrs[NDIRECT+1]) == 0) // 2d block. NDIRECT+1 is to get the index vector ip->addrs[NDIRECT+1] = addr = balloc(ip->dev); bp = bread(ip->dev, addr); a = (uint*)bp->data; if ((addr = a[bn/(NINDIRECT)]) == 0) { /* get index for 1st indirection. (NINDIRECT is 128) */ a[bn/(NINDIRECT)] = addr = balloc(ip->dev); log_write(bp); } brelse(bp); /* release the double indirect table (main level) */ bp = bread(ip->dev, addr); a = (uint*)bp->data; if ((addr = a[bn%(NINDIRECT)]) == 0) { /* get the 2nd level table */ a[bn%(NINDIRECT)] = addr = balloc(ip->dev); log_write(bp); } brelse(bp); return addr; } /* Triple indirect */ bn -= NINDIRECT*NINDIRECT; if(bn addrs[NDIRECT+2]) == 0) // 3d block. NDIRECT+2 is to get the index vector ip->addrs[NDIRECT+2] = addr = balloc(ip->dev); bp = bread(ip->dev, addr); a = (uint*)bp->data; if ((addr = a[bn/(NINDIRECT*4)]) == 0) { /* get index for 2st indirection. (NINDIRECT is 128) */ a[bn/(NINDIRECT*4)] = addr = balloc(ip->dev); log_write(bp); } brelse(bp); bp = bread(ip->dev, addr); a = (uint*)bp->data; if ((addr = a[bn/(NINDIRECT*NINDIRECT*4)]) == 0) { a[bn/(NINDIRECT*NINDIRECT*4)] = addr = balloc(ip->dev); log_write(bp); } brelse(bp); if ((addr = a[bn%(NINDIRECT*NINDIRECT*4)]) == 0) { a[bn%(NINDIRECT*NINDIRECT*4)] = addr = balloc(ip->dev); log_write(bp); } brelse(bp); return addr; } panic("bmap: out of range"); } 

mkfs.c:

 #define stat xv6_stat // avoid clash with host struct stat #include "types.h" #include "fs.h" #include "stat.h" #include "param.h" int nblocks = 20985; int nlog = LOGSIZE; int ninodes = 200; int size = 21029; 

bigfile.c:

 #include "types.h" #include "stat.h" #include "user.h" #include "fcntl.h" void help() { printf(1, "usage:\nfiles   \n" "eg nfiles foo a 40\n creates a file foo, with 40 times the letter a\n"); } void num2str(int i, char str[3]) { str[2]=i%10+'0'; i=i/10; str[1]=i%10+'0'; i=i/10; str[0]=i%10+'0'; i=i/10; } #define BUF_SZ 512 int main(int argc, char *argv[]) { int i, count, fd, n; // char *name; // char c; char buf[BUF_SZ]; if (argc !=4) { help(); exit(); } count = atoi(argv[3]); if((fd=open(argv[1], O_CREATE|O_RDWR))<0) { printf(2,"Failed to open file: %s\n", argv[1]); exit(); } for (i=0; i<BUF_SZ;i++) buf[i]=argv[2][0]; for (i=0; i<count/BUF_SZ;i++) if ((n=write(fd,buf,BUF_SZ)) != BUF_SZ) { printf(2,"Failed 1 to Write count=%d\n",i*BUF_SZ); exit(); } for (i=0; i<count%BUF_SZ;i++) if ((n=write(fd,argv[2],1)) != 1) { printf(2,"Failed 2 to Write count=%d\n",count-i); exit(); } exit(); } 

1.Le nombre de nblocks défini dans mkfs.c est insuffisant.

 int nblocks = 20985; int nlog = LOGSIZE; int ninodes = 200; int size = 21029; 

Vous avez défini:

 #define MAXFILE (NDIRECT + NINDIRECT + NINDIRECT*NINDIRECT + 4*NINDIRECT*NINDIRECT 

ce qui équivaut à: 10 + 128 + 128 ^ 2 + 4 * 128 ^ 2 = 82058.

Il suffit de choisir un nombre de nblocks supérieur à 82058 et de mettre à jour la size conséquence.

2.Dans votre fonction bmap (), dans le code sortingple indirection, votre premier niveau d’indirection correspond à un tableau à quatre entrées (comme vous l’avez mentionné dans votre diagramme). Une fois que vous savez à laquelle de ces quatre entrées vous devez accéder, vous êtes de retour avec le problème de double indirection, que vous avez déjà résolu.

Donc, pour savoir à laquelle des quatre entrées vous devez accéder, vous pouvez utiliser ceci:

 if((addr = a[bn/(NINDIRECT*NINDIRECT)]) == 0){ a[bn/(NINDIRECT*NINDIRECT)] = addr = balloc(ip->dev); log_write(bp); } 

Vous pourriez alors diminuer de la manière suivante:

 bn -= ((NINDIRECT*NINDIRECT)*(bn/(NINDIRECT*NINDIRECT))); 

et résolvez à nouveau le problème de double indirection.