tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

libquota proposal



Hello,
looking at pkgsrc/net/netatalk to make it use the new quota interface
convinced be that we need a libquota, which can return the quota status
for a id in a simple way, as independant as possible from the underlying
filesystem. So I propose to hide the magic in a libquota,
which propose a:
int getfsquota(const char *path, struct ufs_quota_entry *qv, uid_t id,
  const char *class)

(path is path to a file, not necesserely a mount point.
class is "user" or "group" at this time, as defined in sys/quota.h).
This will return the usage and limits from the filesystem quota is supported.
This includes nfs.
For tools that care, a getufsquota() and getnfsquota() is also accessible
(it's free as they are needed for getfsquota() anyway).

functions that actually live in ufs/ufs/quota2_prop.h have moved either to
libprop or libquota (in the common/ subdirectory so they can be accessible
from kernel and userland). A new interface that doesn't reference on-disk
quota2 structures has been defiend, and in-tree tools have been modified to
make use of this. Only tools that directly deal with on-disk quota
data now reference kernel includes or sources

As this is needed to get netatalk to build again on HEAD, I'd like
to commit this in the next few days.

-- 
Manuel Bouyer <bouyer%antioche.eu.org@localhost>
     NetBSD: 26 ans d'experience feront toujours la difference
--
? amd64-build.sh
? amiga-build.sh
? build-amd64.log
? common/include/quota
? common/lib/libquota
? lib/libquota
Index: common/include/prop/prop_array.h
===================================================================
RCS file: /cvsroot/src/common/include/prop/prop_array.h,v
retrieving revision 1.11
diff -u -r1.11 prop_array.h
--- common/include/prop/prop_array.h    20 Jan 2011 11:17:58 -0000      1.11
+++ common/include/prop/prop_array.h    18 Mar 2011 15:58:46 -0000
@@ -154,6 +154,8 @@
                                                   unsigned int,
                                                   const char *);
 
+bool           prop_array_add_and_rel(prop_array_t, prop_object_t);
+
 __END_DECLS
 
 #endif /* _PROPLIB_PROP_ARRAY_H_ */
Index: common/include/prop/prop_dictionary.h
===================================================================
RCS file: /cvsroot/src/common/include/prop/prop_dictionary.h,v
retrieving revision 1.12
diff -u -r1.12 prop_dictionary.h
--- common/include/prop/prop_dictionary.h       20 Jan 2011 11:17:58 -0000      
1.12
+++ common/include/prop/prop_dictionary.h       18 Mar 2011 15:58:46 -0000
@@ -115,6 +115,8 @@
  * Utility routines to make it more convenient to work with values
  * stored in dictionaries.
  */
+bool           prop_dictionary_get_dict(prop_dictionary_t, const char *,
+                                        prop_dictionary_t *);
 bool           prop_dictionary_get_bool(prop_dictionary_t, const char *,
                                         bool *);
 bool           prop_dictionary_set_bool(prop_dictionary_t, const char *,
@@ -168,6 +170,10 @@
                                                   const char *,
                                                   const char *);
 
+bool           prop_dictionary_set_and_rel(prop_dictionary_t,
+                                                  const char *,
+                                                  prop_object_t);
+
 __END_DECLS
 
 #endif /* _PROPLIB_PROP_DICTIONARY_H_ */
Index: common/lib/libprop/prop_array_util.3
===================================================================
RCS file: /cvsroot/src/common/lib/libprop/prop_array_util.3,v
retrieving revision 1.4
diff -u -r1.4 prop_array_util.3
--- common/lib/libprop/prop_array_util.3        20 Jan 2011 10:42:19 -0000      
1.4
+++ common/lib/libprop/prop_array_util.3        18 Mar 2011 15:58:46 -0000
@@ -27,7 +27,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd June 2, 2008
+.Dd March 12, 2011
 .Dt PROP_ARRAY_UTIL 3
 .Os
 .Sh NAME
@@ -61,7 +61,8 @@
 .Nm prop_array_get_cstring ,
 .Nm prop_array_set_cstring ,
 .Nm prop_array_get_cstring_nocopy ,
-.Nm prop_array_set_cstring_nocopy
+.Nm prop_array_set_cstring_nocopy,
+.Nm prop_array_add_and_rel
 .Sh LIBRARY
 .Lb libprop
 .Sh SYNOPSIS
@@ -163,6 +164,9 @@
 .Ft bool
 .Fn prop_array_set_cstring_nocopy "prop_array_t dict" \
     "unsigned int indx" "const char *strp"
+.Ft bool
+.Fn prop_array_add_and_rel "prop_array_t dict" \
+    "prop_object_t obj"
 .Sh DESCRIPTION
 The
 .Nm prop_array_util
@@ -190,6 +194,11 @@
 See
 .Xr prop_string 3
 for more information.
+.Pp
+The
+.Fn prop_array_add_and_rel
+function adds the object to the end of the array and release it.
+The object is also released on failure.
 .Sh RETURN VALUES
 The
 .Nm prop_array_util
Index: common/lib/libprop/prop_array_util.c
===================================================================
RCS file: /cvsroot/src/common/lib/libprop/prop_array_util.c,v
retrieving revision 1.2
diff -u -r1.2 prop_array_util.c
--- common/lib/libprop/prop_array_util.c        11 Sep 2008 13:15:13 -0000      
1.2
+++ common/lib/libprop/prop_array_util.c        18 Mar 2011 15:58:46 -0000
@@ -238,3 +238,14 @@
 TEMPLATE(_nocopy,const)
 
 #undef TEMPLATE
+
+bool
+prop_array_add_and_rel(prop_array_t array, prop_object_t po)
+{
+       bool ret;
+       if (po == NULL)
+               return false;
+       ret = prop_array_add(array, po);
+       prop_object_release(po);
+       return ret;
+}
Index: common/lib/libprop/prop_dictionary_util.3
===================================================================
RCS file: /cvsroot/src/common/lib/libprop/prop_dictionary_util.3,v
retrieving revision 1.4
diff -u -r1.4 prop_dictionary_util.3
--- common/lib/libprop/prop_dictionary_util.3   2 Jun 2008 09:27:04 -0000       
1.4
+++ common/lib/libprop/prop_dictionary_util.3   18 Mar 2011 15:58:46 -0000
@@ -27,11 +27,12 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd October 25, 2006
+.Dd March 12, 2011
 .Dt PROP_DICTIONARY_UTIL 3
 .Os
 .Sh NAME
 .Nm prop_dictionary_util ,
+.Nm prop_dictionary_get_dict ,
 .Nm prop_dictionary_get_bool ,
 .Nm prop_dictionary_set_bool ,
 .Nm prop_dictionary_get_int8 ,
@@ -53,13 +54,17 @@
 .Nm prop_dictionary_get_cstring ,
 .Nm prop_dictionary_set_cstring ,
 .Nm prop_dictionary_get_cstring_nocopy ,
-.Nm prop_dictionary_set_cstring_nocopy
+.Nm prop_dictionary_set_cstring_nocopy,
+.Nm prop_dictionary_set_and_rel
 .Sh LIBRARY
 .Lb libprop
 .Sh SYNOPSIS
 .In prop/proplib.h
 .\"
 .Ft bool
+.Fn prop_dictionary_get_dict "prop_dictionary_t dict" "const char *key" \
+    "bool *dictp"
+.Ft bool
 .Fn prop_dictionary_get_bool "prop_dictionary_t dict" "const char *key" \
     "bool *valp"
 .Ft bool
@@ -131,6 +136,9 @@
 .Ft bool
 .Fn prop_dictionary_set_cstring_nocopy "prop_dictionary_t dict" \
     "const char *key" "const char *strp"
+.Ft bool
+.Fn prop_dictionary_set_and_rel "prop_dictionary_t dict" \
+    "const char *key" "prop_object_t obj"
 .Sh DESCRIPTION
 The
 .Nm prop_dictionary_util
@@ -158,6 +166,11 @@
 See
 .Xr prop_string 3
 for more information.
+.Pp
+The
+.Fn prop_dictionary_set_and_rel
+function adds the object to the dictionary and release it.
+The object is also released on failure.
 .Sh RETURN VALUES
 The
 .Nm prop_dictionary_util
Index: common/lib/libprop/prop_dictionary_util.c
===================================================================
RCS file: /cvsroot/src/common/lib/libprop/prop_dictionary_util.c,v
retrieving revision 1.3
diff -u -r1.3 prop_dictionary_util.c
--- common/lib/libprop/prop_dictionary_util.c   28 Apr 2008 20:22:53 -0000      
1.3
+++ common/lib/libprop/prop_dictionary_util.c   18 Mar 2011 15:58:46 -0000
@@ -42,6 +42,18 @@
 #include "prop_object_impl.h"  /* only to hide kernel vs. not-kernel */
 
 bool
+prop_dictionary_get_dict(prop_dictionary_t dict, const char *key, 
prop_dictionary_t *dp)
+{
+       prop_object_t o;
+       o = prop_dictionary_get(dict, key);
+       if (o == NULL || prop_object_type(o) != PROP_TYPE_DICTIONARY)
+               return false;
+       *dp = o;
+       return true;
+
+}
+
+bool
 prop_dictionary_get_bool(prop_dictionary_t dict,
                         const char *key,
                         bool *valp)
@@ -206,3 +218,15 @@
 TEMPLATE(_nocopy,const)
 
 #undef TEMPLATE
+
+bool
+prop_dictionary_set_and_rel(prop_dictionary_t dict, const char *key,
+    prop_object_t po)
+{
+       bool ret;
+       if (po == NULL)
+               return false;
+       ret = prop_dictionary_set(dict, key, po);
+       prop_object_release(po);
+       return ret;
+}
Index: distrib/sets/lists/base/ad.mips64eb
===================================================================
RCS file: /cvsroot/src/distrib/sets/lists/base/ad.mips64eb,v
retrieving revision 1.44
diff -u -r1.44 ad.mips64eb
--- distrib/sets/lists/base/ad.mips64eb 12 Mar 2011 19:52:45 -0000      1.44
+++ distrib/sets/lists/base/ad.mips64eb 18 Mar 2011 15:58:53 -0000
@@ -185,6 +185,8 @@
 ./usr/lib/64/libpthread_dbg.so.2.0             base-compat-shlib       
compat,pic
 ./usr/lib/64/libpuffs.so.2                     base-compat-shlib       
compat,pic
 ./usr/lib/64/libpuffs.so.2.0                   base-compat-shlib       
compat,pic
+./usr/lib/64/libquota.so.0                     base-compat-shlib       
compat,pic
+./usr/lib/64/libquota.so.0.0                   base-compat-shlib       
compat,pic
 ./usr/lib/64/libradius.so.4                    base-compat-shlib       
compat,pic
 ./usr/lib/64/libradius.so.4.0                  base-compat-shlib       
compat,pic
 ./usr/lib/64/libresolv.so.2                    base-compat-shlib       
compat,pic
@@ -452,6 +454,8 @@
 ./usr/lib/o32/libpthread_dbg.so.2.0            base-compat-shlib       
compat,pic
 ./usr/lib/o32/libpuffs.so.2                    base-compat-shlib       
compat,pic
 ./usr/lib/o32/libpuffs.so.2.0                  base-compat-shlib       
compat,pic
+./usr/lib/o32/libquota.so.0                    base-compat-shlib       
compat,pic
+./usr/lib/o32/libquota.so.0.0                  base-compat-shlib       
compat,pic
 ./usr/lib/o32/libradius.so.4                   base-compat-shlib       
compat,pic
 ./usr/lib/o32/libradius.so.4.0                 base-compat-shlib       
compat,pic
 ./usr/lib/o32/libresolv.so.2                   base-compat-shlib       
compat,pic
Index: distrib/sets/lists/base/ad.mips64el
===================================================================
RCS file: /cvsroot/src/distrib/sets/lists/base/ad.mips64el,v
retrieving revision 1.42
diff -u -r1.42 ad.mips64el
--- distrib/sets/lists/base/ad.mips64el 12 Mar 2011 19:52:45 -0000      1.42
+++ distrib/sets/lists/base/ad.mips64el 18 Mar 2011 15:58:54 -0000
@@ -185,6 +185,8 @@
 ./usr/lib/64/libpthread_dbg.so.2.0             base-compat-shlib       
compat,pic
 ./usr/lib/64/libpuffs.so.2                     base-compat-shlib       
compat,pic
 ./usr/lib/64/libpuffs.so.2.0                   base-compat-shlib       
compat,pic
+./usr/lib/64/libquota.so.0                     base-compat-shlib       
compat,pic
+./usr/lib/64/libquota.so.0.0                   base-compat-shlib       
compat,pic
 ./usr/lib/64/libradius.so.4                    base-compat-shlib       
compat,pic
 ./usr/lib/64/libradius.so.4.0                  base-compat-shlib       
compat,pic
 ./usr/lib/64/libresolv.so.2                    base-compat-shlib       
compat,pic
@@ -452,6 +454,8 @@
 ./usr/lib/o32/libpthread_dbg.so.2.0            base-compat-shlib       
compat,pic
 ./usr/lib/o32/libpuffs.so.2                    base-compat-shlib       
compat,pic
 ./usr/lib/o32/libpuffs.so.2.0                  base-compat-shlib       
compat,pic
+./usr/lib/o32/libquota.so.0                    base-compat-shlib       
compat,pic
+./usr/lib/o32/libquota.so.0.0                  base-compat-shlib       
compat,pic
 ./usr/lib/o32/libradius.so.4                   base-compat-shlib       
compat,pic
 ./usr/lib/o32/libradius.so.4.0                 base-compat-shlib       
compat,pic
 ./usr/lib/o32/libresolv.so.2                   base-compat-shlib       
compat,pic
Index: distrib/sets/lists/base/md.amd64
===================================================================
RCS file: /cvsroot/src/distrib/sets/lists/base/md.amd64,v
retrieving revision 1.117
diff -u -r1.117 md.amd64
--- distrib/sets/lists/base/md.amd64    12 Mar 2011 19:52:45 -0000      1.117
+++ distrib/sets/lists/base/md.amd64    18 Mar 2011 15:58:54 -0000
@@ -189,6 +189,8 @@
 ./usr/lib/i386/libpthread_dbg.so.2.0           base-compat-shlib       
compat,pic
 ./usr/lib/i386/libpuffs.so.2                   base-compat-shlib       
compat,pic
 ./usr/lib/i386/libpuffs.so.2.0                 base-compat-shlib       
compat,pic
+./usr/lib/i386/libquota.so.0                   base-compat-shlib       
compat,pic
+./usr/lib/i386/libquota.so.0.0                 base-compat-shlib       
compat,pic
 ./usr/lib/i386/libradius.so.4                  base-compat-shlib       
compat,pic
 ./usr/lib/i386/libradius.so.4.0                        base-compat-shlib       
compat,pic
 ./usr/lib/i386/librefuse.so.2                  base-compat-shlib       
compat,pic
Index: distrib/sets/lists/base/md.sparc64
===================================================================
RCS file: /cvsroot/src/distrib/sets/lists/base/md.sparc64,v
retrieving revision 1.110
diff -u -r1.110 md.sparc64
--- distrib/sets/lists/base/md.sparc64  12 Mar 2011 19:52:45 -0000      1.110
+++ distrib/sets/lists/base/md.sparc64  18 Mar 2011 15:58:54 -0000
@@ -186,6 +186,8 @@
 ./usr/lib/sparc/libpthread_dbg.so.2.0          base-compat-shlib       
compat,pic
 ./usr/lib/sparc/libpuffs.so.2                  base-compat-shlib       
compat,pic
 ./usr/lib/sparc/libpuffs.so.2.0                        base-compat-shlib       
compat,pic
+./usr/lib/sparc/libquota.so.0                  base-compat-shlib       
compat,pic
+./usr/lib/sparc/libquota.so.0.0                        base-compat-shlib       
compat,pic
 ./usr/lib/sparc/libradius.so.4                 base-compat-shlib       
compat,pic
 ./usr/lib/sparc/libradius.so.4.0               base-compat-shlib       
compat,pic
 ./usr/lib/sparc/librefuse.so.2                 base-compat-shlib       
compat,pic
Index: distrib/sets/lists/base/mi
===================================================================
RCS file: /cvsroot/src/distrib/sets/lists/base/mi,v
retrieving revision 1.926
diff -u -r1.926 mi
--- distrib/sets/lists/base/mi  17 Mar 2011 02:35:27 -0000      1.926
+++ distrib/sets/lists/base/mi  18 Mar 2011 15:58:54 -0000
@@ -846,6 +846,7 @@
 ./usr/include/pcap                             base-c-usr
 ./usr/include/prop                             base-c-usr
 ./usr/include/protocols                                base-c-usr
+./usr/include/quota                            base-c-usr
 ./usr/include/readline                         base-c-usr
 ./usr/include/rpc                              base-c-usr
 ./usr/include/rpcsvc                           base-c-usr
Index: distrib/sets/lists/base/shl.mi
===================================================================
RCS file: /cvsroot/src/distrib/sets/lists/base/shl.mi,v
retrieving revision 1.578
diff -u -r1.578 shl.mi
--- distrib/sets/lists/base/shl.mi      12 Mar 2011 19:52:45 -0000      1.578
+++ distrib/sets/lists/base/shl.mi      18 Mar 2011 15:58:54 -0000
@@ -363,6 +363,9 @@
 ./usr/lib/libpuffs.so                          base-puffs-shlib
 ./usr/lib/libpuffs.so.2                                base-puffs-shlib
 ./usr/lib/libpuffs.so.2.0                      base-puffs-shlib
+./usr/lib/libquota.so                          base-sys-shlib
+./usr/lib/libquota.so.0                                base-sys-shlib
+./usr/lib/libquota.so.0.0                      base-sys-shlib
 ./usr/lib/libradius.so                         base-net-shlib
 ./usr/lib/libradius.so.4                       base-net-shlib
 ./usr/lib/libradius.so.4.0                     base-net-shlib
Index: distrib/sets/lists/comp/ad.mips64eb
===================================================================
RCS file: /cvsroot/src/distrib/sets/lists/comp/ad.mips64eb,v
retrieving revision 1.25
diff -u -r1.25 ad.mips64eb
--- distrib/sets/lists/comp/ad.mips64eb 12 Mar 2011 19:52:46 -0000      1.25
+++ distrib/sets/lists/comp/ad.mips64eb 18 Mar 2011 15:58:54 -0000
@@ -459,6 +459,10 @@
 ./usr/lib/64/libpuffs.so                       base-sys-shlib          
compat,pic
 ./usr/lib/64/libpuffs_p.a                      comp-c-proflib          
compat,profile
 ./usr/lib/64/libpuffs_pic.a                    comp-c-piclib           
compat,pic
+./usr/lib/64/libquota.a                                comp-c-lib              
compat
+./usr/lib/64/libquota.so                       base-sys-shlib          
compat,pic
+./usr/lib/64/libquota_p.a                      comp-c-proflib          
compat,profile
+./usr/lib/64/libquota_pic.a                    comp-c-piclib           
compat,pic
 ./usr/lib/64/libradius.a                       comp-c-lib              compat
 ./usr/lib/64/libradius.so                      base-sys-shlib          
compat,pic
 ./usr/lib/64/libradius_p.a                     comp-c-proflib          
compat,profile
@@ -989,6 +993,10 @@
 ./usr/lib/o32/libpuffs.so                      base-sys-shlib          
compat,pic
 ./usr/lib/o32/libpuffs_p.a                     comp-c-proflib          
compat,profile
 ./usr/lib/o32/libpuffs_pic.a                   comp-c-piclib           
compat,pic
+./usr/lib/o32/libquota.a                       comp-c-lib              compat
+./usr/lib/o32/libquota.so                      base-sys-shlib          
compat,pic
+./usr/lib/o32/libquota_p.a                     comp-c-proflib          
compat,profile
+./usr/lib/o32/libquota_pic.a                   comp-c-piclib           
compat,pic
 ./usr/lib/o32/libradius.a                      comp-c-lib              compat
 ./usr/lib/o32/libradius.so                     base-sys-shlib          
compat,pic
 ./usr/lib/o32/libradius_p.a                    comp-c-proflib          
compat,profile
@@ -1217,6 +1225,7 @@
 ./usr/libdata/debug/usr/lib/64/libpthread.so.1.0.debug comp-sys-debug  
debug,compat
 ./usr/libdata/debug/usr/lib/64/libpthread_dbg.so.2.0.debug     comp-sys-debug  
debug,compat
 ./usr/libdata/debug/usr/lib/64/libpuffs.so.2.0.debug   comp-puffs-debug        
debug,compat
+./usr/libdata/debug/usr/lib/64/libquota.so.0.0.debug   comp-sys-debug  
debug,compat
 ./usr/libdata/debug/usr/lib/64/libradius.so.4.0.debug  comp-net-debug  
debug,compat
 ./usr/libdata/debug/usr/lib/64/librefuse.so.2.0.debug  comp-refuse-debug       
debug,compat
 ./usr/libdata/debug/usr/lib/64/libresolv.so.2.0.debug  comp-net-debug  
debug,compat
@@ -1409,6 +1418,7 @@
 ./usr/libdata/debug/usr/lib/o32/libpthread.so.1.0.debug        comp-sys-debug  
debug,compat
 ./usr/libdata/debug/usr/lib/o32/libpthread_dbg.so.2.0.debug    comp-sys-debug  
debug,compat
 ./usr/libdata/debug/usr/lib/o32/libpuffs.so.2.0.debug  comp-puffs-debug        
debug,compat
+./usr/libdata/debug/usr/lib/o32/libquota.so.0.0.debug  comp-sys-debug  
debug,compat
 ./usr/libdata/debug/usr/lib/o32/libradius.so.4.0.debug comp-net-debug  
debug,compat
 ./usr/libdata/debug/usr/lib/o32/librefuse.so.2.0.debug comp-refuse-debug       
debug,compat
 ./usr/libdata/debug/usr/lib/o32/libresolv.so.2.0.debug comp-net-debug  
debug,compat
Index: distrib/sets/lists/comp/ad.mips64el
===================================================================
RCS file: /cvsroot/src/distrib/sets/lists/comp/ad.mips64el,v
retrieving revision 1.25
diff -u -r1.25 ad.mips64el
--- distrib/sets/lists/comp/ad.mips64el 12 Mar 2011 19:52:46 -0000      1.25
+++ distrib/sets/lists/comp/ad.mips64el 18 Mar 2011 15:58:54 -0000
@@ -459,6 +459,10 @@
 ./usr/lib/64/libpuffs.so                       base-sys-shlib          
compat,pic
 ./usr/lib/64/libpuffs_p.a                      comp-c-proflib          
compat,profile
 ./usr/lib/64/libpuffs_pic.a                    comp-c-piclib           
compat,pic
+./usr/lib/64/libquota.a                                comp-c-lib              
compat
+./usr/lib/64/libquota.so                       base-sys-shlib          
compat,pic
+./usr/lib/64/libquota_p.a                      comp-c-proflib          
compat,profile
+./usr/lib/64/libquota_pic.a                    comp-c-piclib           
compat,pic
 ./usr/lib/64/libradius.a                       comp-c-lib              compat
 ./usr/lib/64/libradius.so                      base-sys-shlib          
compat,pic
 ./usr/lib/64/libradius_p.a                     comp-c-proflib          
compat,profile
@@ -989,6 +993,10 @@
 ./usr/lib/o32/libpuffs.so                      base-sys-shlib          
compat,pic
 ./usr/lib/o32/libpuffs_p.a                     comp-c-proflib          
compat,profile
 ./usr/lib/o32/libpuffs_pic.a                   comp-c-piclib           
compat,pic
+./usr/lib/o32/libquota.a                       comp-c-lib              compat
+./usr/lib/o32/libquota.so                      base-sys-shlib          
compat,pic
+./usr/lib/o32/libquota_p.a                     comp-c-proflib          
compat,profile
+./usr/lib/o32/libquota_pic.a                   comp-c-piclib           
compat,pic
 ./usr/lib/o32/libradius.a                      comp-c-lib              compat
 ./usr/lib/o32/libradius.so                     base-sys-shlib          
compat,pic
 ./usr/lib/o32/libradius_p.a                    comp-c-proflib          
compat,profile
@@ -1217,6 +1225,7 @@
 ./usr/libdata/debug/usr/lib/64/libpthread.so.1.0.debug comp-sys-debug  
debug,compat
 ./usr/libdata/debug/usr/lib/64/libpthread_dbg.so.2.0.debug     comp-sys-debug  
debug,compat
 ./usr/libdata/debug/usr/lib/64/libpuffs.so.2.0.debug   comp-puffs-debug        
debug,compat
+./usr/libdata/debug/usr/lib/64/libquota.so.0.0.debug   comp-sys-debug  
debug,compat
 ./usr/libdata/debug/usr/lib/64/libradius.so.4.0.debug  comp-net-debug  
debug,compat
 ./usr/libdata/debug/usr/lib/64/librefuse.so.2.0.debug  comp-refuse-debug       
debug,compat
 ./usr/libdata/debug/usr/lib/64/libresolv.so.2.0.debug  comp-net-debug  
debug,compat
@@ -1409,6 +1418,7 @@
 ./usr/libdata/debug/usr/lib/o32/libpthread.so.1.0.debug        comp-sys-debug  
debug,compat
 ./usr/libdata/debug/usr/lib/o32/libpthread_dbg.so.2.0.debug    comp-sys-debug  
debug,compat
 ./usr/libdata/debug/usr/lib/o32/libpuffs.so.2.0.debug  comp-puffs-debug        
debug,compat
+./usr/libdata/debug/usr/lib/o32/libquota.so.0.0.debug  comp-sys-debug  
debug,compat
 ./usr/libdata/debug/usr/lib/o32/libradius.so.4.0.debug comp-net-debug  
debug,compat
 ./usr/libdata/debug/usr/lib/o32/librefuse.so.2.0.debug comp-refuse-debug       
