XINU
lfsetup.c
Go to the documentation of this file.
1 /* lfsetup.c - lfsetup */
2 
3 #include <xinu.h>
4 
5 /*------------------------------------------------------------------------
6  * lfsetup - Set a file's index block and data block for the current
7  * file position (assumes file mutex held)
8  *------------------------------------------------------------------------
9  */
11  struct lflcblk *lfptr /* Pointer to slave file device */
12  )
13 {
14  dbid32 dnum; /* Data block to fetch */
15  ibid32 ibnum; /* I-block number during search */
16  struct ldentry *ldptr; /* Ptr to file entry in dir. */
17  struct lfiblk *ibptr; /* Ptr to in-memory index block */
18  uint32 newoffset; /* Computed data offset for */
19  /* next index block */
20  int32 dindex; /* Index into array in an index */
21  /* block */
22 
23 
24  /* Obtain exclusive access to the directory */
25 
27 
28  /* Get pointers to in-memory directory, file's entry in the */
29  /* directory, and the in-memory index block */
30 
31  ldptr = lfptr->lfdirptr;
32  ibptr = &lfptr->lfiblock;
33 
34  /* If existing index block or data block changed, write to disk */
35 
36  if (lfptr->lfibdirty || lfptr->lfdbdirty) {
37  lfflush(lfptr);
38  }
39  ibnum = lfptr->lfinum; /* Get ID of curr. index block */
40 
41  /* If there is no index block in memory (e.g., because the file */
42  /* was just opened), either load the first index block of */
43  /* the file or allocate a new first index block */
44 
45  if (ibnum == LF_INULL) {
46 
47  /* Check directory entry to see if index block exists */
48 
49  ibnum = ldptr->ld_ilist;
50  if (ibnum == LF_INULL) { /* Empty file - get new i-block*/
51  ibnum = lfiballoc();
52  lfibclear(ibptr, 0);
53  ldptr->ld_ilist = ibnum;
54  lfptr->lfibdirty = TRUE;
55  } else { /* Nonempty - read first i-block*/
56  lfibget(Lf_data.lf_dskdev, ibnum, ibptr);
57  }
58  lfptr->lfinum = ibnum;
59 
60  /* Otherwise, if current file position has been moved to an */
61  /* offset before the current index block, start at the */
62  /* beginning of the index list for the file */
63 
64  } else if (lfptr->lfpos < ibptr->ib_offset) {
65 
66  /* Load initial index block for the file (we know that */
67  /* at least one index block exists) */
68 
69  ibnum = ldptr->ld_ilist;
70  lfibget(Lf_data.lf_dskdev, ibnum, ibptr);
71  lfptr->lfinum = ibnum;
72  }
73 
74  /* At this point, an index block is in memory, but may cover */
75  /* an offset less than the current file position. Loop until */
76  /* the index block covers the current file position. */
77 
78  while ((lfptr->lfpos & ~LF_IMASK) > ibptr->ib_offset ) {
79  ibnum = ibptr->ib_next;
80  if (ibnum == LF_INULL) {
81  /* Allocate new index block to extend file */
82  ibnum = lfiballoc();
83  ibptr->ib_next = ibnum;
84  lfibput(Lf_data.lf_dskdev, lfptr->lfinum, ibptr);
85  lfptr->lfinum = ibnum;
86  newoffset = ibptr->ib_offset + LF_IDATA;
87  lfibclear(ibptr, newoffset);
88  lfptr->lfibdirty = TRUE;
89  } else {
90  lfibget(Lf_data.lf_dskdev, ibnum, ibptr);
91  lfptr->lfinum = ibnum;
92  }
93  lfptr->lfdnum = LF_DNULL; /* Invalidate old data block */
94  }
95 
96  /* At this point, the index block in lfiblock covers the */
97  /* current file position (i.e., position lfptr->lfpos). The */
98  /* next step consists of loading the correct data block. */
99 
100  dindex = (lfptr->lfpos & LF_IMASK) >> 9;
101 
102  /* If data block index does not match current data block, read */
103  /* the correct data block from disk */
104 
105  dnum = lfptr->lfiblock.ib_dba[dindex];
106  if (dnum == LF_DNULL) { /* Allocate new data block */
107  dnum = lfdballoc((struct lfdbfree *)&lfptr->lfdblock);
108  lfptr->lfiblock.ib_dba[dindex] = dnum;
109  lfptr->lfibdirty = TRUE;
110  } else if ( dnum != lfptr->lfdnum) {
111  read(Lf_data.lf_dskdev, (char *)lfptr->lfdblock, dnum);
112  lfptr->lfdbdirty = FALSE;
113  }
114  lfptr->lfdnum = dnum;
115 
116  /* Use current file offset to set the pointer to the next byte */
117  /* within the data block */
118 
119  lfptr->lfbyte = &lfptr->lfdblock[lfptr->lfpos & LF_DMASK];
121  return OK;
122 }
int32 dbid32
データブロックID(ファイルシステムで使用する)
Definition: kernel.h:42
dbid32 lfdballoc(struct lfdbfree *)
Definition: lfdballoc.c:19
char * lfbyte
Definition: lfilesys.h:161
struct ldentry * lfdirptr
Definition: lfilesys.h:147
int32 ibid32
ブロックIDのインデックス(ファイルシステムで使用する)
Definition: kernel.h:40
ibid32 ld_ilist
Definition: lfilesys.h:99
sid32 lf_mutex
Definition: lfilesys.h:132
全てのシステムヘッダファイルをインクルードする。
struct lfdata Lf_data
Definition: lfsinit.c:5
syscall read(did32, char *, uint32)
Definition: read.c:9
did32 lf_dskdev
Definition: lfilesys.h:131
void lfibclear(struct lfiblk *, int32)
Definition: lfibclear.c:9
#define OK
処理が成功した場合
Definition: kernel.h:77
int32 status
ステータスを意味する返り値の型(OK/SYSERR)
Definition: kernel.h:57
void lfibget(did32, ibid32, struct lfiblk *)
Definition: lfibget.c:10
struct lfiblk lfiblock
Definition: lfilesys.h:155
#define LF_INULL
Definition: lfilesys.h:55
#define LF_IMASK
Definition: lfilesys.h:60
ibid32 lfinum
Definition: lfilesys.h:153
#define FALSE
Boolean False(0)
Definition: kernel.h:63
#define LF_IDATA
Definition: lfilesys.h:58
#define TRUE
Boolean True(1)
Definition: kernel.h:65
dbid32 lfdnum
Definition: lfilesys.h:157
ibid32 ib_next
Definition: lfilesys.h:72
#define LF_DMASK
Definition: lfilesys.h:63
bool8 lfdbdirty
Definition: lfilesys.h:166
int int32
符号あり32ビット整数(int)
Definition: kernel.h:11
#define LF_DNULL
Definition: lfilesys.h:56
status lfsetup(struct lflcblk *lfptr)
Definition: lfsetup.c:10
uint32 ib_offset
Definition: lfilesys.h:73
dbid32 ib_dba[LF_IBLEN]
Definition: lfilesys.h:75
bool8 lfibdirty
Definition: lfilesys.h:165
syscall wait(sid32)
Definition: wait.c:9
syscall signal(sid32)
セマフォにシグナルを送り、待機プロセスがある場合は解除する。
Definition: signal.c:18
uint32 lfpos
Definition: lfilesys.h:150
unsigned int uint32
符号なし32ビット整数(unsigned int)
Definition: kernel.h:15
char lfdblock[LF_BLKSIZ]
Definition: lfilesys.h:159
status lfflush(struct lflcblk *)
Definition: lfflush.c:10
ibid32 lfiballoc(void)
Definition: lfiballoc.c:10
status lfibput(did32, ibid32, struct lfiblk *)
Definition: lfibput.c:10