Initial IBM OpenAFS 1.0 tree
[openafs.git] / src / WINNT / afsd / cm_utils.c
1 /* 
2  * Copyright (C) 1998, 1989 Transarc Corporation - All rights reserved
3  *
4  * (C) COPYRIGHT IBM CORPORATION 1987, 1988
5  * LICENSED MATERIALS - PROPERTY OF IBM
6  *
7  *
8  */
9
10 #include <afs/param.h>
11 #include <afs/stds.h>
12
13 #include <windows.h>
14 #include <string.h>
15 #include <malloc.h>
16 #include <winsock2.h>
17
18 #include <osi.h>
19 #include <rx/rx.h>
20
21 #include "afsd.h"
22
23 static osi_once_t cm_utilsOnce;
24
25 osi_rwlock_t cm_utilsLock;
26
27 cm_space_t *cm_spaceListp;
28
29 long cm_MapRPCError(long error, cm_req_t *reqp)
30 {
31         if (error == 0) return 0;
32
33         /* If we had to stop retrying, report our saved error code. */
34         if (reqp && error == CM_ERROR_TIMEDOUT) {
35                 if (reqp->accessError)
36                         return reqp->accessError;
37                 if (reqp->volumeError)
38                         return reqp->volumeError;
39                 if (reqp->rpcError)
40                         return reqp->rpcError;
41                 return error;
42         }
43
44         if (error < 0) error = CM_ERROR_TIMEDOUT;
45         else if (error == 30) error = CM_ERROR_READONLY;
46         else if (error == 13) error = CM_ERROR_NOACCESS;
47         else if (error == 18) error = CM_ERROR_CROSSDEVLINK;
48         else if (error == 17) error = CM_ERROR_EXISTS;
49         else if (error == 20) error = CM_ERROR_NOTDIR;
50         else if (error == 2) error = CM_ERROR_NOSUCHFILE;
51         else if (error == 11            /* EAGAIN, most servers */
52                  || error == 35)        /* EAGAIN, Digital UNIX */
53                         error = CM_ERROR_WOULDBLOCK;
54         else if (error == VDISKFULL
55                  || error == 28)        /* ENOSPC */ 
56                         error = CM_ERROR_SPACE;
57         else if (error == VOVERQUOTA
58                  || error == 49         /* EDQUOT on Solaris */
59                  || error == 88         /* EDQUOT on AIX */
60                  || error == 69         /* EDQUOT on Digital UNIX and HPUX */
61                  || error == 122        /* EDQUOT on Linux */
62                  || error == 1133)      /* EDQUOT on Irix  */
63                         error = CM_ERROR_QUOTA;
64         else if (error == VNOVNODE) error = CM_ERROR_BADFD;
65         return error;
66 }
67
68 long cm_MapRPCErrorRmdir(long error, cm_req_t *reqp)
69 {
70         if (error == 0) return 0;
71
72         /* If we had to stop retrying, report our saved error code. */
73         if (reqp && error == CM_ERROR_TIMEDOUT) {
74                 if (reqp->accessError)
75                         return reqp->accessError;
76                 if (reqp->volumeError)
77                         return reqp->volumeError;
78                 if (reqp->rpcError)
79                         return reqp->rpcError;
80                 return error;
81         }
82
83         if (error < 0) error = CM_ERROR_TIMEDOUT;
84         else if (error == 30) error = CM_ERROR_READONLY;
85         else if (error == 20) error = CM_ERROR_NOTDIR;
86         else if (error == 13) error = CM_ERROR_NOACCESS;
87         else if (error == 2) error = CM_ERROR_NOSUCHFILE;
88         else if (error == 17            /* AIX */
89                  || error == 66         /* SunOS 4, Digital UNIX */
90                  || error == 93         /* Solaris 2, IRIX */
91                  || error == 247)       /* HP/UX */
92                 error = CM_ERROR_NOTEMPTY;
93         return error;
94 }
95
96 long cm_MapVLRPCError(long error, cm_req_t *reqp)
97 {
98         if (error == 0) return 0;
99
100         /* If we had to stop retrying, report our saved error code. */
101         if (reqp && error == CM_ERROR_TIMEDOUT) {
102                 if (reqp->accessError)
103                         return reqp->accessError;
104                 if (reqp->volumeError)
105                         return reqp->volumeError;
106                 if (reqp->rpcError)
107                         return reqp->rpcError;
108                 return error;
109         }
110
111         if (error < 0) error = CM_ERROR_TIMEDOUT;
112         else if (error == VL_NOENT) error = CM_ERROR_NOSUCHVOLUME;
113         return error;
114 }
115
116 cm_space_t *cm_GetSpace(void)
117 {
118         cm_space_t *tsp;
119
120         if (osi_Once(&cm_utilsOnce)) {
121                 lock_InitializeRWLock(&cm_utilsLock, "cm_utilsLock");
122                 osi_EndOnce(&cm_utilsOnce);
123         }
124         
125         lock_ObtainWrite(&cm_utilsLock);
126         if (tsp = cm_spaceListp) {
127                 cm_spaceListp = tsp->nextp;
128         }
129         else tsp = (cm_space_t *) malloc(sizeof(cm_space_t));
130         lock_ReleaseWrite(&cm_utilsLock);
131         
132         return tsp;
133 }
134
135 void cm_FreeSpace(cm_space_t *tsp)
136 {
137         lock_ObtainWrite(&cm_utilsLock);
138         tsp->nextp = cm_spaceListp;
139         cm_spaceListp = tsp;
140         lock_ReleaseWrite(&cm_utilsLock);
141 }