debug,compat
 ./usr/libdata/debug/usr/lib/o32/libresolv.so.2.0.debug comp-net-debug  
debug,compat
Index: distrib/sets/lists/comp/md.amd64
===================================================================
RCS file: /cvsroot/src/distrib/sets/lists/comp/md.amd64,v
retrieving revision 1.103
diff -u -r1.103 md.amd64
--- distrib/sets/lists/comp/md.amd64    12 Mar 2011 19:52:46 -0000      1.103
+++ distrib/sets/lists/comp/md.amd64    18 Mar 2011 15:58:54 -0000
@@ -735,6 +735,11 @@
 ./usr/lib/i386/libpuffs_g.a                    comp-c-proflib          
compat,debuglib
 ./usr/lib/i386/libpuffs_p.a                    comp-c-proflib          
compat,profile
 ./usr/lib/i386/libpuffs_pic.a                  comp-c-piclib           
compat,pic
+./usr/lib/i386/libquota.a                      comp-c-lib              compat
+./usr/lib/i386/libquota.so                     comp-sys-shlib          
compat,pic
+./usr/lib/i386/libquota_g.a                    comp-c-proflib          
compat,debuglib
+./usr/lib/i386/libquota_p.a                    comp-c-proflib          
compat,profile
+./usr/lib/i386/libquota_pic.a                  comp-c-proflib          
compat,profile
 ./usr/lib/i386/libradius.a                     comp-c-lib              compat
 ./usr/lib/i386/libradius.so                    comp-sys-shlib          
compat,pic
 ./usr/lib/i386/libradius_g.a                   comp-c-proflib          
compat,debuglib
@@ -992,6 +997,7 @@
 ./usr/libdata/debug/usr/lib/i386/libpthread.so.1.0.debug       
comp-compat-shlib       compat,pic,debug
 ./usr/libdata/debug/usr/lib/i386/libpthread_dbg.so.2.0.debug   
comp-compat-shlib       compat,pic,debug
 ./usr/libdata/debug/usr/lib/i386/libpuffs.so.2.0.debug comp-compat-shlib       
compat,pic,debug
+./usr/libdata/debug/usr/lib/i386/libquota.so.0.0.debug comp-compat-shlib       
compat,pic,debug
 ./usr/libdata/debug/usr/lib/i386/libradius.so.4.0.debug        
comp-compat-shlib       compat,pic,debug
 ./usr/libdata/debug/usr/lib/i386/librefuse.so.2.0.debug        
comp-compat-shlib       compat,pic,debug
 ./usr/libdata/debug/usr/lib/i386/libresolv.so.2.0.debug        
comp-compat-shlib       compat,pic,debug
Index: distrib/sets/lists/comp/md.sparc64
===================================================================
RCS file: /cvsroot/src/distrib/sets/lists/comp/md.sparc64,v
retrieving revision 1.89
diff -u -r1.89 md.sparc64
--- distrib/sets/lists/comp/md.sparc64  12 Mar 2011 19:52:46 -0000      1.89
+++ distrib/sets/lists/comp/md.sparc64  18 Mar 2011 15:58:54 -0000
@@ -530,6 +530,10 @@
 ./usr/lib/sparc/libpuffs.so                    base-sys-shlib          
compat,pic
 ./usr/lib/sparc/libpuffs_p.a                   comp-c-proflib          
compat,profile
 ./usr/lib/sparc/libpuffs_pic.a                 comp-c-piclib           
compat,pic
+./usr/lib/sparc/libquota.a                     comp-c-lib              compat
+./usr/lib/sparc/libquota.so                    base-sys-shlib          
compat,pic
+./usr/lib/sparc/libquota_p.a                   comp-c-proflib          
compat,profile
+./usr/lib/sparc/libquota_pic.a                 comp-c-piclib           
compat,pic
 ./usr/lib/sparc/libradius.a                    comp-c-lib              compat
 ./usr/lib/sparc/libradius.so                   base-sys-shlib          
compat,pic
 ./usr/lib/sparc/libradius_p.a                  comp-c-proflib          
compat,profile
@@ -752,6 +756,7 @@
 ./usr/libdata/debug/usr/lib/sparc/libpthread.so.1.0.debug              
comp-compat-shlib       compat,pic,debug
 ./usr/libdata/debug/usr/lib/sparc/libpthread_dbg.so.2.0.debug          
comp-compat-shlib       compat,pic,debug
 ./usr/libdata/debug/usr/lib/sparc/libpuffs.so.2.0.debug                        
comp-compat-shlib       compat,pic,debug
+./usr/libdata/debug/usr/lib/sparc/libquota.so.2.0.debug                        
comp-compat-shlib       compat,pic,debug
 ./usr/libdata/debug/usr/lib/sparc/libradius.so.4.0.debug               
comp-compat-shlib       compat,pic,debug
 ./usr/libdata/debug/usr/lib/sparc/librefuse.so.2.0.debug               
comp-compat-shlib       compat,pic,debug
 ./usr/libdata/debug/usr/lib/sparc/libresolv.so.2.0.debug               
comp-compat-shlib       compat,pic,debug
Index: distrib/sets/lists/comp/mi
===================================================================
RCS file: /cvsroot/src/distrib/sets/lists/comp/mi,v
retrieving revision 1.1600
diff -u -r1.1600 mi
--- distrib/sets/lists/comp/mi  17 Mar 2011 02:35:27 -0000      1.1600
+++ distrib/sets/lists/comp/mi  18 Mar 2011 15:58:54 -0000
@@ -1869,6 +1869,8 @@
 ./usr/include/puffs.h                          comp-puffs-include
 ./usr/include/puffsdump.h                      comp-puffs-include
 ./usr/include/pwd.h                            comp-c-include
+./usr/include/quota/quota.h                    comp-c-include
+./usr/include/quota/quotaprop.h                        comp-c-include
 ./usr/include/radlib.h                         comp-c-include
 ./usr/include/radlib_vs.h                      comp-c-include
 ./usr/include/randomid.h                       comp-c-include
@@ -2234,8 +2236,8 @@
 ./usr/include/ufs/ufs/extattr.h                        comp-c-include
 ./usr/include/ufs/ufs/inode.h                  comp-c-include
 ./usr/include/ufs/ufs/quota.h                  comp-c-include
-./usr/include/ufs/ufs/quota1.h                 comp-c-include
-./usr/include/ufs/ufs/quota2.h                 comp-c-include
+./usr/include/ufs/ufs/quota1.h                 comp-obsolete           obsolete
+./usr/include/ufs/ufs/quota2.h                 comp-obsolete           obsolete
 ./usr/include/ufs/ufs/ufs_bswap.h              comp-c-include
 ./usr/include/ufs/ufs/ufs_extern.h             comp-c-include
 ./usr/include/ufs/ufs/ufs_wapbl.h              comp-c-include
@@ -2623,6 +2625,9 @@
 ./usr/lib/libpuffs.a                           comp-puffs-lib
 ./usr/lib/libpuffs_g.a                         -unknown-               debuglib
 ./usr/lib/libpuffs_p.a                         comp-puffs-proflib      profile
+./usr/lib/libquota.a                           comp-c-lib
+./usr/lib/libquota_g.a                         -unknown-               debuglib
+./usr/lib/libquota_p.a                         comp-c-proflib          profile
 ./usr/lib/libradius.a                          comp-c-lib
 ./usr/lib/libradius_g.a                                -unknown-               
debuglib
 ./usr/lib/libradius_p.a                                comp-c-proflib          
profile
@@ -3960,6 +3965,7 @@
 ./usr/libdata/lint/llib-lpthread_dbg.ln                comp-c-lintlib          
lint
 ./usr/libdata/lint/llib-lpuffs.ln              comp-puffs-lintlib      lint
 ./usr/libdata/lint/llib-lradius.ln             comp-c-lintlib          lint
+./usr/libdata/lint/llib-lquota.ln              comp-c-lintlib          lint
 ./usr/libdata/lint/llib-lrefuse.ln             comp-refuse-lintlib     lint
 ./usr/libdata/lint/llib-lresolv.ln             comp-c-lintlib          lint
 ./usr/libdata/lint/llib-lrmt.ln                        comp-c-lintlib          
lint
Index: distrib/sets/lists/comp/shl.mi
===================================================================
RCS file: /cvsroot/src/distrib/sets/lists/comp/shl.mi,v
retrieving revision 1.163
diff -u -r1.163 shl.mi
--- distrib/sets/lists/comp/shl.mi      12 Mar 2011 19:52:47 -0000      1.163
+++ distrib/sets/lists/comp/shl.mi      18 Mar 2011 15:58:54 -0000
@@ -91,6 +91,7 @@
 ./usr/lib/libpthread_dbg_pic.a                 comp-c-piclib
 ./usr/lib/libpthread_pic.a                     comp-c-piclib
 ./usr/lib/libpuffs_pic.a                       comp-puffs-piclib
+./usr/lib/libquota_pic.a                       comp-c-piclib
 ./usr/lib/libradius_pic.a                      comp-c-piclib
 ./usr/lib/librefuse_pic.a                      comp-refuse-piclib
 ./usr/lib/libresolv_pic.a                      comp-c-piclib
@@ -288,6 +289,7 @@
 ./usr/libdata/debug/usr/lib/libpthread.so.1.0.debug    comp-sys-debug  debug
 ./usr/libdata/debug/usr/lib/libpthread_dbg.so.2.0.debug        comp-sys-debug  
debug
 ./usr/libdata/debug/usr/lib/libpuffs.so.2.0.debug      comp-puffs-debug        
debug
+./usr/libdata/debug/usr/lib/libquota.so.0.0.debug      comp-sys-debug  debug
 ./usr/libdata/debug/usr/lib/libradius.so.4.0.debug     comp-net-debug  debug
 ./usr/libdata/debug/usr/lib/librefuse.so.2.0.debug     comp-refuse-debug       
debug
 ./usr/libdata/debug/usr/lib/libresolv.so.2.0.debug     comp-net-debug  debug
Index: etc/mtree/NetBSD.dist.base
===================================================================
RCS file: /cvsroot/src/etc/mtree/NetBSD.dist.base,v
retrieving revision 1.78
diff -u -r1.78 NetBSD.dist.base
--- etc/mtree/NetBSD.dist.base  10 Mar 2011 13:16:58 -0000      1.78
+++ etc/mtree/NetBSD.dist.base  18 Mar 2011 15:58:57 -0000
@@ -164,6 +164,7 @@
 ./usr/include/pcap
 ./usr/include/prop
 ./usr/include/protocols
+./usr/include/quota
 ./usr/include/readline
 ./usr/include/rpc
 ./usr/include/rpcsvc
Index: include/Makefile
===================================================================
RCS file: /cvsroot/src/include/Makefile,v
retrieving revision 1.133
diff -u -r1.133 Makefile
--- include/Makefile    31 Jul 2010 21:47:53 -0000      1.133
+++ include/Makefile    18 Mar 2011 15:59:52 -0000
@@ -44,6 +44,7 @@
 
 SUBDIR=                rpc
 SUBDIR+=       ../common/include/prop
+SUBDIR+=       ../common/include/quota
 
 .include <bsd.prog.mk>
 .include <bsd.subdir.mk>
Index: lib/Makefile
===================================================================
RCS file: /cvsroot/src/lib/Makefile,v
retrieving revision 1.164
diff -u -r1.164 Makefile
--- lib/Makefile        12 Feb 2011 22:24:40 -0000      1.164
+++ lib/Makefile        18 Mar 2011 15:59:52 -0000
@@ -87,6 +87,7 @@
 SUBDIR+=       libcurses       # depends on libterminfo
 SUBDIR+=       libdm           # depends on libprop
 SUBDIR+=       libedit         # depends on libterminfo
+SUBDIR+=       libquota        # depends on libprop and librpcsvc
 SUBDIR+=       librefuse       # depends on libpuffs
 SUBDIR+=       librumpuser     # depends on libpthread
 
Index: lib/librumphijack/hijack.c
===================================================================
RCS file: /cvsroot/src/lib/librumphijack/hijack.c,v
retrieving revision 1.86
diff -u -r1.86 hijack.c
--- lib/librumphijack/hijack.c  14 Mar 2011 15:15:47 -0000      1.86
+++ lib/librumphijack/hijack.c  18 Mar 2011 15:59:56 -0000
@@ -97,7 +97,7 @@
        DUALCALL___SYSCTL,
        DUALCALL_GETVFSSTAT, DUALCALL_NFSSVC,
        DUALCALL_GETFH, DUALCALL_FHOPEN, DUALCALL_FHSTAT, DUALCALL_FHSTATVFS1,
-#if __NetBSD_Prereq__(5,99,48)
+#if __NetBSD_Prereq__(5,99,47)
        DUALCALL_QUOTACTL,
 #endif
        DUALCALL__NUM
@@ -247,7 +247,7 @@
        { DUALCALL_FHOPEN,      S(REALFHOPEN),RSYS_NAME(FHOPEN)         },
        { DUALCALL_FHSTAT,      S(REALFHSTAT),RSYS_NAME(FHSTAT)         },
        { DUALCALL_FHSTATVFS1,  S(REALFHSTATVFS1),RSYS_NAME(FHSTATVFS1) },
-#if __NetBSD_Prereq__(5,99,48)
+#if __NetBSD_Prereq__(5,99,47)
        { DUALCALL_QUOTACTL,    S(REALQUOTACTL),RSYS_NAME(QUOTACTL)     },
 #endif
 };
@@ -2197,7 +2197,7 @@
        (const char *, int),                                            \
        (path, flags))
 
-#if __NetBSD_Prereq__(5,99,48)
+#if __NetBSD_Prereq__(5,99,47)
 PATHCALL(int, REALQUOTACTL, DUALCALL_QUOTACTL,                         \
        (const char *path, struct plistref *p),                         \
        (const char *, struct plistref *),                              \
Index: libexec/rpc.rquotad/Makefile
===================================================================
RCS file: /cvsroot/src/libexec/rpc.rquotad/Makefile,v
retrieving revision 1.7
diff -u -r1.7 Makefile
--- libexec/rpc.rquotad/Makefile        6 Mar 2011 17:08:16 -0000       1.7
+++ libexec/rpc.rquotad/Makefile        18 Mar 2011 15:59:56 -0000
@@ -6,14 +6,7 @@
 MAN  = rpc.rquotad.8
 MLINKS = rpc.rquotad.8 rquotad.8
 
-CPPFLAGS+=-I${NETBSDSRCDIR}/sys -I${NETBSDSRCDIR}/usr.bin/quota
-DPADD= ${LIBRPCSVC} ${LIBPROP}
-LDADD= -lrpcsvc -lprop
-
-.PATH:  ${NETBSDSRCDIR}/usr.bin/quota
-SRCS+= getvfsquota.c
-.PATH:  ${NETBSDSRCDIR}/sys/ufs/ufs
-SRCS+= quota2_prop.c quota1_subr.c
-
+DPADD= ${LIBQUOTA} ${LIBRPCSVC} ${LIBPROP}
+LDADD= -lquota -lrpcsvc -lprop
 
 .include <bsd.prog.mk>
Index: libexec/rpc.rquotad/rquotad.c
===================================================================
RCS file: /cvsroot/src/libexec/rpc.rquotad/rquotad.c,v
retrieving revision 1.26
diff -u -r1.26 rquotad.c
--- libexec/rpc.rquotad/rquotad.c       12 Mar 2011 12:30:39 -0000      1.26
+++ libexec/rpc.rquotad/rquotad.c       18 Mar 2011 15:59:56 -0000
@@ -29,16 +29,12 @@
 
 #include <syslog.h>
 
-#include <ufs/ufs/quota2_prop.h>
-#include <ufs/ufs/quota1.h>
+#include <quota/quotaprop.h>
+#include <quota/quota.h>
 #include <rpc/rpc.h>
 #include <rpcsvc/rquota.h>
 #include <arpa/inet.h>
 
-#include <getvfsquota.h>
-
-const char *qfextension[MAXQUOTAS] = INITQFNAMES;
-
 void rquota_service(struct svc_req *request, SVCXPRT *transp);
 void ext_rquota_service(struct svc_req *request, SVCXPRT *transp);
 void sendquota(struct svc_req *request, int vers, SVCXPRT *transp);
@@ -47,6 +43,15 @@
 
 int from_inetd = 1;
 
+static uint32_t
+qlim2rqlim(uint64_t lim)
+{
+       if (lim == UQUAD_MAX)
+               return 0;
+       else
+               return (lim + 1);
+}
+
 void 
 cleanup(int dummy)
 {
@@ -166,10 +171,8 @@
        struct getquota_args getq_args;
        struct ext_getquota_args ext_getq_args;
        struct getquota_rslt getq_rslt;
-       struct quota2_entry q2e;
-       struct dqblk dqblk;
-       int type;
-       int8_t version;
+       struct ufs_quota_entry qe[QUOTA_NLIMITS];
+       const char *class;
        struct timeval timev;
 
        memset((char *)&getq_args, 0, sizeof(getq_args));
@@ -195,10 +198,10 @@
        }
        switch (ext_getq_args.gqa_type) {
        case RQUOTA_USRQUOTA:
-               type = USRQUOTA;
+               class = QUOTADICT_CLASS_USER;
                break;
        case RQUOTA_GRPQUOTA:
-               type = GRPQUOTA;
+               class = QUOTADICT_CLASS_GROUP;
                break;
        default:
                getq_rslt.status = Q_NOQUOTA;
@@ -207,31 +210,31 @@
        if (request->rq_cred.oa_flavor != AUTH_UNIX) {
                /* bad auth */
                getq_rslt.status = Q_EPERM;
-       } else if (!getvfsquota(ext_getq_args.gqa_pathp, &q2e, &version, 
ext_getq_args.gqa_id, ext_getq_args.gqa_type, 0, 0)) {
+       } else if (!getufsquota(ext_getq_args.gqa_pathp, qe,
+           ext_getq_args.gqa_id, class)) {
                /* failed, return noquota */
                getq_rslt.status = Q_NOQUOTA;
        } else {
-               q2e2dqblk(&q2e, &dqblk);
                gettimeofday(&timev, NULL);
                getq_rslt.status = Q_OK;
                getq_rslt.getquota_rslt_u.gqr_rquota.rq_active = TRUE;
                getq_rslt.getquota_rslt_u.gqr_rquota.rq_bsize = DEV_BSIZE;
                getq_rslt.getquota_rslt_u.gqr_rquota.rq_bhardlimit =
-                   dqblk.dqb_bhardlimit;
+                   qlim2rqlim(qe[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit);
                getq_rslt.getquota_rslt_u.gqr_rquota.rq_bsoftlimit =
-                   dqblk.dqb_bsoftlimit;
+                   qlim2rqlim(qe[QUOTA_LIMIT_BLOCK].ufsqe_softlimit);
                getq_rslt.getquota_rslt_u.gqr_rquota.rq_curblocks =
-                   dqblk.dqb_curblocks;
+                   qe[QUOTA_LIMIT_BLOCK].ufsqe_cur;
                getq_rslt.getquota_rslt_u.gqr_rquota.rq_fhardlimit =
-                   dqblk.dqb_ihardlimit;
+                   qlim2rqlim(qe[QUOTA_LIMIT_FILE].ufsqe_hardlimit);
                getq_rslt.getquota_rslt_u.gqr_rquota.rq_fsoftlimit =
-                   dqblk.dqb_isoftlimit;
+                   qlim2rqlim(qe[QUOTA_LIMIT_FILE].ufsqe_softlimit);
                getq_rslt.getquota_rslt_u.gqr_rquota.rq_curfiles =
-                   dqblk.dqb_curinodes;
+                   qe[QUOTA_LIMIT_FILE].ufsqe_cur;
                getq_rslt.getquota_rslt_u.gqr_rquota.rq_btimeleft =
-                   dqblk.dqb_btime;
+                   qe[QUOTA_LIMIT_BLOCK].ufsqe_time - timev.tv_sec;
                getq_rslt.getquota_rslt_u.gqr_rquota.rq_ftimeleft =
-                   dqblk.dqb_itime;
+                   qe[QUOTA_LIMIT_FILE].ufsqe_time - timev.tv_sec;
        }
 out:
        if (!svc_sendreply(transp, xdr_getquota_rslt, (char *)&getq_rslt))
Index: sbin/fsck_ffs/Makefile
===================================================================
RCS file: /cvsroot/src/sbin/fsck_ffs/Makefile,v
retrieving revision 1.41
diff -u -r1.41 Makefile
--- sbin/fsck_ffs/Makefile      6 Mar 2011 17:08:16 -0000       1.41
+++ sbin/fsck_ffs/Makefile      18 Mar 2011 15:59:58 -0000
@@ -13,7 +13,7 @@
 
 FSCK=  ${NETBSDSRCDIR}/sbin/fsck
 DUMP=  ${NETBSDSRCDIR}/sbin/dump
-CPPFLAGS+=-I${FSCK} -I${DUMP}
+CPPFLAGS+=-I${FSCK} -I${DUMP} -I${NETBSDSRCDIR}/sys
 .ifndef  SMALLPROG
 CPPFLAGS+=-DPROGRESS
 .endif
Index: sbin/fsdb/Makefile
===================================================================
RCS file: /cvsroot/src/sbin/fsdb/Makefile,v
retrieving revision 1.28
diff -u -r1.28 Makefile
--- sbin/fsdb/Makefile  6 Mar 2011 17:08:16 -0000       1.28
+++ sbin/fsdb/Makefile  18 Mar 2011 15:59:58 -0000
@@ -15,7 +15,7 @@
 
 FSCK=  ${NETBSDSRCDIR}/sbin/fsck
 FSCK_FFS=${NETBSDSRCDIR}/sbin/fsck_ffs
-CPPFLAGS+= -I${FSCK} -I${FSCK_FFS}
+CPPFLAGS+= -I${FSCK} -I${FSCK_FFS} -I${NETBSDSRCDIR}/sys
 .PATH: ${FSCK} ${FSCK_FFS} ${NETBSDSRCDIR}/sys/ufs/ffs
 
 SRCS+= vfs_wapbl.c wapbl.c
Index: sbin/newfs/Makefile
===================================================================
RCS file: /cvsroot/src/sbin/newfs/Makefile,v
retrieving revision 1.37
diff -u -r1.37 Makefile
--- sbin/newfs/Makefile 6 Mar 2011 17:08:16 -0000       1.37
+++ sbin/newfs/Makefile 18 Mar 2011 15:59:59 -0000
@@ -12,6 +12,7 @@
 FSCK=${NETBSDSRCDIR}/sbin/fsck
 MOUNT=${NETBSDSRCDIR}/sbin/mount
 CPPFLAGS+=-DMFS -I${.CURDIR} -I${DISKLABEL} -I${FSCK} -I${MOUNT}
+CPPFLAGS+=-I${NETBSDSRCDIR}/sys
 CPPFLAGS+=-DGARBAGE
 
 DPADD+= ${LIBUTIL}
Index: sbin/tunefs/Makefile
===================================================================
RCS file: /cvsroot/src/sbin/tunefs/Makefile,v
retrieving revision 1.14
diff -u -r1.14 Makefile
--- sbin/tunefs/Makefile        27 Jun 2005 01:00:07 -0000      1.14
+++ sbin/tunefs/Makefile        18 Mar 2011 15:59:59 -0000
@@ -6,6 +6,7 @@
 PROG=  tunefs
 MAN=   tunefs.8
 SRCS=  tunefs.c ffs_bswap.c
+CPPFLAGS+=-I${NETBSDSRCDIR}/sys
 LDADD+=-lutil
 
 .PATH:  ${NETBSDSRCDIR}/sys/ufs/ffs
Index: share/mk/bsd.README
===================================================================
RCS file: /cvsroot/src/share/mk/bsd.README,v
retrieving revision 1.279
diff -u -r1.279 bsd.README
--- share/mk/bsd.README 20 Feb 2011 20:16:01 -0000      1.279
+++ share/mk/bsd.README 18 Mar 2011 16:00:02 -0000
@@ -1362,6 +1362,7 @@
                LIBPCI?=        ${DESTDIR}/usr/lib/libpci.a
                LIBPMC?=        ${DESTDIR}/usr/lib/libpmc.a
                LIBPOSIX?=      ${DESTDIR}/usr/lib/libposix.a
+               LIBQUOTA?=      ${DESTDIR}/usr/lib/libquota.a
                LIBPTHREAD?=    ${DESTDIR}/usr/lib/libpthread.a
                LIBPTHREAD_DBG?=${DESTDIR}/usr/lib/libpthread_dbg.a
                LIBRADIUS?=     ${DESTDIR}/usr/lib/libradius.a
Index: share/mk/bsd.hostprog.mk
===================================================================
RCS file: /cvsroot/src/share/mk/bsd.hostprog.mk,v
retrieving revision 1.61
diff -u -r1.61 bsd.hostprog.mk
--- share/mk/bsd.hostprog.mk    20 Feb 2011 20:16:01 -0000      1.61
+++ share/mk/bsd.hostprog.mk    18 Mar 2011 16:00:02 -0000
@@ -44,6 +44,7 @@
 LIBPLOT?=      /usr/lib/libplot.a
 LIBPOSIX?=     /usr/lib/libposix.a
 LIBPUFFS?=     /usr/lib/libpuffs.a
+LIBQUOTA?=     /usr/lib/libquota.a
 LIBRESOLV?=    /usr/lib/libresolv.a
 LIBRPCSVC?=    /usr/lib/librpcsvc.a
 LIBRUMP?=      /usr/lib/librump.a
Index: sys/compat/common/vfs_syscalls_50.c
===================================================================
RCS file: /cvsroot/src/sys/compat/common/vfs_syscalls_50.c,v
retrieving revision 1.7
diff -u -r1.7 vfs_syscalls_50.c
--- sys/compat/common/vfs_syscalls_50.c 6 Mar 2011 17:08:33 -0000       1.7
+++ sys/compat/common/vfs_syscalls_50.c 18 Mar 2011 16:00:20 -0000
@@ -314,7 +314,7 @@
 }
 
 #include <ufs/ufs/quota1.h>
-#include <ufs/ufs/quota2_prop.h>
+#include <quota/quotaprop.h>
 
 /* ARGSUSED */
 int   
@@ -335,8 +335,11 @@
        prop_array_t cmds, datas;
        char *bufpath;
        struct dqblk dqblk;
-       struct quota2_entry q2e;
-       static const char *quotatypes[MAXQUOTAS] = INITQFNAMES;
+       struct ufs_quota_entry qe[QUOTA_NLIMITS];
+       uint64_t *values[QUOTA_NLIMITS];
+
+       values[QUOTA_LIMIT_BLOCK] = &qe[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit;
+       values[QUOTA_LIMIT_FILE] = &qe[QUOTA_LIMIT_FILE].ufsqe_hardlimit;
 
        error = namei_simple_user(SCARG(uap, path),
                                NSM_FOLLOW_TRYEMULROOT, &vp);
@@ -373,14 +376,16 @@
                if (!prop_array_add_and_rel(datas, data))
                        goto out_datas;
                if (!quota2_prop_add_command(cmds, "quotaon",
-                   quotatypes[q1cmd & SUBCMDMASK], datas))
+                   ufs_quota_class_names[qtype2ufsclass(q1cmd & SUBCMDMASK)],
+                   datas))
                        goto out_cmds;
                goto do_quotaonoff;
 
        case Q_QUOTAOFF:
                error = ENOMEM;
                if (!quota2_prop_add_command(cmds, "quotaoff",
-                   quotatypes[q1cmd & SUBCMDMASK], datas))
+                   ufs_quota_class_names[qtype2ufsclass(q1cmd & SUBCMDMASK)],
+                   datas))
                        goto out_cmds;
 do_quotaonoff:
                if (!prop_dictionary_set_and_rel(dict, "commands", cmds))
@@ -412,7 +417,8 @@
                if (!prop_array_add_and_rel(datas, data))
                        goto out_datas;
                if (!quota2_prop_add_command(cmds, "get",
-                   quotatypes[q1cmd & SUBCMDMASK], datas))
+                   ufs_quota_class_names[qtype2ufsclass(q1cmd & SUBCMDMASK)],
+                   datas))
                        goto out_cmds;
                if (!prop_dictionary_set_and_rel(dict, "commands", cmds))
                        goto out_dict;
@@ -440,10 +446,12 @@
                data = prop_array_get(datas, 0);
                if (data == NULL)
                        goto out_dict;
-               error = quota2_dict_get_q2e_usage(data, &q2e);
+               error = proptoquota64(data, values,
+                   ufs_quota_entry_names, UFS_QUOTA_NENTRIES,
+                   ufs_quota_limit_names, QUOTA_NLIMITS);
                if (error)
                        goto out_dict;
-               q2e2dqblk(&q2e, &dqblk);
+               ufsqe2dqblk(qe, &dqblk);
                error = copyout(&dqblk, SCARG(uap, arg), sizeof(dqblk));
                goto out_dict;
                
@@ -451,17 +459,19 @@
                error = copyin(SCARG(uap, arg), &dqblk, sizeof(dqblk));
                if (error)
                        goto out_datas;
-               dqblk2q2e(&dqblk, &q2e);
-               q2e.q2e_uid = SCARG(uap, uid);
+               dqblk2ufsqe(&dqblk, qe);
 
                error = ENOMEM;
-               data = q2etoprop(&q2e, 0);
+               data = quota64toprop(SCARG(uap, uid), 0, values,
+                   ufs_quota_entry_names, UFS_QUOTA_NENTRIES,
+                   ufs_quota_limit_names, QUOTA_NLIMITS);
                if (data == NULL)
                        goto out_data;
                if (!prop_array_add_and_rel(datas, data))
                        goto out_datas;
                if (!quota2_prop_add_command(cmds, "set",
-                   quotatypes[q1cmd & SUBCMDMASK], datas))
+                   ufs_quota_class_names[qtype2ufsclass(q1cmd & SUBCMDMASK)],
+                   datas))
                        goto out_cmds;
                if (!prop_dictionary_set_and_rel(dict, "commands", cmds))
                        goto out_dict;
@@ -489,7 +499,8 @@
                 */
                error = ENOMEM;
                if (!quota2_prop_add_command(cmds, "get version",
-                   quotatypes[q1cmd & SUBCMDMASK], datas))
+                   ufs_quota_class_names[qtype2ufsclass(q1cmd & SUBCMDMASK)],
+                   datas))
                        goto out_cmds;
                if (!prop_dictionary_set_and_rel(dict, "commands", cmds))
                        goto out_dict;
Index: sys/lib/libkern/Makefile.libkern
===================================================================
RCS file: /cvsroot/src/sys/lib/libkern/Makefile.libkern,v
retrieving revision 1.12
diff -u -r1.12 Makefile.libkern
--- sys/lib/libkern/Makefile.libkern    26 Feb 2011 18:17:55 -0000      1.12
+++ sys/lib/libkern/Makefile.libkern    18 Mar 2011 16:00:24 -0000
@@ -32,6 +32,7 @@
 .include "${.PARSEDIR}/../../../common/lib/libc/Makefile.inc"
 .include "${.PARSEDIR}/../../../common/lib/libutil/Makefile.inc"
 .include "${.PARSEDIR}/../../../common/lib/libprop/Makefile.inc"
+.include "${.PARSEDIR}/../../../common/lib/libquota/Makefile.inc"
 
 CPPFLAGS+=     -I${KERNDIR}/../../../common/include
 
Index: sys/rump/fs/lib/libffs/Makefile
===================================================================
RCS file: /cvsroot/src/sys/rump/fs/lib/libffs/Makefile,v
retrieving revision 1.13
diff -u -r1.13 Makefile
--- sys/rump/fs/lib/libffs/Makefile     6 Mar 2011 17:08:37 -0000       1.13
+++ sys/rump/fs/lib/libffs/Makefile     18 Mar 2011 16:00:28 -0000
@@ -11,7 +11,7 @@
 
 SRCS+= ufs_bmap.c ufs_dirhash.c ufs_extattr.c ufs_ihash.c ufs_inode.c  \
        ufs_lookup.c ufs_vfsops.c ufs_vnops.c ufs_wapbl.c \
-       ufs_quota.c ufs_quota2.c quota2_subr.c
+       ufs_quota.c ufs_quota2.c quota2_subr.c 
 
 CPPFLAGS+=     -DFFS_EI -DUFS_DIRHASH -DWAPBL -DAPPLE_UFS -DUFS_EXTATTR \
                -DQUOTA2
Index: sys/rump/librump/rumpvfs/Makefile.rumpvfs
===================================================================
RCS file: /cvsroot/src/sys/rump/librump/rumpvfs/Makefile.rumpvfs,v
retrieving revision 1.29
diff -u -r1.29 Makefile.rumpvfs
--- sys/rump/librump/rumpvfs/Makefile.rumpvfs   6 Mar 2011 17:08:37 -0000       
1.29
+++ sys/rump/librump/rumpvfs/Makefile.rumpvfs   18 Mar 2011 16:00:29 -0000
@@ -51,7 +51,7 @@
 SRCS+= mfs_miniroot.c
 
 #quota2 plists
-SRCS+= quota1_subr.c quota2_prop.c 
+SRCS+= quota1_subr.c
 
 # dev
 # firmload is technically part of rumpdev, but it's pure vfs in nature.
Index: sys/sys/quota.h
===================================================================
RCS file: /cvsroot/src/sys/sys/quota.h,v
retrieving revision 1.2
diff -u -r1.2 quota.h
--- sys/sys/quota.h     6 Mar 2011 17:08:38 -0000       1.2
+++ sys/sys/quota.h     18 Mar 2011 16:00:29 -0000
@@ -30,9 +30,25 @@
 #ifndef _SYS_QUOTA_H_
 #define _SYS_QUOTA_H_
 
-#ifndef _KERNEL
+#if !defined(_KERNEL) && !defined(_STANDALONE)
 __BEGIN_DECLS
 int quotactl(const char *, struct plistref *) __RENAME(__quotactl50);
 __END_DECLS
 #endif
+
+/* strings used in dictionary for the different quota class */
+#define QUOTADICT_CLASS_USER "user"
+#define QUOTADICT_CLASS_GROUP "group"
+
+/* strings used in dictionary for the different limit types */
+#define QUOTADICT_LTYPE_BLOCK "block"
+#define QUOTADICT_LTYPE_FILE "file"
+
+/* strings used in dictionary for the different limit and usage values */
+#define QUOTADICT_LIMIT_SOFT "soft"
+#define QUOTADICT_LIMIT_HARD "hard"
+#define QUOTADICT_LIMIT_GTIME "grace time"
+#define QUOTADICT_LIMIT_USAGE "usage"
+#define QUOTADICT_LIMIT_ETIME "expire time"
+
 #endif /* _SYS_QUOTA_H_ */
Index: sys/ufs/files.ufs
===================================================================
RCS file: /cvsroot/src/sys/ufs/files.ufs,v
retrieving revision 1.25
diff -u -r1.25 files.ufs
--- sys/ufs/files.ufs   6 Mar 2011 17:08:38 -0000       1.25
+++ sys/ufs/files.ufs   18 Mar 2011 16:00:29 -0000
@@ -64,7 +64,6 @@
 file   ufs/ufs/ufs_quota2.c            quota2 & (ffs | lfs | mfs | ext2fs)
 file   ufs/ufs/quota1_subr.c
 file   ufs/ufs/quota2_subr.c           quota2 & (ffs | lfs | mfs | ext2fs)
-file   ufs/ufs/quota2_prop.c
 file   ufs/ufs/ufs_vfsops.c            ffs | lfs | mfs | ext2fs
 file   ufs/ufs/ufs_vnops.c             ffs | lfs | mfs | ext2fs
 file   ufs/ufs/ufs_wapbl.c             ffs & wapbl
Index: sys/ufs/ufs/Makefile
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/Makefile,v
retrieving revision 1.7
diff -u -r1.7 Makefile
--- sys/ufs/ufs/Makefile        6 Mar 2011 17:08:39 -0000       1.7
+++ sys/ufs/ufs/Makefile        18 Mar 2011 16:00:30 -0000
@@ -2,7 +2,7 @@
 
 INCSDIR= /usr/include/ufs/ufs
 
-INCS=  dinode.h dir.h extattr.h inode.h quota.h quota1.h quota2.h \
+INCS=  dinode.h dir.h extattr.h inode.h quota.h \
        ufs_bswap.h ufs_extern.h ufs_wapbl.h ufsmount.h
 
 .include <bsd.kinc.mk>
Index: sys/ufs/ufs/quota.h
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/quota.h,v
retrieving revision 1.26
diff -u -r1.26 quota.h
--- sys/ufs/ufs/quota.h 6 Mar 2011 17:08:39 -0000       1.26
+++ sys/ufs/ufs/quota.h 18 Mar 2011 16:00:30 -0000
@@ -36,6 +36,7 @@
 
 #ifndef        _UFS_UFS_QUOTA_H_
 #define        _UFS_UFS_QUOTA_H_
+#include <quota/quotaprop.h>
 
 /*
  * These definitions are common to the original disk quota implementation
@@ -53,22 +54,32 @@
 #define        USRQUOTA        0       /* element used for user quotas */
 #define        GRPQUOTA        1       /* element used for group quotas */
 
-/*
- * Definitions for the default names of the quotas files/quota types.
- */
-#define INITQFNAMES { \
-       "user",         /* USRQUOTA */ \
-       "group",        /* GRPQUOTA */ \
-}
-
-/* definition of limits types for each quota */
-#define QL_BLOCK 0
-#define QL_FILE  1
-#define N_QL     2
-
-#define INITQLNAMES  {"block", "file", "undefined" }
 
+__inline static int __unused
+ufsclass2qtype(int class)
+{
+       switch(class) {
+       case QUOTA_CLASS_USER:
+               return USRQUOTA;
+       case QUOTA_CLASS_GROUP:
+               return GRPQUOTA;
+       default:
+               return -1;
+       }
+}
 
+static __inline int __unused
+qtype2ufsclass(int type)
+{
+       switch(type) {
+       case USRQUOTA:
+               return QUOTA_CLASS_USER;
+       case GRPQUOTA:
+               return QUOTA_CLASS_GROUP;
+       default:
+               return -1;
+       }
+}
 
 #ifdef _KERNEL
 
Index: sys/ufs/ufs/quota1.h
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/quota1.h,v
retrieving revision 1.2
diff -u -r1.2 quota1.h
--- sys/ufs/ufs/quota1.h        6 Mar 2011 17:08:39 -0000       1.2
+++ sys/ufs/ufs/quota1.h        18 Mar 2011 16:00:30 -0000
@@ -43,6 +43,15 @@
  * is deprecated. the newer implementation is defined in quota2.h
  * and friends
  */
+
+/*
+ * Definitions for the default names of the quotas files/quota types.
+ */
+#define INITQFNAMES { \
+       "user",         /* USRQUOTA */ \
+       "group",        /* GRPQUOTA */ \
+}
+
 /*
  * Definitions for disk quotas imposed on the average user
  * (big brother finally hits UNIX).
@@ -94,7 +103,6 @@
 
 /* quota1_subr.c */
 struct quota2_entry;
-void dqblk2q2e(const struct dqblk *, struct quota2_entry *);
-void q2e2dqblk(const struct quota2_entry *, struct dqblk *);
-
+void dqblk2ufsqe(const struct dqblk *, struct ufs_quota_entry *);
+void ufsqe2dqblk(const struct ufs_quota_entry *, struct dqblk *);
 #endif /* !_UFS_UFS_QUOTA1_H_ */
Index: sys/ufs/ufs/quota1_subr.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/quota1_subr.c,v
retrieving revision 1.2
diff -u -r1.2 quota1_subr.c
--- sys/ufs/ufs/quota1_subr.c   6 Mar 2011 17:08:39 -0000       1.2
+++ sys/ufs/ufs/quota1_subr.c   18 Mar 2011 16:00:30 -0000
@@ -33,7 +33,7 @@
 #include <sys/types.h>
 #include <machine/limits.h>
 
-#include <ufs/ufs/quota2.h>
+#include <quota/quotaprop.h>
 #include <ufs/ufs/quota1.h>
 
 static uint64_t
@@ -55,37 +55,38 @@
 }
 
 void
-dqblk2q2e(const struct dqblk *dqblk, struct quota2_entry *q2e)
+dqblk2ufsqe(const struct dqblk *dqblk, struct ufs_quota_entry *qe)
 {
-       q2e->q2e_val[QL_BLOCK].q2v_hardlimit =
+       qe[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit =
            dqblk2q2e_limit(dqblk->dqb_bhardlimit);
-       q2e->q2e_val[QL_BLOCK].q2v_softlimit =
+       qe[QUOTA_LIMIT_BLOCK].ufsqe_softlimit =
            dqblk2q2e_limit(dqblk->dqb_bsoftlimit);
-       q2e->q2e_val[QL_BLOCK].q2v_cur       = dqblk->dqb_curblocks;
-       q2e->q2e_val[QL_BLOCK].q2v_time      = dqblk->dqb_btime;
+       qe[QUOTA_LIMIT_BLOCK].ufsqe_cur       = dqblk->dqb_curblocks;
+       qe[QUOTA_LIMIT_BLOCK].ufsqe_time      = dqblk->dqb_btime;
 
-       q2e->q2e_val[QL_FILE].q2v_hardlimit =
+       qe[QUOTA_LIMIT_FILE].ufsqe_hardlimit =
            dqblk2q2e_limit(dqblk->dqb_ihardlimit);
-       q2e->q2e_val[QL_FILE].q2v_softlimit =
+       qe[QUOTA_LIMIT_FILE].ufsqe_softlimit =
            dqblk2q2e_limit(dqblk->dqb_isoftlimit);
-       q2e->q2e_val[QL_FILE].q2v_cur       = dqblk->dqb_curinodes;
-       q2e->q2e_val[QL_FILE].q2v_time      = dqblk->dqb_itime;
+       qe[QUOTA_LIMIT_FILE].ufsqe_cur       = dqblk->dqb_curinodes;
+       qe[QUOTA_LIMIT_FILE].ufsqe_time      = dqblk->dqb_itime;
 }
 
 void
-q2e2dqblk(const struct quota2_entry *q2e, struct dqblk *dqblk)
+ufsqe2dqblk(const struct ufs_quota_entry *qe, struct dqblk *dqblk)
 {
        dqblk->dqb_bhardlimit =
-           q2e2dqblk_limit(q2e->q2e_val[QL_BLOCK].q2v_hardlimit);
+           q2e2dqblk_limit(qe[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit);
        dqblk->dqb_bsoftlimit =
-           q2e2dqblk_limit(q2e->q2e_val[QL_BLOCK].q2v_softlimit);
-       dqblk->dqb_curblocks  = q2e->q2e_val[QL_BLOCK].q2v_cur;
-       dqblk->dqb_btime      = q2e->q2e_val[QL_BLOCK].q2v_time;
+           q2e2dqblk_limit(qe[QUOTA_LIMIT_BLOCK].ufsqe_softlimit);
+       dqblk->dqb_curblocks  = qe[QUOTA_LIMIT_BLOCK].ufsqe_cur;
+       dqblk->dqb_btime      = qe[QUOTA_LIMIT_BLOCK].ufsqe_time;
 
        dqblk->dqb_ihardlimit =
-           q2e2dqblk_limit(q2e->q2e_val[QL_FILE].q2v_hardlimit);
+           q2e2dqblk_limit(qe[QUOTA_LIMIT_FILE].ufsqe_hardlimit);
        dqblk->dqb_isoftlimit =
-           q2e2dqblk_limit(q2e->q2e_val[QL_FILE].q2v_softlimit);
-       dqblk->dqb_curinodes  = q2e->q2e_val[QL_FILE].q2v_cur;
-       dqblk->dqb_itime      = q2e->q2e_val[QL_FILE].q2v_time;
+           q2e2dqblk_limit(qe[QUOTA_LIMIT_FILE].ufsqe_softlimit);
+       dqblk->dqb_curinodes  = qe[QUOTA_LIMIT_FILE].ufsqe_cur;
+       dqblk->dqb_itime      = qe[QUOTA_LIMIT_FILE].ufsqe_time;
 }
+
Index: sys/ufs/ufs/quota2.h
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/quota2.h,v
retrieving revision 1.3
diff -u -r1.3 quota2.h
--- sys/ufs/ufs/quota2.h        9 Mar 2011 18:12:04 -0000       1.3
+++ sys/ufs/ufs/quota2.h        18 Mar 2011 16:00:30 -0000
@@ -30,6 +30,7 @@
 #ifndef _UFS_UFS_QUOTA2_H_
 #define _UFS_UFS_QUOTA2_H_
 #include <ufs/ufs/quota.h>
+#include <quota/quota.h>
 
 
 /* New disk quota implementation. In this implementation, the quota datas
@@ -56,12 +57,34 @@
        int64_t q2v_grace; /* allowed time for softlimit overflow */
 };
 
+/* NAMES for the above in the plist */
+#define INITQVNAMES_ALL { \
+    QUOTADICT_LIMIT_HARD, \
+    QUOTADICT_LIMIT_SOFT, \
+    QUOTADICT_LIMIT_USAGE, \
+    QUOTADICT_LIMIT_ETIME, \
+    QUOTADICT_LIMIT_GTIME \
+    }
+#define INITQVNAMES_LIMITSONLY { \
+    QUOTADICT_LIMIT_HARD, \
+    QUOTADICT_LIMIT_SOFT, \
+    NULL, \
+    NULL, \
+    QUOTADICT_LIMIT_GTIME \
+    }
+
+#define N_QV 5
 /*
  * On-disk description of a user or group quota
  * These entries are keept as linked list, either in one of the hash HEAD,
  * or in the free list.
  */
 
