The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/subr_prop.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: subr_prop.c,v 1.12 2003/12/21 11:54:16 simonb Exp $    */
    2 
    3 /*  
    4  * Copyright (c) 2001 Eduardo Horvath.
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. All advertising materials mentioning features or use of this software
   16  *    must display the following acknowledgement:
   17  *      This product includes software developed by Eduardo Horvath.
   18  * 4. The name of the author may not be used to endorse or promote products
   19  *    derived from this software without specific prior written permission
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __KERNEL_RCSID(0, "$NetBSD: subr_prop.c,v 1.12 2003/12/21 11:54:16 simonb Exp $");
   35 
   36 #include <sys/param.h>
   37 #include <sys/systm.h>
   38 #include <sys/malloc.h>
   39 #include <sys/queue.h>
   40 #include <sys/sysctl.h>
   41 #include <sys/properties.h>
   42 
   43 #ifdef DEBUG
   44 
   45 int propdebug = 0;
   46 #define DPRINTF(v, t)   if (propdebug) printf t
   47 #else
   48 #define DPRINTF(v, t)
   49 #endif
   50 
   51 /* 
   52  * Kernel properties database implementation.
   53  *
   54  * While this could theoretically be flat, lookups
   55  * are always done in the following order:
   56  *
   57  *      database, object, name
   58  *
   59  * So we'll lay out the structures to make this efficient.
   60  *
   61  */
   62 #define KDB_SIZE        32      /* Initial hash table size */
   63 #define KDB_MAXLEN      6       /* Max acceptable bucket length */
   64 #define KDB_STEP        2       /* Increment size for hash table */
   65 #define KDB_HASH(v, s)  ((((v)>>16)^((v)>>8))&((s)-1))
   66 
   67 typedef LIST_HEAD(kobj_head, kdbobj) kobj_bucket_t;
   68 
   69 static LIST_HEAD(propdb_list, propdb) propdbs =
   70         LIST_HEAD_INITIALIZER(propdbs);
   71 
   72 struct propdb {
   73         LIST_ENTRY(propdb)      kd_link;
   74         char                    kd_name[MAX_KDBNAME];
   75         size_t                  kd_size;
   76 
   77         /* Hash table of kdbobj structs */
   78         kobj_bucket_t           *kd_obj;
   79         int                     kd_longest;     /* Keep track of collisions */
   80 };
   81 
   82 struct kdbobj {
   83         LIST_ENTRY(kdbobj)      ko_link;
   84         opaque_t                ko_object;
   85         /* 
   86          * There should only be a dozen props for each object,
   87          * so we can keep them in a list.
   88          */
   89         LIST_HEAD(kprops, kdbprop) ko_props;
   90 };
   91 
   92 struct kdbprop {
   93         LIST_ENTRY(kdbprop)     kp_link;
   94         const char              *kp_name;
   95         const char              *kp_val;
   96         int                     kp_len;
   97         int                     kp_type;
   98 };
   99 
  100 
  101 static struct kdbprop *allocprop(const char *name, size_t len, int wait);
  102 static void kdb_rehash(struct propdb *db);
  103 static struct kdbobj *kdbobj_find(propdb_t db, opaque_t object, 
  104         int create, int wait);
  105 static int prop_insert(struct kdbobj *obj, const char *name, void *val, 
  106         size_t len, int type, int wait);
  107 
  108 MALLOC_DEFINE(M_PROP, "prop", "Kernel properties structures");
  109 
  110 /* 
  111  * Allocate a prop structure large enough to hold
  112  * `name' and `len' bytes of data.  For PROP_CONST
  113  * pass in a `len' of 0.
  114  */
  115 static struct kdbprop *
  116 allocprop(const char *name, size_t len, int wait) 
  117 {
  118         struct kdbprop *kp;
  119         char *np, *vp;
  120         size_t dsize, nsize;
  121 
  122         dsize = ALIGN(len);
  123         nsize = ALIGN(strlen(name) + 1);
  124 
  125         DPRINTF(x, ("allocprop: allocating %lu bytes for %s %s\n",
  126                 (unsigned long)(sizeof(struct kdbprop) + dsize + nsize), name, 
  127                 wait ? "can wait" : "can't wait"));
  128 
  129         kp = (struct kdbprop *)malloc(sizeof(struct kdbprop) + dsize + nsize,
  130                 M_PROP, wait ? M_WAITOK : M_NOWAIT);
  131 
  132         DPRINTF(x, ("allocprop: got %p for prop\n", kp));
  133 
  134         if (kp) {
  135                 /* Install name and init pointers */
  136                 vp = (char *)&kp[1];
  137                 kp->kp_val = (const char *)vp;
  138                 np = vp + dsize;
  139                 strlcpy(np, name, nsize);
  140                 kp->kp_name = (const char *)np;
  141                 kp->kp_len = len;
  142         }
  143         return (kp);
  144 }
  145 
  146 
  147 /*
  148  * If the database hash chains grow too long try to resize
  149  * the hash table.  Failure is not catastrophic.
  150  */
  151 static void
  152 kdb_rehash(struct propdb *db)
  153 {
  154         struct kdbobj *obj;
  155         kobj_bucket_t *new, *old = db->kd_obj;
  156         long hash;
  157         size_t i, newsize = (db->kd_size << KDB_STEP);
  158         int s;
  159 
  160         new = (kobj_bucket_t *)malloc(sizeof(kobj_bucket_t) * newsize,
  161                 M_PROP, M_NOWAIT);
  162         if (new == NULL)
  163                 return;
  164         s = splvm();
  165         for (i = 0; i < newsize; i++)
  166                 LIST_INIT(&new[i]);
  167 
  168         /* Now pop an object from the old table and insert it in the new one. */
  169         for (i = 0; i < db->kd_size; i++) {
  170                 while ((obj = LIST_FIRST(&old[i])) != NULL) {
  171                         LIST_REMOVE(obj, ko_link);
  172                         hash = (long)obj->ko_object;
  173                         hash = KDB_HASH(hash, db->kd_size);
  174                         LIST_INSERT_HEAD(&new[hash], obj, ko_link);
  175                 }
  176         }
  177         db->kd_size = newsize;
  178         db->kd_obj = new;
  179         splx(s);
  180         free(old, M_PROP);
  181 }
  182 
  183 /*
  184  * For propdb structures we use a simple power-of-2
  185  * hash.
  186  */
  187 
  188 propdb_t 
  189 propdb_create(const char *name)
  190 {
  191         struct propdb *db;
  192         size_t i;
  193 
  194         db = (struct propdb *)malloc(sizeof(struct propdb),
  195                 M_PROP, M_WAITOK);
  196 
  197         strncpy(db->kd_name, name, sizeof(db->kd_name));
  198 
  199         /* Initialize the hash table. */
  200         db->kd_size = KDB_SIZE;
  201         db->kd_longest = 0;
  202         db->kd_obj = (kobj_bucket_t *)malloc(sizeof(kobj_bucket_t) * 
  203                 db->kd_size, M_PROP, M_WAITOK);
  204         for (i = 0; i < db->kd_size; i++)
  205                 LIST_INIT(&db->kd_obj[i]);
  206         LIST_INSERT_HEAD(&propdbs, db, kd_link);
  207         return (db);
  208 }
  209 
  210 void 
  211 propdb_destroy(propdb_t db)
  212 {
  213         struct kdbobj *obj;
  214         struct kdbprop *prop;
  215         size_t i;
  216 
  217 #ifdef DIAGNOSTIC
  218         struct propdb *p;
  219 
  220         /* Make sure we have a handle to a valid database */
  221         LIST_FOREACH(p, &propdbs, kd_link) {
  222                 if (p == db) break;
  223         }
  224         if (p == NULL) panic("propdb_destroy: invalid database");
  225 #endif
  226         LIST_REMOVE(db, kd_link);
  227 
  228         /* Empty out each hash bucket */
  229         for (i = 0; i < db->kd_size; i++) {
  230                 while ((obj = LIST_FIRST(&db->kd_obj[i]))) {
  231                         LIST_REMOVE(obj, ko_link);
  232                         while ((prop = LIST_FIRST(&obj->ko_props))) {
  233                                 LIST_REMOVE(prop, kp_link);
  234                                 free(prop, M_PROP);
  235                         }
  236                         free(obj, M_PROP);
  237                 }
  238         }
  239         free(db->kd_obj, M_PROP);
  240         free(db, M_PROP);
  241 }
  242 
  243 /*
  244  * Find an object in the database and possibly create it too.
  245  */
  246 static struct kdbobj *
  247 kdbobj_find(propdb_t db, opaque_t object, int create, int wait)
  248 {
  249         struct kdbobj *obj;
  250         long hash = (long)object;
  251         int i;
  252 
  253         /* Find our object */
  254         hash = KDB_HASH(hash, db->kd_size);
  255         i=0;
  256         LIST_FOREACH(obj, &db->kd_obj[hash], ko_link) {
  257                 i++;    /* Measure chain depth */
  258                 if (obj->ko_object == object)
  259                         break;
  260         }
  261         if (create && (obj == NULL)) {
  262                 /* Need a new object. */
  263                 obj = (struct kdbobj *)malloc(sizeof(struct kdbobj),
  264                         M_PROP, wait ? M_WAITOK : M_NOWAIT);
  265 
  266                 if (!obj) {
  267                         return (obj);
  268                 }
  269 
  270                 /* Handle hash table growth */
  271                 if (++i > db->kd_longest) 
  272                         db->kd_longest = i;
  273                 if (db->kd_longest > KDB_MAXLEN) {
  274                         /* Increase the size of our hash table */
  275                         kdb_rehash(db);
  276                 }
  277 
  278                 /* Initialize object */
  279                 obj->ko_object = object;
  280                 LIST_INIT(&obj->ko_props);
  281                 LIST_INSERT_HEAD(&db->kd_obj[hash], obj, ko_link);
  282         }
  283         return (obj);
  284 }
  285 
  286 /*
  287  * Internal property insertion routine. 
  288  */
  289 static int
  290 prop_insert(struct kdbobj *obj, const char *name, void *val, size_t len,
  291         int type, int wait)
  292 {
  293         struct kdbprop *prop = NULL, *oprop;
  294 
  295         /* Does the prop exist already? */
  296         LIST_FOREACH(oprop, &obj->ko_props, kp_link) {
  297                 if (strcmp(oprop->kp_name, name) == 0)
  298                         break;
  299         }
  300         if (oprop) {
  301                 /* Can is it big enough? */
  302                 if ((type & PROP_CONST) ||
  303                         ((ALIGN(len) < ALIGN(oprop->kp_len)) &&
  304                                 (oprop->kp_type & PROP_CONST) == 0)) {
  305                         /* We can reuse it */
  306                         prop = oprop;
  307                 } 
  308         }
  309         if (!prop) {
  310                 /* Allocate a new prop */
  311                 if (type & PROP_CONST)
  312                         prop = allocprop(name, 0, wait);
  313                 else
  314                         prop = allocprop(name, len, wait);
  315                 if (!prop) return (wait ? ENOMEM : EAGAIN);
  316         }
  317         /* Set the values */
  318         if (type & PROP_CONST) {
  319                 prop->kp_val = val;
  320         } else {
  321                 char *dest = (char *)prop->kp_val;
  322                 memcpy(dest, val, len);
  323         }
  324         prop->kp_len = len;
  325         prop->kp_type = type;
  326 
  327         /* Now clean up if necessary */
  328         if (prop != oprop) {
  329                 LIST_INSERT_HEAD(&obj->ko_props, prop, kp_link);
  330                 if (oprop) {
  331                         LIST_REMOVE(oprop, kp_link);
  332                         free(oprop, M_PROP);
  333                 }
  334         }
  335         return (0);
  336 }
  337 
  338 int 
  339 prop_set(propdb_t db, opaque_t object, const char *name,
  340         void *val, size_t len, int type, int wait)
  341 {
  342         struct kdbobj *obj;
  343         struct kdbprop *prop = NULL, *oprop;
  344         int s;
  345 
  346         DPRINTF(x, ("prop_set: %p, %p, %s, %p, %lx, %x, %d\n", db, object, 
  347                 name ? name : "NULL", val, (unsigned long)len, type, wait));
  348 
  349         /* Find our object */
  350         s = splvm();
  351         obj = kdbobj_find(db, object, 1, wait);
  352         if (!obj) {
  353                 splx(s);
  354                 return (wait ? ENOMEM : EAGAIN);
  355         }
  356 
  357 #if 1
  358         {
  359                 int rv;
  360 
  361 oprop = prop; /* XXXX -- use vars to make gcc happy. */
  362                 rv = prop_insert(obj, name, val, len, type, wait);
  363                 splx(s);
  364                 return (rv);
  365         }
  366 #else
  367         /* Does the prop exist already? */
  368         LIST_FOREACH(oprop, &obj->ko_props, kp_link) {
  369                 if (strcmp(oprop->kp_name, name) == 0)
  370                         break;
  371         }
  372         if (oprop) {
  373                 /* Can is it big enough? */
  374                 if ((type & PROP_CONST) ||
  375                         ((ALIGN(len) < ALIGN(oprop->kp_len)) &&
  376                                 (oprop->kp_type & PROP_CONST) == 0)) {
  377                         /* We can reuse it */
  378                         prop = oprop;
  379                 } 
  380         }
  381         if (!prop) {
  382                 /* Allocate a new prop */
  383                 if (type & PROP_CONST)
  384                         prop = allocprop(name, 0, wait);
  385                 else
  386                         prop = allocprop(name, len, wait);
  387                 if (!prop) return (wait ? ENOMEM : EAGAIN);
  388         }
  389         /* Set the values */
  390         if (type & PROP_CONST) {
  391                 prop->kp_val = val;
  392         } else {
  393                 char *dest = (char *)prop->kp_val;
  394                 memcpy(dest, val, len);
  395         }
  396         prop->kp_len = len;
  397         prop->kp_type = type;
  398 
  399         /* Now clean up if necessary */
  400         if (prop != oprop) {
  401                 LIST_INSERT_HEAD(&obj->ko_props, prop, kp_link);
  402                 if (oprop) {
  403                         LIST_REMOVE(oprop, kp_link);
  404                         free(oprop, M_PROP);
  405                 }
  406         }
  407         splx(s);
  408         return (0);
  409 #endif
  410 }
  411 
  412 size_t 
  413 prop_get(propdb_t db, opaque_t object, const char *name, void *val, 
  414         size_t len, int *type)
  415 {
  416         struct kdbobj *obj;
  417         struct kdbprop *prop = NULL;
  418         int s;
  419 
  420         DPRINTF(x, ("prop_get: %p, %p, %s, %p, %lx, %p\n", db, object, 
  421                 name ? name : "NULL", val, (unsigned long)len, type));
  422 
  423         /* Find our object */
  424         s = splvm();
  425         obj = kdbobj_find(db, object, 0, 0);
  426         if (!obj) {
  427                 splx(s);
  428                 return (-1);
  429         }
  430 
  431         /* find our prop */
  432         LIST_FOREACH(prop, &obj->ko_props, kp_link) {
  433                 if (strcmp(prop->kp_name, name) == 0)
  434                         break;
  435         }
  436         if (!prop) {
  437                 splx(s);
  438                 DPRINTF(x, ("prop not found\n"));
  439                 return (-1);
  440         }
  441 
  442         /* Copy out our prop */
  443         len = min(len, prop->kp_len);
  444         if (val && len) {
  445                 memcpy(val, prop->kp_val, len);
  446         }
  447         if (type) 
  448                 *type = prop->kp_type;
  449         splx(s);
  450         DPRINTF(x, ("copied %ld of %d\n", (long) len, prop->kp_len));
  451         return (prop->kp_len);
  452 }
  453 
  454 /*
  455  * Return the total number of objects in the database and as
  456  * many as fit in the buffer.
  457  */
  458 size_t
  459 prop_objs(propdb_t db, opaque_t *objects, size_t len) 
  460 {
  461         struct kdbobj *obj;
  462         size_t i, j, nelem = (len / sizeof(opaque_t));
  463         int s;
  464 
  465         DPRINTF(x, ("prop_objs: %p, %p, %lx\n", db, objects,
  466             (unsigned long)len));
  467 
  468         s = splvm();
  469         for (i = 0, j = 0; i < db->kd_size; i++) {
  470                 LIST_FOREACH(obj, &db->kd_obj[i], ko_link) {
  471                         if (objects && j < nelem)
  472                                 objects[j] = obj->ko_object;
  473                         j++;
  474                 }
  475         }
  476         splx(s);
  477         return (j * sizeof(opaque_t));
  478 }
  479 
  480 /*
  481  * Return the total number of property names associated with an object
  482  * and as many as fit in the buffer.
  483  */
  484 size_t
  485 prop_list(propdb_t db, opaque_t object, char *names, size_t len) 
  486 {
  487         struct kdbobj *obj;
  488         struct kdbprop *prop = NULL;
  489         int s, i = 0;
  490         char *sp, *ep;
  491 
  492         DPRINTF(x, ("prop_list: %p, %p, %p, %lx\n", 
  493                 db, object, names, (unsigned long)len));
  494 
  495         /* Find our source object */
  496         s = splvm();
  497         obj = kdbobj_find(db, object, 0, 0);
  498         if (obj == NULL) {
  499                 splx(s);
  500                 return (0);
  501         }
  502 
  503         sp = names;
  504         ep = names + len;
  505         LIST_FOREACH(prop, &obj->ko_props, kp_link) {
  506                 i = strlen(prop->kp_name) + 1;
  507                 if (names + i + 1 < ep) {
  508                         strlcpy(names, prop->kp_name, ep - names);
  509                         names += i;
  510                         /* Add an extra NUL */
  511                         names[i + 1] = 0;
  512                 }
  513         }
  514         splx(s);
  515         return (names - sp);
  516 }
  517 
  518 int 
  519 prop_delete(propdb_t db, opaque_t object, const char *name)
  520 {
  521         struct kdbobj *obj;
  522         struct kdbprop *prop = NULL;
  523         int s, i = 0;
  524 
  525         DPRINTF(x, ("prop_delete: %p, %p, %s\n", db, object, 
  526                 name ? name : "NULL"));
  527 
  528         /* Find our object */
  529         s = splvm();
  530         obj = kdbobj_find(db, object, 0, 0);
  531         if (obj == NULL) {
  532                 splx(s);
  533                 return (0);
  534         }
  535 
  536         if (name) {
  537                 /* Find our prop */
  538                 LIST_FOREACH(prop, &obj->ko_props, kp_link) {
  539                         if (strcmp(prop->kp_name, name) == 0)
  540                                 break;
  541                 }
  542                 if (!prop) {
  543                         splx(s);
  544                         return (0);
  545                 }
  546                 LIST_REMOVE(prop, kp_link);
  547                 free(prop, M_PROP);
  548                 i++;
  549         } else {
  550                 while ((prop = LIST_FIRST(&obj->ko_props))) {
  551                         LIST_REMOVE(prop, kp_link);
  552                         free(prop, M_PROP);
  553                         i++;
  554                 }
  555         }
  556         if (LIST_EMPTY(&obj->ko_props)) {
  557                 /* Free up the empty container. */
  558                 LIST_REMOVE(obj, ko_link);
  559                 free(obj, M_PROP);
  560         }
  561         splx(s);
  562         return (i);
  563 }
  564 
  565 int 
  566 prop_copy(propdb_t db, opaque_t source, opaque_t dest, int wait)
  567 {
  568         struct kdbobj *nobj, *oobj;
  569         struct kdbprop *prop, *oprop, *srcp;
  570         int s;
  571 
  572         DPRINTF(x, ("prop_copy: %p, %p, %p, %d\n", db, source, dest, wait));
  573 
  574         /* Find our source object */
  575         s = splvm();
  576         oobj = kdbobj_find(db, source, 0, wait);
  577         if (oobj == NULL) {
  578                 splx(s);
  579                 return (EINVAL);
  580         }
  581 
  582         /* Find our dest object */
  583         nobj = kdbobj_find(db, dest, 1, wait);
  584         if (!nobj) {
  585                 splx(s);
  586                 return (wait ? ENOMEM : EAGAIN);
  587         }
  588 
  589         /* Copy these properties over now */
  590         LIST_FOREACH(srcp, &oobj->ko_props, kp_link) {
  591 
  592                 DPRINTF(x, ("prop_copy: copying prop %s\n", 
  593                         srcp->kp_name));
  594 
  595 #if 1
  596                 {
  597                         int rv;
  598 
  599 oprop = prop; /* XXXX -- use vars to make gcc happy. */
  600                         rv = prop_insert(nobj, srcp->kp_name, 
  601                                 (void *)srcp->kp_val, srcp->kp_len,
  602                                 srcp->kp_type, wait);
  603                         if (rv) {
  604                                 /* Error of some sort */
  605                                 splx(s);
  606                                 return (rv);
  607                         }
  608                 }
  609 #else
  610                 /* Does the prop exist already? */
  611                 prop = NULL;
  612                 LIST_FOREACH(oprop, &nobj->ko_props, kp_link) {
  613                         if (strcmp(oprop->kp_name, srcp->kp_name) == 0)
  614                                 break;
  615                 }
  616                 if (oprop) {
  617 
  618                         DPRINTF(x, ("prop_copy: found old prop %p\n",
  619                                 oprop));
  620 
  621                         /* Can is it big enough? */
  622                         if ((srcp->kp_type & PROP_CONST) ||
  623                                 ((ALIGN(srcp->kp_len) < ALIGN(oprop->kp_len)) &&
  624                                         (oprop->kp_type & PROP_CONST) == 0)) {
  625                                 /* We can reuse it */
  626                                 prop = oprop;
  627                                 DPRINTF(x, ("prop_copy: using old prop\n"));
  628                         }
  629                 }
  630                 if (!prop) {
  631                         /* Allocate a new prop */
  632                         if (srcp->kp_type & PROP_CONST)
  633                                 prop = allocprop(srcp->kp_name, 0, wait);
  634                         else
  635                                 prop = allocprop(srcp->kp_name, 
  636                                         srcp->kp_len, wait);
  637                         if (!prop) {
  638                                 splx(s);
  639                                 return (wait ? ENOMEM : EAGAIN);
  640                         }
  641                 }
  642                 /* Set the values */
  643                 if (srcp->kp_type & PROP_CONST) {
  644                         prop->kp_val = srcp->kp_val;
  645                 } else {
  646                         char *dest = (char *)prop->kp_val;
  647                         memcpy(dest, srcp->kp_val, srcp->kp_len);
  648                 }
  649                 prop->kp_len = srcp->kp_len;
  650                 prop->kp_type = srcp->kp_type;
  651 
  652                 /* Now clean up if necessary */
  653                 if (prop != oprop) {
  654 
  655                         DPRINTF(x, ("prop_copy: inserting prop %p\n", prop));
  656                         LIST_INSERT_HEAD(&nobj->ko_props, prop, kp_link);
  657                         if (oprop) {
  658                                 DPRINTF(x, ("prop_copy: removing prop %p\n", 
  659                                         oprop));
  660                                 LIST_REMOVE(oprop, kp_link);
  661                                 free(oprop, M_PROP);
  662                         }
  663                 }
  664 #endif
  665         }
  666         DPRINTF(x, ("prop_copy: done\n"));
  667         splx(s);
  668         return (0);
  669 
  670 }

Cache object: 69803a168229bfac0432beb2778de6d0


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.