9ns: Fix issues with can_have_children
[akaros.git] / kern / src / ns / fs_file.c
1 /* Copyright (c) 2018 Google Inc
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * fs_file: structs and helpers for files for 9ns devices
6  */
7
8 #include <fs_file.h>
9 #include <kmalloc.h>
10 #include <string.h>
11 #include <stdio.h>
12 #include <assert.h>
13 #include <error.h>
14 #include <umem.h>
15 #include <pmap.h>
16
17 /* Initializes a zalloced fs_file.  The caller is responsible for filling in
18  * dir, except for name.  Most fields are fine with being zeroed.  Note the kref
19  * == 0 too. */
20 void fs_file_init(struct fs_file *f, const char *name, struct fs_file_ops *ops)
21 {
22         qlock_init(&f->qlock);
23         fs_file_set_basename(f, name);
24         f->ops = ops;
25         /* TODO: consider holding off on initializing the PM, since only walked and
26          * opened entries could use it.  pm == NULL means no PM yet.  Negative
27          * entries will never be used in this manner.  Doing it now avoids races,
28          * though it's mostly zeroing cache-hot fields. */
29         f->pm = &f->static_pm;
30         pm_init(f->pm, (struct page_map_operations*)ops, f);
31 }
32
33 void fs_file_set_basename(struct fs_file *f, const char *name)
34 {
35         size_t name_len = strlen(name) + 1;
36
37         if (name_len > KNAMELEN)
38                 f->dir.name = kzmalloc(name_len, MEM_WAIT);
39         else
40                 f->dir.name = f->static_name;
41         memcpy(f->dir.name, name, name_len);
42 }
43
44 /* Technically, a reader could see the old string pointer and read it.  That
45  * memory could be realloced and used for something else.  But thanks to the
46  * seqctr, the reader will retry.  Otherwise, we might not need the seqctr,
47  * since we never change_basename when a file is in a tree.  So far.
48  *
49  * The only reader that races with setting the name is stat.  Regular lookups
50  * won't see the file, since it was removed from the HT, and readdirs won't see
51  * it due to the parent's qlock. */
52 void fs_file_change_basename(struct fs_file *f, const char *name)
53 {
54         char *old_name = NULL;
55         char *new_name = NULL;
56         size_t name_len = strlen(name) + 1;
57
58         if (name_len > KNAMELEN)
59                 new_name = kzmalloc(name_len, MEM_WAIT);
60         qlock(&f->qlock);
61         if (f->dir.name != f->static_name)
62                 old_name = f->dir.name;
63         if (new_name)
64                 f->dir.name = new_name;
65         else
66                 f->dir.name = f->static_name;
67         memcpy(f->dir.name, name, name_len);
68         /* TODO: if we store the hash of the name in the file, do so here. */
69         qunlock(&f->qlock);
70         kfree(old_name);
71 }
72
73 /* Helper for building a dir.  Caller sets qid path and vers.  YMMV. */
74 void fs_file_init_dir(struct fs_file *f, int dir_type, int dir_dev,
75                       struct username *user, int perm)
76 {
77         struct dir *dir = &f->dir;
78
79         if (perm & DMDIR)
80                 dir->qid.type |= QTDIR;
81         if (perm & DMAPPEND)
82                 dir->qid.type |= QTAPPEND;
83         if (perm & DMEXCL)
84                 dir->qid.type |= QTEXCL;
85         if (perm & DMSYMLINK)
86                 dir->qid.type |= QTSYMLINK;
87         /* dir->mode stores all the DM bits, but note that userspace can only affect
88          * the permissions (S_PMASK) bits. */
89         dir->mode = perm;
90         __set_acmtime(f, FSF_ATIME | FSF_BTIME | FSF_MTIME | FSF_CTIME);
91         dir->length = 0;
92         /* TODO: this is a mess if you use anything other than eve.  If you use a
93          * process, that memory is sitting in the proc struct, but we have weak refs
94          * on it.  What happens when that proc exits?  Disaster. */
95         assert(user == &eve);
96         dir->uid = user->name;
97         dir->gid = user->name;
98         dir->muid = user->name;
99 }
100
101 static char *copy_str(const char *s)
102 {
103         char *ret;
104         size_t sz;
105
106         if (!s)
107                 return NULL;
108         sz = strlen(s) + 1;
109         ret = kmalloc(sz, MEM_WAIT);
110         memcpy(ret, s, sz);
111         return ret;
112 }
113
114 /* Deep copies the contents of dir into the fs_file's dir. */
115 void fs_file_copy_from_dir(struct fs_file *f, struct dir *dir)
116 {
117         memcpy(&f->dir, dir, sizeof(struct dir));
118         fs_file_set_basename(f, dir->name);
119         /* TODO: sort out usernames.  Not only are these just eve, but they are not
120          * struct user or something and they ignore whatever the name was from the
121          * remote end. */
122         f->dir.uid = eve.name;
123         f->dir.gid = eve.name;
124         f->dir.muid = eve.name;
125         f->dir.ext = copy_str(dir->ext);
126 }
127
128 void cleanup_fs_file(struct fs_file *f)
129 {
130         if (f->dir.name != f->static_name)
131                 kfree(f->dir.name);
132         /* TODO: Not sure if these will be refcounted objects in the future.  Keep
133          * this in sync with other code that manages/sets uid/gid/muid. */
134         f->dir.uid = NULL;
135         f->dir.gid = NULL;
136         f->dir.muid = NULL;
137         if (f->dir.ext)
138                 kfree(f->dir.ext);
139         f->dir.ext = NULL;
140         pm_destroy(f->pm);
141         /* Might share mappings in the future.  Catch it here. */
142         assert(f->pm == &f->static_pm);
143 }
144
145 void __set_acmtime_to(struct fs_file *f, int which, struct timespec *t)
146 {
147         /* WRITE_ONCE, due to lockless peakers */
148         if (which & FSF_ATIME) {
149                 WRITE_ONCE(f->dir.atime.tv_sec, t->tv_sec);
150                 WRITE_ONCE(f->dir.atime.tv_nsec, t->tv_nsec);
151         }
152         if (which & FSF_BTIME) {
153                 WRITE_ONCE(f->dir.btime.tv_sec, t->tv_sec);
154                 WRITE_ONCE(f->dir.btime.tv_nsec, t->tv_nsec);
155         }
156         if (which & FSF_CTIME) {
157                 WRITE_ONCE(f->dir.ctime.tv_sec, t->tv_sec);
158                 WRITE_ONCE(f->dir.ctime.tv_nsec, t->tv_nsec);
159         }
160         if (which & FSF_MTIME) {
161                 WRITE_ONCE(f->dir.mtime.tv_sec, t->tv_sec);
162                 WRITE_ONCE(f->dir.mtime.tv_nsec, t->tv_nsec);
163         }
164 }
165
166 /* Caller should hold f's qlock */
167 void __set_acmtime(struct fs_file *f, int which)
168 {
169         struct timespec now = nsec2timespec(epoch_nsec());
170
171         __set_acmtime_to(f, which, &now);
172 }
173
174 /* Recall that the frontend always has the most up-to-date info.  This gets
175  * synced to the backend when we flush or fsync. */
176 void set_acmtime_to(struct fs_file *f, int which, struct timespec *t)
177 {
178         ERRSTACK(1);
179
180         qlock(&f->qlock);
181         if (waserror()) {
182                 qunlock(&f->qlock);
183                 nexterror();
184         }
185         if ((which & FSF_ATIME) && !caller_has_file_perms(f, O_READ))
186                 error(EPERM, "insufficient perms to set atime");
187         if ((which & FSF_BTIME) && !caller_is_username(f->dir.uid))
188                 error(EPERM, "insufficient perms to set btime");
189         if ((which & FSF_CTIME) && !caller_has_file_perms(f, O_WRITE))
190                 error(EPERM, "insufficient perms to set ctime");
191         if ((which & FSF_MTIME) && !caller_has_file_perms(f, O_WRITE))
192                 error(EPERM, "insufficient perms to set mtime");
193         __set_acmtime_to(f, which, t);
194         qunlock(&f->qlock);
195         poperror();
196 }
197
198 void set_acmtime_noperm(struct fs_file *f, int which)
199 {
200         struct timespec now = nsec2timespec(epoch_nsec());
201
202         /* <3 atime.  We'll go with an hour resolution, like NTFS. */
203         if (which == FSF_ATIME) {
204                 if (now.tv_sec < ACCESS_ONCE(f->dir.atime.tv_sec) + 3600)
205                         return;
206         }
207         qlock(&f->qlock);
208         __set_acmtime_to(f, which, &now);
209         qunlock(&f->qlock);
210 }
211
212 size_t fs_file_stat(struct fs_file *f, uint8_t *m_buf, size_t m_buf_sz)
213 {
214         size_t ret;
215
216         qlock(&f->qlock);
217         ret = convD2M(&f->dir, m_buf, m_buf_sz);
218         qunlock(&f->qlock);
219         if (ret <= BIT16SZ)
220                 error(EINVAL, "buffer too small for stat");
221         return ret;
222 }
223
224 /* Helper: update file metadata after a write */
225 static void write_metadata(struct fs_file *f, off64_t offset,
226                            bool always_update_len)
227 {
228         qlock(&f->qlock);
229         f->flags |= FSF_DIRTY;
230         if (always_update_len || (offset > f->dir.length))
231                 WRITE_ONCE(f->dir.length, offset);
232         __set_acmtime(f, FSF_MTIME | FSF_CTIME);
233         qunlock(&f->qlock);
234 }
235
236 /* Punches a hole from begin to end.  Pages completely in the hole will be
237  * removed.  Otherwise, the edges will be zeroed.
238  *
239  * Concurrent truncates with reads and writes can lead to weird data.
240  * truncate()/punch_hole will attempt to remove data in page-sized chunks.
241  * Concurrent users (with a PM refcnt, under the current code) will prevent
242  * removal.  punch_hole will memset those areas to 0, similar to a concurrent
243  * write.
244  *
245  * read() will return data that is up to the file's length.  write() and
246  * punch_hole() will add or remove data and set the length.  When adding data
247  * (write), we add it first, then set the len.  When removing data, we set the
248  * len, then remove it.  If you mix those ops, the len could be set above an
249  * area where the data is still being mucked with.  read/write/mmap all grab
250  * references to the PM's page slot, locking the page in the page cache for a
251  * little.  Truncate often won't remove those pages, but it will try to zero
252  * them.  reads and mmaps will check the length on their own, while it is being
253  * changed by other ops.
254  *
255  * A few examples:
256  * - Trunc to 0 during write to N.  A reader might get zeros instead of the data
257  *   written (trunc was dropping/zeroing the pages after write wrote them).
258  * - Trunc to 0, trunc back to N, with concurrent reads/mmaps of the area in
259  *   between: a reader might see the old data or tears in the data.
260  * - mmaps of pages in a region that gets hole-punched and faults at the same
261  *   time might not get a SIGBUS / ESPIPE.  That length check is best effort.
262  * - After we remove hole pages from the page cache, but before we tell the
263  *   backend, a read/write/mmap-fault to a page in the hole could fetch the old
264  *   data from the backend before the FS op removes the data from the backend,
265  *   and we'd end up with some old data.  The root issue here is that the
266  *   frontend is a cache, and it has the most recent version of the data.  In
267  *   the case of hole punching, we want there to be an absence of data.
268  *   Technically, we could have zeroed pages, but we don't want the overhead of
269  *   that.  So we drop the pages - that situation looks the same as not having
270  *   the data in the cache/frontend.
271  *
272  * To prevent these things, we could qlock the entire file during all ops, or
273  * even just for trunc, write, and loading pages into the PM for read.  That was
274  * my first version of this.  But you can imagine backends that don't require
275  * this sort of serialization (e.g. ramfs, future #mnts, etc), and it
276  * complicates some mmap / pagemap code.  If you want the qlock to protect the
277  * invariant (one of which is that the file's contents below len are always
278  * valid; another is that hole punches don't keep old data), then we can add
279  * some sort of file locking.
280  */
281 static void fs_file_punch_hole(struct fs_file *f, off64_t begin, off64_t end)
282 {
283         size_t first_pg_idx, last_pg_idx, nr_pages, zero_amt;
284         struct page *page;
285         int error;
286
287         /* Caller should check for this */
288         assert((long)begin >= 0);
289         assert((long)end >= 0);
290         if (end <= begin)
291                 return;
292         /* We're punching for the range [begin, end), but inclusive for the pages:
293          * [first_pg_idx, last_pg_idx]. */
294         first_pg_idx = LA2PPN(begin);
295         last_pg_idx = LA2PPN(ROUNDUP(end, PGSIZE)) - 1;
296         nr_pages = last_pg_idx - first_pg_idx + 1;
297         if (PGOFF(begin)) {
298                 error = pm_load_page(f->pm, first_pg_idx, &page);
299                 if (error)
300                         error(-error, "punch_hole pm_load_page failed");
301                 zero_amt = MIN(PGSIZE - PGOFF(begin), end - begin);
302                 memset(page2kva(page) + PGOFF(begin), 0, zero_amt);
303                 atomic_or(&page->pg_flags, PG_DIRTY);
304                 pm_put_page(page);
305                 first_pg_idx++;
306                 nr_pages--;
307                 if (!nr_pages)
308                         return;
309         }
310         if (PGOFF(end)) {
311                 /* if this unaligned end is beyond the EOF, we might pull in a page of
312                  * zeros, then zero the first part of it. */
313                 error = pm_load_page(f->pm, last_pg_idx, &page);
314                 if (error)
315                         error(-error, "punch_hole pm_load_page failed");
316                 memset(page2kva(page), 0, PGOFF(end));
317                 atomic_or(&page->pg_flags, PG_DIRTY);
318                 pm_put_page(page);
319                 last_pg_idx--;
320                 nr_pages--;
321                 if (!nr_pages)
322                         return;
323         }
324         pm_remove_or_zero_pages(f->pm, first_pg_idx, nr_pages);
325         /* After we removed the pages from the PM, but before we tell the backend,
326          * someone could load a backend page.  Note that we only tell the backend
327          * about the intermediate pages - we already dealt with the edge pages
328          * above, and the PM has the latest, dirty version of them. */
329         f->ops->punch_hole(f, first_pg_idx << PGSHIFT,
330                            (first_pg_idx + nr_pages) << PGSHIFT);
331 }
332
333 void fs_file_truncate(struct fs_file *f, off64_t to)
334 {
335         off64_t old_len = fs_file_get_length(f);
336
337         fs_file_perm_check(f, O_WRITE);
338         if ((to > old_len) && !f->ops->can_grow_to(f, to))
339                 error(EINVAL, "can't grow file to %lu bytes", to);
340         write_metadata(f, to, true);
341         if (to < old_len) {
342                 /* Round up the old_len to avoid making an unnecessary partial page of
343                  * zeros at the end of the file. */
344                 fs_file_punch_hole(f, to, ROUNDUP(old_len, PGSIZE));
345         }
346 }
347
348 /* Standard read.  We sync with write, in that once the length is set, we'll
349  * attempt to read those bytes. */
350 size_t fs_file_read(struct fs_file *f, uint8_t *buf, size_t count,
351                     off64_t offset)
352 {
353         ERRSTACK(1);
354         struct page *page;
355         size_t copy_amt, pg_off, pg_idx, total_remaining;
356         volatile size_t so_far = 0;             /* volatile for waserror */
357         const uint8_t *buf_end = buf + count;
358         int error;
359
360         if (waserror()) {
361                 if (so_far) {
362                         poperror();
363                         return so_far;
364                 }
365                 nexterror();
366         }
367         while (buf < buf_end) {
368                 /* Check early, so we don't load pages beyond length needlessly.  The
369                  * PM/FSF op might just create zeroed pages when asked. */
370                 if (offset + so_far >= fs_file_get_length(f))
371                         break;
372                 pg_off = PGOFF(offset + so_far);
373                 pg_idx = LA2PPN(offset + so_far);
374                 error = pm_load_page(f->pm, pg_idx, &page);
375                 if (error)
376                         error(-error, "read pm_load_page failed");
377                 copy_amt = MIN(PGSIZE - pg_off, buf_end - buf);
378                 /* Lockless peak.  Check the len so we don't read beyond EOF.  We have a
379                  * page, but we don't necessarily have access to all of it. */
380                 total_remaining = fs_file_get_length(f) - (offset + so_far);
381                 if (copy_amt > total_remaining) {
382                         copy_amt = total_remaining;
383                         buf_end = buf + copy_amt;
384                 }
385                 memcpy_to_safe(buf, page2kva(page) + pg_off, copy_amt);
386                 buf += copy_amt;
387                 so_far += copy_amt;
388                 pm_put_page(page);
389         }
390         if (so_far)
391                 set_acmtime_noperm(f, FSF_ATIME);
392         poperror();
393         return so_far;
394 }
395
396 size_t fs_file_write(struct fs_file *f, const uint8_t *buf, size_t count,
397                      off64_t offset)
398 {
399         ERRSTACK(1);
400         struct page *page;
401         size_t copy_amt, pg_off, pg_idx;
402         volatile size_t so_far = 0;             /* volatile for waserror */
403         const uint8_t *buf_end = buf + count;
404         int error;
405
406         if (waserror()) {
407                 if (so_far) {
408                         write_metadata(f, offset + so_far, false);
409                         poperror();
410                         return so_far;
411                 }
412                 nexterror();
413         };
414         if (offset + count > fs_file_get_length(f)) {
415                 if (!f->ops->can_grow_to(f, offset + count))
416                         error(EINVAL, "can't write file to %lu bytes", offset + count);
417         }
418         while (buf < buf_end) {
419                 pg_off = PGOFF(offset + so_far);
420                 pg_idx = LA2PPN(offset + so_far);
421                 error = pm_load_page(f->pm, pg_idx, &page);
422                 if (error)
423                         error(-error, "write pm_load_page failed");
424                 copy_amt = MIN(PGSIZE - pg_off, buf_end - buf);
425                 memcpy_from_safe(page2kva(page) + pg_off, buf, copy_amt);
426                 buf += copy_amt;
427                 so_far += copy_amt;
428                 atomic_or(&page->pg_flags, PG_DIRTY);
429                 pm_put_page(page);
430         }
431         assert(buf == buf_end);
432         assert(count == so_far);
433         /* We set the len *after* writing for our lockless reads.  If we set len
434          * before, then read() could start as soon as we loaded the page (all
435          * zeros), but before we wrote the actual data.  They'd get zeros instead of
436          * what we added. */
437         write_metadata(f, offset + so_far, false);
438         poperror();
439         return so_far;
440 }
441
442 static void wstat_mode(struct fs_file *f, int new_mode)
443 {
444         ERRSTACK(1);
445         int mode;
446
447         qlock(&f->qlock);
448         if (waserror()) {
449                 qunlock(&f->qlock);
450                 nexterror();
451         }
452         if (!caller_is_username(f->dir.uid))
453                 error(EPERM, "wrong user for wstat, need %s", f->dir.uid);
454         /* Only allowing changes in permissions, not random stuff like whether it is
455          * a directory or symlink. */
456         static_assert(!(DMMODE_BITS & S_PMASK));
457         mode = (f->dir.mode & ~S_PMASK) | (new_mode & S_PMASK);
458         WRITE_ONCE(f->dir.mode, mode);
459         __set_acmtime(f, FSF_CTIME);
460         qunlock(&f->qlock);
461         poperror();
462 }
463
464 size_t fs_file_wstat(struct fs_file *f, uint8_t *m_buf, size_t m_buf_sz)
465 {
466         struct dir *m_dir;
467         size_t m_sz;
468
469         /* common trick in wstats.  we want the dir and any strings in the M.  the
470          * strings are smaller than the entire M (which is strings plus the real dir
471          * M).  the strings will be placed right after the dir (dir[1]) */
472         m_dir = kzmalloc(sizeof(struct dir) + m_buf_sz, MEM_WAIT);
473         m_sz = convM2D(m_buf, m_buf_sz, &m_dir[0], (char*)&m_dir[1]);
474         if (!m_sz) {
475                 kfree(m_dir);
476                 error(ENODATA, "couldn't convM2D");
477         }
478         /* We'll probably have similar issues for all of the strings.  At that
479          * point, we might not even bother reading the strings in. */
480         if (!emptystr(m_dir->name))
481                 error(EINVAL, "do not rename with wstat");
482         if (m_dir->mode != -1)
483                 wstat_mode(f, m_dir->mode);
484         if (m_dir->length != -1)
485                 fs_file_truncate(f, m_dir->length);
486         if ((int64_t)m_dir->atime.tv_sec != -1)
487                 set_acmtime_to(f, FSF_ATIME, &m_dir->atime);
488         if ((int64_t)m_dir->btime.tv_sec != -1)
489                 set_acmtime_to(f, FSF_BTIME, &m_dir->btime);
490         if ((int64_t)m_dir->ctime.tv_sec != -1)
491                 set_acmtime_to(f, FSF_CTIME, &m_dir->ctime);
492         if ((int64_t)m_dir->mtime.tv_sec != -1)
493                 set_acmtime_to(f, FSF_MTIME, &m_dir->mtime);
494         /* TODO: handle uid/gid/muid changes */
495         kfree(m_dir);
496         return m_sz;
497 }