+#define N_QL 2
+#define QL_BLOCK 0
+#define QL_FILE 1
+#define INITQLNAMES {QUOTADICT_LTYPE_BLOCK, QUOTADICT_LTYPE_FILE}
+
 struct quota2_entry {
        /* block & inode limits and status */
        struct quota2_val q2e_val[N_QL];
@@ -101,15 +124,10 @@
 void quota2_ufs_rwq2v(const struct quota2_val *, struct quota2_val *, int);
 void quota2_ufs_rwq2e(const struct quota2_entry *, struct quota2_entry *, int);
 
-int quota2_check_limit(struct quota2_val *, uint64_t, time_t);
-#define QL_S_ALLOW_OK  0x00 /* below soft limit */
-#define QL_S_ALLOW_SOFT        0x01 /* over soft limit */
-#define QL_S_DENY_GRACE        0x02 /* over soft limit, grace time expired */
-#define QL_S_DENY_HARD 0x03 /* over hard limit */
-
-#define QL_F_CROSS     0x80 /* crossing soft limit */
-
-#define QL_STATUS(x)   ((x) & 0x0f)
-#define QL_FLAGS(x)    ((x) & 0xf0)
-
+__inline static int __unused
+quota2_check_limit(struct quota2_val *q2v, uint64_t change, time_t now)
+{
+       return quota_check_limit(q2v->q2v_cur, change, q2v->q2v_softlimit,
+           q2v->q2v_hardlimit, q2v->q2v_time, now);
+}
 #endif /*  _UFS_UFS_QUOTA2_H_ */
Index: sys/ufs/ufs/quota2_prop.c
===================================================================
RCS file: sys/ufs/ufs/quota2_prop.c
diff -N sys/ufs/ufs/quota2_prop.c
--- sys/ufs/ufs/quota2_prop.c   6 Mar 2011 17:08:39 -0000       1.2
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,275 +0,0 @@
-/* $NetBSD: quota2_prop.c,v 1.2 2011/03/06 17:08:39 bouyer Exp $ */
-/*-
-  * Copyright (c) 2010 Manuel Bouyer
-  * All rights reserved.
-  * This software is distributed under the following condiions
-  * compliant with the NetBSD foundation policy.
-  *
-  * Redistribution and use in source and binary forms, with or without
-  * modification, are permitted provided that the following conditions
-  * are met:
-  * 1. Redistributions of source code must retain the above copyright
-  *    notice, this list of conditions and the following disclaimer.
-  * 2. Redistributions in binary form must reproduce the above copyright
-  *    notice, this list of conditions and the following disclaimer in the
-  *    documentation and/or other materials provided with the distribution.
-  *
-  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
-  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
-  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-  * POSSIBILITY OF SUCH DAMAGE.
-  */
-
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/inttypes.h>
-#include <sys/errno.h>
-
-#include <ufs/ufs/quota2_prop.h>
-
-const char *quota2_valnames[] = INITQLNAMES;
-
-prop_dictionary_t
-prop_dictionary_get_dict(prop_dictionary_t dict, const char *key)
-{
-       prop_object_t o;
-       o = prop_dictionary_get(dict, key);
-       if (o == NULL || prop_object_type(o) != PROP_TYPE_DICTIONARY)
-               return NULL;
-       return o;
-
-}
-
-int
-quota2_dict_get_q2v_limits(prop_dictionary_t dict, struct quota2_val *q2v,
-    bool update)
-{
-       uint64_t vu;
-       int64_t v;
-       if (!prop_dictionary_get_uint64(dict, "soft", &vu)) {
-               if (!update)
-                       return EINVAL;
-       } else
-               q2v->q2v_softlimit = vu;
-       if (!prop_dictionary_get_uint64(dict, "hard", &vu)) {
-               if (!update)
-                       return EINVAL;
-       } else
-               q2v->q2v_hardlimit = vu;
-       if (!prop_dictionary_get_int64(dict, "grace time", &v)) {
-               if (!update)
-                       return EINVAL;
-       } else
-               q2v->q2v_grace = v;
-       return 0;
-}
-
-int
-quota2_dict_update_q2e_limits(prop_dictionary_t data, struct quota2_entry *q2e)
-{
-       int i, error;
-       prop_dictionary_t val;
-       for (i = 0; i < N_QL; i++) {
-               val = prop_dictionary_get_dict(data, quota2_valnames[i]);
-               if (val == NULL)
-                       continue;
-               error = quota2_dict_get_q2v_limits(val, &q2e->q2e_val[i], 1);
-               if (error)
-                       return error;
-       }
-       return 0;
-}
-
-int
-quota2_dict_get_q2v_usage(prop_dictionary_t dict, struct quota2_val *q2v)
-{
-       uint64_t vu;
-       int64_t v;
-       int err;
-
-       err = quota2_dict_get_q2v_limits(dict, q2v, false);
-       if (err)
-               return err;
-       if (!prop_dictionary_get_uint64(dict, "usage", &vu))
-               return EINVAL;
-       q2v->q2v_cur = vu;
-       if (!prop_dictionary_get_int64(dict, "expire time", &v))
-               return EINVAL;
-       q2v->q2v_time = v;
-       return 0;
-}
-
-int
-quota2_dict_get_q2e_usage(prop_dictionary_t data, struct quota2_entry *q2e)
-{
-       int i, error;
-       prop_dictionary_t val;
-       for (i = 0; i < N_QL; i++) {
-               val = prop_dictionary_get_dict(data, quota2_valnames[i]);
-               if (val == NULL)
-                       return EINVAL;
-               error = quota2_dict_get_q2v_usage(val, &q2e->q2e_val[i]);
-               if (error)
-                       return error;
-       }
-       return 0;
-}
-
-int
-quota2_get_cmds(prop_dictionary_t qdict, prop_array_t *cmds)
-{
-       prop_number_t pn;
-       prop_object_t o;
-
-       pn = prop_dictionary_get(qdict, "interface version");
-       if (pn == NULL)
-               return EINVAL;
-       if (prop_number_integer_value(pn) != 1)
-               return EINVAL;
-
-       o = prop_dictionary_get(qdict, "commands");
-       if (o == NULL)
-               return ENOMEM;
-        if(prop_object_type(o) != PROP_TYPE_ARRAY)
-               return EINVAL;
-       *cmds = o;
-       return 0;
-}
-
-bool
-prop_array_add_and_rel(prop_array_t array, prop_object_t po)
-{
-       bool ret;
-       if (po == NULL)
-               return false;
-       ret = prop_array_add(array, po);
-       prop_object_release(po);
-       return ret;
-}
-
-bool
-prop_dictionary_set_and_rel(prop_dictionary_t dict, const char *key,
-    prop_object_t po)
-{
-       bool ret;
-       if (po == NULL)
-               return false;
-       ret = prop_dictionary_set(dict, key, po);
-       prop_object_release(po);
-       return ret;
-}
-
-prop_dictionary_t
-quota2_prop_create(void)
-{
-       prop_dictionary_t dict = prop_dictionary_create();
-
-       if (dict == NULL)
-               return NULL;
-
-       if (!prop_dictionary_set_uint8(dict, "interface version", 1)) {
-               goto err;
-       }
-       return dict;
-err:
-       prop_object_release(dict);
-       return NULL;
-}
-
-bool
-quota2_prop_add_command(prop_array_t arrcmd, const char *cmd, const char *type,
-    prop_array_t data)
-{
-       prop_dictionary_t dict;
-
-       dict = prop_dictionary_create();
-       if (dict == NULL) {
-               return false;
-       }
-       if (!prop_dictionary_set_cstring(dict, "type", type)) {
-               goto err;
-       }
-       if (!prop_dictionary_set_cstring(dict, "command", cmd)) {
-               goto err;
-       }
-       if (!prop_dictionary_set_and_rel(dict, "data", data)) {
-               goto err;
-       }
-       if (!prop_array_add(arrcmd, dict)) {
-               goto err;
-       }
-       prop_object_release(dict);
-       return true;
-err:
-       prop_object_release(dict);
-       return false;
-}
-
-prop_dictionary_t
-q2vtoprop(struct quota2_val *q2v)
-{
-       prop_dictionary_t dict1 = prop_dictionary_create();
-
-       if (dict1 == NULL)
-               return NULL;
-       if (!prop_dictionary_set_uint64(dict1, "hard", q2v->q2v_hardlimit)) {
-               goto err;
-       }
-       if (!prop_dictionary_set_uint64(dict1, "soft", q2v->q2v_softlimit)) {
-               goto err;
-       }
-       if (!prop_dictionary_set_uint64(dict1, "usage", q2v->q2v_cur)) {
-               goto err;
-       }
-       if (!prop_dictionary_set_int64(dict1, "expire time", q2v->q2v_time)) {
-               goto err;
-       }
-       if (!prop_dictionary_set_int64(dict1, "grace time", q2v->q2v_grace)) {
-               goto err;
-       }
-       return dict1;
-err:
-       prop_object_release(dict1);
-       return NULL;
-}
-
-prop_dictionary_t
-q2etoprop(struct quota2_entry *q2e, int def)
-{
-       prop_dictionary_t dict1 = prop_dictionary_create();
-       prop_dictionary_t dict2;
-       int i;
-
-       if (dict1 == NULL)
-               return NULL;
-       if (def) {
-               if (!prop_dictionary_set_cstring_nocopy(dict1, "id",
-                   "default")) {
-                       goto err;
-               }
-       } else {
-               if (!prop_dictionary_set_uint32(dict1, "id", q2e->q2e_uid)) {
-                       goto err;
-               }
-       }
-       for (i = 0; i < N_QL; i++) {
-               dict2 = q2vtoprop(&q2e->q2e_val[i]);
-               if (dict2 == NULL)
-                       goto err;
-               if (!prop_dictionary_set_and_rel(dict1, quota2_valnames[i],
-                   dict2))
-                       goto err;
-       }
-
-       return dict1;
-err:
-       prop_object_release(dict1);
-       return NULL;
-}
Index: sys/ufs/ufs/quota2_prop.h
===================================================================
RCS file: sys/ufs/ufs/quota2_prop.h
diff -N sys/ufs/ufs/quota2_prop.h
--- sys/ufs/ufs/quota2_prop.h   6 Mar 2011 17:08:39 -0000       1.2
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,47 +0,0 @@
-/* $NetBSD: quota2_prop.h,v 1.2 2011/03/06 17:08:39 bouyer Exp $ */
-/*-
-  * Copyright (c) 2010 Manuel Bouyer
-  * All rights reserved.
-  * This software is distributed under the following condiions
-  * compliant with the NetBSD foundation policy.
-  *
-  * Redistribution and use in source and binary forms, with or without
-  * modification, are permitted provided that the following conditions
-  * are met:
-  * 1. Redistributions of source code must retain the above copyright
-  *    notice, this list of conditions and the following disclaimer.
-  * 2. Redistributions in binary form must reproduce the above copyright
-  *    notice, this list of conditions and the following disclaimer in the
-  *    documentation and/or other materials provided with the distribution.
-  *
-  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
-  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
-  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-  * POSSIBILITY OF SUCH DAMAGE.
-  */
-
-#include <prop/proplib.h>
-#include <ufs/ufs/quota2.h>
-
-prop_dictionary_t prop_dictionary_get_dict(prop_dictionary_t, const char *);
-int quota2_dict_get_q2v_limits(prop_dictionary_t, struct quota2_val *, bool);
-int quota2_dict_update_q2e_limits(prop_dictionary_t, struct quota2_entry *);
-int quota2_dict_get_q2v_usage(prop_dictionary_t, struct quota2_val *);
-int quota2_dict_get_q2e_usage(prop_dictionary_t, struct quota2_entry *);
-int quota2_get_cmds(prop_dictionary_t, prop_array_t *);
-
-bool prop_array_add_and_rel(prop_array_t, prop_object_t);
-bool prop_dictionary_set_and_rel(prop_dictionary_t, const char *,
-     prop_object_t);
-prop_dictionary_t quota2_prop_create(void);
-bool quota2_prop_add_command(prop_array_t, const char *, const char *,
-    prop_array_t);
-prop_dictionary_t q2vtoprop(struct quota2_val *);
-prop_dictionary_t q2etoprop(struct quota2_entry *, int);
Index: sys/ufs/ufs/quota2_subr.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/quota2_subr.c,v
retrieving revision 1.2
diff -u -r1.2 quota2_subr.c
--- sys/ufs/ufs/quota2_subr.c   6 Mar 2011 17:08:39 -0000       1.2
+++ sys/ufs/ufs/quota2_subr.c   18 Mar 2011 16:00:30 -0000
@@ -108,21 +108,3 @@
            needswap);
        d->q2e_uid = ufs_rw32(s->q2e_uid, needswap);
 }
-
-int
-quota2_check_limit(struct quota2_val *q2v, uint64_t change, time_t now)
-{
-       if (q2v->q2v_cur + change > q2v->q2v_hardlimit) {
-               if (q2v->q2v_cur <= q2v->q2v_softlimit) 
-                       return (QL_F_CROSS | QL_S_DENY_HARD);
-               return QL_S_DENY_HARD;
-       } else if (q2v->q2v_cur + change > q2v->q2v_softlimit) {
-               if (q2v->q2v_cur <= q2v->q2v_softlimit)
-                       return (QL_F_CROSS | QL_S_ALLOW_SOFT);
-               if (now > q2v->q2v_time) {
-                       return QL_S_DENY_GRACE;
-               }
-               return QL_S_ALLOW_SOFT;
-       }
-       return QL_S_ALLOW_OK;
-}
Index: sys/ufs/ufs/ufs_quota.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_quota.c,v
retrieving revision 1.69
diff -u -r1.69 ufs_quota.c
--- sys/ufs/ufs/ufs_quota.c     6 Mar 2011 17:08:39 -0000       1.69
+++ sys/ufs/ufs/ufs_quota.c     18 Mar 2011 16:00:30 -0000
@@ -55,13 +55,11 @@
 #include <ufs/ufs/ufsmount.h>
 #include <ufs/ufs/ufs_extern.h>
 #include <ufs/ufs/ufs_quota.h>
-#include <ufs/ufs/quota2_prop.h>
+#include <quota/quotaprop.h>
 
 kmutex_t dqlock;
 kcondvar_t dqcv;
 
-const char *quotatypes[MAXQUOTAS] = INITQFNAMES;
-
 /*
  * Code pertaining to management of the in-core dquot data structures.
  */
@@ -165,9 +163,9 @@
                return EINVAL;
        if (!prop_dictionary_get_cstring_nocopy(cmddict, "type", &type))
                return EINVAL;
