windows-byte-range-locks-20050816
[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) 
84         return 0;
85
86     /* If we had to stop retrying, report our saved error code. */
87     if (reqp && error == CM_ERROR_TIMEDOUT) {
88         if (reqp->accessError)
89             return reqp->accessError;
90         if (reqp->volumeError)
91             return reqp->volumeError;
92         if (reqp->rpcError)
93             return reqp->rpcError;
94         return error;
95     }
96
97     if (error < 0) 
98         error = CM_ERROR_TIMEDOUT;
99     else if (error == 30) 
100         error = CM_ERROR_READONLY;
101     else if (error == 20) 
102         error = CM_ERROR_NOTDIR;
103     else if (error == 13) 
104         error = CM_ERROR_NOACCESS;
105     else if (error == 2) 
106         error = CM_ERROR_NOSUCHFILE;
107     else if (error == 17                /* AIX */
108               || error == 66            /* SunOS 4, Digital UNIX */
109               || error == 93            /* Solaris 2, IRIX */
110               || error == 247)  /* HP/UX */
111         error = CM_ERROR_NOTEMPTY;
112     return error;
113 }       
114
115 long cm_MapVLRPCError(long error, cm_req_t *reqp)
116 {
117         if (error == 0) return 0;
118
119         /* If we had to stop retrying, report our saved error code. */
120         if (reqp && error == CM_ERROR_TIMEDOUT) {
121                 if (reqp->accessError)
122                         return reqp->accessError;
123                 if (reqp->volumeError)
124                         return reqp->volumeError;
125                 if (reqp->rpcError)
126                         return reqp->rpcError;
127                 return error;
128         }
129
130         if (error < 0) 
131             error = CM_ERROR_TIMEDOUT;
132         else if (error == VL_NOENT) 
133             error = CM_ERROR_NOSUCHVOLUME;
134         return error;
135 }
136
137 cm_space_t *cm_GetSpace(void)
138 {
139         cm_space_t *tsp;
140
141         if (osi_Once(&cm_utilsOnce)) {
142                 lock_InitializeRWLock(&cm_utilsLock, "cm_utilsLock");
143                 osi_EndOnce(&cm_utilsOnce);
144         }
145         
146         lock_ObtainWrite(&cm_utilsLock);
147         if (tsp = cm_spaceListp) {
148                 cm_spaceListp = tsp->nextp;
149         }
150         else tsp = (cm_space_t *) malloc(sizeof(cm_space_t));
151         (void) memset(tsp, 0, sizeof(cm_space_t));
152         lock_ReleaseWrite(&cm_utilsLock);
153         
154         return tsp;
155 }
156
157 void cm_FreeSpace(cm_space_t *tsp)
158 {
159         lock_ObtainWrite(&cm_utilsLock);
160         tsp->nextp = cm_spaceListp;
161         cm_spaceListp = tsp;
162         lock_ReleaseWrite(&cm_utilsLock);
163 }