windows-pcache-20050310
[openafs.git] / src / WINNT / afsd / cm_utils.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afs/param.h>
11 #include <afs/stds.h>
12
13 #ifndef DJGPP
14 #include <windows.h>
15 #include <winsock2.h>
16 #endif /* !DJGPP */
17 #include <string.h>
18 #include <malloc.h>
19
20 #include <osi.h>
21 #include <rx/rx.h>
22
23 #include "afsd.h"
24
25 static osi_once_t cm_utilsOnce;
26
27 osi_rwlock_t cm_utilsLock;
28
29 cm_space_t *cm_spaceListp;
30
31 long cm_MapRPCError(long error, cm_req_t *reqp)
32 {
33     if (error == 0) 
34         return 0;
35
36     /* If we had to stop retrying, report our saved error code. */
37     if (reqp && error == CM_ERROR_TIMEDOUT) {
38         if (reqp->accessError)
39             return reqp->accessError;
40         if (reqp->volumeError)
41             return reqp->volumeError;
42         if (reqp->rpcError)
43             return reqp->rpcError;
44         return error;
45     }
46
47     if (error < 0) 
48         error = CM_ERROR_TIMEDOUT;
49     else if (error == 30) 
50         error = CM_ERROR_READONLY;
51     else if (error == 13) 
52         error = CM_ERROR_NOACCESS;
53     else if (error == 18) 
54         error = CM_ERROR_CROSSDEVLINK;
55     else if (error == 17) 
56         error = CM_ERROR_EXISTS;
57     else if (error == 20) 
58         error = CM_ERROR_NOTDIR;
59     else if (error == 2) 
60         error = CM_ERROR_NOSUCHFILE;
61     else if (error == 11                /* EAGAIN, most servers */
62              || error == 35)    /* EAGAIN, Digital UNIX */
63         error = CM_ERROR_WOULDBLOCK;
64     else if (error == VDISKFULL
65               || error == 28)        /* ENOSPC */ 
66         error = CM_ERROR_SPACE;
67     else if (error == VOVERQUOTA
68               || error == 49         /* EDQUOT on Solaris */
69               || error == 88            /* EDQUOT on AIX */
70               || error == 69            /* EDQUOT on Digital UNIX and HPUX */
71               || error == 122        /* EDQUOT on Linux */
72               || error == 1133)      /* EDQUOT on Irix  */
73         error = CM_ERROR_QUOTA;
74     else if (error == VNOVNODE) 
75         error = CM_ERROR_BADFD;
76     else if (error == 21)
77         return CM_ERROR_ISDIR;
78     return error;
79 }
80
81 long cm_MapRPCErrorRmdir(long error, cm_req_t *reqp)
82 {
83         if (error == 0) return 0;
84
85         /* If we had to stop retrying, report our saved error code. */
86         if (reqp && error == CM_ERROR_TIMEDOUT) {
87             if (reqp->accessError)
88                 return reqp->accessError;
89             if (reqp->volumeError)
90                 return reqp->volumeError;
91             if (reqp->rpcError)
92                 return reqp->rpcError;
93             return error;
94         }
95
96         if (error < 0) 
97             error = CM_ERROR_TIMEDOUT;
98         else if (error == 30) 
99             error = CM_ERROR_READONLY;
100         else if (error == 20) 
101             error = CM_ERROR_NOTDIR;
102         else if (error == 13) 
103             error = CM_ERROR_NOACCESS;
104         else if (error == 2) 
105             error = CM_ERROR_NOSUCHFILE;
106         else if (error == 17            /* AIX */
107                  || error == 66         /* SunOS 4, Digital UNIX */
108                  || error == 93         /* Solaris 2, IRIX */
109                  || error == 247)       /* HP/UX */
110             error = CM_ERROR_NOTEMPTY;
111         return error;
112 }
113
114 long cm_MapVLRPCError(long error, cm_req_t *reqp)
115 {
116         if (error == 0) return 0;
117
118         /* If we had to stop retrying, report our saved error code. */
119         if (reqp && error == CM_ERROR_TIMEDOUT) {
120                 if (reqp->accessError)
121                         return reqp->accessError;
122                 if (reqp->volumeError)
123                         return reqp->volumeError;
124                 if (reqp->rpcError)
125                         return reqp->rpcError;
126                 return error;
127         }
128
129         if (error < 0) 
130             error = CM_ERROR_TIMEDOUT;
131         else if (error == VL_NOENT) 
132             error = CM_ERROR_NOSUCHVOLUME;
133         return error;
134 }
135
136 cm_space_t *cm_GetSpace(void)
137 {
138         cm_space_t *tsp;
139
140         if (osi_Once(&cm_utilsOnce)) {
141                 lock_InitializeRWLock(&cm_utilsLock, "cm_utilsLock");
142                 osi_EndOnce(&cm_utilsOnce);
143         }
144         
145         lock_ObtainWrite(&cm_utilsLock);
146         if (tsp = cm_spaceListp) {
147                 cm_spaceListp = tsp->nextp;
148         }
149         else tsp = (cm_space_t *) malloc(sizeof(cm_space_t));
150         (void) memset(tsp, 0, sizeof(cm_space_t));
151         lock_ReleaseWrite(&cm_utilsLock);
152         
153         return tsp;
154 }
155
156 void cm_FreeSpace(cm_space_t *tsp)
157 {
158         lock_ObtainWrite(&cm_utilsLock);
159         tsp->nextp = cm_spaceListp;
160         cm_spaceListp = tsp;
161         lock_ReleaseWrite(&cm_utilsLock);
162 }