-       if (!strcmp(type, "user")) {
+       if (!strcmp(type, QUOTADICT_CLASS_USER)) {
                q2type = USRQUOTA;
-       } else if (!strcmp(type, "group")) {
+       } else if (!strcmp(type, QUOTADICT_CLASS_GROUP)) {
                q2type = GRPQUOTA;
        } else
                return EOPNOTSUPP;
Index: sys/ufs/ufs/ufs_quota1.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_quota1.c,v
retrieving revision 1.2
diff -u -r1.2 ufs_quota1.c
--- sys/ufs/ufs/ufs_quota1.c    6 Mar 2011 17:08:39 -0000       1.2
+++ sys/ufs/ufs/ufs_quota1.c    18 Mar 2011 16:00:30 -0000
@@ -47,7 +47,7 @@
 #include <sys/mount.h>
 #include <sys/kauth.h>
 
-#include <ufs/ufs/quota2_prop.h>
+#include <quota/quotaprop.h>
 #include <ufs/ufs/quota1.h>
 #include <ufs/ufs/inode.h>
 #include <ufs/ufs/ufsmount.h>
@@ -501,9 +501,13 @@
     int defaultq, prop_array_t replies)
 {
        struct dquot *dq;
-       struct quota2_entry q2e;
+       struct ufs_quota_entry qe[QUOTA_NLIMITS];
        prop_dictionary_t dict;
        int error;
+       uint64_t *valuesp[QUOTA_NLIMITS];
+       valuesp[QUOTA_LIMIT_BLOCK] = &qe[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit;
+       valuesp[QUOTA_LIMIT_FILE] = &qe[QUOTA_LIMIT_FILE].ufsqe_hardlimit;
+
 
        if (ump->um_quotas[type] == NULLVP)
                return ENODEV;
@@ -511,25 +515,28 @@
        if (defaultq) { /* we want the grace period of id 0 */
                if ((error = dqget(NULLVP, 0, ump, type, &dq)) != 0)
                        return error;
+
        } else {
                if ((error = dqget(NULLVP, id, ump, type, &dq)) != 0)
                        return error;
        }
-       dqblk2q2e(&dq->dq_un.dq1_dqb, &q2e);
+       dqblk2ufsqe(&dq->dq_un.dq1_dqb, qe);
        dqrele(NULLVP, dq);
        if (defaultq) {
-               if (q2e.q2e_val[QL_BLOCK].q2v_time > 0)
-                       q2e.q2e_val[QL_BLOCK].q2v_grace =
-                           q2e.q2e_val[QL_BLOCK].q2v_time;
+               if (qe[QUOTA_LIMIT_BLOCK].ufsqe_time > 0)
+                       qe[QUOTA_LIMIT_BLOCK].ufsqe_grace =
+                           qe[QUOTA_LIMIT_BLOCK].ufsqe_time;
                else
-                       q2e.q2e_val[QL_BLOCK].q2v_grace = MAX_DQ_TIME;
-               if (q2e.q2e_val[QL_FILE].q2v_time > 0)
-                       q2e.q2e_val[QL_FILE].q2v_grace =
-                           q2e.q2e_val[QL_FILE].q2v_time;
+                       qe[QUOTA_LIMIT_BLOCK].ufsqe_grace = MAX_DQ_TIME;
+               if (qe[QUOTA_LIMIT_FILE].ufsqe_time > 0)
+                       qe[QUOTA_LIMIT_FILE].ufsqe_grace =
+                           qe[QUOTA_LIMIT_FILE].ufsqe_time;
                else
-                       q2e.q2e_val[QL_FILE].q2v_grace = MAX_DQ_TIME;
+                       qe[QUOTA_LIMIT_FILE].ufsqe_grace = MAX_DQ_TIME;
        }
-       dict = q2etoprop(&q2e, defaultq);
+       dict = quota64toprop(id, defaultq, valuesp,
+           ufs_quota_entry_names, UFS_QUOTA_NENTRIES,
+           ufs_quota_limit_names, QUOTA_NLIMITS);
        if (dict == NULL)
                return ENOMEM;
        if (!prop_array_add_and_rel(replies, dict))
@@ -542,35 +549,48 @@
     int defaultq, prop_dictionary_t data)
 {
        struct dquot *dq;
-       struct quota2_entry q2e;
        struct dqblk dqb;
        int error;
+       uint64_t bval[2];
+       uint64_t ival[2];
+       const char *val_limitsonly_grace[] = {QUOTADICT_LIMIT_GTIME};
+#define Q1_GTIME 0
+       const char *val_limitsonly_softhard[] =
+           {QUOTADICT_LIMIT_SOFT, QUOTADICT_LIMIT_HARD};
+#define Q1_SOFT 0
+#define Q1_HARD 1
+
+       uint64_t *valuesp[QUOTA_NLIMITS];
+       valuesp[QUOTA_LIMIT_BLOCK] = bval;
+       valuesp[QUOTA_LIMIT_FILE] = ival;
 
        if (ump->um_quotas[type] == NULLVP)
                return ENODEV;
 
-       error = quota2_dict_update_q2e_limits(data, &q2e);
-       if (error)
-               return error;
-
        if (defaultq) {
                /* just update grace times */
+               error = proptoquota64(data, valuesp, val_limitsonly_grace, 1,
+                   ufs_quota_limit_names, QUOTA_NLIMITS);
+               if (error)
+                       return error;
                if ((error = dqget(NULLVP, id, ump, type, &dq)) != 0)
                        return error;
                mutex_enter(&dq->dq_interlock);
-               if (q2e.q2e_val[QL_BLOCK].q2v_grace > 0)
+               if (bval[Q1_GTIME] > 0)
                        ump->umq1_btime[type] = dq->dq_btime =
-                           q2e.q2e_val[QL_BLOCK].q2v_grace;
-               if (q2e.q2e_val[QL_FILE].q2v_grace > 0)
+                           bval[Q1_GTIME];
+               if (ival[Q1_GTIME] > 0)
                        ump->umq1_itime[type] = dq->dq_itime =
-                           q2e.q2e_val[QL_FILE].q2v_grace;
+                           ival[Q1_GTIME];
                mutex_exit(&dq->dq_interlock);
                dq->dq_flags |= DQ_MOD;
                dqrele(NULLVP, dq);
                return 0;
        }
-
-       q2e2dqblk(&q2e, &dqb);
+       error = proptoquota64(data, valuesp, val_limitsonly_softhard, 2,
+           ufs_quota_limit_names, QUOTA_NLIMITS);
+       if (error)
+               return error;
 
        if ((error = dqget(NULLVP, id, ump, type, &dq)) != 0)
                return (error);
@@ -582,9 +602,23 @@
         */
        dqb.dqb_curblocks = dq->dq_curblocks;
        dqb.dqb_curinodes = dq->dq_curinodes;
-       if (dq->dq_id != 0) {
-               dqb.dqb_btime = dq->dq_btime;
-               dqb.dqb_itime = dq->dq_itime;
+       dqb.dqb_btime = dq->dq_btime;
+       dqb.dqb_itime = dq->dq_itime;
+       dqb.dqb_bsoftlimit = (bval[Q1_SOFT] == UQUAD_MAX) ? 0 : bval[Q1_SOFT];
+       dqb.dqb_bhardlimit = (bval[Q1_HARD] == UQUAD_MAX) ? 0 : bval[Q1_HARD];
+       dqb.dqb_isoftlimit = (ival[Q1_SOFT] == UQUAD_MAX) ? 0 : ival[Q1_SOFT];
+       dqb.dqb_ihardlimit = (ival[Q1_HARD] == UQUAD_MAX) ? 0 : ival[Q1_HARD];
+       if (dq->dq_id == 0) {
+               /* also update grace time if available */
+               if (proptoquota64(data, valuesp, val_limitsonly_grace, 1,
+                   ufs_quota_limit_names, QUOTA_NLIMITS) == 0) {
+                       if (bval[Q1_GTIME] > 0)
+                               ump->umq1_btime[type] = dqb.dqb_btime =
+                                   bval[Q1_GTIME];
+                       if (ival[Q1_GTIME] > 0)
+                               ump->umq1_itime[type] = dqb.dqb_itime =
+                                   ival[Q1_GTIME];
+               }
        }
        if (dqb.dqb_bsoftlimit &&
            dq->dq_curblocks >= dqb.dqb_bsoftlimit &&
Index: sys/ufs/ufs/ufs_quota2.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_quota2.c,v
retrieving revision 1.2
diff -u -r1.2 ufs_quota2.c
--- sys/ufs/ufs/ufs_quota2.c    6 Mar 2011 17:08:39 -0000       1.2
+++ sys/ufs/ufs/ufs_quota2.c    18 Mar 2011 16:00:30 -0000
@@ -51,7 +51,7 @@
 #include <ufs/ufs/ufs_extern.h>
 #include <ufs/ufs/ufs_quota.h>
 #include <ufs/ufs/ufs_wapbl.h>
-#include <ufs/ufs/quota2_prop.h>
+#include <quota/quotaprop.h>
 
 /*
  * LOCKING:
@@ -75,7 +75,68 @@
     int (*func)(struct ufsmount *, uint64_t *, struct quota2_entry *,
       uint64_t, void *));
 
-static const char *valtypes[] = INITQLNAMES;
+static int quota2_dict_update_q2e_limits(prop_dictionary_t,
+    struct quota2_entry *);
+static prop_dictionary_t q2etoprop(struct quota2_entry *, int);
+
+static const char *limnames[] = INITQLNAMES;
+
+static int
+quota2_dict_update_q2e_limits(prop_dictionary_t data,
+    struct quota2_entry *q2e)
+{
+       const char *val_limitsonly_names[] = INITQVNAMES_LIMITSONLY;
+
+       int i, error;
+       prop_dictionary_t val;
+
+       for (i = 0; i < N_QL; i++) {
+               if (!prop_dictionary_get_dict(data, limnames[i], &val))
+                       return EINVAL;
+               error = quotaprop_dict_get_uint64(val,
+                   &q2e->q2e_val[i].q2v_hardlimit,
+                   val_limitsonly_names, N_QV, true);
+               if (error)
+                       return error;
+       }
+       return 0;
+}
+static prop_dictionary_t
+q2etoprop(struct quota2_entry *q2e, int def)
+{
+       const char *val_names[] = INITQVNAMES_ALL;
+       prop_dictionary_t dict1 = prop_dictionary_create();
+       prop_dictionary_t dict2;
+       int i;
+
+       if (dict1 == NULL)
+               return NULL;
+
+       if (def) {
+               if (!prop_dictionary_set_cstring_nocopy(dict1, "id",
+                   "default")) {
+                       goto err;
+               }
+       } else {
+               if (!prop_dictionary_set_uint32(dict1, "id", q2e->q2e_uid)) {
+                       goto err;
+               }
+       }
+       for (i = 0; i < N_QL; i++) {
+               dict2 = limits64toprop(&q2e->q2e_val[i].q2v_hardlimit,
+                   val_names, N_QV);
+               if (dict2 == NULL)
+                       goto err;
+               if (!prop_dictionary_set_and_rel(dict1, limnames[i], dict2))
+                       goto err;
+       }
+       return dict1;
+
+err:
+       prop_object_release(dict1);
+       return NULL;
+}
+
 
 static int
 quota2_bwrite(struct mount *mp, struct buf *bp)
@@ -457,7 +518,7 @@
                                        uprintf("\n%s: write failed, %s %s "
                                            "limit reached\n",
                                            mp->mnt_stat.f_mntonname,
-                                           quotatypes[i], valtypes[vtype]);
+                                           quotatypes[i], limnames[vtype]);
                                        dq->dq_flags |= DQ_WARN(vtype);
                                }
                                error = EDQUOT;
@@ -467,7 +528,7 @@
                                        uprintf("\n%s: write failed, %s %s "
                                            "limit reached\n",
                                            mp->mnt_stat.f_mntonname,
-                                           quotatypes[i], valtypes[vtype]);
+                                           quotatypes[i], limnames[vtype]);
                                        dq->dq_flags |= DQ_WARN(vtype);
                                }
                                error = EDQUOT;
@@ -477,7 +538,7 @@
                                        uprintf("\n%s: warning, %s %s "
                                            "quota exceeded\n",
                                            mp->mnt_stat.f_mntonname,
-                                           quotatypes[i], valtypes[vtype]);
+                                           quotatypes[i], limnames[vtype]);
                                        dq->dq_flags |= DQ_WARN(vtype);
                                }
                                break;
Index: sys/ufs/ufs/ufs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_vfsops.c,v
retrieving revision 1.41
diff -u -r1.41 ufs_vfsops.c
--- sys/ufs/ufs/ufs_vfsops.c    6 Mar 2011 17:08:39 -0000       1.41
+++ sys/ufs/ufs/ufs_vfsops.c    18 Mar 2011 16:00:30 -0000
@@ -62,7 +62,7 @@
 #ifdef UFS_DIRHASH
 #include <ufs/ufs/dirhash.h>
 #endif
-#include <ufs/ufs/quota2_prop.h>
+#include <quota/quotaprop.h>
 
 /* how many times ufs_init() was called */
 static int ufs_initcount = 0;
Index: usr.bin/quota/Makefile
===================================================================
RCS file: /cvsroot/src/usr.bin/quota/Makefile,v
retrieving revision 1.9
diff -u -r1.9 Makefile
--- usr.bin/quota/Makefile      6 Mar 2011 22:36:07 -0000       1.9
+++ usr.bin/quota/Makefile      18 Mar 2011 16:00:39 -0000
@@ -4,12 +4,10 @@
 WARNS ?= 4
 .include <bsd.own.mk>
 PROG=  quota
-SRCS=  quota.c printquota.c getvfsquota.c quotautil.c
+SRCS=  quota.c printquota.c getvfsquota.c
 
-CPPFLAGS+=-I${NETBSDSRCDIR}/sys -I${NETBSDSRCDIR}/usr.bin/quota
-DPADD= ${LIBRPCSVC} ${LIBPROP}
-LDADD= -lrpcsvc -lprop
+CPPFLAGS+= -I${NETBSDSRCDIR}/usr.bin/quota
+DPADD= ${LIBQUOTA} ${LIBRPCSVC} ${LIBPROP}
+LDADD= -lquota -lrpcsvc -lprop
 
-.PATH: ${NETBSDSRCDIR}/sys/ufs/ufs 
-SRCS+= quota2_prop.c quota2_subr.c quota1_subr.c
 .include <bsd.prog.mk>
Index: usr.bin/quota/getvfsquota.c
===================================================================
RCS file: /cvsroot/src/usr.bin/quota/getvfsquota.c,v
retrieving revision 1.5
diff -u -r1.5 getvfsquota.c
--- usr.bin/quota/getvfsquota.c 12 Mar 2011 12:28:47 -0000      1.5
+++ usr.bin/quota/getvfsquota.c 18 Mar 2011 16:00:39 -0000
@@ -39,14 +39,14 @@
 
 #include <sys/types.h>
 
-#include <ufs/ufs/quota2_prop.h>
+#include <quota/quotaprop.h>
 #include <sys/quota.h>
 
 #include "getvfsquota.h"
 
-/* retrieve quotas from vfs, for the given user id */
+/* private version of getufsquota() */
 int
-getvfsquota(const char *mp, struct quota2_entry *q2e, int8_t *versp,
+getvfsquota(const char *mp, struct ufs_quota_entry *qv, int8_t *versp,
     uint32_t id, int type, int defaultq, int debug)
 {
        prop_dictionary_t dict, data, cmd;
@@ -74,9 +74,11 @@
                
        if (!prop_array_add_and_rel(datas, data))
                err(1, "prop_array_add(data)");
-       if (!quota2_prop_add_command(cmds, "get", qfextension[type], datas))
+       if (!quota2_prop_add_command(cmds, "get",
+           ufs_quota_class_names[type], datas))
                err(1, "prop_add_command");
-       if (!quota2_prop_add_command(cmds, "get version", qfextension[type],
+       if (!quota2_prop_add_command(cmds, "get version",
+           ufs_quota_class_names[type],
            prop_array_create()))
                err(1, "prop_add_command");
        if (!prop_dictionary_set(dict, "commands", cmds))
@@ -117,10 +119,10 @@
                                errno = error8;
                                if (defaultq) {
                                        warn("get default %s quota",
-                                           qfextension[type]);
+                                           ufs_quota_class_names[type]);
                                } else {
                                        warn("get %s quota for %u",
-                                           qfextension[type], id);
+                                           ufs_quota_class_names[type], id);
                                }
                        }
                        prop_object_release(dict);
@@ -143,13 +145,21 @@
                                
                /* only one data, no need to iter */
                if (prop_array_count(datas) > 0) {
+                       uint64_t *values[QUOTA_NLIMITS];
                        data = prop_array_get(datas, 0);
                        if (data == NULL)
                                err(1, "prop_array_get(data)");
 
-                       errno = quota2_dict_get_q2e_usage(data, q2e);
+                       values[QUOTA_LIMIT_BLOCK] =
+                           &qv[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit;
+                       values[QUOTA_LIMIT_FILE] =
+                           &qv[QUOTA_LIMIT_FILE].ufsqe_hardlimit;
+
+                       errno = proptoquota64(data, values,
+                            ufs_quota_entry_names, UFS_QUOTA_NENTRIES,
+                            ufs_quota_limit_names, QUOTA_NLIMITS);
                        if (errno)
-                               err(1, "quota2_dict_get_q2e_usage");
+                               err(1, "proptoquota64");
                        retval = 1;
                }
        }
Index: usr.bin/quota/getvfsquota.h
===================================================================
RCS file: /cvsroot/src/usr.bin/quota/getvfsquota.h,v
retrieving revision 1.3
diff -u -r1.3 getvfsquota.h
--- usr.bin/quota/getvfsquota.h 6 Mar 2011 20:47:59 -0000       1.3
+++ usr.bin/quota/getvfsquota.h 18 Mar 2011 16:00:39 -0000
@@ -1,6 +1,4 @@
 /*     $NetBSD: getvfsquota.h,v 1.3 2011/03/06 20:47:59 christos Exp $ */
 
-int getvfsquota(const char *, struct quota2_entry *, int8_t *,
+int getvfsquota(const char *, struct ufs_quota_entry *, int8_t *,
     uint32_t, int, int, int);
-
-extern const char *qfextension[];
Index: usr.bin/quota/printquota.c
===================================================================
RCS file: /cvsroot/src/usr.bin/quota/printquota.c,v
retrieving revision 1.5
diff -u -r1.5 printquota.c
--- usr.bin/quota/printquota.c  7 Mar 2011 11:46:55 -0000       1.5
+++ usr.bin/quota/printquota.c  18 Mar 2011 16:00:39 -0000
@@ -271,3 +271,16 @@
                *val = btodb(*val);
        return ret;
 }
+
+int
+alldigits(const char *s)
+{
+       unsigned char c;
+
+       c = *s++;
+       do {
+               if (!isdigit(c))
+                       return 0;
+       } while ((c = *s++) != 0);
+       return 1;
+}
Index: usr.bin/quota/printquota.h
===================================================================
RCS file: /cvsroot/src/usr.bin/quota/printquota.h,v
retrieving revision 1.4
diff -u -r1.4 printquota.h
--- usr.bin/quota/printquota.h  6 Mar 2011 22:36:07 -0000       1.4
+++ usr.bin/quota/printquota.h  18 Mar 2011 16:00:39 -0000
@@ -5,3 +5,4 @@
 const char *timepprt(char *, size_t, time_t, int);
 int timeprd(const char *, time_t *);
 int intrd(char *str, uint64_t *val, u_int);
+int alldigits(const char *);
Index: usr.bin/quota/quota.c
===================================================================
RCS file: /cvsroot/src/usr.bin/quota/quota.c,v
retrieving revision 1.36
diff -u -r1.36 quota.c
--- usr.bin/quota/quota.c       6 Mar 2011 22:36:07 -0000       1.36
+++ usr.bin/quota/quota.c       18 Mar 2011 16:00:39 -0000
@@ -69,29 +69,22 @@
 #include <time.h>
 #include <unistd.h>
 
-#include <ufs/ufs/quota2.h>
-#include <ufs/ufs/quota1.h>
-
-#include <rpc/rpc.h>
-#include <rpc/pmap_prot.h>
-#include <rpcsvc/rquota.h>
+#include <quota/quotaprop.h>
+#include <quota/quota.h>
 
 #include "printquota.h"
-#include "quotautil.h"
 #include "getvfsquota.h"
 
 struct quotause {
        struct  quotause *next;
        long    flags;
-       struct  quota2_entry q2e;
+       uid_t   id;
+       struct  ufs_quota_entry qe[QUOTA_NLIMITS];
        char    fsname[MAXPATHLEN + 1];
 };
 #define        FOUND   0x01
 #define        QUOTA2  0x02
 
-static int     callaurpc(const char *, rpcprog_t, rpcvers_t, rpcproc_t,
-    xdrproc_t, void *, xdrproc_t, void *);
-static int     getnfsquota(struct statvfs *, struct quotause *, uint32_t, int);
 static struct quotause *getprivs(uint32_t, int);
 static void    heading(int, uint32_t, const char *, const char *);
 static void    showgid(gid_t);
@@ -154,9 +147,9 @@
                        errx(1, "-d: permission denied");
 #endif
                if (uflag)
-                       showquotas(USRQUOTA, 0, "");
+                       showquotas(QUOTA_CLASS_USER, 0, "");
                if (gflag)
-                       showquotas(GRPQUOTA, 0, "");
+                       showquotas(QUOTA_CLASS_GROUP, 0, "");
                return 0;
        }
        if (argc == 0) {
@@ -230,7 +223,7 @@
                warnx("%s (uid %d): permission denied", name, uid);
                return;
        }
-       showquotas(USRQUOTA, uid, name);
+       showquotas(QUOTA_CLASS_USER, uid, name);
 }
 
 /*
@@ -249,7 +242,7 @@
                warnx("%s (uid %d): permission denied", name, pwd->pw_uid);
                return;
        }
-       showquotas(USRQUOTA, pwd->pw_uid, name);
+       showquotas(QUOTA_CLASS_USER, pwd->pw_uid, name);
 }
 
 /*
@@ -283,7 +276,7 @@
                        return;
                }
        }
-       showquotas(GRPQUOTA, gid, name);
+       showquotas(QUOTA_CLASS_GROUP, gid, name);
 }
 
 /*
@@ -317,7 +310,7 @@
                        return;
                }
        }
-       showquotas(GRPQUOTA, grp->gr_gid, name);
+       showquotas(QUOTA_CLASS_GROUP, grp->gr_gid, name);
 }
 
 static void
@@ -335,14 +328,17 @@
        quplist = getprivs(id, type);
        for (qup = quplist; qup; qup = qup->next) {
                int ql_stat;
-               struct quota2_val *q = qup->q2e.q2e_val;
+               struct ufs_quota_entry *q = qup->qe;
                if (!vflag &&
-                   q[QL_BLOCK].q2v_softlimit == UQUAD_MAX &&
-                   q[QL_BLOCK].q2v_hardlimit == UQUAD_MAX &&
-                   q[QL_FILE].q2v_softlimit == UQUAD_MAX &&
-                   q[QL_FILE].q2v_hardlimit == UQUAD_MAX)
+                   q[QUOTA_LIMIT_BLOCK].ufsqe_softlimit == UQUAD_MAX &&
+                   q[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit == UQUAD_MAX &&
+                   q[QUOTA_LIMIT_FILE].ufsqe_softlimit == UQUAD_MAX &&
+                   q[QUOTA_LIMIT_FILE].ufsqe_hardlimit == UQUAD_MAX)
                        continue;
-               ql_stat = quota2_check_limit(&q[QL_FILE], 1, now);
+               ql_stat = quota_check_limit(q[QUOTA_LIMIT_FILE].ufsqe_cur, 1,
+                   q[QUOTA_LIMIT_FILE].ufsqe_softlimit,
+                   q[QUOTA_LIMIT_FILE].ufsqe_hardlimit,
+                   q[QUOTA_LIMIT_FILE].ufsqe_time, now);
                switch(QL_STATUS(ql_stat)) {
                case QL_S_DENY_HARD:
                        msgi = "File limit reached on";
@@ -356,7 +352,10 @@
                default:
                        msgi = NULL;
                }
-               ql_stat = quota2_check_limit(&q[QL_BLOCK], 1, now);
+               ql_stat = quota_check_limit(q[QUOTA_LIMIT_BLOCK].ufsqe_cur, 1,
+                   q[QUOTA_LIMIT_BLOCK].ufsqe_softlimit,
+                   q[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit,
+                   q[QUOTA_LIMIT_BLOCK].ufsqe_time, now);
                switch(QL_STATUS(ql_stat)) {
                case QL_S_DENY_HARD:
                        msgb = "Block limit reached on";
@@ -380,8 +379,9 @@
                                printf("\t%s %s\n", msgb, qup->fsname);
                        continue;
                }
-               if (vflag || dflag || msgi || msgb || q[QL_BLOCK].q2v_cur ||
-                   q[QL_FILE].q2v_cur) {
+               if (vflag || dflag || msgi || msgb ||
+                   q[QUOTA_LIMIT_BLOCK].ufsqe_cur ||
+                   q[QUOTA_LIMIT_FILE].ufsqe_cur) {
                        if (lines++ == 0)
                                heading(type, id, name, "");
                        nam = qup->fsname;
@@ -391,38 +391,41 @@
                        } 
                        if (msgb)
                                timemsg = timeprt(b0, 9, now,
-                                   q[QL_BLOCK].q2v_time);
+                                   q[QUOTA_LIMIT_BLOCK].ufsqe_time);
                        else if ((qup->flags & QUOTA2) != 0 && vflag)
                                timemsg = timeprt(b0, 9, 0,
-                                   q[QL_BLOCK].q2v_grace);
+                                   q[QUOTA_LIMIT_BLOCK].ufsqe_grace);
                        else
                                timemsg = "";
                                
                        printf("%12s%9s%c%8s%9s%8s",
                            nam,
-                           intprt(b1, 9, q[QL_BLOCK].q2v_cur,
+                           intprt(b1, 9, q[QUOTA_LIMIT_BLOCK].ufsqe_cur,
                            HN_B, hflag),
                            (msgb == NULL) ? ' ' : '*',
-                           intprt(b2, 9, q[QL_BLOCK].q2v_softlimit,
+                           intprt(b2, 9, q[QUOTA_LIMIT_BLOCK].ufsqe_softlimit,
                            HN_B, hflag),
-                           intprt(b3, 9, q[QL_BLOCK].q2v_hardlimit,
+                           intprt(b3, 9, q[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit,
                            HN_B, hflag),
                            timemsg);
 
                        if (msgi)
                                timemsg = timeprt(b0, 9, now, 
-                                   q[QL_FILE].q2v_time);
+                                   q[QUOTA_LIMIT_FILE].ufsqe_time);
                        else if ((qup->flags & QUOTA2) != 0 && vflag)
                                timemsg = timeprt(b0, 9, 0,
-                                   q[QL_FILE].q2v_grace);
+                                   q[QUOTA_LIMIT_FILE].ufsqe_grace);
                        else
                                timemsg = "";
                                
                        printf("%8s%c%7s%8s%8s\n",
-                           intprt(b1, 8, q[QL_FILE].q2v_cur, 0, hflag),
+                           intprt(b1, 8, q[QUOTA_LIMIT_FILE].ufsqe_cur, 0,
+                            hflag),
                            (msgi == NULL) ? ' ' : '*',
-                           intprt(b2, 8, q[QL_FILE].q2v_softlimit, 0, hflag),
-                           intprt(b3, 8, q[QL_FILE].q2v_hardlimit, 0, hflag),
+                           intprt(b2, 8, q[QUOTA_LIMIT_FILE].ufsqe_softlimit,
+                            0, hflag),
+                           intprt(b3, 8, q[QUOTA_LIMIT_FILE].ufsqe_hardlimit,
+                            0, hflag),
                            timemsg);
                        continue;
                }
@@ -436,11 +439,11 @@
 {
        if (dflag)
                printf("Default %s disk quotas: %s\n",
-                   qfextension[type], tag);
+                   ufs_quota_class_names[type], tag);
        else
                printf("Disk quotas for %s %s (%cid %u): %s\n",
-                   qfextension[type], name, *qfextension[type],
-                   id, tag);
+                   ufs_quota_class_names[type], name,
+                   *ufs_quota_class_names[type], id, tag);
 
        if (!qflag && tag[0] == '\0') {
                printf("%12s%9s %8s%9s%8s%8s %7s%8s%8s\n"
@@ -482,11 +485,12 @@
                if (strncmp(fst[i].f_fstypename, "nfs", 
                    sizeof(fst[i].f_fstypename)) == 0) {
                        version = 0;
-                       if (getnfsquota(&fst[i], qup, id, quotatype) == 0)
+                       if (getnfsquota(fst[i].f_mntfromname,
+                           qup->qe, id, ufs_quota_class_names[quotatype]) != 1)
                                continue;
                } else if ((fst[i].f_flag & ST_QUOTA) != 0) {
-                       if (getvfsquota(fst[i].f_mntonname, &qup->q2e, &version,
-                           id, quotatype, dflag, Dflag) == 0)
+                       if (getvfsquota(fst[i].f_mntonname, qup->qe, &version,
+                           id, quotatype, dflag, Dflag) != 1)
                                continue;
                } else
                        continue;
@@ -505,136 +509,3 @@
        free(qup);
        return quphead;
 }
-
-static int
-getnfsquota(struct statvfs *fst, struct quotause *qup,
-    uint32_t id, int quotatype)
-{
-       struct getquota_args gq_args;
-       struct ext_getquota_args ext_gq_args;
-       struct getquota_rslt gq_rslt;
-       struct quota2_entry *q2e = &qup->q2e;
-       struct dqblk dqblk;
-       struct timeval tv;
-       char *cp;
-       int ret;
-
-       if (fst->f_flag & MNT_LOCAL)
-               return 0;
-
-       /*
-        * must be some form of "hostname:/path"
-        */
-       cp = strchr(fst->f_mntfromname, ':');
-       if (cp == NULL) {
-               warnx("cannot find hostname for %s", fst->f_mntfromname);
-               return 0;
-       }
- 
-       *cp = '\0';
-       if (*(cp+1) != '/') {
-               *cp = ':';
-               return 0;
-       }
-
-       ext_gq_args.gqa_pathp = cp + 1;
-       ext_gq_args.gqa_id = id;
-       ext_gq_args.gqa_type =
-           (quotatype == USRQUOTA) ? RQUOTA_USRQUOTA : RQUOTA_GRPQUOTA;
-       ret = callaurpc(fst->f_mntfromname, RQUOTAPROG, EXT_RQUOTAVERS,
-           RQUOTAPROC_GETQUOTA, xdr_ext_getquota_args, &ext_gq_args,
-           xdr_getquota_rslt, &gq_rslt);
-       if (ret == RPC_PROGVERSMISMATCH) {
-               if (quotatype != USRQUOTA) {
-                       *cp = ':';
-                       return 0;
-               }
-               /* try RQUOTAVERS */
-               gq_args.gqa_pathp = cp + 1;
-               gq_args.gqa_uid = id;
-               ret = callaurpc(fst->f_mntfromname, RQUOTAPROG, RQUOTAVERS,
-                   RQUOTAPROC_GETQUOTA, xdr_getquota_args, &gq_args,
-                   xdr_getquota_rslt, &gq_rslt);
-       }
-       if (ret != RPC_SUCCESS) {
-               *cp = ':';
-               return 0;
-       }
-
-       switch (gq_rslt.status) {
-       case Q_NOQUOTA:
-               break;
-       case Q_EPERM:
-               warnx("quota permission error, host: %s", fst->f_mntfromname);
-               break;
-       case Q_OK:
-               gettimeofday(&tv, NULL);
-
-               /* blocks*/
-               q2e->q2e_val[QL_BLOCK].q2v_hardlimit =
-               dqblk.dqb_bhardlimit =
-                   gq_rslt.getquota_rslt_u.gqr_rquota.rq_bhardlimit *
-                   (gq_rslt.getquota_rslt_u.gqr_rquota.rq_bsize / DEV_BSIZE);
-               dqblk.dqb_bsoftlimit =
-                   gq_rslt.getquota_rslt_u.gqr_rquota.rq_bsoftlimit *
-                   (gq_rslt.getquota_rslt_u.gqr_rquota.rq_bsize / DEV_BSIZE);
-               dqblk.dqb_curblocks =
-                   gq_rslt.getquota_rslt_u.gqr_rquota.rq_curblocks *
-                   (gq_rslt.getquota_rslt_u.gqr_rquota.rq_bsize / DEV_BSIZE);
-
-               /* inodes */
-               dqblk.dqb_ihardlimit =
-                   gq_rslt.getquota_rslt_u.gqr_rquota.rq_fhardlimit;
-               dqblk.dqb_isoftlimit =
-                   gq_rslt.getquota_rslt_u.gqr_rquota.rq_fsoftlimit;
-               dqblk.dqb_curinodes =
-                   gq_rslt.getquota_rslt_u.gqr_rquota.rq_curfiles;
-
-               /* grace times */
-               dqblk.dqb_btime = (int)(tv.tv_sec +
-                   gq_rslt.getquota_rslt_u.gqr_rquota.rq_btimeleft);
-               dqblk.dqb_itime = (int)(tv.tv_sec +
-                   gq_rslt.getquota_rslt_u.gqr_rquota.rq_ftimeleft);
-               dqblk2q2e(&dqblk, q2e);
-               *cp = ':';
-               return 1;
-       default:
-               warnx("bad rpc result, host: %s", fst->f_mntfromname);
-               break;
-       }
-       *cp = ':';
-       return 0;
-}
- 
-static int
-callaurpc(const char *host, rpcprog_t prognum, rpcvers_t versnum,
-    rpcproc_t procnum, xdrproc_t inproc, void *in, xdrproc_t outproc, void 
*out)
-{
-       struct sockaddr_in server_addr;
-       enum clnt_stat clnt_stat;
-       struct hostent *hp;
-       struct timeval timeout, tottimeout;
- 
-       CLIENT *client = NULL;
-       int sock = RPC_ANYSOCK;
- 
-       if ((hp = gethostbyname(host)) == NULL)
-               return (int) RPC_UNKNOWNHOST;
-       timeout.tv_usec = 0;
-       timeout.tv_sec = 6;
-       memmove(&server_addr.sin_addr, hp->h_addr, hp->h_length);
-       server_addr.sin_family = AF_INET;
-       server_addr.sin_port =  0;
-
-       if ((client = clntudp_create(&server_addr, prognum,
-           versnum, timeout, &sock)) == NULL)
-               return (int) rpc_createerr.cf_stat;
-
-       client->cl_auth = authunix_create_default();
-       tottimeout.tv_sec = 25;
-       tottimeout.tv_usec = 0;
-       clnt_stat = clnt_call(client, procnum, inproc, in,
-           outproc, out, tottimeout);
- 
-       return (int) clnt_stat;
-}
Index: usr.bin/quota/quotautil.c
===================================================================
RCS file: /cvsroot/src/usr.bin/quota/quotautil.c,v
retrieving revision 1.2
diff -u -r1.2 quotautil.c
--- usr.bin/quota/quotautil.c   6 Mar 2011 23:26:05 -0000       1.2
+++ usr.bin/quota/quotautil.c   18 Mar 2011 16:00:39 -0000
@@ -60,13 +60,13 @@
 #include <limits.h>
 #include <inttypes.h>
 
-#include <ufs/ufs/quota2.h>
+#include <quota/quotaprop.h>
 #include <ufs/ufs/quota1.h>
 
 #include "quotautil.h"
 
-const char *qfextension[MAXQUOTAS] = INITQFNAMES;
-const char *qfname = QUOTAFILENAME;
+const char *qfextension[] = INITQFNAMES;
+const char *qfnamep = QUOTAFILENAME;
  
 /*
  * Check to see if a particular quota is to be enabled.
@@ -105,19 +105,6 @@
        return 1;
 }
 
-int
-alldigits(const char *s)
-{
-       unsigned char c;
-
-       c = *s++;
-       do {
-               if (!isdigit(c))
-                       return 0;
-       } while ((c = *s++) != 0);
-       return 1;
-}
-
 /*
  * Check to see if target appears in list of size cnt.
  */
Index: usr.bin/quota/quotautil.h
===================================================================
RCS file: /cvsroot/src/usr.bin/quota/quotautil.h,v
retrieving revision 1.2
diff -u -r1.2 quotautil.h
--- usr.bin/quota/quotautil.h   6 Mar 2011 23:26:16 -0000       1.2
+++ usr.bin/quota/quotautil.h   18 Mar 2011 16:00:39 -0000
@@ -4,5 +4,4 @@
 const char *qfname;
 struct fstab;
 int hasquota(char *, size_t, struct fstab *, int);
-int alldigits(const char *);
 int oneof(const char *, char *[], int);
Index: usr.sbin/edquota/Makefile
===================================================================
RCS file: /cvsroot/src/usr.sbin/edquota/Makefile,v
retrieving revision 1.7
diff -u -r1.7 Makefile
--- usr.sbin/edquota/Makefile   6 Mar 2011 22:34:57 -0000       1.7
+++ usr.sbin/edquota/Makefile   18 Mar 2011 16:00:41 -0000
@@ -9,12 +9,12 @@
 MAN=   edquota.8
 
 CPPFLAGS+=-I${NETBSDSRCDIR}/sys -I${NETBSDSRCDIR}/usr.bin/quota
-DPADD= ${LIBPROP}
-LDADD= -lprop
+DPADD= ${LIBQUOTA} ${LIBPROP} ${LIBRPCSVC}
+LDADD= -lquota -lprop -lrpcsvc
 
 .PATH: ${NETBSDSRCDIR}/usr.bin/quota
 SRCS+= getvfsquota.c printquota.c quotautil.c
 .PATH: ${NETBSDSRCDIR}/sys/ufs/ufs 
-SRCS+= quota2_prop.c quota1_subr.c
+SRCS+= quota1_subr.c
 
 .include <bsd.prog.mk>
Index: usr.sbin/edquota/edquota.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/edquota/edquota.c,v
retrieving revision 1.31
diff -u -r1.31 edquota.c
--- usr.sbin/edquota/edquota.c  6 Mar 2011 22:34:57 -0000       1.31
+++ usr.sbin/edquota/edquota.c  18 Mar 2011 16:00:41 -0000
@@ -56,7 +56,8 @@
 #include <sys/types.h>
 #include <sys/statvfs.h>
 
-#include <ufs/ufs/quota2_prop.h>
+#include <quota/quotaprop.h>
+#include <quota/quota.h>
 #include <ufs/ufs/quota1.h>
 #include <sys/quota.h>
 
@@ -85,7 +86,7 @@
 struct quotause {
        struct  quotause *next;
        long    flags;
-       struct  quota2_entry q2e;
+       struct  ufs_quota_entry qe[QUOTA_NLIMITS];
        char    fsname[MAXPATHLEN + 1];
        char    *qfname;
 };
@@ -114,12 +115,16 @@
 static int Dflag = 0;
 static int dflag = 0;
 
+/* more compact form of constants */
+#define QL_BLK QUOTA_LIMIT_BLOCK
+#define QL_FL  QUOTA_LIMIT_FILE
+
 int
 main(int argc, char *argv[])
 {
        struct quotause *qup, *protoprivs, *curprivs;
        long id, protoid;
-       int quotatype, tmpfd;
+       int quotaclass, tmpfd;
        char *protoname;
        char *soft = NULL, *hard = NULL, *grace = NULL;
        char *fs = NULL;
@@ -132,7 +137,7 @@
        if (getuid())
                errx(1, "permission denied");
        protoname = NULL;
-       quotatype = USRQUOTA;
+       quotaclass = QUOTA_CLASS_USER;
        while ((ch = getopt(argc, argv, "DHcdugp:s:h:t:f:")) != -1) {
                switch(ch) {
                case 'D':
@@ -152,10 +157,10 @@
                        pflag++;
                        break;
                case 'g':
-                       quotatype = GRPQUOTA;
+                       quotaclass = QUOTA_CLASS_GROUP;
                        break;
                case 'u':
-                       quotatype = USRQUOTA;
+                       quotaclass = QUOTA_CLASS_USER;
                        break;
                case 's':
                        soft = optarg;
@@ -179,17 +184,17 @@
        if (pflag) {
                if (soft || hard || grace || dflag || cflag)
                        usage();
-               if ((protoid = getentry(protoname, quotatype)) == -1)
+               if ((protoid = getentry(protoname, quotaclass)) == -1)
                        return 1;
-               protoprivs = getprivs(protoid, quotatype, fs, 0);
+               protoprivs = getprivs(protoid, quotaclass, fs, 0);
                for (qup = protoprivs; qup; qup = qup->next) {
-                       qup->q2e.q2e_val[QL_BLOCK].q2v_time = 0;
-                       qup->q2e.q2e_val[QL_FILE].q2v_time = 0;
+                       qup->qe[QL_BLK].ufsqe_time = 0;
+                       qup->qe[QL_FL].ufsqe_time = 0;
                }
                while (argc-- > 0) {
-                       if ((id = getentry(*argv++, quotatype)) < 0)
+                       if ((id = getentry(*argv++, quotaclass)) < 0)
                                continue;
-                       putprivs(id, quotatype, protoprivs);
+                       putprivs(id, quotaclass, protoprivs);
                }
                return 0;
        }
@@ -232,58 +237,58 @@
                                errx(1, "%s: bad number", grace);
                }
                if (dflag) {
-                       curprivs = getprivs(0, quotatype, fs, 1);
+                       curprivs = getprivs(0, quotaclass, fs, 1);
                        for (lqup = curprivs; lqup; lqup = lqup->next) {
-                               struct quota2_val *q = lqup->q2e.q2e_val;
+                               struct ufs_quota_entry *q = lqup->qe;
                                if (soft) {
-                                       q[QL_BLOCK].q2v_softlimit = softb;
-                                       q[QL_FILE].q2v_softlimit = softi;
+                                       q[QL_BLK].ufsqe_softlimit = softb;
+                                       q[QL_FL].ufsqe_softlimit = softi;
                                }
                                if (hard) {
-                                       q[QL_BLOCK].q2v_hardlimit = hardb;
-                                       q[QL_FILE].q2v_hardlimit = hardi;
+                                       q[QL_BLK].ufsqe_hardlimit = hardb;
+                                       q[QL_FL].ufsqe_hardlimit = hardi;
                                }
                                if (grace) {
-                                       q[QL_BLOCK].q2v_grace = graceb;
-                                       q[QL_FILE].q2v_grace = gracei;
+                                       q[QL_BLK].ufsqe_grace = graceb;
+                                       q[QL_FL].ufsqe_grace = gracei;
                                }
                        }
-                       putprivs(0, quotatype, curprivs);
+                       putprivs(0, quotaclass, curprivs);
                        freeprivs(curprivs);
                        return 0;
                }
                for ( ; argc > 0; argc--, argv++) {
-                       if ((id = getentry(*argv, quotatype)) == -1)
+                       if ((id = getentry(*argv, quotaclass)) == -1)
                                continue;
-                       curprivs = getprivs(id, quotatype, fs, 0);
+                       curprivs = getprivs(id, quotaclass, fs, 0);
                        for (lqup = curprivs; lqup; lqup = lqup->next) {
-                               struct quota2_val *q = lqup->q2e.q2e_val;
+                               struct ufs_quota_entry *q = lqup->qe;
                                if (soft) {
                                        if (softb &&
-                                           q[QL_BLOCK].q2v_cur >= softb &&
-                                           (q[QL_BLOCK].q2v_softlimit == 0 ||
-                                           q[QL_BLOCK].q2v_cur <
-                                           q[QL_BLOCK].q2v_softlimit))
-                                               q[QL_BLOCK].q2v_time = 0;
+                                           q[QL_BLK].ufsqe_cur >= softb &&
+                                           (q[QL_BLK].ufsqe_softlimit == 0 ||
+                                           q[QL_BLK].ufsqe_cur <
+                                           q[QL_BLK].ufsqe_softlimit))
+                                               q[QL_BLK].ufsqe_time = 0;
                                        if (softi &&
-                                           q[QL_FILE].q2v_cur >= softb &&
-                                           (q[QL_FILE].q2v_softlimit == 0 ||
-                                           q[QL_FILE].q2v_cur <
-                                           q[QL_FILE].q2v_softlimit))
-                                               q[QL_FILE].q2v_time = 0;
-                                       q[QL_BLOCK].q2v_softlimit = softb;
-                                       q[QL_FILE].q2v_softlimit = softi;
+                                           q[QL_FL].ufsqe_cur >= softb &&
+                                           (q[QL_FL].ufsqe_softlimit == 0 ||
+                                           q[QL_FL].ufsqe_cur <
+                                           q[QL_FL].ufsqe_softlimit))
+                                               q[QL_FL].ufsqe_time = 0;
+                                       q[QL_BLK].ufsqe_softlimit = softb;
+                                       q[QL_FL].ufsqe_softlimit = softi;
                                }
                                if (hard) {
-                                       q[QL_BLOCK].q2v_hardlimit = hardb;
-                                       q[QL_FILE].q2v_hardlimit = hardi;
+                                       q[QL_BLK].ufsqe_hardlimit = hardb;
+                                       q[QL_FL].ufsqe_hardlimit = hardi;
                                }
                                if (grace) {
-                                       q[QL_BLOCK].q2v_grace = graceb;
-                                       q[QL_FILE].q2v_grace = gracei;
+                                       q[QL_BLK].ufsqe_grace = graceb;
+                                       q[QL_FL].ufsqe_grace = gracei;
                                }
                        }
-                       putprivs(id, quotatype, curprivs);
+                       putprivs(id, quotaclass, curprivs);
                        freeprivs(curprivs);
                }
                return 0;
@@ -291,26 +296,26 @@
        if (cflag) {
                if (dflag)
                        usage();
-               clearpriv(argc, argv, fs, quotatype);
+               clearpriv(argc, argv, fs, quotaclass);
                return 0;
        }
        tmpfd = mkstemp(tmpfil);
        fchown(tmpfd, getuid(), getgid());
        if (dflag) {
-               curprivs = getprivs(0, quotatype, fs, 1);
-               if (writeprivs(curprivs, tmpfd, NULL, quotatype) &&
+               curprivs = getprivs(0, quotaclass, fs, 1);
+               if (writeprivs(curprivs, tmpfd, NULL, quotaclass) &&
                    editit(tmpfil) && readprivs(curprivs, tmpfd))
-                       putprivs(0, quotatype, curprivs);
+                       putprivs(0, quotaclass, curprivs);
                freeprivs(curprivs);
        }
        for ( ; argc > 0; argc--, argv++) {
-               if ((id = getentry(*argv, quotatype)) == -1)
+               if ((id = getentry(*argv, quotaclass)) == -1)
                        continue;
-               curprivs = getprivs(id, quotatype, fs, 0);
-               if (writeprivs(curprivs, tmpfd, *argv, quotatype) == 0)
+               curprivs = getprivs(id, quotaclass, fs, 0);
+               if (writeprivs(curprivs, tmpfd, *argv, quotaclass) == 0)
                        continue;
                if (editit(tmpfil) && readprivs(curprivs, tmpfd))
-                       putprivs(id, quotatype, curprivs);
+                       putprivs(id, quotaclass, curprivs);
                freeprivs(curprivs);
        }
        close(tmpfd);
@@ -343,26 +348,26 @@
  * getinoquota as to the interpretation of quota types.
  */
 static int
-getentry(const char *name, int quotatype)
+getentry(const char *name, int quotaclass)
 {
        struct passwd *pw;
        struct group *gr;
 
        if (alldigits(name))
                return atoi(name);
-       switch(quotatype) {
-       case USRQUOTA:
+       switch(quotaclass) {
+       case QUOTA_CLASS_USER:
                if ((pw = getpwnam(name)) != NULL)
                        return pw->pw_uid;
                warnx("%s: no such user", name);
                break;
-       case GRPQUOTA:
+       case QUOTA_CLASS_GROUP:
                if ((gr = getgrnam(name)) != NULL)
                        return gr->gr_gid;
                warnx("%s: no such group", name);
                break;
        default:
-               warnx("%d: unknown quota type", quotatype);
+               warnx("%d: unknown quota type", quotaclass);
                break;
        }
        sleep(1);
@@ -373,7 +378,7 @@
  * Collect the requested quota information.
  */
 static struct quotause *
-getprivs(long id, int quotatype, const char *filesys, int defaultq)
+getprivs(long id, int quotaclass, const char *filesys, int defaultq)
 {
        struct statvfs *fst;
        int nfst, i;
@@ -390,7 +395,7 @@
                if (filesys && strcmp(fst[i].f_mntonname, filesys) != 0 &&
                    strcmp(fst[i].f_mntfromname, filesys) != 0)
                        continue;
-               qup = getprivs2(id, quotatype, fst[i].f_mntonname, defaultq);
+               qup = getprivs2(id, quotaclass, fst[i].f_mntonname, defaultq);
                if (qup == NULL)
                        return NULL;
                if (quphead == NULL)
@@ -405,7 +410,7 @@
                if (defaultq)
                        errx(1, "no default quota for version 1");
                /* if we get there, filesys is not mounted. try the old way */
-               qup = getprivs1(id, quotatype, filesys);
+               qup = getprivs1(id, quotaclass, filesys);
                if (qup == NULL)
                        return NULL;
                if (quphead == NULL)
@@ -419,7 +424,7 @@
 }
 
 static struct quotause *
-getprivs2(long id, int quotatype, const char *filesys, int defaultq)
+getprivs2(long id, int quotaclass, const char *filesys, int defaultq)
 {
        struct quotause *qup;
        int8_t version;
@@ -430,23 +435,22 @@
        strcpy(qup->fsname, filesys);
        if (defaultq)
                qup->flags |= DEFAULT;
-       if (!getvfsquota(filesys, &qup->q2e, &version,
-           id, quotatype, defaultq, Dflag)) {
+       if (!getvfsquota(filesys, qup->qe, &version,
+           id, quotaclass, defaultq, Dflag)) {
                /* no entry, get default entry */
-               if (!getvfsquota(filesys, &qup->q2e, &version,
-                   id, quotatype, 1, Dflag)) {
+               if (!getvfsquota(filesys, qup->qe, &version,
+                   id, quotaclass, 1, Dflag)) {
                        free(qup);
                        return NULL;
                }
        }
        if (version == 2)
                qup->flags |= QUOTA2;
-       qup->q2e.q2e_uid = id;
        return qup;
 }
 
 static struct quotause *
-getprivs1(long id, int quotatype, const char *filesys)
+getprivs1(long id, int quotaclass, const char *filesys)
 {
        struct fstab *fs;
        char qfpathname[MAXPATHLEN];
@@ -465,7 +469,8 @@
        if (fs == NULL)
                return NULL;
 
-       if (!hasquota(qfpathname, sizeof(qfpathname), fs, quotatype))
+       if (!hasquota(qfpathname, sizeof(qfpathname), fs,
+           ufsclass2qtype(quotaclass)))
                return NULL;
        if ((qup = malloc(sizeof(*qup))) == NULL)
                err(1, "out of memory");
@@ -479,7 +484,8 @@
                }
                warnx("Creating quota file %s", qfpathname);
                sleep(3);
-               (void)fchown(fd, getuid(), getentry(quotagroup, GRPQUOTA));
+               (void)fchown(fd, getuid(),
+                   getentry(quotagroup, QUOTA_CLASS_GROUP));
                (void)fchmod(fd, 0640);
        }
        (void)lseek(fd, (off_t)(id * sizeof(struct dqblk)),
@@ -505,7 +511,7 @@
        close(fd);
        qup->qfname = qfpathname;
        endfsent();
-       dqblk2q2e(&dqblk, &qup->q2e);
+       dqblk2ufsqe(&dqblk, qup->qe);
        return qup;
 }
 
@@ -513,32 +519,39 @@
  * Store the requested quota information.
  */
 void
-putprivs(uint32_t id, int quotatype, struct quotause *quplist)
+putprivs(uint32_t id, int quotaclass, struct quotause *quplist)
 {
        struct quotause *qup;
 
         for (qup = quplist; qup; qup = qup->next) {
                if (qup->qfname == NULL)
-                       putprivs2(id, quotatype, qup);
+                       putprivs2(id, quotaclass, qup);
                else
-                       putprivs1(id, quotatype, qup);
+                       putprivs1(id, quotaclass, qup);
        }
 }
 
 static void
-putprivs2(uint32_t id, int quotatype, struct quotause *qup)
+putprivs2(uint32_t id, int quotaclass, struct quotause *qup)
 {
 
        prop_dictionary_t dict, data, cmd;
        prop_array_t cmds, datas;
        struct plistref pref;
        int8_t error8;
+       uint64_t *valuesp[QUOTA_NLIMITS];
 
-       qup->q2e.q2e_uid = id;
-       data = q2etoprop(&qup->q2e, (qup->flags & DEFAULT) ? 1 : 0);
+       valuesp[QL_BLK] =
+           &qup->qe[QL_BLK].ufsqe_hardlimit;
+       valuesp[QL_FL] =
+           &qup->qe[QL_FL].ufsqe_hardlimit;
+
+       data = quota64toprop(id, (qup->flags & DEFAULT) ? 1 : 0,
+           valuesp, ufs_quota_entry_names, UFS_QUOTA_NENTRIES,
+           ufs_quota_limit_names, QUOTA_NLIMITS);
 
        if (data == NULL)
-               err(1, "q2etoprop(id)");
+               err(1, "quota64toprop(id)");
 
        dict = quota2_prop_create();
        cmds = prop_array_create();
@@ -552,7 +565,7 @@
                err(1, "prop_array_add(data)");
        
        if (!quota2_prop_add_command(cmds, "set",
-           qfextension[quotatype], datas))
+           ufs_quota_class_names[quotaclass], datas))
                err(1, "prop_add_command");
        if (!prop_dictionary_set(dict, "commands", cmds))
                err(1, "prop_dictionary_set(command)");
@@ -589,20 +602,22 @@
        if (error8) {
                errno = error8;
                if (qup->flags & DEFAULT)
-                       warn("set default %s quota", qfextension[quotatype]);
+                       warn("set default %s quota",
+                           ufs_quota_class_names[quotaclass]);
                else
-                       warn("set %s quota for %u", qfextension[quotatype], id);
+                       warn("set %s quota for %u",
+                           ufs_quota_class_names[quotaclass], id);
        }
        prop_object_release(dict);
 }
 
 static void
-putprivs1(uint32_t id, int quotatype, struct quotause *qup)
+putprivs1(uint32_t id, int quotaclass, struct quotause *qup)
 {
        struct dqblk dqblk;
        int fd;
 
-       q2e2dqblk(&qup->q2e, &dqblk);
+       ufsqe2dqblk(qup->qe, &dqblk);
        assert((qup->flags & DEFAULT) == 0);
 
        if ((fd = open(qup->qfname, O_WRONLY)) < 0) {
@@ -678,7 +693,7 @@
  */
 static int
 writeprivs(struct quotause *quplist, int outfd, const char *name,
-    int quotatype)
+    int quotaclass)
 {
        struct quotause *qup;
        FILE *fd;
@@ -689,23 +704,24 @@
        if ((fd = fdopen(dup(outfd), "w")) == NULL)
                errx(1, "fdopen `%s'", tmpfil);
        if (dflag) {
-               fprintf(fd, "Default %s quotas:\n", qfextension[quotatype]);
+               fprintf(fd, "Default %s quotas:\n",
+                   ufs_quota_class_names[quotaclass]);
        } else {
                fprintf(fd, "Quotas for %s %s:\n",
-                   qfextension[quotatype], name);
+                   ufs_quota_class_names[quotaclass], name);
        }
        for (qup = quplist; qup; qup = qup->next) {
-               struct quota2_val *q = qup->q2e.q2e_val;
+               struct ufs_quota_entry *q = qup->qe;
                fprintf(fd, "%s (version %d):\n",
                     qup->fsname, (qup->flags & QUOTA2) ? 2 : 1);
                if ((qup->flags & DEFAULT) == 0 || (qup->flags & QUOTA2) != 0) {
                        fprintf(fd, "\tblocks in use: %s, "
                            "limits (soft = %s, hard = %s",
-                           intprt(b1, 21, q[QL_BLOCK].q2v_cur,
+                           intprt(b1, 21, q[QL_BLK].ufsqe_cur,
                            HN_NOSPACE | HN_B, Hflag), 
-                           intprt(b2, 21, q[QL_BLOCK].q2v_softlimit,
+                           intprt(b2, 21, q[QL_BLK].ufsqe_softlimit,
                            HN_NOSPACE | HN_B, Hflag),
-                           intprt(b3, 21, q[QL_BLOCK].q2v_hardlimit,
+                           intprt(b3, 21, q[QL_BLK].ufsqe_hardlimit,
                                HN_NOSPACE | HN_B, Hflag));
                        if (qup->flags & QUOTA2)
                                fprintf(fd, ", ");
@@ -714,17 +730,17 @@
                        
                if (qup->flags & (QUOTA2|DEFAULT)) {
                    fprintf(fd, "grace = %s",
-                       timepprt(b0, 21, q[QL_BLOCK].q2v_grace, Hflag));
+                       timepprt(b0, 21, q[QL_BLK].ufsqe_grace, Hflag));
                }
                fprintf(fd, ")\n");
                if ((qup->flags & DEFAULT) == 0 || (qup->flags & QUOTA2) != 0) {
                        fprintf(fd, "\tinodes in use: %s, "
                            "limits (soft = %s, hard = %s",
-                           intprt(b1, 21, q[QL_FILE].q2v_cur,
+                           intprt(b1, 21, q[QL_FL].ufsqe_cur,
                            HN_NOSPACE, Hflag),
-                           intprt(b2, 21, q[QL_FILE].q2v_softlimit,
+                           intprt(b2, 21, q[QL_FL].ufsqe_softlimit,
                            HN_NOSPACE, Hflag),
-                           intprt(b3, 21, q[QL_FILE].q2v_hardlimit,
+                           intprt(b3, 21, q[QL_FL].ufsqe_hardlimit,
                             HN_NOSPACE, Hflag));
                        if (qup->flags & QUOTA2)
                                fprintf(fd, ", ");
@@ -733,7 +749,7 @@
 
                if (qup->flags & (QUOTA2|DEFAULT)) {
                    fprintf(fd, "grace = %s",
-                       timepprt(b0, 21, q[QL_FILE].q2v_grace, Hflag));
+                       timepprt(b0, 21, q[QL_FL].ufsqe_grace, Hflag));
                }
                fprintf(fd, ")\n");
        }
@@ -913,21 +929,21 @@
                        }
                }
                for (qup = quplist; qup; qup = qup->next) {
-                       struct quota2_val *q = qup->q2e.q2e_val;
+                       struct ufs_quota_entry *q = qup->qe;
                        char b1[32], b2[32];
                        if (strcmp(fsp, qup->fsname))
                                continue;
                        if (version == 1 && dflag) {
-                               q[QL_BLOCK].q2v_grace = graceb;
-                               q[QL_FILE].q2v_grace = gracei;
+                               q[QL_BLK].ufsqe_grace = graceb;
+                               q[QL_FL].ufsqe_grace = gracei;
                                qup->flags |= FOUND;
                                continue;
                        }
 
-                       if (strcmp(intprt(b1, 21, q[QL_BLOCK].q2v_cur,
+                       if (strcmp(intprt(b1, 21, q[QL_BLK].ufsqe_cur,
                            HN_NOSPACE | HN_B, Hflag),
                            scurb) != 0 ||
-                           strcmp(intprt(b2, 21, q[QL_FILE].q2v_cur,
+                           strcmp(intprt(b2, 21, q[QL_FL].ufsqe_cur,
                            HN_NOSPACE, Hflag),
                            scuri) != 0) {
                                warnx("%s: cannot change current allocation",
@@ -940,24 +956,24 @@
                         * or were under it, but now have a soft limit
                         * and are over it.
                         */
-                       if (q[QL_BLOCK].q2v_cur &&
-                           q[QL_BLOCK].q2v_cur >= softb &&
-                           (q[QL_BLOCK].q2v_softlimit == 0 ||
-                            q[QL_BLOCK].q2v_cur < q[QL_BLOCK].q2v_softlimit))
-                               q[QL_BLOCK].q2v_time = 0;
-                       if (q[QL_FILE].q2v_cur &&
-                           q[QL_FILE].q2v_cur >= softi &&
-                           (q[QL_FILE].q2v_softlimit == 0 ||
-                            q[QL_FILE].q2v_cur < q[QL_FILE].q2v_softlimit))
-                               q[QL_FILE].q2v_time = 0;
-                       q[QL_BLOCK].q2v_softlimit = softb;
-                       q[QL_BLOCK].q2v_hardlimit = hardb;
+                       if (q[QL_BLK].ufsqe_cur &&
+                           q[QL_BLK].ufsqe_cur >= softb &&
+                           (q[QL_BLK].ufsqe_softlimit == 0 ||
+                            q[QL_BLK].ufsqe_cur < q[QL_BLK].ufsqe_softlimit))
+                               q[QL_BLK].ufsqe_time = 0;
+                       if (q[QL_FL].ufsqe_cur &&
+                           q[QL_FL].ufsqe_cur >= softi &&
+                           (q[QL_FL].ufsqe_softlimit == 0 ||
+                            q[QL_FL].ufsqe_cur < q[QL_FL].ufsqe_softlimit))
+                               q[QL_FL].ufsqe_time = 0;
+                       q[QL_BLK].ufsqe_softlimit = softb;
+                       q[QL_BLK].ufsqe_hardlimit = hardb;
                        if (version == 2)
-                               q[QL_BLOCK].q2v_grace = graceb;
-                       q[QL_FILE].q2v_softlimit  = softi;
-                       q[QL_FILE].q2v_hardlimit  = hardi;
+                               q[QL_BLK].ufsqe_grace = graceb;
+                       q[QL_FL].ufsqe_softlimit  = softi;
+                       q[QL_FL].ufsqe_hardlimit  = hardi;
                        if (version == 2)
-                               q[QL_FILE].q2v_grace = gracei;
+                               q[QL_FL].ufsqe_grace = gracei;
                        qup->flags |= FOUND;
                }
        }
@@ -967,17 +983,17 @@
         * Disable quotas for any filesystems that have not been found.
         */
        for (qup = quplist; qup; qup = qup->next) {
-               struct quota2_val *q = qup->q2e.q2e_val;
+               struct ufs_quota_entry *q = qup->qe;
                if (qup->flags & FOUND) {
                        qup->flags &= ~FOUND;
                        continue;
                }
-               q[QL_BLOCK].q2v_softlimit = UQUAD_MAX;
-               q[QL_BLOCK].q2v_hardlimit = UQUAD_MAX;
-               q[QL_BLOCK].q2v_grace = 0;
-               q[QL_FILE].q2v_softlimit = UQUAD_MAX;
-               q[QL_FILE].q2v_hardlimit = UQUAD_MAX;
-               q[QL_FILE].q2v_grace = 0;
+               q[QL_BLK].ufsqe_softlimit = UQUAD_MAX;
+               q[QL_BLK].ufsqe_hardlimit = UQUAD_MAX;
+               q[QL_BLK].ufsqe_grace = 0;
+               q[QL_FL].ufsqe_softlimit = UQUAD_MAX;
+               q[QL_FL].ufsqe_hardlimit = UQUAD_MAX;
+               q[QL_FL].ufsqe_grace = 0;
        }
        return 1;
 }
@@ -1007,7 +1023,7 @@
 }
 
 static void
-clearpriv(int argc, char **argv, const char *filesys, int quotatype)
+clearpriv(int argc, char **argv, const char *filesys, int quotaclass)
 {
        prop_array_t cmds, datas;
        prop_dictionary_t protodict, dict, data, cmd;
@@ -1027,7 +1043,7 @@
        }
 
        for ( ; argc > 0; argc--, argv++) {
-               if ((id = getentry(*argv, quotatype)) == -1)
+               if ((id = getentry(*argv, quotaclass)) == -1)
                        continue;
                data = prop_dictionary_create();
                if (data == NULL)
@@ -1039,8 +1055,8 @@
                if (!prop_array_add_and_rel(datas, data))
                        err(1, "prop_array_add(data)");
        }
-       if (!quota2_prop_add_command(cmds, "clear", qfextension[quotatype],
-           datas))
+       if (!quota2_prop_add_command(cmds, "clear",
+           ufs_quota_class_names[quotaclass], datas))
                err(1, "prop_add_command");
 
        if (!prop_dictionary_set(protodict, "commands", cmds))
@@ -1090,7 +1106,8 @@
                if (error8) {
                        errno = error8;
                        warn("clear %s quota entries on %s",
-                           qfextension[quotatype], fst[i].f_mntonname);
+                           ufs_quota_class_names[quotaclass],
+                           fst[i].f_mntonname);
                }
                prop_object_release(dict);
        }
Index: usr.sbin/quotacheck/Makefile
===================================================================
RCS file: /cvsroot/src/usr.sbin/quotacheck/Makefile,v
retrieving revision 1.19
diff -u -r1.19 Makefile
--- usr.sbin/quotacheck/Makefile        6 Mar 2011 23:07:23 -0000       1.19
+++ usr.sbin/quotacheck/Makefile        18 Mar 2011 16:00:44 -0000
@@ -9,6 +9,7 @@
 DPADD= ${LIBUTIL}
 LDADD+=        -lutil
 CPPFLAGS+=-I${NETBSDSRCDIR}/sbin/fsck -I${NETBSDSRCDIR}/usr.bin/quota
+CPPFLAGS+=-I${NETBSDSRCDIR}/sys
 .PATH: ${NETBSDSRCDIR}/sbin/fsck ${NETBSDSRCDIR}/sys/ufs/ffs 
${NETBSDSRCDIR}/usr.bin/quota
 SRCS+=  quotautil.c
 
Index: usr.sbin/quotactl/Makefile
===================================================================
RCS file: /cvsroot/src/usr.sbin/quotactl/Makefile,v
retrieving revision 1.2
diff -u -r1.2 Makefile
--- usr.sbin/quotactl/Makefile  6 Mar 2011 17:08:43 -0000       1.2
+++ usr.sbin/quotactl/Makefile  18 Mar 2011 16:00:44 -0000
@@ -7,10 +7,7 @@
 MAN=   quotactl.8
 
 CPPFLAGS+=-I${NETBSDSRCDIR}/sys 
-DPADD= ${LIBPROP}
-LDADD= -lprop
-
-.PATH: ${NETBSDSRCDIR}/sys/ufs/ufs 
-SRCS+= quota2_prop.c
+DPADD= ${LIBQUOTA} ${LIBPROP} ${LIBRPCSVC}
+LDADD= -lquota -lprop -lrpcsvc
 
 .include <bsd.prog.mk>
Index: usr.sbin/quotactl/quotactl.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/quotactl/quotactl.c,v
retrieving revision 1.2
diff -u -r1.2 quotactl.c
--- usr.sbin/quotactl/quotactl.c        6 Mar 2011 17:08:43 -0000       1.2
+++ usr.sbin/quotactl/quotactl.c        18 Mar 2011 16:00:44 -0000
@@ -48,7 +48,7 @@
 #include <string.h>
 #include <unistd.h>
 
-#include <ufs/ufs/quota2_prop.h>
+#include <quota/quotaprop.h>
 
 void usage(void);
 
Index: usr.sbin/quotaon/Makefile
===================================================================
RCS file: /cvsroot/src/usr.sbin/quotaon/Makefile,v
retrieving revision 1.7
diff -u -r1.7 Makefile
--- usr.sbin/quotaon/Makefile   6 Mar 2011 23:24:33 -0000       1.7
+++ usr.sbin/quotaon/Makefile   18 Mar 2011 16:00:44 -0000
@@ -13,12 +13,9 @@
 .PATH:  ${NETBSDSRCDIR}/usr.bin/quota
 SRCS+=  quotautil.c
 CPPFLAGS+=-I${NETBSDSRCDIR}/usr.bin/quota
-
 CPPFLAGS+=-I${NETBSDSRCDIR}/sys
-DPADD= ${LIBPROP}
-LDADD= -lprop
 
-.PATH: ${NETBSDSRCDIR}/sys/ufs/ufs
-SRCS+= quota2_prop.c
+DPADD= ${LIBQUOTA} ${LIBPROP} ${LIBRPCSVC}
+LDADD= -lquota -lprop -lrpcsvc
 
 .include <bsd.prog.mk>
Index: usr.sbin/quotaon/quotaon.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/quotaon/quotaon.c,v
retrieving revision 1.25
diff -u -r1.25 quotaon.c
--- usr.sbin/quotaon/quotaon.c  6 Mar 2011 23:24:33 -0000       1.25
+++ usr.sbin/quotaon/quotaon.c  18 Mar 2011 16:00:44 -0000
@@ -53,7 +53,7 @@
 #include <sys/file.h>
 #include <sys/mount.h>
 
-#include <ufs/ufs/quota2_prop.h>
+#include <quota/quotaprop.h>
 #include <ufs/ufs/quota1.h>
 #include <sys/quota.h>
 
Index: usr.sbin/repquota/Makefile
===================================================================
RCS file: /cvsroot/src/usr.sbin/repquota/Makefile,v
retrieving revision 1.7
diff -u -r1.7 Makefile
--- usr.sbin/repquota/Makefile  6 Mar 2011 22:33:55 -0000       1.7
+++ usr.sbin/repquota/Makefile  18 Mar 2011 16:00:44 -0000
@@ -8,12 +8,12 @@
 MAN=   repquota.8
 
 CPPFLAGS+=-I${NETBSDSRCDIR}/sys -I${NETBSDSRCDIR}/usr.bin/quota
-DPADD= ${LIBPROP}
-LDADD= -lprop
+DPADD= ${LIBQUOTA} ${LIBPROP} ${LIBRPCSVC}
+LDADD= -lquota -lprop -lrpcsvc
 
 .PATH: ${NETBSDSRCDIR}/usr.bin/quota
 SRCS+= printquota.c quotautil.c
 .PATH: ${NETBSDSRCDIR}/sys/ufs/ufs 
-SRCS+= quota2_prop.c quota2_subr.c quota1_subr.c
+SRCS+= quota1_subr.c
 
 .include <bsd.prog.mk>
Index: usr.sbin/repquota/repquota.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/repquota/repquota.c,v
retrieving revision 1.29
diff -u -r1.29 repquota.c
--- usr.sbin/repquota/repquota.c        7 Mar 2011 11:56:31 -0000       1.29
+++ usr.sbin/repquota/repquota.c        18 Mar 2011 16:00:44 -0000
@@ -53,8 +53,6 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/statvfs.h>
-#include <prop/proplib.h>
-#include <sys/quota.h>
 
 #include <errno.h>
 #include <err.h>
@@ -66,24 +64,26 @@
 #include <string.h>
 #include <unistd.h>
 
-#include <ufs/ufs/quota2_prop.h>
+#include <quota/quotaprop.h>
+#include <quota/quota.h>
 #include <ufs/ufs/quota1.h>
+#include <sys/quota.h>
 
 #include "printquota.h"
 #include "quotautil.h"
 
 struct fileusage {
        struct  fileusage *fu_next;
-       struct  quota2_entry fu_q2e;
+       struct  ufs_quota_entry fu_qe[QUOTA_NLIMITS];
        uint32_t        fu_id;
        char    fu_name[1];
        /* actually bigger */
 };
 #define FUHASH 1024    /* must be power of two */
-static struct fileusage *fuhead[MAXQUOTAS][FUHASH];
-static uint32_t highid[MAXQUOTAS];     /* highest addid()'ed identifier per 
type */
-int valid[MAXQUOTAS];
-static struct quota2_entry defaultq2e[MAXQUOTAS];
+static struct fileusage *fuhead[QUOTA_NCLASS][FUHASH];
+static uint32_t highid[QUOTA_NCLASS];  /* highest addid()'ed identifier per 
class */
+int valid[QUOTA_NCLASS];
+static struct ufs_quota_entry defaultqe[QUOTA_NCLASS][QUOTA_NLIMITS];
 
 static int     vflag = 0;              /* verbose */
 static int     aflag = 0;              /* all file systems */
@@ -158,18 +158,18 @@
                        continue;
                if (aflag) {
                        if (gflag)
-                               errs += repquota(&fst[i], GRPQUOTA);
+                               errs += repquota(&fst[i], QUOTA_CLASS_GROUP);
                        if (uflag)
-                               errs += repquota(&fst[i], USRQUOTA);
+                               errs += repquota(&fst[i], QUOTA_CLASS_USER);
                        continue;
                }
                if ((argnum = oneof(fst[i].f_mntonname, argv, argc)) >= 0 ||
                    (argnum = oneof(fst[i].f_mntfromname, argv, argc)) >= 0) {
                        done |= 1U << argnum;
                        if (gflag)
-                               errs += repquota(&fst[i], GRPQUOTA);
+                               errs += repquota(&fst[i], QUOTA_CLASS_GROUP);
                        if (uflag)
-                               errs += repquota(&fst[i], USRQUOTA);
+                               errs += repquota(&fst[i], QUOTA_CLASS_USER);
                }
        }
        if (xflag)
@@ -191,25 +191,26 @@
 }
 
 static int
-repquota(const struct statvfs *vfs, int type)
+repquota(const struct statvfs *vfs, int class)
 {
-       if (repquota2(vfs, type) != 0)
-               return repquota1(vfs, type);
+       if (repquota2(vfs, class) != 0)
+               return repquota1(vfs, class);
        return 0;
 }
 
 static int
-repquota2(const struct statvfs *vfs, int type)
+repquota2(const struct statvfs *vfs, int class)
 {
        prop_dictionary_t dict, data, cmd;
        prop_array_t cmds, datas;
        struct plistref pref;
        int8_t error8, version = 0;
        prop_object_iterator_t cmditer, dataiter;
-       struct quota2_entry *q2ep;
+       struct ufs_quota_entry *qep;
        struct fileusage *fup;
        const char *strid;
        uint32_t id;
+       uint64_t *values[QUOTA_NLIMITS];
 
        dict = quota2_prop_create();
        cmds = prop_array_create();
@@ -217,10 +218,11 @@
 
        if (dict == NULL || cmds == NULL || datas == NULL)
                errx(1, "can't allocate proplist");
-       if (!quota2_prop_add_command(cmds, "getall", qfextension[type], datas))
+       if (!quota2_prop_add_command(cmds, "getall",
+           ufs_quota_class_names[class], datas))
                err(1, "prop_add_command");
-       if (!quota2_prop_add_command(cmds, "get version", qfextension[type],
-            prop_array_create()))
+       if (!quota2_prop_add_command(cmds, "get version",
+           ufs_quota_class_names[class], prop_array_create()))
                err(1, "prop_add_command");
        if (!prop_dictionary_set(dict, "commands", cmds))
                err(1, "prop_dictionary_set(command)");
@@ -260,7 +262,8 @@
                        prop_object_release(dict);
                        if (error8 != EOPNOTSUPP) {
                                errno = error8;
-                               warn("get %s quotas", qfextension[type]);
+                               warn("get %s quotas",
+                                   ufs_quota_class_names[class]);
                        }
                        return error8;
                }
@@ -281,7 +284,7 @@
                if (dataiter == NULL)
                        err(1, "prop_array_iterator");
 
-               valid[type] = 1;
+               valid[class] = 1;
                while ((data = prop_object_iterator_next(dataiter)) != NULL) {
                        strid = NULL;
                        if (!prop_dictionary_get_uint32(data, "id", &id)) {
@@ -293,29 +296,34 @@
                                            "wrong id string %s in quota entry",
                                            strid);
                                }
-                               q2ep = &defaultq2e[type];
+                               qep = defaultqe[class];
                        } else {
-                               if ((fup = lookup(id, type)) == 0)
-                                       fup = addid(id, type, (char *)0);
-                               q2ep = &fup->fu_q2e;
-                               q2ep->q2e_uid = id;
+                               if ((fup = lookup(id, class)) == 0)
+                                       fup = addid(id, class, (char *)0);
+                               qep = fup->fu_qe;
                        }
+                       values[QUOTA_LIMIT_BLOCK] =
+                           &qep[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit;
+                       values[QUOTA_LIMIT_FILE] =
+                           &qep[QUOTA_LIMIT_FILE].ufsqe_hardlimit;
                                
-                       errno = quota2_dict_get_q2e_usage(data, q2ep);
+                       errno = proptoquota64(data, values,
+                           ufs_quota_entry_names, UFS_QUOTA_NENTRIES,
+                           ufs_quota_limit_names, QUOTA_NLIMITS);
                        if (errno)
-                               err(1, "quota2_dict_get_q2e_usage");
+                               err(1, "proptoquota64");
                }
                prop_object_iterator_release(dataiter);
        }
        prop_object_iterator_release(cmditer);
        prop_object_release(dict);
        if (xflag == 0)
-               printquotas(type, vfs, version);
+               printquotas(class, vfs, version);
        return 0;
 }
 
 static int
-repquota1(const struct statvfs *vfs, int type)
+repquota1(const struct statvfs *vfs, int class)
 {
        char qfpathname[MAXPATHLEN];
        struct fstab *fs;
@@ -324,6 +332,7 @@
        uint32_t id;
        struct dqblk dqbuf;
        time_t bgrace = MAX_DQ_TIME, igrace = MAX_DQ_TIME;
+       int type = ufsclass2qtype(class);
 
        setfsent();
        while ((fs = getfsent()) != NULL) {
@@ -357,59 +366,59 @@
                    dqbuf.dqb_bsoftlimit == 0 && dqbuf.dqb_bhardlimit == 0 &&
                    dqbuf.dqb_isoftlimit == 0 && dqbuf.dqb_ihardlimit == 0)
                        continue;
-               if ((fup = lookup(id, type)) == 0)
-                       fup = addid(id, type, (char *)0);
-               dqblk2q2e(&dqbuf, &fup->fu_q2e);
-               fup->fu_q2e.q2e_val[QL_BLOCK].q2v_grace = bgrace;
-               fup->fu_q2e.q2e_val[QL_FILE].q2v_grace = igrace;
-       }
-       defaultq2e[type].q2e_val[QL_BLOCK].q2v_grace = bgrace;
-       defaultq2e[type].q2e_val[QL_FILE].q2v_grace = igrace;
-       defaultq2e[type].q2e_val[QL_BLOCK].q2v_softlimit = 
-           defaultq2e[type].q2e_val[QL_BLOCK].q2v_hardlimit = 
-           defaultq2e[type].q2e_val[QL_FILE].q2v_softlimit = 
-           defaultq2e[type].q2e_val[QL_FILE].q2v_hardlimit = UQUAD_MAX;
+               if ((fup = lookup(id, class)) == 0)
+                       fup = addid(id, class, (char *)0);
+               dqblk2ufsqe(&dqbuf, fup->fu_qe);
+               fup->fu_qe[QUOTA_LIMIT_BLOCK].ufsqe_grace = bgrace;
+               fup->fu_qe[QUOTA_LIMIT_FILE].ufsqe_grace = igrace;
+       }
+       defaultqe[class][QUOTA_LIMIT_BLOCK].ufsqe_grace = bgrace;
+       defaultqe[class][QUOTA_LIMIT_FILE].ufsqe_grace = igrace;
+       defaultqe[class][QUOTA_LIMIT_BLOCK].ufsqe_softlimit = 
+           defaultqe[class][QUOTA_LIMIT_BLOCK].ufsqe_hardlimit = 
+           defaultqe[class][QUOTA_LIMIT_FILE].ufsqe_softlimit = 
+           defaultqe[class][QUOTA_LIMIT_FILE].ufsqe_hardlimit = UQUAD_MAX;
        fclose(qf);
-       valid[type] = 1;
+       valid[class] = 1;
        if (xflag == 0)
-               printquotas(type, vfs, 1);
+               printquotas(class, vfs, 1);
        return 0;
 }
 
 static void
-printquotas(int type, const struct statvfs *vfs, int version)
+printquotas(int class, const struct statvfs *vfs, int version)
 {
        static int multiple = 0;
        uint32_t id;
        int i;
        struct fileusage *fup;
-       struct quota2_val *q;
-       const char *timemsg[N_QL];
-       char overchar[N_QL];
+       struct ufs_quota_entry *q;
+       const char *timemsg[QUOTA_NLIMITS];
+       char overchar[QUOTA_NLIMITS];
        time_t now;
        char b0[2][20], b1[20], b2[20], b3[20];
 
-       switch(type) {
-       case  GRPQUOTA:
+       switch(class) {
+       case  QUOTA_CLASS_GROUP:
                {
                struct group *gr;
                setgrent();
                while ((gr = getgrent()) != 0)
-                       (void)addid(gr->gr_gid, GRPQUOTA, gr->gr_name);
+                       (void)addid(gr->gr_gid, QUOTA_CLASS_GROUP, gr->gr_name);
                endgrent();
                break;
                }
-       case USRQUOTA:
+       case QUOTA_CLASS_USER:
                {
                struct passwd *pw;
                setpwent();
                while ((pw = getpwent()) != 0)
-                       (void)addid(pw->pw_uid, USRQUOTA, pw->pw_name);
+                       (void)addid(pw->pw_uid, QUOTA_CLASS_USER, pw->pw_name);
                endpwent();
                break;
                }
        default:
-               errx(1, "unknown quota type %d", type);
+               errx(1, "unknown quota class %d", class);
        }
 
        time(&now);
@@ -418,54 +427,62 @@
                printf("\n");
        if (vflag)
                printf("*** Report for %s quotas on %s (%s, version %d)\n",
-                   qfextension[type], vfs->f_mntonname, vfs->f_mntfromname,
-                   version);
+                   ufs_quota_class_names[class], vfs->f_mntonname,
+                   vfs->f_mntfromname, version);
        printf("                        Block limits               "
            "File limits\n");
-       printf(type == USRQUOTA ? "User " : "Group");
+       printf(class == QUOTA_CLASS_USER ? "User " : "Group");
        printf("            used     soft     hard  grace      used"
            "soft    hard  grace\n");
-       for (id = 0; id <= highid[type]; id++) {
-               fup = qremove(id, type);
-               q = fup->fu_q2e.q2e_val;
+       for (id = 0; id <= highid[class]; id++) {
+               fup = qremove(id, class);
+               q = fup->fu_qe;
                if (fup == 0)
                        continue;
-               for (i = 0; i < N_QL; i++) {
-                       switch (QL_STATUS(quota2_check_limit(&q[i], 1, now))) {
+               for (i = 0; i < QUOTA_NLIMITS; i++) {
+                       switch (QL_STATUS(quota_check_limit(q[i].ufsqe_cur, 1,
+                           q[i].ufsqe_softlimit, q[i].ufsqe_hardlimit,
+                           q[i].ufsqe_time, now))) {
                        case QL_S_DENY_HARD:
                        case QL_S_DENY_GRACE:
                        case QL_S_ALLOW_SOFT:
                                timemsg[i] = timeprt(b0[i], 8, now,
-                                   q[i].q2v_time);
+                                   q[i].ufsqe_time);
                                overchar[i] = '+';
                                break;
                        default:
                                timemsg[i] =  (vflag && version == 2) ?
-                                   timeprt(b0[i], 8, 0, q[i].q2v_grace) : "";
+                                   timeprt(b0[i], 8, 0, q[i].ufsqe_grace) : "";
                                overchar[i] = '-';
                                break;
                        }
                }
 
-               if (q[QL_BLOCK].q2v_cur == 0 &&
-                   q[QL_FILE].q2v_cur == 0 && vflag == 0 &&
-                   overchar[QL_BLOCK] == '-' && overchar[QL_FILE] == '-')
+               if (q[QUOTA_LIMIT_BLOCK].ufsqe_cur == 0 &&
+                   q[QUOTA_LIMIT_FILE].ufsqe_cur == 0 && vflag == 0 &&
+                   overchar[QUOTA_LIMIT_BLOCK] == '-' &&
+                   overchar[QUOTA_LIMIT_FILE] == '-')
                        continue;
                if (strlen(fup->fu_name) > 9)
                        printf("%s ", fup->fu_name);
                else
                        printf("%-10s", fup->fu_name);
                printf("%c%c%9s%9s%9s%7s",
-                       overchar[QL_BLOCK], overchar[QL_FILE],
-                       intprt(b1, 10, q[QL_BLOCK].q2v_cur, HN_B, hflag),
-                       intprt(b2, 10, q[QL_BLOCK].q2v_softlimit, HN_B, hflag),
-                       intprt(b3, 10, q[QL_BLOCK].q2v_hardlimit, HN_B, hflag),
-                       timemsg[QL_BLOCK]);
+                       overchar[QUOTA_LIMIT_BLOCK], overchar[QUOTA_LIMIT_FILE],
+                       intprt(b1, 10, q[QUOTA_LIMIT_BLOCK].ufsqe_cur,
+                         HN_B, hflag),
+                       intprt(b2, 10, q[QUOTA_LIMIT_BLOCK].ufsqe_softlimit,
+                         HN_B, hflag),
+                       intprt(b3, 10, q[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit,
+                         HN_B, hflag),
+                       timemsg[QUOTA_LIMIT_BLOCK]);
                printf("  %8s%8s%8s%7s\n",
-                       intprt(b1, 9, q[QL_FILE].q2v_cur, 0, hflag),
-                       intprt(b2, 9, q[QL_FILE].q2v_softlimit, 0, hflag),
-                       intprt(b3, 9, q[QL_FILE].q2v_hardlimit, 0, hflag),
-                       timemsg[QL_FILE]);
+                       intprt(b1, 9, q[QUOTA_LIMIT_FILE].ufsqe_cur, 0, hflag),
+                       intprt(b2, 9, q[QUOTA_LIMIT_FILE].ufsqe_softlimit,
+                         0, hflag),
+                       intprt(b3, 9, q[QUOTA_LIMIT_FILE].ufsqe_hardlimit,
+                         0, hflag),
+                       timemsg[QUOTA_LIMIT_FILE]);
                free(fup);
        }
 }
@@ -477,7 +494,8 @@
        struct fileusage *fup;
        prop_dictionary_t dict, data;
        prop_array_t cmds, datas;
-       int type;
+       int class;
+       uint64_t *valuesp[QUOTA_NLIMITS];
 
        dict = quota2_prop_create();
        cmds = prop_array_create();
@@ -487,33 +505,44 @@
        }
 
 
-       for (type = 0; type < MAXQUOTAS; type++) {
-               if (valid[type] == 0)
+       for (class = 0; class < QUOTA_NCLASS; class++) {
+               if (valid[class] == 0)
                        continue;
                datas = prop_array_create();
                if (datas == NULL)
                        errx(1, "can't allocate proplist");
-               data = q2etoprop(&defaultq2e[type], 1);
+               valuesp[QUOTA_LIMIT_BLOCK] =
+                   &defaultqe[class][QUOTA_LIMIT_BLOCK].ufsqe_hardlimit;
+               valuesp[QUOTA_LIMIT_FILE] =
+                   &defaultqe[class][QUOTA_LIMIT_FILE].ufsqe_hardlimit;
+               data = quota64toprop(0, 1, valuesp,
+                   ufs_quota_entry_names, UFS_QUOTA_NENTRIES,
+                   ufs_quota_limit_names, QUOTA_NLIMITS);
                if (data == NULL)
-                       err(1, "q2etoprop(default)");
+                       err(1, "quota64toprop(default)");
                if (!prop_array_add_and_rel(datas, data))
                        err(1, "prop_array_add(data)");
 
-               for (id = 0; id <= highid[type]; id++) {
-                       fup = qremove(id, type);
+               for (id = 0; id <= highid[class]; id++) {
+                       fup = qremove(id, class);
                        if (fup == 0)
                                continue;
-                       fup->fu_q2e.q2e_uid = id;
-                       data = q2etoprop(&fup->fu_q2e, 0);
+                       valuesp[QUOTA_LIMIT_BLOCK] =
+                           &fup->fu_qe[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit;
+                       valuesp[QUOTA_LIMIT_FILE] =
+                           &fup->fu_qe[QUOTA_LIMIT_FILE].ufsqe_hardlimit;
+                       data = quota64toprop(id, 0, valuesp,
+                           ufs_quota_entry_names, UFS_QUOTA_NENTRIES,
+                           ufs_quota_limit_names, QUOTA_NLIMITS);
                        if (data == NULL)
-                               err(1, "q2etoprop(default)");
+                               err(1, "quota64toprop(id)");
                        if (!prop_array_add_and_rel(datas, data))
                                err(1, "prop_array_add(data)");
                        free(fup);
                }
 
                if (!quota2_prop_add_command(cmds, "set",
-                   qfextension[type], datas))
+                   ufs_quota_class_names[class], datas))
                        err(1, "prop_add_command");
        }
 
@@ -527,27 +556,27 @@
 /*
  * Routines to manage the file usage table.
  *
- * Lookup an id of a specific type.
+ * Lookup an id of a specific class.
  */
 struct fileusage *
-lookup(uint32_t id, int type)
+lookup(uint32_t id, int class)
 {
        struct fileusage *fup;
 
-       for (fup = fuhead[type][id & (FUHASH-1)]; fup != 0; fup = fup->fu_next)
+       for (fup = fuhead[class][id & (FUHASH-1)]; fup != 0; fup = fup->fu_next)
                if (fup->fu_id == id)
                        return fup;
        return NULL;
 }
 /*
- * Lookup and remove an id of a specific type.
+ * Lookup and remove an id of a specific class.
  */
 static struct fileusage *
-qremove(uint32_t id, int type)
+qremove(uint32_t id, int class)
 {
        struct fileusage *fup, **fupp;
 
-       for (fupp = &fuhead[type][id & (FUHASH-1)]; *fupp != 0;) {
+       for (fupp = &fuhead[class][id & (FUHASH-1)]; *fupp != 0;) {
                fup = *fupp;
                if (fup->fu_id == id) {
                        *fupp = fup->fu_next;
@@ -562,31 +591,31 @@
  * Add a new file usage id if it does not already exist.
  */
 static struct fileusage *
-addid(uint32_t id, int type, const char *name)
+addid(uint32_t id, int class, const char *name)
 {
        struct fileusage *fup, **fhp;
        struct group *gr = NULL;
        struct passwd *pw = NULL;
        size_t len;
 
-       if ((fup = lookup(id, type)) != NULL) {
+       if ((fup = lookup(id, class)) != NULL) {
                return fup;
        }
        if (name == NULL) {
-               switch(type) {
-               case  GRPQUOTA:
+               switch(class) {
+               case  QUOTA_CLASS_GROUP:
                        gr = getgrgid(id);
                        
                        if (gr != NULL)
                                name = gr->gr_name;
                        break;
-               case USRQUOTA:
+               case QUOTA_CLASS_USER:
                        pw = getpwuid(id);
                        if (pw)
                                name = pw->pw_name;
                        break;
                default:
-                       errx(1, "unknown quota type %d\n", type);
+                       errx(1, "unknown quota class %d\n", class);
                }
        }
 
@@ -596,17 +625,18 @@
                len = 10;
        if ((fup = calloc(1, sizeof(*fup) + len)) == NULL)
                err(1, "out of memory for fileusage structures");
-       fhp = &fuhead[type][id & (FUHASH - 1)];
+       fhp = &fuhead[class][id & (FUHASH - 1)];
        fup->fu_next = *fhp;
        *fhp = fup;
        fup->fu_id = id;
-       if (id > highid[type])
-               highid[type] = id;
+       if (id > highid[class])
+               highid[class] = id;
        if (name) {
                memmove(fup->fu_name, name, len + 1);
        } else {
                snprintf(fup->fu_name, len + 1, "%u", id);
        }
-       fup->fu_q2e = defaultq2e[type];
+       fup->fu_qe[QUOTA_LIMIT_BLOCK] = defaultqe[class][QUOTA_LIMIT_BLOCK];
+       fup->fu_qe[QUOTA_LIMIT_FILE] = defaultqe[class][QUOTA_LIMIT_FILE];
        return fup;
 }
diff -urN /tmp/newdir/Makefile common/include/quota/Makefile
--- /tmp/newdir/Makefile        1970-01-01 01:00:00.000000000 +0100
+++ common/include/quota/Makefile       2011-03-16 13:38:01.000000000 +0100
@@ -0,0 +1,6 @@
+#      $NetBSD: Makefile,v 1.3 2007/08/17 11:05:04 pavel Exp $
+
+INCS=  quotaprop.h quota.h
+INCSDIR=       /usr/include/quota
+
+.include <bsd.prog.mk>
diff -urN /tmp/newdir/quota.h common/include/quota/quota.h
--- /tmp/newdir/quota.h 1970-01-01 01:00:00.000000000 +0100
+++ common/include/quota/quota.h        2011-03-16 16:44:50.000000000 +0100
@@ -0,0 +1,61 @@
+/* $NetBSD: quota2_prop.h,v 1.2 2011/03/06 17:08:39 bouyer Exp $ */
+/*-
+  * Copyright (c) 2010 Manuel Bouyer
+  * All rights reserved.
+  * This software is distributed under the following condiions
+  * compliant with the NetBSD foundation policy.
+  *
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGE.
+  */
+
+#ifndef _QUOTA_QUOTA_H
+#define _QUOTA_QUOTA_H
+#include <sys/types.h>
+#include <quota/quotaprop.h>
+
+/* check a quota usage against limits (assumes UFS semantic) */
+int quota_check_limit(uint64_t, uint64_t,  uint64_t, uint64_t, time_t, time_t);
+/* return values for above */
+#define QL_S_ALLOW_OK  0x00 /* below soft limit */
+#define QL_S_ALLOW_SOFT        0x01 /* over soft limit */
+#define QL_S_DENY_GRACE        0x02 /* over soft limit, grace time expired */
+#define QL_S_DENY_HARD 0x03 /* over hard limit */
+ 
+#define QL_F_CROSS     0x80 /* crossing soft limit */
+
+#define QL_STATUS(x)   ((x) & 0x0f)
+#define QL_FLAGS(x)    ((x) & 0xf0)
+
+/*
+ * retrieve quotas with ufs semantics from vfs, for the given id and class.
+ * second argument points to a struct ufs_quota_entry array of QUOTA_NLIMITS
+ * elements.
+ */
+int getufsquota(const char *, struct ufs_quota_entry *, uid_t, const char *);
+
+/* same as above, but for NFS */
+int getnfsquota(const char *, struct ufs_quota_entry *, uid_t, const char *);
+
+/* call one of the above, if appropriate, after a statvfs(2) */
+int getfsquota(const char *, struct ufs_quota_entry *, uid_t, const char *);
+
+#endif /* _QUOTA_QUOTA_H */
diff -urN /tmp/newdir/quotaprop.h common/include/quota/quotaprop.h
--- /tmp/newdir/quotaprop.h     1970-01-01 01:00:00.000000000 +0100
+++ common/include/quota/quotaprop.h    2011-03-16 20:17:44.000000000 +0100
@@ -0,0 +1,83 @@
+/* $NetBSD: quota2_prop.h,v 1.2 2011/03/06 17:08:39 bouyer Exp $ */
+/*-
+  * Copyright (c) 2010 Manuel Bouyer
+  * All rights reserved.
+  * This software is distributed under the following condiions
+  * compliant with the NetBSD foundation policy.
+  *
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGE.
+  */
+
+#ifndef _QUOTA_QUOTAPROP_H
+#define _QUOTA_QUOTAPROP_H
+#include <prop/proplib.h>
+#include <sys/quota.h>
+
+int quotaprop_dict_get_uint64(prop_dictionary_t, uint64_t[],
+    const char *[], int, bool);
+int proptoquota64(prop_dictionary_t, uint64_t *[], const char *[], int,
+    const char *[], int);
+
+int quota2_get_cmds(prop_dictionary_t, prop_array_t *);
+prop_dictionary_t quota2_prop_create(void);
+bool quota2_prop_add_command(prop_array_t, const char *, const char *,
+    prop_array_t);
+
+prop_dictionary_t limits64toprop(uint64_t[], const char *[], int);
+prop_dictionary_t quota64toprop(uid_t, int, uint64_t *[], const char *[], int,
+    const char *[], int);
+
+/* structure used to describe a UFS-like quota entry */
+struct ufs_quota_entry {
+        uint64_t ufsqe_hardlimit; /* absolute limit */
+       uint64_t ufsqe_softlimit; /* overflowable limit */
+       uint64_t ufsqe_cur; /* current usage */
+       int64_t ufsqe_time; /* grace expiration date for softlimit overflow */
+       int64_t ufsqe_grace; /* allowed time for softlimit overflow */
+};
+
+/* array of strings for the above */
+#define UFS_QUOTA_ENTRY_NAMES \
+    {QUOTADICT_LIMIT_HARD, \
+     QUOTADICT_LIMIT_SOFT, \
+     QUOTADICT_LIMIT_USAGE, \
+     QUOTADICT_LIMIT_ETIME, \
+     QUOTADICT_LIMIT_GTIME \
+    }
+#define UFS_QUOTA_NENTRIES 5
+extern const char *ufs_quota_entry_names[];
+
+/* array of strings for limit types and associated #define */
+extern const char *ufs_quota_limit_names[];
+#define QUOTA_LIMIT_BLOCK 0
+#define QUOTA_LIMIT_FILE 1
+#define QUOTA_NLIMITS 2
+#define QUOTA_LIMIT_NAMES { QUOTADICT_LTYPE_BLOCK, QUOTADICT_LTYPE_FILE }
+
+/* array of strings for quota class and associated #define */
+extern const char *ufs_quota_class_names[];
+#define QUOTA_CLASS_USER 0
+#define QUOTA_CLASS_GROUP 1
+#define QUOTA_NCLASS 2
+#define QUOTA_CLASS_NAMES { QUOTADICT_CLASS_USER, QUOTADICT_CLASS_GROUP }
+
+#endif /* _QUOTA_QUOTAPROP_H */
diff -urN /tmp/newdir/Makefile.inc common/lib/libquota/Makefile.inc
--- /tmp/newdir/Makefile.inc    1970-01-01 01:00:00.000000000 +0100
+++ common/lib/libquota/Makefile.inc    2011-03-16 18:04:05.000000000 +0100
@@ -0,0 +1,4 @@
+#      $NetBSD: Makefile.inc,v 1.1 2008/12/16 22:33:11 christos Exp $
+
+.PATH.c: ${.PARSEDIR}
+SRCS+= quotaprop.c quotasubr.c
diff -urN /tmp/newdir/quotaprop.c common/lib/libquota/quotaprop.c
--- /tmp/newdir/quotaprop.c     1970-01-01 01:00:00.000000000 +0100
+++ common/lib/libquota/quotaprop.c     2011-03-16 23:02:45.000000000 +0100
@@ -0,0 +1,216 @@
+/* $NetBSD: quota2_prop.c,v 1.2 2011/03/06 17:08:39 bouyer Exp $ */
+/*-
+  * Copyright (c) 2011 Manuel Bouyer
+  * All rights reserved.
+  * This software is distributed under the following condiions
+  * compliant with the NetBSD foundation policy.
+  *
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGE.
+  */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/inttypes.h>
+#include <sys/errno.h>
+
+#include <quota/quotaprop.h>
+
+/*
+ * update values from value[] using dict entries whose key is stored
+ * in name[]. Unknown keys are ignored. If update is false,
+ * a key in name[] but not in dict is an error.
+ * name[] may have NULL pointers to skip a value[]
+ */
+int
+quotaprop_dict_get_uint64(prop_dictionary_t dict, uint64_t value[],
+    const char *name[], int nvalues, bool update)
+{
+       int i;
+       uint64_t v;
+
+       for (i = 0; i < nvalues; i++) {
+               if (name[i] == NULL)
+                       continue;
+               if (!prop_dictionary_get_uint64(dict, name[i], &v)) {
+                       if (!update)
+                               return EINVAL;
+               }
+               value[i] = v;
+       }
+       return 0;
+}
+
+/*
+ * convert a quota entry dictionary to in-memory array of uint64_t's
+ */
+int
+proptoquota64(prop_dictionary_t data, uint64_t *values[], const char 
*valname[],
+    int nvalues, const char *limname[], int nlimits)
+{
+       int i, error;
+       prop_dictionary_t val;
+
+       for (i = 0; i < nlimits; i++) {
+               if (limname[i] == NULL)
+                       continue;
+               if (!prop_dictionary_get_dict(data, limname[i], &val))
+                       return EINVAL;
+               error = quotaprop_dict_get_uint64(val, values[i],
+                   valname, nvalues, false);
+               if (error)
+                       return error;
+       }
+       return 0;
+}
+
+int
+quota2_get_cmds(prop_dictionary_t qdict, prop_array_t *cmds)
+{
+       prop_number_t pn;
+       prop_object_t o;
+
+       pn = prop_dictionary_get(qdict, "interface version");
+       if (pn == NULL)
+               return EINVAL;
+       if (prop_number_integer_value(pn) != 1)
+               return EINVAL;
+
+       o = prop_dictionary_get(qdict, "commands");
+       if (o == NULL)
+               return ENOMEM;
+        if(prop_object_type(o) != PROP_TYPE_ARRAY)
+               return EINVAL;
+       *cmds = o;
+       return 0;
+}
+
+
+prop_dictionary_t
+quota2_prop_create(void)
+{
+       prop_dictionary_t dict = prop_dictionary_create();
+
+       if (dict == NULL)
+               return NULL;
+
+       if (!prop_dictionary_set_uint8(dict, "interface version", 1)) {
+               goto err;
+       }
+       return dict;
+err:
+       prop_object_release(dict);
+       return NULL;
+}
+
+bool
+quota2_prop_add_command(prop_array_t arrcmd, const char *cmd, const char *type,
+    prop_array_t data)
+{
+       prop_dictionary_t dict;
+
+       dict = prop_dictionary_create();
+       if (dict == NULL) {
+               return false;
+       }
+       if (!prop_dictionary_set_cstring(dict, "type", type)) {
+               goto err;
+       }
+       if (!prop_dictionary_set_cstring(dict, "command", cmd)) {
+               goto err;
+       }
+       if (!prop_dictionary_set_and_rel(dict, "data", data)) {
+               goto err;
+       }
+       if (!prop_array_add(arrcmd, dict)) {
+               goto err;
+       }
+       prop_object_release(dict);
+       return true;
+err:
+       prop_object_release(dict);
+       return false;
+}
+
+/* construct a dictionary using array of values and corresponding keys */
+prop_dictionary_t
+limits64toprop(uint64_t value[], const char *name[], int nvalues)
+{
+       int i;
+       prop_dictionary_t dict1 = prop_dictionary_create();
+       if (dict1 == NULL)
+               return NULL;
+
+       for (i = 0;  i < nvalues; i++) {
+               if (name[i] == NULL)
+                       continue;
+               if (!prop_dictionary_set_uint64(dict1, name[i], value[i])) {
+                       prop_object_release(dict1);
+                       return NULL;
+               }
+       }
+       return dict1;
+}
+
+/*
+ * construct a quota entry using provided array of values, array of values
+ * names
+ */
+prop_dictionary_t
+quota64toprop(uid_t uid, int def, uint64_t *values[], const char *valname[],
+    int nvalues, const char *limname[], int nlimits)
+{
+       prop_dictionary_t dict1 = prop_dictionary_create();
+       prop_dictionary_t dict2;
+       int i;
+
+       if (dict1 == NULL)
+               return NULL;
+       if (def) {
+               if (!prop_dictionary_set_cstring_nocopy(dict1, "id",
+                   "default")) {
+                       goto err;
+               }
+       } else {
+               if (!prop_dictionary_set_uint32(dict1, "id", uid)) {
+                       goto err;
+               }
+       }
+       for (i = 0; i < nlimits; i++) {
+               if (limname[i] == NULL)
+                       continue;
+               dict2 = limits64toprop(values[i], valname, nvalues);
+               if (dict2 == NULL)
+                       goto err;
+               if (!prop_dictionary_set_and_rel(dict1, limname[i],
+                   dict2))
+                       goto err;
+       }
+
+       return dict1;
+err:
+       prop_object_release(dict1);
+       return NULL;
+}
+
+const char *ufs_quota_entry_names[] = UFS_QUOTA_ENTRY_NAMES;
+const char *ufs_quota_limit_names[] = QUOTA_LIMIT_NAMES;
+const char *ufs_quota_class_names[] = QUOTA_CLASS_NAMES;
diff -urN /tmp/newdir/quotasubr.c common/lib/libquota/quotasubr.c
--- /tmp/newdir/quotasubr.c     1970-01-01 01:00:00.000000000 +0100
+++ common/lib/libquota/quotasubr.c     2011-03-16 15:50:48.000000000 +0100
@@ -0,0 +1,54 @@
+/* $NetBSD: quota2_prop.c,v 1.2 2011/03/06 17:08:39 bouyer Exp $ */
+/*-
+  * Copyright (c) 2011 Manuel Bouyer
+  * All rights reserved.
+  * This software is distributed under the following condiions
+  * compliant with the NetBSD foundation policy.
+  *
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGE.
+  */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/inttypes.h>
+#include <sys/errno.h>
+
+#include <quota/quota.h>
+
+int
+quota_check_limit(uint64_t cur, uint64_t change, uint64_t soft, uint64_t hard,
+    time_t expire, time_t now)
+{ 
+       if (cur + change > hard) {
+               if (cur <= soft)
+                       return (QL_F_CROSS | QL_S_DENY_HARD);
+               return QL_S_DENY_HARD;
+       } else if (cur + change > soft) {
+               if (cur <= soft)
+                       return (QL_F_CROSS | QL_S_ALLOW_SOFT);
+               if (now > expire) {
+                       return QL_S_DENY_GRACE;
+               }
+               return QL_S_ALLOW_SOFT;
+       }
+       return QL_S_ALLOW_OK;
+} 
diff -urN /tmp/newdir/Makefile lib/libquota/Makefile
--- /tmp/newdir/Makefile        1970-01-01 01:00:00.000000000 +0100
+++ lib/libquota/Makefile       2011-03-17 23:46:30.000000000 +0100
@@ -0,0 +1,17 @@
+#      $NetBSD: Makefile,v 1.63 2010/01/27 19:10:31 drochner Exp $
+#      @(#)Makefile    8.1 (Berkeley) 6/4/93
+
+.include <bsd.own.mk>
+
+.include "${NETBSDSRCDIR}/common/lib/libquota/Makefile.inc"
+
+WARNS= 4
+LIB=   quota
+
+LIBDPLIBS+=     prop  ${.CURDIR}/../libprop
+LIBDPLIBS+=     rpcsvc  ${.CURDIR}/../librpcsvc
+
+SRCS+= getfsquota.c getnfsquota.c getufsquota.c
+MAN=
+
+.include <bsd.lib.mk>
diff -urN /tmp/newdir/getfsquota.c lib/libquota/getfsquota.c
--- /tmp/newdir/getfsquota.c    1970-01-01 01:00:00.000000000 +0100
+++ lib/libquota/getfsquota.c   2011-03-16 18:09:26.000000000 +0100
@@ -0,0 +1,67 @@
+/*     $NetBSD: getvfsquota.c,v 1.5 2011/03/12 12:28:47 bouyer Exp $ */
+
+/*-
+  * Copyright (c) 2011 Manuel Bouyer
+  * All rights reserved.
+  * This software is distributed under the following condiions
+  * compliant with the NetBSD foundation policy.
+  *
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGE.
+  */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: getvfsquota.c,v 1.5 2011/03/12 12:28:47 bouyer Exp $");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <err.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/statvfs.h>
+
+#include <quota/quotaprop.h>
+#include <quota/quota.h>
+
+/* retrieve quotas with ufs semantics from vfs, for the given user id */
+int
+getfsquota(const char *path, struct ufs_quota_entry *qv, uid_t id,
+    const char *class)
+{
+       struct statvfs v;
+
+       if (statvfs(path, &v) < 0) {
+               return -1;
+       }
+       if (strcmp(v.f_fstypename, "nfs"))
+               return getnfsquota(v.f_mntfromname, qv, id, class);
+       else {
+               if ((v.f_flag & ST_QUOTA) == 0)
+                       return 0;
+               /*
+                * assume all quota-enabled local filesystems have UFS
+                * semantic for now
+                */
+               return getufsquota(v.f_mntonname, qv, id, class);
+       }
+}
diff -urN /tmp/newdir/getnfsquota.c lib/libquota/getnfsquota.c
--- /tmp/newdir/getnfsquota.c   1970-01-01 01:00:00.000000000 +0100
+++ lib/libquota/getnfsquota.c  2011-03-16 20:08:50.000000000 +0100
@@ -0,0 +1,208 @@
+/*     $NetBSD: quota.c,v 1.36 2011/03/06 22:36:07 christos Exp $      */
+
+/*
+ * Copyright (c) 1980, 1990, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Robert Elz at The University of Melbourne.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__COPYRIGHT("@(#) Copyright (c) 1980, 1990, 1993\
+ The Regents of the University of California.  All rights reserved.");
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)quota.c    8.4 (Berkeley) 4/28/95";
+#else
+__RCSID("$NetBSD: quota.c,v 1.36 2011/03/06 22:36:07 christos Exp $");
+#endif
+#endif /* not lint */
+
+/*
+ * Disk quota reporting program.
+ */
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <quota/quota.h>
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpcsvc/rquota.h>
+
+/* convert a rquota limit to our semantic */
+static uint64_t
+rqlim2qlim(uint32_t lim)
+{
+       if (lim == 0)
+               return UQUAD_MAX;
+       else
+               return (lim - 1);
+}
+ 
+static int
+callaurpc(const char *host, rpcprog_t prognum, rpcvers_t versnum,
+    rpcproc_t procnum, xdrproc_t inproc, void *in, xdrproc_t outproc, void 
*out)
+{
+       struct sockaddr_in server_addr;
+       enum clnt_stat clnt_stat;
+       struct hostent *hp;
+       struct timeval timeout, tottimeout;
+ 
+       CLIENT *client = NULL;
+       int sock = RPC_ANYSOCK;
+ 
+       if ((hp = gethostbyname(host)) == NULL)
+               return (int) RPC_UNKNOWNHOST;
+       timeout.tv_usec = 0;
+       timeout.tv_sec = 6;
+       memmove(&server_addr.sin_addr, hp->h_addr, hp->h_length);
+       server_addr.sin_family = AF_INET;
+       server_addr.sin_port =  0;
+
+       if ((client = clntudp_create(&server_addr, prognum,
+           versnum, timeout, &sock)) == NULL)
+               return (int) rpc_createerr.cf_stat;
+
+       client->cl_auth = authunix_create_default();
+       tottimeout.tv_sec = 25;
+       tottimeout.tv_usec = 0;
+       clnt_stat = clnt_call(client, procnum, inproc, in,
+           outproc, out, tottimeout);
+ 
+       return (int) clnt_stat;
+}
+
+int
+getnfsquota(const char *mp, struct ufs_quota_entry *qv,
+    uint32_t id, const char *class)
+{
+       struct getquota_args gq_args;
+       struct ext_getquota_args ext_gq_args;
+       struct getquota_rslt gq_rslt;
+       struct timeval tv;
+       char *host, *path;
+       int ret, rpcqtype;
+
+       if (strcmp(class, QUOTADICT_CLASS_USER) == 0)
+               rpcqtype = RQUOTA_USRQUOTA;
+       else if (strcmp(class, QUOTADICT_CLASS_GROUP) == 0)
+               rpcqtype = RQUOTA_GRPQUOTA;
+       else {
+               errno = EINVAL;
+               return -1;
+       }
+
+       /*
+        * must be some form of "hostname:/path"
+        */
+       path = strdup(mp);
+       if (path == NULL) {
+               errno = ENOMEM;
+               return -1;
+       }
+       host = strsep(&path, ":");
+       if (path == NULL) {
+               free(host);
+               return EINVAL;
+       }
+
+       ext_gq_args.gqa_pathp = path;
+       ext_gq_args.gqa_id = id;
+       ext_gq_args.gqa_type = rpcqtype;
+       ret = callaurpc(host, RQUOTAPROG, EXT_RQUOTAVERS,
+           RQUOTAPROC_GETQUOTA, xdr_ext_getquota_args, &ext_gq_args,
+           xdr_getquota_rslt, &gq_rslt);
+       if (ret == RPC_PROGVERSMISMATCH && rpcqtype == RQUOTA_USRQUOTA) {
+               /* try RQUOTAVERS */
+               gq_args.gqa_pathp = path;
+               gq_args.gqa_uid = id;
+               ret = callaurpc(host, RQUOTAPROG, RQUOTAVERS,
+                   RQUOTAPROC_GETQUOTA, xdr_getquota_args, &gq_args,
+                   xdr_getquota_rslt, &gq_rslt);
+       }
+       free(host);
+
+       if (ret != RPC_SUCCESS) {
+               return 0;
+       }
+
+       switch (gq_rslt.status) {
+       case Q_NOQUOTA:
+               break;
+       case Q_EPERM:
+               errno = EACCES;
+               return -1;
+       case Q_OK:
+               gettimeofday(&tv, NULL);
+
+               /* blocks*/
+               qv[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit = rqlim2qlim(
+                   gq_rslt.getquota_rslt_u.gqr_rquota.rq_bhardlimit *
+                   (gq_rslt.getquota_rslt_u.gqr_rquota.rq_bsize / DEV_BSIZE));
+               qv[QUOTA_LIMIT_BLOCK].ufsqe_softlimit = rqlim2qlim(
+                   gq_rslt.getquota_rslt_u.gqr_rquota.rq_bsoftlimit *
+                   (gq_rslt.getquota_rslt_u.gqr_rquota.rq_bsize / DEV_BSIZE));
+               qv[QUOTA_LIMIT_BLOCK].ufsqe_cur =
+                   gq_rslt.getquota_rslt_u.gqr_rquota.rq_curblocks *
+                   (gq_rslt.getquota_rslt_u.gqr_rquota.rq_bsize / DEV_BSIZE);
+               qv[QUOTA_LIMIT_BLOCK].ufsqe_time = (tv.tv_sec +
+                   gq_rslt.getquota_rslt_u.gqr_rquota.rq_btimeleft);
+
+               /* inodes */
+               qv[QUOTA_LIMIT_FILE].ufsqe_hardlimit = rqlim2qlim(
+                   gq_rslt.getquota_rslt_u.gqr_rquota.rq_fhardlimit);
+               qv[QUOTA_LIMIT_FILE].ufsqe_softlimit = rqlim2qlim(
+                   gq_rslt.getquota_rslt_u.gqr_rquota.rq_fsoftlimit);
+               qv[QUOTA_LIMIT_FILE].ufsqe_cur =
+                   gq_rslt.getquota_rslt_u.gqr_rquota.rq_curfiles;
+               qv[QUOTA_LIMIT_FILE].ufsqe_time = (int)(tv.tv_sec +
+                   gq_rslt.getquota_rslt_u.gqr_rquota.rq_ftimeleft);
+               qv[QUOTA_LIMIT_BLOCK].ufsqe_grace =
+                   qv[QUOTA_LIMIT_FILE].ufsqe_grace = 0;
+               return 1;
+       default:
+               /* XXX sert errno and return -1 ? */
+               break;
+       }
+       return 0;
+}
diff -urN /tmp/newdir/getufsquota.c lib/libquota/getufsquota.c
--- /tmp/newdir/getufsquota.c   1970-01-01 01:00:00.000000000 +0100
+++ lib/libquota/getufsquota.c  2011-03-16 18:56:45.000000000 +0100
@@ -0,0 +1,180 @@
+/*     $NetBSD: getvfsquota.c,v 1.5 2011/03/12 12:28:47 bouyer Exp $ */
+
+/*-
+  * Copyright (c) 2011 Manuel Bouyer
+  * All rights reserved.
+  * This software is distributed under the following condiions
+  * compliant with the NetBSD foundation policy.
+  *
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGE.
+  */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: getvfsquota.c,v 1.5 2011/03/12 12:28:47 bouyer Exp $");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <err.h>
+#include <string.h>
+
+#include <sys/types.h>
+
+#include <quota/quotaprop.h>
+#include <quota/quota.h>
+
+/* retrieve quotas with ufs semantics from vfs, for the given user id */
+int
+getufsquota(const char *mp, struct ufs_quota_entry *qv, uid_t id,
+    const char *class)
+{
+       prop_dictionary_t dict, data, cmd;
+       prop_array_t cmds, datas;
+       struct plistref pref;
+       int8_t error8;
+       int retval;
+       const char *cmdstr;
+
+       dict = quota2_prop_create();
+       if (dict == NULL) {
+               errno = ENOMEM;
+               goto end_dict;
+       }
+       cmds = prop_array_create();
+       if (cmds == NULL) {
+               errno = ENOMEM;
+               goto end_cmds;
+       }
+       datas = prop_array_create();
+       if (datas == NULL) {
+               errno = ENOMEM;
+               goto end_datas;
+       }
+       data = prop_dictionary_create();
+       if (data == NULL) {
+               errno = ENOMEM;
+               goto end_data;
+       }
+
+       if (!prop_dictionary_set_uint32(data, "id", id)) {
+               errno = ENOMEM;
+               goto end_data;
+       }
+       if (!prop_array_add_and_rel(datas, data)) {
+               errno = ENOMEM;
+               goto end_datas;
+       }
+       if (!quota2_prop_add_command(cmds, "get", class,  datas)) {
+               errno = ENOMEM;
+               goto end_cmds;
+       }
+       if (!prop_dictionary_set(dict, "commands", cmds)) {
+               errno = ENOMEM;
+               goto end_dict;
+       }
+
+       if (!prop_dictionary_send_syscall(dict, &pref))
+               goto end_dict;
+       prop_object_release(dict);
+
+       if (quotactl(mp, &pref) != 0)
+               return -1;
+       
+       if ((errno = prop_dictionary_recv_syscall(&pref, &dict)) != 0)
+               return -1;
+       
+       if ((errno = quota2_get_cmds(dict, &cmds)) != 0)
+               goto end_dict;
+
+       /* only one command, no need to iter */
+
+       cmd = prop_array_get(cmds, 0);
+       if (cmd == NULL) {
+               errno = EINVAL;
+               goto end_dict;
+       }
+
+       if (!prop_dictionary_get_cstring_nocopy(cmd, "command",
+           &cmdstr)) {
+               errno = EINVAL;
+               goto end_dict;
+       }
+
+       if (strcmp("get", cmdstr) != 0) {
+               errno = EINVAL;
+               goto end_dict;
+       }
+                       
+       if (!prop_dictionary_get_int8(cmd, "return", &error8)) {
+               errno = EINVAL;
+               goto end_dict;
+       }
+
+       if (error8) {
+               prop_object_release(dict);
+               if (error8 != ENOENT && error8 != ENODEV) {
+                       errno = error8;
+                       return -1;
+               }
+               return 0;
+       }
+       datas = prop_dictionary_get(cmd, "data");
+       if (datas == NULL) {
+               errno = EINVAL;
+               goto end_dict;
+       }
+
+       /* only one data, no need to iter */
+       if (prop_array_count(datas) > 0) {
+               uint64_t *values[QUOTA_NLIMITS];
+
+               data = prop_array_get(datas, 0);
+               if (data == NULL) {
+                       errno = EINVAL;
+                       goto end_dict;
+               }
+               values[QUOTA_LIMIT_BLOCK] =
+                   &qv[QUOTA_LIMIT_BLOCK].ufsqe_hardlimit;
+               values[QUOTA_LIMIT_FILE] =
+                   &qv[QUOTA_LIMIT_FILE].ufsqe_hardlimit;
+
+               errno = proptoquota64(data, values, ufs_quota_entry_names,
+                   UFS_QUOTA_NENTRIES, ufs_quota_limit_names, QUOTA_NLIMITS);
+               if (errno)
+                       goto end_dict;
+               retval = 1;
+       } else {
+               retval = 0;
+       }
+       prop_object_release(dict);
+       return retval;
+
+end_data:
+       prop_object_release(data);
+end_datas:
+       prop_object_release(datas);
+end_cmds:
+       prop_object_release(cmds);
+end_dict:
+       prop_object_release(dict);
+       return -1;
+}
diff -urN /tmp/newdir/shlib_version lib/libquota/shlib_version
--- /tmp/newdir/shlib_version   1970-01-01 01:00:00.000000000 +0100
+++ lib/libquota/shlib_version  2011-03-16 12:44:03.000000000 +0100
@@ -0,0 +1,5 @@
+#      $NetBSD: shlib_version,v 1.47 2009/05/13 02:50:32 pgoyette Exp $
+#      Remember to update distrib/sets/lists/base/shl.* when changing
+#
+major=0
+minor=0


Home | Main Index | Thread Index | Old Index