You can subscribe to this list here.
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(2) |
Jun
|
Jul
(1) |
Aug
|
Sep
(6) |
Oct
|
Nov
(11) |
Dec
(5) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2009 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
(7) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(9) |
Dec
(4) |
2010 |
Jan
(4) |
Feb
(2) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
From: <ab...@us...> - 2009-06-03 20:41:00
|
Revision: 32 http://npfs.svn.sourceforge.net/npfs/?rev=32&view=rev Author: abbyz9 Date: 2009-06-03 20:40:56 +0000 (Wed, 03 Jun 2009) Log Message: ----------- Add a target to build fus. Modified Paths: -------------- npfs/trunk/fs/Makefile Modified: npfs/trunk/fs/Makefile =================================================================== --- npfs/trunk/fs/Makefile 2009-06-03 20:39:45 UTC (rev 31) +++ npfs/trunk/fs/Makefile 2009-06-03 20:40:56 UTC (rev 32) @@ -14,6 +14,7 @@ FS=\ npfs\ + fus\ ramfs\ nullfs\ ramfs2\ @@ -35,6 +36,9 @@ npfs: ufs.o npfs.o $(CC) -o npfs $(CFLAGS) ufs.o npfs.o $(LFLAGS) $(NPFS_LFLAGS) +fus: fus.o + $(CC) -o fus $(CFLAGS) fus.o $(LFLAGS) + rdmanpfs: ufs.o rdmanpfs.o $(CC) -o rdmanpfs $(CFLAGS) ufs.o rdmanpfs.o $(LFLAGS) $(NPFS_LFLAGS) -libverbs -lrdmacm This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ab...@us...> - 2009-06-03 20:39:48
|
Revision: 31 http://npfs.svn.sourceforge.net/npfs/?rev=31&view=rev Author: abbyz9 Date: 2009-06-03 20:39:45 +0000 (Wed, 03 Jun 2009) Log Message: ----------- Add the definition of npc_create() to npclient.h Modified Paths: -------------- npfs/trunk/include/npclient.h Modified: npfs/trunk/include/npclient.h =================================================================== --- npfs/trunk/include/npclient.h 2009-03-12 20:31:09 UTC (rev 30) +++ npfs/trunk/include/npclient.h 2009-06-03 20:39:45 UTC (rev 31) @@ -39,6 +39,7 @@ struct addrinfo *npc_netaddr(char *address, int dfltport); Npcfsys * npc_netmount(struct addrinfo *address, Npuser *user, int dfltport, int (*auth)(Npcfid *afid, Npuser *user, void *aux), void *aux); +Npcfid* npc_create(Npcfsys *fs, char *path, u32 perm, int mode); Npcfid* npc_open(Npcfsys *fs, char *path, int mode); int npc_close(Npcfid *fid); int npc_remove(Npcfsys *fs, char *path); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <li...@us...> - 2009-03-12 20:31:23
|
Revision: 30 http://npfs.svn.sourceforge.net/npfs/?rev=30&view=rev Author: lionkov Date: 2009-03-12 20:31:09 +0000 (Thu, 12 Mar 2009) Log Message: ----------- fast file server that doesn't use any library Added Paths: ----------- npfs/trunk/fs/fus.c Added: npfs/trunk/fs/fus.c =================================================================== --- npfs/trunk/fs/fus.c (rev 0) +++ npfs/trunk/fs/fus.c 2009-03-12 20:31:09 UTC (rev 30) @@ -0,0 +1,2097 @@ +/* + * Copyright (C) 2008 by Latchesar Ionkov <lu...@io...> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * LATCHESAR IONKOV AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +//#define _XOPEN_SOURCE 500 +#define _BSD_SOURCE +#define _GNU_SOURCE +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <pthread.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> +#include <dirent.h> +#include <fcntl.h> +#include <utime.h> +#include <pwd.h> +#include <grp.h> +#include <assert.h> +#include <sys/syscall.h> +#include <sys/sendfile.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <stdarg.h> +#include <sched.h> + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; + +typedef struct Conn Conn; +typedef struct Fid Fid; +typedef struct Wthread Wthread; +typedef struct Freq Freq; +typedef struct Qid Qid; + +enum { + Tfirst = 100, + Tversion = 100, + Rversion, + Tauth = 102, + Rauth, + Tattach = 104, + Rattach, + Terror = 106, + Rerror, + Tflush = 108, + Rflush, + Twalk = 110, + Rwalk, + Topen = 112, + Ropen, + Tcreate = 114, + Rcreate, + Tread = 116, + Rread, + Twrite = 118, + Rwrite, + Tclunk = 120, + Rclunk, + Tremove = 122, + Rremove, + Tstat = 124, + Rstat, + Twstat = 126, + Rwstat, + Tlast = 126, + + Fidtblsz = 8192, + Fidhtblsz = 32, + Maxwelem = 16, +}; + +/* modes */ +enum { + Oread = 0x00, + Owrite = 0x01, + Ordwr = 0x02, + Oexec = 0x03, + Oexcl = 0x04, + Otrunc = 0x10, + Orexec = 0x20, + Orclose = 0x40, + Oappend = 0x80, +}; + +/* permissions */ +enum { + Dmdir = 0x80000000, + Dmappend = 0x40000000, + Dmexcl = 0x20000000, + Dmmount = 0x10000000, + Dmauth = 0x08000000, + Dmtmp = 0x04000000, + Dmsymlink = 0x02000000, + Dmlink = 0x01000000, + + /* 9P2000.u extensions */ + Dmdevice = 0x00800000, + Dmnamedpipe = 0x00200000, + Dmsocket = 0x00100000, + Dmsetuid = 0x00080000, + Dmsetgid = 0x00040000, +}; + +/* qid.types */ +enum { + Qtdir = 0x80, + Qtappend = 0x40, + Qtexcl = 0x20, + Qtmount = 0x10, + Qtauth = 0x08, + Qttmp = 0x04, + Qtsymlink = 0x02, + Qtlink = 0x01, + Qtfile = 0x00, +}; + +struct Fid { + u32 fid; + char* path; + int fd; + DIR* dir; + int diroffset; + char* direntname; + char cpath[256]; + u8 type; + uid_t uid; + gid_t gid; + Fid* next; +}; + +struct Conn { + int sock; + pthread_mutex_t rlock; + int rfutex; + int dotu; + u32 msize; + + /* data for the next message (if size not ~0) */ + u32 size; + u8 type; + u16 tag; + u8 buf[23]; + int bpos; + + /* used to write to file */ + int pip[2]; + int nwthreads; + Wthread* wthreads; + + /* Fid stuff */ + Fid fidtbl[Fidtblsz]; + Fid *fidhtbl[Fidhtblsz]; + pthread_mutex_t wlock; + int wfutex; +}; + +struct Wthread { + pthread_t tid; + Conn* conn; + u16 tag; + Freq* freqs; + u8 stk[32768]; +}; + +struct Freq { + u16 tag; + Freq* next; +}; + +struct Qid { + u8 type; + u32 version; + u64 path; +}; + +static int p9version(Conn *, u8, u16, u32, u8 *); +static int p9auth(Conn *, u8, u16, u32, u8 *); +static int p9attach(Conn *, u8, u16, u32, u8 *); +static int p9flush(Conn *, u8, u16, u32, u8 *); +static int p9walk(Conn *, u8, u16, u32, u8 *); +static int p9open(Conn *, u8, u16, u32, u8 *); +static int p9create(Conn *, u8, u16, u32, u8 *); +static int p9read(Conn *, u8, u16, u32, u8 *); +static int p9write(Conn *, u8, u16, u32, u8 *); +static int p9clunk(Conn *, u8, u16, u32, u8 *); +static int p9remove(Conn *, u8, u16, u32, u8 *); +static int p9stat(Conn *, u8, u16, u32, u8 *); +static int p9wstat(Conn *, u8, u16, u32, u8 *); + +static int connproc(void *a); +void conndestroy(Conn *conn); +static int writen(Conn *conn, u8 *buf, int buflen); +static int rflush(Conn *conn, u16 tag, u8 *buf); + +static int debuglevel; +static int msize = 8192; +static int dotu = 1; +static int sameuser = 0; + +static int (*fhndlrs[])(Conn *, u8, u16, u32, u8 *) = { + p9version, + p9auth, + p9attach, + NULL, + p9flush, + p9walk, + p9open, + p9create, + p9read, + p9write, + p9clunk, + p9remove, + p9stat, + p9wstat, +}; + +#define FUTEX_WAIT 0 +#define FUTEX_WAKE 1 + +static inline int +cmpxchg(int *ptr, int old, int new) +{ + int prev; + + asm volatile("lock cmpxchgl %k1,%2" + : "=a"(prev) + : "r"(new), "m"(*ptr), "0"(old) + : "memory"); + + return prev; +} + +static inline int +xchg(int *ptr, int x) +{ + asm volatile("lock xchgl %k0,%1" + : "=r" (x) + : "m" (*ptr), "0" (x) + : "memory"); + + return x; +} + +static inline int +dec(int *ptr) +{ + int i; + + i = -1; + asm volatile("lock xaddl %0, %1" + : "+r" (i), "+m" (*ptr) + : : "memory"); + + return i; +} + +static int +futex(int *uaddr, int op, int val, const struct timespec *timeout, int *uaddr2, int val3) +{ + return syscall(SYS_futex, uaddr, op, val, timeout, uaddr2, val3); +} + +static inline void +flock(int *val) +{ + int n; + + if ((n = cmpxchg(val, 0, 1)) == 0) + return; + + while (xchg(val, 2) != 0) + futex(val, FUTEX_WAIT, 2, NULL, NULL, 0); +} + +static inline void +fulock(int *val) +{ + unsigned long n; + + if ((n = dec(val)) != 1) { + *val = 0; + futex(val, FUTEX_WAKE, 1, NULL, NULL, 0); + } +} + +static void +debug(char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + if (debuglevel) + vfprintf(stderr, fmt, ap); + va_end(ap); +} + +static inline void +rlock(Conn *conn) +{ + flock(&conn->rfutex); +// pthread_mutex_lock(&conn->rlock); +} + +static inline void +runlock(Conn *conn) +{ + fulock(&conn->rfutex); +// pthread_mutex_unlock(&conn->rlock); +} + +static inline void +wlock(Conn *conn) +{ + flock(&conn->wfutex); +// pthread_mutex_lock(&conn->wlock); +} + +static inline void +wunlock(Conn *conn) +{ + fulock(&conn->wfutex); +// pthread_mutex_unlock(&conn->wlock); +} + +static inline u8 * +pint8(u8 *data, u8 val) +{ + data[0] = val; + return data + 1; +} + +static inline u8 * +pint16(u8 *data, u16 val) +{ + data[0] = val; + data[1] = val >> 8; + return data + 2; +} + +static inline u8 * +pint32(u8 *data, u32 val) +{ + data[0] = val; + data[1] = val >> 8; + data[2] = val >> 16; + data[3] = val >> 24; + return data + 4; +} + +static inline u8 * +pint64(u8 *data, u64 val) +{ + data[0] = val; + data[1] = val >> 8; + data[2] = val >> 16; + data[3] = val >> 24; + data[4] = val >> 32; + data[5] = val >> 40; + data[6] = val >> 48; + data[7] = val >> 56; + return data + 8; +} + +static inline int +pstr(u8 *data, u16 sz, char *val) +{ + pint16(data, sz); + if (sz) + memmove(data+2, val, sz); + + return sz + 2; +} + +static inline int +pstat(char *path, u8 *data, int dotu, int maxsz) +{ + int n, sz, nsz, usz, gsz, msz, esz; + int mode; + u32 version; + u64 qpath; + char ext[256], ubuf[256], gbuf[256], *name; + struct passwd pw, *pwp; + struct group grp, *pgrp; + struct stat st; + + if (lstat(path, &st) < 0) + return -1; + + name = strrchr(path, '/'); + if (name) + name++; + else + name = path; + + mode = 0; + if (S_ISDIR(st.st_mode)) + mode |= Dmdir; + + ext[0] = '\0'; + if (dotu) { + if (S_ISLNK(st.st_mode)) { + mode |= Dmsymlink; + n = readlink(path, ext, sizeof(ext) - 1); + if (n < 0) + return -1; + } + + if (S_ISSOCK(st.st_mode)) + mode |= Dmsocket; + if (S_ISFIFO(st.st_mode)) + mode |= Dmnamedpipe; + if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)) { + snprintf(ext, sizeof(ext), "%c %u %u", S_ISCHR(st.st_mode)?'c':'b', + major(st.st_rdev), minor(st.st_rdev)); + + mode |= Dmdevice; + } + + if (st.st_mode & S_ISUID) + mode |= Dmsetuid; + if (st.st_mode & S_ISGID) + mode |= Dmsetgid; + } + + mode |= st.st_mode & 0777; + nsz = 0; + usz = 0; + gsz = 0; + msz = 0; + esz = 0; + if (name) + nsz = strlen(name); + + if (!dotu) { + if (getpwuid_r(st.st_uid, &pw, ubuf, sizeof(ubuf), &pwp)) + return -1; + + usz = strlen(pw.pw_name); + if (getgrgid_r(st.st_gid, &grp, gbuf, sizeof(gbuf), &pgrp)) + return -1; + + gsz = strlen(grp.gr_name); + } + + esz = strlen(ext); + sz = 2+4+13+4+4+4+8+2+2+2+2+nsz+usz+gsz+msz+esz; + if (dotu) + sz += 4+4+4+2; + + if (sz >= maxsz) + return -1; + + qpath = 0; + n = sizeof(qpath); + if (n > sizeof(st.st_ino)) + n = sizeof(st.st_ino); + memmove(&qpath, &st.st_ino, n); + version = st.st_mtime ^ (st.st_size << 8); + + pint16(data, sz); + pint16(data+2, 0); + pint32(data+4, 0); + pint8(data+8, mode>>24); + pint32(data+9, version); + pint64(data+13, qpath); + pint32(data+21, mode); + pint32(data+25, st.st_atime); + pint32(data+29, st.st_mtime); + pint64(data+33, st.st_size); + n = 41; + n += pstr(data+n, nsz, name); + n += pstr(data+n, usz, pw.pw_name); + n += pstr(data+n, gsz, grp.gr_name); + n += pstr(data+n, 0, NULL); + if (dotu) { + n += pstr(data+n, esz, ext); + pint32(data+n, st.st_uid); + pint32(data+n+4, st.st_gid); + pint32(data+n+8, ~0); + } + + return sz + 2; +} + +static inline u8 +gint8(u8 *data) +{ + return data[0]; +} + +static inline u16 +gint16(u8 *data) +{ + return data[0] | (data[1]<<8); +} + +static inline u32 +gint32(u8 *data) +{ + return data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24); +} + +static inline u64 +gint64(u8 *data) +{ + return (u64)data[0] | ((u64)data[1]<<8) | ((u64)data[2]<<16) | + ((u64)data[3]<<24) | ((u64)data[4]<<32) | ((u64)data[5]<<40) | + ((u64)data[6]<<48) | ((u64)data[7]<<56); +} + +static inline int +gstr(u8 *data, char **s, int maxsize) +{ + u16 n; + + n = gint16(data); + if (n >= maxsize) + return -1; + + if (n) { + memmove(data, data + 2, n); + data[n] = '\0'; + *s = (char *) data; + } else + *s = NULL; + + return n; +} + +Fid * +fidget(Conn *conn, u32 fid) +{ + int hash; + Fid *f; + + if (fid < Fidtblsz) { + f = &conn->fidtbl[fid]; + if (f->fid == ~0) + f = NULL; + + return f; + } + + hash = fid % Fidhtblsz; + for(f = conn->fidhtbl[hash]; f != NULL; f = f->next) + if (f->fid == fid) + break; + + return f; +} + +Fid * +fidcreate(Conn *conn, u32 fid) +{ + int hash; + Fid *f, *p; + + if (fid < Fidtblsz) { + f = &conn->fidtbl[fid]; + if (f->fid != ~0) + return NULL; + + f->fid = fid; + return f; + } + + f = calloc(1, sizeof(Fid)); + hash = fid % Fidhtblsz; + if (!conn->fidhtbl[hash]) + conn->fidhtbl[hash] = f; + else { + for(p = conn->fidhtbl[hash]; p->next != NULL; p = p->next) + ; + + p->next = f; + } + + return f; +} + +void +fiddestroy(Conn *conn, Fid *f) +{ + int hash; + Fid *p; + + if (f->fid < Fidtblsz) { + memset(f, 0, sizeof(*f)); + f->fid = ~0; + return; + } + + hash = f->fid % Fidhtblsz; + if (f == conn->fidhtbl[hash]) + conn->fidhtbl[hash] = f->next; + else { + for(p = conn->fidhtbl[hash]; p->next != NULL; p = p->next) + if (p->next == f) { + p->next = f->next; + break; + } + } + + free(f); +} + +Conn * +conncreate(int sock, int nwthreads) +{ + int i; + Conn *conn; + + conn = calloc(1, sizeof(*conn) + nwthreads*sizeof(Wthread)); + conn->sock = sock; +// pthread_mutex_init(&conn->rlock, NULL); +// pthread_mutex_init(&conn->wlock, NULL); + conn->msize = msize; + conn->dotu = dotu; + conn->size = ~0; + conn->bpos = 0; + pipe(conn->pip); + for(i = 0; i < Fidtblsz; i++) + conn->fidtbl[i].fid = ~0; + + conn->nwthreads = 0; + conn->wthreads = (Wthread *) &conn[1]; + for(i = 0; i < nwthreads; i++) { + conn->wthreads[i].conn = conn; + conn->wthreads[i].tag = ~0; + +/* + if (clone(connproc, conn->wthreads[i].stk + sizeof(conn->wthreads[i].stk), + CLONE_FS | CLONE_FILES | CLONE_VM, &conn->wthreads[i]) < 0) { + conndestroy(conn); + return NULL; + } +*/ + + if (pthread_create(&conn->wthreads[i].tid, NULL, connproc, &conn->wthreads[i]) < 0) { + conndestroy(conn); + return NULL; + } + + conn->nwthreads++; + } + + return conn; +} + +void +conndestroy(Conn *conn) +{ + int i; + void *v; + + close(conn->sock); + rlock(conn); + conn->sock = -1; + runlock(conn); + + for(i = 0; i < conn->nwthreads; i++) + pthread_join(conn->wthreads[i].tid, &v); + + free(conn); +} + +void +conndisconnect(Conn *conn) +{ + close(conn->sock); + conn->sock = -1; +} + +static int +connproc(void *a) +{ + int n; + u8 type; + u32 size; + u16 tag; + u8 *buf; + Wthread *wt; + Conn *conn; + Freq *freq, *freq1; + + wt = a; + conn = wt->conn; + buf = malloc(conn->msize + sizeof(conn->buf)); + while (1) { + rlock(conn); + if (conn->sock < 0) { + runlock(conn); + return -1; + } + + if (conn->size == ~0) { +ragain: + n = read(conn->sock, conn->buf + conn->bpos, + sizeof(conn->buf) - conn->bpos); + + if (n <= 0) { + if (n<0 && (errno==EAGAIN || errno==EINTR)) + goto ragain; + + goto disconn; + } + + conn->bpos += n; + if (conn->bpos < 7) + goto ragain; + + size = gint32(conn->buf); + type = gint8(conn->buf + 4); + tag = gint16(conn->buf + 5); + assert(size>0&&size<conn->msize && type>=100); + } else { + size = conn->size; + type = conn->type; + tag = conn->tag; + } + + assert(size <= conn->msize); + conn->size = ~0; + if (type&1 || type<Tfirst || type>Tlast || !fhndlrs[(type-Tfirst)/2]) + goto disconn; + + assert(wt->tag==(u16)~0 && wt->freqs==NULL); + wt->tag = tag; + assert(size>0); + n = (*fhndlrs[(type-Tfirst)/2])(conn, type, tag, size, buf); + wlock(conn); + if (n) + writen(conn, buf, n); + + freq = wt->freqs; + while (freq != NULL) { + n = rflush(conn, tag, buf); + writen(conn, buf, n); + freq1 = freq->next; + free(freq); + freq = freq1; + } + + wt->tag = ~0; + wt->freqs = NULL; + wunlock(conn); + } + +disconn: + conndisconnect(conn); + runlock(conn); + + return -1; +} + +static int +writen(Conn *conn, u8 *buf, int buflen) +{ + int n, pos; + + pos = 0; + +again: + n = write(conn->sock, buf + pos, buflen - pos); + if (n <= 0) { + if (n<0 && (errno==EAGAIN || errno==EINTR)) + goto again; + + conndisconnect(conn); + return -1; + } + + pos += n; + if (pos < n) + goto again; + + return buflen; +} + +/* reads the rest of the message into buf, sets up the size, type, tag values + for the next message, and unlocks the read lock */ +static int +readrest(Conn *conn, u32 size, u8 *buf, int unlock) +{ + int n, sz; + u8 *p; + + sz = size; + p = buf; + assert(sz >= 0); + /* first get data from conn->buf, if there is any */ + n = conn->bpos - 7; + if (n > 0) { +// debug("%%%% move sz %d bpos %d\n", sz, conn->bpos); + if (n > sz) + n = sz; + + memmove(p, conn->buf + 7, n); + sz -= n; + p += n; + if (n < conn->bpos-7) + memmove(conn->buf, conn->buf + 7 + n, conn->bpos - 7 - n); + + conn->bpos -= 7 + n; + } + + while (sz > 0) { +// debug("%%%% read sz %d\n", sz); + n = read(conn->sock, p, sz + (unlock?sizeof(conn->buf):0)); + if (n <= 0) { + if (n<0 && (errno==EAGAIN || errno==EINTR)) + continue; + + goto error; + } + + p += n; + sz -= n; + } + + /* now we have the whole message in buf, may be some data for the next */ + if (sz <= 0) { +// debug("%%%% move2 sz %d bpos %d\n", sz, conn->bpos); + memmove(conn->buf + conn->bpos, buf + size, -sz); + conn->bpos += -sz; + } + + if (conn->bpos > 7) { + conn->size = gint32(conn->buf); + conn->type = gint8(conn->buf + 4); + conn->tag = gint16(conn->buf + 5); + assert(conn->size>0 && conn->size<=conn->msize && conn->type>=100); + } + + if (unlock) + runlock(conn); + return size; + +error: + fprintf(stderr, "readrest error %d\n", errno); + conndisconnect(conn); + if (unlock) + runlock(conn); + return -1; +} + +static int +rerror(Conn *conn, u16 tag, u8 *buf, char *ename, int ecode) +{ + int sz, slen; + + slen = strlen(ename); + sz = 9 + slen; + if (conn->dotu) + sz += 4; + + pint32(buf, sz); + pint8(buf + 4, Rerror); + pint16(buf + 5, tag); + pint16(buf + 7, slen); + memmove(buf+9, ename, slen); + if (conn->dotu) + pint32(buf + 9 + slen, ecode); + + return sz; +} + +static int +ruerror(Conn *conn, u16 tag, u8 *buf, int ecode) +{ + char ename[256]; + + strerror_r(ecode, ename, sizeof(ename)); + return rerror(conn, tag, buf, ename, ecode); +} + +static int +badmsg(Conn *conn, u16 tag, u8 *buf) +{ + fprintf(stderr, "bad message\n"); + return rerror(conn, tag, buf, "invalid message", EINVAL); +} + +static int +badfid(Conn *conn, u16 tag, u8 *buf) +{ + return rerror(conn, tag, buf, "invalid fid", EINVAL); +} + +static int +rversion(Conn *conn, u16 tag, u8 *buf, char *version, int msize) +{ + int sz, slen; + + slen = strlen(version); + sz = 13 + slen; + pint32(buf, sz); + pint8(buf + 4, Rversion); + pint16(buf + 5, tag); + pint32(buf + 7, msize); + pint16(buf + 11, slen); + memmove(buf+13, version, slen); + return sz; +} + +static int +rflush(Conn *conn, u16 tag, u8 *buf) +{ + pint32(buf, 7); + pint8(buf + 4, Rflush); + pint16(buf + 5, tag); + return 7; +} + +static int +rattach(Conn *conn, u16 tag, u8 *buf, Qid *qid) +{ + pint32(buf, 20); + pint8(buf + 4, Rattach); + pint16(buf + 5, tag); + pint8(buf + 7, qid->type); + pint32(buf + 8, qid->version); + pint64(buf + 12, qid->path); + return 20; +} + +static int +rwalk(Conn *conn, u16 tag, u8 *buf, u16 nwqid, Qid *wqid) +{ + int i; + + pint32(buf, 9 + nwqid*13); + pint8(buf + 4, Rwalk); + pint16(buf + 5, tag); + pint16(buf + 7, nwqid); + for(i = 0; i < nwqid; i++) { + pint8(buf + 9 + i*13, wqid[i].type); + pint32(buf + 10 + i*13, wqid[i].version); + pint64(buf + 14 + i*13, wqid[i].path); + } + + return 9 + nwqid*13; +} + +static int +ropen(Conn *conn, u16 tag, u8 *buf, Qid *qid, u32 iounit) +{ + pint32(buf, 24); + pint8(buf + 4, Ropen); + pint16(buf + 5, tag); + pint8(buf + 7, qid->type); + pint32(buf + 8, qid->version); + pint64(buf + 12, qid->path); + pint32(buf + 20, iounit); + return 24; +} + +static int +rcreate(Conn *conn, u16 tag, u8 *buf, Qid *qid, u32 iounit) +{ + pint32(buf, 24); + pint8(buf + 4, Rcreate); + pint16(buf + 5, tag); + pint8(buf + 7, qid->type); + pint32(buf + 8, qid->version); + pint64(buf + 12, qid->path); + pint32(buf + 20, iounit); + return 24; +} + +static int +rwrite(Conn *conn, u16 tag, u8 *buf, u32 count) +{ + pint32(buf, 11); + pint8(buf + 4, Rwrite); + pint16(buf + 5, tag); + pint32(buf + 7, count); + return 11; +} + +static int +rclunk(Conn *conn, u16 tag, u8 *buf) +{ + pint32(buf, 7); + pint8(buf + 4, Rclunk); + pint16(buf + 5, tag); + return 7; +} + +static int +rremove(Conn *conn, u16 tag, u8 *buf) +{ + pint32(buf, 7); + pint8(buf + 4, Rremove); + pint16(buf + 5, tag); + return 7; +} + +static int +rstat(Conn *conn, u16 tag, u8 *buf, char *path) +{ + int sz; + + pint8(buf + 4, Rstat); + pint16(buf + 5, tag); + sz = pstat(path, buf + 9, conn->dotu, conn->msize - 9); + if (sz < 0) { + return rerror(conn, tag, buf, "insufficient msize", EIO); + } + + pint16(buf + 7, sz); + pint32(buf, 7 + sz + 2); + return 9 + sz; +} + +static int +rwstat(Conn *conn, u16 tag, u8 *buf) +{ + pint32(buf, 7); + pint8(buf + 4, Rwstat); + pint16(buf + 5, tag); + return 7; +} + +static inline void +setuser(uid_t uid, gid_t gid) +{ + if (sameuser) + return; + + syscall(SYS_setreuid, -1, uid); + syscall(SYS_setregid, -1, gid); +} + +static int +p9version(Conn *conn, u8 type, u16 tag, u32 size, u8 *buf) +{ + int msize; + char *version; + + debug("version tag %d\n", tag); + size -= 7; + if (readrest(conn, size, buf, 1) < 0) + return 0; + + if (size < 6) + return badmsg(conn, tag, buf); + + msize = gint32(buf); + conn->dotu = 0; + if (gstr(buf + 4, &version, size - 4) < 0) + return badmsg(conn, tag, buf); + + if (msize < conn->msize) + conn->msize = msize; + + if (strncmp(version, "9P2000", 6) != 0) + return rerror(conn, tag, buf, "unsupported version", 0); + + conn->dotu = dotu; + if (dotu && strcmp(version, "9P2000.u")==0) + version = "9P2000.u"; + else { + conn->dotu = 0; + version = "9P2000"; + } + + return rversion(conn, tag, buf, version, conn->msize); +} + + +static int +p9auth(Conn *conn, u8 type, u16 tag, u32 size, u8 *buf) +{ + debug("auth tag %d\n", tag); + size -= 7; + if (readrest(conn, size, buf, 1) < 0) + return 0; + + return rerror(conn, tag, buf, "authentication not required", EIO); +} + +static int +stat2qid(struct stat *st, Qid *qid) +{ + int n; + + qid->type = 0; + if (S_ISDIR(st->st_mode)) + qid->type |= Qtdir; + + if (S_ISLNK(st->st_mode)) + qid->type |= Qtsymlink; + + qid->path = 0; + n = sizeof(qid->path); + if (n > sizeof(st->st_ino)) + n = sizeof(st->st_ino); + memmove(&qid->path, &st->st_ino, n); + qid->version = st->st_mtime ^ (st->st_size << 8); + + return 0; +} + +static int +statqid(char *path, Qid *qid) +{ + struct stat st; + + if (lstat(path, &st) < 0) + return -errno; + + return stat2qid(&st, qid); +} + +static int +p9attach(Conn *conn, u8 type, u16 tag, u32 size, u8 *buf) +{ + int n, m; + char *uname, *aname; + u32 nuname; + Fid *fid; + Qid qid; + char ubuf[512]; + struct passwd pw, *pwp; + + debug("attach tag %d\n", tag); + size -= 7; + if (readrest(conn, size, buf, 1) < 0) + return 0; + + if (size < 12) + return badmsg(conn, tag, buf); + + fid = fidcreate(conn, gint32(buf)); + if (!fid) + return rerror(conn, tag, buf, "cannot allocate fid", EIO); + + if (gint32(buf+4) != ~0) + return rerror(conn, tag, buf, "invalid afid", EIO); + + n = 8; + if ((m = gstr(buf+n, &uname, size-n)) < 0) + return badmsg(conn, tag, buf); + + n += m + 2; + if ((m = gstr(buf+n, &aname, size-n)) < 0) + return rerror(conn, tag, buf, "invalid aname", EIO); + + n += m + 2; + if (conn->dotu) + nuname = gint32(buf+n); + else + nuname = ~0; + + fid->uid = ~0; + fid->gid = ~0; + if (nuname != ~0) { + fid->uid = nuname; + n = getpwuid_r(nuname, &pw, ubuf, sizeof(ubuf), &pwp); + if (n) + return ruerror(conn, tag, buf, n); + + fid->gid = pw.pw_gid; + } else if (uname) { + n = getpwnam_r(uname, &pw, ubuf, sizeof(ubuf), &pwp); + if (n) + return ruerror(conn, tag, buf, n); + + fid->uid = pw.pw_uid; + fid->gid = pw.pw_gid; + } + + setuser(fid->uid, fid->gid); + if (aname) + n = strlen(aname) + 1; + else + n = 2; + + if (n < sizeof(fid->cpath)) { + fid->path = fid->cpath; + if (aname) + memmove(fid->path, aname, n); + else + fid->path = strdup("/"); + } else + fid->path = strdup(aname); + + + if ((n = statqid(fid->path, &qid)) < 0) { + fiddestroy(conn, fid); + return ruerror(conn, tag, buf, -n); + } + + fid->type = qid.type; + return rattach(conn, tag, buf, &qid); +} + +static int +p9flush(Conn *conn, u8 type, u16 tag, u32 size, u8 *buf) +{ + int i; + u16 oldtag; + Wthread *wt; + Freq *freq; + + debug("flush tag %d\n", tag); + size -= 7; + if (readrest(conn, size, buf, 1) < 0) + return 0; + + oldtag = gint16(buf); + if (oldtag == tag) + goto respond; + + wlock(conn); + for(i = 0; i < conn->nwthreads; i++) { + wt = &conn->wthreads[i]; + if (wt->tag == oldtag) { + freq = malloc(sizeof(*freq)); + freq->tag = oldtag; + freq->next = wt->freqs; + wt->freqs = freq; + wunlock(conn); + return 0; + } + } + wunlock(conn); + +respond: + return rflush(conn, tag, buf); +} + +static int +p9walk(Conn *conn, u8 type, u16 tag, u32 size, u8 *buf) +{ + int i, n, m, nwname, slen, olen; + char *path; + Fid *fid, *newfid; + char *wnames[Maxwelem]; + u16 wlen[Maxwelem]; + Qid wqids[Maxwelem]; + + debug("walk tag %d\n", tag); + size -= 7; + if (readrest(conn, size, buf, 1) < 0) + return 0; + + if (size < 10) + return badmsg(conn, tag, buf); + + fid = fidget(conn, gint32(buf)); + if (!fid) + return badfid(conn, tag, buf); + + setuser(fid->uid, fid->gid); + n = gint32(buf + 4); + if (n != fid->fid) { + newfid = fidcreate(conn, n); + if (!newfid) + return rerror(conn, tag, buf, "fid already exists", EIO); + } else + newfid = fid; + + nwname = gint16(buf + 8); + slen = 0; + for(i = 0, n = 10, m = 0; i < nwname; i++) { + wlen[i] = gstr(buf+n, &wnames[i], size-n); + if (wlen[i] < 0) + return badmsg(conn, tag, buf); + + n += wlen[i] + 2; + slen += wlen[i] + 1; + } + + olen = strlen(fid->path); + slen += olen + 1; + if (slen >= sizeof(newfid->cpath)) + path = malloc(slen); + else + path = newfid->cpath; + + n = olen; + memmove(path, fid->path, n+1); + for(i = 0; i < nwname; i++) { + path[n++] = '/'; + memmove(&path[n], wnames[i], wlen[i]); + n += wlen[i]; + path[n] = '\0'; + if (statqid(path, &wqids[i]) < 0) + break; + } + + if (nwname && i<=0) { + if (newfid != fid) + fiddestroy(conn, newfid); + else + path[olen] = '\0'; + + if (path != newfid->cpath) + free(path); + + return ruerror(conn, tag, buf, ENOENT); + } + + if (newfid->path && newfid->path != newfid->cpath) + free(newfid->path); + + newfid->path = path; + if (i==0) + newfid->type = fid->type; + else + newfid->type = wqids[i-1].type; + + return rwalk(conn, tag, buf, i, wqids); +} + +int +uflags(u8 mode) +{ + int flags; + + flags = 0; + switch (mode & 3) { + case Oexec: + case Oread: + flags = O_RDONLY; + break; + case Owrite: + flags = O_WRONLY; + break; + case Ordwr: + flags = O_RDWR; + break; + } + + if (mode & Otrunc) + flags |= O_TRUNC; + if (mode & Oappend) + flags |= O_APPEND; + if (mode & Oexcl) + flags |= O_EXCL; + + return flags; +} + +static int +p9open(Conn *conn, u8 type, u16 tag, u32 size, u8 *buf) +{ + Fid *fid; + Qid qid; + + debug("open tag %d\n", tag); + size -= 7; + if (readrest(conn, size, buf, 1) < 0) + return 0; + + if (size < 5) + return badmsg(conn, tag, buf); + + fid = fidget(conn, gint32(buf)); + if (!fid) + return badfid(conn, tag, buf); + + setuser(fid->uid, fid->gid); + if (fid->type & Qtdir) { + fid->dir = opendir(fid->path); + if (!fid->dir) + return ruerror(conn, tag, buf, errno); + } else { + fid->fd = open(fid->path, uflags(gint8(buf + 4))); + if (fid->fd < 0) + return ruerror(conn, tag, buf, errno); + } + + if (statqid(fid->path, &qid) < 0) + return ruerror(conn, tag, buf, errno); + + return ropen(conn, tag, buf, &qid, 0); +} + + +static int +p9create(Conn *conn, u8 type, u16 tag, u32 size, u8 *buf) +{ + u8 omode; + char ctype; + int olen, nlen, n; + int major, minor; + u32 perm; + char *path, *name, *extension, *s; + Fid *fid, *ofid; + Qid qid; + + debug("create tag %d\n", tag); + size -= 7; + if (readrest(conn, size, buf, 1) < 0) + return 0; + + if (size < 11) + return badmsg(conn, tag, buf); + + fid = fidget(conn, gint32(buf)); + if (!fid) + return badfid(conn, tag, buf); + + setuser(fid->uid, fid->gid); + if (!(fid->type & Qtdir)) + return rerror(conn, tag, buf, "not a directory", ENOTDIR); + + nlen = gstr(buf+4, &name, size-4); + if (nlen < 0) + return badmsg(conn, tag, buf); + + perm = gint32(buf+6+nlen); + omode = gint8(buf+10+nlen); + if (conn->dotu && gstr(buf+11+nlen, &extension, size-8-nlen) < 0) + return badmsg(conn, tag, buf); + + olen = strlen(fid->path); + if (olen+nlen+2 < sizeof(fid->cpath)) + path = fid->cpath; + else + path = malloc(olen+nlen+2); + + memmove(path, fid->path, olen); + path[olen] = '/'; + memmove(path + olen + 1, name, nlen + 1); + + if (perm & Dmdir) { + if (mkdir(path, perm & 0777) < 0) + goto uerror; + } else if (perm & Dmnamedpipe) { + if (mknod(path, S_IFIFO | (perm&0777), 0) < 0) + goto uerror; + } else if (perm & Dmsymlink) { + if (symlink(extension, path) < 0) + goto uerror; + + if (chmod(path, perm&0777) < 0) + goto uerror; + } else if (perm & Dmlink) { + n = strtol(extension, &s, 10); + if (*s != '\0') { + n = rerror(conn, tag, buf, "invalid link", EINVAL); + goto error; + } + + ofid = fidget(conn, n); + if (!ofid) { + n = rerror(conn, tag, buf, "invalid fid", EINVAL); + goto error; + } + + if (link(ofid->path, path) < 0) + goto uerror; + } else if (perm & Dmdevice) { + if (sscanf(extension, "%c %u %u", &ctype, &major, &minor) != 3) { + n = rerror(conn, tag, buf, "invalid format", EINVAL); + goto error; + } + + switch (ctype) { + case 'c': + n = S_IFCHR; + break; + + case 'b': + n = S_IFBLK; + break; + + default: + n = rerror(conn, tag, buf, "invalid device type", EINVAL); + goto error; + } + + if (mknod(path, n & (perm&0777), 0) < 0) + goto uerror; + } else { + fid->fd = open(path, O_CREAT | uflags(omode), perm&0777); + if (fid->fd < 0) + goto uerror; + } + + if (fid->path != fid->cpath) + free(fid->path); + + fid->path = path; + if (statqid(fid->path, &qid) < 0) + return ruerror(conn, tag, buf, errno); + + fid->type = qid.type; + return rcreate(conn, tag, buf, &qid, 0); + +uerror: + n = ruerror(conn, tag, buf, errno); + +error: + if (path != fid->cpath) + free(path); + else + path[olen] = '\0'; + + return n; +} + +static int +p9readdir(Conn *conn, u16 tag, u8 *buf, Fid *fid, u64 offset, u32 count) +{ + int n, m, plen; + char *path, *dname; + struct dirent *dirent; + + if (offset==0) { + rewinddir(fid->dir); + fid->diroffset = 0; + free(fid->direntname); + fid->direntname = NULL; + } + + plen = strlen(fid->path); + path = malloc(plen + NAME_MAX + 3); + memmove(path, fid->path, plen); + path[plen] = '/'; + n = 0; + dname = fid->direntname; + while (n < count) { + if (!dname) { + dirent = readdir(fid->dir); + if (!dirent) + break; + + if (strcmp(dirent->d_name, ".") == 0 || + strcmp(dirent->d_name, "..") == 0) + continue; + + dname = dirent->d_name; + } + + strcpy(&path[plen + 1], dname); + m = pstat(path, buf + n + 11, conn->dotu, count + 11 - n); + if (m < 0) { + if (n==0) { + m = errno; + if (m==0) + m = EIO; + return ruerror(conn, tag, buf, m); + } + + break; + } + + n += m; + dname = NULL; + } + + free(fid->direntname); + if (dname) + fid->direntname = strdup(dname); + + pint32(buf, 11 + n); + pint8(buf+4, Rread); + pint16(buf+5, tag); + pint32(buf+7, n); + + return 11 + n; +} + +static int +p9read(Conn *conn, u8 type, u16 tag, u32 size, u8 *buf) +{ + int n, m; + u32 count; + u64 offset; + off_t eoff; + Fid *fid; + struct msghdr mhdr; + struct iovec iov; + + debug("read tag %d\n", tag); + size -= 7; + if (readrest(conn, size, buf, 1) < 0) + return 0; + + if (size < 16) + return badmsg(conn, tag, buf); + + fid = fidget(conn, gint32(buf)); + if (!fid) + return badfid(conn, tag, buf); + + setuser(fid->uid, fid->gid); + offset = gint64(buf+4); + count = gint32(buf+12); + + if (fid->type & Qtdir) + return p9readdir(conn, tag, buf, fid, offset, count); + +/* + mhdr.msg_name = NULL; + mhdr.msg_namelen = 0; + mhdr.msg_iov = &iov; + mhdr.msg_iovlen = 0; + mhdr.msg_control = NULL; + mhdr.msg_controllen = 0; + mhdr.msg_flags = MSG_MORE; + iov.iov_base = buf; + iov.iov_len = 11; + while (iov.iov_len > 0) { + n = sendmsg(conn->sock, &mhdr, MSG_MORE); + if (n < 0) { + fprintf(stderr, "ERROR %d\n", errno); + wunlock(conn); + return 0; + } + + iov.iov_base += n; + iov.iov_len -= n; + } +*/ + +#ifndef X + n = 0; + while (n < count) { + m = pread(fid->fd, buf+11+n, count-n, offset+n); + if (m < 0) + return ruerror(conn, tag, buf, errno); + else if (m == 0) + break; + + n += m; + } + + pint32(buf, 11+n); + pint8(buf+4, Rread); + pint16(buf+5, tag); + pint32(buf+7, n); + + return 11+n; +#else + wlock(conn); + eoff = lseek(fid->fd, 0, SEEK_END); + if (eoff-offset < count) + count = eoff - offset; + + pint32(buf, 11 + count); + pint8(buf+4, Rread); + pint16(buf+5, tag); + pint32(buf+7, count); + n = writen(conn, buf, 11); + if (n < 0) { + wunlock(conn); + return 0; + } + + eoff = offset; + while (count) { + n = sendfile(conn->sock, fid->fd, &eoff, count); + if (n < 0) { + if (errno==EAGAIN || errno==EINTR) + continue; + + // TODO: that's not right + return ruerror(conn, tag, buf, errno); + } else if (n == 0) + break; + + count -= n; + } + wunlock(conn); + + + return 0; +#endif +} + +static int +p9write(Conn *conn, u8 type, u16 tag, u32 size, u8 *buf) +{ + int i, n, m, c; + u32 count; + u64 offset; + Fid *fid; + + debug("write tag %d\n", tag); + size -= 7; + if (size < 16) + return badmsg(conn, tag, buf); + +#ifdef XY + if (readrest(conn, 16, buf, 0) < 0) { +#else + if (readrest(conn, size, buf, 1) < 0) { +#endif + runlock(conn); + return 0; + } + + fid = fidget(conn, gint32(buf)); + if (!fid) { + runlock(conn); + return badfid(conn, tag, buf); + } + + setuser(fid->uid, fid->gid); + offset = gint64(buf+4); + count = gint32(buf+12); + + if (fid->type & Qtdir) { + readrest(conn, size - 16, buf, 1); + return rerror(conn, tag, buf, "permission denied", EPERM); + } + +#ifdef XY + c = count; + if (conn->bpos) { + n = conn->bpos; + if (count < n) + n = count; + + i = 0; + while (i < n) { + m = pwrite(fid->fd, conn->buf + i, n - i, offset + i); + if (m < 0) + return ruerror(conn, tag, buf, errno); + else if (m == 0) + goto error; + } + + if (conn->bpos > count) { + memmove(conn->buf, conn->buf + count, conn->bpos - count); + conn->bpos -= count; + } + + offset += n; + count -= n; + } + + while (count > 0) { + n = splice(conn->sock, NULL, conn->pip[1], NULL, count, 0); + if (n < 0) + goto error; + + m = splice(conn->pip[0], NULL, fid->fd, (off_t *) &offset, n, 0); + if (m < 0) + goto error; + + if (m != n) + goto error; + + count -= n; + } + + runlock(conn); +#else + c = count; + n = 0; + while (n < count) { + m = pwrite(fid->fd, buf+4+n, count-n, offset+n); + if (m < 0) + return ruerror(conn, tag, buf, errno); + else if (m == 0) + goto error; + + n += m; + } + + return rwrite(conn, tag, buf, c); +#endif + +error: + fprintf(stderr, "*** splice error\n"); + conndisconnect(conn); + return 0; +} + + +static int +p9clunk(Conn *conn, u8 type, u16 tag, u32 size, u8 *buf) +{ + Fid *fid; + + debug("clunk tag %d\n", tag); + size -= 7; + if (size < 4) + return badmsg(conn, tag, buf); + + if (readrest(conn, size, buf, 1) < 0) + return 0; + + fid = fidget(conn, gint32(buf)); + if (!fid) { + runlock(conn); + return badfid(conn, tag, buf); + } + + setuser(fid->uid, fid->gid); + if (fid->fd) + close(fid->fd); + + if (fid->dir) { + closedir(fid->dir); + } + + if (fid->path != fid->cpath) + free(fid->path); + + free(fid->direntname); + fiddestroy(conn, fid); + + return rclunk(conn, tag, buf); +} + + +static int +p9remove(Conn *conn, u8 type, u16 tag, u32 size, u8 *buf) +{ + Fid *fid; + + debug("remove tag %d\n", tag); + size -= 7; + if (size < 4) + return badmsg(conn, tag, buf); + + if (readrest(conn, size, buf, 1) < 0) + return 0; + + fid = fidget(conn, gint32(buf)); + if (!fid) { + runlock(conn); + return badfid(conn, tag, buf); + } + + setuser(fid->uid, fid->gid); + if (fid->type&Qtdir) { + if (rmdir(fid->path) < 0) + return ruerror(conn, tag, buf, errno); + } else { + if (unlink(fid->path) < 0) + return ruerror(conn, tag, buf, errno); + } + + if (fid->fd) + close(fid->fd); + + if (fid->path != fid->cpath) + free(fid->path); + + free(fid->direntname); + fiddestroy(conn, fid); + return rremove(conn, tag, buf); +} + + +static int +p9stat(Conn *conn, u8 type, u16 tag, u32 size, u8 *buf) +{ + Fid *fid; + + debug("stat tag %d\n", tag); + size -= 7; + if (size < 4) + return badmsg(conn, tag, buf); + + if (readrest(conn, size, buf, 1) < 0) + return 0; + + fid = fidget(conn, gint32(buf)); + if (!fid) { + runlock(conn); + return badfid(conn, tag, buf); + } + + setuser(fid->uid, fid->gid); + return rstat(conn, tag, buf, fid->path); +} + + +static int +p9wstat(Conn *conn, u8 type, u16 tag, u32 size, u8 *buf) +{ + int n, nlen, pos, glen; + u32 mode, mtime, ngid; + u64 length; + char *name, *gid, *p, *npath, ubuf[512]; + Fid *fid; + struct group grp, *pgrp; + struct utimbuf tb; + + debug("wstat tag %d\n", tag); + size -= 7; + if (size < 53) + return badmsg(conn, tag, buf); + + if (conn->dotu && size<67) + return badmsg(conn, tag, buf); + + if (readrest(conn, size, buf, 1) < 0) + return 0; + + fid = fidget(conn, gint32(buf)); + if (!fid) { + runlock(conn); + return badfid(conn, tag, buf); + } + + setuser(fid->uid, fid->gid); + mode = gint32(buf+27); + mtime = gint32(buf+35); + length = gint64(buf+39); + nlen = gstr(buf+47, &name, size-47); + if (nlen<0) + return badmsg(conn, tag, buf); + + pos = 49 + nlen; + pos += gint16(buf+pos) + 2; + if (pos >= size) + return badmsg(conn, tag, buf); + + glen = gstr(buf+pos, &gid, size-pos); + if (glen<0) + return badmsg(conn, tag, buf); + + pos += glen + 2; + pos += gint16(buf+pos) + 2; + if (pos >= size) + return badmsg(conn, tag, buf); + + ngid = ~0; + if (conn->dotu) { + pos += gint16(buf+pos) + 2; + if (pos >= size) + return badmsg(conn, tag, buf); + + ngid = gint32(buf+pos+4); + } + + if (ngid==~0 && gid) { + n = getgrnam_r(gid, &grp, ubuf, sizeof(ubuf), &pgrp); + if (n) + return ruerror(conn, tag, buf, n); + + ngid = grp.gr_gid; + } + + if (mode != ~0) { + if (chmod(fid->path, mode&0777) < 0) + return ruerror(conn, tag, buf, errno); + } + if (mtime != ~0) { + tb.actime = 0; + tb.modtime = mtime; + if (utime(fid->path, &tb) < 0) + return ruerror(conn, tag, buf, errno); + } + if (ngid != ~0) { + if (chown(fid->path, -1, ngid) < 0) + return ruerror(conn, tag, buf, errno); + } + if (name) { + p = strrchr(fid->path, '/'); + if (!p) + p = fid->path + strlen(fid->path); + + nlen = strlen(name); + npath = malloc(nlen + (p - fid->path) + 2); + memmove(npath, fid->path, p - fid->path); + npath[p - fid->path] = '/'; + memmove(npath + (p - fid->path) + 1, name, nlen); + npath[(p - fid->path) + 1 + nlen] = 0; + if (strcmp(npath, fid->path) != 0) { + if (rename(fid->path, npath) < 0) { + free(npath); + return ruerror(conn, tag, buf, errno); + } + + if (fid->path != fid->cpath) + free(fid->path); + + fid->path = npath; + } else + free(npath); + } + if (length != ~0) { + if (truncate(fid->path, length) < 0) + return ruerror(conn, tag, buf, errno); + } + + return rwstat(conn, tag, buf); +} + +void +usage() +{ + fprintf(stderr, "npfs: -d -s -p port -w nthreads\n"); + exit(-1); +} + +int +main(int argc, char *argv[]) +{ + int c, csock, sock; + socklen_t n; + int port, nwthreads; + char *s; + struct sockaddr_in saddr; + Conn *conn; + + port = 564; + nwthreads = 16; + msize = 8216; + while ((c = getopt(argc, argv, "dsp:w:m:")) != -1) { + switch (c) { + case 'd': + debuglevel = 1; + break; + + case 'p': + port = strtol(optarg, &s, 10); + if (*s != '\0') + usage(); + break; + + case 'w': + nwthreads = strtol(optarg, &s, 10); + if (*s != '\0') + usage(); + break; + + case 's': + sameuser = 1; + break; + + case 'm': + msize = strtol(optarg, &s, 10); + if (*s != '\0') + usage(); + break; + + default: + usage(); + } + } + + sock = socket(PF_INET, SOCK_STREAM, 0); + if (sock < 0) { + perror("socket"); + return -1; + } + + saddr.sin_family = AF_INET; + saddr.sin_port = htons(port); + saddr.sin_addr.s_addr = htonl(INADDR_ANY); + if (bind(sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) { + perror("bind"); + return -1; + } + + if (listen(sock, 1) < 0) { + perror("listen"); + return -1; + } + + n = sizeof(saddr); + while ((csock = accept(sock, &saddr, &n)) >= 0) { + conn = conncreate(csock, nwthreads); + } + + return 0; +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ab...@us...> - 2008-12-09 20:51:38
|
Revision: 29 http://npfs.svn.sourceforge.net/npfs/?rev=29&view=rev Author: abbyz9 Date: 2008-12-09 20:51:35 +0000 (Tue, 09 Dec 2008) Log Message: ----------- Makefile fixes for spfs. spclient was not being installed through the top-level Makefile install target. Also added some multilib goo so that libraries are installed in /usr/local/lib64 on 64-bit platforms. Signed-off-by: Abhishek Kulkarni <kul...@la...> Acked-by: Latchesar Ionkov <lu...@io...> Modified Paths: -------------- spfs/trunk/Makefile spfs/trunk/libspclient/Makefile spfs/trunk/libspfs/Makefile Modified: spfs/trunk/Makefile =================================================================== --- spfs/trunk/Makefile 2008-12-09 20:50:27 UTC (rev 28) +++ spfs/trunk/Makefile 2008-12-09 20:51:35 UTC (rev 29) @@ -1,5 +1,7 @@ SYSNAME:=${shell uname} SYSNAME!=uname +INSTALLPREFIX:=/usr/local +export INSTALLPREFIX all: make -C libspfs @@ -13,5 +15,5 @@ make -C fs clean install: - cp include/spfs.h /usr/local/include - cp libspfs/libspfs.a /usr/local/lib + make -C libspfs install + make -C libspclient install Modified: spfs/trunk/libspclient/Makefile =================================================================== --- spfs/trunk/libspclient/Makefile 2008-12-09 20:50:27 UTC (rev 28) +++ spfs/trunk/libspclient/Makefile 2008-12-09 20:51:35 UTC (rev 29) @@ -1,5 +1,6 @@ SYSNAME:=${shell uname} SYSNAME!=uname +MULTILIBPATH=${shell test -d /lib64 && echo lib64 || echo lib} HFILES=../include/spfs.h ../include/spclient.h spcimpl.h CFLAGS=-Wall -g -I ../include @@ -28,9 +29,9 @@ install: mkdir -p $(INSTALLPREFIX)/include - mkdir -p $(INSTALLPREFIX)/lib + mkdir -p $(INSTALLPREFIX)/$(MULTILIBPATH) cp ../include/spclient.h $(INSTALLPREFIX)/include - cp libspclient.a $(INSTALLPREFIX)/lib + cp libspclient.a $(INSTALLPREFIX)/$(MULTILIBPATH) clean: rm -f *.o *.a *~ Modified: spfs/trunk/libspfs/Makefile =================================================================== --- spfs/trunk/libspfs/Makefile 2008-12-09 20:50:27 UTC (rev 28) +++ spfs/trunk/libspfs/Makefile 2008-12-09 20:51:35 UTC (rev 29) @@ -1,5 +1,6 @@ SYSNAME:=${shell uname} SYSNAME!=uname +MULTILIBPATH=${shell test -d /lib64 && echo lib64 || echo lib} HFILES=../include/spfs.h spfsimpl.h CFLAGS=-Wall -g -I ../include -D$(SYSNAME) @@ -28,9 +29,9 @@ install: mkdir -p $(INSTALLPREFIX)/include - mkdir -p $(INSTALLPREFIX)/lib + mkdir -p $(INSTALLPREFIX)/$(MULTILIBPATH) cp ../include/spfs.h $(INSTALLPREFIX)/include - cp libspfs.a $(INSTALLPREFIX)/lib + cp libspfs.a $(INSTALLPREFIX)/$(MULTILIBPATH) clean: rm -f *.o *.a *~ core.* This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ab...@us...> - 2008-12-09 20:50:30
|
Revision: 28 http://npfs.svn.sourceforge.net/npfs/?rev=28&view=rev Author: abbyz9 Date: 2008-12-09 20:50:27 +0000 (Tue, 09 Dec 2008) Log Message: ----------- Makefile fixes for npfs. npclient was not being installed through the top-level Makefile install target. Also added some multilib goo so that libraries are installed in /usr/local/lib64 on 64-bit platforms. Signed-off-by: Abhishek Kulkarni <kul...@la...> Acked-by: Latchesar Ionkov <lu...@io...> Modified Paths: -------------- npfs/trunk/Makefile npfs/trunk/libnpclient/Makefile npfs/trunk/libnpfs/Makefile Modified: npfs/trunk/Makefile =================================================================== --- npfs/trunk/Makefile 2008-12-04 16:59:22 UTC (rev 27) +++ npfs/trunk/Makefile 2008-12-09 20:50:27 UTC (rev 28) @@ -1,15 +1,19 @@ CFLAGS=-Wall -g +INSTALLPREFIX:=/usr/local +export INSTALLPREFIX all: make -C libnpfs + make -C libnpclient make -C fs clean: make -C libnpfs clean + make -C libnpclient clean make -C fs clean rm -f *~ include/*~ install: - cp include/npfs.h /usr/local/include - cp libnpfs/libnpfs.a /usr/local/lib + make -C libnpfs install + make -C libnpclient install Modified: npfs/trunk/libnpclient/Makefile =================================================================== --- npfs/trunk/libnpclient/Makefile 2008-12-04 16:59:22 UTC (rev 27) +++ npfs/trunk/libnpclient/Makefile 2008-12-09 20:50:27 UTC (rev 28) @@ -1,5 +1,6 @@ SYSNAME:=${shell uname} SYSNAME!=uname +MULTILIBPATH=${shell test -d /lib64 && echo lib64 || echo lib} HFILES=../include/npfs.h ../include/npclient.h npcimpl.h CFLAGS=-Wall -g -I ../include @@ -24,9 +25,9 @@ install: mkdir -p $(INSTALLPREFIX)/include - mkdir -p $(INSTALLPREFIX)/lib + mkdir -p $(INSTALLPREFIX)/$(MULTILIBPATH) cp ../include/npclient.h $(INSTALLPREFIX)/include - cp libnpclient.a $(INSTALLPREFIX)/lib + cp libnpclient.a $(INSTALLPREFIX)/$(MULTILIBPATH) clean: rm -f *.o *.a *~ Modified: npfs/trunk/libnpfs/Makefile =================================================================== --- npfs/trunk/libnpfs/Makefile 2008-12-04 16:59:22 UTC (rev 27) +++ npfs/trunk/libnpfs/Makefile 2008-12-09 20:50:27 UTC (rev 28) @@ -1,5 +1,6 @@ SYSNAME:=${shell uname} SYSNAME!=uname +MULTILIBPATH=${shell test -d /lib64 && echo lib64 || echo lib} HFILES=../include/npfs.h npfsimpl.h CFLAGS=-Wall -g -I../include -D$(SYSNAME) INCLUDEDIRS:=/usr/include/ /usr/local/include/ /opt/include/ @@ -44,9 +45,9 @@ install: mkdir -p $(INSTALLPREFIX)/include - mkdir -p $(INSTALLPREFIX)/lib + mkdir -p $(INSTALLPREFIX)/$(MULTILIBPATH) cp ../include/npfs.h $(INSTALLPREFIX)/include - cp libnpfs.a $(INSTALLPREFIX)/lib + cp libnpfs.a $(INSTALLPREFIX)/$(MULTILIBPATH) clean: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ab...@us...> - 2008-12-04 16:59:51
|
Revision: 27 http://npfs.svn.sourceforge.net/npfs/?rev=27&view=rev Author: abbyz9 Date: 2008-12-04 16:59:22 +0000 (Thu, 04 Dec 2008) Log Message: ----------- np_unix_users->uid2user was not assigning the groups to a user properly. this patch fixes the bug. Signed-off-by: Abhishek Kulkarni <kul...@la...> Acked-by: Latchesar Ionkov <lu...@io...> Modified Paths: -------------- npfs/trunk/libnpfs/uxusers.c Modified: npfs/trunk/libnpfs/uxusers.c =================================================================== --- npfs/trunk/libnpfs/uxusers.c 2008-12-04 16:56:35 UTC (rev 26) +++ npfs/trunk/libnpfs/uxusers.c 2008-12-04 16:59:22 UTC (rev 27) @@ -364,10 +364,8 @@ pthread_mutex_lock(&grentlock); setgrent(); - if(u->dfltgroup) { + if(u->dfltgroup) gids[0] = u->dfltgroup->gid; - n++; - } while ((g = getgrent()) != NULL) { for (i = 0; g->gr_mem[i]; i++) { @@ -382,15 +380,15 @@ endgrent(); pthread_mutex_unlock(&grentlock); - grps = np_malloc(sizeof(*grps) * n); + grps = np_malloc(sizeof(*grps) * (n+1)); if (!grps) { free(gids); return -1; } - for(i = 0; i < n; i++) { + for(i = 0; i <= n; i++) { grps[i] = u->upool->gid2group(u->upool, gids[i]); - if (grps[i]) { + if (!grps[i]) { free(grps); return -1; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ab...@us...> - 2008-12-04 16:56:38
|
Revision: 26 http://npfs.svn.sourceforge.net/npfs/?rev=26&view=rev Author: abbyz9 Date: 2008-12-04 16:56:35 +0000 (Thu, 04 Dec 2008) Log Message: ----------- sp_unix_users->uid2user was not assigning the groups to a user properly. Signed-off-by: Abhishek Kulkarni <kul...@la...> Acked-by: Latchesar Ionkov <lu...@io...> Modified Paths: -------------- spfs/trunk/libspfs/uxusers.c Modified: spfs/trunk/libspfs/uxusers.c =================================================================== --- spfs/trunk/libspfs/uxusers.c 2008-12-03 03:22:07 UTC (rev 25) +++ spfs/trunk/libspfs/uxusers.c 2008-12-04 16:56:35 UTC (rev 26) @@ -355,10 +355,8 @@ setgrent(); - if(u->dfltgroup) { + if(u->dfltgroup) gids[0] = u->dfltgroup->gid; - n++; - } while ((g = getgrent()) != NULL) { for (i = 0; g->gr_mem[i]; i++) { @@ -372,15 +370,15 @@ endgrent(); - grps = sp_malloc(sizeof(*grps) * n); + grps = sp_malloc(sizeof(*grps) * (n+1)); if (!grps) { free(gids); return -1; } - for(i = 0; i < n; i++) { + for(i = 0; i <= n; i++) { grps[i] = u->upool->gid2group(u->upool, gids[i]); - if (grps[i]) { + if (!grps[i]) { free(grps); return -1; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ab...@us...> - 2008-12-03 03:22:10
|
Revision: 25 http://npfs.svn.sourceforge.net/npfs/?rev=25&view=rev Author: abbyz9 Date: 2008-12-03 03:22:07 +0000 (Wed, 03 Dec 2008) Log Message: ----------- weird libspclient spc_notify bug. this was done this way because sometimes an unrelated error can pop-up in unexpected places. reverting this for now as this caused a strange hang for xrx. Signed-off-by: Abhishek Kulkarni <kul...@la...> Acked-by: Lucho Modified Paths: -------------- spfs/trunk/libspclient/fsys.c Modified: spfs/trunk/libspclient/fsys.c =================================================================== --- spfs/trunk/libspclient/fsys.c 2008-11-25 23:43:36 UTC (rev 24) +++ spfs/trunk/libspclient/fsys.c 2008-12-03 03:22:07 UTC (rev 25) @@ -456,8 +456,8 @@ static void spc_notify(Spfd *spfd, void *aux) { - int ecode, ec; - char *ename, *en; + int ecode; + char *ename; Spcfsys *fs; fs = aux; @@ -485,17 +485,12 @@ spc_disconnect_fsys(fs); error: - sp_rerror(&en, &ec); - if (ec) { + sp_rerror(&ename, &ecode); + if (ecode) { if (spc_chatty) - fprintf(stderr, "Error: %s: %d\n", en, ec); + fprintf(stderr, "Error: %s: %d\n", ename, ecode); sp_werror(NULL, 0); } - - if (ecode) - sp_werror(ename, ecode); - - free(ename); fs->in_notify--; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ab...@us...> - 2008-11-25 23:43:46
|
Revision: 24 http://npfs.svn.sourceforge.net/npfs/?rev=24&view=rev Author: abbyz9 Date: 2008-11-25 23:43:36 +0000 (Tue, 25 Nov 2008) Log Message: ----------- more libspclient fixes. adding the function definitions for spc_getladdr and spc_getraddr. removing the obsolete, never-used spc_get_local_address() and spc_get_remore_address() Modified Paths: -------------- spfs/trunk/include/spclient.h spfs/trunk/libspclient/fsys.c Modified: spfs/trunk/include/spclient.h =================================================================== --- spfs/trunk/include/spclient.h 2008-11-25 23:29:34 UTC (rev 23) +++ spfs/trunk/include/spclient.h 2008-11-25 23:43:36 UTC (rev 24) @@ -88,5 +88,6 @@ void spcfd_stop_loop(void); int spcfd_read(Spcfd *spcfd, void *buf, int buflen); int spcfd_write(Spcfd *spcfd, void *buf, int buflen); -char *spc_get_local_address(Spcfsys *fs); -char *spc_get_remote_address(Spcfsys *fs); + +int spc_getladdr(Spcfsys *fs, char *buf, int buflen); +int spc_getraddr(Spcfsys *fs, char *buf, int buflen); Modified: spfs/trunk/libspclient/fsys.c =================================================================== --- spfs/trunk/libspclient/fsys.c 2008-11-25 23:29:34 UTC (rev 23) +++ spfs/trunk/libspclient/fsys.c 2008-11-25 23:43:36 UTC (rev 24) @@ -199,18 +199,6 @@ free(fs); } -char * -spc_get_local_address(Spcfsys *fs) -{ - return fs->laddr; -} - -char * -spc_get_remote_address(Spcfsys *fs) -{ - return fs->raddr; -} - void spc_request_flushed(Spcreq *r) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ab...@us...> - 2008-11-25 23:29:39
|
Revision: 23 http://npfs.svn.sourceforge.net/npfs/?rev=23&view=rev Author: abbyz9 Date: 2008-11-25 23:29:34 +0000 (Tue, 25 Nov 2008) Log Message: ----------- This patch adds some functions to libspclient that allow getting the local and remote address for a session. refer r693 from sxcpu/libspclient Modified Paths: -------------- spfs/trunk/libspclient/fsys.c Modified: spfs/trunk/libspclient/fsys.c =================================================================== --- spfs/trunk/libspclient/fsys.c 2008-11-25 23:23:05 UTC (rev 22) +++ spfs/trunk/libspclient/fsys.c 2008-11-25 23:29:34 UTC (rev 23) @@ -656,3 +656,25 @@ return fc; } + +int +spc_getladdr(Spcfsys *fs, char *buf, int buflen) +{ + if (fs->laddr) { + strncpy(buf, fs->laddr, buflen); + return 0; + } + + return -1; +} + +int +spc_getraddr(Spcfsys *fs, char *buf, int buflen) +{ + if (fs->raddr) { + strncpy(buf, fs->raddr, buflen); + return 0; + } + + return -1; +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ab...@us...> - 2008-11-25 23:23:09
|
Revision: 22 http://npfs.svn.sourceforge.net/npfs/?rev=22&view=rev Author: abbyz9 Date: 2008-11-25 23:23:05 +0000 (Tue, 25 Nov 2008) Log Message: ----------- This patch prevents a segfault caused by spc_rpc and spc_walk if the filesystem was previously disconnected by spc_disconnect_fsys . Modified Paths: -------------- spfs/trunk/libspclient/fsys.c spfs/trunk/libspclient/walk.c Modified: spfs/trunk/libspclient/fsys.c =================================================================== --- spfs/trunk/libspclient/fsys.c 2008-11-25 23:15:17 UTC (rev 21) +++ spfs/trunk/libspclient/fsys.c 2008-11-25 23:23:05 UTC (rev 22) @@ -597,6 +597,9 @@ char *ename; Spcrpc r; + if (fs->fd < 0) + return -1; + if (rc) *rc = NULL; Modified: spfs/trunk/libspclient/walk.c =================================================================== --- spfs/trunk/libspclient/walk.c 2008-11-25 23:15:17 UTC (rev 21) +++ spfs/trunk/libspclient/walk.c 2008-11-25 23:23:05 UTC (rev 22) @@ -39,6 +39,9 @@ Spfcall *tc, *rc; Spcfid *fid; + if (!fs->root) + return NULL; + while (*path == '/') path++; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ab...@us...> - 2008-11-25 23:15:27
|
Revision: 21 http://npfs.svn.sourceforge.net/npfs/?rev=21&view=rev Author: abbyz9 Date: 2008-11-25 23:15:17 +0000 (Tue, 25 Nov 2008) Log Message: ----------- adding 9readnb target to libspclient examples Makefile. Modified Paths: -------------- spfs/trunk/libspclient/examples/Makefile Modified: spfs/trunk/libspclient/examples/Makefile =================================================================== --- spfs/trunk/libspclient/examples/Makefile 2008-11-25 23:12:16 UTC (rev 20) +++ spfs/trunk/libspclient/examples/Makefile 2008-11-25 23:15:17 UTC (rev 21) @@ -8,6 +8,7 @@ 9write\ 9read\ 9read2\ + 9readnb\ all: $(CMD) @@ -23,6 +24,9 @@ 9read2: 9read2.o ../../libspfs/libspfs.a ../libspclient.a $(CC) -o 9read2 $(CFLAGS) 9read2.o $(LFLAGS) +9readnb: 9readnb.o ../../libspfs/libspfs.a ../libspclient.a + $(CC) -o 9readnb $(CFLAGS) 9readnb.o $(LFLAGS) + clean: rm -f *.o *.a *~ $(CMD) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ab...@us...> - 2008-11-25 23:12:21
|
Revision: 20 http://npfs.svn.sourceforge.net/npfs/?rev=20&view=rev Author: abbyz9 Date: 2008-11-25 23:12:16 +0000 (Tue, 25 Nov 2008) Log Message: ----------- Changes spcfd_add so it accepts an offset (this will be used by xget for retrying a file at a specific point rather than starting over). Fixes all calls to spcfd_add ,so they conform to the new signature. Moves the Spcfd definition to spclient.h Signed-off-by: Hugh Greenberg <hn...@la...> Acked-by: Latchesar Ionkov <lu...@io...> Modified Paths: -------------- spfs/trunk/include/spclient.h spfs/trunk/libspclient/examples/9read2.c spfs/trunk/libspclient/poll.c Modified: spfs/trunk/include/spclient.h =================================================================== --- spfs/trunk/include/spclient.h 2008-11-25 22:59:06 UTC (rev 19) +++ spfs/trunk/include/spclient.h 2008-11-25 23:12:16 UTC (rev 20) @@ -28,6 +28,24 @@ struct Spcfsys; struct Spcfd; +struct Spcfd { + Spfd* spfd; + Spcfid* fid; + int flags; + int iounit; + void (*notify)(Spcfd *, void *); + void* aux; + u64 offset; + u8* rbuf; + int rpos; + u8* wbuf; + int wpos; + Spfcall* rtc; + Spfcall* wtc; + + Spcfd* next; +}; + struct Spcfid { u32 iounit; u8 mode; @@ -58,7 +76,8 @@ void (*cb)(void *, int), void *cba); int spc_writenb(Spcfid *fid, u8 *buf, u32 count, u64 offset, void (*cb)(void *, int), void *cba); -Spcfd *spcfd_add(Spcfid *fid, void (*notify)(Spcfd *, void *), void *aux); +Spcfd *spcfd_add(Spcfid *fid, void (*notify)(Spcfd *, void *), void *aux, + u64 offset); Spcfd *spcfd_add_fd(int fd, void (*notify)(Spcfd *, void *), void *aux); void spcfd_remove(Spcfd *spcfd); int spcfd_can_write(Spcfd *spcfd); Modified: spfs/trunk/libspclient/examples/9read2.c =================================================================== --- spfs/trunk/libspclient/examples/9read2.c 2008-11-25 22:59:06 UTC (rev 19) +++ spfs/trunk/libspclient/examples/9read2.c 2008-11-25 23:12:16 UTC (rev 20) @@ -112,7 +112,7 @@ exit(1); } - ispcfd = spcfd_add(fid, in_notify, fid); + ispcfd = spcfd_add(fid, in_notify, fid, 0); spcfd_start_loop(); spc_close(fid); spc_umount(fs); Modified: spfs/trunk/libspclient/poll.c =================================================================== --- spfs/trunk/libspclient/poll.c 2008-11-25 22:59:06 UTC (rev 19) +++ spfs/trunk/libspclient/poll.c 2008-11-25 23:12:16 UTC (rev 20) @@ -35,24 +35,6 @@ Reof, }; -struct Spcfd { - Spfd* spfd; - Spcfid* fid; - int flags; - int iounit; - void (*notify)(Spcfd *, void *); - void* aux; - u64 offset; - u8* rbuf; - int rpos; - u8* wbuf; - int wpos; - Spfcall* rtc; - Spfcall* wtc; - - Spcfd* next; -}; - static int spcfd_shutdown; static Spcfd *spcfds; @@ -62,7 +44,7 @@ static void spcfd_send_read_request(Spcfd *spcfd); Spcfd * -spcfd_add(Spcfid *fid, void (notify)(Spcfd *, void *), void *aux) +spcfd_add(Spcfid *fid, void (notify)(Spcfd *, void *), void *aux, u64 offset) { int iounit; Spcfd *ret; @@ -81,7 +63,7 @@ ret->iounit = iounit; ret->notify = notify; ret->aux = aux; - ret->offset = 0; + ret->offset = offset; ret->rbuf = ((u8 *) ret) + sizeof(*ret); ret->rpos = 0; ret->wbuf = ret->rbuf + iounit; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ab...@us...> - 2008-11-25 22:59:11
|
Revision: 19 http://npfs.svn.sourceforge.net/npfs/?rev=19&view=rev Author: abbyz9 Date: 2008-11-25 22:59:06 +0000 (Tue, 25 Nov 2008) Log Message: ----------- minor libspclient fix. in cases where spc_netmount failed, the same address was being freed twice. The patch also adds some functions to libspclient that allow getting the local address for a session (used in xmvapich.c). Modified Paths: -------------- spfs/trunk/libspclient/netmount.c Modified: spfs/trunk/libspclient/netmount.c =================================================================== --- spfs/trunk/libspclient/netmount.c 2008-11-25 22:37:01 UTC (rev 18) +++ spfs/trunk/libspclient/netmount.c 2008-11-25 22:59:06 UTC (rev 19) @@ -28,7 +28,6 @@ #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> -#include <arpa/inet.h> #include "spfs.h" #include "spclient.h" #include "spcimpl.h" @@ -90,10 +89,12 @@ spc_netmount(char *address, Spuser *user, int dfltport, int (*auth)(Spcfid *afid, Spuser *user, void *aux), void *aux) { - int n, fd, port; + int fd, port; + socklen_t n; char *addr, *name, *p, *s; struct sockaddr_in saddr; struct hostent *hostinfo; + unsigned char a[4]; char buf[64]; Spcfsys *fs; @@ -135,11 +136,10 @@ /* real computers have errstr */ static char error[128]; /* too bad for f-ing gcc and friends */ - unsigned char octet[4]; - octet[0] = saddr.sin_addr.s_addr >> 24; - octet[1] = saddr.sin_addr.s_addr >>16; - octet[2] = saddr.sin_addr.s_addr >>8; - octet[3] = saddr.sin_addr.s_addr; + a[0] = saddr.sin_addr.s_addr >> 24; + a[1] = saddr.sin_addr.s_addr >>16; + a[2] = saddr.sin_addr.s_addr >>8; + a[3] = saddr.sin_addr.s_addr; /* yeah, they broke this too char *i = inet_ntoa(saddr.sin_addr); */ @@ -148,28 +148,41 @@ //strerror_r(errno, error, sizeof(error)); strcpy(error, strerror(errno)); error[strlen(error)] = ':'; - sprintf(&error[strlen(error)], "%d.%d.%d.%d", octet[3], octet[2], octet[1], octet[0]); + sprintf(&error[strlen(error)], "%d.%d.%d.%d", a[3], a[2], a[1], a[0]); // sp_werror("Host :%s:%s", errno, i, error); sp_werror(error, errno); goto error; } free(addr); + addr = NULL; fs = spc_mount(fd, NULL, user, auth, aux); - if (fs) { - snprintf(buf, sizeof(buf), "%s", inet_ntoa(saddr.sin_addr)); - fs->raddr = strdup(buf); - - n = sizeof(saddr); - if (getsockname(fd, (struct sockaddr *) &saddr, (socklen_t *) &n) >= 0) { - snprintf(buf, sizeof(buf), "%s", inet_ntoa(saddr.sin_addr)); - fs->laddr = strdup(buf); - } + if (!fs) + goto error; - if (spc_chatty) - fprintf(stderr, "connection %p to %s opened\n", fs, fs->raddr); + n = sizeof(saddr); + if (getsockname(fd, (struct sockaddr *) &saddr, &n) >= 0) { + a[0] = saddr.sin_addr.s_addr >> 24; + a[1] = saddr.sin_addr.s_addr >> 16; + a[2] = saddr.sin_addr.s_addr >> 8; + a[3] = saddr.sin_addr.s_addr; + snprintf(buf, sizeof(buf), "%d.%d.%d.%d", a[3], a[2], a[1], a[0]); + fs->laddr = strdup(buf); } + n = sizeof(saddr); + if (getpeername(fd, (struct sockaddr *) &saddr, &n) >= 0) { + a[0] = saddr.sin_addr.s_addr >> 24; + a[1] = saddr.sin_addr.s_addr >> 16; + a[2] = saddr.sin_addr.s_addr >> 8; + a[3] = saddr.sin_addr.s_addr; + snprintf(buf, sizeof(buf), "%d.%d.%d.%d", a[3], a[2], a[1], a[0]); + fs->raddr = strdup(buf); + } + + if (spc_chatty) + fprintf(stderr, "connection %p to %s opened\n", fs, fs->raddr); + return fs; error: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ab...@us...> - 2008-11-25 22:37:11
|
Revision: 18 http://npfs.svn.sourceforge.net/npfs/?rev=18&view=rev Author: abbyz9 Date: 2008-11-25 22:37:01 +0000 (Tue, 25 Nov 2008) Log Message: ----------- in sp_conn_destroy, the connection is reset after closing the open file descriptors. Modified Paths: -------------- spfs/trunk/libspfs/conn.c Modified: spfs/trunk/libspfs/conn.c =================================================================== --- spfs/trunk/libspfs/conn.c 2008-11-25 22:04:34 UTC (rev 17) +++ spfs/trunk/libspfs/conn.c 2008-11-25 22:37:01 UTC (rev 18) @@ -82,8 +82,6 @@ static void sp_conn_destroy(Spconn *conn) { - sp_srv_remove_conn(conn->srv, conn); - sp_conn_reset(conn, 0, 0); close(conn->fdin); if (conn->fdout != conn->fdin) close(conn->fdin); @@ -91,6 +89,9 @@ spfd_remove(conn->spfdin); if (conn->spfdout != conn->spfdin) spfd_remove(conn->spfdout); + + sp_srv_remove_conn(conn->srv, conn); + sp_conn_reset(conn, 0, 0); free(conn->address); free(conn); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ab...@us...> - 2008-11-25 22:04:40
|
Revision: 17 http://npfs.svn.sourceforge.net/npfs/?rev=17&view=rev Author: abbyz9 Date: 2008-11-25 22:04:34 +0000 (Tue, 25 Nov 2008) Log Message: ----------- conforming to the XSI-compliant version of strerror_r in sp_suerror. the error string is returned in the supplied string buffer err. Modified Paths: -------------- spfs/trunk/libspfs/error.c spfs/trunk/libspfs/pvusers.c Modified: spfs/trunk/libspfs/error.c =================================================================== --- spfs/trunk/libspfs/error.c 2008-11-25 21:54:28 UTC (rev 16) +++ spfs/trunk/libspfs/error.c 2008-11-25 22:04:34 UTC (rev 17) @@ -20,7 +20,6 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ -#define _GNU_SOURCE #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -92,10 +91,10 @@ void sp_suerror(char *s, int ecode) { - char err[256], *str; + char err[256]; char buf[512]; - str = strerror_r(ecode, err, sizeof(err)); - snprintf(buf, sizeof(buf), "%s: %s", s, str); + strerror_r(ecode, err, sizeof(err)); + snprintf(buf, sizeof(buf), "%s: %s", s, err); sp_werror(buf, ecode); } Modified: spfs/trunk/libspfs/pvusers.c =================================================================== --- spfs/trunk/libspfs/pvusers.c 2008-11-25 21:54:28 UTC (rev 16) +++ spfs/trunk/libspfs/pvusers.c 2008-11-25 22:04:34 UTC (rev 17) @@ -197,6 +197,7 @@ void sp_priv_group_del(Spgroup *g) { + int i; Spgroup *tg, *pg; Spuser *tu; Upool *upp; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ab...@us...> - 2008-11-25 22:02:29
|
Revision: 15 http://npfs.svn.sourceforge.net/npfs/?rev=15&view=rev Author: abbyz9 Date: 2008-11-25 21:47:54 +0000 (Tue, 25 Nov 2008) Log Message: ----------- added a check in sp_priv_group_del to see if the group is empty or not. if the group has users associated with it, sp_priv_group_del returns Egroupbusy. Signed-off-by: Abhishek Kulkarni <kul...@la...> Modified Paths: -------------- spfs/trunk/libspfs/pvusers.c Modified: spfs/trunk/libspfs/pvusers.c =================================================================== --- spfs/trunk/libspfs/pvusers.c 2008-11-24 16:11:42 UTC (rev 14) +++ spfs/trunk/libspfs/pvusers.c 2008-11-25 21:47:54 UTC (rev 15) @@ -40,6 +40,7 @@ static char *Euserexists = "user exists"; static char *Egroupexists = "group exists"; +static char *Egroupbusy = "group not empty"; static Spuser *sp_priv_uname2user(Spuserpool *up, char *uname); static Spuser *sp_priv_uid2user(Spuserpool *up, u32 uid); @@ -184,6 +185,7 @@ sp_priv_group_del(Spgroup *g) { Spgroup *tg, *pg; + Spuser *tu; Upool *upp; upp = g->upool->aux; @@ -195,6 +197,18 @@ if (tg == g) break; + for(tu = upp->users; tu != NULL; tu = tu->next) { + if(!strcmp("xcpu-admin", tu->uname)) + continue; + + for(i = 0; i < tu->ngroups; i++) { + if (tu->groups[i] == g) { + sp_werror("%s:%s", EIO, g->gname, Egroupbusy); + return; + } + } + } + if (!pg) upp->groups = g->next; else This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ab...@us...> - 2008-11-25 22:02:03
|
Revision: 16 http://npfs.svn.sourceforge.net/npfs/?rev=16&view=rev Author: abbyz9 Date: 2008-11-25 21:54:28 +0000 (Tue, 25 Nov 2008) Log Message: ----------- added functions sp_priv_user_list and sp_priv_group_list to retrieve the users and groups from their pools respectively. Modified Paths: -------------- spfs/trunk/include/spfs.h spfs/trunk/libspfs/pvusers.c Modified: spfs/trunk/include/spfs.h =================================================================== --- spfs/trunk/include/spfs.h 2008-11-25 21:47:54 UTC (rev 15) +++ spfs/trunk/include/spfs.h 2008-11-25 21:54:28 UTC (rev 16) @@ -529,9 +529,11 @@ Spuserpool *sp_priv_userpool_create(); Spuser *sp_priv_user_add(Spuserpool *up, char *uname, u32 uid, void *aux); void sp_priv_user_del(Spuser *u); +Spuser *sp_priv_user_list(Spuserpool *up); int sp_priv_user_setdfltgroup(Spuser *u, Spgroup *g); Spgroup *sp_priv_group_add(Spuserpool *up, char *gname, u32 gid); void sp_priv_group_del(Spgroup *g); +Spgroup *sp_priv_group_list(Spuserpool *up); int sp_priv_group_adduser(Spgroup *g, Spuser *u); int sp_priv_group_deluser(Spgroup *g, Spuser *u); Modified: spfs/trunk/libspfs/pvusers.c =================================================================== --- spfs/trunk/libspfs/pvusers.c 2008-11-25 21:47:54 UTC (rev 15) +++ spfs/trunk/libspfs/pvusers.c 2008-11-25 21:54:28 UTC (rev 16) @@ -134,6 +134,19 @@ sp_user_decref(u); } +Spuser * +sp_priv_user_list(Spuserpool *up) +{ + Upool *upp; + + upp = up->aux; + + if (!upp->users) + return NULL; + + return upp->users; +} + int sp_priv_user_setdfltgroup(Spuser *u, Spgroup *g) { @@ -217,6 +230,19 @@ sp_group_decref(g); } +Spgroup * +sp_priv_group_list(Spuserpool *up) +{ + Upool *upp; + + upp = up->aux; + + if (!upp->groups) + return NULL; + + return upp->groups; +} + int sp_priv_group_adduser(Spgroup *g, Spuser *u) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ab...@us...> - 2008-11-24 16:11:51
|
Revision: 14 http://npfs.svn.sourceforge.net/npfs/?rev=14&view=rev Author: abbyz9 Date: 2008-11-24 16:11:42 +0000 (Mon, 24 Nov 2008) Log Message: ----------- conditional compilation of npfs rdma support. we check if the required headers and libraries for ibverbs and rdmacm exist or not to avoid compilation errors on systems not having these rdma dependencies installed. Signed-off-by: Abhishek Kulkarni <kul...@la...> Modified Paths: -------------- npfs/trunk/Makefile npfs/trunk/fs/Makefile npfs/trunk/libnpfs/Makefile Modified: npfs/trunk/Makefile =================================================================== --- npfs/trunk/Makefile 2008-09-28 04:35:34 UTC (rev 13) +++ npfs/trunk/Makefile 2008-11-24 16:11:42 UTC (rev 14) @@ -9,3 +9,7 @@ make -C fs clean rm -f *~ include/*~ +install: + cp include/npfs.h /usr/local/include + cp libnpfs/libnpfs.a /usr/local/lib + Modified: npfs/trunk/fs/Makefile =================================================================== --- npfs/trunk/fs/Makefile 2008-09-28 04:35:34 UTC (rev 13) +++ npfs/trunk/fs/Makefile 2008-11-24 16:11:42 UTC (rev 14) @@ -6,6 +6,7 @@ GPHOTO_LPATH=/usr/lib ETPAN_HPATH=/usr/include/libetpan ETPAN_LPATH=/usr/lib +LIBDIRS:=/usr/lib/ /usr/local/lib/ /opt/lib/ #ifeq ($(SYSNAME),Linux) #NPFS_LFLAGS=-laio @@ -13,12 +14,22 @@ FS=\ npfs\ - rdmanpfs\ ramfs\ nullfs\ ramfs2\ echofs\ +ifeq ($(SYSNAME),Linux) + RDMADEPS:=\ + $(and $(foreach dir,$(LIBDIRS),$(wildcard $(dir)/libibverbs.*)), \ + $(foreach dir,$(LIBDIRS), $(wildcard $(dir)/librdmacm.*))) + ifneq ($(strip $(RDMADEPS)),) + FS += rdmanpfs + endif +endif + +.PHONY: all clean + all: $(FS) npfs: ufs.o npfs.o Modified: npfs/trunk/libnpfs/Makefile =================================================================== --- npfs/trunk/libnpfs/Makefile 2008-09-28 04:35:34 UTC (rev 13) +++ npfs/trunk/libnpfs/Makefile 2008-11-24 16:11:42 UTC (rev 14) @@ -2,11 +2,16 @@ SYSNAME!=uname HFILES=../include/npfs.h npfsimpl.h CFLAGS=-Wall -g -I../include -D$(SYSNAME) +INCLUDEDIRS:=/usr/include/ /usr/local/include/ /opt/include/ ifeq ($(SYSNAME), SunOS) CFLAGS += -D_POSIX_PTHREAD_SEMANTICS endif +.PHONY: all clean + +.all: libnpfs.a + LIBFILES=\ conn.o\ error.o\ @@ -24,7 +29,13 @@ uxusers.o\ ifeq ($(SYSNAME), Linux) - LIBFILES += pipesrv.o rdmasrv.o rdmatrans.o + LIBFILES += pipesrv.o + RDMADEPS:=\ + $(and $(foreach dir,$(INCLUDEDIRS),$(wildcard $(dir)/rdma/rdma_cma.h)), \ + $(foreach dir,$(INCLUDEDIRS), $(wildcard $(dir)/infiniband/verbs.h))) + ifneq ($(strip $(RDMADEPS)),) + LIBFILES += rdmasrv.o rdmatrans.o + endif endif libnpfs.a: $(LIBFILES) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <li...@us...> - 2008-09-28 04:35:40
|
Revision: 13 http://npfs.svn.sourceforge.net/npfs/?rev=13&view=rev Author: lionkov Date: 2008-09-28 04:35:34 +0000 (Sun, 28 Sep 2008) Log Message: ----------- fix few races and memory leaks in the uxusers.c, fixes in the RDMA transport by Tom Tucker. Modified Paths: -------------- npfs/trunk/libnpfs/rdmasrv.c npfs/trunk/libnpfs/rdmatrans.c npfs/trunk/libnpfs/uxusers.c Modified: npfs/trunk/libnpfs/rdmasrv.c =================================================================== --- npfs/trunk/libnpfs/rdmasrv.c 2008-09-22 22:30:07 UTC (rev 12) +++ npfs/trunk/libnpfs/rdmasrv.c 2008-09-28 04:35:34 UTC (rev 13) @@ -157,13 +157,13 @@ case RDMA_CM_EVENT_DISCONNECTED: printf("Connection shutting down\n"); - cmid = (struct rdma_cm_id *) event->id; conn = cmid->context; + np_conn_shutdown(conn); break; default: fprintf(stderr, "event %d received waiting for a connect request\n", - event->event); + etype); } } return NULL; Modified: npfs/trunk/libnpfs/rdmatrans.c =================================================================== --- npfs/trunk/libnpfs/rdmatrans.c 2008-09-22 22:30:07 UTC (rev 12) +++ npfs/trunk/libnpfs/rdmatrans.c 2008-09-28 04:35:34 UTC (rev 13) @@ -143,7 +143,7 @@ if (ret) goto error; rdma->qp = rdma->cm_id->qp; - + p = rdma->rcv_buf; for (i = 0; i < q_depth; i++) rdma_post_recv(rdma, (Rdmactx *)(p + i*rdma->msize)); @@ -179,12 +179,16 @@ rdma_trans_destroy(void *a) { Rdmatrans *rdma; + struct ibv_qp_attr attr; rdma = a; if (rdma->connected) rdma_disconnect(rdma->cm_id); - if (rdma->qp) + if (rdma->qp) { + attr.qp_state = IBV_QPS_ERR; + ibv_modify_qp(rdma->qp, &attr, IBV_QP_STATE); ibv_destroy_qp(rdma->qp); + } if (rdma->cq) ibv_destroy_cq(rdma->cq); if (rdma->ch) Modified: npfs/trunk/libnpfs/uxusers.c =================================================================== --- npfs/trunk/libnpfs/uxusers.c 2008-09-22 22:30:07 UTC (rev 12) +++ npfs/trunk/libnpfs/uxusers.c 2008-09-28 04:35:34 UTC (rev 13) @@ -54,18 +54,18 @@ Npuserpool *np_unix_users = &upool; static struct Npusercache { + pthread_mutex_t lock; int init; int hsize; Npuser** htable; - pthread_mutex_t lock; -} usercache = { 0 }; +} usercache = { PTHREAD_MUTEX_INITIALIZER, 0 }; static struct Npgroupcache { + pthread_mutex_t lock; int init; int hsize; Npgroup** htable; - pthread_mutex_t lock; -} groupcache = { 0 }; +} groupcache = { PTHREAD_MUTEX_INITIALIZER, 0 }; pthread_mutex_t grentlock = PTHREAD_MUTEX_INITIALIZER; @@ -97,7 +97,7 @@ static Npuser * np_unix_uname2user(Npuserpool *up, char *uname) { - int i, n, found; + int i, n; struct passwd pw, *pwp; int bufsize; char *buf; @@ -107,37 +107,17 @@ if (!usercache.init) initusercache(); - found = 0; for(i = 0; i<usercache.hsize; i++) for(u = usercache.htable[i]; u != NULL; u = u->next) if (strcmp(uname, u->uname) == 0) { - found = 1; - break; + pthread_mutex_unlock(&usercache.lock); + goto done; } - if (found) { - pthread_mutex_unlock(&usercache.lock); - pthread_mutex_lock(&u->lock); - found = u->uname != NULL; - pthread_mutex_unlock(&u->lock); - - if (!found) - return NULL; - - goto done; - } - u = np_malloc(sizeof(*u) + 256); pthread_mutex_init(&u->lock, NULL); - u->uname = NULL; - n = u->uid % usercache.hsize; - u->next = usercache.htable[n]; - usercache.htable[n] = u; - pthread_mutex_lock(&u->lock); - pthread_mutex_unlock(&usercache.lock); - bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); if (bufsize < 256) bufsize = 256; @@ -147,7 +127,8 @@ if (i) { np_uerror(i); free(buf); - pthread_mutex_unlock(&u->lock); + free(u); + pthread_mutex_unlock(&usercache.lock); return NULL; } @@ -156,12 +137,17 @@ u->uid = pw.pw_uid; u->uname = (char *)u + sizeof(*u); strncpy(u->uname, pw.pw_name, 256); - u->dfltgroup = (*up->gid2group)(up, pw.pw_gid); - + u->dfltgroup = NULL; u->ngroups = 0; u->groups = NULL; - np_init_user_groups(u); + n = u->uid % usercache.hsize; + u->next = usercache.htable[n]; + usercache.htable[n] = u; + pthread_mutex_lock(&u->lock); + pthread_mutex_unlock(&usercache.lock); free(buf); + u->dfltgroup = (*up->gid2group)(up, pw.pw_gid); + np_init_user_groups(u); pthread_mutex_unlock(&u->lock); done: @@ -186,32 +172,14 @@ n = uid % usercache.hsize; for(u = usercache.htable[n]; u != NULL; u = u->next) if (u->uid == uid) { - found = 1; - break; + pthread_mutex_unlock(&usercache.lock); + goto done; } - if (found) { - pthread_mutex_unlock(&usercache.lock); - pthread_mutex_lock(&u->lock); - found = u->uname != NULL; - pthread_mutex_unlock(&u->lock); - - if (!found) - return NULL; - - goto done; - } - u = np_malloc(sizeof(*u) + 256); pthread_mutex_init(&u->lock, NULL); - u->uname = NULL; - u->next = usercache.htable[n]; - usercache.htable[n] = u; - pthread_mutex_lock(&u->lock); - pthread_mutex_unlock(&usercache.lock); - bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); if (bufsize < 256) bufsize = 256; @@ -221,7 +189,8 @@ if (i) { np_uerror(i); free(buf); - pthread_mutex_unlock(&u->lock); + free(u); + pthread_mutex_unlock(&usercache.lock); return NULL; } @@ -230,10 +199,14 @@ u->uid = uid; u->uname = (char *)u + sizeof(*u); strncpy(u->uname, pw.pw_name, 256); - u->dfltgroup = up->gid2group(up, pw.pw_gid); - + u->next = usercache.htable[n]; + usercache.htable[n] = u; + u->dfltgroup = NULL; u->ngroups = 0; u->groups = NULL; + pthread_mutex_lock(&u->lock); + pthread_mutex_unlock(&usercache.lock); + u->dfltgroup = up->gid2group(up, pw.pw_gid); np_init_user_groups(u); free(buf); pthread_mutex_unlock(&u->lock); @@ -246,7 +219,7 @@ static Npgroup * np_unix_gname2group(Npuserpool *up, char *gname) { - int i, bufsize, found; + int i, n, bufsize; Npgroup *g; struct group grp, *pgrp; char *buf; @@ -255,32 +228,15 @@ if (!groupcache.init) initgroupcache(); - found = 0; for(i = 0; i < groupcache.hsize; i++) for(g = groupcache.htable[i]; g != NULL; g = g->next) if (strcmp(g->gname, gname) == 0) { - found = 1; - break; + pthread_mutex_unlock(&groupcache.lock); + goto done; } - if (found) { - pthread_mutex_unlock(&groupcache.lock); - pthread_mutex_lock(&g->lock); - found = g->gname != NULL; - pthread_mutex_unlock(&g->lock); - - if (!found) - return NULL; - - goto done; - } - g = np_malloc(sizeof(*g) + 256); pthread_mutex_init(&g->lock, NULL); - g->gname = NULL; - pthread_mutex_lock(&g->lock); - pthread_mutex_unlock(&groupcache.lock); - bufsize = sysconf(_SC_GETGR_R_SIZE_MAX); if (bufsize < 256) bufsize = 256; @@ -290,7 +246,8 @@ if (i) { np_uerror(i); free(buf); - pthread_mutex_unlock(&g->lock); + free(g); + pthread_mutex_unlock(&groupcache.lock); return NULL; } @@ -299,8 +256,10 @@ g->gid = grp.gr_gid; g->gname = (char *)g + sizeof(*g); strncpy(g->gname, grp.gr_name, 256); - - pthread_mutex_unlock(&g->lock); + n = g->gid % groupcache.hsize; + g->next = groupcache.htable[n]; + groupcache.htable[n] = g; + pthread_mutex_unlock(&groupcache.lock); free(buf); done: @@ -311,7 +270,7 @@ static Npgroup * np_unix_gid2group(Npuserpool *up, u32 gid) { - int n, err, found; + int n, err; Npgroup *g; struct group grp, *pgrp; int bufsize; @@ -322,30 +281,15 @@ initgroupcache(); n = gid % groupcache.hsize; - found = 0; for(g = groupcache.htable[n]; g != NULL; g = g->next) if (g->gid == gid) { - found = 1; - break; + pthread_mutex_unlock(&groupcache.lock); + goto done; } - if (found) { - pthread_mutex_unlock(&groupcache.lock); - pthread_mutex_lock(&g->lock); - found = g->gname != NULL; - pthread_mutex_unlock(&g->lock); - if (!found) - return NULL; - - goto done; - } - g = np_malloc(sizeof(*g) + 256); pthread_mutex_init(&g->lock, NULL); g->gname = NULL; - pthread_mutex_lock(&g->lock); - pthread_mutex_unlock(&groupcache.lock); - bufsize = sysconf(_SC_GETGR_R_SIZE_MAX); if (bufsize < 256) bufsize = 256; @@ -355,7 +299,8 @@ if (err) { np_uerror(err); free(buf); - pthread_mutex_unlock(&g->lock); + free(g); + pthread_mutex_unlock(&groupcache.lock); return NULL; } @@ -364,8 +309,9 @@ g->gid = grp.gr_gid; g->gname = (char *)g + sizeof(*g); strncpy(g->gname, grp.gr_name, 256); - - pthread_mutex_unlock(&g->lock); + g->next = groupcache.htable[n]; + groupcache.htable[n] = g; + pthread_mutex_unlock(&groupcache.lock); free(buf); done: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <li...@us...> - 2008-09-22 22:30:16
|
Revision: 12 http://npfs.svn.sourceforge.net/npfs/?rev=12&view=rev Author: lionkov Date: 2008-09-22 22:30:07 +0000 (Mon, 22 Sep 2008) Log Message: ----------- - When shutting down a user mode RDMA connection, the RDMA libraries keep counts of delivered, but unacknowledged events. These are events generated by the device, but not yet processed by the app. Since these events have memory associated with them and an implicit reference on the underlying device, they need to be 'acked' by the app so that the infrastructure a) knows the underlying memory can be freed, and b) there is no longer a reference on the device for this event. If you only kill the app between runs, this isn't really an issue since the clean-up code will take care of this for you, but since npfs is a long lived server that won't really work. The fix is simply to acknowledge events before processing them so that events that would shut down don't hold a reference and deadlock the server. - The rdma_trans_read function needs to recognize when the connection is closing and exit with an error so that the caller can clean up the thread associated with the client. Otherwise, the thread hangs around forever after unmount. - The new architecture creates a thread for each client and therefore doesn't need poll since a) these threads can block and b) you only ever care about one file descriptor. ibv_get_cq_event blocks when no events are available, so it is effectively equivalent to poll. Signed-off-by: Tom Tucker <to...@op...> Acked-by: Latchesar Ionkov <lu...@io...> Modified Paths: -------------- npfs/trunk/libnpfs/rdmasrv.c npfs/trunk/libnpfs/rdmatrans.c Modified: npfs/trunk/libnpfs/rdmasrv.c =================================================================== --- npfs/trunk/libnpfs/rdmasrv.c 2008-09-18 22:33:44 UTC (rev 11) +++ npfs/trunk/libnpfs/rdmasrv.c 2008-09-22 22:30:07 UTC (rev 12) @@ -127,6 +127,7 @@ Rdmasrv *rdma; struct rdma_cm_event *event; struct rdma_cm_id *cmid; + enum rdma_cm_event_type etype; srv = a; rdma = srv->srvaux; @@ -135,10 +136,13 @@ if (ret) goto error; - switch (event->event) { + cmid = (struct rdma_cm_id *)event->id; + etype = event->event; + rdma_ack_cm_event(event); + + switch (etype) { case RDMA_CM_EVENT_CONNECT_REQUEST: printf("Connection request\n"); - cmid = (struct rdma_cm_id *) event->id; trans = np_rdmatrans_create(cmid, srv->nwthread, srv->msize); if (trans) { conn = np_conn_create(srv, trans); @@ -154,15 +158,13 @@ case RDMA_CM_EVENT_DISCONNECTED: printf("Connection shutting down\n"); cmid = (struct rdma_cm_id *) event->id; - np_conn_shutdown(conn); + conn = cmid->context; break; default: fprintf(stderr, "event %d received waiting for a connect request\n", event->event); } - - rdma_ack_cm_event(event); } return NULL; Modified: npfs/trunk/libnpfs/rdmatrans.c =================================================================== --- npfs/trunk/libnpfs/rdmatrans.c 2008-09-18 22:33:44 UTC (rev 11) +++ npfs/trunk/libnpfs/rdmatrans.c 2008-09-22 22:30:07 UTC (rev 12) @@ -113,7 +113,7 @@ goto error; rdma->next_buf = 0; - rdma->snd_mr = ibv_reg_mr(rdma->pd, rdma->snd_buf, msize * q_depth * 2, 0); + rdma->snd_mr = ibv_reg_mr(rdma->pd, rdma->snd_buf, rdma->msize * q_depth * 2, 0); if (!rdma->snd_mr) goto error; @@ -206,14 +206,14 @@ static int rdma_trans_read(u8 *data, u32 count, void *a) { - int n, ret; + int n, ret, closing; struct ibv_cq *cq; struct ibv_wc wc; void *context; - struct pollfd pfd; Rdmatrans *rdma; Rdmactx *ctx; + closing = 0; rdma = a; pthread_mutex_lock(&rdma->lock); again: @@ -239,22 +239,15 @@ } pthread_mutex_unlock(&rdma->lock); - pfd.fd = rdma->ch->fd; - pfd.events = POLLIN | POLLERR | POLLNVAL | POLLHUP; poll: - while ((n = poll(&pfd, 1, 1000)) <= 0) - ; - - if (pfd.revents & (POLLERR | POLLNVAL | POLLHUP)) - return -1; - ret = ibv_get_cq_event(rdma->ch, &cq, &context); if (ret) { np_uerror(ret); fprintf(stderr, "Error %d polling cq\n", ret); return -1; } + ibv_ack_cq_events(rdma->cq, 1); ibv_req_notify_cq(cq, 0); while ((ret = ibv_poll_cq(rdma->cq, 1, &wc)) > 0) { @@ -262,6 +255,7 @@ if (wc.status != IBV_WC_SUCCESS) { fprintf(stderr, "cq fail: status %d opcode %d\n", wc.status, wc.opcode); + closing = 1; continue; } @@ -288,7 +282,7 @@ } } - if (!ret) + if (!ret && !closing) goto poll; np_uerror(ret); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <li...@us...> - 2008-09-18 15:33:34
|
Revision: 11 http://npfs.svn.sourceforge.net/npfs/?rev=11&view=rev Author: lionkov Date: 2008-09-18 22:33:44 +0000 (Thu, 18 Sep 2008) Log Message: ----------- remove a debug statement Modified Paths: -------------- npfs/trunk/libnpfs/error.c Modified: npfs/trunk/libnpfs/error.c =================================================================== --- npfs/trunk/libnpfs/error.c 2008-09-18 15:31:00 UTC (rev 10) +++ npfs/trunk/libnpfs/error.c 2008-09-18 22:33:44 UTC (rev 11) @@ -92,9 +92,6 @@ va_list ap; Nperror *err; - if (ecode == 5) - printf("EIO...\n"); - pthread_once(&error_once, np_init_error_key); err = pthread_getspecific(error_key); if (!err) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <li...@us...> - 2008-09-18 15:30:50
|
Revision: 10 http://npfs.svn.sourceforge.net/npfs/?rev=10&view=rev Author: lionkov Date: 2008-09-18 15:31:00 +0000 (Thu, 18 Sep 2008) Log Message: ----------- add missing file Added Paths: ----------- npfs/trunk/fs/ufs.h Added: npfs/trunk/fs/ufs.h =================================================================== --- npfs/trunk/fs/ufs.h (rev 0) +++ npfs/trunk/fs/ufs.h 2008-09-18 15:31:00 UTC (rev 10) @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2008 by Latchesar Ionkov <lu...@io...> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * LATCHESAR IONKOV AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +extern Npsrv *srv; +extern int debuglevel; +extern int sameuser; +extern int use_aio; +extern pthread_t aio_thread; + +Npfcall* npfs_attach(Npfid *fid, Npfid *afid, Npstr *uname, Npstr *aname); +int npfs_clone(Npfid *fid, Npfid *newfid); +int npfs_walk(Npfid *fid, Npstr *wname, Npqid *wqid); +Npfcall* npfs_open(Npfid *fid, u8 mode); +Npfcall* npfs_create(Npfid *fid, Npstr *name, u32 perm, u8 mode, + Npstr *extension); +Npfcall* npfs_read(Npfid *fid, u64 offset, u32 count, Npreq *); +Npfcall* npfs_write(Npfid *fid, u64 offset, u32 count, u8 *data, Npreq *); +Npfcall* npfs_clunk(Npfid *fid); +Npfcall* npfs_remove(Npfid *fid); +Npfcall* npfs_stat(Npfid *fid); +Npfcall* npfs_wstat(Npfid *fid, Npstat *stat); +void npfs_flush(Npreq *req); +void npfs_fiddestroy(Npfid *fid); +int npfs_aio_init(int n); +void *npfs_aio_proc(void *a); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <li...@us...> - 2008-09-18 01:31:16
|
Revision: 9 http://npfs.svn.sourceforge.net/npfs/?rev=9&view=rev Author: lionkov Date: 2008-09-18 01:31:26 +0000 (Thu, 18 Sep 2008) Log Message: ----------- Infiniband RDMA support. Author: Tom Tucker <to...@op...> Modified Paths: -------------- npfs/trunk/fs/Makefile npfs/trunk/fs/ufs.c npfs/trunk/include/npfs.h npfs/trunk/libnpfs/Makefile npfs/trunk/libnpfs/conn.c npfs/trunk/libnpfs/srv.c npfs/trunk/libnpfs/user.c Added Paths: ----------- npfs/trunk/fs/npfs.c npfs/trunk/fs/rdmanpfs.c npfs/trunk/libnpfs/rdmasrv.c npfs/trunk/libnpfs/rdmatrans.c Modified: npfs/trunk/fs/Makefile =================================================================== --- npfs/trunk/fs/Makefile 2008-09-18 01:03:08 UTC (rev 8) +++ npfs/trunk/fs/Makefile 2008-09-18 01:31:26 UTC (rev 9) @@ -13,18 +13,20 @@ FS=\ npfs\ + rdmanpfs\ ramfs\ nullfs\ ramfs2\ - gphotofs\ - mboxfs\ echofs\ -all: npfs ramfs nullfs ramfs2 echofs +all: $(FS) -npfs: ufs.o - $(CC) -o npfs $(CFLAGS) ufs.o $(LFLAGS) $(NPFS_LFLAGS) +npfs: ufs.o npfs.o + $(CC) -o npfs $(CFLAGS) ufs.o npfs.o $(LFLAGS) $(NPFS_LFLAGS) +rdmanpfs: ufs.o rdmanpfs.o + $(CC) -o rdmanpfs $(CFLAGS) ufs.o rdmanpfs.o $(LFLAGS) $(NPFS_LFLAGS) -libverbs -lrdmacm + ramfs: ramfs.o $(CC) -o ramfs $(CFLAGS) ramfs.o $(LFLAGS) Added: npfs/trunk/fs/npfs.c =================================================================== --- npfs/trunk/fs/npfs.c (rev 0) +++ npfs/trunk/fs/npfs.c 2008-09-18 01:31:26 UTC (rev 9) @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2005-2008 by Latchesar Ionkov <lu...@io...> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * LATCHESAR IONKOV AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +//#define _XOPEN_SOURCE 500 +#define _BSD_SOURCE +#include <stdlib.h> +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <pthread.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> +#include <dirent.h> +#include <fcntl.h> +#include <utime.h> +#include "npfs.h" +#include "ufs.h" + +void +usage() +{ + fprintf(stderr, "npfs: -d -s -p port -w nthreads\n"); + exit(-1); +} + +int +main(int argc, char **argv) +{ + int c; + int port, nwthreads; + char *s; + + port = 564; + nwthreads = 16; + while ((c = getopt(argc, argv, "dsp:w:")) != -1) { + switch (c) { + case 'd': + debuglevel = 1; + break; + + case 'p': + port = strtol(optarg, &s, 10); + if (*s != '\0') + usage(); + break; + + case 'w': + nwthreads = strtol(optarg, &s, 10); + if (*s != '\0') + usage(); + break; + + case 's': + sameuser = 1; + break; + + default: + usage(); + } + } + + if (use_aio && npfs_aio_init(nwthreads * 2)) + use_aio = 0; + + if (use_aio && pthread_create(&aio_thread, NULL, npfs_aio_proc, NULL)) + use_aio = 0; + + srv = np_socksrv_create_tcp(nwthreads, &port); + + if (!srv) + return -1; + + srv->dotu = 1; + srv->attach = npfs_attach; + srv->clone = npfs_clone; + srv->walk = npfs_walk; + srv->open = npfs_open; + srv->create = npfs_create; + srv->read = npfs_read; + srv->write = npfs_write; + srv->clunk = npfs_clunk; + srv->remove = npfs_remove; + srv->stat = npfs_stat; + srv->wstat = npfs_wstat; + srv->flush = npfs_flush; + srv->fiddestroy = npfs_fiddestroy; + srv->debuglevel = debuglevel; + + np_srv_start(srv); + while (1) { + sleep(100); + } + + return 0; +} + Added: npfs/trunk/fs/rdmanpfs.c =================================================================== --- npfs/trunk/fs/rdmanpfs.c (rev 0) +++ npfs/trunk/fs/rdmanpfs.c 2008-09-18 01:31:26 UTC (rev 9) @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2005-2008 by Latchesar Ionkov <lu...@io...> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * LATCHESAR IONKOV AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +//#define _XOPEN_SOURCE 500 +#define _BSD_SOURCE +#include <stdlib.h> +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <pthread.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> +#include <dirent.h> +#include <fcntl.h> +#include <utime.h> +#include "npfs.h" +#include "ufs.h" + +void +usage() +{ + fprintf(stderr, "npfs: -d -s -p port -w nthreads\n"); + exit(-1); +} + +int +main(int argc, char **argv) +{ + int c; + int port, nwthreads; + char *s; + + port = 564; + nwthreads = 16; + while ((c = getopt(argc, argv, "dsp:w:")) != -1) { + switch (c) { + case 'd': + debuglevel = 1; + break; + + case 'p': + port = strtol(optarg, &s, 10); + if (*s != '\0') + usage(); + break; + + case 'w': + nwthreads = strtol(optarg, &s, 10); + if (*s != '\0') + usage(); + break; + + case 's': + sameuser = 1; + break; + + default: + usage(); + } + } + + srv = np_rdmasrv_create(nwthreads, &port); + + if (!srv) + return -1; + + srv->dotu = 1; + srv->attach = npfs_attach; + srv->clone = npfs_clone; + srv->walk = npfs_walk; + srv->open = npfs_open; + srv->create = npfs_create; + srv->read = npfs_read; + srv->write = npfs_write; + srv->clunk = npfs_clunk; + srv->remove = npfs_remove; + srv->stat = npfs_stat; + srv->wstat = npfs_wstat; + srv->flush = npfs_flush; + srv->fiddestroy = npfs_fiddestroy; + srv->debuglevel = debuglevel; + + np_srv_start(srv); + while (1) { + sleep(100); + } + + return 0; +} + Modified: npfs/trunk/fs/ufs.c =================================================================== --- npfs/trunk/fs/ufs.c 2008-09-18 01:03:08 UTC (rev 8) +++ npfs/trunk/fs/ufs.c 2008-09-18 01:31:26 UTC (rev 9) @@ -35,6 +35,7 @@ #include <fcntl.h> #include <utime.h> #include "npfs.h" +#include "ufs.h" #if SYSNAME == Linux #define NPFS_USE_AIO @@ -62,12 +63,6 @@ int debuglevel; int sameuser; -pthread_mutex_t culock = PTHREAD_MUTEX_INITIALIZER; -pthread_cond_t cucond = PTHREAD_COND_INITIALIZER; -Npuser *cuser; -int curef; -int maxref; - char *Estatfailed = "stat failed"; char *Ebadfid = "fid unknown or out of range"; char *Enoextension = "empty extension while creating special file"; @@ -82,26 +77,8 @@ static mode_t npstat2umode(Npstat *st, int dotu); static void ustat2npwstat(char *path, struct stat *st, Npwstat *wstat, int dotu, Npuserpool *up); -static Npfcall* npfs_attach(Npfid *fid, Npfid *afid, Npstr *uname, Npstr *aname); -static int npfs_clone(Npfid *fid, Npfid *newfid); -static int npfs_walk(Npfid *fid, Npstr *wname, Npqid *wqid); -static Npfcall* npfs_open(Npfid *fid, u8 mode); -static Npfcall* npfs_create(Npfid *fid, Npstr *name, u32 perm, u8 mode, - Npstr *extension); -static Npfcall* npfs_read(Npfid *fid, u64 offset, u32 count, Npreq *); -static Npfcall* npfs_write(Npfid *fid, u64 offset, u32 count, u8 *data, Npreq *); -static Npfcall* npfs_clunk(Npfid *fid); -static Npfcall* npfs_remove(Npfid *fid); -static Npfcall* npfs_stat(Npfid *fid); -static Npfcall* npfs_wstat(Npfid *fid, Npstat *stat); -static void npfs_flush(Npreq *req); - -static void npfs_fiddestroy(Npfid *fid); - -static int npfs_aio_init(int); static int npfs_aio_read(Npfid *fid, Npfcall *rread, u64 offset, u32 count, Npreq *); static int npfs_aio_write(Npfid *fid, u8 *data, u64 offset, u32 count, Npreq *); -static void* npfs_aio_proc(void *a); #ifdef NPFS_USE_AIO #include <libaio.h> @@ -126,84 +103,6 @@ pthread_t aio_thread; -void -usage() -{ - fprintf(stderr, "npfs: -d -s -p port -w nthreads\n"); - exit(-1); -} - -int -main(int argc, char **argv) -{ - int c; - int port, nwthreads; - char *s; - - port = 564; - nwthreads = 16; - while ((c = getopt(argc, argv, "dsp:w:")) != -1) { - switch (c) { - case 'd': - debuglevel = 1; - break; - - case 'p': - port = strtol(optarg, &s, 10); - if (*s != '\0') - usage(); - break; - - case 'w': - nwthreads = strtol(optarg, &s, 10); - if (*s != '\0') - usage(); - break; - - case 's': - sameuser = 1; - break; - - default: - usage(); - } - } - - if (use_aio && npfs_aio_init(nwthreads * 2)) - use_aio = 0; - - if (use_aio && pthread_create(&aio_thread, NULL, npfs_aio_proc, NULL)) - use_aio = 0; - - srv = np_socksrv_create_tcp(nwthreads, &port); - - if (!srv) - return -1; - - srv->dotu = 1; - srv->attach = npfs_attach; - srv->clone = npfs_clone; - srv->walk = npfs_walk; - srv->open = npfs_open; - srv->create = npfs_create; - srv->read = npfs_read; - srv->write = npfs_write; - srv->clunk = npfs_clunk; - srv->remove = npfs_remove; - srv->stat = npfs_stat; - srv->wstat = npfs_wstat; - srv->flush = npfs_flush; - srv->fiddestroy = npfs_fiddestroy; - srv->debuglevel = debuglevel; - - np_srv_start(srv); - while (1) { - sleep(100); - } - - return 0; -} - static int fidstat(Fid *fid) { @@ -232,7 +131,7 @@ return f; } -static void +void npfs_fiddestroy(Npfid *fid) { Fid *f; @@ -458,7 +357,7 @@ np_change_user(user); } -static Npfcall* +Npfcall* npfs_attach(Npfid *nfid, Npfid *nafid, Npstr *uname, Npstr *aname) { int err; @@ -498,7 +397,7 @@ return ret; } -static int +int npfs_clone(Npfid *fid, Npfid *newfid) { Fid *f, *nf; @@ -512,7 +411,7 @@ } -static int +int npfs_walk(Npfid *fid, Npstr* wname, Npqid *wqid) { int n; @@ -546,7 +445,7 @@ return 1; } -static Npfcall* +Npfcall* npfs_open(Npfid *fid, u8 mode) { int err; @@ -668,7 +567,7 @@ } -static Npfcall* +Npfcall* npfs_create(Npfid *fid, Npstr *name, u32 perm, u8 mode, Npstr *extension) { int n, err, omode; @@ -750,7 +649,7 @@ return ret; } -static u32 +u32 npfs_read_dir(Npfid *fid, u8* buf, u64 offset, u32 count, int dotu) { int i, n, plen; @@ -816,7 +715,7 @@ return n; } -static Npfcall* +Npfcall* npfs_read(Npfid *fid, u64 offset, u32 count, Npreq *req) { int n; @@ -849,7 +748,7 @@ return ret; } -static Npfcall* +Npfcall* npfs_write(Npfid *fid, u64 offset, u32 count, u8 *data, Npreq *req) { int n; @@ -872,7 +771,7 @@ return np_create_rwrite(n); } -static Npfcall* +Npfcall* npfs_clunk(Npfid *fid) { Fid *f; @@ -884,7 +783,7 @@ return ret; } -static Npfcall* +Npfcall* npfs_remove(Npfid *fid) { Fid *f; @@ -906,7 +805,7 @@ } -static Npfcall* +Npfcall* npfs_stat(Npfid *fid) { int err; @@ -928,7 +827,7 @@ return ret; } -static Npfcall* +Npfcall* npfs_wstat(Npfid *fid, Npstat *stat) { int err; @@ -1079,7 +978,7 @@ } #endif -static void +void npfs_flush(Npreq *req) { if (req->tcall->type!=Tread && req->tcall->type!=Twrite) @@ -1114,7 +1013,7 @@ return; } -/*static*/ int +int npfs_aio_init(int n) { int ret = 0; @@ -1182,7 +1081,7 @@ return ret; } -static void* +void* npfs_aio_proc(void *a) { #ifdef NPFS_USE_AIO Modified: npfs/trunk/include/npfs.h =================================================================== --- npfs/trunk/include/npfs.h 2008-09-18 01:03:08 UTC (rev 8) +++ npfs/trunk/include/npfs.h 2008-09-18 01:31:26 UTC (rev 9) @@ -362,6 +362,7 @@ pthread_cond_t reqcond; int shuttingdown; Npconn* conns; + int nwthread; Npwthread* wthreads; Npreq* reqs_first; Npreq* reqs_last; @@ -579,6 +580,8 @@ Npsrv *np_pipesrv_create(int nwthreads); int np_pipesrv_mount(Npsrv *srv, char *mntpt, char *user, int mntflags, char *opts); +Npsrv *np_rdmasrv_create(int nwthreads, int *port); + void np_werror(char *ename, int ecode, ...); void np_rerror(char **ename, int *ecode); int np_haserror(void); Modified: npfs/trunk/libnpfs/Makefile =================================================================== --- npfs/trunk/libnpfs/Makefile 2008-09-18 01:03:08 UTC (rev 8) +++ npfs/trunk/libnpfs/Makefile 2008-09-18 01:31:26 UTC (rev 9) @@ -24,7 +24,7 @@ uxusers.o\ ifeq ($(SYSNAME), Linux) - LIBFILES += pipesrv.o + LIBFILES += pipesrv.o rdmasrv.o rdmatrans.o endif libnpfs.a: $(LIBFILES) Modified: npfs/trunk/libnpfs/conn.c =================================================================== --- npfs/trunk/libnpfs/conn.c 2008-09-18 01:03:08 UTC (rev 8) +++ npfs/trunk/libnpfs/conn.c 2008-09-18 01:31:26 UTC (rev 9) @@ -310,7 +310,8 @@ conn->trans = NULL; pthread_mutex_unlock(&conn->lock); - np_trans_destroy(trans); + if (trans) + np_trans_destroy(trans); } void Added: npfs/trunk/libnpfs/rdmasrv.c =================================================================== --- npfs/trunk/libnpfs/rdmasrv.c (rev 0) +++ npfs/trunk/libnpfs/rdmasrv.c 2008-09-18 01:31:26 UTC (rev 9) @@ -0,0 +1,172 @@ +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <unistd.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <pthread.h> +#include <errno.h> +#include "npfs.h" +#include "npfsimpl.h" +#include <infiniband/verbs.h> +#include <rdma/rdma_cma.h> + +typedef struct Rdmasrv Rdmasrv; +struct Rdmasrv { + struct rdma_cm_id *listen_id; + struct rdma_event_channel *event_channel; + struct sockaddr_in addr; + int shutdown; + pthread_t thread; +}; + +extern Nptrans *np_rdmatrans_create(struct rdma_cm_id *cmid, int q_depth, int msize); + +static void rdmasrv_start(Npsrv *srv); +static void rdmasrv_shutdown(Npsrv *srv); +static void rdmasrv_destroy(Npsrv *srv); +static void *rdmasrv_listenproc(void *a); + +Npsrv* +np_rdmasrv_create(int nwthreads, int *port) +{ + Npsrv *srv; + Rdmasrv *rdma; + int ret; + + rdma = malloc(sizeof(struct Rdmasrv)); + if (!rdma) + return NULL; + + rdma->event_channel = rdma_create_event_channel(); + if (!rdma->event_channel) { + np_werror("Can't create event channel", EIO); + goto error; + } + + ret = rdma_create_id(rdma->event_channel, &rdma->listen_id, + NULL, RDMA_PS_TCP); + if (ret) { + np_werror("Can't create an id", ret); + goto error; + } + + rdma->addr.sin_family = AF_INET; + rdma->addr.sin_port = htons(*port); + rdma->addr.sin_addr.s_addr = htonl(INADDR_ANY); + ret = rdma_bind_addr(rdma->listen_id, (struct sockaddr *)&rdma->addr); + if (ret) { + np_werror("Can't bind", ret); + goto error; + } + + srv = np_srv_create(nwthreads); + srv->srvaux = rdma; + srv->start = rdmasrv_start; + srv->shutdown = rdmasrv_shutdown; + srv->destroy = rdmasrv_destroy; + + return srv; + + error: + free(rdma); + return NULL; +} + +static void +rdmasrv_start(Npsrv *srv) +{ + int n; + Rdmasrv *rdma; + + rdma = srv->srvaux; + n = rdma_listen(rdma->listen_id, 1); + if (n < 0) { + np_uerror(n); + return; + } + + n = pthread_create(&rdma->thread, NULL, rdmasrv_listenproc, srv); + if (n) + np_uerror(n); +} + +static void +rdmasrv_shutdown(Npsrv *srv) +{ + Rdmasrv *rdma; + + rdma = srv->srvaux; + rdma->shutdown = 1; + if (rdma->listen_id) + rdma_destroy_id(rdma->listen_id); + + rdma->listen_id = NULL; +} + +static void +rdmasrv_destroy(Npsrv *srv) +{ + Rdmasrv *rdma; + void *ret; + + rdma = srv->srvaux; + rdmasrv_shutdown(srv); + pthread_join(rdma->thread, &ret); + free(rdma); + srv->srvaux = NULL; +} + +static void * +rdmasrv_listenproc(void *a) +{ + int ret; + Npsrv *srv; + Npconn *conn; + Nptrans *trans; + Rdmasrv *rdma; + struct rdma_cm_event *event; + struct rdma_cm_id *cmid; + + srv = a; + rdma = srv->srvaux; + while (!rdma->shutdown) { + ret = rdma_get_cm_event(rdma->event_channel, &event); + if (ret) + goto error; + + switch (event->event) { + case RDMA_CM_EVENT_CONNECT_REQUEST: + printf("Connection request\n"); + cmid = (struct rdma_cm_id *) event->id; + trans = np_rdmatrans_create(cmid, srv->nwthread, srv->msize); + if (trans) { + conn = np_conn_create(srv, trans); + cmid->context = conn; + np_srv_add_conn(srv, conn); + } + break; + + case RDMA_CM_EVENT_ESTABLISHED: + printf("Connection established\n"); + break; + + case RDMA_CM_EVENT_DISCONNECTED: + printf("Connection shutting down\n"); + cmid = (struct rdma_cm_id *) event->id; + np_conn_shutdown(conn); + break; + + default: + fprintf(stderr, "event %d received waiting for a connect request\n", + event->event); + } + + rdma_ack_cm_event(event); + } + return NULL; + + error: + fprintf(stderr, "shutting down the server with error %d\n", ret); + return 0; +} Added: npfs/trunk/libnpfs/rdmatrans.c =================================================================== --- npfs/trunk/libnpfs/rdmatrans.c (rev 0) +++ npfs/trunk/libnpfs/rdmatrans.c 2008-09-18 01:31:26 UTC (rev 9) @@ -0,0 +1,377 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/poll.h> +#include <pthread.h> +#include <errno.h> +#include "npfs.h" +#include "npfsimpl.h" +#include <infiniband/verbs.h> +#include <rdma/rdma_cma.h> + +typedef struct Rdmatrans Rdmatrans; +typedef struct Rdmactx Rdmactx; + +struct Rdmatrans { + struct Nptrans* trans; + pthread_mutex_t lock; + pthread_cond_t cond; + int connected; + size_t msize; + size_t q_depth; + struct rdma_cm_id* cm_id; + struct ibv_context* context; + int fd; + u8* rcv_buf; + u8* snd_buf; + int next_buf; + struct ibv_pd* pd; + struct ibv_mr* rcv_mr; + struct ibv_mr* snd_mr; + struct ibv_cq* cq; + struct ibv_comp_channel* ch; + struct ibv_qp* qp; + struct rdma_event_channel* event_ch; + + Rdmactx* rfirst; + Rdmactx* rlast; +}; + +struct Rdmactx { + int used; + enum ibv_wc_opcode wc_op; + struct Rdmatrans* rdma; + u32 pos; + u32 len; + Rdmactx* next; + unsigned char buf[0]; +}; + +static void rdma_trans_destroy(void *a); +static int rdma_trans_read(u8 *data, u32 count, void *a); +static int rdma_trans_write(u8 *data, u32 count, void *a); +static void rdma_post_recv(struct Rdmatrans *rdma, Rdmactx *rctx); + + + +/** + * \brief Create an RDMA transport server + * + * \param cmid The CM id passed up in the connect event + * \param q_depth A hint from the client on the depth of it's SQ/RQ + * \param msize The max message size + * \returns A pointer to the newly allocated transport + */ +Nptrans * +np_rdmatrans_create(struct rdma_cm_id *cmid, int q_depth, int msize) +{ + int i, ret; + u8 *p; + struct Nptrans *trans; + struct Rdmatrans *rdma; + struct ibv_qp_init_attr qp_attr; + struct rdma_conn_param cparam; + + rdma = calloc(1, sizeof *rdma); + if (!rdma) + goto error; + + ret = pthread_mutex_init(&rdma->lock, NULL); + if (ret) + goto error; + + ret = pthread_cond_init(&rdma->cond, NULL); + if (ret) + goto error; + + rdma->trans = trans; + rdma->connected = 0; + rdma->cm_id = cmid; + rdma->context = cmid->verbs; + rdma->q_depth = q_depth; + rdma->msize = msize + sizeof(Rdmactx); + + rdma->pd = ibv_alloc_pd(rdma->context); + if (!rdma->pd) + goto error; + + /* Create receive buffer space and register it */ + rdma->rcv_buf = malloc(rdma->msize * q_depth); + if (!rdma->rcv_buf) + goto error; + + rdma->rcv_mr = ibv_reg_mr(rdma->pd, rdma->rcv_buf, rdma->msize * q_depth, + IBV_ACCESS_LOCAL_WRITE); + if (!rdma->rcv_mr) + goto error; + + /* Create send buffer space and register it */ + rdma->snd_buf = malloc(rdma->msize * q_depth); + if (!rdma->snd_buf) + goto error; + + rdma->next_buf = 0; + rdma->snd_mr = ibv_reg_mr(rdma->pd, rdma->snd_buf, msize * q_depth * 2, 0); + if (!rdma->snd_mr) + goto error; + + rdma->ch = ibv_create_comp_channel(rdma->context); + if (!rdma->ch) + goto error; + + rdma->fd = rdma->ch->fd; + rdma->cq = ibv_create_cq(rdma->context, 2*q_depth, rdma, rdma->ch, 0); + if (!rdma->cq) + goto error; + + ibv_req_notify_cq(rdma->cq, 0); + + /* Create the CQ */ + memset(&qp_attr, 0, sizeof qp_attr); + qp_attr.send_cq = rdma->cq; + qp_attr.recv_cq = rdma->cq; + qp_attr.cap.max_send_wr = q_depth; + qp_attr.cap.max_recv_wr = q_depth; + qp_attr.cap.max_send_sge = 1; + qp_attr.cap.max_send_sge = 1; + qp_attr.cap.max_recv_sge = 1; + qp_attr.cap.max_inline_data = 64; + qp_attr.qp_type = IBV_QPT_RC; + ret = rdma_create_qp(rdma->cm_id, rdma->pd, &qp_attr); + if (ret) + goto error; + rdma->qp = rdma->cm_id->qp; + + p = rdma->rcv_buf; + for (i = 0; i < q_depth; i++) + rdma_post_recv(rdma, (Rdmactx *)(p + i*rdma->msize)); + + trans = np_trans_create(rdma, rdma_trans_read, rdma_trans_write, + rdma_trans_destroy); + if (!trans) + goto error; + + memset(&cparam, 0, sizeof(cparam)); + cparam.responder_resources = 1; + cparam.initiator_depth = 1; + cparam.private_data = NULL; + cparam.private_data_len = 0; + ret = rdma_accept(cmid, &cparam); + if (ret) { + np_uerror(ret); + goto error; + } + + rdma->connected = 1; + return trans; + + error: + if (rdma) + rdma_trans_destroy(rdma); + + rdma_reject(cmid, NULL, 0); + return NULL; +} + +static void +rdma_trans_destroy(void *a) +{ + Rdmatrans *rdma; + + rdma = a; + if (rdma->connected) + rdma_disconnect(rdma->cm_id); + if (rdma->qp) + ibv_destroy_qp(rdma->qp); + if (rdma->cq) + ibv_destroy_cq(rdma->cq); + if (rdma->ch) + ibv_destroy_comp_channel(rdma->ch); + if (rdma->snd_mr) + ibv_dereg_mr(rdma->snd_mr); + if (rdma->snd_buf) + free(rdma->snd_buf); + if (rdma->rcv_mr) + ibv_dereg_mr(rdma->rcv_mr); + if (rdma->rcv_buf) + free(rdma->rcv_buf); + if (rdma->pd) + ibv_dealloc_pd(rdma->pd); + if (rdma->cm_id) + rdma_destroy_id(rdma->cm_id); +} + +static int +rdma_trans_read(u8 *data, u32 count, void *a) +{ + int n, ret; + struct ibv_cq *cq; + struct ibv_wc wc; + void *context; + struct pollfd pfd; + Rdmatrans *rdma; + Rdmactx *ctx; + + rdma = a; + pthread_mutex_lock(&rdma->lock); +again: + if (rdma->rfirst) { + ctx = rdma->rfirst; + + n = ctx->len - ctx->pos; + if (n > count) + n = count; + + memmove(data, ctx->buf + ctx->pos, n); + ctx->pos += n; + if (ctx->pos == ctx->len) { + rdma->rfirst = ctx->next; + if (ctx == rdma->rlast) + rdma->rlast = NULL; + + rdma_post_recv(rdma, ctx); + } + + pthread_mutex_unlock(&rdma->lock); + return n; + } + + pthread_mutex_unlock(&rdma->lock); + pfd.fd = rdma->ch->fd; + pfd.events = POLLIN | POLLERR | POLLNVAL | POLLHUP; + +poll: + while ((n = poll(&pfd, 1, 1000)) <= 0) + ; + + if (pfd.revents & (POLLERR | POLLNVAL | POLLHUP)) + return -1; + + ret = ibv_get_cq_event(rdma->ch, &cq, &context); + if (ret) { + np_uerror(ret); + fprintf(stderr, "Error %d polling cq\n", ret); + return -1; + } + + ibv_req_notify_cq(cq, 0); + while ((ret = ibv_poll_cq(rdma->cq, 1, &wc)) > 0) { + /* Check if it's a flush */ + if (wc.status != IBV_WC_SUCCESS) { + fprintf(stderr, "cq fail: status %d opcode %d\n", + wc.status, wc.opcode); + continue; + } + + if (wc.opcode == IBV_WC_RECV) { + ctx = (Rdmactx *) wc.wr_id; + pthread_mutex_lock(&rdma->lock); + ctx->used = 0; + ctx->len = wc.byte_len; + ctx->pos = 0; + if (rdma->rlast) + rdma->rlast->next = ctx; + else + rdma->rfirst = ctx; + + rdma->rlast = ctx; + ctx->next = NULL; + goto again; + } else if (wc.opcode == IBV_WC_SEND) { + ctx = (Rdmactx *) wc.wr_id; + pthread_mutex_lock(&rdma->lock); + ctx->used = 0; + pthread_cond_signal(&rdma->cond); + pthread_mutex_unlock(&rdma->lock); + } + } + + if (!ret) + goto poll; + + np_uerror(ret); + return -1; +} + +static int +rdma_trans_write(u8 *data, u32 count, void *a) +{ + int i, n; + Rdmatrans *rdma; + struct ibv_sge sge; + struct ibv_send_wr wr, *bad_wr; + Rdmactx *wctx; + + rdma = a; + pthread_mutex_lock(&rdma->lock); + +again: + for(i = 0, wctx = (Rdmactx *) rdma->snd_buf; i < rdma->q_depth; + i++, wctx = (Rdmactx *) ((char *) wctx + rdma->msize)) + if (!wctx->used) + break; + + if (i >= rdma->q_depth) { + /* wait for a slot */ + pthread_cond_wait(&rdma->cond, &rdma->lock); + goto again; + } + + wctx->wc_op = IBV_WC_SEND; + wctx->rdma = rdma; + wctx->used = 1; + wctx->len = count; + wctx->pos = 0; + memmove(wctx->buf, data, count); + pthread_mutex_unlock(&rdma->lock); + + sge.addr = (uintptr_t) wctx->buf; + sge.length = count; + sge.lkey = rdma->snd_mr->lkey; + wr.next = NULL; + wr.wr_id = (u64)(unsigned long)wctx; + wr.opcode = IBV_WR_SEND; + wr.send_flags = IBV_SEND_SIGNALED; + wr.sg_list = &sge; + wr.num_sge = 1; + n = ibv_post_send(rdma->qp, &wr, &bad_wr); + if (n) { + np_uerror(n); + return -1; + } + + return count; +} + +/** + * \brief Post a new receive buffer to the RQ + * + * \param rdma Pointer to the rdma transport structure + * \c RDMA buffer context + */ +static void +rdma_post_recv(struct Rdmatrans *rdma, Rdmactx *rctx) +{ + int n, rc; + struct ibv_sge sge; + struct ibv_recv_wr wr, *bad_wr; + + rctx->wc_op = IBV_WC_RECV; + rctx->rdma = rdma; + rctx->next = NULL; + rctx->used = 1; + sge.addr = (uintptr_t)rctx->buf; + sge.length = rdma->msize - sizeof(Rdmactx); + sge.lkey = rdma->rcv_mr->lkey; + wr.next = NULL; + wr.wr_id = (u64)(unsigned long)rctx; + wr.sg_list = &sge; + wr.num_sge = 1; + n = ibv_post_recv(rdma->qp, &wr, &bad_wr); + if (n) { + np_uerror(n); + fprintf(stderr, "Error %d posting recv\n", rc); + } +} Modified: npfs/trunk/libnpfs/srv.c =================================================================== --- npfs/trunk/libnpfs/srv.c 2008-09-18 01:03:08 UTC (rev 8) +++ npfs/trunk/libnpfs/srv.c 2008-09-18 01:31:26 UTC (rev 9) @@ -98,6 +98,7 @@ srv->workreqs = NULL; srv->wthreads = NULL; srv->debuglevel = 0; + srv->nwthread = nwthread; for(i = 0; i < nwthread; i++) np_wthread_create(srv); Modified: npfs/trunk/libnpfs/user.c =================================================================== --- npfs/trunk/libnpfs/user.c 2008-09-18 01:03:08 UTC (rev 8) +++ npfs/trunk/libnpfs/user.c 2008-09-18 01:31:26 UTC (rev 9) @@ -29,6 +29,7 @@ #include <grp.h> #include <errno.h> #include <pthread.h> +#include <sys/syscall.h> #include "npfs.h" #include "npfsimpl.h" @@ -101,6 +102,18 @@ } int +sreuid(int a, int b) +{ + return syscall(SYS_setreuid, a, b); +} + +int +sregid(int a, int b) +{ + return syscall(SYS_setregid, a, b); +} + +int np_change_user(Npuser *u) { int i; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <li...@us...> - 2008-09-18 01:02:58
|
Revision: 8 http://npfs.svn.sourceforge.net/npfs/?rev=8&view=rev Author: lionkov Date: 2008-09-18 01:03:08 +0000 (Thu, 18 Sep 2008) Log Message: ----------- Multiple races in the unix user function. Modified Paths: -------------- npfs/trunk/fs/ufs.c npfs/trunk/include/npfs.h npfs/trunk/libnpfs/Makefile npfs/trunk/libnpfs/conn.c npfs/trunk/libnpfs/error.c npfs/trunk/libnpfs/fcall.c npfs/trunk/libnpfs/fidpool.c npfs/trunk/libnpfs/mount-Linux.c npfs/trunk/libnpfs/mount-none.c npfs/trunk/libnpfs/npfsimpl.h npfs/trunk/libnpfs/user.c npfs/trunk/libnpfs/uxusers.c Modified: npfs/trunk/fs/ufs.c =================================================================== --- npfs/trunk/fs/ufs.c 2008-07-17 17:20:51 UTC (rev 7) +++ npfs/trunk/fs/ufs.c 2008-09-18 01:03:08 UTC (rev 8) @@ -62,6 +62,12 @@ int debuglevel; int sameuser; +pthread_mutex_t culock = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t cucond = PTHREAD_COND_INITIALIZER; +Npuser *cuser; +int curef; +int maxref; + char *Estatfailed = "stat failed"; char *Ebadfid = "fid unknown or out of range"; char *Enoextension = "empty extension while creating special file"; @@ -441,10 +447,15 @@ } static inline void -npfs_change_user(Npuser *user) +npfs_set_user(Npuser *user) { - if (!sameuser) - np_change_user(user); + if (sameuser) + return; + + if (geteuid() == user->uid) + return; + + np_change_user(user); } static Npfcall* @@ -459,12 +470,12 @@ user = NULL; ret = NULL; + npfs_set_user(nfid->user); if (nafid != NULL) { np_werror(Enoauth, EIO); goto done; } - npfs_change_user(nfid->user); fid = npfs_fidalloc(); fid->omode = -1; if (aname->len==0 || *aname->str!='/') @@ -510,7 +521,7 @@ char *path; f = fid->aux; - npfs_change_user(fid->user); + npfs_set_user(fid->user); n = fidstat(f); if (n < 0) create_rerror(n); @@ -543,7 +554,7 @@ Npqid qid; f = fid->aux; - npfs_change_user(fid->user); + npfs_set_user(fid->user); if ((err = fidstat(f)) < 0) create_rerror(err); @@ -814,7 +825,7 @@ f = fid->aux; ret = np_alloc_rread(count); - npfs_change_user(fid->user); + npfs_set_user(fid->user); if (f->dir) n = npfs_read_dir(fid, ret->data, offset, count, fid->conn->dotu); else { @@ -845,7 +856,7 @@ Fid *f; f = fid->aux; - npfs_change_user(fid->user); + npfs_set_user(fid->user); if (use_aio) { n = npfs_aio_write(fid, data, offset, count, req); @@ -881,7 +892,7 @@ ret = NULL; f = fid->aux; - npfs_change_user(fid->user); + npfs_set_user(fid->user); if (remove(f->path) < 0) { create_rerror(errno); goto out; @@ -904,7 +915,7 @@ Npwstat wstat; f = fid->aux; - npfs_change_user(fid->user); + npfs_set_user(fid->user); err = fidstat(f); if (err < 0) create_rerror(err); @@ -934,7 +945,7 @@ ret = NULL; f = fid->aux; up = fid->conn->srv->upool; - npfs_change_user(fid->user); + npfs_set_user(fid->user); err = fidstat(f); if (err < 0) { create_rerror(err); @@ -1046,7 +1057,7 @@ rc = NULL; if (count<0 && !flush) { - if (areq->req->tcall->id == Tread) + if (areq->req->tcall->type == Tread) free(areq->rread); if (strerror_r(count, buf, sizeof(buf))) @@ -1054,7 +1065,7 @@ rc = np_create_rerror(buf, count, areq->req->conn->dotu); } else { - if (areq->req->tcall->id == Tread) { + if (areq->req->tcall->type == Tread) { rc = areq->rread; np_set_rread_count(rc, count); } else { Modified: npfs/trunk/include/npfs.h =================================================================== --- npfs/trunk/include/npfs.h 2008-07-17 17:20:51 UTC (rev 7) +++ npfs/trunk/include/npfs.h 2008-09-18 01:03:08 UTC (rev 8) @@ -34,6 +34,7 @@ typedef struct Npwstat Npwstat; typedef struct Npfcall Npfcall; typedef struct Npfid Npfid; +typedef struct Npfidpool Npfidpool; typedef struct Npbuf Npbuf; typedef struct Nptrans Nptrans; typedef struct Npconn Npconn; @@ -231,6 +232,7 @@ }; struct Npfid { + pthread_mutex_t lock; Npconn* conn; u32 fid; int refcount; @@ -241,6 +243,7 @@ void* aux; Npfid* next; /* list of fids within a bucket */ + Npfid* prev; }; struct Npbuf { @@ -258,8 +261,15 @@ void (*destroy)(void *); }; +struct Npfidpool { + pthread_mutex_t lock; + int size; + Npfid** htable; +}; + struct Npconn { pthread_mutex_t lock; + pthread_mutex_t wlock; int refcount; int resetting; @@ -271,7 +281,7 @@ int shutdown; Npsrv* srv; Nptrans* trans; - Npfid** fidpool; + Npfidpool* fidpool; int freercnum; Npfcall* freerclist; void* aux; @@ -491,11 +501,11 @@ void np_conn_respond(Npreq *req); void np_respond(Npreq *, Npfcall *); -Npfid **np_fidpool_create(void); -void np_fidpool_destroy(Npfid **); +Npfidpool *np_fidpool_create(void); +void np_fidpool_destroy(Npfidpool *); Npfid *np_fid_find(Npconn *, u32); Npfid *np_fid_create(Npconn *, u32, void *); -int np_fid_destroy(Npfid *); +void np_fid_destroy(Npfid *); void np_fid_incref(Npfid *); void np_fid_decref(Npfid *); Modified: npfs/trunk/libnpfs/Makefile =================================================================== --- npfs/trunk/libnpfs/Makefile 2008-07-17 17:20:51 UTC (rev 7) +++ npfs/trunk/libnpfs/Makefile 2008-09-18 01:03:08 UTC (rev 8) @@ -16,7 +16,6 @@ file.o\ fmt.o\ np.o\ - pipesrv.o\ pvusers.o\ socksrv.o\ srv.o\ @@ -24,6 +23,10 @@ user.o\ uxusers.o\ +ifeq ($(SYSNAME), Linux) + LIBFILES += pipesrv.o +endif + libnpfs.a: $(LIBFILES) ar rc libnpfs.a $(LIBFILES) ranlib libnpfs.a Modified: npfs/trunk/libnpfs/conn.c =================================================================== --- npfs/trunk/libnpfs/conn.c 2008-07-17 17:20:51 UTC (rev 7) +++ npfs/trunk/libnpfs/conn.c 2008-09-18 01:03:08 UTC (rev 8) @@ -32,7 +32,7 @@ extern int printfcall(FILE *f, Npfcall *fc, int dotu); static Npfcall *np_conn_new_incall(Npconn *conn); -static void np_conn_free_incall(Npconn *, Npfcall *); +static void np_conn_free_incall(Npconn *, Npfcall *, int); static void *np_conn_read_proc(void *); Npconn* @@ -46,6 +46,7 @@ //fprintf(stderr, "np_conn_create %p\n", conn); pthread_mutex_init(&conn->lock, NULL); + pthread_mutex_init(&conn->wlock, NULL); pthread_cond_init(&conn->resetcond, NULL); pthread_cond_init(&conn->resetdonecond, NULL); conn->refcount = 0; @@ -169,7 +170,7 @@ pthread_mutex_lock(&conn->lock); trans = conn->trans; conn->trans = NULL; - np_conn_free_incall(conn, fc); + np_conn_free_incall(conn, fc, 0); pthread_mutex_unlock(&conn->lock); np_srv_remove_conn(conn->srv, conn); @@ -315,7 +316,7 @@ void np_conn_respond(Npreq *req) { - int n; + int n, send; Npconn *conn; Nptrans *trans; Npfcall *rc; @@ -323,25 +324,36 @@ trans = NULL; conn = req->conn; rc = req->rcall; + if (!rc) + goto done; + pthread_mutex_lock(&conn->lock); - if (conn->trans && !conn->resetting && rc) { + send = conn->trans && !conn->resetting; + pthread_mutex_unlock(&conn->lock); + + if (send) { + pthread_mutex_lock(&conn->wlock); if (conn->srv->debuglevel) { fprintf(stderr, ">>> (%p) ", conn); np_printfcall(stderr, rc, conn->dotu); fprintf(stderr, "\n"); } n = np_trans_write(conn->trans, rc->pkt, rc->size); + pthread_mutex_unlock(&conn->wlock); + if (n <= 0) { + pthread_mutex_lock(&conn->lock); trans = conn->trans; conn->trans = NULL; + pthread_mutex_unlock(&conn->lock); } } - np_conn_free_incall(req->conn, req->tcall); +done: + np_conn_free_incall(req->conn, req->tcall, 1); free(req->rcall); req->tcall = NULL; req->rcall = NULL; - pthread_mutex_unlock(&conn->lock); if (conn->resetting) { pthread_mutex_lock(&conn->srv->lock); @@ -384,19 +396,23 @@ } static void -np_conn_free_incall(Npconn* conn, Npfcall *rc) +np_conn_free_incall(Npconn* conn, Npfcall *rc, int lock) { if (!rc) return; -// pthread_mutex_lock(&conn->lock); + if (lock) + pthread_mutex_lock(&conn->lock); + if (conn->freercnum < 64) { rc->next = conn->freerclist; conn->freerclist = rc; rc = NULL; } -// pthread_mutex_unlock(&conn->lock); + if (lock) + pthread_mutex_unlock(&conn->lock); + if (rc) free(rc); } Modified: npfs/trunk/libnpfs/error.c =================================================================== --- npfs/trunk/libnpfs/error.c 2008-07-17 17:20:51 UTC (rev 7) +++ npfs/trunk/libnpfs/error.c 2008-09-18 01:03:08 UTC (rev 8) @@ -92,6 +92,9 @@ va_list ap; Nperror *err; + if (ecode == 5) + printf("EIO...\n"); + pthread_once(&error_once, np_init_error_key); err = pthread_getspecific(error_key); if (!err) { @@ -152,10 +155,10 @@ void np_suerror(char *s, int ecode) { - char err[256], *str; + char err[256]; char buf[512]; - str = strerror_r(ecode, err, sizeof(err)); - snprintf(buf, sizeof(buf), "%s: %s", s, str); + strerror_r(ecode, err, sizeof(err)); + snprintf(buf, sizeof(buf), "%s: %s", s, err); np_werror(buf, ecode); } Modified: npfs/trunk/libnpfs/fcall.c =================================================================== --- npfs/trunk/libnpfs/fcall.c 2008-07-17 17:20:51 UTC (rev 7) +++ npfs/trunk/libnpfs/fcall.c 2008-09-18 01:03:08 UTC (rev 8) @@ -307,6 +307,7 @@ } if (tc->fid != tc->newfid) { +// printf("newfid conn %p fid %d\n", conn, tc->newfid); newfid = np_fid_find(conn, tc->newfid); if (newfid) { np_werror(Einuse, EIO); Modified: npfs/trunk/libnpfs/fidpool.c =================================================================== --- npfs/trunk/libnpfs/fidpool.c 2008-07-17 17:20:51 UTC (rev 7) +++ npfs/trunk/libnpfs/fidpool.c 2008-09-18 01:03:08 UTC (rev 8) @@ -28,27 +28,36 @@ #include "npfs.h" #include "npfsimpl.h" -Npfid** +Npfidpool * np_fidpool_create(void) { - Npfid **ret; + Npfidpool *fp; - return calloc(FID_HTABLE_SIZE, sizeof(*ret)); + fp = np_malloc(sizeof(*fp) + FID_HTABLE_SIZE * sizeof(Npfid *)); + if (!fp) + return NULL; + + pthread_mutex_init(&fp->lock, NULL); + fp->size = FID_HTABLE_SIZE; + fp->htable = (Npfid **)((char *) fp + sizeof(*fp)); + memset(fp->htable, 0, fp->size * sizeof(Npfid *)); + + return fp; } void -np_fidpool_destroy(Npfid **pool) +np_fidpool_destroy(Npfidpool *pool) { int i; Npfid *f, *ff; Npsrv *srv; - for(i = 0; i < FID_HTABLE_SIZE; i++) { - f = pool[i]; + for(i = 0; i < pool->size; i++) { + f = pool->htable[i]; while (f != NULL) { ff = f->next; srv = f->conn->srv; - if (f->type&Qtauth && srv->auth->clunk) + if (f->type&Qtauth && srv->auth && srv->auth->clunk) (*srv->auth->clunk)(f); else if (!(f->type&Qtauth) && srv->fiddestroy) (*srv->fiddestroy)(f); @@ -60,103 +69,130 @@ free(pool); } -Npfid* -np_fid_find(Npconn *conn, u32 fid) +Npfid * +np_fid_lookup(Npfidpool *fp, u32 fid, int hash) { - int hash; - Npfid **htable, *f, **prevp; + Npfid **htable, *f; - hash = fid % FID_HTABLE_SIZE; - htable = conn->fidpool; - pthread_mutex_lock(&conn->lock); - prevp = &htable[hash]; - f = *prevp; - while (f != NULL) { + htable = fp->htable; + for(f = htable[hash]; f != NULL; f = f->next) { if (f->fid == fid) { - *prevp = f->next; - f->next = htable[hash]; - htable[hash] = f; + if (f != htable[hash]) { + if (f->next) + f->next->prev = f->prev; + + f->prev->next = f->next; + f->prev = NULL; + f->next = htable[hash]; + htable[hash]->prev = f; + htable[hash] = f; + } + break; } + } - prevp = &f->next; - f = *prevp; - } - pthread_mutex_unlock(&conn->lock); return f; } Npfid* +np_fid_find(Npconn *conn, u32 fid) +{ + int hash; + Npfidpool *fp; + Npfid *ret; + + fp = conn->fidpool; + pthread_mutex_lock(&fp->lock); + hash = fid % fp->size; + ret = np_fid_lookup(fp, fid, hash); + pthread_mutex_unlock(&fp->lock); + + return ret; +} + +Npfid* np_fid_create(Npconn *conn, u32 fid, void *aux) { int hash; + Npfidpool *fp; Npfid **htable, *f; + fp = conn->fidpool; + pthread_mutex_lock(&fp->lock); + htable = fp->htable; hash = fid % FID_HTABLE_SIZE; - htable = conn->fidpool; - f = np_fid_find(conn, fid); - if (f) - return NULL; + f = np_fid_lookup(fp, fid, hash); + if (!f) { + f = np_malloc(sizeof(*f)); + if (!f) { + pthread_mutex_unlock(&fp->lock); + return NULL; + } - f = malloc(sizeof(*f)); - if (!f) - return NULL; + pthread_mutex_init(&f->lock, NULL); + f->fid = fid; + f->conn = conn; + f->refcount = 0; + f->omode = ~0; + f->type = 0; + f->diroffset = 0; + f->user = NULL; + f->aux = aux; - f->fid = fid; - f->conn = conn; - f->refcount = 0; - f->omode = ~0; - f->type = 0; - f->diroffset = 0; - f->user = NULL; - f->aux = aux; + f->next = htable[hash]; + f->prev = NULL; + if (htable[hash]) + htable[hash]->prev = f; - pthread_mutex_lock(&conn->lock); - f->next = htable[hash]; - htable[hash] = f; - pthread_mutex_unlock(&conn->lock); + htable[hash] = f; + } + pthread_mutex_unlock(&fp->lock); + return f; } -int +void np_fid_destroy(Npfid *fid) { int hash; Npconn *conn; Npsrv *srv; - Npfid **htable, *f, **prevp; + Npfidpool *fp; + Npfid **htable; conn = fid->conn; - hash = fid->fid % FID_HTABLE_SIZE; - htable = conn->fidpool; - if(!htable) - return 0; + srv = conn->srv; + fp = conn->fidpool; + if (!fp) + return; - pthread_mutex_lock(&conn->lock); - prevp = &htable[hash]; - f = *prevp; - while (f != NULL) { - if (f->fid == fid->fid) { - *prevp = f->next; - srv = f->conn->srv; - if (f->type & Qtauth && srv->auth->clunk) - (*srv->auth->clunk)(f); - else if (!(f->type&Qtauth) && srv->fiddestroy) - (*srv->fiddestroy)(f); +// printf("destroy conn %p fid %d\n", conn, fid->fid); + pthread_mutex_lock(&fp->lock); + hash = fid->fid % fp->size; + htable = fp->htable; + if (fid->prev) + fid->prev->next = fid->next; + else + htable[hash] = fid->next; - if (f->user) - np_user_decref(f->user); + if (fid->next) + fid->next->prev = fid->prev; - free(f); - break; - } + pthread_mutex_unlock(&fp->lock); - prevp = &f->next; - f = *prevp; - } - pthread_mutex_unlock(&conn->lock); - return f != NULL; + if (fid->type & Qtauth && srv->auth && srv->auth->clunk) + (*srv->auth->clunk)(fid); + else if (!(fid->type&Qtauth) && srv->fiddestroy) + (*srv->fiddestroy)(fid); + + if (fid->user) + np_user_decref(fid->user); + + free(fid); + + return; } void @@ -165,17 +201,23 @@ if (!fid) return; + pthread_mutex_lock(&fid->lock); fid->refcount++; + pthread_mutex_unlock(&fid->lock); } void np_fid_decref(Npfid *fid) { + int n; + if (!fid) return; - fid->refcount--; + pthread_mutex_lock(&fid->lock); + n = --fid->refcount; + pthread_mutex_unlock(&fid->lock); - if (!fid->refcount) + if (!n) np_fid_destroy(fid); } Modified: npfs/trunk/libnpfs/mount-Linux.c =================================================================== --- npfs/trunk/libnpfs/mount-Linux.c 2008-07-17 17:20:51 UTC (rev 7) +++ npfs/trunk/libnpfs/mount-Linux.c 2008-09-18 01:03:08 UTC (rev 8) @@ -1,6 +1,19 @@ #include <sys/mount.h> +#include <sys/syscall.h> int np_mount(char *mntpt, int mntflags, char *opts) { return mount("none", mntpt, "9p", mntflags, opts); } + +int +sreuid(int a, int b) +{ + return syscall(SYS_setreuid, a, b); +} + +int +sregid(int a, int b) +{ + return syscall(SYS_setregid, a, b); +} Modified: npfs/trunk/libnpfs/mount-none.c =================================================================== --- npfs/trunk/libnpfs/mount-none.c 2008-07-17 17:20:51 UTC (rev 7) +++ npfs/trunk/libnpfs/mount-none.c 2008-09-18 01:03:08 UTC (rev 8) @@ -1,3 +1,5 @@ +#include <unistd.h> + int np_mount(char *mntpt, int mntflags, char *opts) { return -1; @@ -2 +4,13 @@ } + +int +sreuid(int a, int b) +{ + return setreuid(a, b); +} + +int +sregid(int a, int b) +{ + return setregid(a, b); +} Modified: npfs/trunk/libnpfs/npfsimpl.h =================================================================== --- npfs/trunk/libnpfs/npfsimpl.h 2008-07-17 17:20:51 UTC (rev 7) +++ npfs/trunk/libnpfs/npfsimpl.h 2008-09-18 01:03:08 UTC (rev 8) @@ -52,3 +52,5 @@ void np_req_unref(Npreq*); void np_req_free(Npreq *req); void np_srv_process_fcall(Npconn *conn, Npfcall *tc); +int sreuid(int a, int b); +int sregid(int a, int b); Modified: npfs/trunk/libnpfs/user.c =================================================================== --- npfs/trunk/libnpfs/user.c 2008-07-17 17:20:51 UTC (rev 7) +++ npfs/trunk/libnpfs/user.c 2008-09-18 01:03:08 UTC (rev 8) @@ -32,8 +32,6 @@ #include "npfs.h" #include "npfsimpl.h" -static Npuser *currentUser; - void np_user_incref(Npuser *u) { @@ -108,10 +106,7 @@ int i; gid_t *gids; - if (currentUser == u) - return 0; - - if (setreuid(0, 0) < 0) + if (sreuid(0, 0) < 0) goto error; gids = np_malloc(u->ngroups * sizeof(gid_t)); @@ -123,16 +118,13 @@ if (u->ngroups > 0) { setgroups(u->ngroups, gids); - if (setregid(-1, u->dfltgroup->gid) < 0) + if (sregid(-1, u->dfltgroup->gid) < 0) goto error; } - if (setreuid(-1, u->uid) < 0) + if (sreuid(-1, u->uid) < 0) goto error; - np_user_incref(u); - np_user_decref(currentUser); - currentUser = u; return 0; error: @@ -143,5 +135,5 @@ Npuser * np_current_user(void) { - return currentUser; + return NULL; } Modified: npfs/trunk/libnpfs/uxusers.c =================================================================== --- npfs/trunk/libnpfs/uxusers.c 2008-07-17 17:20:51 UTC (rev 7) +++ npfs/trunk/libnpfs/uxusers.c 2008-09-18 01:03:08 UTC (rev 8) @@ -67,6 +67,8 @@ pthread_mutex_t lock; } groupcache = { 0 }; +pthread_mutex_t grentlock = PTHREAD_MUTEX_INITIALIZER; + static void initusercache(void) { @@ -95,7 +97,7 @@ static Npuser * np_unix_uname2user(Npuserpool *up, char *uname) { - int i, n; + int i, n, found; struct passwd pw, *pwp; int bufsize; char *buf; @@ -105,55 +107,63 @@ if (!usercache.init) initusercache(); + found = 0; for(i = 0; i<usercache.hsize; i++) for(u = usercache.htable[i]; u != NULL; u = u->next) - if (strcmp(uname, u->uname) == 0) + if (strcmp(uname, u->uname) == 0) { + found = 1; break; - pthread_mutex_unlock(&usercache.lock); + } - if (u) + if (found) { + pthread_mutex_unlock(&usercache.lock); + pthread_mutex_lock(&u->lock); + found = u->uname != NULL; + pthread_mutex_unlock(&u->lock); + + if (!found) + return NULL; + goto done; + } + u = np_malloc(sizeof(*u) + 256); + pthread_mutex_init(&u->lock, NULL); + u->uname = NULL; + + n = u->uid % usercache.hsize; + u->next = usercache.htable[n]; + usercache.htable[n] = u; + + pthread_mutex_lock(&u->lock); + pthread_mutex_unlock(&usercache.lock); + bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); if (bufsize < 256) bufsize = 256; buf = np_malloc(bufsize); - if (!buf) - return NULL; - i = getpwnam_r(uname, &pw, buf, bufsize, &pwp); if (i) { np_uerror(i); free(buf); + pthread_mutex_unlock(&u->lock); return NULL; } - u = np_malloc(sizeof(*u) + strlen(pw.pw_name) + 1); - if (!u) { - free(buf); - return NULL; - } - - pthread_mutex_init(&u->lock, NULL); u->refcount = 1; u->upool = up; u->uid = pw.pw_uid; u->uname = (char *)u + sizeof(*u); - strcpy(u->uname, pw.pw_name); + strncpy(u->uname, pw.pw_name, 256); u->dfltgroup = (*up->gid2group)(up, pw.pw_gid); u->ngroups = 0; u->groups = NULL; np_init_user_groups(u); free(buf); + pthread_mutex_unlock(&u->lock); - pthread_mutex_lock(&usercache.lock); - n = u->uid % usercache.hsize; - u->next = usercache.htable[n]; - usercache.htable[n] = u; - pthread_mutex_unlock(&usercache.lock); - done: np_user_incref(u); return u; @@ -162,7 +172,7 @@ static Npuser * np_unix_uid2user(Npuserpool *up, u32 uid) { - int n, i; + int n, i, found; Npuser *u; struct passwd pw, *pwp; int bufsize; @@ -172,54 +182,62 @@ if (!usercache.init) initusercache(); + found = 0; n = uid % usercache.hsize; for(u = usercache.htable[n]; u != NULL; u = u->next) - if (u->uid == uid) + if (u->uid == uid) { + found = 1; break; - pthread_mutex_unlock(&usercache.lock); + } - if (u) + if (found) { + pthread_mutex_unlock(&usercache.lock); + pthread_mutex_lock(&u->lock); + found = u->uname != NULL; + pthread_mutex_unlock(&u->lock); + + if (!found) + return NULL; + goto done; + } + u = np_malloc(sizeof(*u) + 256); + pthread_mutex_init(&u->lock, NULL); + u->uname = NULL; + + u->next = usercache.htable[n]; + usercache.htable[n] = u; + + pthread_mutex_lock(&u->lock); + pthread_mutex_unlock(&usercache.lock); + bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); if (bufsize < 256) bufsize = 256; buf = np_malloc(bufsize); - if (!buf) - return NULL; - i = getpwuid_r(uid, &pw, buf, bufsize, &pwp); if (i) { np_uerror(i); free(buf); + pthread_mutex_unlock(&u->lock); return NULL; } - u = np_malloc(sizeof(*u) + strlen(pw.pw_name) + 1); - if (!u) { - free(buf); - return NULL; - } - - pthread_mutex_init(&u->lock, NULL); u->refcount = 1; u->upool = up; u->uid = uid; u->uname = (char *)u + sizeof(*u); - strcpy(u->uname, pw.pw_name); + strncpy(u->uname, pw.pw_name, 256); u->dfltgroup = up->gid2group(up, pw.pw_gid); u->ngroups = 0; u->groups = NULL; np_init_user_groups(u); free(buf); + pthread_mutex_unlock(&u->lock); - pthread_mutex_lock(&usercache.lock); - u->next = usercache.htable[n]; - usercache.htable[n] = u; - pthread_mutex_unlock(&usercache.lock); - done: np_user_incref(u); return u; @@ -228,7 +246,7 @@ static Npgroup * np_unix_gname2group(Npuserpool *up, char *gname) { - int i, n, bufsize; + int i, bufsize, found; Npgroup *g; struct group grp, *pgrp; char *buf; @@ -237,48 +255,52 @@ if (!groupcache.init) initgroupcache(); + found = 0; for(i = 0; i < groupcache.hsize; i++) for(g = groupcache.htable[i]; g != NULL; g = g->next) - if (strcmp(g->gname, gname) == 0) + if (strcmp(g->gname, gname) == 0) { + found = 1; break; - pthread_mutex_unlock(&groupcache.lock); + } - if (g) + if (found) { + pthread_mutex_unlock(&groupcache.lock); + pthread_mutex_lock(&g->lock); + found = g->gname != NULL; + pthread_mutex_unlock(&g->lock); + + if (!found) + return NULL; + goto done; + } + g = np_malloc(sizeof(*g) + 256); + pthread_mutex_init(&g->lock, NULL); + g->gname = NULL; + pthread_mutex_lock(&g->lock); + pthread_mutex_unlock(&groupcache.lock); + bufsize = sysconf(_SC_GETGR_R_SIZE_MAX); if (bufsize < 256) bufsize = 256; buf = np_malloc(bufsize); - if (!buf) - return NULL; - i = getgrnam_r(gname, &grp, buf, bufsize, &pgrp); if (i) { np_uerror(i); free(buf); + pthread_mutex_unlock(&g->lock); return NULL; } - g = np_malloc(sizeof(*g) + strlen(grp.gr_name) + 1); - if (!g) { - free(buf); - return NULL; - } - g->refcount = 1; g->upool = up; g->gid = grp.gr_gid; g->gname = (char *)g + sizeof(*g); - strcpy(g->gname, grp.gr_name); + strncpy(g->gname, grp.gr_name, 256); - pthread_mutex_lock(&groupcache.lock); - n = g->gid % groupcache.hsize; - g->next = groupcache.htable[n]; - groupcache.htable[n] = g; - pthread_mutex_unlock(&groupcache.lock); - + pthread_mutex_unlock(&g->lock); free(buf); done: @@ -289,7 +311,7 @@ static Npgroup * np_unix_gid2group(Npuserpool *up, u32 gid) { - int n, err; + int n, err, found; Npgroup *g; struct group grp, *pgrp; int bufsize; @@ -300,47 +322,50 @@ initgroupcache(); n = gid % groupcache.hsize; + found = 0; for(g = groupcache.htable[n]; g != NULL; g = g->next) - if (g->gid == gid) + if (g->gid == gid) { + found = 1; break; - pthread_mutex_unlock(&groupcache.lock); + } + if (found) { + pthread_mutex_unlock(&groupcache.lock); + pthread_mutex_lock(&g->lock); + found = g->gname != NULL; + pthread_mutex_unlock(&g->lock); - if (g) + if (!found) + return NULL; + goto done; + } + g = np_malloc(sizeof(*g) + 256); + pthread_mutex_init(&g->lock, NULL); + g->gname = NULL; + pthread_mutex_lock(&g->lock); + pthread_mutex_unlock(&groupcache.lock); + bufsize = sysconf(_SC_GETGR_R_SIZE_MAX); if (bufsize < 256) bufsize = 256; buf = np_malloc(bufsize); - if (!buf) - return NULL; - err = getgrgid_r(gid, &grp, buf, bufsize, &pgrp); if (err) { np_uerror(err); free(buf); + pthread_mutex_unlock(&g->lock); return NULL; } - g = np_malloc(sizeof(*g) + strlen(grp.gr_name) + 1); - if (!g) { - free(buf); - return NULL; - } - - pthread_mutex_init(&g->lock, NULL); g->refcount = 1; g->upool = up; g->gid = grp.gr_gid; g->gname = (char *)g + sizeof(*g); - strcpy(g->gname, grp.gr_name); + strncpy(g->gname, grp.gr_name, 256); - pthread_mutex_lock(&groupcache.lock); - g->next = groupcache.htable[n]; - groupcache.htable[n] = g; - pthread_mutex_unlock(&groupcache.lock); - + pthread_mutex_unlock(&g->lock); free(buf); done: @@ -353,15 +378,19 @@ { int i; - if (!u->groups && np_init_user_groups(u)<0) + pthread_mutex_lock(&u->lock); + if (!u->groups && np_init_user_groups(u) < 0) { + pthread_mutex_unlock(&u->lock); return -1; + } for(i = 0; i < u->ngroups; i++) { if (g == u->groups[i]) - return 1; + break; } + pthread_mutex_unlock(&u->lock); - return 0; + return i < u->ngroups; } static void @@ -386,6 +415,7 @@ free(u->groups); u->ngroups = 0; + pthread_mutex_lock(&grentlock); setgrent(); if(u->dfltgroup) { @@ -404,6 +434,7 @@ } endgrent(); + pthread_mutex_unlock(&grentlock); grps = np_malloc(sizeof(*grps) * n); if (!grps) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |