Age | Commit message (Collapse) | Author |
|
Make global variables static to avoid symbol clashes.
Order Link fields more compactly for 64-bit archs.
Add a common freelink() function for freeing Boards and Srvs.
Chain all Boards in a circular doubly-linked list,
so srvrename() can actually change the owners of *all*
the boards instead of just the root. We cannot use
recursion here as that could potentially blow the
kernel stack.
srvname() was also only processing the root.
Instead, we add a srvname field to Chan and set it to
the original path of the srv file that was used to post
the channel.
Call openmode() at the beginning of srvopen().
The reason is if omode has invalid bits it can error
and leave stuff in a inconsistent state.
Prevent srvwstat() to rename a file to "clone", it is
reserved.
Get rid of "lease expired" error message, just use
Eshutdown.
|
|
The mount ID is a sequence number in a 32 bit integer, which means that
it can't be unique. This is largely harmless, because there is no way to
use the mount id, beyond checking if it's negative.
However, there's no overflow check, so the mount ID can wrap negative,
which will break error checks on mount calls.
Because it's useless, let's just stop returning it.
|
|
|
|
In a few places, we where using a fixed buffer of sizeof(Dir)+100
size for stat. This is not correct and fails if the name returned
in stat is long.
This results in being unable to seek to the end of file with a
long filename.
The kernel should do the same thing as dirfstat() from libc;
handling the conversion and buffer allocation and returning a
freeable Dir* pointer.
For this, a new dirchanstat() function was added.
The fstat syscall was not rewriting the name to the last path
element; fix it.
In addition, gracefully handle the mountfix case, reallocating
the buffer to accomidate the required stat length plus
size of the new name so dirsetname() does not fail.
|
|
The Mhead structures have two sources of references to them:
- from Pgrp.mnthash hash-table
- from a channels Chan.umh pointer as returned by namec() for a union directory
Unless one holds the Mhead.lock RWLock, the Mhead.mount chain
can be mutated by eigther cmount(), cunmount() or closepgrp().
Readers, skipping acquiering the lock where:
mountfix(): responsible for rewriting directory entries for
union directory reads; was walking the Mhead.mount chain to
detect if the passed channel itself appears in the mount list.
cmount(): had a check and copy when "new" chan was a union itself
and if the MCREATE flag is set and would copy the mount table.
All this needs to be done with Mhead read-locked while copying
the mount entries.
devproc(): in the handler for reading /proc/n/ns file.
namec(): while checking if the Chan->umh should be initialized.
In addition to this, cmount() is changed to do the mountfree()
of the original mount chain when MREPL is done after releasing
the locks.
Also, some cosmetic changes...
|
|
opening /fd, /srv and /shr
The OCEXEC flag used to be maintained per channel,
making it shared between all the file desciptors.
This has a unexpected side effects with regard to
channel passing drivers such as devdup (/fd),
devsrv (/srv) and devshr (/shr).
For example, opening a /srv file with OCEXEC
makes it impossible to be remounted by exportfs
as it internally does a exec() to mount and
re-export it. There is no way to reset the flag.
This change makes the OCEXEC flag per file descriptor,
so a open with the OCEXEC flag only affects the fd
group of the calling process, and not the channel
itself.
On rfork(RFFDG), the per file descriptor flags get
copied.
On dup(), the per file descriptor flags are reset.
The second modification is that /fd, /srv and /shr
should reject the ORCLOSE flag, as the files that
are returned have already been opend.
|
|
The Abind case in namec() needs to cunique() the chan
before attaching the umh mount head pointer onto it.
This is because we cannot give a reference to the mount
head to any of the mh->mount...->to channels, as they
will never go away until the mount head goes away.
This is a cyclic reference.
This could be reproduced with:
@{rfork n; mount -a '#s/boot' /mnt/root; bind /mnt/root /}
Also, fix memory leaks around cunique(), which can
error, leaking the mount head we got from domount().
Move the umh != nil check inside cunique().
|
|
|
|
|
|
see drawterm commits f5e26ae93a6a and fa388286b4ca
|
|
make sure the loop terminates and doesnt get stuck at
name == aname. avoid memrchr() as it conflicts with
libc on unix (drawterm). declare namelenerror() as
static.
|
|
|
|
|
|
|
|
instead of ordering the source mount list, order the new destination
list which has the advantage that we do not need to wlock the source
namespace, so copying can be done in parallel and we do not need the
copy forward pointer in the Mount structure.
the Mhead back pointer in the Mount strcture was unused, removed.
|
|
there was a race between cunmount() and walk() on Mhead.from as Mhead.from was
unconditionally freed when we cunmount(), but findmount might have already
returned the Mhead in walk(). we have to ensure that Mhead.from is not freed
before the Mhead itself (now done in putmhead() once the reference count of the
Mhead drops to zero).
the Mhead struct contained two unused locks, removing.
no need to hold Pgrp.ns lock in closegrp() as nobody can get to it (refcount
droped to zero).
avoid cclose() and freemount() while holding Mhead.lock or Pgrp.ns locks as
it might block on a hung up fileserver.
remove the debug prints...
cleanup: use nil for pointers, remove redundant nil checks before putmhead().
|
|
|
|
|
|
|
|
special case in namec()
we already export mntauth() and mntversion(), so why not stop
being sneaky and just export mntattach() so bindmount() and
devshr can just call it directly with proper arguments being
checked.
we can also avoid handling #M attach specially in namec()
by having the devmnt's attach function do error(Enoattach).
|
|
|
|
|
|
newchan()
|
|
Lock
make the Page stucture less than half its original size by getting rid of
the Lock and the lru.
The Lock was required to coordinate the unchaining of pages that where
both cached and on the lru freelist.
now pages have a single next pointer that is used for palloc.head
freelist xor for page cache hash chains in Image.pghash[].
cached pages are not on the freelist anymore, but will be reclaimed
from images by the pager when the freelist runs out of pages.
each Image has its own 512 hash chains for cached page lookup. That is
2MB worth of pages and there should be no collisions for most text images.
page reclaiming can be done without holding palloc.lock as the Image is
the owner of the page hash chains protected by the Image's lock.
reclaiming Image structures can be done quickly by only reclaiming pages from
inactive images, that is images which are not currently in use by segments.
the Ref structure has no Lock anymore. Only a single long that is atomically
incremented or decremnted using cmpswap().
there are various other changes as a consequence code. and lots of pikeshedding,
sorry.
|
|
if theres an error transmitting a Tclunk or Tremove request,
we cannot assume the fid to be clunked. in case this was
a transient error, reusing the fid on further requests
will fail.
as a work arround, we zero the channels fid and allocate
a new fid before the chan is reused.
this is not correct as we essentially leak the fid
on the fileserver, but we will still be able to use
the mount.
|
|
this change is in preparation for amd64. the systab calling
convention was also changed to return uintptr (as segattach
returns a pointer) and the arguments are now passed as
va_list which handles amd64 arguments properly (all arguments
are passed in 64bit quantities on the stack, tho the upper
part will not be initialized when the element is smaller
than 8 bytes).
this is partial. xalloc needs to be converted in the future.
|
|
the shr mount is linked into the Mhead with m->to initially nil. only
after the the server has been attached is m->to set. just check for
it in createdir().
|
|
make closeproc() spawn more procs on demand insead of
doing it from closechanq(). this avoids the palloc lock
checks and simplifies the logic.
|
|
closechanq() is unable to fork a new closeproc when palloc
is locked. so we spawn a closeproc early in chandevinit()
and make sure theres always one process arround to handle
the queue.
|
|
p->dot can be nil when process exits (see pexit())
set closeprocs dot to up->slash so it will show up
right in devproc.
|
|
catch potential interrupt error from kproc(). this can happen when
we run out of processes, then newproc() will call rsrcwait()
which does tsleep(). if the process gets a note, this might
raise a interrupt error.
|
|
|
|
dont let the clunk queue grow too large if we are allowed to
block (cclose) as the fileserver might run out of fids.
|
|
kstrcpy() did not null terminate for < 4 byte buffers. fixed,
but i dont think there is any case where this can happen in
practice.
always set malloctag in kstrdup(), cleanup.
always use ERRMAX bounded kstrcpy() to set up->errstr, q->err
and note[]->msg. paranoia.
instead of silently truncating interface name in netifinit(),
panic the kernel if interface name is too long as this case
is clearly a mistake.
panic kernel when filename is too long for addbootfile() in
devroot. this might happen if your kernel configuration is
messed up.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|