/[hurd]/hurd/nfsd/cache.c
ViewVC logotype

Diff of /hurd/nfsd/cache.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.10 by roland, Wed May 8 09:29:13 2002 UTC revision 1.11 by marcus, Sun Sep 29 15:12:48 2002 UTC
# Line 1  Line 1 
1  /*  /* cache.c - Cache operations for the nfs daemon.
2     Copyright (C) 1996,98,99,2000,02 Free Software Foundation, Inc.     Copyright (C) 1996,98,99,2000,02 Free Software Foundation, Inc.
3     Written by Michael I. Bushnell, p/BSG.     Written by Michael I. Bushnell, p/BSG.
4    
# Line 46  spin_lock_t idhashlock = SPIN_LOCK_INITI Line 46  spin_lock_t idhashlock = SPIN_LOCK_INITI
46  static int nfreeids;  static int nfreeids;
47  static int leastidlastuse;  static int leastidlastuse;
48    
49  /* Compare I against the specified set of users/groups. */  /* Compare I against the specified set of users/groups.  */
50  /* Use of int in decl of UIDS and GIDS is correct here; that's  /* Use of int in decl of UIDS and GIDS is correct here; that's
51     the NFS type because they come in in known 32 bit slots. */     the NFS type because they come in in known 32 bit slots.  */
52  static int  static int
53  idspec_compare (struct idspec *i, int nuids, int ngids,  idspec_compare (struct idspec *i, int nuids, int ngids,
54                  int *uids, int *gids)                  int *uids, int *gids)
# Line 66  idspec_compare (struct idspec *i, int nu Line 66  idspec_compare (struct idspec *i, int nu
66    return 1;    return 1;
67  }  }
68    
69  /* Compute a hash value for a given user spec */  /* Compute a hash value for a given user spec.  */
70  static int  static int
71  idspec_hash (int nuids, int ngids, int *uids, int *gids)  idspec_hash (int nuids, int ngids, int *uids, int *gids)
72  {  {
# Line 81  idspec_hash (int nuids, int ngids, int * Line 81  idspec_hash (int nuids, int ngids, int *
81    return hash;    return hash;
82  }  }
83    
84  /* Lookup a user spec in the hash table and allocate a reference */  /* Lookup a user spec in the hash table and allocate a reference.  */
85  static struct idspec *  static struct idspec *
86  idspec_lookup (int nuids, int ngids, int *uids, int *gids)  idspec_lookup (int nuids, int ngids, int *uids, int *gids)
87  {  {
# Line 107  idspec_lookup (int nuids, int ngids, int Line 107  idspec_lookup (int nuids, int ngids, int
107    i->ngids = ngids;    i->ngids = ngids;
108    i->uids = malloc (nuids * sizeof (uid_t));    i->uids = malloc (nuids * sizeof (uid_t));
109    i->gids = malloc (ngids * sizeof (gid_t));    i->gids = malloc (ngids * sizeof (gid_t));
110    bcopy (uids, i->uids, nuids * sizeof (uid_t));    memcpy (i->uids, uids, nuids * sizeof (uid_t));
111    bcopy (gids, i->gids, ngids * sizeof (gid_t));    memcpy (i->gids, gids, ngids * sizeof (gid_t));
112    i->references = 1;    i->references = 1;
113    
114    i->next = idhashtable[hash];    i->next = idhashtable[hash];
# Line 132  process_cred (int *p, struct idspec **cr Line 132  process_cred (int *p, struct idspec **cr
132    int firstgid;    int firstgid;
133    int i;    int i;
134    
135    type = ntohl (*p++);    type = ntohl (*p);
136      p++;
137    
138    if (type != AUTH_UNIX)    if (type != AUTH_UNIX)
139      {      {
140        int size = ntohl (*p++);        int size = ntohl (*p);
141          p++;
142        *credp = idspec_lookup (0, 0, 0, 0);        *credp = idspec_lookup (0, 0, 0, 0);
143        p += INTSIZE (size);        p += INTSIZE (size);
144      }      }
145    else    else
146      {      {
147        p++;                      /* skip size */        p++;                      /* Skip size.  */
148        p++;                      /* skip seconds */        p++;                      /* Skip seconds.  */
149        len = ntohl (*p++);        len = ntohl (*p);
150        p += INTSIZE (len);       /* skip hostname */        p++;
151          p += INTSIZE (len);       /* Skip hostname.  */
152    
153        uid = p++;                /* remember loc of uid */        uid = p++;                /* Remember location of uid.  */
154        *uid = ntohl (*uid);        *uid = ntohl (*uid);
155    
156        firstgid = *p++;          /* remember first gid */        firstgid = *(p++);        /* Remember first gid.  */
157        gids = p;                 /* here's where the array will start */        gids = p;                 /* Here is where the array will start.  */
158        ngids = ntohl (*p++);        ngids = ntohl (*p);
159          p++;
160    
161        /* Now swap the first gid to be the first element of the array */        /* Now swap the first gid to be the first element of the
162             array.  */
163        *gids = firstgid;        *gids = firstgid;
164        ngids++;                  /* and count it */        ngids++;                  /* And count it.  */
165    
166        /* And byteswap the gids */        /* And byteswap the gids.  */
167        for (i = 0; i < ngids; i++)        for (i = 0; i < ngids; i++)
168          gids[i] = ntohl (gids[i]);          gids[i] = ntohl (gids[i]);
169    
# Line 167  process_cred (int *p, struct idspec **cr Line 172  process_cred (int *p, struct idspec **cr
172        *credp = idspec_lookup (1, ngids, uid, gids);        *credp = idspec_lookup (1, ngids, uid, gids);
173      }      }
174    
175    /* Next is the verf field; skip it entirely */    /* Next is the verf field; skip it entirely.  */
176    p++;                          /* skip id */    p++;                          /* Skip ID.  */
177    len = htonl (*p++);    len = htonl (*p);
178      p++;
179    p += INTSIZE (len);    p += INTSIZE (len);
180    
181    return p;    return p;
# Line 235  scan_creds () Line 241  scan_creds ()
241              }              }
242          }          }
243    
244        /* If we didn't bail early, then this is valid */        /* If we didn't bail early, then this is valid.  */
245        if (nfreeids)        if (nfreeids)
246          leastidlastuse = newleast;          leastidlastuse = newleast;
247      }      }
# Line 281  lookup_cache_handle (int *p, struct cach Line 287  lookup_cache_handle (int *p, struct cach
287          return p + NFS2_FHSIZE / sizeof (int);          return p + NFS2_FHSIZE / sizeof (int);
288        }        }
289    
290    /* Not found */    /* Not found.  */
291    
292    /* First four bytes are our internal table of filesystems */    /* First four bytes are our internal table of filesystems.  */
293    fsys = lookup_filesystem (*p);    fsys = lookup_filesystem (*p);
294    if (fsys == MACH_PORT_NULL    if (fsys == MACH_PORT_NULL
295        || fsys_getfile (fsys, i->uids, i->nuids, i->gids, i->ngids,        || fsys_getfile (fsys, i->uids, i->nuids, i->gids, i->ngids,
# Line 295  lookup_cache_handle (int *p, struct cach Line 301  lookup_cache_handle (int *p, struct cach
301      }      }
302    
303    c = malloc (sizeof (struct cache_handle));    c = malloc (sizeof (struct cache_handle));
304    bcopy (p, c->handle, NFS2_FHSIZE);    memcpy (c->handle, p, NFS2_FHSIZE);
305    cred_ref (i);    cred_ref (i);
306    c->ids = i;    c->ids = i;
307    c->port = port;    c->port = port;
# Line 363  scan_fhs () Line 369  scan_fhs ()
369              }              }
370          }          }
371    
372        /* If we didn't bail early, then this is valid. */        /* If we didn't bail early, then this is valid.  */
373        if (nfreefh)        if (nfreefh)
374          leastfhlastuse = newleast;          leastfhlastuse = newleast;
375      }      }
# Line 381  create_cached_handle (int fs, struct cac Line 387  create_cached_handle (int fs, struct cac
387    size_t handlelen = NFS2_FHSIZE - sizeof (int);    size_t handlelen = NFS2_FHSIZE - sizeof (int);
388    mach_port_t newport, ref;    mach_port_t newport, ref;
389    
390    /* Authenticate USERPORT so that we can call file_getfh on it. */    /* Authenticate USERPORT so that we can call file_getfh on it.  */
391    ref = mach_reply_port ();    ref = mach_reply_port ();
392    /* MAKE_SEND is safe becaue we destroy REF ourselves. */    /* MAKE_SEND is safe becaue we destroy REF ourselves.  */
393    if (io_reauthenticate (userport, ref, MACH_MSG_TYPE_MAKE_SEND)    if (io_reauthenticate (userport, ref, MACH_MSG_TYPE_MAKE_SEND)
394        || auth_user_authenticate (authserver, ref, MACH_MSG_TYPE_MAKE_SEND,        || auth_user_authenticate (authserver, ref, MACH_MSG_TYPE_MAKE_SEND,
395                                   &newport))                                   &newport))
396      {      {
397        /* Reauthentication has failed, but maybe the filesystem will let        /* Reauthentication has failed, but maybe the filesystem will let
398           us call file_getfh anyway. */           us call file_getfh anyway.  */
399        newport = userport;        newport = userport;
400      }      }
401    else    else
402      mach_port_deallocate (mach_task_self (), userport);      mach_port_deallocate (mach_task_self (), userport);
403    mach_port_destroy (mach_task_self (), ref);    mach_port_destroy (mach_task_self (), ref);
404    
405    /* Fetch the file handle */    /* Fetch the file handle.  */
406    *(int *)fhandle = fs;    *(int *)fhandle = fs;
407    err = file_getfh (newport, &bp, &handlelen);    err = file_getfh (newport, &bp, &handlelen);
408    mach_port_deallocate (mach_task_self (), newport);    mach_port_deallocate (mach_task_self (), newport);
# Line 404  create_cached_handle (int fs, struct cac Line 410  create_cached_handle (int fs, struct cac
410      return 0;      return 0;
411    if (bp != fhandle + sizeof (int))    if (bp != fhandle + sizeof (int))
412      {      {
413        bcopy (bp, fhandle + sizeof (int), NFS2_FHSIZE - sizeof (int));        memcpy (fhandle + sizeof (int), bp, NFS2_FHSIZE - sizeof (int));
414        munmap (bp, handlelen);        munmap (bp, handlelen);
415      }      }
416    
417    /* Cache it */    /* Cache it.  */
418    hash = fh_hash (fhandle, credc->ids);    hash = fh_hash (fhandle, credc->ids);
419    mutex_lock (&fhhashlock);    mutex_lock (&fhhashlock);
420    for (c = fhhashtable[hash]; c; c = c->next)    for (c = fhhashtable[hash]; c; c = c->next)
421      if (c->ids == credc->ids && ! bcmp (fhandle, c->handle, NFS2_FHSIZE))      if (c->ids == credc->ids && ! bcmp (fhandle, c->handle, NFS2_FHSIZE))
422        {        {
423          /* Return this one */          /* Return this one.  */
424          if (c->references == 0)          if (c->references == 0)
425            nfreefh--;            nfreefh--;
426          c->references++;          c->references++;
# Line 423  create_cached_handle (int fs, struct cac Line 429  create_cached_handle (int fs, struct cac
429        }        }
430    
431    /* Always call fsys_getfile so that we don't depend on the    /* Always call fsys_getfile so that we don't depend on the
432       particular open modes of the port passed in. */       particular open modes of the port passed in.  */
433    
434    err = fsys_getfile (lookup_filesystem (fs),    err = fsys_getfile (lookup_filesystem (fs),
435                        credc->ids->uids, credc->ids->nuids,                        credc->ids->uids, credc->ids->nuids,
# Line 436  create_cached_handle (int fs, struct cac Line 442  create_cached_handle (int fs, struct cac
442        return 0;        return 0;
443      }      }
444    
445    /* Create it anew */    /* Create it anew.  */
446    c = malloc (sizeof (struct cache_handle));    c = malloc (sizeof (struct cache_handle));
447    bcopy (fhandle, c->handle, NFS2_FHSIZE);    memcpy (c->handle, fhandle, NFS2_FHSIZE);
448    cred_ref (credc->ids);    cred_ref (credc->ids);
449    c->ids = credc->ids;    c->ids = credc->ids;
450    c->port = newport;    c->port = newport;
451    c->references = 1;    c->references = 1;
452    
453    /* And add it to the hash table */    /* And add it to the hash table.  */
454    c->next = fhhashtable[hash];    c->next = fhhashtable[hash];
455    if (c->next)    if (c->next)
456      c->next->prevp = &c->next;      c->next->prevp = &c->next;
# Line 464  static int leastreplylastuse; Line 470  static int leastreplylastuse;
470    
471  /* Check the list of cached replies to see if this is a replay of a  /* Check the list of cached replies to see if this is a replay of a
472     previous transaction; if so, return the cache record.  Otherwise,     previous transaction; if so, return the cache record.  Otherwise,
473     create a new cache record. */     create a new cache record.  */
474  struct cached_reply *  struct cached_reply *
475  check_cached_replies (int xid,  check_cached_replies (int xid,
476                        struct sockaddr_in *sender)                        struct sockaddr_in *sender)
# Line 490  check_cached_replies (int xid, Line 496  check_cached_replies (int xid,
496    cr = malloc (sizeof (struct cached_reply));    cr = malloc (sizeof (struct cached_reply));
497    mutex_init (&cr->lock);    mutex_init (&cr->lock);
498    mutex_lock (&cr->lock);    mutex_lock (&cr->lock);
499    bcopy (sender, &cr->source, sizeof (struct sockaddr_in));    memcpy (&cr->source, sender, sizeof (struct sockaddr_in));
500    cr->xid = xid;    cr->xid = xid;
501    cr->data = 0;    cr->data = 0;
502    cr->references = 1;    cr->references = 1;
# Line 506  check_cached_replies (int xid, Line 512  check_cached_replies (int xid,
512  }  }
513    
514  /* A cached reply returned by check_cached_replies is now no longer  /* A cached reply returned by check_cached_replies is now no longer
515     needed by its caller. */     needed by its caller.  */
516  void  void
517  release_cached_reply (struct cached_reply *cr)  release_cached_reply (struct cached_reply *cr)
518  {  {
# Line 559  scan_replies () Line 565  scan_replies ()
565              }              }
566          }          }
567    
568        /* If we didn't bail early, then this is valid */        /* If we didn't bail early, then this is valid.  */
569        if (nfreereplies)        if (nfreereplies)
570          leastreplylastuse = newleast;          leastreplylastuse = newleast;
571      }      }

Legend:
Removed from v.1.10  
changed lines
  Added in v.1.11

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26