Re: tweak for lockmgr
Thinking about this some more, I like it even less. VOP_ISLOCKED is actually documented by the man page to return either 0 or 1. Not some LK flag. The fact that some filesystems are lazy and just feed up lockstatus doesn't mean lockstatus is broken. It means tmpfs_islocked and ufs_islocked are broken. The code currently in the tree is (at long last) compliant with the man page. According to lock(9), lockstatus() is currently broken: lockstatus(lock) Determine the status of lock lock. Returns LK_EXCLUSIVE or LK_SHARED for exclusive-access and shared-access locks respectively. -p.
Re: tmpfs
One more note. We already have a fmt_scaled function in libutil which would be better than introducing a private dehumanisze_number. Good point; I will switch to fmt_scaled() in the next iteration of the diff. -p.
Re: tmpfs
However, both fs indirection structures will need fixing, as they use C99 field assignments: you know stuff like: +struct vops tmpfs_fifovops = { + .vop_lookup = tmpfs_fifo_lookup, + .vop_create = tmpfs_fifo_create, and +struct vops tmpfs_specvops = { + .vop_lookup = tmpfs_spec_lookup, + .vop_create = tmpfs_spec_create, This is the same kind of field assignment used by all other file systems in the tree for 2 years now. -p.
Re: tmpfs
http://block.io/tmpfs/tmpfs4.diff My bad, the correct URL is: http://block.io/tmp/tmpfs4.diff -p.
Re: tmpfs
$ cat goodfilename coincoin $ perl -pi -e 's/toto/tutu/' goodfilename works $ cp goodfilename /tmp $ perl -pi -e 's/toto/tutu/' /tmp/goodfilename Can't do inplace edit on goodfilename: File exists. $ cat /tmp/goodfilename cat: /tmp/goodfilename: No such file or directory. ktrace shows a disturbing lack of Unix semantics: 15350 perl CALL open(0x1850b9e863f0,0) 15350 perl NAMI "goodfilename" 15350 perl RET open 3 ... 15350 perl CALL unlink(0x1850b9e86a00) 15350 perl NAMI "goodfilename" 15350 perl RET unlink 0 15350 perl CALL open(0x1850b9e868e0,0xa01,0x180) 15350 perl NAMI "goodfilename" 15350 perl RET open -1 errno 17 File exists err... simply put: #include #include #include int main() { if (open("fucked_up", O_RDWR|O_CREAT|O_TRUNC, 0666) == -1) perror("open"); if (unlink("fucked_up") != 0) perror("unlink"); if (open("fucked_up", O_WRONLY|O_CREAT|O_EXCL, 0666) == -1) perror("reopen"); return 0; } Thank you very much for spotting this. The problem was a missing check when calling cache_enter() from tmpfs_lookup(). I have fixed the glitch in version 4 of the diff: http://block.io/tmpfs/tmpfs4.diff Alternatively, you might want to ammend the source code directly, since it is a one-line change. In tmpfs_vnops.c, replace the following check in line 289 if (cnp->cn_nameiop != CREATE) { cache_enter(dvp, *vpp, cnp); } with if ((cnp->cn_flags & MAKEENTRY) && cnp->cn_nameiop != CREATE) { cache_enter(dvp, *vpp, cnp); } -p.
Re: tmpfs
So, it's not working. After about 5 mn of succesful build, my tmpfs is full touch /tmp/a touch: /tmp/a: No space left on device whereas: df -khi /tmp tmpfs 10.5G 600M 9.9G 6% 45728 41386496 0% /tmp so, something put it into a "no space left" configuration internally ? My guess is that you are reaching the UVM aobj limit. Try a 'vmstat -m' to check that. -p.
Re: tmpfs
I'd like to test this, but I'm not very experienced with building only part of the userland. How do I tell the build system to install the new header files? cd /usr/src; make obj cleandir includes Please contact me off-list should you need further assistance. -p.
Re: tmpfs
Speaking of, I see a lot of int64_max sprinkled throughout, which doesn't seem right for 32 bit platforms. Hi Ted, In tmpfs3.diff there are three uses of INT64_MAX: The first, in tmpfs_mount(), concerns the maximum amount of memory (in bytes) that tmpfs will contemplate. This value is bounded by the numbers in UVM's uvmexp and by the parameters specified upon mount, if any. The second and the third bound the number of pages available to tmpfs, which is kept internally as a uint64_t (certainly overkill, could perfectly be uint32_t, but is unlikely to cause problems and helps when translating from pages to bytes). This bounding happens when filling struct statfs's f_bavail and f_favail, which are int64_t. -p.
Re: tmpfs
What kind of numbers are we talking about here? I have an mfs on a box where I have had to bump the inodes in order to accomodate a huge amount of small files. Around 1100k files across all tmpfs mount points. Anything beyond that limit will get you a ENOSPC error. That is obviously a bug, but fixing it while preventing tmpfs from eating the machine is not trivial. -p.
Re: tmpfs
I have ported NetBSD's tmpfs to OpenBSD. The port should be functional on i386 and amd64. I haven't tested on other architectures. There are limitations: update of mount options is not supported and the number of nodes in a tmpfs file system is limited by the number of anonymous UVM objects we can allocate. Otherwise, give it a go. The diff can be found at: http://block.io/tmp/tmpfs.diff You will need a new kernel with option TMPFS enabled, fresh include files and mount_tmpfs. tmpfs is a better MFS, it is faster and can free unused memory. I have put up an updated diff at: http://block.io/tmp/tmpfs3.diff This diff fixes a couple of 64 vs 32-bit inconsistencies in the original diff, as well as a missing call to uvm_vnp_uncache() upon truncation. Many thanks to Chris Jackman for testing on sparc64. -p.
-Wshorten-64-to-32
Hi, Apple has added a -Wshorten-64-to-32 option to GCC. It generates a warning if a value is implicitly converted from a 64-bit to a 32-bit type. I found it useful, looked at the code and ported it to OpenBSD. I don't think this is worth integrating. Use at your own discretion. :) -p. Index: gcc/gcc/c-common.c === RCS file: /cvs/src/gnu/gcc/gcc/c-common.c,v retrieving revision 1.4 diff -u -p -r1.4 c-common.c --- gcc/gcc/c-common.c 15 Sep 2011 12:19:12 - 1.4 +++ gcc/gcc/c-common.c 3 Apr 2013 12:38:19 - @@ -552,6 +552,8 @@ static bool nonnull_check_p (tree, unsig static bool get_nonnull_operand (tree, unsigned HOST_WIDE_INT *); static int resort_field_decl_cmp (const void *, const void *); +static void warnings_for_convert_and_check (tree, tree, tree); + /* Table of machine-independent attributes common to all C-like languages. */ const struct attribute_spec c_common_attribute_table[] = { @@ -1073,6 +1075,26 @@ vector_types_convertible_p (tree t1, tre == INTEGRAL_TYPE_P (TREE_TYPE (t2))); } +void +warnings_for_convert_and_check (tree type, tree expr, tree result ATTRIBUTE_UNUSED) +{ + if (warn_shorten_64_to_32 + && TYPE_PRECISION (TREE_TYPE (expr)) == 64 + && TYPE_PRECISION (type) == 32) + { + /* As a special case, don't warn when we are working with small + constants as the enum forming code shortens them into smaller + types. */ + if (TREE_CODE (expr) == INTEGER_CST) +{ + bool unsignedp = tree_int_cst_sgn (expr) >= 0; + if (min_precision (expr, unsignedp) <= TYPE_PRECISION (type)) +return; +} + warning (0, "implicit conversion shortens 64-bit value into a 32-bit value"); + } +} + /* Convert EXPR to TYPE, warning about conversion problems with constants. Invoke this function on every expression that is converted implicitly, i.e. because of language rules and not because of an explicit cast. */ @@ -1109,6 +1131,8 @@ convert_and_check (tree type, tree expr) else unsigned_conversion_warning (t, expr); } + if (!skip_evaluation && !TREE_OVERFLOW (expr) && t != error_mark_node) +warnings_for_convert_and_check (type, expr, t); return t; } Index: gcc/gcc/c.opt === RCS file: /cvs/src/gnu/gcc/gcc/c.opt,v retrieving revision 1.4 diff -u -p -r1.4 c.opt --- gcc/gcc/c.opt 15 Sep 2011 12:19:12 - 1.4 +++ gcc/gcc/c.opt 3 Apr 2013 12:38:19 - @@ -161,6 +161,10 @@ Wconversion C ObjC C++ ObjC++ Var(warn_conversion) Warn about possibly confusing type conversions +Wshorten-64-to-32 +C Var(warn_shorten_64_to_32) +Warn if a value is implicitly converted from a 64-bit to a 32-bit type + Wctor-dtor-privacy C++ ObjC++ Var(warn_ctor_dtor_privacy) Warn when all constructors and destructors are private
tmpfs
Hi, I have ported NetBSD's tmpfs to OpenBSD. The port should be functional on i386 and amd64. I haven't tested on other architectures. There are limitations: update of mount options is not supported and the number of nodes in a tmpfs file system is limited by the number of anonymous UVM objects we can allocate. Otherwise, give it a go. The diff can be found at: http://block.io/tmp/tmpfs.diff You will need a new kernel with option TMPFS enabled, fresh include files and mount_tmpfs. tmpfs is a better MFS, it is faster and can free unused memory. -p.
Fix iteration of softdep hash tables
Hi, The code in clear_remove() and clear_inodedeps() does not iterate over the pagedep and inodedep hash tables correctly. The last entry in the table is skipped -- this is due to the fact that 'pagedep_hash' and 'inodedep_hash' hold the size of the hash tables - 1. -p. Index: ufs/ffs/ffs_softdep.c === RCS file: /cvs/src/sys/ufs/ffs/ffs_softdep.c,v retrieving revision 1.116 diff -u -p -r1.116 ffs_softdep.c --- ufs/ffs/ffs_softdep.c 17 Feb 2013 17:39:29 - 1.116 +++ ufs/ffs/ffs_softdep.c 25 Mar 2013 10:36:26 - @@ -5320,9 +5320,9 @@ clear_remove(struct proc *p) ino_t ino; ACQUIRE_LOCK(&lk); - for (cnt = 0; cnt < pagedep_hash; cnt++) { + for (cnt = 0; cnt <= pagedep_hash; cnt++) { pagedephd = &pagedep_hashtbl[next++]; - if (next >= pagedep_hash) + if (next > pagedep_hash) next = 0; LIST_FOREACH(pagedep, pagedephd, pd_hash) { if (LIST_FIRST(&pagedep->pd_dirremhd) == NULL) @@ -5376,9 +5376,9 @@ clear_inodedeps(struct proc *p) * We will then gather up all the inodes in its block * that have dependencies and flush them out. */ - for (cnt = 0; cnt < inodedep_hash; cnt++) { + for (cnt = 0; cnt <= inodedep_hash; cnt++) { inodedephd = &inodedep_hashtbl[next++]; - if (next >= inodedep_hash) + if (next > inodedep_hash) next = 0; if ((inodedep = LIST_FIRST(inodedephd)) != NULL) break;