6 extern uint8_t fsipcbuf
[PGSIZE
]; // page-aligned, declared in entry.S
8 // Send an IP request to the file server, and wait for a reply.
9 // type: request code, passed as the simple integer IPC value.
10 // fsreq: page to send containing additional request data, usually fsipcbuf.
11 // Can be modified by server to return additional response info.
12 // dstva: virtual address at which to receive reply page, 0 if none.
13 // *perm: permissions of received page.
14 // Returns 0 if successful, < 0 on failure.
16 fsipc(unsigned type
, void *fsreq
, void *dstva
, int *perm
)
21 cprintf("[%08x] fsipc %d %08x\n", env
->env_id
, type
, fsipcbuf
);
23 ipc_send(envs
[1].env_id
, type
, fsreq
, PTE_P
| PTE_W
| PTE_U
);
24 return ipc_recv(&whom
, dstva
, perm
);
27 // Send file-open request to the file server.
28 // Includes 'path' and 'omode' in request,
29 // and on reply maps the returned file descriptor page
30 // at the address indicated by the caller in 'fd'.
31 // Returns 0 on success, < 0 on failure.
33 fsipc_open(const char *path
, int omode
, struct Fd
*fd
)
36 struct Fsreq_open
*req
;
38 req
= (struct Fsreq_open
*)fsipcbuf
;
39 if (strlen(path
) >= MAXPATHLEN
)
41 strcpy(req
->req_path
, path
);
42 req
->req_omode
= omode
;
44 return fsipc(FSREQ_OPEN
, req
, fd
, &perm
);
47 // Make a map-block request to the file server.
48 // We send the fileid and the (byte) offset of the desired block in the file,
49 // and the server sends us back a mapping for a page containing that block.
50 // Returns 0 on success, < 0 on failure.
52 fsipc_map(int fileid
, off_t offset
, void *dstva
)
55 struct Fsreq_map
*req
;
57 req
= (struct Fsreq_map
*) fsipcbuf
;
58 req
->req_fileid
= fileid
;
59 req
->req_offset
= offset
;
60 if ((r
= fsipc(FSREQ_MAP
, req
, dstva
, &perm
)) < 0)
62 if ((perm
& ~(PTE_W
| PTE_SHARE
)) != (PTE_U
| PTE_P
))
63 panic("fsipc_map: unexpected permissions %08x for dstva %08x", perm
, dstva
);
67 // Make a set-file-size request to the file server.
69 fsipc_set_size(int fileid
, off_t size
)
71 struct Fsreq_set_size
*req
;
73 req
= (struct Fsreq_set_size
*) fsipcbuf
;
74 req
->req_fileid
= fileid
;
76 return fsipc(FSREQ_SET_SIZE
, req
, 0, 0);
79 // Make a file-close request to the file server.
80 // After this the fileid is invalid.
82 fsipc_close(int fileid
)
84 struct Fsreq_close
*req
;
86 req
= (struct Fsreq_close
*) fsipcbuf
;
87 req
->req_fileid
= fileid
;
88 return fsipc(FSREQ_CLOSE
, req
, 0, 0);
91 // Ask the file server to mark a particular file block dirty.
93 fsipc_dirty(int fileid
, off_t offset
)
95 struct Fsreq_dirty
*req
;
97 req
= (struct Fsreq_dirty
*) fsipcbuf
;
98 req
->req_fileid
= fileid
;
99 req
->req_offset
= offset
;
100 return fsipc(FSREQ_DIRTY
, req
, 0, 0);
103 // Ask the file server to delete a file, given its pathname.
105 fsipc_remove(const char *path
)
107 struct Fsreq_remove
*req
;
109 req
= (struct Fsreq_remove
*) fsipcbuf
;
110 if (strlen(path
) >= MAXPATHLEN
)
112 strcpy(req
->req_path
, path
);
113 return fsipc(FSREQ_REMOVE
, req
, 0, 0);
116 // Ask the file server to update the disk
117 // by writing any dirty blocks in the buffer cache.
121 return fsipc(FSREQ_SYNC
, fsipcbuf
, 0, 0);