bozo: Introduce bnode_Wait()
[openafs.git] / src / vol / physio.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 /*
11         System:         VICE-TWO
12         Module:         physio.c
13         Institution:    The Information Technology Center, Carnegie-Mellon University
14
15  */
16
17 #include <afsconfig.h>
18 #include <afs/param.h>
19
20 #include <roken.h>
21
22 #ifdef HAVE_SYS_FILE_H
23 #include <sys/file.h>
24 #endif
25
26 #include <rx/xdr.h>
27 #include <afs/afsint.h>
28 #include <afs/afssyscalls.h>
29 #include "nfs.h"
30 #include "ihandle.h"
31 #include "salvage.h"
32 #include <afs/dir.h>
33 #include "vol_internal.h"
34
35 /*
36  * Read the specified page from a directory object
37  *
38  * \parm[in] file       handle to the directory object
39  * \parm[in] block      requested page from the directory object
40  * \parm[out] data      buffer for the returned page
41  * \parm[out] physerr   (optional) pointer to errno if physical error
42  *
43  * \retval 0    success
44  * \retval EIO  physical or logical error;
45  *              if physerr is supplied by caller, it will be set to:
46  *                  0       for logical errors
47  *                  errno   for physical errors
48  */
49 int
50 ReallyRead(DirHandle *file, int block, char *data, int *physerr)
51 {
52     FdHandle_t *fdP;
53     int code = 0;
54     int saverr = 0;
55     ssize_t nBytes;
56
57     errno = 0;
58     fdP = IH_OPEN(file->dirh_handle);
59     if (fdP == NULL) {
60         saverr = errno;
61         code = EIO;
62         goto done;
63     }
64     nBytes = FDH_PREAD(fdP, data, (afs_fsize_t) AFS_PAGESIZE,
65                        ((afs_foff_t)block) * AFS_PAGESIZE);
66     if (nBytes != AFS_PAGESIZE) {
67         if (nBytes < 0)
68             saverr = errno;
69         else
70             saverr = 0;     /* logical error: short read */
71         code = EIO;
72         FDH_REALLYCLOSE(fdP);
73         goto done;
74     }
75     FDH_CLOSE(fdP);
76
77  done:
78     if (physerr != NULL)
79         *physerr = saverr;
80     return code;
81 }
82
83 /* returns 0 on success, errno on failure */
84 int
85 ReallyWrite(DirHandle * file, int block, char *data)
86 {
87     FdHandle_t *fdP;
88     int code;
89     ssize_t nBytes;
90
91     errno = 0;
92
93     fdP = IH_OPEN(file->dirh_handle);
94     if (fdP == NULL) {
95         code = errno;
96         return code;
97     }
98     nBytes = FDH_PWRITE(fdP, data, (afs_fsize_t) AFS_PAGESIZE,
99                         ((afs_foff_t)block) * AFS_PAGESIZE);
100     if (nBytes != AFS_PAGESIZE) {
101         if (nBytes < 0)
102             code = errno;
103         else
104             code = EIO;
105         FDH_REALLYCLOSE(fdP);
106         return code;
107     }
108     FDH_CLOSE(fdP);
109     *(file->volumeChanged) = 1;
110     return 0;
111 }
112
113 /* SetSalvageDirHandle:
114  * Create a handle to a directory entry and reference it (IH_INIT).
115  * The handle needs to be dereferenced with the FidZap() routine.
116  */
117 void
118 SetSalvageDirHandle(DirHandle * dir, VolumeId volume, Device device,
119                     Inode inode, int *volumeChanged)
120 {
121     static int SalvageCacheCheck = 1;
122     memset(dir, 0, sizeof(DirHandle));
123
124     dir->dirh_device = device;
125     dir->dirh_volume = volume;
126     dir->dirh_inode = inode;
127     IH_INIT(dir->dirh_handle, device, volume, inode);
128     /* Always re-read for a new dirhandle */
129     dir->dirh_cacheCheck = SalvageCacheCheck++;
130     dir->volumeChanged = volumeChanged;
131 }
132
133 void
134 FidZap(DirHandle * file)
135 {
136     IH_RELEASE(file->dirh_handle);
137     memset(file, 0, sizeof(DirHandle));
138 }
139
140 void
141 FidZero(DirHandle * file)
142 {
143     memset(file, 0, sizeof(DirHandle));
144 }
145
146 int
147 FidEq(DirHandle * afile, DirHandle * bfile)
148 {
149     if (afile->dirh_volume != bfile->dirh_volume)
150         return 0;
151     if (afile->dirh_device != bfile->dirh_device)
152         return 0;
153     if (afile->dirh_cacheCheck != bfile->dirh_cacheCheck)
154         return 0;
155     if (afile->dirh_inode != bfile->dirh_inode)
156         return 0;
157     return 1;
158 }
159
160 int
161 FidVolEq(DirHandle * afile, VolumeId vid)
162 {
163     if (afile->dirh_volume != vid)
164         return 0;
165     return 1;
166 }
167
168 void
169 FidCpy(DirHandle * tofile, DirHandle * fromfile)
170 {
171     *tofile = *fromfile;
172     IH_COPY(tofile->dirh_handle, fromfile->dirh_handle);
173 }
174
175 void
176 Die(const char *msg)
177 {
178     printf("%s\n", msg);
179     osi_Panic("%s\n", msg);
180 }