segment_alloc may not allocate enough memory.
[mit-jos.git] / lib / fsipc.c
blobeabed1fbdfc7ba3360994d54ba923b1d78ca0f06
1 #include <inc/fs.h>
2 #include <inc/lib.h>
4 #define debug 0
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.
15 static int
16 fsipc(unsigned type, void *fsreq, void *dstva, int *perm)
18 envid_t whom;
20 if (debug)
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.
32 int
33 fsipc_open(const char *path, int omode, struct Fd *fd)
35 int perm;
36 struct Fsreq_open *req;
38 req = (struct Fsreq_open*)fsipcbuf;
39 if (strlen(path) >= MAXPATHLEN)
40 return -E_BAD_PATH;
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.
51 int
52 fsipc_map(int fileid, off_t offset, void *dstva)
54 int r, perm;
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)
61 return r;
62 if ((perm & ~(PTE_W | PTE_SHARE)) != (PTE_U | PTE_P))
63 panic("fsipc_map: unexpected permissions %08x for dstva %08x", perm, dstva);
64 return 0;
67 // Make a set-file-size request to the file server.
68 int
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;
75 req->req_size = size;
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.
81 int
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.
92 int
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)
111 return -E_BAD_PATH;
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.
119 fsipc_sync(void)
121 return fsipc(FSREQ_SYNC, fsipcbuf, 0, 0);