Bug Summary

File:dviced/./../viced/afsfileprocs.c
Location:line 1305, column 3
Description:Value stored to 'rc' is never read

Annotated Source Code

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/* afs_fileprocs.c - Complete File Server request routines */
11/* */
12/* Information Technology Center */
13/* Carnegie Mellon University */
14/* */
15/* Date: 8/10/88 */
16/* */
17/* Function - A set of routines to handle the various file Server */
18/* requests; these routines are invoked by rxgen. */
19/* */
20/* ********************************************************************** */
21
22/*
23 * in Check_PermissionRights, certain privileges are afforded to the owner
24 * of the volume, or the owner of a file. Are these considered "use of
25 * privilege"?
26 */
27
28#include <afsconfig.h>
29#include <afs/param.h>
30#include <afs/stds.h>
31
32#include <roken.h>
33
34#ifdef AFS_SGI_ENV
35#undef SHARED /* XXX */
36#endif
37
38#ifdef HAVE_NET_IF_H1
39#include <net/if.h>
40#endif
41
42#ifdef HAVE_NETINET_IF_ETHER_H1
43#include <netinet/if_ether.h>
44#endif
45
46#if !defined(AFS_SGI_ENV) && defined(HAVE_SYS_MAP_H)
47#include <sys/map.h>
48#endif
49
50#ifdef HAVE_SYS_STATFS_H
51#include <sys/statfs.h>
52#endif
53
54#ifdef HAVE_SYS_LOCKF_H1
55#include <sys/lockf.h>
56#endif
57
58#ifdef HAVE_SYS_DK_H
59#include <sys/dk.h>
60#endif
61
62#ifdef AFS_HPUX_ENV
63/* included early because of name conflict on IOPEN */
64#include <sys/inode.h>
65#ifdef IOPEN
66#undef IOPEN
67#endif
68#endif /* AFS_HPUX_ENV */
69
70#include <rx/xdr.h>
71#include <afs/nfs.h>
72#include <afs/afs_assert.h>
73#include <lwp.h>
74#include <lock.h>
75#include <afs/afsint.h>
76#include <afs/vldbint.h>
77#include <afs/errors.h>
78#include <afs/ihandle.h>
79#include <afs/vnode.h>
80#include <afs/volume.h>
81#include <afs/ptclient.h>
82#include <afs/ptuser.h>
83#include <afs/prs_fs.h>
84#include <afs/acl.h>
85#include <rx/rx.h>
86#include <rx/rx_globals.h>
87
88#include <afs/cellconfig.h>
89#include <afs/keys.h>
90
91#include <afs/partition.h>
92#include "viced_prototypes.h"
93#include "viced.h"
94#include "host.h"
95#include "callback.h"
96#include <afs/unified_afs.h>
97#include <afs/audit.h>
98#include <afs/afsutil.h>
99#include <afs/dir.h>
100
101extern void SetDirHandle(DirHandle * dir, Vnode * vnode);
102extern void FidZap(DirHandle * file);
103extern void FidZero(DirHandle * file);
104
105#ifdef AFS_PTHREAD_ENV1
106pthread_mutex_t fileproc_glock_mutex;
107#endif /* AFS_PTHREAD_ENV */
108
109/* Useful local defines used by this module */
110
111#define DONTCHECK0 0
112#define MustNOTBeDIR1 1
113#define MustBeDIR2 2
114
115#define TVS_SDATA1 1
116#define TVS_SSTATUS2 2
117#define TVS_CFILE4 4
118#define TVS_SLINK8 8
119#define TVS_MKDIR0x10 0x10
120
121#define CHK_FETCH0x10 0x10
122#define CHK_FETCHDATA0x10 0x10
123#define CHK_FETCHACL0x11 0x11
124#define CHK_FETCHSTATUS0x12 0x12
125#define CHK_STOREDATA0x00 0x00
126#define CHK_STOREACL0x01 0x01
127#define CHK_STORESTATUS0x02 0x02
128
129#define OWNERREAD0400 0400
130#define OWNERWRITE0200 0200
131#define OWNEREXEC0100 0100
132#ifdef USE_GROUP_PERMS
133#define GROUPREAD 0040
134#define GROUPWRITE 0020
135#define GROUPREXEC 0010
136#endif
137
138/* The following errors were not defined in NT. They are given unique
139 * names here to avoid any potential collision.
140 */
141#define FSERR_ELOOP90 90
142#define FSERR_EOPNOTSUPP122 122
143#define FSERR_ECONNREFUSED130 130
144
145#define NOTACTIVECALL0 0
146#define ACTIVECALL1 1
147
148#define CREATE_SGUID_ADMIN_ONLY1 1
149
150extern struct afsconf_dir *confDir;
151extern afs_int32 dataVersionHigh;
152
153extern int SystemId;
154static struct AFSCallStatistics AFSCallStats;
155#if FS_STATS_DETAILED1
156struct fs_stats_FullPerfStats afs_FullPerfStats;
157extern int AnonymousID;
158#endif /* FS_STATS_DETAILED */
159#if OPENAFS_VOL_STATS1
160static const char nullString[] = "";
161#endif /* OPENAFS_VOL_STATS */
162
163struct afs_FSStats {
164 afs_int32 NothingYet;
165};
166
167struct afs_FSStats afs_fsstats;
168
169int LogLevel = 0;
170int supported = 1;
171int Console = 0;
172afs_int32 BlocksSpare = 1024; /* allow 1 MB overruns */
173afs_int32 PctSpare;
174extern afs_int32 implicitAdminRights;
175extern afs_int32 readonlyServer;
176extern int CopyOnWrite_calls, CopyOnWrite_off0, CopyOnWrite_size0;
177extern afs_fsize_t CopyOnWrite_maxsize;
178
179/*
180 * Externals used by the xstat code.
181 */
182extern VolPkgStats VStats;
183extern int CEs, CEBlocks;
184
185extern int HTs, HTBlocks;
186
187static afs_int32 FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
188 struct rx_call *Call, afs_sfsize_t Pos,
189 afs_sfsize_t Len, afs_int32 Int64Mode,
190 afs_sfsize_t * a_bytesToFetchP,
191 afs_sfsize_t * a_bytesFetchedP);
192
193static afs_int32 StoreData_RXStyle(Volume * volptr, Vnode * targetptr,
194 struct AFSFid *Fid, struct client *client,
195 struct rx_call *Call, afs_fsize_t Pos,
196 afs_fsize_t Length, afs_fsize_t FileLength,
197 int sync,
198 afs_sfsize_t * a_bytesToStoreP,
199 afs_sfsize_t * a_bytesStoredP);
200
201#ifdef AFS_SGI_XFS_IOPS_ENV
202#include <afs/xfsattrs.h>
203static int
204GetLinkCount(Volume * avp, struct stat *astat)(struct stat *astat)->st_nlink
205{
206 if (!strcmp("xfs", astat->st_fstype)) {
207 return (astat->st_mode & AFS_XFS_MODE_LINK_MASK);
208 } else
209 return astat->st_nlink;
210}
211#else
212#define GetLinkCount(V, S)(S)->st_nlink (S)->st_nlink
213#endif
214
215afs_int32
216SpareComp(Volume * avolp)
217{
218 afs_int32 temp;
219
220 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 220), 0));
;
221 if (PctSpare) {
222 temp = V_maxquota(avolp)((avolp)->header->diskstuff.maxquota);
223 if (temp == 0) {
224 /* no matter; doesn't check in this case */
225 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 225), 0));
;
226 return 0;
227 }
228 temp = (temp * PctSpare) / 100;
229 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 229), 0));
;
230 return temp;
231 } else {
232 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 232), 0));
;
233 return BlocksSpare;
234 }
235
236} /*SpareComp */
237
238/*
239 * Set the volume synchronization parameter for this volume. If it changes,
240 * the Cache Manager knows that the volume must be purged from the stat cache.
241 */
242static void
243SetVolumeSync(struct AFSVolSync *async, Volume * avol)
244{
245 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 245), 0));
;
246 /* date volume instance was created */
247 if (async) {
248 if (avol)
249 async->spare1 = avol->header->diskstuff.creationDate;
250 else
251 async->spare1 = 0;
252 async->spare2 = 0;
253 async->spare3 = 0;
254 async->spare4 = 0;
255 async->spare5 = 0;
256 async->spare6 = 0;
257 }
258 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 258), 0));
;
259} /*SetVolumeSync */
260
261/**
262 * Verify that the on-disk size for a vnode matches the length in the vnode
263 * index.
264 *
265 * @param[in] vp Volume pointer
266 * @param[in] vnp Vnode pointer
267 * @param[in] alen Size of the vnode on disk, if known. If unknown, give -1,
268 * and CheckLength itself will determine the on-disk size.
269 *
270 * @return operation status
271 * @retval 0 lengths match
272 * @retval nonzero Error; either the lengths do not match or there was an
273 * error determining the on-disk size. The volume should be
274 * taken offline and salvaged.
275 */
276static int
277CheckLength(struct Volume *vp, struct Vnode *vnp, afs_sfsize_t alen)
278{
279 afs_sfsize_t vlen;
280 VN_GET_LEN(vlen, vnp)(vlen) = ((afs_int64)((vnp)->disk.vn_length_hi) << 32
) | ((vnp)->disk.length);
;
281
282 if (alen < 0) {
283 FdHandle_t *fdP;
284
285 fdP = IH_OPEN(vnp->handle)ih_open(vnp->handle);
286 if (fdP == NULL((void *)0)) {
287 ViceLog(0, ("CheckLength: cannot open inode for fid %lu.%lu.%lu\n",do { if ((0) <= LogLevel) (FSLog ("CheckLength: cannot open inode for fid %lu.%lu.%lu\n"
, afs_printable_uint32_lu(vp->hashid), afs_printable_uint32_lu
(((vnp)->vnodeNumber)), afs_printable_uint32_lu(vnp->disk
.uniquifier))); } while (0)
288 afs_printable_uint32_lu(vp->hashid),do { if ((0) <= LogLevel) (FSLog ("CheckLength: cannot open inode for fid %lu.%lu.%lu\n"
, afs_printable_uint32_lu(vp->hashid), afs_printable_uint32_lu
(((vnp)->vnodeNumber)), afs_printable_uint32_lu(vnp->disk
.uniquifier))); } while (0)
289 afs_printable_uint32_lu(Vn_id(vnp)),do { if ((0) <= LogLevel) (FSLog ("CheckLength: cannot open inode for fid %lu.%lu.%lu\n"
, afs_printable_uint32_lu(vp->hashid), afs_printable_uint32_lu
(((vnp)->vnodeNumber)), afs_printable_uint32_lu(vnp->disk
.uniquifier))); } while (0)
290 afs_printable_uint32_lu(vnp->disk.uniquifier)))do { if ((0) <= LogLevel) (FSLog ("CheckLength: cannot open inode for fid %lu.%lu.%lu\n"
, afs_printable_uint32_lu(vp->hashid), afs_printable_uint32_lu
(((vnp)->vnodeNumber)), afs_printable_uint32_lu(vnp->disk
.uniquifier))); } while (0)
;
291 return -1;
292 }
293 alen = FDH_SIZE(fdP)ih_size((fdP)->fd_fd);
294 FDH_CLOSE(fdP)(fd_close(fdP), (fdP)=((void *)0), 0);
295 if (alen < 0) {
296 afs_int64 alen64 = alen;
297 ViceLog(0, ("CheckLength: cannot get size for inode for fid "do { if ((0) <= LogLevel) (FSLog ("CheckLength: cannot get size for inode for fid "
"%lu.%lu.%lu; FDH_SIZE returned %" "lld" "\n", afs_printable_uint32_lu
(vp->hashid), afs_printable_uint32_lu(((vnp)->vnodeNumber
)), afs_printable_uint32_lu(vnp->disk.uniquifier), alen64)
); } while (0)
298 "%lu.%lu.%lu; FDH_SIZE returned %" AFS_INT64_FMT "\n",do { if ((0) <= LogLevel) (FSLog ("CheckLength: cannot get size for inode for fid "
"%lu.%lu.%lu; FDH_SIZE returned %" "lld" "\n", afs_printable_uint32_lu
(vp->hashid), afs_printable_uint32_lu(((vnp)->vnodeNumber
)), afs_printable_uint32_lu(vnp->disk.uniquifier), alen64)
); } while (0)
299 afs_printable_uint32_lu(vp->hashid),do { if ((0) <= LogLevel) (FSLog ("CheckLength: cannot get size for inode for fid "
"%lu.%lu.%lu; FDH_SIZE returned %" "lld" "\n", afs_printable_uint32_lu
(vp->hashid), afs_printable_uint32_lu(((vnp)->vnodeNumber
)), afs_printable_uint32_lu(vnp->disk.uniquifier), alen64)
); } while (0)
300 afs_printable_uint32_lu(Vn_id(vnp)),do { if ((0) <= LogLevel) (FSLog ("CheckLength: cannot get size for inode for fid "
"%lu.%lu.%lu; FDH_SIZE returned %" "lld" "\n", afs_printable_uint32_lu
(vp->hashid), afs_printable_uint32_lu(((vnp)->vnodeNumber
)), afs_printable_uint32_lu(vnp->disk.uniquifier), alen64)
); } while (0)
301 afs_printable_uint32_lu(vnp->disk.uniquifier),do { if ((0) <= LogLevel) (FSLog ("CheckLength: cannot get size for inode for fid "
"%lu.%lu.%lu; FDH_SIZE returned %" "lld" "\n", afs_printable_uint32_lu
(vp->hashid), afs_printable_uint32_lu(((vnp)->vnodeNumber
)), afs_printable_uint32_lu(vnp->disk.uniquifier), alen64)
); } while (0)
302 alen64))do { if ((0) <= LogLevel) (FSLog ("CheckLength: cannot get size for inode for fid "
"%lu.%lu.%lu; FDH_SIZE returned %" "lld" "\n", afs_printable_uint32_lu
(vp->hashid), afs_printable_uint32_lu(((vnp)->vnodeNumber
)), afs_printable_uint32_lu(vnp->disk.uniquifier), alen64)
); } while (0)
;
303 return -1;
304 }
305 }
306
307 if (alen != vlen) {
308 afs_int64 alen64 = alen, vlen64 = vlen;
309 ViceLog(0, ("Fid %lu.%lu.%lu has inconsistent length (index "do { if ((0) <= LogLevel) (FSLog ("Fid %lu.%lu.%lu has inconsistent length (index "
"%lld inode %lld ); volume must be salvaged\n", afs_printable_uint32_lu
(vp->hashid), afs_printable_uint32_lu(((vnp)->vnodeNumber
)), afs_printable_uint32_lu(vnp->disk.uniquifier), vlen64,
alen64)); } while (0)
310 "%lld inode %lld ); volume must be salvaged\n",do { if ((0) <= LogLevel) (FSLog ("Fid %lu.%lu.%lu has inconsistent length (index "
"%lld inode %lld ); volume must be salvaged\n", afs_printable_uint32_lu
(vp->hashid), afs_printable_uint32_lu(((vnp)->vnodeNumber
)), afs_printable_uint32_lu(vnp->disk.uniquifier), vlen64,
alen64)); } while (0)
311 afs_printable_uint32_lu(vp->hashid),do { if ((0) <= LogLevel) (FSLog ("Fid %lu.%lu.%lu has inconsistent length (index "
"%lld inode %lld ); volume must be salvaged\n", afs_printable_uint32_lu
(vp->hashid), afs_printable_uint32_lu(((vnp)->vnodeNumber
)), afs_printable_uint32_lu(vnp->disk.uniquifier), vlen64,
alen64)); } while (0)
312 afs_printable_uint32_lu(Vn_id(vnp)),do { if ((0) <= LogLevel) (FSLog ("Fid %lu.%lu.%lu has inconsistent length (index "
"%lld inode %lld ); volume must be salvaged\n", afs_printable_uint32_lu
(vp->hashid), afs_printable_uint32_lu(((vnp)->vnodeNumber
)), afs_printable_uint32_lu(vnp->disk.uniquifier), vlen64,
alen64)); } while (0)
313 afs_printable_uint32_lu(vnp->disk.uniquifier),do { if ((0) <= LogLevel) (FSLog ("Fid %lu.%lu.%lu has inconsistent length (index "
"%lld inode %lld ); volume must be salvaged\n", afs_printable_uint32_lu
(vp->hashid), afs_printable_uint32_lu(((vnp)->vnodeNumber
)), afs_printable_uint32_lu(vnp->disk.uniquifier), vlen64,
alen64)); } while (0)
314 vlen64, alen64))do { if ((0) <= LogLevel) (FSLog ("Fid %lu.%lu.%lu has inconsistent length (index "
"%lld inode %lld ); volume must be salvaged\n", afs_printable_uint32_lu
(vp->hashid), afs_printable_uint32_lu(((vnp)->vnodeNumber
)), afs_printable_uint32_lu(vnp->disk.uniquifier), vlen64,
alen64)); } while (0)
;
315 return -1;
316 }
317 return 0;
318}
319
320/*
321 * Note that this function always returns a held host, so
322 * that CallPostamble can block without the host's disappearing.
323 * Call returns rx connection in passed in *tconn
324 */
325static int
326CallPreamble(struct rx_call *acall, int activecall,
327 struct rx_connection **tconn, struct host **ahostp)
328{
329 struct host *thost;
330 struct client *tclient;
331 int retry_flag = 1;
332 int code = 0;
333 char hoststr[16], hoststr2[16];
334#ifdef AFS_PTHREAD_ENV1
335 struct ubik_client *uclient;
336#endif
337 *ahostp = NULL((void *)0);
338
339 if (!tconn) {
340 ViceLog(0, ("CallPreamble: unexpected null tconn!\n"))do { if ((0) <= LogLevel) (FSLog ("CallPreamble: unexpected null tconn!\n"
)); } while (0)
;
341 return -1;
342 }
343 *tconn = rx_ConnectionOf(acall)((acall)->conn);
344
345 H_LOCK(void)((pthread_mutex_lock(&host_glock_mutex) == 0) || (osi_AssertFailU
("pthread_mutex_lock(&host_glock_mutex) == 0", "./../viced/afsfileprocs.c"
, 345), 0));
;
346 retry:
347 tclient = h_FindClient_r(*tconn);
348 if (!tclient) {
349 ViceLog(0, ("CallPreamble: Couldn't get CPS. Too many lockers\n"))do { if ((0) <= LogLevel) (FSLog ("CallPreamble: Couldn't get CPS. Too many lockers\n"
)); } while (0)
;
350 H_UNLOCK(void)((pthread_mutex_unlock(&host_glock_mutex) == 0) || (
osi_AssertFailU("pthread_mutex_unlock(&host_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 350), 0));
;
351 return VBUSY110;
352 }
353 thost = tclient->host;
354 if (tclient->prfail == 1) { /* couldn't get the CPS */
355 if (!retry_flag) {
356 h_ReleaseClient_r(tclient);
357 h_Release_r(thost)do { do { --((thost)->refCount); } while (0); if (((thost)
->refCount < 1) && (((thost)->hostFlags &
0x10) || ((thost)->hostFlags & 0x20))) h_TossStuff_r(
(thost)); } while(0)
;
358 ViceLog(0, ("CallPreamble: Couldn't get CPS. Fail\n"))do { if ((0) <= LogLevel) (FSLog ("CallPreamble: Couldn't get CPS. Fail\n"
)); } while (0)
;
359 H_UNLOCK(void)((pthread_mutex_unlock(&host_glock_mutex) == 0) || (
osi_AssertFailU("pthread_mutex_unlock(&host_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 359), 0));
;
360 return -1001;
361 }
362 retry_flag = 0; /* Retry once */
363
364 /* Take down the old connection and re-read the key file */
365 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("CallPreamble: Couldn't get CPS. Reconnect to ptserver\n"
)); } while (0)
366 ("CallPreamble: Couldn't get CPS. Reconnect to ptserver\n"))do { if ((0) <= LogLevel) (FSLog ("CallPreamble: Couldn't get CPS. Reconnect to ptserver\n"
)); } while (0)
;
367#ifdef AFS_PTHREAD_ENV1
368 uclient = (struct ubik_client *)pthread_getspecific(viced_uclient_key);
369
370 /* Is it still necessary to drop this? We hit the net, we should... */
371 H_UNLOCK(void)((pthread_mutex_unlock(&host_glock_mutex) == 0) || (
osi_AssertFailU("pthread_mutex_unlock(&host_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 371), 0));
;
372 if (uclient) {
373 hpr_End(uclient);
374 uclient = NULL((void *)0);
375 }
376 code = hpr_Initialize(&uclient);
377
378 if (!code)
379 osi_Assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0)(void)((pthread_setspecific(viced_uclient_key, (void *)uclient
) == 0) || (osi_AssertFailU("pthread_setspecific(viced_uclient_key, (void *)uclient) == 0"
, "./../viced/afsfileprocs.c", 379), 0))
;
380 H_LOCK(void)((pthread_mutex_lock(&host_glock_mutex) == 0) || (osi_AssertFailU
("pthread_mutex_lock(&host_glock_mutex) == 0", "./../viced/afsfileprocs.c"
, 380), 0));
;
381#else
382 code = pr_Initialize(2, AFSDIR_SERVER_ETC_DIRPATHgetDirPath(AFSDIR_SERVER_ETC_DIRPATH_ID), 0);
383#endif
384 if (code) {
385 h_ReleaseClient_r(tclient);
386 h_Release_r(thost)do { do { --((thost)->refCount); } while (0); if (((thost)
->refCount < 1) && (((thost)->hostFlags &
0x10) || ((thost)->hostFlags & 0x20))) h_TossStuff_r(
(thost)); } while(0)
;
387 H_UNLOCK(void)((pthread_mutex_unlock(&host_glock_mutex) == 0) || (
osi_AssertFailU("pthread_mutex_unlock(&host_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 387), 0));
;
388 ViceLog(0, ("CallPreamble: couldn't reconnect to ptserver\n"))do { if ((0) <= LogLevel) (FSLog ("CallPreamble: couldn't reconnect to ptserver\n"
)); } while (0)
;
389 return -1001;
390 }
391
392 tclient->prfail = 2; /* Means re-eval client's cps */
393 h_ReleaseClient_r(tclient);
394 h_Release_r(thost)do { do { --((thost)->refCount); } while (0); if (((thost)
->refCount < 1) && (((thost)->hostFlags &
0x10) || ((thost)->hostFlags & 0x20))) h_TossStuff_r(
(thost)); } while(0)
;
395 goto retry;
396 }
397
398 tclient->LastCall = thost->LastCall = FT_ApproxTime();
399 if (activecall) /* For all but "GetTime", "GetStats", and "GetCaps" calls */
400 thost->ActiveCall = thost->LastCall;
401
402 h_Lock_r(thost);
403 if (thost->hostFlags & HOSTDELETED0x10) {
404 ViceLog(3,do { if ((3) <= LogLevel) (FSLog ("Discarded a packet for deleted host %s:%d\n"
, afs_inet_ntoa_r(thost->host, hoststr), (__builtin_constant_p
(thost->port) ? (__uint16_t)(((__uint16_t)(thost->port)
) << 8 | ((__uint16_t)(thost->port)) >> 8) : __bswap16_var
(thost->port)))); } while (0)
405 ("Discarded a packet for deleted host %s:%d\n",do { if ((3) <= LogLevel) (FSLog ("Discarded a packet for deleted host %s:%d\n"
, afs_inet_ntoa_r(thost->host, hoststr), (__builtin_constant_p
(thost->port) ? (__uint16_t)(((__uint16_t)(thost->port)
) << 8 | ((__uint16_t)(thost->port)) >> 8) : __bswap16_var
(thost->port)))); } while (0)
406 afs_inet_ntoa_r(thost->host, hoststr), ntohs(thost->port)))do { if ((3) <= LogLevel) (FSLog ("Discarded a packet for deleted host %s:%d\n"
, afs_inet_ntoa_r(thost->host, hoststr), (__builtin_constant_p
(thost->port) ? (__uint16_t)(((__uint16_t)(thost->port)
) << 8 | ((__uint16_t)(thost->port)) >> 8) : __bswap16_var
(thost->port)))); } while (0)
;
407 code = VBUSY110; /* raced, so retry */
408 } else if ((thost->hostFlags & VENUSDOWN0x08)
409 || (thost->hostFlags & HFE_LATER0x80)) {
410 if (BreakDelayedCallBacks_r(thost)) {
411 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("BreakDelayedCallbacks FAILED for host %s:%d which IS UP. Connection from %s:%d. Possible network or routing failure.\n"
, afs_inet_ntoa_r(thost->host, hoststr), (__builtin_constant_p
(thost->port) ? (__uint16_t)(((__uint16_t)(thost->port)
) << 8 | ((__uint16_t)(thost->port)) >> 8) : __bswap16_var
(thost->port)), afs_inet_ntoa_r((((((struct rx_connection *
)(*tconn))->peer))->host), hoststr2), (__builtin_constant_p
(((((((struct rx_connection *)(*tconn)))->peer))->port)
) ? (__uint16_t)(((__uint16_t)(((((((struct rx_connection *)(
*tconn)))->peer))->port))) << 8 | ((__uint16_t)((
(((((struct rx_connection *)(*tconn)))->peer))->port)))
>> 8) : __bswap16_var(((((((struct rx_connection *)(*tconn
)))->peer))->port))))); } while (0)
412 ("BreakDelayedCallbacks FAILED for host %s:%d which IS UP. Connection from %s:%d. Possible network or routing failure.\n",do { if ((0) <= LogLevel) (FSLog ("BreakDelayedCallbacks FAILED for host %s:%d which IS UP. Connection from %s:%d. Possible network or routing failure.\n"
, afs_inet_ntoa_r(thost->host, hoststr), (__builtin_constant_p
(thost->port) ? (__uint16_t)(((__uint16_t)(thost->port)
) << 8 | ((__uint16_t)(thost->port)) >> 8) : __bswap16_var
(thost->port)), afs_inet_ntoa_r((((((struct rx_connection *
)(*tconn))->peer))->host), hoststr2), (__builtin_constant_p
(((((((struct rx_connection *)(*tconn)))->peer))->port)
) ? (__uint16_t)(((__uint16_t)(((((((struct rx_connection *)(
*tconn)))->peer))->port))) << 8 | ((__uint16_t)((
(((((struct rx_connection *)(*tconn)))->peer))->port)))
>> 8) : __bswap16_var(((((((struct rx_connection *)(*tconn
)))->peer))->port))))); } while (0)
413 afs_inet_ntoa_r(thost->host, hoststr), ntohs(thost->port), afs_inet_ntoa_r(rxr_HostOf(*tconn), hoststr2),do { if ((0) <= LogLevel) (FSLog ("BreakDelayedCallbacks FAILED for host %s:%d which IS UP. Connection from %s:%d. Possible network or routing failure.\n"
, afs_inet_ntoa_r(thost->host, hoststr), (__builtin_constant_p
(thost->port) ? (__uint16_t)(((__uint16_t)(thost->port)
) << 8 | ((__uint16_t)(thost->port)) >> 8) : __bswap16_var
(thost->port)), afs_inet_ntoa_r((((((struct rx_connection *
)(*tconn))->peer))->host), hoststr2), (__builtin_constant_p
(((((((struct rx_connection *)(*tconn)))->peer))->port)
) ? (__uint16_t)(((__uint16_t)(((((((struct rx_connection *)(
*tconn)))->peer))->port))) << 8 | ((__uint16_t)((
(((((struct rx_connection *)(*tconn)))->peer))->port)))
>> 8) : __bswap16_var(((((((struct rx_connection *)(*tconn
)))->peer))->port))))); } while (0)
414 ntohs(rxr_PortOf(*tconn))))do { if ((0) <= LogLevel) (FSLog ("BreakDelayedCallbacks FAILED for host %s:%d which IS UP. Connection from %s:%d. Possible network or routing failure.\n"
, afs_inet_ntoa_r(thost->host, hoststr), (__builtin_constant_p
(thost->port) ? (__uint16_t)(((__uint16_t)(thost->port)
) << 8 | ((__uint16_t)(thost->port)) >> 8) : __bswap16_var
(thost->port)), afs_inet_ntoa_r((((((struct rx_connection *
)(*tconn))->peer))->host), hoststr2), (__builtin_constant_p
(((((((struct rx_connection *)(*tconn)))->peer))->port)
) ? (__uint16_t)(((__uint16_t)(((((((struct rx_connection *)(
*tconn)))->peer))->port))) << 8 | ((__uint16_t)((
(((((struct rx_connection *)(*tconn)))->peer))->port)))
>> 8) : __bswap16_var(((((((struct rx_connection *)(*tconn
)))->peer))->port))))); } while (0)
;
415 if (MultiProbeAlternateAddress_r(thost)) {
416 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("MultiProbe failed to find new address for host %s:%d\n"
, afs_inet_ntoa_r(thost->host, hoststr), (__builtin_constant_p
(thost->port) ? (__uint16_t)(((__uint16_t)(thost->port)
) << 8 | ((__uint16_t)(thost->port)) >> 8) : __bswap16_var
(thost->port)))); } while (0)
417 ("MultiProbe failed to find new address for host %s:%d\n",do { if ((0) <= LogLevel) (FSLog ("MultiProbe failed to find new address for host %s:%d\n"
, afs_inet_ntoa_r(thost->host, hoststr), (__builtin_constant_p
(thost->port) ? (__uint16_t)(((__uint16_t)(thost->port)
) << 8 | ((__uint16_t)(thost->port)) >> 8) : __bswap16_var
(thost->port)))); } while (0)
418 afs_inet_ntoa_r(thost->host, hoststr),do { if ((0) <= LogLevel) (FSLog ("MultiProbe failed to find new address for host %s:%d\n"
, afs_inet_ntoa_r(thost->host, hoststr), (__builtin_constant_p
(thost->port) ? (__uint16_t)(((__uint16_t)(thost->port)
) << 8 | ((__uint16_t)(thost->port)) >> 8) : __bswap16_var
(thost->port)))); } while (0)
419 ntohs(thost->port)))do { if ((0) <= LogLevel) (FSLog ("MultiProbe failed to find new address for host %s:%d\n"
, afs_inet_ntoa_r(thost->host, hoststr), (__builtin_constant_p
(thost->port) ? (__uint16_t)(((__uint16_t)(thost->port)
) << 8 | ((__uint16_t)(thost->port)) >> 8) : __bswap16_var
(thost->port)))); } while (0)
;
420 code = -1;
421 } else {
422 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("MultiProbe found new address for host %s:%d\n"
, afs_inet_ntoa_r(thost->host, hoststr), (__builtin_constant_p
(thost->port) ? (__uint16_t)(((__uint16_t)(thost->port)
) << 8 | ((__uint16_t)(thost->port)) >> 8) : __bswap16_var
(thost->port)))); } while (0)
423 ("MultiProbe found new address for host %s:%d\n",do { if ((0) <= LogLevel) (FSLog ("MultiProbe found new address for host %s:%d\n"
, afs_inet_ntoa_r(thost->host, hoststr), (__builtin_constant_p
(thost->port) ? (__uint16_t)(((__uint16_t)(thost->port)
) << 8 | ((__uint16_t)(thost->port)) >> 8) : __bswap16_var
(thost->port)))); } while (0)
424 afs_inet_ntoa_r(thost->host, hoststr),do { if ((0) <= LogLevel) (FSLog ("MultiProbe found new address for host %s:%d\n"
, afs_inet_ntoa_r(thost->host, hoststr), (__builtin_constant_p
(thost->port) ? (__uint16_t)(((__uint16_t)(thost->port)
) << 8 | ((__uint16_t)(thost->port)) >> 8) : __bswap16_var
(thost->port)))); } while (0)
425 ntohs(thost->port)))do { if ((0) <= LogLevel) (FSLog ("MultiProbe found new address for host %s:%d\n"
, afs_inet_ntoa_r(thost->host, hoststr), (__builtin_constant_p
(thost->port) ? (__uint16_t)(((__uint16_t)(thost->port)
) << 8 | ((__uint16_t)(thost->port)) >> 8) : __bswap16_var
(thost->port)))); } while (0)
;
426 if (BreakDelayedCallBacks_r(thost)) {
427 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("BreakDelayedCallbacks FAILED AGAIN for host %s:%d which IS UP. Connection from %s:%d. Possible network or routing failure.\n"
, afs_inet_ntoa_r(thost->host, hoststr), (__builtin_constant_p
(thost->port) ? (__uint16_t)(((__uint16_t)(thost->port)
) << 8 | ((__uint16_t)(thost->port)) >> 8) : __bswap16_var
(thost->port)), afs_inet_ntoa_r((((((struct rx_connection *
)(*tconn))->peer))->host), hoststr2), (__builtin_constant_p
(((((((struct rx_connection *)(*tconn)))->peer))->port)
) ? (__uint16_t)(((__uint16_t)(((((((struct rx_connection *)(
*tconn)))->peer))->port))) << 8 | ((__uint16_t)((
(((((struct rx_connection *)(*tconn)))->peer))->port)))
>> 8) : __bswap16_var(((((((struct rx_connection *)(*tconn
)))->peer))->port))))); } while (0)
428 ("BreakDelayedCallbacks FAILED AGAIN for host %s:%d which IS UP. Connection from %s:%d. Possible network or routing failure.\n",do { if ((0) <= LogLevel) (FSLog ("BreakDelayedCallbacks FAILED AGAIN for host %s:%d which IS UP. Connection from %s:%d. Possible network or routing failure.\n"
, afs_inet_ntoa_r(thost->host, hoststr), (__builtin_constant_p
(thost->port) ? (__uint16_t)(((__uint16_t)(thost->port)
) << 8 | ((__uint16_t)(thost->port)) >> 8) : __bswap16_var
(thost->port)), afs_inet_ntoa_r((((((struct rx_connection *
)(*tconn))->peer))->host), hoststr2), (__builtin_constant_p
(((((((struct rx_connection *)(*tconn)))->peer))->port)
) ? (__uint16_t)(((__uint16_t)(((((((struct rx_connection *)(
*tconn)))->peer))->port))) << 8 | ((__uint16_t)((
(((((struct rx_connection *)(*tconn)))->peer))->port)))
>> 8) : __bswap16_var(((((((struct rx_connection *)(*tconn
)))->peer))->port))))); } while (0)
429 afs_inet_ntoa_r(thost->host, hoststr), ntohs(thost->port), afs_inet_ntoa_r(rxr_HostOf(*tconn), hoststr2),do { if ((0) <= LogLevel) (FSLog ("BreakDelayedCallbacks FAILED AGAIN for host %s:%d which IS UP. Connection from %s:%d. Possible network or routing failure.\n"
, afs_inet_ntoa_r(thost->host, hoststr), (__builtin_constant_p
(thost->port) ? (__uint16_t)(((__uint16_t)(thost->port)
) << 8 | ((__uint16_t)(thost->port)) >> 8) : __bswap16_var
(thost->port)), afs_inet_ntoa_r((((((struct rx_connection *
)(*tconn))->peer))->host), hoststr2), (__builtin_constant_p
(((((((struct rx_connection *)(*tconn)))->peer))->port)
) ? (__uint16_t)(((__uint16_t)(((((((struct rx_connection *)(
*tconn)))->peer))->port))) << 8 | ((__uint16_t)((
(((((struct rx_connection *)(*tconn)))->peer))->port)))
>> 8) : __bswap16_var(((((((struct rx_connection *)(*tconn
)))->peer))->port))))); } while (0)
430 ntohs(rxr_PortOf(*tconn))))do { if ((0) <= LogLevel) (FSLog ("BreakDelayedCallbacks FAILED AGAIN for host %s:%d which IS UP. Connection from %s:%d. Possible network or routing failure.\n"
, afs_inet_ntoa_r(thost->host, hoststr), (__builtin_constant_p
(thost->port) ? (__uint16_t)(((__uint16_t)(thost->port)
) << 8 | ((__uint16_t)(thost->port)) >> 8) : __bswap16_var
(thost->port)), afs_inet_ntoa_r((((((struct rx_connection *
)(*tconn))->peer))->host), hoststr2), (__builtin_constant_p
(((((((struct rx_connection *)(*tconn)))->peer))->port)
) ? (__uint16_t)(((__uint16_t)(((((((struct rx_connection *)(
*tconn)))->peer))->port))) << 8 | ((__uint16_t)((
(((((struct rx_connection *)(*tconn)))->peer))->port)))
>> 8) : __bswap16_var(((((((struct rx_connection *)(*tconn
)))->peer))->port))))); } while (0)
;
431 code = -1;
432 }
433 }
434 }
435 } else {
436 code = 0;
437 }
438
439 h_ReleaseClient_r(tclient);
440 h_Unlock_r(thost)do { (void)((pthread_mutex_lock(&(&(thost)->lock)->
mutex) == 0) || (osi_AssertFailU("pthread_mutex_lock(&(&(thost)->lock)->mutex) == 0"
, "./../viced/afsfileprocs.c", 440), 0));; (&(thost)->
lock)->excl_locked &= ~2; if ((&(thost)->lock)->
wait_states) Afs_Lock_ReleaseR(&(thost)->lock); (void)
((pthread_mutex_unlock(&(&(thost)->lock)->mutex
) == 0) || (osi_AssertFailU("pthread_mutex_unlock(&(&(thost)->lock)->mutex) == 0"
, "./../viced/afsfileprocs.c", 440), 0));; } while (0)
;
441 H_UNLOCK(void)((pthread_mutex_unlock(&host_glock_mutex) == 0) || (
osi_AssertFailU("pthread_mutex_unlock(&host_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 441), 0));
;
442 *ahostp = thost;
443 return code;
444
445} /*CallPreamble */
446
447
448static afs_int32
449CallPostamble(struct rx_connection *aconn, afs_int32 ret,
450 struct host *ahost)
451{
452 struct host *thost;
453 struct client *tclient;
454 int translate = 0;
455
456 H_LOCK(void)((pthread_mutex_lock(&host_glock_mutex) == 0) || (osi_AssertFailU
("pthread_mutex_lock(&host_glock_mutex) == 0", "./../viced/afsfileprocs.c"
, 456), 0));
;
457 tclient = h_FindClient_r(aconn);
458 if (!tclient)
459 goto busyout;
460 thost = tclient->host;
461 if (thost->hostFlags & HERRORTRANS0x100)
462 translate = 1;
463 h_ReleaseClient_r(tclient);
464
465 if (ahost) {
466 if (ahost != thost) {
467 /* host/client recycle */
468 char hoststr[16], hoststr2[16];
469 ViceLog(0, ("CallPostamble: ahost %s:%d (%p) != thost "do { if ((0) <= LogLevel) (FSLog ("CallPostamble: ahost %s:%d (%p) != thost "
"%s:%d (%p)\n", afs_inet_ntoa_r(ahost->host, hoststr), (__builtin_constant_p
(ahost->port) ? (__uint16_t)(((__uint16_t)(ahost->port)
) << 8 | ((__uint16_t)(ahost->port)) >> 8) : __bswap16_var
(ahost->port)), ahost, afs_inet_ntoa_r(thost->host, hoststr2
), (__builtin_constant_p(thost->port) ? (__uint16_t)(((__uint16_t
)(thost->port)) << 8 | ((__uint16_t)(thost->port)
) >> 8) : __bswap16_var(thost->port)), thost)); } while
(0)
470 "%s:%d (%p)\n",do { if ((0) <= LogLevel) (FSLog ("CallPostamble: ahost %s:%d (%p) != thost "
"%s:%d (%p)\n", afs_inet_ntoa_r(ahost->host, hoststr), (__builtin_constant_p
(ahost->port) ? (__uint16_t)(((__uint16_t)(ahost->port)
) << 8 | ((__uint16_t)(ahost->port)) >> 8) : __bswap16_var
(ahost->port)), ahost, afs_inet_ntoa_r(thost->host, hoststr2
), (__builtin_constant_p(thost->port) ? (__uint16_t)(((__uint16_t
)(thost->port)) << 8 | ((__uint16_t)(thost->port)
) >> 8) : __bswap16_var(thost->port)), thost)); } while
(0)
471 afs_inet_ntoa_r(ahost->host, hoststr),do { if ((0) <= LogLevel) (FSLog ("CallPostamble: ahost %s:%d (%p) != thost "
"%s:%d (%p)\n", afs_inet_ntoa_r(ahost->host, hoststr), (__builtin_constant_p
(ahost->port) ? (__uint16_t)(((__uint16_t)(ahost->port)
) << 8 | ((__uint16_t)(ahost->port)) >> 8) : __bswap16_var
(ahost->port)), ahost, afs_inet_ntoa_r(thost->host, hoststr2
), (__builtin_constant_p(thost->port) ? (__uint16_t)(((__uint16_t
)(thost->port)) << 8 | ((__uint16_t)(thost->port)
) >> 8) : __bswap16_var(thost->port)), thost)); } while
(0)
472 ntohs(ahost->port),do { if ((0) <= LogLevel) (FSLog ("CallPostamble: ahost %s:%d (%p) != thost "
"%s:%d (%p)\n", afs_inet_ntoa_r(ahost->host, hoststr), (__builtin_constant_p
(ahost->port) ? (__uint16_t)(((__uint16_t)(ahost->port)
) << 8 | ((__uint16_t)(ahost->port)) >> 8) : __bswap16_var
(ahost->port)), ahost, afs_inet_ntoa_r(thost->host, hoststr2
), (__builtin_constant_p(thost->port) ? (__uint16_t)(((__uint16_t
)(thost->port)) << 8 | ((__uint16_t)(thost->port)
) >> 8) : __bswap16_var(thost->port)), thost)); } while
(0)
473 ahost,do { if ((0) <= LogLevel) (FSLog ("CallPostamble: ahost %s:%d (%p) != thost "
"%s:%d (%p)\n", afs_inet_ntoa_r(ahost->host, hoststr), (__builtin_constant_p
(ahost->port) ? (__uint16_t)(((__uint16_t)(ahost->port)
) << 8 | ((__uint16_t)(ahost->port)) >> 8) : __bswap16_var
(ahost->port)), ahost, afs_inet_ntoa_r(thost->host, hoststr2
), (__builtin_constant_p(thost->port) ? (__uint16_t)(((__uint16_t
)(thost->port)) << 8 | ((__uint16_t)(thost->port)
) >> 8) : __bswap16_var(thost->port)), thost)); } while
(0)
474 afs_inet_ntoa_r(thost->host, hoststr2),do { if ((0) <= LogLevel) (FSLog ("CallPostamble: ahost %s:%d (%p) != thost "
"%s:%d (%p)\n", afs_inet_ntoa_r(ahost->host, hoststr), (__builtin_constant_p
(ahost->port) ? (__uint16_t)(((__uint16_t)(ahost->port)
) << 8 | ((__uint16_t)(ahost->port)) >> 8) : __bswap16_var
(ahost->port)), ahost, afs_inet_ntoa_r(thost->host, hoststr2
), (__builtin_constant_p(thost->port) ? (__uint16_t)(((__uint16_t
)(thost->port)) << 8 | ((__uint16_t)(thost->port)
) >> 8) : __bswap16_var(thost->port)), thost)); } while
(0)
475 ntohs(thost->port),do { if ((0) <= LogLevel) (FSLog ("CallPostamble: ahost %s:%d (%p) != thost "
"%s:%d (%p)\n", afs_inet_ntoa_r(ahost->host, hoststr), (__builtin_constant_p
(ahost->port) ? (__uint16_t)(((__uint16_t)(ahost->port)
) << 8 | ((__uint16_t)(ahost->port)) >> 8) : __bswap16_var
(ahost->port)), ahost, afs_inet_ntoa_r(thost->host, hoststr2
), (__builtin_constant_p(thost->port) ? (__uint16_t)(((__uint16_t
)(thost->port)) << 8 | ((__uint16_t)(thost->port)
) >> 8) : __bswap16_var(thost->port)), thost)); } while
(0)
476 thost))do { if ((0) <= LogLevel) (FSLog ("CallPostamble: ahost %s:%d (%p) != thost "
"%s:%d (%p)\n", afs_inet_ntoa_r(ahost->host, hoststr), (__builtin_constant_p
(ahost->port) ? (__uint16_t)(((__uint16_t)(ahost->port)
) << 8 | ((__uint16_t)(ahost->port)) >> 8) : __bswap16_var
(ahost->port)), ahost, afs_inet_ntoa_r(thost->host, hoststr2
), (__builtin_constant_p(thost->port) ? (__uint16_t)(((__uint16_t
)(thost->port)) << 8 | ((__uint16_t)(thost->port)
) >> 8) : __bswap16_var(thost->port)), thost)); } while
(0)
;
477 }
478 /* return the reference taken in CallPreamble */
479 h_Release_r(ahost)do { do { --((ahost)->refCount); } while (0); if (((ahost)
->refCount < 1) && (((ahost)->hostFlags &
0x10) || ((ahost)->hostFlags & 0x20))) h_TossStuff_r(
(ahost)); } while(0)
;
480 } else {
481 char hoststr[16];
482 ViceLog(0, ("CallPostamble: null ahost for thost %s:%d (%p)\n",do { if ((0) <= LogLevel) (FSLog ("CallPostamble: null ahost for thost %s:%d (%p)\n"
, afs_inet_ntoa_r(thost->host, hoststr), (__builtin_constant_p
(thost->port) ? (__uint16_t)(((__uint16_t)(thost->port)
) << 8 | ((__uint16_t)(thost->port)) >> 8) : __bswap16_var
(thost->port)), thost)); } while (0)
483 afs_inet_ntoa_r(thost->host, hoststr),do { if ((0) <= LogLevel) (FSLog ("CallPostamble: null ahost for thost %s:%d (%p)\n"
, afs_inet_ntoa_r(thost->host, hoststr), (__builtin_constant_p
(thost->port) ? (__uint16_t)(((__uint16_t)(thost->port)
) << 8 | ((__uint16_t)(thost->port)) >> 8) : __bswap16_var
(thost->port)), thost)); } while (0)
484 ntohs(thost->port),do { if ((0) <= LogLevel) (FSLog ("CallPostamble: null ahost for thost %s:%d (%p)\n"
, afs_inet_ntoa_r(thost->host, hoststr), (__builtin_constant_p
(thost->port) ? (__uint16_t)(((__uint16_t)(thost->port)
) << 8 | ((__uint16_t)(thost->port)) >> 8) : __bswap16_var
(thost->port)), thost)); } while (0)
485 thost))do { if ((0) <= LogLevel) (FSLog ("CallPostamble: null ahost for thost %s:%d (%p)\n"
, afs_inet_ntoa_r(thost->host, hoststr), (__builtin_constant_p
(thost->port) ? (__uint16_t)(((__uint16_t)(thost->port)
) << 8 | ((__uint16_t)(thost->port)) >> 8) : __bswap16_var
(thost->port)), thost)); } while (0)
;
486 }
487
488 /* return the reference taken in local h_FindClient_r--h_ReleaseClient_r
489 * does not decrement refcount on client->host */
490 h_Release_r(thost)do { do { --((thost)->refCount); } while (0); if (((thost)
->refCount < 1) && (((thost)->hostFlags &
0x10) || ((thost)->hostFlags & 0x20))) h_TossStuff_r(
(thost)); } while(0)
;
491
492 busyout:
493 H_UNLOCK(void)((pthread_mutex_unlock(&host_glock_mutex) == 0) || (
osi_AssertFailU("pthread_mutex_unlock(&host_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 493), 0));
;
494 return (translate ? sys_error_to_et(ret) : ret);
495} /*CallPostamble */
496
497/*
498 * Returns the volume and vnode pointers associated with file Fid; the lock
499 * type on the vnode is set to lock. Note that both volume/vnode's ref counts
500 * are incremented and they must be eventualy released.
501 */
502static afs_int32
503CheckVnodeWithCall(AFSFid * fid, Volume ** volptr, struct VCallByVol *cbv,
504 Vnode ** vptr, int lock)
505{
506 Errorbit32 fileCode = 0;
507 Errorbit32 local_errorCode, errorCode = -1;
508 static struct timeval restartedat = { 0, 0 };
509
510 if (fid->Volume == 0 || fid->Vnode == 0) /* not: || fid->Unique == 0) */
511 return (EINVAL22);
512 if ((*volptr) == 0) {
513 extern int VInit;
514
515 while (1) {
516 int restarting =
517#ifdef AFS_DEMAND_ATTACH_FS1
518 VSALVAGE101
519#else
520 VRESTARTING-100
521#endif
522 ;
523#ifdef AFS_PTHREAD_ENV1
524 static const struct timespec timeout_ts = { 0, 0 };
525 static const struct timespec * const ts = &timeout_ts;
526#else
527 static const struct timespec * const ts = NULL((void *)0);
528#endif
529
530 errorCode = 0;
531 *volptr = VGetVolumeWithCall(&local_errorCode, &errorCode,
532 fid->Volume, ts, cbv);
533 if (!errorCode) {
534 osi_Assert(*volptr)(void)((*volptr) || (osi_AssertFailU("*volptr", "./../viced/afsfileprocs.c"
, 534), 0))
;
535 break;
536 }
537 if ((errorCode == VOFFLINE106) && (VInit < 2)) {
538 /* The volume we want may not be attached yet because
539 * the volume initialization is not yet complete.
540 * We can do several things:
541 * 1. return -1, which will cause users to see
542 * "connection timed out". This is more or
543 * less the same as always, except that the servers
544 * may appear to bounce up and down while they
545 * are actually restarting.
546 * 2. return VBUSY which will cause clients to
547 * sleep and retry for 6.5 - 15 minutes, depending
548 * on what version of the CM they are running. If
549 * the file server takes longer than that interval
550 * to attach the desired volume, then the application
551 * will see an ENODEV or EIO. This approach has
552 * the advantage that volumes which have been attached
553 * are immediately available, it keeps the server's
554 * immediate backlog low, and the call is interruptible
555 * by the user. Users see "waiting for busy volume."
556 * 3. sleep here and retry. Some people like this approach
557 * because there is no danger of seeing errors. However,
558 * this approach only works with a bounded number of
559 * clients, since the pending queues will grow without
560 * stopping. It might be better to find a way to take
561 * this call and stick it back on a queue in order to
562 * recycle this thread for a different request.
563 * 4. Return a new error code, which new cache managers will
564 * know enough to interpret as "sleep and retry", without
565 * the upper bound of 6-15 minutes that is imposed by the
566 * VBUSY handling. Users will see "waiting for
567 * busy volume," so they know that something is
568 * happening. Old cache managers must be able to do
569 * something reasonable with this, for instance, mark the
570 * server down. Fortunately, any error code < 0
571 * will elicit that behavior. See #1.
572 * 5. Some combination of the above. I like doing #2 for 10
573 * minutes, followed by #4. 3.1b and 3.2 cache managers
574 * will be fine as long as the restart period is
575 * not longer than 6.5 minutes, otherwise they may
576 * return ENODEV to users. 3.3 cache managers will be
577 * fine for 10 minutes, then will return
578 * ETIMEDOUT. 3.4 cache managers will just wait
579 * until the call works or fails definitively.
580 * NB. The problem with 2,3,4,5 is that old clients won't
581 * fail over to an alternate read-only replica while this
582 * server is restarting. 3.4 clients will fail over right away.
583 */
584 if (restartedat.tv_sec == 0) {
585 /* I'm not really worried about when we restarted, I'm */
586 /* just worried about when the first VBUSY was returned. */
587 FT_GetTimeOfDay(&restartedat, 0);
588 if (busyonrst) {
589 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 589), 0));
;
590 afs_perfstats.fs_nBusies++;
591 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 591), 0));
;
592 }
593 return (busyonrst ? VBUSY110 : restarting);
594 } else {
595 struct timeval now;
596 FT_GetTimeOfDay(&now, 0);
597 if ((now.tv_sec - restartedat.tv_sec) < (11 * 60)) {
598 if (busyonrst) {
599 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 599), 0));
;
600 afs_perfstats.fs_nBusies++;
601 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 601), 0));
;
602 }
603 return (busyonrst ? VBUSY110 : restarting);
604 } else {
605 return (restarting);
606 }
607 }
608 }
609 /* allow read operations on busy volume.
610 * must check local_errorCode because demand attach fs
611 * can have local_errorCode == VSALVAGING, errorCode == VBUSY */
612 else if (local_errorCode == VBUSY110 && lock == READ_LOCK1) {
613#ifdef AFS_DEMAND_ATTACH_FS1
614 /* DAFS case is complicated by the fact that local_errorCode can
615 * be VBUSY in cases where the volume is truly offline */
616 if (!*volptr) {
617 /* volume is in VOL_STATE_UNATTACHED */
618 return (errorCode);
619 }
620#endif /* AFS_DEMAND_ATTACH_FS */
621 errorCode = 0;
622 break;
623 } else if (errorCode)
624 return (errorCode);
625 }
626 }
627 osi_Assert(*volptr)(void)((*volptr) || (osi_AssertFailU("*volptr", "./../viced/afsfileprocs.c"
, 627), 0))
;
628
629 /* get the vnode */
630 *vptr = VGetVnode(&errorCode, *volptr, fid->Vnode, lock);
631 if (errorCode)
632 return (errorCode);
633 if ((*vptr)->disk.uniquifier != fid->Unique) {
634 VPutVnode(&fileCode, *vptr);
635 osi_Assert(fileCode == 0)(void)((fileCode == 0) || (osi_AssertFailU("fileCode == 0", "./../viced/afsfileprocs.c"
, 635), 0))
;
636 *vptr = 0;
637 return (VNOVNODE102); /* return the right error code, at least */
638 }
639 return (0);
640} /*CheckVnode */
641
642static_inlinestatic inline afs_int32
643CheckVnode(AFSFid * fid, Volume ** volptr, Vnode ** vptr, int lock)
644{
645 return CheckVnodeWithCall(fid, volptr, NULL((void *)0), vptr, lock);
646}
647
648/*
649 * This routine returns the ACL associated with the targetptr. If the
650 * targetptr isn't a directory, we access its parent dir and get the ACL
651 * thru the parent; in such case the parent's vnode is returned in
652 * READ_LOCK mode.
653 */
654static afs_int32
655SetAccessList(Vnode ** targetptr, Volume ** volume,
656 struct acl_accessList **ACL, int *ACLSize, Vnode ** parent,
657 AFSFid * Fid, int Lock)
658{
659 if ((*targetptr)->disk.type == vDirectory2) {
660 *parent = 0;
661 *ACL = VVnodeACL(*targetptr)(((AL_AccessList *) (((byte *)(&(*targetptr)->disk))+64
)))
;
662 *ACLSize = VAclSize(*targetptr)(256 - 64);
663 return (0);
664 } else {
665 osi_Assert(Fid != 0)(void)((Fid != 0) || (osi_AssertFailU("Fid != 0", "./../viced/afsfileprocs.c"
, 665), 0))
;
666 while (1) {
667 VnodeId parentvnode;
668 Errorbit32 errorCode = 0;
669
670 parentvnode = (*targetptr)->disk.parent;
671 VPutVnode(&errorCode, *targetptr);
672 *targetptr = 0;
673 if (errorCode)
674 return (errorCode);
675 *parent = VGetVnode(&errorCode, *volume, parentvnode, READ_LOCK1);
676 if (errorCode)
677 return (errorCode);
678 *ACL = VVnodeACL(*parent)(((AL_AccessList *) (((byte *)(&(*parent)->disk))+64))
)
;
679 *ACLSize = VAclSize(*parent)(256 - 64);
680 if ((errorCode = CheckVnode(Fid, volume, targetptr, Lock)) != 0)
681 return (errorCode);
682 if ((*targetptr)->disk.parent != parentvnode) {
683 VPutVnode(&errorCode, *parent);
684 *parent = 0;
685 if (errorCode)
686 return (errorCode);
687 } else
688 return (0);
689 }
690 }
691
692} /*SetAccessList */
693
694/* Must not be called with H_LOCK held */
695static void
696client_CheckRights(struct client *client, struct acl_accessList *ACL,
697 afs_int32 *rights)
698{
699 *rights = 0;
700 ObtainReadLock(&client->lock)do { (void)((pthread_mutex_lock(&(&client->lock)->
mutex) == 0) || (osi_AssertFailU("pthread_mutex_lock(&(&client->lock)->mutex) == 0"
, "./../viced/afsfileprocs.c", 700), 0));; if (!((&client
->lock)->excl_locked & 2) && !(&client->
lock)->wait_states) (&client->lock) -> readers_reading
++; else Afs_Lock_Obtain(&client->lock, 1); (void)((pthread_mutex_unlock
(&(&client->lock)->mutex) == 0) || (osi_AssertFailU
("pthread_mutex_unlock(&(&client->lock)->mutex) == 0"
, "./../viced/afsfileprocs.c", 700), 0));; } while (0)
;
701 if (client->CPS.prlist_len > 0 && !client->deleted &&
702 client->host && !(client->host->hostFlags & HOSTDELETED0x10))
703 acl_CheckRights(ACL, &client->CPS, rights);
704 ReleaseReadLock(&client->lock)do { (void)((pthread_mutex_lock(&(&client->lock)->
mutex) == 0) || (osi_AssertFailU("pthread_mutex_lock(&(&client->lock)->mutex) == 0"
, "./../viced/afsfileprocs.c", 704), 0));; if (!--(&client
->lock)->readers_reading && (&client->lock
)->wait_states) Afs_Lock_ReleaseW(&client->lock) ; (
void)((pthread_mutex_unlock(&(&client->lock)->mutex
) == 0) || (osi_AssertFailU("pthread_mutex_unlock(&(&client->lock)->mutex) == 0"
, "./../viced/afsfileprocs.c", 704), 0));; } while (0)
;
705}
706
707/* Must not be called with H_LOCK held */
708static afs_int32
709client_HasAsMember(struct client *client, afs_int32 id)
710{
711 afs_int32 code = 0;
712
713 ObtainReadLock(&client->lock)do { (void)((pthread_mutex_lock(&(&client->lock)->
mutex) == 0) || (osi_AssertFailU("pthread_mutex_lock(&(&client->lock)->mutex) == 0"
, "./../viced/afsfileprocs.c", 713), 0));; if (!((&client
->lock)->excl_locked & 2) && !(&client->
lock)->wait_states) (&client->lock) -> readers_reading
++; else Afs_Lock_Obtain(&client->lock, 1); (void)((pthread_mutex_unlock
(&(&client->lock)->mutex) == 0) || (osi_AssertFailU
("pthread_mutex_unlock(&(&client->lock)->mutex) == 0"
, "./../viced/afsfileprocs.c", 713), 0));; } while (0)
;
714 if (client->CPS.prlist_len > 0 && !client->deleted &&
715 client->host && !(client->host->hostFlags & HOSTDELETED0x10))
716 code = acl_IsAMember(id, &client->CPS);
717 ReleaseReadLock(&client->lock)do { (void)((pthread_mutex_lock(&(&client->lock)->
mutex) == 0) || (osi_AssertFailU("pthread_mutex_lock(&(&client->lock)->mutex) == 0"
, "./../viced/afsfileprocs.c", 717), 0));; if (!--(&client
->lock)->readers_reading && (&client->lock
)->wait_states) Afs_Lock_ReleaseW(&client->lock) ; (
void)((pthread_mutex_unlock(&(&client->lock)->mutex
) == 0) || (osi_AssertFailU("pthread_mutex_unlock(&(&client->lock)->mutex) == 0"
, "./../viced/afsfileprocs.c", 717), 0));; } while (0)
;
718 return code;
719}
720
721/*
722 * Compare the directory's ACL with the user's access rights in the client
723 * connection and return the user's and everybody else's access permissions
724 * in rights and anyrights, respectively
725 */
726static afs_int32
727GetRights(struct client *client, struct acl_accessList *ACL,
728 afs_int32 * rights, afs_int32 * anyrights)
729{
730 extern prlist SystemAnyUserCPS;
731 afs_int32 hrights = 0;
732#ifndef AFS_PTHREAD_ENV1
733 int code;
734#endif
735
736 if (acl_CheckRights(ACL, &SystemAnyUserCPS, anyrights) != 0) {
737 ViceLog(0, ("CheckRights failed\n"))do { if ((0) <= LogLevel) (FSLog ("CheckRights failed\n"))
; } while (0)
;
738 *anyrights = 0;
739 }
740 *rights = 0;
741
742 client_CheckRights(client, ACL, rights);
743
744 /* wait if somebody else is already doing the getCPS call */
745 H_LOCK(void)((pthread_mutex_lock(&host_glock_mutex) == 0) || (osi_AssertFailU
("pthread_mutex_lock(&host_glock_mutex) == 0", "./../viced/afsfileprocs.c"
, 745), 0));
;
746 while (client->host->hostFlags & HCPS_INPROGRESS0x01) {
747 client->host->hostFlags |= HCPS_WAITING0x02; /* I am waiting */
748#ifdef AFS_PTHREAD_ENV1
749 CV_WAIT(&client->host->cond, &host_glock_mutex)(void)((pthread_cond_wait(&client->host->cond, &
host_glock_mutex) == 0) || (osi_AssertFailU("pthread_cond_wait(&client->host->cond, &host_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 749), 0))
;
750#else /* AFS_PTHREAD_ENV */
751 if ((code =
752 LWP_WaitProcess(&(client->host->hostFlags))) != LWP_SUCCESS)
753 ViceLog(0, ("LWP_WaitProcess returned %d\n", code))do { if ((0) <= LogLevel) (FSLog ("LWP_WaitProcess returned %d\n"
, code)); } while (0)
;
754#endif /* AFS_PTHREAD_ENV */
755 }
756
757 if (!client->host->hcps.prlist_len || !client->host->hcps.prlist_val) {
758 char hoststr[16];
759 ViceLog(5,do { if ((5) <= LogLevel) (FSLog ("CheckRights: len=%u, for host=%s:%d\n"
, client->host->hcps.prlist_len, afs_inet_ntoa_r(client
->host->host, hoststr), (__builtin_constant_p(client->
host->port) ? (__uint16_t)(((__uint16_t)(client->host->
port)) << 8 | ((__uint16_t)(client->host->port)) >>
8) : __bswap16_var(client->host->port)))); } while (0)
760 ("CheckRights: len=%u, for host=%s:%d\n",do { if ((5) <= LogLevel) (FSLog ("CheckRights: len=%u, for host=%s:%d\n"
, client->host->hcps.prlist_len, afs_inet_ntoa_r(client
->host->host, hoststr), (__builtin_constant_p(client->
host->port) ? (__uint16_t)(((__uint16_t)(client->host->
port)) << 8 | ((__uint16_t)(client->host->port)) >>
8) : __bswap16_var(client->host->port)))); } while (0)
761 client->host->hcps.prlist_len,do { if ((5) <= LogLevel) (FSLog ("CheckRights: len=%u, for host=%s:%d\n"
, client->host->hcps.prlist_len, afs_inet_ntoa_r(client
->host->host, hoststr), (__builtin_constant_p(client->
host->port) ? (__uint16_t)(((__uint16_t)(client->host->
port)) << 8 | ((__uint16_t)(client->host->port)) >>
8) : __bswap16_var(client->host->port)))); } while (0)
762 afs_inet_ntoa_r(client->host->host, hoststr),do { if ((5) <= LogLevel) (FSLog ("CheckRights: len=%u, for host=%s:%d\n"
, client->host->hcps.prlist_len, afs_inet_ntoa_r(client
->host->host, hoststr), (__builtin_constant_p(client->
host->port) ? (__uint16_t)(((__uint16_t)(client->host->
port)) << 8 | ((__uint16_t)(client->host->port)) >>
8) : __bswap16_var(client->host->port)))); } while (0)
763 ntohs(client->host->port)))do { if ((5) <= LogLevel) (FSLog ("CheckRights: len=%u, for host=%s:%d\n"
, client->host->hcps.prlist_len, afs_inet_ntoa_r(client
->host->host, hoststr), (__builtin_constant_p(client->
host->port) ? (__uint16_t)(((__uint16_t)(client->host->
port)) << 8 | ((__uint16_t)(client->host->port)) >>
8) : __bswap16_var(client->host->port)))); } while (0)
;
764 } else
765 acl_CheckRights(ACL, &client->host->hcps, &hrights);
766 H_UNLOCK(void)((pthread_mutex_unlock(&host_glock_mutex) == 0) || (
osi_AssertFailU("pthread_mutex_unlock(&host_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 766), 0));
;
767 /* Allow system:admin the rights given with the -implicit option */
768 if (client_HasAsMember(client, SystemId))
769 *rights |= implicitAdminRights;
770
771 *rights |= hrights;
772 *anyrights |= hrights;
773
774 return (0);
775
776} /*GetRights */
777
778/*
779 * VanillaUser returns 1 (true) if the user is a vanilla user (i.e., not
780 * a System:Administrator)
781 */
782static afs_int32
783VanillaUser(struct client *client)
784{
785 if (client_HasAsMember(client, SystemId))
786 return (0); /* not a system administrator, then you're "vanilla" */
787 return (1);
788
789} /*VanillaUser */
790
791
792/*
793 * This unusual afs_int32-parameter routine encapsulates all volume package related
794 * operations together in a single function; it's called by almost all AFS
795 * interface calls.
796 */
797static afs_int32
798GetVolumePackageWithCall(struct rx_connection *tcon, struct VCallByVol *cbv,
799 AFSFid * Fid, Volume ** volptr, Vnode ** targetptr,
800 int chkforDir, Vnode ** parent, struct client **client,
801 int locktype, afs_int32 * rights, afs_int32 * anyrights)
802{
803 struct acl_accessList *aCL; /* Internal access List */
804 int aCLSize; /* size of the access list */
805 Errorbit32 errorCode = 0; /* return code to caller */
806
807 if ((errorCode = CheckVnodeWithCall(Fid, volptr, cbv, targetptr, locktype)))
808 return (errorCode);
809 if (chkforDir) {
810 if (chkforDir == MustNOTBeDIR1
811 && ((*targetptr)->disk.type == vDirectory2))
812 return (EISDIR21);
813 else if (chkforDir == MustBeDIR2
814 && ((*targetptr)->disk.type != vDirectory2))
815 return (ENOTDIR20);
816 }
817 if ((errorCode =
818 SetAccessList(targetptr, volptr, &aCL, &aCLSize, parent,
819 (chkforDir == MustBeDIR2 ? (AFSFid *) 0 : Fid),
820 (chkforDir == MustBeDIR2 ? 0 : locktype))) != 0)
821 return (errorCode);
822 if (chkforDir == MustBeDIR2)
823 osi_Assert((*parent) == 0)(void)(((*parent) == 0) || (osi_AssertFailU("(*parent) == 0",
"./../viced/afsfileprocs.c", 823), 0))
;
824 if (!(*client)) {
825 if ((errorCode = GetClient(tcon, client)) != 0)
826 return (errorCode);
827 if (!(*client))
828 return (EINVAL22);
829 }
830 GetRights(*client, aCL, rights, anyrights);
831 /* ok, if this is not a dir, set the PRSFS_ADMINISTER bit iff we're the owner */
832 if ((*targetptr)->disk.type != vDirectory2) {
833 /* anyuser can't be owner, so only have to worry about rights, not anyrights */
834 if ((*targetptr)->disk.owner == (*client)->ViceId)
835 (*rights) |= PRSFS_ADMINISTER64;
836 else
837 (*rights) &= ~PRSFS_ADMINISTER64;
838 }
839#ifdef ADMIN_IMPLICIT_LOOKUP
840 /* admins get automatic lookup on everything */
841 if (!VanillaUser(*client))
842 (*rights) |= PRSFS_LOOKUP8;
843#endif /* ADMIN_IMPLICIT_LOOKUP */
844 return errorCode;
845
846} /*GetVolumePackage */
847
848static_inlinestatic inline afs_int32
849GetVolumePackage(struct rx_connection *tcon, AFSFid * Fid, Volume ** volptr,
850 Vnode ** targetptr, int chkforDir, Vnode ** parent,
851 struct client **client, int locktype, afs_int32 * rights,
852 afs_int32 * anyrights)
853{
854 return GetVolumePackageWithCall(tcon, NULL((void *)0), Fid, volptr, targetptr,
855 chkforDir, parent, client, locktype,
856 rights, anyrights);
857}
858
859
860/*
861 * This is the opposite of GetVolumePackage(), and is always used at the end of
862 * AFS calls to put back all used vnodes and the volume in the proper order!
863 */
864static void
865PutVolumePackageWithCall(Vnode * parentwhentargetnotdir, Vnode * targetptr,
866 Vnode * parentptr, Volume * volptr,
867 struct client **client, struct VCallByVol *cbv)
868{
869 Errorbit32 fileCode = 0; /* Error code returned by the volume package */
870
871 if (parentwhentargetnotdir) {
872 VPutVnode(&fileCode, parentwhentargetnotdir);
873 osi_Assert(!fileCode || (fileCode == VSALVAGE))(void)((!fileCode || (fileCode == 101)) || (osi_AssertFailU("!fileCode || (fileCode == VSALVAGE)"
, "./../viced/afsfileprocs.c", 873), 0))
;
874 }
875 if (targetptr) {
876 VPutVnode(&fileCode, targetptr);
877 osi_Assert(!fileCode || (fileCode == VSALVAGE))(void)((!fileCode || (fileCode == 101)) || (osi_AssertFailU("!fileCode || (fileCode == VSALVAGE)"
, "./../viced/afsfileprocs.c", 877), 0))
;
878 }
879 if (parentptr) {
880 VPutVnode(&fileCode, parentptr);
881 osi_Assert(!fileCode || (fileCode == VSALVAGE))(void)((!fileCode || (fileCode == 101)) || (osi_AssertFailU("!fileCode || (fileCode == VSALVAGE)"
, "./../viced/afsfileprocs.c", 881), 0))
;
882 }
883 if (volptr) {
884 VPutVolumeWithCall(volptr, cbv);
885 }
886 if (*client) {
887 PutClient(client);
888 }
889} /*PutVolumePackage */
890
891static_inlinestatic inline void
892PutVolumePackage(Vnode * parentwhentargetnotdir, Vnode * targetptr,
893 Vnode * parentptr, Volume * volptr, struct client **client)
894{
895 PutVolumePackageWithCall(parentwhentargetnotdir, targetptr, parentptr,
896 volptr, client, NULL((void *)0));
897}
898
899static int
900VolumeOwner(struct client *client, Vnode * targetptr)
901{
902 afs_int32 owner = V_owner(targetptr->volumePtr)((targetptr->volumePtr)->header->diskstuff.owner); /* get volume owner */
903
904 if (owner >= 0)
905 return (client->ViceId == owner);
906 else {
907 /*
908 * We don't have to check for host's cps since only regular
909 * viceid are volume owners.
910 */
911 return (client_HasAsMember(client, owner));
912 }
913
914} /*VolumeOwner */
915
916static int
917VolumeRootVnode(Vnode * targetptr)
918{
919 return ((targetptr->vnodeNumber == ROOTVNODE1)
920 && (targetptr->disk.uniquifier == 1));
921
922} /*VolumeRootVnode */
923
924/*
925 * Check if target file has the proper access permissions for the Fetch
926 * (FetchData, FetchACL, FetchStatus) and Store (StoreData, StoreACL,
927 * StoreStatus) related calls
928 */
929/* this code should probably just set a "priv" flag where all the audit events
930 * are now, and only generate the audit event once at the end of the routine,
931 * thus only generating the event if all the checks succeed, but only because
932 * of the privilege XXX
933 */
934static afs_int32
935Check_PermissionRights(Vnode * targetptr, struct client *client,
936 afs_int32 rights, int CallingRoutine,
937 AFSStoreStatus * InStatus)
938{
939 Errorbit32 errorCode = 0;
940#define OWNSp(client, target)((client)->ViceId == (target)->disk.owner) ((client)->ViceId == (target)->disk.owner)
941#define CHOWN(i,t)(((i)->Mask & 2) &&((i)->Owner != (t)->disk
.owner))
(((i)->Mask & AFS_SETOWNER2) &&((i)->Owner != (t)->disk.owner))
942#define CHGRP(i,t)(((i)->Mask & 4) &&((i)->Group != (t)->disk
.group))
(((i)->Mask & AFS_SETGROUP4) &&((i)->Group != (t)->disk.group))
943
944 if (CallingRoutine & CHK_FETCH0x10) {
945 if (CallingRoutine == CHK_FETCHDATA0x10 || VanillaUser(client)) {
946 if (targetptr->disk.type == vDirectory2
947 || targetptr->disk.type == vSymlink3) {
948 if (!(rights & PRSFS_LOOKUP8)
949#ifdef ADMIN_IMPLICIT_LOOKUP
950 /* grant admins fetch on all directories */
951 && VanillaUser(client)
952#endif /* ADMIN_IMPLICIT_LOOKUP */
953 && !VolumeOwner(client, targetptr))
954 return (EACCES13);
955 } else { /* file */
956 /* must have read access, or be owner and have insert access */
957 if (!(rights & PRSFS_READ1)
958 && !((OWNSp(client, targetptr)((client)->ViceId == (targetptr)->disk.owner) && (rights & PRSFS_INSERT4)
959 && (client->ViceId != AnonymousID))))
960 return (EACCES13);
961 }
962 if (CallingRoutine == CHK_FETCHDATA0x10
963 && targetptr->disk.type == vFile1)
964#ifdef USE_GROUP_PERMS
965 if (!OWNSp(client, targetptr)((client)->ViceId == (targetptr)->disk.owner)
966 && !client_HasAsMember(client, targetptr->disk.owner)) {
967 errorCode =
968 (((GROUPREAD | GROUPEXEC) & targetptr->disk.modeBits)
969 ? 0 : EACCES13);
970 } else {
971 errorCode =
972 (((OWNERREAD0400 | OWNEREXEC0100) & targetptr->disk.modeBits)
973 ? 0 : EACCES13);
974 }
975#else
976 /*
977 * The check with the ownership below is a kludge to allow
978 * reading of files created with no read permission. The owner
979 * of the file is always allowed to read it.
980 */
981 if ((client->ViceId != targetptr->disk.owner)
982 && VanillaUser(client))
983 errorCode =
984 (((OWNERREAD0400 | OWNEREXEC0100) & targetptr->disk.
985 modeBits) ? 0 : EACCES13);
986#endif
987 } else { /* !VanillaUser(client) && !FetchData */
988
989 osi_audit(PrivilegeEvent"AFS_Priv", 0, AUD_ID10,
990 (client ? client->ViceId : 0), AUD_INT2, CallingRoutine,
991 AUD_END0);
992 }
993 } else { /* a store operation */
994 if ((rights & PRSFS_INSERT4) && OWNSp(client, targetptr)((client)->ViceId == (targetptr)->disk.owner)
995 && (CallingRoutine != CHK_STOREACL0x01)
996 && (targetptr->disk.type == vFile1)) {
997 /* bypass protection checks on first store after a create
998 * for the creator; also prevent chowns during this time
999 * unless you are a system administrator */
1000 /****** InStatus->Owner && UnixModeBits better be SET!! */
1001 if (CHOWN(InStatus, targetptr)(((InStatus)->Mask & 2) &&((InStatus)->Owner
!= (targetptr)->disk.owner))
|| CHGRP(InStatus, targetptr)(((InStatus)->Mask & 4) &&((InStatus)->Group
!= (targetptr)->disk.group))
) {
1002 if (readonlyServer)
1003 return (VREADONLY30);
1004 else if (VanillaUser(client))
1005 return (EPERM1); /* Was EACCES */
1006 else
1007 osi_audit(PrivilegeEvent"AFS_Priv", 0, AUD_ID10,
1008 (client ? client->ViceId : 0), AUD_INT2,
1009 CallingRoutine, AUD_END0);
1010 }
1011 } else {
1012 if (CallingRoutine != CHK_STOREDATA0x00 && !VanillaUser(client)) {
1013 osi_audit(PrivilegeEvent"AFS_Priv", 0, AUD_ID10,
1014 (client ? client->ViceId : 0), AUD_INT2,
1015 CallingRoutine, AUD_END0);
1016 } else {
1017 if (readonlyServer) {
1018 return (VREADONLY30);
1019 }
1020 if (CallingRoutine == CHK_STOREACL0x01) {
1021 if (!(rights & PRSFS_ADMINISTER64)
1022 && !VolumeOwner(client, targetptr))
1023 return (EACCES13);
1024 } else { /* store data or status */
1025 /* watch for chowns and chgrps */
1026 if (CHOWN(InStatus, targetptr)(((InStatus)->Mask & 2) &&((InStatus)->Owner
!= (targetptr)->disk.owner))
1027 || CHGRP(InStatus, targetptr)(((InStatus)->Mask & 4) &&((InStatus)->Group
!= (targetptr)->disk.group))
) {
1028 if (readonlyServer)
1029 return (VREADONLY30);
1030 else if (VanillaUser(client))
1031 return (EPERM1); /* Was EACCES */
1032 else
1033 osi_audit(PrivilegeEvent"AFS_Priv", 0, AUD_ID10,
1034 (client ? client->ViceId : 0), AUD_INT2,
1035 CallingRoutine, AUD_END0);
1036 }
1037 /* must be sysadmin to set suid/sgid bits */
1038 if ((InStatus->Mask & AFS_SETMODE8) &&
1039#ifdef AFS_NT40_ENV
1040 (InStatus->UnixModeBits & 0xc00) != 0) {
1041#else
1042 (InStatus->UnixModeBits & (S_ISUID0004000 | S_ISGID0002000)) != 0) {
1043#endif
1044 if (readonlyServer)
1045 return (VREADONLY30);
1046 if (VanillaUser(client))
1047 return (EACCES13);
1048 else
1049 osi_audit(PrivSetID"AFS_PrivSet", 0, AUD_ID10,
1050 (client ? client->ViceId : 0), AUD_INT2,
1051 CallingRoutine, AUD_END0);
1052 }
1053 if (CallingRoutine == CHK_STOREDATA0x00) {
1054 if (readonlyServer)
1055 return (VREADONLY30);
1056 if (!(rights & PRSFS_WRITE2))
1057 return (EACCES13);
1058 /* Next thing is tricky. We want to prevent people
1059 * from writing files sans 0200 bit, but we want
1060 * creating new files with 0444 mode to work. We
1061 * don't check the 0200 bit in the "you are the owner"
1062 * path above, but here we check the bit. However, if
1063 * you're a system administrator, we ignore the 0200
1064 * bit anyway, since you may have fchowned the file,
1065 * too */
1066#ifdef USE_GROUP_PERMS
1067 if ((targetptr->disk.type == vFile1)
1068 && VanillaUser(client)) {
1069 if (!OWNSp(client, targetptr)((client)->ViceId == (targetptr)->disk.owner)
1070 && !client_HasAsMember(client, targetptr->disk.owner)) {
1071 errorCode =
1072 ((GROUPWRITE & targetptr->disk.modeBits)
1073 ? 0 : EACCES13);
1074 } else {
1075 errorCode =
1076 ((OWNERWRITE0200 & targetptr->disk.modeBits)
1077 ? 0 : EACCES13);
1078 }
1079 } else
1080#endif
1081 if ((targetptr->disk.type != vDirectory2)
1082 && (!(targetptr->disk.modeBits & OWNERWRITE0200))) {
1083 if (readonlyServer)
1084 return (VREADONLY30);
1085 if (VanillaUser(client))
1086 return (EACCES13);
1087 else
1088 osi_audit(PrivilegeEvent"AFS_Priv", 0, AUD_ID10,
1089 (client ? client->ViceId : 0),
1090 AUD_INT2, CallingRoutine, AUD_END0);
1091 }
1092 } else { /* a status store */
1093 if (readonlyServer)
1094 return (VREADONLY30);
1095 if (targetptr->disk.type == vDirectory2) {
1096 if (!(rights & PRSFS_DELETE16)
1097 && !(rights & PRSFS_INSERT4))
1098 return (EACCES13);
1099 } else { /* a file or symlink */
1100 if (!(rights & PRSFS_WRITE2))
1101 return (EACCES13);
1102 }
1103 }
1104 }
1105 }
1106 }
1107 }
1108 return (errorCode);
1109
1110} /*Check_PermissionRights */
1111
1112
1113/*
1114 * The Access List information is converted from its internal form in the
1115 * target's vnode buffer (or its parent vnode buffer if not a dir), to an
1116 * external form and returned back to the caller, via the AccessList
1117 * structure
1118 */
1119static afs_int32
1120RXFetch_AccessList(Vnode * targetptr, Vnode * parentwhentargetnotdir,
1121 struct AFSOpaque *AccessList)
1122{
1123 char *eACL; /* External access list placeholder */
1124
1125 if (acl_Externalize_pr
1126 (hpr_IdToName, (targetptr->disk.type ==
1127 vDirectory2 ? VVnodeACL(targetptr)(((AL_AccessList *) (((byte *)(&(targetptr)->disk))+64
)))
:
1128 VVnodeACL(parentwhentargetnotdir)(((AL_AccessList *) (((byte *)(&(parentwhentargetnotdir)->
disk))+64)))
), &eACL) != 0) {
1129 return EIO5;
1130 }
1131 if ((strlen(eACL) + 1) > AFSOPAQUEMAX1024) {
1132 acl_FreeExternalACL(&eACL);
1133 return (E2BIG7);
1134 } else {
1135 strcpy((char *)(AccessList->AFSOpaque_val), (char *)eACL);
1136 AccessList->AFSOpaque_len = strlen(eACL) + 1;
1137 }
1138 acl_FreeExternalACL(&eACL);
1139 return (0);
1140
1141} /*RXFetch_AccessList */
1142
1143
1144/*
1145 * The Access List information is converted from its external form in the
1146 * input AccessList structure to the internal representation and copied into
1147 * the target dir's vnode storage.
1148 */
1149static afs_int32
1150RXStore_AccessList(Vnode * targetptr, struct AFSOpaque *AccessList)
1151{
1152 struct acl_accessList *newACL; /* PlaceHolder for new access list */
1153
1154 if (acl_Internalize_pr(hpr_NameToId, AccessList->AFSOpaque_val, &newACL)
1155 != 0)
1156 return (EINVAL22);
1157 if ((newACL->size + 4) > VAclSize(targetptr)(256 - 64))
1158 return (E2BIG7);
1159 memcpy((char *)VVnodeACL(targetptr)(((AL_AccessList *) (((byte *)(&(targetptr)->disk))+64
)))
, (char *)newACL, (int)(newACL->size));
1160 acl_FreeACL(&newACL);
1161 return (0);
1162
1163} /*RXStore_AccessList */
1164
1165
1166/* In our current implementation, each successive data store (new file
1167 * data version) creates a new inode. This function creates the new
1168 * inode, copies the old inode's contents to the new one, remove the old
1169 * inode (i.e. decrement inode count -- if it's currently used the delete
1170 * will be delayed), and modify some fields (i.e. vnode's
1171 * disk.inodeNumber and cloned)
1172 */
1173#define COPYBUFFSIZE8192 8192
1174#define MAXFSIZE(~(afs_fsize_t) 0) (~(afs_fsize_t) 0)
1175static int
1176CopyOnWrite(Vnode * targetptr, Volume * volptr, afs_foff_t off, afs_fsize_t len)
1177{
1178 Inode ino;
1179 Inode nearInode AFS_UNUSED__attribute__((unused));
1180 ssize_t rdlen;
1181 ssize_t wrlen;
1182 afs_fsize_t size;
1183 afs_foff_t done;
1184 size_t length;
1185 char *buff;
1186 int rc; /* return code */
1187 IHandle_t *newH; /* Use until finished copying, then cp to vnode. */
1188 FdHandle_t *targFdP; /* Source Inode file handle */
1189 FdHandle_t *newFdP; /* Dest Inode file handle */
1190
1191 if (targetptr->disk.type == vDirectory2)
1192 DFlush(); /* just in case? */
1193
1194 VN_GET_LEN(size, targetptr)(size) = ((afs_int64)((targetptr)->disk.vn_length_hi) <<
32) | ((targetptr)->disk.length);
;
1195 if (size > off)
1196 size -= off;
1197 else
1198 size = 0;
1199 if (size > len)
1200 size = len;
1201
1202 buff = (char *)malloc(COPYBUFFSIZE8192);
1203 if (buff == NULL((void *)0)) {
1204 return EIO5;
1205 }
1206
1207 ino = VN_GET_INO(targetptr)((Inode)((targetptr)->disk.vn_ino_lo | ((targetptr)->disk
.vn_ino_hi ? (((Inode)(targetptr)->disk.vn_ino_hi)<<
32) : 0)))
;
1208 if (!VALID_INO(ino)((ino) != (Inode)-1 && (ino) != (Inode)0)) {
1209 free(buff);
1210 VTakeOffline(volptr);
1211 ViceLog(0, ("Volume %u now offline, must be salvaged.\n",do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
1212 volptr->hashid))do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
;
1213 return EIO5;
1214 }
1215 targFdP = IH_OPEN(targetptr->handle)ih_open(targetptr->handle);
1216 if (targFdP == NULL((void *)0)) {
1217 rc = errno(* __error());
1218 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("CopyOnWrite failed: Failed to open target vnode %u in volume %u (errno = %d)\n"
, targetptr->vnodeNumber, ((volptr)->header->diskstuff
.id), rc)); } while (0)
1219 ("CopyOnWrite failed: Failed to open target vnode %u in volume %u (errno = %d)\n",do { if ((0) <= LogLevel) (FSLog ("CopyOnWrite failed: Failed to open target vnode %u in volume %u (errno = %d)\n"
, targetptr->vnodeNumber, ((volptr)->header->diskstuff
.id), rc)); } while (0)
1220 targetptr->vnodeNumber, V_id(volptr), rc))do { if ((0) <= LogLevel) (FSLog ("CopyOnWrite failed: Failed to open target vnode %u in volume %u (errno = %d)\n"
, targetptr->vnodeNumber, ((volptr)->header->diskstuff
.id), rc)); } while (0)
;
1221 free(buff);
1222 VTakeOffline(volptr);
1223 return rc;
1224 }
1225
1226 nearInode = VN_GET_INO(targetptr)((Inode)((targetptr)->disk.vn_ino_lo | ((targetptr)->disk
.vn_ino_hi ? (((Inode)(targetptr)->disk.vn_ino_hi)<<
32) : 0)))
;
1227 ino =
1228 IH_CREATE(V_linkHandle(volptr), V_device(volptr),namei_icreate(((volptr)->linkHandle), VPartitionPath(((volptr
)->partition)), ((volptr)->header->diskstuff.id), targetptr
->vnodeNumber, targetptr->disk.uniquifier, (int)targetptr
->disk.dataVersion)
1229 VPartitionPath(V_partition(volptr)), nearInode,namei_icreate(((volptr)->linkHandle), VPartitionPath(((volptr
)->partition)), ((volptr)->header->diskstuff.id), targetptr
->vnodeNumber, targetptr->disk.uniquifier, (int)targetptr
->disk.dataVersion)
1230 V_id(volptr), targetptr->vnodeNumber,namei_icreate(((volptr)->linkHandle), VPartitionPath(((volptr
)->partition)), ((volptr)->header->diskstuff.id), targetptr
->vnodeNumber, targetptr->disk.uniquifier, (int)targetptr
->disk.dataVersion)
1231 targetptr->disk.uniquifier,namei_icreate(((volptr)->linkHandle), VPartitionPath(((volptr
)->partition)), ((volptr)->header->diskstuff.id), targetptr
->vnodeNumber, targetptr->disk.uniquifier, (int)targetptr
->disk.dataVersion)
1232 (int)targetptr->disk.dataVersion)namei_icreate(((volptr)->linkHandle), VPartitionPath(((volptr
)->partition)), ((volptr)->header->diskstuff.id), targetptr
->vnodeNumber, targetptr->disk.uniquifier, (int)targetptr
->disk.dataVersion)
;
1233 if (!VALID_INO(ino)((ino) != (Inode)-1 && (ino) != (Inode)0)) {
1234 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("CopyOnWrite failed: Partition %s that contains volume %u may be out of free inodes(errno = %d)\n"
, volptr->partition->name, ((volptr)->header->diskstuff
.id), (* __error()))); } while (0)
1235 ("CopyOnWrite failed: Partition %s that contains volume %u may be out of free inodes(errno = %d)\n",do { if ((0) <= LogLevel) (FSLog ("CopyOnWrite failed: Partition %s that contains volume %u may be out of free inodes(errno = %d)\n"
, volptr->partition->name, ((volptr)->header->diskstuff
.id), (* __error()))); } while (0)
1236 volptr->partition->name, V_id(volptr), errno))do { if ((0) <= LogLevel) (FSLog ("CopyOnWrite failed: Partition %s that contains volume %u may be out of free inodes(errno = %d)\n"
, volptr->partition->name, ((volptr)->header->diskstuff
.id), (* __error()))); } while (0)
;
1237 FDH_CLOSE(targFdP)(fd_close(targFdP), (targFdP)=((void *)0), 0);
1238 free(buff);
1239 return ENOSPC28;
1240 }
1241 IH_INIT(newH, V_device(volptr), V_id(volptr), ino)((newH) = ih_init((((volptr)->device)), (((volptr)->header
->diskstuff.id)), (ino)))
;
1242 newFdP = IH_OPEN(newH)ih_open(newH);
1243 osi_Assert(newFdP != NULL)(void)((newFdP != ((void *)0)) || (osi_AssertFailU("newFdP != NULL"
, "./../viced/afsfileprocs.c", 1243), 0))
;
1244
1245 done = off;
1246 while (size > 0) {
1247 if (size > COPYBUFFSIZE8192) { /* more than a buffer */
1248 length = COPYBUFFSIZE8192;
1249 size -= COPYBUFFSIZE8192;
1250 } else {
1251 length = size;
1252 size = 0;
1253 }
1254 rdlen = FDH_PREAD(targFdP, buff, length, done)pread((targFdP)->fd_fd, buff, length, done);
1255 if (rdlen == length) {
1256 wrlen = FDH_PWRITE(newFdP, buff, length, done)pwrite((newFdP)->fd_fd, buff, length, done);
1257 done += rdlen;
1258 } else
1259 wrlen = 0;
1260 /* Callers of this function are not prepared to recover
1261 * from error that put the filesystem in an inconsistent
1262 * state. Make sure that we force the volume off-line if
1263 * we some error other than ENOSPC - 4.29.99)
1264 *
1265 * In case we are unable to write the required bytes, and the
1266 * error code indicates that the disk is full, we roll-back to
1267 * the initial state.
1268 */
1269 if ((rdlen != length) || (wrlen != length)) {
1270 if ((wrlen < 0) && (errno(* __error()) == ENOSPC28)) { /* disk full */
1271 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("CopyOnWrite failed: Partition %s containing volume %u is full\n"
, volptr->partition->name, ((volptr)->header->diskstuff
.id))); } while (0)
1272 ("CopyOnWrite failed: Partition %s containing volume %u is full\n",do { if ((0) <= LogLevel) (FSLog ("CopyOnWrite failed: Partition %s containing volume %u is full\n"
, volptr->partition->name, ((volptr)->header->diskstuff
.id))); } while (0)
1273 volptr->partition->name, V_id(volptr)))do { if ((0) <= LogLevel) (FSLog ("CopyOnWrite failed: Partition %s containing volume %u is full\n"
, volptr->partition->name, ((volptr)->header->diskstuff
.id))); } while (0)
;
1274 /* remove destination inode which was partially copied till now */
1275 FDH_REALLYCLOSE(newFdP)(fd_reallyclose(newFdP), (newFdP)=((void *)0), 0);
1276 IH_RELEASE(newH)(ih_release(newH), (newH)=((void *)0), 0);
1277 FDH_REALLYCLOSE(targFdP)(fd_reallyclose(targFdP), (targFdP)=((void *)0), 0);
1278 rc = IH_DEC(V_linkHandle(volptr), ino, V_parentId(volptr))namei_dec(((volptr)->linkHandle), ino, ((volptr)->header
->diskstuff.parentId))
;
1279 if (!rc) {
1280 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("CopyOnWrite failed: error %u after i_dec on disk full, volume %u in partition %s needs salvage\n"
, rc, ((volptr)->header->diskstuff.id), volptr->partition
->name)); } while (0)
1281 ("CopyOnWrite failed: error %u after i_dec on disk full, volume %u in partition %s needs salvage\n",do { if ((0) <= LogLevel) (FSLog ("CopyOnWrite failed: error %u after i_dec on disk full, volume %u in partition %s needs salvage\n"
, rc, ((volptr)->header->diskstuff.id), volptr->partition
->name)); } while (0)
1282 rc, V_id(volptr), volptr->partition->name))do { if ((0) <= LogLevel) (FSLog ("CopyOnWrite failed: error %u after i_dec on disk full, volume %u in partition %s needs salvage\n"
, rc, ((volptr)->header->diskstuff.id), volptr->partition
->name)); } while (0)
;
1283 VTakeOffline(volptr);
1284 }
1285 free(buff);
1286 return ENOSPC28;
1287 } else {
1288 /* length, rdlen, and wrlen may or may not be 64-bits wide;
1289 * since we never do any I/O anywhere near 2^32 bytes at a
1290 * time, just case to an unsigned int for printing */
1291
1292 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("CopyOnWrite failed: volume %u in partition %s (tried reading %u, read %u, wrote %u, errno %u) volume needs salvage\n"
, ((volptr)->header->diskstuff.id), volptr->partition
->name, (unsigned)length, (unsigned)rdlen, (unsigned)wrlen
, (* __error()))); } while (0)
1293 ("CopyOnWrite failed: volume %u in partition %s (tried reading %u, read %u, wrote %u, errno %u) volume needs salvage\n",do { if ((0) <= LogLevel) (FSLog ("CopyOnWrite failed: volume %u in partition %s (tried reading %u, read %u, wrote %u, errno %u) volume needs salvage\n"
, ((volptr)->header->diskstuff.id), volptr->partition
->name, (unsigned)length, (unsigned)rdlen, (unsigned)wrlen
, (* __error()))); } while (0)
1294 V_id(volptr), volptr->partition->name, (unsigned)length, (unsigned)rdlen,do { if ((0) <= LogLevel) (FSLog ("CopyOnWrite failed: volume %u in partition %s (tried reading %u, read %u, wrote %u, errno %u) volume needs salvage\n"
, ((volptr)->header->diskstuff.id), volptr->partition
->name, (unsigned)length, (unsigned)rdlen, (unsigned)wrlen
, (* __error()))); } while (0)
1295 (unsigned)wrlen, errno))do { if ((0) <= LogLevel) (FSLog ("CopyOnWrite failed: volume %u in partition %s (tried reading %u, read %u, wrote %u, errno %u) volume needs salvage\n"
, ((volptr)->header->diskstuff.id), volptr->partition
->name, (unsigned)length, (unsigned)rdlen, (unsigned)wrlen
, (* __error()))); } while (0)
;
1296#if defined(AFS_DEMAND_ATTACH_FS1)
1297 ViceLog(0, ("CopyOnWrite failed: requesting salvage\n"))do { if ((0) <= LogLevel) (FSLog ("CopyOnWrite failed: requesting salvage\n"
)); } while (0)
;
1298#else
1299 ViceLog(0, ("CopyOnWrite failed: taking volume offline\n"))do { if ((0) <= LogLevel) (FSLog ("CopyOnWrite failed: taking volume offline\n"
)); } while (0)
;
1300#endif
1301 /* Decrement this inode so salvager doesn't find it. */
1302 FDH_REALLYCLOSE(newFdP)(fd_reallyclose(newFdP), (newFdP)=((void *)0), 0);
1303 IH_RELEASE(newH)(ih_release(newH), (newH)=((void *)0), 0);
1304 FDH_REALLYCLOSE(targFdP)(fd_reallyclose(targFdP), (targFdP)=((void *)0), 0);
1305 rc = IH_DEC(V_linkHandle(volptr), ino, V_parentId(volptr))namei_dec(((volptr)->linkHandle), ino, ((volptr)->header
->diskstuff.parentId))
;
Value stored to 'rc' is never read
1306 free(buff);
1307 VTakeOffline(volptr);
1308 return EIO5;
1309 }
1310 }
1311#ifndef AFS_PTHREAD_ENV1
1312 IOMGR_Poll();
1313#endif /* !AFS_PTHREAD_ENV */
1314 }
1315 FDH_REALLYCLOSE(targFdP)(fd_reallyclose(targFdP), (targFdP)=((void *)0), 0);
1316 rc = IH_DEC(V_linkHandle(volptr), VN_GET_INO(targetptr),namei_dec(((volptr)->linkHandle), ((Inode)((targetptr)->
disk.vn_ino_lo | ((targetptr)->disk.vn_ino_hi ? (((Inode)(
targetptr)->disk.vn_ino_hi)<<32) : 0))), ((volptr)->
header->diskstuff.parentId))
1317 V_parentId(volptr))namei_dec(((volptr)->linkHandle), ((Inode)((targetptr)->
disk.vn_ino_lo | ((targetptr)->disk.vn_ino_hi ? (((Inode)(
targetptr)->disk.vn_ino_hi)<<32) : 0))), ((volptr)->
header->diskstuff.parentId))
;
1318 osi_Assert(!rc)(void)((!rc) || (osi_AssertFailU("!rc", "./../viced/afsfileprocs.c"
, 1318), 0))
;
1319 IH_RELEASE(targetptr->handle)(ih_release(targetptr->handle), (targetptr->handle)=((void
*)0), 0)
;
1320
1321 rc = FDH_SYNC(newFdP)((newFdP->fd_ih!=((void *)0)) ? ( newFdP->fd_ih->ih_synced
= 1) - 1 : 1)
;
1322 osi_Assert(rc == 0)(void)((rc == 0) || (osi_AssertFailU("rc == 0", "./../viced/afsfileprocs.c"
, 1322), 0))
;
1323 FDH_CLOSE(newFdP)(fd_close(newFdP), (newFdP)=((void *)0), 0);
1324 targetptr->handle = newH;
1325 VN_SET_INO(targetptr, ino)((targetptr)->disk.vn_ino_lo = (int)((ino)&0xffffffff)
, ((targetptr)->disk.vn_ino_hi = (ino) ? (int)(((ino)>>
32)&0xffffffff) : 0))
;
1326 targetptr->disk.cloned = 0;
1327 /* Internal change to vnode, no user level change to volume - def 5445 */
1328 targetptr->changed_oldTime = 1;
1329 free(buff);
1330 return 0; /* success */
1331} /*CopyOnWrite */
1332
1333static int
1334CopyOnWrite2(FdHandle_t *targFdP, FdHandle_t *newFdP, afs_foff_t off,
1335 afs_sfsize_t size)
1336{
1337 char *buff = malloc(COPYBUFFSIZE8192);
1338 size_t length;
1339 ssize_t rdlen;
1340 ssize_t wrlen;
1341 int rc = 0;
1342 afs_foff_t done = off;
1343
1344 if (size > FDH_SIZE(targFdP)ih_size((targFdP)->fd_fd) - off)
1345 size = FDH_SIZE(targFdP)ih_size((targFdP)->fd_fd) - off;
1346
1347 while (size > 0) {
1348 if (size > COPYBUFFSIZE8192) { /* more than a buffer */
1349 length = COPYBUFFSIZE8192;
1350 size -= COPYBUFFSIZE8192;
1351 } else {
1352 length = size;
1353 size = 0;
1354 }
1355 rdlen = FDH_PREAD(targFdP, buff, length, done)pread((targFdP)->fd_fd, buff, length, done);
1356 if (rdlen == length) {
1357 wrlen = FDH_PWRITE(newFdP, buff, length, done)pwrite((newFdP)->fd_fd, buff, length, done);
1358 done += rdlen;
1359 }
1360 else
1361 wrlen = 0;
1362
1363 if ((rdlen != length) || (wrlen != length)) {
1364 /* no error recovery, at the worst we'll have a "hole"
1365 * in the file */
1366 rc = 1;
1367 break;
1368 }
1369 }
1370 free(buff);
1371 return rc;
1372}
1373
1374
1375/*
1376 * Common code to handle with removing the Name (file when it's called from
1377 * SAFS_RemoveFile() or an empty dir when called from SAFS_rmdir()) from a
1378 * given directory, parentptr.
1379 */
1380int DT1 = 0, DT0 = 0;
1381static afs_int32
1382DeleteTarget(Vnode * parentptr, Volume * volptr, Vnode ** targetptr,
1383 DirHandle * dir, AFSFid * fileFid, char *Name, int ChkForDir)
1384{
1385 DirHandle childdir; /* Handle for dir package I/O */
1386 Errorbit32 errorCode = 0;
1387 int code;
1388 afs_ino_str_t stmp;
1389
1390 /* watch for invalid names */
1391 if (!strcmp(Name, ".") || !strcmp(Name, ".."))
1392 return (EINVAL22);
1393
1394 if (CheckLength(volptr, parentptr, -1)) {
1395 VTakeOffline(volptr);
1396 return VSALVAGE101;
1397 }
1398
1399 if (parentptr->disk.cloned) {
1400 ViceLog(25, ("DeleteTarget : CopyOnWrite called\n"))do { if ((25) <= LogLevel) (FSLog ("DeleteTarget : CopyOnWrite called\n"
)); } while (0)
;
1401 if ((errorCode = CopyOnWrite(parentptr, volptr, 0, MAXFSIZE(~(afs_fsize_t) 0)))) {
1402 ViceLog(20,do { if ((20) <= LogLevel) (FSLog ("DeleteTarget %s: CopyOnWrite failed %d\n"
, Name, errorCode)); } while (0)
1403 ("DeleteTarget %s: CopyOnWrite failed %d\n", Name,do { if ((20) <= LogLevel) (FSLog ("DeleteTarget %s: CopyOnWrite failed %d\n"
, Name, errorCode)); } while (0)
1404 errorCode))do { if ((20) <= LogLevel) (FSLog ("DeleteTarget %s: CopyOnWrite failed %d\n"
, Name, errorCode)); } while (0)
;
1405 return errorCode;
1406 }
1407 }
1408
1409 /* check that the file is in the directory */
1410 SetDirHandle(dir, parentptr);
1411 if (afs_dir_Lookup(dir, Name, fileFid))
1412 return (ENOENT2);
1413 fileFid->Volume = V_id(volptr)((volptr)->header->diskstuff.id);
1414
1415 /* just-in-case check for something causing deadlock */
1416 if (fileFid->Vnode == parentptr->vnodeNumber)
1417 return (EINVAL22);
1418
1419 *targetptr = VGetVnode(&errorCode, volptr, fileFid->Vnode, WRITE_LOCK2);
1420 if (errorCode) {
1421 return (errorCode);
1422 }
1423 if (ChkForDir == MustBeDIR2) {
1424 if ((*targetptr)->disk.type != vDirectory2)
1425 return (ENOTDIR20);
1426 } else if ((*targetptr)->disk.type == vDirectory2)
1427 return (EISDIR21);
1428
1429 /*osi_Assert((*targetptr)->disk.uniquifier == fileFid->Unique); */
1430 /**
1431 * If the uniquifiers dont match then instead of asserting
1432 * take the volume offline and return VSALVAGE
1433 */
1434 if ((*targetptr)->disk.uniquifier != fileFid->Unique) {
1435 VTakeOffline(volptr);
1436 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
1437 ("Volume %u now offline, must be salvaged.\n",do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
1438 volptr->hashid))do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
;
1439 errorCode = VSALVAGE101;
1440 return errorCode;
1441 }
1442
1443 if (ChkForDir == MustBeDIR2) {
1444 SetDirHandle(&childdir, *targetptr);
1445 if (afs_dir_IsEmpty(&childdir) != 0)
1446 return (EEXIST17);
1447 DZap(&childdir);
1448 FidZap(&childdir);
1449 (*targetptr)->delete = 1;
1450 } else if ((--(*targetptr)->disk.linkCount) == 0)
1451 (*targetptr)->delete = 1;
1452 if ((*targetptr)->delete) {
1453 if (VN_GET_INO(*targetptr)((Inode)((*targetptr)->disk.vn_ino_lo | ((*targetptr)->
disk.vn_ino_hi ? (((Inode)(*targetptr)->disk.vn_ino_hi)<<
32) : 0)))
) {
1454 DT0++;
1455 IH_REALLYCLOSE((*targetptr)->handle)ih_reallyclose((*targetptr)->handle);
1456 errorCode =
1457 IH_DEC(V_linkHandle(volptr), VN_GET_INO(*targetptr),namei_dec(((volptr)->linkHandle), ((Inode)((*targetptr)->
disk.vn_ino_lo | ((*targetptr)->disk.vn_ino_hi ? (((Inode)
(*targetptr)->disk.vn_ino_hi)<<32) : 0))), ((volptr)
->header->diskstuff.parentId))
1458 V_parentId(volptr))namei_dec(((volptr)->linkHandle), ((Inode)((*targetptr)->
disk.vn_ino_lo | ((*targetptr)->disk.vn_ino_hi ? (((Inode)
(*targetptr)->disk.vn_ino_hi)<<32) : 0))), ((volptr)
->header->diskstuff.parentId))
;
1459 IH_RELEASE((*targetptr)->handle)(ih_release((*targetptr)->handle), ((*targetptr)->handle
)=((void *)0), 0)
;
1460 if (errorCode == -1) {
1461 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("DT: inode=%s, name=%s, errno=%d\n"
, PrintInode(stmp, ((Inode)((*targetptr)->disk.vn_ino_lo |
((*targetptr)->disk.vn_ino_hi ? (((Inode)(*targetptr)->
disk.vn_ino_hi)<<32) : 0)))), Name, (* __error()))); } while
(0)
1462 ("DT: inode=%s, name=%s, errno=%d\n",do { if ((0) <= LogLevel) (FSLog ("DT: inode=%s, name=%s, errno=%d\n"
, PrintInode(stmp, ((Inode)((*targetptr)->disk.vn_ino_lo |
((*targetptr)->disk.vn_ino_hi ? (((Inode)(*targetptr)->
disk.vn_ino_hi)<<32) : 0)))), Name, (* __error()))); } while
(0)
1463 PrintInode(stmp, VN_GET_INO(*targetptr)), Name,do { if ((0) <= LogLevel) (FSLog ("DT: inode=%s, name=%s, errno=%d\n"
, PrintInode(stmp, ((Inode)((*targetptr)->disk.vn_ino_lo |
((*targetptr)->disk.vn_ino_hi ? (((Inode)(*targetptr)->
disk.vn_ino_hi)<<32) : 0)))), Name, (* __error()))); } while
(0)
1464 errno))do { if ((0) <= LogLevel) (FSLog ("DT: inode=%s, name=%s, errno=%d\n"
, PrintInode(stmp, ((Inode)((*targetptr)->disk.vn_ino_lo |
((*targetptr)->disk.vn_ino_hi ? (((Inode)(*targetptr)->
disk.vn_ino_hi)<<32) : 0)))), Name, (* __error()))); } while
(0)
;
1465 if (errno(* __error()) != ENOENT2)
1466 {
1467 VTakeOffline(volptr);
1468 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
1469 ("Volume %u now offline, must be salvaged.\n",do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
1470 volptr->hashid))do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
;
1471 return (EIO5);
1472 }
1473 DT1++;
1474 errorCode = 0;
1475 }
1476 }
1477 VN_SET_INO(*targetptr, (Inode) 0)((*targetptr)->disk.vn_ino_lo = (int)(((Inode) 0)&0xffffffff
), ((*targetptr)->disk.vn_ino_hi = ((Inode) 0) ? (int)((((
Inode) 0)>>32)&0xffffffff) : 0))
;
1478 {
1479 afs_fsize_t adjLength;
1480 VN_GET_LEN(adjLength, *targetptr)(adjLength) = ((afs_int64)((*targetptr)->disk.vn_length_hi
) << 32) | ((*targetptr)->disk.length);
;
1481 VAdjustDiskUsage(&errorCode, volptr, -(int)nBlocks(adjLength)((afs_sfsize_t)((adjLength) == 0? 1: (((afs_sfsize_t)(adjLength
))+1023)/1024))
, 0);
1482 }
1483 }
1484
1485 (*targetptr)->changed_newTime = 1; /* Status change of deleted file/dir */
1486
1487 code = afs_dir_Delete(dir, Name);
1488 if (code) {
1489 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("Error %d deleting %s\n"
, code, (((*targetptr)->disk.type == 2) ? "directory" : "file"
))); } while (0)
1490 ("Error %d deleting %s\n", code,do { if ((0) <= LogLevel) (FSLog ("Error %d deleting %s\n"
, code, (((*targetptr)->disk.type == 2) ? "directory" : "file"
))); } while (0)
1491 (((*targetptr)->disk.type ==do { if ((0) <= LogLevel) (FSLog ("Error %d deleting %s\n"
, code, (((*targetptr)->disk.type == 2) ? "directory" : "file"
))); } while (0)
1492 Directory) ? "directory" : "file")))do { if ((0) <= LogLevel) (FSLog ("Error %d deleting %s\n"
, code, (((*targetptr)->disk.type == 2) ? "directory" : "file"
))); } while (0)
;
1493 VTakeOffline(volptr);
1494 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
1495 ("Volume %u now offline, must be salvaged.\n",do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
1496 volptr->hashid))do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
;
1497 if (!errorCode)
1498 errorCode = code;
1499 }
1500
1501 DFlush();
1502 return (errorCode);
1503
1504} /*DeleteTarget */
1505
1506
1507/*
1508 * This routine updates the parent directory's status block after the
1509 * specified operation (i.e. RemoveFile(), CreateFile(), Rename(),
1510 * SymLink(), Link(), MakeDir(), RemoveDir()) on one of its children has
1511 * been performed.
1512 */
1513static void
1514Update_ParentVnodeStatus(Vnode * parentptr, Volume * volptr, DirHandle * dir,
1515 int author, int linkcount,
1516#if FS_STATS_DETAILED1
1517 char a_inSameNetwork
1518#endif /* FS_STATS_DETAILED */
1519 )
1520{
1521 afs_fsize_t newlength; /* Holds new directory length */
1522 afs_fsize_t parentLength;
1523 Errorbit32 errorCode;
1524#if FS_STATS_DETAILED1
1525 Dateafs_uint32 currDate; /*Current date */
1526 int writeIdx; /*Write index to bump */
1527 int timeIdx; /*Authorship time index to bump */
1528#endif /* FS_STATS_DETAILED */
1529
1530 parentptr->disk.dataVersion++;
1531 newlength = (afs_fsize_t) afs_dir_Length(dir);
1532 /*
1533 * This is a called on both dir removals (i.e. remove, removedir, rename) but also in dir additions
1534 * (create, symlink, link, makedir) so we need to check if we have enough space
1535 * XXX But we still don't check the error since we're dealing with dirs here and really the increase
1536 * of a new entry would be too tiny to worry about failures (since we have all the existing cushion)
1537 */
1538 VN_GET_LEN(parentLength, parentptr)(parentLength) = ((afs_int64)((parentptr)->disk.vn_length_hi
) << 32) | ((parentptr)->disk.length);
;
1539 if (nBlocks(newlength)((afs_sfsize_t)((newlength) == 0? 1: (((afs_sfsize_t)(newlength
))+1023)/1024))
!= nBlocks(parentLength)((afs_sfsize_t)((parentLength) == 0? 1: (((afs_sfsize_t)(parentLength
))+1023)/1024))
) {
1540 VAdjustDiskUsage(&errorCode, volptr,
1541 (nBlocks(newlength)((afs_sfsize_t)((newlength) == 0? 1: (((afs_sfsize_t)(newlength
))+1023)/1024))
- nBlocks(parentLength)((afs_sfsize_t)((parentLength) == 0? 1: (((afs_sfsize_t)(parentLength
))+1023)/1024))
),
1542 (nBlocks(newlength)((afs_sfsize_t)((newlength) == 0? 1: (((afs_sfsize_t)(newlength
))+1023)/1024))
- nBlocks(parentLength)((afs_sfsize_t)((parentLength) == 0? 1: (((afs_sfsize_t)(parentLength
))+1023)/1024))
));
1543 }
1544 VN_SET_LEN(parentptr, newlength)((parentptr)->disk.vn_length_hi) = ((afs_int64)newlength) >>
32; ((parentptr)->disk.length) = (newlength) & 0xFFFFFFFF
;
;
1545
1546#if FS_STATS_DETAILED1
1547 /*
1548 * Update directory write stats for this volume. Note that the auth
1549 * counter is located immediately after its associated ``distance''
1550 * counter.
1551 */
1552 if (a_inSameNetwork)
1553 writeIdx = VOL_STATS_SAME_NET0;
1554 else
1555 writeIdx = VOL_STATS_DIFF_NET2;
1556 V_stat_writes(volptr, writeIdx)(((volptr)->header->diskstuff.stat_writes)[writeIdx])++;
1557 if (author != AnonymousID) {
1558 V_stat_writes(volptr, writeIdx + 1)(((volptr)->header->diskstuff.stat_writes)[writeIdx + 1
])
++;
1559 }
1560
1561 /*
1562 * Update the volume's authorship information in response to this
1563 * directory operation. Get the current time, decide to which time
1564 * slot this operation belongs, and bump the appropriate slot.
1565 */
1566 currDate = (FT_ApproxTime() - parentptr->disk.unixModifyTime);
1567 timeIdx =
1568 (currDate < VOL_STATS_TIME_CAP_060 ? VOL_STATS_TIME_IDX_00 : currDate <
1569 VOL_STATS_TIME_CAP_1600 ? VOL_STATS_TIME_IDX_11 : currDate <
1570 VOL_STATS_TIME_CAP_23600 ? VOL_STATS_TIME_IDX_22 : currDate <
1571 VOL_STATS_TIME_CAP_386400 ? VOL_STATS_TIME_IDX_33 : currDate <
1572 VOL_STATS_TIME_CAP_4604800 ? VOL_STATS_TIME_IDX_44 : VOL_STATS_TIME_IDX_55);
1573 if (parentptr->disk.author == author) {
1574 V_stat_dirSameAuthor(volptr, timeIdx)(((volptr)->header->diskstuff.stat_dirSameAuthor)[timeIdx
])
++;
1575 } else {
1576 V_stat_dirDiffAuthor(volptr, timeIdx)(((volptr)->header->diskstuff.stat_dirDiffAuthor)[timeIdx
])
++;
1577 }
1578#endif /* FS_STATS_DETAILED */
1579
1580 parentptr->disk.author = author;
1581 parentptr->disk.linkCount = linkcount;
1582 parentptr->disk.unixModifyTime = FT_ApproxTime(); /* This should be set from CLIENT!! */
1583 parentptr->disk.serverModifyTime = FT_ApproxTime();
1584 parentptr->changed_newTime = 1; /* vnode changed, write it back. */
1585}
1586
1587
1588/*
1589 * Update the target file's (or dir's) status block after the specified
1590 * operation is complete. Note that some other fields maybe updated by
1591 * the individual module.
1592 */
1593
1594/* XXX INCOMPLETE - More attention is needed here! */
1595static void
1596Update_TargetVnodeStatus(Vnode * targetptr, afs_uint32 Caller,
1597 struct client *client, AFSStoreStatus * InStatus,
1598 Vnode * parentptr, Volume * volptr,
1599 afs_fsize_t length)
1600{
1601#if FS_STATS_DETAILED1
1602 Dateafs_uint32 currDate; /*Current date */
1603 int writeIdx; /*Write index to bump */
1604 int timeIdx; /*Authorship time index to bump */
1605#endif /* FS_STATS_DETAILED */
1606
1607 if (Caller & (TVS_CFILE4 | TVS_SLINK8 | TVS_MKDIR0x10)) { /* initialize new file */
1608 targetptr->disk.parent = parentptr->vnodeNumber;
1609 VN_SET_LEN(targetptr, length)((targetptr)->disk.vn_length_hi) = ((afs_int64)length) >>
32; ((targetptr)->disk.length) = (length) & 0xFFFFFFFF
;
;
1610 /* targetptr->disk.group = 0; save some cycles */
1611 targetptr->disk.modeBits = 0777;
1612 targetptr->disk.owner = client->ViceId;
1613 targetptr->disk.dataVersion = 0; /* consistent with the client */
1614 targetptr->disk.linkCount = (Caller & TVS_MKDIR0x10 ? 2 : 1);
1615 /* the inode was created in Alloc_NewVnode() */
1616 }
1617#if FS_STATS_DETAILED1
1618 /*
1619 * Update file write stats for this volume. Note that the auth
1620 * counter is located immediately after its associated ``distance''
1621 * counter.
1622 */
1623 if (client->InSameNetwork)
1624 writeIdx = VOL_STATS_SAME_NET0;
1625 else
1626 writeIdx = VOL_STATS_DIFF_NET2;
1627 V_stat_writes(volptr, writeIdx)(((volptr)->header->diskstuff.stat_writes)[writeIdx])++;
1628 if (client->ViceId != AnonymousID) {
1629 V_stat_writes(volptr, writeIdx + 1)(((volptr)->header->diskstuff.stat_writes)[writeIdx + 1
])
++;
1630 }
1631
1632 /*
1633 * We only count operations that DON'T involve creating new objects
1634 * (files, symlinks, directories) or simply setting status as
1635 * authorship-change operations.
1636 */
1637 if (!(Caller & (TVS_CFILE4 | TVS_SLINK8 | TVS_MKDIR0x10 | TVS_SSTATUS2))) {
1638 /*
1639 * Update the volume's authorship information in response to this
1640 * file operation. Get the current time, decide to which time
1641 * slot this operation belongs, and bump the appropriate slot.
1642 */
1643 currDate = (FT_ApproxTime() - targetptr->disk.unixModifyTime);
1644 timeIdx =
1645 (currDate <
1646 VOL_STATS_TIME_CAP_060 ? VOL_STATS_TIME_IDX_00 : currDate <
1647 VOL_STATS_TIME_CAP_1600 ? VOL_STATS_TIME_IDX_11 : currDate <
1648 VOL_STATS_TIME_CAP_23600 ? VOL_STATS_TIME_IDX_22 : currDate <
1649 VOL_STATS_TIME_CAP_386400 ? VOL_STATS_TIME_IDX_33 : currDate <
1650 VOL_STATS_TIME_CAP_4604800 ? VOL_STATS_TIME_IDX_44 :
1651 VOL_STATS_TIME_IDX_55);
1652 if (targetptr->disk.author == client->ViceId) {
1653 V_stat_fileSameAuthor(volptr, timeIdx)(((volptr)->header->diskstuff.stat_fileSameAuthor)[timeIdx
])
++;
1654 } else {
1655 V_stat_fileDiffAuthor(volptr, timeIdx)(((volptr)->header->diskstuff.stat_fileDiffAuthor)[timeIdx
])
++;
1656 }
1657 }
1658#endif /* FS_STATS_DETAILED */
1659
1660 if (!(Caller & TVS_SSTATUS2))
1661 targetptr->disk.author = client->ViceId;
1662 if (Caller & TVS_SDATA1) {
1663 targetptr->disk.dataVersion++;
1664 if (VanillaUser(client)) {
1665 targetptr->disk.modeBits &= ~04000; /* turn off suid for file. */
1666#ifdef CREATE_SGUID_ADMIN_ONLY1
1667 targetptr->disk.modeBits &= ~02000; /* turn off sgid for file. */
1668#endif
1669 }
1670 }
1671 if (Caller & TVS_SSTATUS2) { /* update time on non-status change */
1672 /* store status, must explicitly request to change the date */
1673 if (InStatus->Mask & AFS_SETMODTIME1)
1674 targetptr->disk.unixModifyTime = InStatus->ClientModTime;
1675 } else { /* other: date always changes, but perhaps to what is specified by caller */
1676 targetptr->disk.unixModifyTime =
1677 (InStatus->Mask & AFS_SETMODTIME1 ? InStatus->
1678 ClientModTime : FT_ApproxTime());
1679 }
1680 if (InStatus->Mask & AFS_SETOWNER2) {
1681 /* admin is allowed to do chmod, chown as well as chown, chmod. */
1682 if (VanillaUser(client)) {
1683 targetptr->disk.modeBits &= ~04000; /* turn off suid for file. */
1684#ifdef CREATE_SGUID_ADMIN_ONLY1
1685 targetptr->disk.modeBits &= ~02000; /* turn off sgid for file. */
1686#endif
1687 }
1688 targetptr->disk.owner = InStatus->Owner;
1689 if (VolumeRootVnode(targetptr)) {
1690 Errorbit32 errorCode = 0; /* what should be done with this? */
1691
1692 V_owner(targetptr->volumePtr)((targetptr->volumePtr)->header->diskstuff.owner) = InStatus->Owner;
1693 VUpdateVolume(&errorCode, targetptr->volumePtr);
1694 }
1695 }
1696 if (InStatus->Mask & AFS_SETMODE8) {
1697 int modebits = InStatus->UnixModeBits;
1698#define CREATE_SGUID_ADMIN_ONLY1 1
1699#ifdef CREATE_SGUID_ADMIN_ONLY1
1700 if (VanillaUser(client))
1701 modebits = modebits & 0777;
1702#endif
1703 if (VanillaUser(client)) {
1704 targetptr->disk.modeBits = modebits;
1705 } else {
1706 targetptr->disk.modeBits = modebits;
1707 switch (Caller) {
1708 case TVS_SDATA1:
1709 osi_audit(PrivSetID"AFS_PrivSet", 0, AUD_ID10, client->ViceId, AUD_INT2,
1710 CHK_STOREDATA0x00, AUD_END0);
1711 break;
1712 case TVS_CFILE4:
1713 case TVS_SSTATUS2:
1714 osi_audit(PrivSetID"AFS_PrivSet", 0, AUD_ID10, client->ViceId, AUD_INT2,
1715 CHK_STORESTATUS0x02, AUD_END0);
1716 break;
1717 default:
1718 break;
1719 }
1720 }
1721 }
1722 targetptr->disk.serverModifyTime = FT_ApproxTime();
1723 if (InStatus->Mask & AFS_SETGROUP4)
1724 targetptr->disk.group = InStatus->Group;
1725 /* vnode changed : to be written back by VPutVnode */
1726 targetptr->changed_newTime = 1;
1727
1728} /*Update_TargetVnodeStatus */
1729
1730
1731/*
1732 * Fills the CallBack structure with the expiration time and type of callback
1733 * structure. Warning: this function is currently incomplete.
1734 */
1735static void
1736SetCallBackStruct(afs_uint32 CallBackTime, struct AFSCallBack *CallBack)
1737{
1738 /* CallBackTime could not be 0 */
1739 if (CallBackTime == 0) {
1740 ViceLog(0, ("WARNING: CallBackTime == 0!\n"))do { if ((0) <= LogLevel) (FSLog ("WARNING: CallBackTime == 0!\n"
)); } while (0)
;
1741 CallBack->ExpirationTime = 0;
1742 } else
1743 CallBack->ExpirationTime = CallBackTime - FT_ApproxTime();
1744 CallBack->CallBackVersion = CALLBACK_VERSION1;
1745 CallBack->CallBackType = CB_SHARED2; /* The default for now */
1746
1747} /*SetCallBackStruct */
1748
1749
1750/*
1751 * Adjusts (Subtract) "length" number of blocks from the volume's disk
1752 * allocation; if some error occured (exceeded volume quota or partition
1753 * was full, or whatever), it frees the space back and returns the code.
1754 * We usually pre-adjust the volume space to make sure that there's
1755 * enough space before consuming some.
1756 */
1757static afs_int32
1758AdjustDiskUsage(Volume * volptr, afs_sfsize_t length,
1759 afs_sfsize_t checkLength)
1760{
1761 Errorbit32 rc;
1762 Errorbit32 nc;
1763
1764 VAdjustDiskUsage(&rc, volptr, length, checkLength);
1765 if (rc) {
1766 VAdjustDiskUsage(&nc, volptr, -length, 0);
1767 if (rc == VOVERQUOTA109) {
1768 ViceLog(2,do { if ((2) <= LogLevel) (FSLog ("Volume %u (%s) is full\n"
, ((volptr)->header->diskstuff.id), ((volptr)->header
->diskstuff.name))); } while (0)
1769 ("Volume %u (%s) is full\n", V_id(volptr),do { if ((2) <= LogLevel) (FSLog ("Volume %u (%s) is full\n"
, ((volptr)->header->diskstuff.id), ((volptr)->header
->diskstuff.name))); } while (0)
1770 V_name(volptr)))do { if ((2) <= LogLevel) (FSLog ("Volume %u (%s) is full\n"
, ((volptr)->header->diskstuff.id), ((volptr)->header
->diskstuff.name))); } while (0)
;
1771 return (rc);
1772 }
1773 if (rc == VDISKFULL108) {
1774 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("Partition %s that contains volume %u is full\n"
, volptr->partition->name, ((volptr)->header->diskstuff
.id))); } while (0)
1775 ("Partition %s that contains volume %u is full\n",do { if ((0) <= LogLevel) (FSLog ("Partition %s that contains volume %u is full\n"
, volptr->partition->name, ((volptr)->header->diskstuff
.id))); } while (0)
1776 volptr->partition->name, V_id(volptr)))do { if ((0) <= LogLevel) (FSLog ("Partition %s that contains volume %u is full\n"
, volptr->partition->name, ((volptr)->header->diskstuff
.id))); } while (0)
;
1777 return (rc);
1778 }
1779 ViceLog(0, ("Got error return %d from VAdjustDiskUsage\n", rc))do { if ((0) <= LogLevel) (FSLog ("Got error return %d from VAdjustDiskUsage\n"
, rc)); } while (0)
;
1780 return (rc);
1781 }
1782 return (0);
1783
1784} /*AdjustDiskUsage */
1785
1786/*
1787 * Common code that handles the creation of a new file (SAFS_CreateFile and
1788 * SAFS_Symlink) or a new dir (SAFS_MakeDir)
1789 */
1790static afs_int32
1791Alloc_NewVnode(Vnode * parentptr, DirHandle * dir, Volume * volptr,
1792 Vnode ** targetptr, char *Name, struct AFSFid *OutFid,
1793 int FileType, afs_sfsize_t BlocksPreallocatedForVnode)
1794{
1795 Errorbit32 errorCode = 0; /* Error code returned back */
1796 Errorbit32 temp;
1797 Inode inode = 0;
1798 Inode nearInode AFS_UNUSED__attribute__((unused)); /* hint for inode allocation in solaris */
1799 afs_ino_str_t stmp;
1800
1801 if ((errorCode =
1802 AdjustDiskUsage(volptr, BlocksPreallocatedForVnode,
1803 BlocksPreallocatedForVnode))) {
1804 ViceLog(25,do { if ((25) <= LogLevel) (FSLog ("Insufficient space to allocate %lld blocks\n"
, (afs_intmax_t) BlocksPreallocatedForVnode)); } while (0)
1805 ("Insufficient space to allocate %lld blocks\n",do { if ((25) <= LogLevel) (FSLog ("Insufficient space to allocate %lld blocks\n"
, (afs_intmax_t) BlocksPreallocatedForVnode)); } while (0)
1806 (afs_intmax_t) BlocksPreallocatedForVnode))do { if ((25) <= LogLevel) (FSLog ("Insufficient space to allocate %lld blocks\n"
, (afs_intmax_t) BlocksPreallocatedForVnode)); } while (0)
;
1807 return (errorCode);
1808 }
1809
1810 if (CheckLength(volptr, parentptr, -1)) {
1811 VAdjustDiskUsage(&temp, volptr, -BlocksPreallocatedForVnode, 0);
1812 VTakeOffline(volptr);
1813 return VSALVAGE101;
1814 }
1815
1816 *targetptr = VAllocVnode(&errorCode, volptr, FileType);
1817 if (errorCode != 0) {
1818 VAdjustDiskUsage(&temp, volptr, -BlocksPreallocatedForVnode, 0);
1819 return (errorCode);
1820 }
1821 OutFid->Volume = V_id(volptr)((volptr)->header->diskstuff.id);
1822 OutFid->Vnode = (*targetptr)->vnodeNumber;
1823 OutFid->Unique = (*targetptr)->disk.uniquifier;
1824
1825 nearInode = VN_GET_INO(parentptr)((Inode)((parentptr)->disk.vn_ino_lo | ((parentptr)->disk
.vn_ino_hi ? (((Inode)(parentptr)->disk.vn_ino_hi)<<
32) : 0)))
; /* parent is also in same vol */
1826
1827 /* create the inode now itself */
1828 inode =
1829 IH_CREATE(V_linkHandle(volptr), V_device(volptr),namei_icreate(((volptr)->linkHandle), VPartitionPath(((volptr
)->partition)), ((volptr)->header->diskstuff.id), (*
targetptr)->vnodeNumber, (*targetptr)->disk.uniquifier,
1)
1830 VPartitionPath(V_partition(volptr)), nearInode,namei_icreate(((volptr)->linkHandle), VPartitionPath(((volptr
)->partition)), ((volptr)->header->diskstuff.id), (*
targetptr)->vnodeNumber, (*targetptr)->disk.uniquifier,
1)
1831 V_id(volptr), (*targetptr)->vnodeNumber,namei_icreate(((volptr)->linkHandle), VPartitionPath(((volptr
)->partition)), ((volptr)->header->diskstuff.id), (*
targetptr)->vnodeNumber, (*targetptr)->disk.uniquifier,
1)
1832 (*targetptr)->disk.uniquifier, 1)namei_icreate(((volptr)->linkHandle), VPartitionPath(((volptr
)->partition)), ((volptr)->header->diskstuff.id), (*
targetptr)->vnodeNumber, (*targetptr)->disk.uniquifier,
1)
;
1833
1834 /* error in creating inode */
1835 if (!VALID_INO(inode)((inode) != (Inode)-1 && (inode) != (Inode)0)) {
1836 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("Volume : %u vnode = %u Failed to create inode: errno = %d\n"
, (*targetptr)->volumePtr->header->diskstuff.id, (*targetptr
)->vnodeNumber, (* __error()))); } while (0)
1837 ("Volume : %u vnode = %u Failed to create inode: errno = %d\n",do { if ((0) <= LogLevel) (FSLog ("Volume : %u vnode = %u Failed to create inode: errno = %d\n"
, (*targetptr)->volumePtr->header->diskstuff.id, (*targetptr
)->vnodeNumber, (* __error()))); } while (0)
1838 (*targetptr)->volumePtr->header->diskstuff.id,do { if ((0) <= LogLevel) (FSLog ("Volume : %u vnode = %u Failed to create inode: errno = %d\n"
, (*targetptr)->volumePtr->header->diskstuff.id, (*targetptr
)->vnodeNumber, (* __error()))); } while (0)
1839 (*targetptr)->vnodeNumber, errno))do { if ((0) <= LogLevel) (FSLog ("Volume : %u vnode = %u Failed to create inode: errno = %d\n"
, (*targetptr)->volumePtr->header->diskstuff.id, (*targetptr
)->vnodeNumber, (* __error()))); } while (0)
;
1840 VAdjustDiskUsage(&temp, volptr, -BlocksPreallocatedForVnode, 0);
1841 (*targetptr)->delete = 1; /* delete vnode */
1842 return ENOSPC28;
1843 }
1844 VN_SET_INO(*targetptr, inode)((*targetptr)->disk.vn_ino_lo = (int)((inode)&0xffffffff
), ((*targetptr)->disk.vn_ino_hi = (inode) ? (int)(((inode
)>>32)&0xffffffff) : 0))
;
1845 IH_INIT(((*targetptr)->handle), V_device(volptr), V_id(volptr), inode)((((*targetptr)->handle)) = ih_init((((volptr)->device)
), (((volptr)->header->diskstuff.id)), (inode)))
;
1846
1847 /* copy group from parent dir */
1848 (*targetptr)->disk.group = parentptr->disk.group;
1849
1850 if (parentptr->disk.cloned) {
1851 ViceLog(25, ("Alloc_NewVnode : CopyOnWrite called\n"))do { if ((25) <= LogLevel) (FSLog ("Alloc_NewVnode : CopyOnWrite called\n"
)); } while (0)
;
1852 if ((errorCode = CopyOnWrite(parentptr, volptr, 0, MAXFSIZE(~(afs_fsize_t) 0)))) { /* disk full */
1853 ViceLog(25, ("Alloc_NewVnode : CopyOnWrite failed\n"))do { if ((25) <= LogLevel) (FSLog ("Alloc_NewVnode : CopyOnWrite failed\n"
)); } while (0)
;
1854 /* delete the vnode previously allocated */
1855 (*targetptr)->delete = 1;
1856 VAdjustDiskUsage(&temp, volptr, -BlocksPreallocatedForVnode, 0);
1857 IH_REALLYCLOSE((*targetptr)->handle)ih_reallyclose((*targetptr)->handle);
1858 if (IH_DEC(V_linkHandle(volptr), inode, V_parentId(volptr))namei_dec(((volptr)->linkHandle), inode, ((volptr)->header
->diskstuff.parentId))
)
1859 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("Alloc_NewVnode: partition %s idec %s failed\n"
, volptr->partition->name, PrintInode(stmp, inode))); }
while (0)
1860 ("Alloc_NewVnode: partition %s idec %s failed\n",do { if ((0) <= LogLevel) (FSLog ("Alloc_NewVnode: partition %s idec %s failed\n"
, volptr->partition->name, PrintInode(stmp, inode))); }
while (0)
1861 volptr->partition->name, PrintInode(stmp, inode)))do { if ((0) <= LogLevel) (FSLog ("Alloc_NewVnode: partition %s idec %s failed\n"
, volptr->partition->name, PrintInode(stmp, inode))); }
while (0)
;
1862 IH_RELEASE((*targetptr)->handle)(ih_release((*targetptr)->handle), ((*targetptr)->handle
)=((void *)0), 0)
;
1863
1864 return errorCode;
1865 }
1866 }
1867
1868 /* add the name to the directory */
1869 SetDirHandle(dir, parentptr);
1870 if ((errorCode = afs_dir_Create(dir, Name, OutFid))) {
1871 (*targetptr)->delete = 1;
1872 VAdjustDiskUsage(&temp, volptr, -BlocksPreallocatedForVnode, 0);
1873 IH_REALLYCLOSE((*targetptr)->handle)ih_reallyclose((*targetptr)->handle);
1874 if (IH_DEC(V_linkHandle(volptr), inode, V_parentId(volptr))namei_dec(((volptr)->linkHandle), inode, ((volptr)->header
->diskstuff.parentId))
)
1875 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("Alloc_NewVnode: partition %s idec %s failed\n"
, volptr->partition->name, PrintInode(stmp, inode))); }
while (0)
1876 ("Alloc_NewVnode: partition %s idec %s failed\n",do { if ((0) <= LogLevel) (FSLog ("Alloc_NewVnode: partition %s idec %s failed\n"
, volptr->partition->name, PrintInode(stmp, inode))); }
while (0)
1877 volptr->partition->name, PrintInode(stmp, inode)))do { if ((0) <= LogLevel) (FSLog ("Alloc_NewVnode: partition %s idec %s failed\n"
, volptr->partition->name, PrintInode(stmp, inode))); }
while (0)
;
1878 IH_RELEASE((*targetptr)->handle)(ih_release((*targetptr)->handle), ((*targetptr)->handle
)=((void *)0), 0)
;
1879 return (errorCode);
1880 }
1881 DFlush();
1882 return (0);
1883
1884} /*Alloc_NewVnode */
1885
1886
1887/*
1888 * Handle all the lock-related code (SAFS_SetLock, SAFS_ExtendLock and
1889 * SAFS_ReleaseLock)
1890 */
1891static afs_int32
1892HandleLocking(Vnode * targetptr, struct client *client, afs_int32 rights, ViceLockType LockingType)
1893{
1894 int Time; /* Used for time */
1895 int writeVnode = targetptr->changed_oldTime; /* save original status */
1896
1897 targetptr->changed_oldTime = 1; /* locking doesn't affect any time stamp */
1898 Time = FT_ApproxTime();
1899 switch (LockingType) {
1900 case LockRead0:
1901 case LockWrite1:
1902 if (Time > targetptr->disk.lock.lockTime)
1903 targetptr->disk.lock.lockTime = targetptr->disk.lock.lockCount =
1904 0;
1905 Time += AFS_LOCKWAIT(5*60);
1906 if (LockingType == LockRead0) {
1907 if ( !(rights & PRSFS_LOCK32) &&
1908 !(rights & PRSFS_WRITE2) &&
1909 !(OWNSp(client, targetptr)((client)->ViceId == (targetptr)->disk.owner) && (rights & PRSFS_INSERT4)) )
1910 return(EACCES13);
1911
1912 if (targetptr->disk.lock.lockCount >= 0) {
1913 ++(targetptr->disk.lock.lockCount);
1914 targetptr->disk.lock.lockTime = Time;
1915 } else
1916 return (EAGAIN35);
1917 } else if (LockingType == LockWrite1) {
1918 if ( !(rights & PRSFS_WRITE2) &&
1919 !(OWNSp(client, targetptr)((client)->ViceId == (targetptr)->disk.owner) && (rights & PRSFS_INSERT4)) )
1920 return(EACCES13);
1921
1922 if (targetptr->disk.lock.lockCount == 0) {
1923 targetptr->disk.lock.lockCount = -1;
1924 targetptr->disk.lock.lockTime = Time;
1925 } else
1926 return (EAGAIN35);
1927 }
1928 break;
1929 case LockExtend2:
1930 Time += AFS_LOCKWAIT(5*60);
1931 if (targetptr->disk.lock.lockCount != 0)
1932 targetptr->disk.lock.lockTime = Time;
1933 else
1934 return (EINVAL22);
1935 break;
1936 case LockRelease3:
1937 if ((--targetptr->disk.lock.lockCount) <= 0)
1938 targetptr->disk.lock.lockCount = targetptr->disk.lock.lockTime =
1939 0;
1940 break;
1941 default:
1942 targetptr->changed_oldTime = writeVnode; /* restore old status */
1943 ViceLog(0, ("Illegal Locking type %d\n", LockingType))do { if ((0) <= LogLevel) (FSLog ("Illegal Locking type %d\n"
, LockingType)); } while (0)
;
1944 }
1945 return (0);
1946} /*HandleLocking */
1947
1948/* Checks if caller has the proper AFS and Unix (WRITE) access permission to the target directory; Prfs_Mode refers to the AFS Mode operation while rights contains the caller's access permissions to the directory. */
1949
1950static afs_int32
1951CheckWriteMode(Vnode * targetptr, afs_int32 rights, int Prfs_Mode)
1952{
1953 if (readonlyServer)
1954 return (VREADONLY30);
1955 if (!(rights & Prfs_Mode))
1956 return (EACCES13);
1957 if ((targetptr->disk.type != vDirectory2)
1958 && (!(targetptr->disk.modeBits & OWNERWRITE0200)))
1959 return (EACCES13);
1960 return (0);
1961}
1962
1963/*
1964 * If some flags (i.e. min or max quota) are set, the volume's in disk
1965 * label is updated; Name, OfflineMsg, and Motd are also reflected in the
1966 * update, if applicable.
1967 */
1968static afs_int32
1969RXUpdate_VolumeStatus(Volume * volptr, AFSStoreVolumeStatus * StoreVolStatus,
1970 char *Name, char *OfflineMsg, char *Motd)
1971{
1972 Errorbit32 errorCode = 0;
1973
1974 if (StoreVolStatus->Mask & AFS_SETMINQUOTA1)
1975 V_minquota(volptr)((volptr)->header->diskstuff.minquota) = StoreVolStatus->MinQuota;
1976 if (StoreVolStatus->Mask & AFS_SETMAXQUOTA2)
1977 V_maxquota(volptr)((volptr)->header->diskstuff.maxquota) = StoreVolStatus->MaxQuota;
1978 if (strlen(OfflineMsg) > 0) {
1979 strcpy(V_offlineMessage(volptr)((volptr)->header->diskstuff.offlineMessage), OfflineMsg);
1980 }
1981 if (strlen(Name) > 0) {
1982 strcpy(V_name(volptr)((volptr)->header->diskstuff.name), Name);
1983 }
1984#if OPENAFS_VOL_STATS1
1985 /*
1986 * We don't overwrite the motd field, since it's now being used
1987 * for stats
1988 */
1989#else
1990 if (strlen(Motd) > 0) {
1991 strcpy(V_motd(volptr)((volptr)->header->diskstuff.motd), Motd);
1992 }
1993#endif /* FS_STATS_DETAILED */
1994 VUpdateVolume(&errorCode, volptr);
1995 return (errorCode);
1996
1997} /*RXUpdate_VolumeStatus */
1998
1999
2000static afs_int32
2001RXGetVolumeStatus(AFSFetchVolumeStatus * status, char **name, char **offMsg,
2002 char **motd, Volume * volptr)
2003{
2004 int temp;
2005
2006 status->Vid = V_id(volptr)((volptr)->header->diskstuff.id);
2007 status->ParentId = V_parentId(volptr)((volptr)->header->diskstuff.parentId);
2008 status->Online = V_inUse(volptr)((volptr)->header->diskstuff.inUse);
2009 status->InService = V_inService(volptr)((volptr)->header->diskstuff.inService);
2010 status->Blessed = V_blessed(volptr)((volptr)->header->diskstuff.blessed);
2011 status->NeedsSalvage = V_needsSalvaged(volptr)((volptr)->header->diskstuff.needsSalvaged);
2012 if (VolumeWriteable(volptr)(((volptr)->header->diskstuff.type)==0))
2013 status->Type = ReadWrite1;
2014 else
2015 status->Type = ReadOnly0;
2016 status->MinQuota = V_minquota(volptr)((volptr)->header->diskstuff.minquota);
2017 status->MaxQuota = V_maxquota(volptr)((volptr)->header->diskstuff.maxquota);
2018 status->BlocksInUse = V_diskused(volptr)((volptr)->header->diskstuff.diskused);
2019 status->PartBlocksAvail = RoundInt64ToInt32(volptr->partition->free)(volptr->partition->free > 0xFFFFFFFF) ? 0xFFFFFFFF :
volptr->partition->free;
;
2020 status->PartMaxBlocks = RoundInt64ToInt32(volptr->partition->totalUsable)(volptr->partition->totalUsable > 0xFFFFFFFF) ? 0xFFFFFFFF
: volptr->partition->totalUsable;
;
2021
2022 /* now allocate and copy these things; they're freed by the RXGEN stub */
2023 temp = strlen(V_name(volptr)((volptr)->header->diskstuff.name)) + 1;
2024 *name = malloc(temp);
2025 if (!*name) {
2026 ViceLogThenPanic(0, ("Failed malloc in RXGetVolumeStatus\n"))do { do { if ((0) <= LogLevel) (FSLog ("Failed malloc in RXGetVolumeStatus\n"
)); } while (0); osi_Panic ("Failed malloc in RXGetVolumeStatus\n"
); } while(0);
;
2027 }
2028 strcpy(*name, V_name(volptr)((volptr)->header->diskstuff.name));
2029 temp = strlen(V_offlineMessage(volptr)((volptr)->header->diskstuff.offlineMessage)) + 1;
2030 *offMsg = malloc(temp);
2031 if (!*offMsg) {
2032 ViceLogThenPanic(0, ("Failed malloc in RXGetVolumeStatus\n"))do { do { if ((0) <= LogLevel) (FSLog ("Failed malloc in RXGetVolumeStatus\n"
)); } while (0); osi_Panic ("Failed malloc in RXGetVolumeStatus\n"
); } while(0);
;
2033 }
2034 strcpy(*offMsg, V_offlineMessage(volptr)((volptr)->header->diskstuff.offlineMessage));
2035#if OPENAFS_VOL_STATS1
2036 *motd = malloc(1);
2037 if (!*motd) {
2038 ViceLogThenPanic(0, ("Failed malloc in RXGetVolumeStatus\n"))do { do { if ((0) <= LogLevel) (FSLog ("Failed malloc in RXGetVolumeStatus\n"
)); } while (0); osi_Panic ("Failed malloc in RXGetVolumeStatus\n"
); } while(0);
;
2039 }
2040 strcpy(*motd, nullString);
2041#else
2042 temp = strlen(V_motd(volptr)((volptr)->header->diskstuff.motd)) + 1;
2043 *motd = malloc(temp);
2044 if (!*motd) {
2045 ViceLogThenPanic(0, ("Failed malloc in RXGetVolumeStatus\n"))do { do { if ((0) <= LogLevel) (FSLog ("Failed malloc in RXGetVolumeStatus\n"
)); } while (0); osi_Panic ("Failed malloc in RXGetVolumeStatus\n"
); } while(0);
;
2046 }
2047 strcpy(*motd, V_motd(volptr)((volptr)->header->diskstuff.motd));
2048#endif /* OPENAFS_VOL_STATS */
2049 return 0;
2050} /*RXGetVolumeStatus */
2051
2052
2053static afs_int32
2054FileNameOK(char *aname)
2055{
2056 afs_int32 i, tc;
2057 i = strlen(aname);
2058 if (i >= 4) {
2059 /* watch for @sys on the right */
2060 if (strcmp(aname + i - 4, "@sys") == 0)
2061 return 0;
2062 }
2063 while ((tc = *aname++)) {
2064 if (tc == '/')
2065 return 0; /* very bad character to encounter */
2066 }
2067 return 1; /* file name is ok */
2068
2069} /*FileNameOK */
2070
2071
2072/*
2073 * This variant of symlink is expressly to support the AFS/DFS translator
2074 * and is not supported by the AFS fileserver. We just return EINVAL.
2075 * The cache manager should not generate this call to an AFS cache manager.
2076 */
2077afs_int32
2078SRXAFS_DFSSymlink(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
2079 char *LinkContents, struct AFSStoreStatus *InStatus,
2080 struct AFSFid *OutFid, struct AFSFetchStatus *OutFidStatus,
2081 struct AFSFetchStatus *OutDirStatus,
2082 struct AFSCallBack *CallBack, struct AFSVolSync *Sync)
2083{
2084 return EINVAL22;
2085}
2086
2087afs_int32
2088SRXAFS_FsCmd(struct rx_call * acall, struct AFSFid * Fid,
2089 struct FsCmdInputs * Inputs,
2090 struct FsCmdOutputs * Outputs)
2091{
2092 afs_int32 code = 0;
2093
2094 switch (Inputs->command) {
2095 default:
2096 code = EINVAL22;
2097 }
2098 ViceLog(1,("FsCmd: cmd = %d, code=%d\n",do { if ((1) <= LogLevel) (FSLog ("FsCmd: cmd = %d, code=%d\n"
, Inputs->command, Outputs->code)); } while (0)
2099 Inputs->command, Outputs->code))do { if ((1) <= LogLevel) (FSLog ("FsCmd: cmd = %d, code=%d\n"
, Inputs->command, Outputs->code)); } while (0)
;
2100 return code;
2101}
2102
2103#ifndef HAVE_PIOV
2104static struct afs_buffer {
2105 struct afs_buffer *next;
2106} *freeBufferList = 0;
2107static int afs_buffersAlloced = 0;
2108
2109static int
2110FreeSendBuffer(struct afs_buffer *adata)
2111{
2112 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 2112), 0));
;
2113 afs_buffersAlloced--;
2114 adata->next = freeBufferList;
2115 freeBufferList = adata;
2116 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 2116), 0));
;
2117 return 0;
2118
2119} /*FreeSendBuffer */
2120
2121/* allocate space for sender */
2122static char *
2123AllocSendBuffer(void)
2124{
2125 struct afs_buffer *tp;
2126
2127 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 2127), 0));
;
2128 afs_buffersAlloced++;
2129 if (!freeBufferList) {
2130 char *tmp;
2131 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 2131), 0));
;
2132 tmp = malloc(sendBufSize);
2133 if (!tmp) {
2134 ViceLogThenPanic(0, ("Failed malloc in AllocSendBuffer\n"))do { do { if ((0) <= LogLevel) (FSLog ("Failed malloc in AllocSendBuffer\n"
)); } while (0); osi_Panic ("Failed malloc in AllocSendBuffer\n"
); } while(0);
;
2135 }
2136 return tmp;
2137 }
2138 tp = freeBufferList;
2139 freeBufferList = tp->next;
2140 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 2140), 0));
;
2141 return (char *)tp;
2142
2143} /*AllocSendBuffer */
2144#endif /* HAVE_PIOV */
2145
2146/*
2147 * This routine returns the status info associated with the targetptr vnode
2148 * in the AFSFetchStatus structure. Some of the newer fields, such as
2149 * SegSize and Group are not yet implemented
2150 */
2151static
2152 void
2153GetStatus(Vnode * targetptr, AFSFetchStatus * status, afs_int32 rights,
2154 afs_int32 anyrights, Vnode * parentptr)
2155{
2156 /* initialize return status from a vnode */
2157 status->InterfaceVersion = 1;
2158 status->SyncCounter = status->dataVersionHigh = status->lockCount =
2159 status->errorCode = 0;
2160 status->ResidencyMask = 1; /* means for MR-AFS: file in /vicepr-partition */
2161 if (targetptr->disk.type == vFile1)
2162 status->FileType = File1;
2163 else if (targetptr->disk.type == vDirectory2)
2164 status->FileType = Directory2;
2165 else if (targetptr->disk.type == vSymlink3)
2166 status->FileType = SymbolicLink3;
2167 else
2168 status->FileType = Invalid0; /*invalid type field */
2169 status->LinkCount = targetptr->disk.linkCount;
2170 {
2171 afs_fsize_t targetLen;
2172 VN_GET_LEN(targetLen, targetptr)(targetLen) = ((afs_int64)((targetptr)->disk.vn_length_hi)
<< 32) | ((targetptr)->disk.length);
;
2173 SplitOffsetOrSize(targetLen, status->Length_hi, status->Length)(status->Length_hi) = ((afs_int64)targetLen) >> 32; (
status->Length) = (targetLen) & 0xFFFFFFFF;
;
2174 }
2175 status->DataVersion = targetptr->disk.dataVersion;
2176 status->Author = targetptr->disk.author;
2177 status->Owner = targetptr->disk.owner;
2178 status->CallerAccess = rights;
2179 status->AnonymousAccess = anyrights;
2180 status->UnixModeBits = targetptr->disk.modeBits;
2181 status->ClientModTime = targetptr->disk.unixModifyTime; /* This might need rework */
2182 status->ParentVnode =
2183 (status->FileType ==
2184 Directory2 ? targetptr->vnodeNumber : parentptr->vnodeNumber);
2185 status->ParentUnique =
2186 (status->FileType ==
2187 Directory2 ? targetptr->disk.uniquifier : parentptr->disk.uniquifier);
2188 status->ServerModTime = targetptr->disk.serverModifyTime;
2189 status->Group = targetptr->disk.group;
2190 status->lockCount = targetptr->disk.lock.lockCount;
2191 status->errorCode = 0;
2192
2193} /*GetStatus */
2194
2195static
2196 afs_int32
2197common_FetchData64(struct rx_call *acall, struct AFSFid *Fid,
2198 afs_sfsize_t Pos, afs_sfsize_t Len,
2199 struct AFSFetchStatus *OutStatus,
2200 struct AFSCallBack *CallBack, struct AFSVolSync *Sync,
2201 int type)
2202{
2203 Vnode *targetptr = 0; /* pointer to vnode to fetch */
2204 Vnode *parentwhentargetnotdir = 0; /* parent vnode if vptr is a file */
2205 Vnode tparentwhentargetnotdir; /* parent vnode for GetStatus */
2206 Errorbit32 errorCode = 0; /* return code to caller */
2207 Errorbit32 fileCode = 0; /* return code from vol package */
2208 Volume *volptr = 0; /* pointer to the volume */
2209 struct client *client = 0; /* pointer to the client data */
2210 struct rx_connection *tcon; /* the connection we're part of */
2211 struct host *thost;
2212 afs_int32 rights, anyrights; /* rights for this and any user */
2213 struct client *t_client = NULL((void *)0); /* tmp ptr to client data */
2214 struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
2215 struct VCallByVol tcbv, *cbv = NULL((void *)0);
2216 static int remainder = 0; /* shared access protected by FS_LOCK */
2217 struct fsstats fsstats;
2218 afs_sfsize_t bytesToXfer; /* # bytes to xfer */
2219 afs_sfsize_t bytesXferred; /* # bytes actually xferred */
2220
2221#if FS_STATS_DETAILED1
2222 int readIdx; /* Index of read stats array to bump */
2223#endif /* FS_STATS_DETAILED */
2224
2225 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_FETCHDATA0);
2226
2227 ViceLog(1,do { if ((1) <= LogLevel) (FSLog ("SRXAFS_FetchData, Fid = %u.%u.%u\n"
, Fid->Volume, Fid->Vnode, Fid->Unique)); } while (0
)
2228 ("SRXAFS_FetchData, Fid = %u.%u.%u\n", Fid->Volume, Fid->Vnode,do { if ((1) <= LogLevel) (FSLog ("SRXAFS_FetchData, Fid = %u.%u.%u\n"
, Fid->Volume, Fid->Vnode, Fid->Unique)); } while (0
)
2229 Fid->Unique))do { if ((1) <= LogLevel) (FSLog ("SRXAFS_FetchData, Fid = %u.%u.%u\n"
, Fid->Volume, Fid->Vnode, Fid->Unique)); } while (0
)
;
2230 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 2230), 0));
;
2231 AFSCallStats.FetchData++, AFSCallStats.TotalCalls++;
2232 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 2232), 0));
;
2233 if ((errorCode = CallPreamble(acall, ACTIVECALL1, &tcon, &thost)))
2234 goto Bad_FetchData;
2235
2236 /* Get ptr to client data for user Id for logging */
2237 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
2238 logHostAddr.s_addr = rxr_HostOf(tcon)(((((struct rx_connection *)(tcon))->peer))->host);
2239 ViceLog(5,do { if ((5) <= LogLevel) (FSLog ("SRXAFS_FetchData, Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
2240 ("SRXAFS_FetchData, Fid = %u.%u.%u, Host %s:%d, Id %d\n",do { if ((5) <= LogLevel) (FSLog ("SRXAFS_FetchData, Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
2241 Fid->Volume, Fid->Vnode, Fid->Unique, inet_ntoa(logHostAddr),do { if ((5) <= LogLevel) (FSLog ("SRXAFS_FetchData, Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
2242 ntohs(rxr_PortOf(tcon)), t_client->ViceId))do { if ((5) <= LogLevel) (FSLog ("SRXAFS_FetchData, Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
;
2243
2244 queue_NodeInit(&tcbv)((((struct rx_queue *)(&tcbv)))->prev = (((struct rx_queue
*)(&tcbv)))->next = ((void *)0))
;
2245 tcbv.call = acall;
2246 cbv = &tcbv;
2247
2248 /*
2249 * Get volume/vnode for the fetched file; caller's access rights to
2250 * it are also returned
2251 */
2252 if ((errorCode =
2253 GetVolumePackageWithCall(tcon, cbv, Fid, &volptr, &targetptr, DONTCHECK0,
2254 &parentwhentargetnotdir, &client, READ_LOCK1,
2255 &rights, &anyrights)))
2256 goto Bad_FetchData;
2257
2258 SetVolumeSync(Sync, volptr);
2259
2260#if FS_STATS_DETAILED1
2261 /*
2262 * Remember that another read operation was performed.
2263 */
2264 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 2264), 0));
;
2265 if (client->InSameNetwork)
2266 readIdx = VOL_STATS_SAME_NET0;
2267 else
2268 readIdx = VOL_STATS_DIFF_NET2;
2269 V_stat_reads(volptr, readIdx)(((volptr)->header->diskstuff.stat_reads)[readIdx])++;
2270 if (client->ViceId != AnonymousID) {
2271 V_stat_reads(volptr, readIdx + 1)(((volptr)->header->diskstuff.stat_reads)[readIdx + 1])++;
2272 }
2273 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 2273), 0));
;
2274#endif /* FS_STATS_DETAILED */
2275 /* Check whether the caller has permission access to fetch the data */
2276 if ((errorCode =
2277 Check_PermissionRights(targetptr, client, rights, CHK_FETCHDATA0x10, 0)))
2278 goto Bad_FetchData;
2279
2280 /*
2281 * Drop the read lock on the parent directory after saving the parent
2282 * vnode information we need to pass to GetStatus
2283 */
2284 if (parentwhentargetnotdir != NULL((void *)0)) {
2285 tparentwhentargetnotdir = *parentwhentargetnotdir;
2286 VPutVnode(&fileCode, parentwhentargetnotdir);
2287 osi_Assert(!fileCode || (fileCode == VSALVAGE))(void)((!fileCode || (fileCode == 101)) || (osi_AssertFailU("!fileCode || (fileCode == VSALVAGE)"
, "./../viced/afsfileprocs.c", 2287), 0))
;
2288 parentwhentargetnotdir = NULL((void *)0);
2289 }
2290
2291 fsstats_StartXfer(&fsstats);
2292
2293 /* actually do the data transfer */
2294 errorCode =
2295 FetchData_RXStyle(volptr, targetptr, acall, Pos, Len, type,
2296 &bytesToXfer, &bytesXferred);
2297
2298 fsstats_FinishXfer(&fsstats, errorCode, bytesToXfer, bytesXferred,
2299 &remainder);
2300
2301 if (errorCode)
2302 goto Bad_FetchData;
2303
2304 /* write back the OutStatus from the target vnode */
2305 GetStatus(targetptr, OutStatus, rights, anyrights,
2306 &tparentwhentargetnotdir);
2307
2308 /* if a r/w volume, promise a callback to the caller */
2309 if (VolumeWriteable(volptr)(((volptr)->header->diskstuff.type)==0))
2310 SetCallBackStruct(AddCallBack(client->host, Fid)AddCallBack1((client->host), (Fid), (afs_uint32 *)0, 1 , 0
)
, CallBack);
2311 else {
2312 struct AFSFid myFid;
2313 memset(&myFid, 0, sizeof(struct AFSFid));
2314 myFid.Volume = Fid->Volume;
2315 SetCallBackStruct(AddVolCallBack(client->host, &myFid)AddCallBack1((client->host), (&myFid), (afs_uint32 *)0
, 3 , 0)
, CallBack);
2316 }
2317
2318 Bad_FetchData:
2319 /* Update and store volume/vnode and parent vnodes back */
2320 (void)PutVolumePackageWithCall(parentwhentargetnotdir, targetptr,
2321 (Vnode *) 0, volptr, &client, cbv);
2322 ViceLog(2, ("SRXAFS_FetchData returns %d\n", errorCode))do { if ((2) <= LogLevel) (FSLog ("SRXAFS_FetchData returns %d\n"
, errorCode)); } while (0)
;
2323 errorCode = CallPostamble(tcon, errorCode, thost);
2324
2325 fsstats_FinishOp(&fsstats, errorCode);
2326
2327 osi_auditU(acall, FetchDataEvent"AFS_SRX_FchData", errorCode,
2328 AUD_ID10, t_client ? t_client->ViceId : 0,
2329 AUD_FID7, Fid, AUD_END0);
2330 return (errorCode);
2331
2332} /*SRXAFS_FetchData */
2333
2334afs_int32
2335SRXAFS_FetchData(struct rx_call * acall, struct AFSFid * Fid, afs_int32 Pos,
2336 afs_int32 Len, struct AFSFetchStatus * OutStatus,
2337 struct AFSCallBack * CallBack, struct AFSVolSync * Sync)
2338{
2339 return common_FetchData64(acall, Fid, Pos, Len, OutStatus, CallBack,
2340 Sync, 0);
2341}
2342
2343afs_int32
2344SRXAFS_FetchData64(struct rx_call * acall, struct AFSFid * Fid, afs_int64 Pos,
2345 afs_int64 Len, struct AFSFetchStatus * OutStatus,
2346 struct AFSCallBack * CallBack, struct AFSVolSync * Sync)
2347{
2348 int code;
2349 afs_sfsize_t tPos, tLen;
2350
2351 tPos = (afs_sfsize_t) Pos;
2352 tLen = (afs_sfsize_t) Len;
2353
2354 code =
2355 common_FetchData64(acall, Fid, tPos, tLen, OutStatus, CallBack, Sync,
2356 1);
2357 return code;
2358}
2359
2360afs_int32
2361SRXAFS_FetchACL(struct rx_call * acall, struct AFSFid * Fid,
2362 struct AFSOpaque * AccessList,
2363 struct AFSFetchStatus * OutStatus, struct AFSVolSync * Sync)
2364{
2365 Vnode *targetptr = 0; /* pointer to vnode to fetch */
2366 Vnode *parentwhentargetnotdir = 0; /* parent vnode if targetptr is a file */
2367 Errorbit32 errorCode = 0; /* return error code to caller */
2368 Volume *volptr = 0; /* pointer to the volume */
2369 struct client *client = 0; /* pointer to the client data */
2370 afs_int32 rights, anyrights; /* rights for this and any user */
2371 struct rx_connection *tcon = rx_ConnectionOf(acall)((acall)->conn);
2372 struct host *thost;
2373 struct client *t_client = NULL((void *)0); /* tmp ptr to client data */
2374 struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
2375 struct fsstats fsstats;
2376
2377 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_FETCHACL1);
2378
2379 ViceLog(1,do { if ((1) <= LogLevel) (FSLog ("SAFS_FetchACL, Fid = %u.%u.%u\n"
, Fid->Volume, Fid->Vnode, Fid->Unique)); } while (0
)
2380 ("SAFS_FetchACL, Fid = %u.%u.%u\n", Fid->Volume, Fid->Vnode,do { if ((1) <= LogLevel) (FSLog ("SAFS_FetchACL, Fid = %u.%u.%u\n"
, Fid->Volume, Fid->Vnode, Fid->Unique)); } while (0
)
2381 Fid->Unique))do { if ((1) <= LogLevel) (FSLog ("SAFS_FetchACL, Fid = %u.%u.%u\n"
, Fid->Volume, Fid->Vnode, Fid->Unique)); } while (0
)
;
2382 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 2382), 0));
;
2383 AFSCallStats.FetchACL++, AFSCallStats.TotalCalls++;
2384 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 2384), 0));
;
2385 if ((errorCode = CallPreamble(acall, ACTIVECALL1, &tcon, &thost)))
2386 goto Bad_FetchACL;
2387
2388 /* Get ptr to client data for user Id for logging */
2389 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
2390 logHostAddr.s_addr = rxr_HostOf(tcon)(((((struct rx_connection *)(tcon))->peer))->host);
2391 ViceLog(5,do { if ((5) <= LogLevel) (FSLog ("SAFS_FetchACL, Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
2392 ("SAFS_FetchACL, Fid = %u.%u.%u, Host %s:%d, Id %d\n", Fid->Volume,do { if ((5) <= LogLevel) (FSLog ("SAFS_FetchACL, Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
2393 Fid->Vnode, Fid->Unique, inet_ntoa(logHostAddr),do { if ((5) <= LogLevel) (FSLog ("SAFS_FetchACL, Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
2394 ntohs(rxr_PortOf(tcon)), t_client->ViceId))do { if ((5) <= LogLevel) (FSLog ("SAFS_FetchACL, Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
;
2395
2396 AccessList->AFSOpaque_len = 0;
2397 AccessList->AFSOpaque_val = malloc(AFSOPAQUEMAX1024);
2398 if (!AccessList->AFSOpaque_val) {
2399 ViceLogThenPanic(0, ("Failed malloc in SRXAFS_FetchACL\n"))do { do { if ((0) <= LogLevel) (FSLog ("Failed malloc in SRXAFS_FetchACL\n"
)); } while (0); osi_Panic ("Failed malloc in SRXAFS_FetchACL\n"
); } while(0);
;
2400 }
2401
2402 /*
2403 * Get volume/vnode for the fetched file; caller's access rights to it
2404 * are also returned
2405 */
2406 if ((errorCode =
2407 GetVolumePackage(tcon, Fid, &volptr, &targetptr, DONTCHECK0,
2408 &parentwhentargetnotdir, &client, READ_LOCK1,
2409 &rights, &anyrights)))
2410 goto Bad_FetchACL;
2411
2412 SetVolumeSync(Sync, volptr);
2413
2414 /* Check whether we have permission to fetch the ACL */
2415 if ((errorCode =
2416 Check_PermissionRights(targetptr, client, rights, CHK_FETCHACL0x11, 0)))
2417 goto Bad_FetchACL;
2418
2419 /* Get the Access List from the dir's vnode */
2420 if ((errorCode =
2421 RXFetch_AccessList(targetptr, parentwhentargetnotdir, AccessList)))
2422 goto Bad_FetchACL;
2423
2424 /* Get OutStatus back From the target Vnode */
2425 GetStatus(targetptr, OutStatus, rights, anyrights,
2426 parentwhentargetnotdir);
2427
2428 Bad_FetchACL:
2429 /* Update and store volume/vnode and parent vnodes back */
2430 (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
2431 volptr, &client);
2432 ViceLog(2,do { if ((2) <= LogLevel) (FSLog ("SAFS_FetchACL returns %d (ACL=%s)\n"
, errorCode, AccessList->AFSOpaque_val)); } while (0)
2433 ("SAFS_FetchACL returns %d (ACL=%s)\n", errorCode,do { if ((2) <= LogLevel) (FSLog ("SAFS_FetchACL returns %d (ACL=%s)\n"
, errorCode, AccessList->AFSOpaque_val)); } while (0)
2434 AccessList->AFSOpaque_val))do { if ((2) <= LogLevel) (FSLog ("SAFS_FetchACL returns %d (ACL=%s)\n"
, errorCode, AccessList->AFSOpaque_val)); } while (0)
;
2435 errorCode = CallPostamble(tcon, errorCode, thost);
2436
2437 fsstats_FinishOp(&fsstats, errorCode);
2438
2439 osi_auditU(acall, FetchACLEvent"AFS_SRX_FchACL", errorCode,
2440 AUD_ID10, t_client ? t_client->ViceId : 0,
2441 AUD_FID7, Fid,
2442 AUD_ACL11, AccessList->AFSOpaque_val, AUD_END0);
2443 return errorCode;
2444} /*SRXAFS_FetchACL */
2445
2446
2447/*
2448 * This routine is called exclusively by SRXAFS_FetchStatus(), and should be
2449 * merged into it when possible.
2450 */
2451static
2452 afs_int32
2453SAFSS_FetchStatus(struct rx_call *acall, struct AFSFid *Fid,
2454 struct AFSFetchStatus *OutStatus,
2455 struct AFSCallBack *CallBack, struct AFSVolSync *Sync)
2456{
2457 Vnode *targetptr = 0; /* pointer to vnode to fetch */
2458 Vnode *parentwhentargetnotdir = 0; /* parent vnode if targetptr is a file */
2459 Errorbit32 errorCode = 0; /* return code to caller */
2460 Volume *volptr = 0; /* pointer to the volume */
2461 struct client *client = 0; /* pointer to the client data */
2462 afs_int32 rights, anyrights; /* rights for this and any user */
2463 struct client *t_client = NULL((void *)0); /* tmp ptr to client data */
2464 struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
2465 struct rx_connection *tcon = rx_ConnectionOf(acall)((acall)->conn);
2466
2467 /* Get ptr to client data for user Id for logging */
2468 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
2469 logHostAddr.s_addr = rxr_HostOf(tcon)(((((struct rx_connection *)(tcon))->peer))->host);
2470 ViceLog(1,do { if ((1) <= LogLevel) (FSLog ("SAFS_FetchStatus, Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
2471 ("SAFS_FetchStatus, Fid = %u.%u.%u, Host %s:%d, Id %d\n",do { if ((1) <= LogLevel) (FSLog ("SAFS_FetchStatus, Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
2472 Fid->Volume, Fid->Vnode, Fid->Unique, inet_ntoa(logHostAddr),do { if ((1) <= LogLevel) (FSLog ("SAFS_FetchStatus, Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
2473 ntohs(rxr_PortOf(tcon)), t_client->ViceId))do { if ((1) <= LogLevel) (FSLog ("SAFS_FetchStatus, Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
;
2474 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 2474), 0));
;
2475 AFSCallStats.FetchStatus++, AFSCallStats.TotalCalls++;
2476 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 2476), 0));
;
2477 /*
2478 * Get volume/vnode for the fetched file; caller's rights to it are
2479 * also returned
2480 */
2481 if ((errorCode =
2482 GetVolumePackage(tcon, Fid, &volptr, &targetptr, DONTCHECK0,
2483 &parentwhentargetnotdir, &client, READ_LOCK1,
2484 &rights, &anyrights)))
2485 goto Bad_FetchStatus;
2486
2487 /* set volume synchronization information */
2488 SetVolumeSync(Sync, volptr);
2489
2490 /* Are we allowed to fetch Fid's status? */
2491 if (targetptr->disk.type != vDirectory2) {
2492 if ((errorCode =
2493 Check_PermissionRights(targetptr, client, rights,
2494 CHK_FETCHSTATUS0x12, 0))) {
2495 if (rx_GetCallAbortCode(acall)((acall)->abortCode) == errorCode)
2496 rx_SetCallAbortCode(acall, 0)((acall)->abortCode = (0));
2497 goto Bad_FetchStatus;
2498 }
2499 }
2500
2501 /* set OutStatus From the Fid */
2502 GetStatus(targetptr, OutStatus, rights, anyrights,
2503 parentwhentargetnotdir);
2504
2505 /* If a r/w volume, also set the CallBack state */
2506 if (VolumeWriteable(volptr)(((volptr)->header->diskstuff.type)==0))
2507 SetCallBackStruct(AddCallBack(client->host, Fid)AddCallBack1((client->host), (Fid), (afs_uint32 *)0, 1 , 0
)
, CallBack);
2508 else {
2509 struct AFSFid myFid;
2510 memset(&myFid, 0, sizeof(struct AFSFid));
2511 myFid.Volume = Fid->Volume;
2512 SetCallBackStruct(AddVolCallBack(client->host, &myFid)AddCallBack1((client->host), (&myFid), (afs_uint32 *)0
, 3 , 0)
, CallBack);
2513 }
2514
2515 Bad_FetchStatus:
2516 /* Update and store volume/vnode and parent vnodes back */
2517 (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
2518 volptr, &client);
2519 ViceLog(2, ("SAFS_FetchStatus returns %d\n", errorCode))do { if ((2) <= LogLevel) (FSLog ("SAFS_FetchStatus returns %d\n"
, errorCode)); } while (0)
;
2520 return errorCode;
2521
2522} /*SAFSS_FetchStatus */
2523
2524
2525afs_int32
2526SRXAFS_BulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
2527 struct AFSBulkStats * OutStats, struct AFSCBs * CallBacks,
2528 struct AFSVolSync * Sync)
2529{
2530 int i;
2531 afs_int32 nfiles;
2532 Vnode *targetptr = 0; /* pointer to vnode to fetch */
2533 Vnode *parentwhentargetnotdir = 0; /* parent vnode if targetptr is a file */
2534 Errorbit32 errorCode = 0; /* return code to caller */
2535 Volume *volptr = 0; /* pointer to the volume */
2536 struct client *client = 0; /* pointer to the client data */
2537 afs_int32 rights, anyrights; /* rights for this and any user */
2538 struct AFSFid *tfid; /* file id we're dealing with now */
2539 struct rx_connection *tcon = rx_ConnectionOf(acall)((acall)->conn);
2540 struct host *thost;
2541 struct client *t_client = NULL((void *)0); /* tmp pointer to the client data */
2542 struct fsstats fsstats;
2543
2544 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_BULKSTATUS25);
2545
2546 ViceLog(1, ("SAFS_BulkStatus\n"))do { if ((1) <= LogLevel) (FSLog ("SAFS_BulkStatus\n")); }
while (0)
;
2547 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 2547), 0));
;
2548 AFSCallStats.TotalCalls++;
2549 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 2549), 0));
;
2550 nfiles = Fids->AFSCBFids_len; /* # of files in here */
2551 if (nfiles <= 0) { /* Sanity check */
2552 errorCode = EINVAL22;
2553 goto Audit_and_Return;
2554 }
2555
2556 /* allocate space for return output parameters */
2557 OutStats->AFSBulkStats_val = (struct AFSFetchStatus *)
2558 malloc(nfiles * sizeof(struct AFSFetchStatus));
2559 if (!OutStats->AFSBulkStats_val) {
2560 ViceLogThenPanic(0, ("Failed malloc in SRXAFS_BulkStatus\n"))do { do { if ((0) <= LogLevel) (FSLog ("Failed malloc in SRXAFS_BulkStatus\n"
)); } while (0); osi_Panic ("Failed malloc in SRXAFS_BulkStatus\n"
); } while(0);
;
2561 }
2562 OutStats->AFSBulkStats_len = nfiles;
2563 CallBacks->AFSCBs_val = (struct AFSCallBack *)
2564 malloc(nfiles * sizeof(struct AFSCallBack));
2565 if (!CallBacks->AFSCBs_val) {
2566 ViceLogThenPanic(0, ("Failed malloc in SRXAFS_BulkStatus\n"))do { do { if ((0) <= LogLevel) (FSLog ("Failed malloc in SRXAFS_BulkStatus\n"
)); } while (0); osi_Panic ("Failed malloc in SRXAFS_BulkStatus\n"
); } while(0);
;
2567 }
2568 CallBacks->AFSCBs_len = nfiles;
2569
2570 if ((errorCode = CallPreamble(acall, ACTIVECALL1, &tcon, &thost)))
2571 goto Bad_BulkStatus;
2572
2573 tfid = Fids->AFSCBFids_val;
2574 for (i = 0; i < nfiles; i++, tfid++) {
2575 /*
2576 * Get volume/vnode for the fetched file; caller's rights to it
2577 * are also returned
2578 */
2579 if ((errorCode =
2580 GetVolumePackage(tcon, tfid, &volptr, &targetptr, DONTCHECK0,
2581 &parentwhentargetnotdir, &client, READ_LOCK1,
2582 &rights, &anyrights)))
2583 goto Bad_BulkStatus;
2584 /* set volume synchronization information, but only once per call */
2585 if (i == 0)
2586 SetVolumeSync(Sync, volptr);
2587
2588 /* Are we allowed to fetch Fid's status? */
2589 if (targetptr->disk.type != vDirectory2) {
2590 if ((errorCode =
2591 Check_PermissionRights(targetptr, client, rights,
2592 CHK_FETCHSTATUS0x12, 0))) {
2593 if (rx_GetCallAbortCode(acall)((acall)->abortCode) == errorCode)
2594 rx_SetCallAbortCode(acall, 0)((acall)->abortCode = (0));
2595 goto Bad_BulkStatus;
2596 }
2597 }
2598
2599 /* set OutStatus From the Fid */
2600 GetStatus(targetptr, &OutStats->AFSBulkStats_val[i], rights,
2601 anyrights, parentwhentargetnotdir);
2602
2603 /* If a r/w volume, also set the CallBack state */
2604 if (VolumeWriteable(volptr)(((volptr)->header->diskstuff.type)==0))
2605 SetCallBackStruct(AddBulkCallBack(client->host, tfid)AddCallBack1((client->host), (tfid), (afs_uint32 *)0, 4 , 0
)
,
2606 &CallBacks->AFSCBs_val[i]);
2607 else {
2608 struct AFSFid myFid;
2609 memset(&myFid, 0, sizeof(struct AFSFid));
2610 myFid.Volume = tfid->Volume;
2611 SetCallBackStruct(AddVolCallBack(client->host, &myFid)AddCallBack1((client->host), (&myFid), (afs_uint32 *)0
, 3 , 0)
,
2612 &CallBacks->AFSCBs_val[i]);
2613 }
2614
2615 /* put back the file ID and volume */
2616 (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
2617 volptr, &client);
2618 parentwhentargetnotdir = (Vnode *) 0;
2619 targetptr = (Vnode *) 0;
2620 volptr = (Volume *) 0;
2621 client = (struct client *)0;
2622 }
2623
2624 Bad_BulkStatus:
2625 /* Update and store volume/vnode and parent vnodes back */
2626 (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
2627 volptr, &client);
2628 errorCode = CallPostamble(tcon, errorCode, thost);
2629
2630 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
2631
2632 fsstats_FinishOp(&fsstats, errorCode);
2633
2634 Audit_and_Return:
2635 ViceLog(2, ("SAFS_BulkStatus returns %d\n", errorCode))do { if ((2) <= LogLevel) (FSLog ("SAFS_BulkStatus returns %d\n"
, errorCode)); } while (0)
;
2636 osi_auditU(acall, BulkFetchStatusEvent"AFS_SRX_BFchSta", errorCode,
2637 AUD_ID10, t_client ? t_client->ViceId : 0,
2638 AUD_FIDS8, Fids, AUD_END0);
2639 return errorCode;
2640
2641} /*SRXAFS_BulkStatus */
2642
2643
2644afs_int32
2645SRXAFS_InlineBulkStatus(struct rx_call * acall, struct AFSCBFids * Fids,
2646 struct AFSBulkStats * OutStats,
2647 struct AFSCBs * CallBacks, struct AFSVolSync * Sync)
2648{
2649 int i;
2650 afs_int32 nfiles;
2651 Vnode *targetptr = 0; /* pointer to vnode to fetch */
2652 Vnode *parentwhentargetnotdir = 0; /* parent vnode if targetptr is a file */
2653 Errorbit32 errorCode = 0; /* return code to caller */
2654 Volume *volptr = 0; /* pointer to the volume */
2655 struct client *client = 0; /* pointer to the client data */
2656 afs_int32 rights, anyrights; /* rights for this and any user */
2657 struct AFSFid *tfid; /* file id we're dealing with now */
2658 struct rx_connection *tcon;
2659 struct host *thost;
2660 struct client *t_client = NULL((void *)0); /* tmp ptr to client data */
2661 AFSFetchStatus *tstatus;
2662 int VolSync_set = 0;
2663 struct fsstats fsstats;
2664
2665 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_BULKSTATUS25);
2666
2667 ViceLog(1, ("SAFS_InlineBulkStatus\n"))do { if ((1) <= LogLevel) (FSLog ("SAFS_InlineBulkStatus\n"
)); } while (0)
;
2668 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 2668), 0));
;
2669 AFSCallStats.TotalCalls++;
2670 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 2670), 0));
;
2671 nfiles = Fids->AFSCBFids_len; /* # of files in here */
2672 if (nfiles <= 0) { /* Sanity check */
2673 errorCode = EINVAL22;
2674 goto Audit_and_Return;
2675 }
2676
2677 /* allocate space for return output parameters */
2678 OutStats->AFSBulkStats_val = (struct AFSFetchStatus *)
2679 malloc(nfiles * sizeof(struct AFSFetchStatus));
2680 if (!OutStats->AFSBulkStats_val) {
2681 ViceLogThenPanic(0, ("Failed malloc in SRXAFS_FetchStatus\n"))do { do { if ((0) <= LogLevel) (FSLog ("Failed malloc in SRXAFS_FetchStatus\n"
)); } while (0); osi_Panic ("Failed malloc in SRXAFS_FetchStatus\n"
); } while(0);
;
2682 }
2683 OutStats->AFSBulkStats_len = nfiles;
2684 CallBacks->AFSCBs_val = (struct AFSCallBack *)
2685 malloc(nfiles * sizeof(struct AFSCallBack));
2686 if (!CallBacks->AFSCBs_val) {
2687 ViceLogThenPanic(0, ("Failed malloc in SRXAFS_FetchStatus\n"))do { do { if ((0) <= LogLevel) (FSLog ("Failed malloc in SRXAFS_FetchStatus\n"
)); } while (0); osi_Panic ("Failed malloc in SRXAFS_FetchStatus\n"
); } while(0);
;
2688 }
2689 CallBacks->AFSCBs_len = nfiles;
2690
2691 /* Zero out return values to avoid leaking information on partial succes */
2692 memset(OutStats->AFSBulkStats_val, 0, nfiles * sizeof(struct AFSFetchStatus));
2693 memset(CallBacks->AFSCBs_val, 0, nfiles * sizeof(struct AFSCallBack));
2694 memset(Sync, 0, sizeof(*Sync));
2695
2696 if ((errorCode = CallPreamble(acall, ACTIVECALL1, &tcon, &thost))) {
2697 goto Bad_InlineBulkStatus;
2698 }
2699
2700 tfid = Fids->AFSCBFids_val;
2701 for (i = 0; i < nfiles; i++, tfid++) {
2702 /*
2703 * Get volume/vnode for the fetched file; caller's rights to it
2704 * are also returned
2705 */
2706 if ((errorCode =
2707 GetVolumePackage(tcon, tfid, &volptr, &targetptr, DONTCHECK0,
2708 &parentwhentargetnotdir, &client, READ_LOCK1,
2709 &rights, &anyrights))) {
2710 tstatus = &OutStats->AFSBulkStats_val[i];
2711 tstatus->errorCode = errorCode;
2712 PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
2713 volptr, &client);
2714 parentwhentargetnotdir = (Vnode *) 0;
2715 targetptr = (Vnode *) 0;
2716 volptr = (Volume *) 0;
2717 client = (struct client *)0;
2718 continue;
2719 }
2720
2721 /* set volume synchronization information, but only once per call */
2722 if (!VolSync_set) {
2723 SetVolumeSync(Sync, volptr);
2724 VolSync_set = 1;
2725 }
2726
2727 /* Are we allowed to fetch Fid's status? */
2728 if (targetptr->disk.type != vDirectory2) {
2729 if ((errorCode =
2730 Check_PermissionRights(targetptr, client, rights,
2731 CHK_FETCHSTATUS0x12, 0))) {
2732 tstatus = &OutStats->AFSBulkStats_val[i];
2733 tstatus->errorCode = errorCode;
2734 (void)PutVolumePackage(parentwhentargetnotdir, targetptr,
2735 (Vnode *) 0, volptr, &client);
2736 parentwhentargetnotdir = (Vnode *) 0;
2737 targetptr = (Vnode *) 0;
2738 volptr = (Volume *) 0;
2739 client = (struct client *)0;
2740 continue;
2741 }
2742 }
2743
2744 /* set OutStatus From the Fid */
2745 GetStatus(targetptr,
2746 (struct AFSFetchStatus *)&OutStats->AFSBulkStats_val[i],
2747 rights, anyrights, parentwhentargetnotdir);
2748
2749 /* If a r/w volume, also set the CallBack state */
2750 if (VolumeWriteable(volptr)(((volptr)->header->diskstuff.type)==0))
2751 SetCallBackStruct(AddBulkCallBack(client->host, tfid)AddCallBack1((client->host), (tfid), (afs_uint32 *)0, 4 , 0
)
,
2752 &CallBacks->AFSCBs_val[i]);
2753 else {
2754 struct AFSFid myFid;
2755 memset(&myFid, 0, sizeof(struct AFSFid));
2756 myFid.Volume = tfid->Volume;
2757 SetCallBackStruct(AddVolCallBack(client->host, &myFid)AddCallBack1((client->host), (&myFid), (afs_uint32 *)0
, 3 , 0)
,
2758 &CallBacks->AFSCBs_val[i]);
2759 }
2760
2761 /* put back the file ID and volume */
2762 (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
2763 volptr, &client);
2764 parentwhentargetnotdir = (Vnode *) 0;
2765 targetptr = (Vnode *) 0;
2766 volptr = (Volume *) 0;
2767 client = (struct client *)0;
2768 }
2769
2770 Bad_InlineBulkStatus:
2771 /* Update and store volume/vnode and parent vnodes back */
2772 (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
2773 volptr, &client);
2774 errorCode = CallPostamble(tcon, errorCode, thost);
2775
2776 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
2777
2778 fsstats_FinishOp(&fsstats, errorCode);
2779
2780 Audit_and_Return:
2781 ViceLog(2, ("SAFS_InlineBulkStatus returns %d\n", errorCode))do { if ((2) <= LogLevel) (FSLog ("SAFS_InlineBulkStatus returns %d\n"
, errorCode)); } while (0)
;
2782 osi_auditU(acall, InlineBulkFetchStatusEvent"AFS_SRX_BIFchSt", errorCode,
2783 AUD_ID10, t_client ? t_client->ViceId : 0,
2784 AUD_FIDS8, Fids, AUD_END0);
2785 return 0;
2786
2787} /*SRXAFS_InlineBulkStatus */
2788
2789
2790afs_int32
2791SRXAFS_FetchStatus(struct rx_call * acall, struct AFSFid * Fid,
2792 struct AFSFetchStatus * OutStatus,
2793 struct AFSCallBack * CallBack, struct AFSVolSync * Sync)
2794{
2795 afs_int32 code;
2796 struct rx_connection *tcon;
2797 struct host *thost;
2798 struct client *t_client = NULL((void *)0); /* tmp ptr to client data */
2799 struct fsstats fsstats;
2800
2801 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_FETCHSTATUS2);
2802
2803 if ((code = CallPreamble(acall, ACTIVECALL1, &tcon, &thost)))
2804 goto Bad_FetchStatus;
2805
2806 code = SAFSS_FetchStatus(acall, Fid, OutStatus, CallBack, Sync);
2807
2808 Bad_FetchStatus:
2809 code = CallPostamble(tcon, code, thost);
2810
2811 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
2812
2813 fsstats_FinishOp(&fsstats, code);
2814
2815 osi_auditU(acall, FetchStatusEvent"AFS_SRX_FchStat", code,
2816 AUD_ID10, t_client ? t_client->ViceId : 0,
2817 AUD_FID7, Fid, AUD_END0);
2818 return code;
2819
2820} /*SRXAFS_FetchStatus */
2821
2822static
2823 afs_int32
2824common_StoreData64(struct rx_call *acall, struct AFSFid *Fid,
2825 struct AFSStoreStatus *InStatus, afs_fsize_t Pos,
2826 afs_fsize_t Length, afs_fsize_t FileLength,
2827 struct AFSFetchStatus *OutStatus, struct AFSVolSync *Sync)
2828{
2829 Vnode *targetptr = 0; /* pointer to input fid */
2830 Vnode *parentwhentargetnotdir = 0; /* parent of Fid to get ACL */
2831 Vnode tparentwhentargetnotdir; /* parent vnode for GetStatus */
2832 Errorbit32 errorCode = 0; /* return code for caller */
2833 Errorbit32 fileCode = 0; /* return code from vol package */
2834 Volume *volptr = 0; /* pointer to the volume header */
2835 struct client *client = 0; /* pointer to client structure */
2836 afs_int32 rights, anyrights; /* rights for this and any user */
2837 struct client *t_client = NULL((void *)0); /* tmp ptr to client data */
2838 struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
2839 struct rx_connection *tcon;
2840 struct host *thost;
2841 struct fsstats fsstats;
2842 afs_sfsize_t bytesToXfer;
2843 afs_sfsize_t bytesXferred;
2844 static int remainder = 0;
2845
2846 ViceLog(1,do { if ((1) <= LogLevel) (FSLog ("StoreData: Fid = %u.%u.%u\n"
, Fid->Volume, Fid->Vnode, Fid->Unique)); } while (0
)
2847 ("StoreData: Fid = %u.%u.%u\n", Fid->Volume, Fid->Vnode,do { if ((1) <= LogLevel) (FSLog ("StoreData: Fid = %u.%u.%u\n"
, Fid->Volume, Fid->Vnode, Fid->Unique)); } while (0
)
2848 Fid->Unique))do { if ((1) <= LogLevel) (FSLog ("StoreData: Fid = %u.%u.%u\n"
, Fid->Volume, Fid->Vnode, Fid->Unique)); } while (0
)
;
2849
2850 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_STOREDATA3);
2851
2852 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 2852), 0));
;
2853 AFSCallStats.StoreData++, AFSCallStats.TotalCalls++;
2854 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 2854), 0));
;
2855 if ((errorCode = CallPreamble(acall, ACTIVECALL1, &tcon, &thost)))
2856 goto Bad_StoreData;
2857
2858 /* Get ptr to client data for user Id for logging */
2859 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
2860 logHostAddr.s_addr = rxr_HostOf(tcon)(((((struct rx_connection *)(tcon))->peer))->host);
2861 ViceLog(5,do { if ((5) <= LogLevel) (FSLog ("StoreData: Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
2862 ("StoreData: Fid = %u.%u.%u, Host %s:%d, Id %d\n", Fid->Volume,do { if ((5) <= LogLevel) (FSLog ("StoreData: Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
2863 Fid->Vnode, Fid->Unique, inet_ntoa(logHostAddr),do { if ((5) <= LogLevel) (FSLog ("StoreData: Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
2864 ntohs(rxr_PortOf(tcon)), t_client->ViceId))do { if ((5) <= LogLevel) (FSLog ("StoreData: Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
;
2865
2866 /*
2867 * Get associated volume/vnode for the stored file; caller's rights
2868 * are also returned
2869 */
2870 if ((errorCode =
2871 GetVolumePackage(tcon, Fid, &volptr, &targetptr, MustNOTBeDIR1,
2872 &parentwhentargetnotdir, &client, WRITE_LOCK2,
2873 &rights, &anyrights))) {
2874 goto Bad_StoreData;
2875 }
2876
2877 /* set volume synchronization information */
2878 SetVolumeSync(Sync, volptr);
2879
2880 if ((targetptr->disk.type == vSymlink3)) {
2881 /* Should we return a better error code here??? */
2882 errorCode = EISDIR21;
2883 goto Bad_StoreData;
2884 }
2885
2886 /* Check if we're allowed to store the data */
2887 if ((errorCode =
2888 Check_PermissionRights(targetptr, client, rights, CHK_STOREDATA0x00,
2889 InStatus))) {
2890 goto Bad_StoreData;
2891 }
2892
2893 /*
2894 * Drop the read lock on the parent directory after saving the parent
2895 * vnode information we need to pass to GetStatus
2896 */
2897 if (parentwhentargetnotdir != NULL((void *)0)) {
2898 tparentwhentargetnotdir = *parentwhentargetnotdir;
2899 VPutVnode(&fileCode, parentwhentargetnotdir);
2900 osi_Assert(!fileCode || (fileCode == VSALVAGE))(void)((!fileCode || (fileCode == 101)) || (osi_AssertFailU("!fileCode || (fileCode == VSALVAGE)"
, "./../viced/afsfileprocs.c", 2900), 0))
;
2901 parentwhentargetnotdir = NULL((void *)0);
2902 }
2903
2904 fsstats_StartXfer(&fsstats);
2905
2906 errorCode =
2907 StoreData_RXStyle(volptr, targetptr, Fid, client, acall, Pos, Length,
2908 FileLength, (InStatus->Mask & AFS_FSYNC1024),
2909 &bytesToXfer, &bytesXferred);
2910
2911 fsstats_FinishXfer(&fsstats, errorCode, bytesToXfer, bytesXferred,
2912 &remainder);
2913
2914 if (errorCode && (!targetptr->changed_newTime))
2915 goto Bad_StoreData;
2916
2917 /* Update the status of the target's vnode */
2918 Update_TargetVnodeStatus(targetptr, TVS_SDATA1, client, InStatus,
2919 targetptr, volptr, 0);
2920
2921 /* Get the updated File's status back to the caller */
2922 GetStatus(targetptr, OutStatus, rights, anyrights,
2923 &tparentwhentargetnotdir);
2924
2925 Bad_StoreData:
2926 /* Update and store volume/vnode and parent vnodes back */
2927 (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
2928 volptr, &client);
2929 ViceLog(2, ("SAFS_StoreData returns %d\n", errorCode))do { if ((2) <= LogLevel) (FSLog ("SAFS_StoreData returns %d\n"
, errorCode)); } while (0)
;
2930
2931 errorCode = CallPostamble(tcon, errorCode, thost);
2932
2933 fsstats_FinishOp(&fsstats, errorCode);
2934
2935 osi_auditU(acall, StoreDataEvent"AFS_SRX_StData", errorCode,
2936 AUD_ID10, t_client ? t_client->ViceId : 0,
2937 AUD_FID7, Fid, AUD_END0);
2938 return (errorCode);
2939} /*common_StoreData64 */
2940
2941afs_int32
2942SRXAFS_StoreData(struct rx_call * acall, struct AFSFid * Fid,
2943 struct AFSStoreStatus * InStatus, afs_uint32 Pos,
2944 afs_uint32 Length, afs_uint32 FileLength,
2945 struct AFSFetchStatus * OutStatus, struct AFSVolSync * Sync)
2946{
2947 if (FileLength > 0x7fffffff || Pos > 0x7fffffff ||
2948 (0x7fffffff - Pos) < Length)
2949 return EFBIG27;
2950
2951 return common_StoreData64(acall, Fid, InStatus, Pos, Length, FileLength,
2952 OutStatus, Sync);
2953} /*SRXAFS_StoreData */
2954
2955afs_int32
2956SRXAFS_StoreData64(struct rx_call * acall, struct AFSFid * Fid,
2957 struct AFSStoreStatus * InStatus, afs_uint64 Pos,
2958 afs_uint64 Length, afs_uint64 FileLength,
2959 struct AFSFetchStatus * OutStatus,
2960 struct AFSVolSync * Sync)
2961{
2962 int code;
2963 afs_fsize_t tPos;
2964 afs_fsize_t tLength;
2965 afs_fsize_t tFileLength;
2966
2967 tPos = (afs_fsize_t) Pos;
2968 tLength = (afs_fsize_t) Length;
2969 tFileLength = (afs_fsize_t) FileLength;
2970
2971 code =
2972 common_StoreData64(acall, Fid, InStatus, tPos, tLength, tFileLength,
2973 OutStatus, Sync);
2974 return code;
2975}
2976
2977afs_int32
2978SRXAFS_StoreACL(struct rx_call * acall, struct AFSFid * Fid,
2979 struct AFSOpaque * AccessList,
2980 struct AFSFetchStatus * OutStatus, struct AFSVolSync * Sync)
2981{
2982 Vnode *targetptr = 0; /* pointer to input fid */
2983 Vnode *parentwhentargetnotdir = 0; /* parent of Fid to get ACL */
2984 Errorbit32 errorCode = 0; /* return code for caller */
2985 struct AFSStoreStatus InStatus; /* Input status for fid */
2986 Volume *volptr = 0; /* pointer to the volume header */
2987 struct client *client = 0; /* pointer to client structure */
2988 afs_int32 rights, anyrights; /* rights for this and any user */
2989 struct rx_connection *tcon;
2990 struct host *thost;
2991 struct client *t_client = NULL((void *)0); /* tmp ptr to client data */
2992 struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
2993 struct fsstats fsstats;
2994
2995 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_STOREACL4);
2996
2997 if ((errorCode = CallPreamble(acall, ACTIVECALL1, &tcon, &thost)))
2998 goto Bad_StoreACL;
2999
3000 /* Get ptr to client data for user Id for logging */
3001 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
3002 logHostAddr.s_addr = rxr_HostOf(tcon)(((((struct rx_connection *)(tcon))->peer))->host);
3003 ViceLog(1,do { if ((1) <= LogLevel) (FSLog ("SAFS_StoreACL, Fid = %u.%u.%u, ACL=%s, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, AccessList->
AFSOpaque_val, __inet_ntoa(logHostAddr), (__builtin_constant_p
(((((((struct rx_connection *)(tcon)))->peer))->port)) ?
(__uint16_t)(((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) << 8 | ((__uint16_t)(((((((struct
rx_connection *)(tcon)))->peer))->port))) >> 8) :
__bswap16_var(((((((struct rx_connection *)(tcon)))->peer
))->port))), t_client->ViceId)); } while (0)
3004 ("SAFS_StoreACL, Fid = %u.%u.%u, ACL=%s, Host %s:%d, Id %d\n",do { if ((1) <= LogLevel) (FSLog ("SAFS_StoreACL, Fid = %u.%u.%u, ACL=%s, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, AccessList->
AFSOpaque_val, __inet_ntoa(logHostAddr), (__builtin_constant_p
(((((((struct rx_connection *)(tcon)))->peer))->port)) ?
(__uint16_t)(((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) << 8 | ((__uint16_t)(((((((struct
rx_connection *)(tcon)))->peer))->port))) >> 8) :
__bswap16_var(((((((struct rx_connection *)(tcon)))->peer
))->port))), t_client->ViceId)); } while (0)
3005 Fid->Volume, Fid->Vnode, Fid->Unique, AccessList->AFSOpaque_val,do { if ((1) <= LogLevel) (FSLog ("SAFS_StoreACL, Fid = %u.%u.%u, ACL=%s, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, AccessList->
AFSOpaque_val, __inet_ntoa(logHostAddr), (__builtin_constant_p
(((((((struct rx_connection *)(tcon)))->peer))->port)) ?
(__uint16_t)(((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) << 8 | ((__uint16_t)(((((((struct
rx_connection *)(tcon)))->peer))->port))) >> 8) :
__bswap16_var(((((((struct rx_connection *)(tcon)))->peer
))->port))), t_client->ViceId)); } while (0)
3006 inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId))do { if ((1) <= LogLevel) (FSLog ("SAFS_StoreACL, Fid = %u.%u.%u, ACL=%s, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, AccessList->
AFSOpaque_val, __inet_ntoa(logHostAddr), (__builtin_constant_p
(((((((struct rx_connection *)(tcon)))->peer))->port)) ?
(__uint16_t)(((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) << 8 | ((__uint16_t)(((((((struct
rx_connection *)(tcon)))->peer))->port))) >> 8) :
__bswap16_var(((((((struct rx_connection *)(tcon)))->peer
))->port))), t_client->ViceId)); } while (0)
;
3007 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 3007), 0));
;
3008 AFSCallStats.StoreACL++, AFSCallStats.TotalCalls++;
3009 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 3009), 0));
;
3010 InStatus.Mask = 0; /* not storing any status */
3011
3012 /*
3013 * Get associated volume/vnode for the target dir; caller's rights
3014 * are also returned.
3015 */
3016 if ((errorCode =
3017 GetVolumePackage(tcon, Fid, &volptr, &targetptr, MustBeDIR2,
3018 &parentwhentargetnotdir, &client, WRITE_LOCK2,
3019 &rights, &anyrights))) {
3020 goto Bad_StoreACL;
3021 }
3022
3023 /* set volume synchronization information */
3024 SetVolumeSync(Sync, volptr);
3025
3026 /* Check if we have permission to change the dir's ACL */
3027 if ((errorCode =
3028 Check_PermissionRights(targetptr, client, rights, CHK_STOREACL0x01,
3029 &InStatus))) {
3030 goto Bad_StoreACL;
3031 }
3032
3033 /* Build and store the new Access List for the dir */
3034 if ((errorCode = RXStore_AccessList(targetptr, AccessList))) {
3035 goto Bad_StoreACL;
3036 }
3037
3038 targetptr->changed_newTime = 1; /* status change of directory */
3039
3040 /* convert the write lock to a read lock before breaking callbacks */
3041 VVnodeWriteToRead(&errorCode, targetptr);
3042 osi_Assert(!errorCode || errorCode == VSALVAGE)(void)((!errorCode || errorCode == 101) || (osi_AssertFailU("!errorCode || errorCode == VSALVAGE"
, "./../viced/afsfileprocs.c", 3042), 0))
;
3043
3044 /* break call backs on the directory */
3045 BreakCallBack(client->host, Fid, 0);
3046
3047 /* Get the updated dir's status back to the caller */
3048 GetStatus(targetptr, OutStatus, rights, anyrights, 0);
3049
3050 Bad_StoreACL:
3051 /* Update and store volume/vnode and parent vnodes back */
3052 PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
3053 volptr, &client);
3054 ViceLog(2, ("SAFS_StoreACL returns %d\n", errorCode))do { if ((2) <= LogLevel) (FSLog ("SAFS_StoreACL returns %d\n"
, errorCode)); } while (0)
;
3055 errorCode = CallPostamble(tcon, errorCode, thost);
3056
3057 fsstats_FinishOp(&fsstats, errorCode);
3058
3059 osi_auditU(acall, StoreACLEvent"AFS_SRX_StACL", errorCode,
3060 AUD_ID10, t_client ? t_client->ViceId : 0,
3061 AUD_FID7, Fid, AUD_ACL11, AccessList->AFSOpaque_val, AUD_END0);
3062 return errorCode;
3063
3064} /*SRXAFS_StoreACL */
3065
3066
3067/*
3068 * Note: This routine is called exclusively from SRXAFS_StoreStatus(), and
3069 * should be merged when possible.
3070 */
3071static afs_int32
3072SAFSS_StoreStatus(struct rx_call *acall, struct AFSFid *Fid,
3073 struct AFSStoreStatus *InStatus,
3074 struct AFSFetchStatus *OutStatus, struct AFSVolSync *Sync)
3075{
3076 Vnode *targetptr = 0; /* pointer to input fid */
3077 Vnode *parentwhentargetnotdir = 0; /* parent of Fid to get ACL */
3078 Errorbit32 errorCode = 0; /* return code for caller */
3079 Volume *volptr = 0; /* pointer to the volume header */
3080 struct client *client = 0; /* pointer to client structure */
3081 afs_int32 rights, anyrights; /* rights for this and any user */
3082 struct client *t_client = NULL((void *)0); /* tmp ptr to client data */
3083 struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
3084 struct rx_connection *tcon = rx_ConnectionOf(acall)((acall)->conn);
3085
3086 /* Get ptr to client data for user Id for logging */
3087 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
3088 logHostAddr.s_addr = rxr_HostOf(tcon)(((((struct rx_connection *)(tcon))->peer))->host);
3089 ViceLog(1,do { if ((1) <= LogLevel) (FSLog ("SAFS_StoreStatus, Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
3090 ("SAFS_StoreStatus, Fid = %u.%u.%u, Host %s:%d, Id %d\n",do { if ((1) <= LogLevel) (FSLog ("SAFS_StoreStatus, Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
3091 Fid->Volume, Fid->Vnode, Fid->Unique, inet_ntoa(logHostAddr),do { if ((1) <= LogLevel) (FSLog ("SAFS_StoreStatus, Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
3092 ntohs(rxr_PortOf(tcon)), t_client->ViceId))do { if ((1) <= LogLevel) (FSLog ("SAFS_StoreStatus, Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
;
3093 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 3093), 0));
;
3094 AFSCallStats.StoreStatus++, AFSCallStats.TotalCalls++;
3095 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 3095), 0));
;
3096 /*
3097 * Get volume/vnode for the target file; caller's rights to it are
3098 * also returned
3099 */
3100 if ((errorCode =
3101 GetVolumePackage(tcon, Fid, &volptr, &targetptr, DONTCHECK0,
3102 &parentwhentargetnotdir, &client, WRITE_LOCK2,
3103 &rights, &anyrights))) {
3104 goto Bad_StoreStatus;
3105 }
3106
3107 /* set volume synchronization information */
3108 SetVolumeSync(Sync, volptr);
3109
3110 /* Check if the caller has proper permissions to store status to Fid */
3111 if ((errorCode =
3112 Check_PermissionRights(targetptr, client, rights, CHK_STORESTATUS0x02,
3113 InStatus))) {
3114 goto Bad_StoreStatus;
3115 }
3116 /*
3117 * Check for a symbolic link; we can't chmod these (otherwise could
3118 * change a symlink to a mt pt or vice versa)
3119 */
3120 if (targetptr->disk.type == vSymlink3 && (InStatus->Mask & AFS_SETMODE8)) {
3121 errorCode = EINVAL22;
3122 goto Bad_StoreStatus;
3123 }
3124
3125 /* Update the status of the target's vnode */
3126 Update_TargetVnodeStatus(targetptr, TVS_SSTATUS2, client, InStatus,
3127 (parentwhentargetnotdir ? parentwhentargetnotdir
3128 : targetptr), volptr, 0);
3129
3130 /* convert the write lock to a read lock before breaking callbacks */
3131 VVnodeWriteToRead(&errorCode, targetptr);
3132 osi_Assert(!errorCode || errorCode == VSALVAGE)(void)((!errorCode || errorCode == 101) || (osi_AssertFailU("!errorCode || errorCode == VSALVAGE"
, "./../viced/afsfileprocs.c", 3132), 0))
;
3133
3134 /* Break call backs on Fid */
3135 BreakCallBack(client->host, Fid, 0);
3136
3137 /* Return the updated status back to caller */
3138 GetStatus(targetptr, OutStatus, rights, anyrights,
3139 parentwhentargetnotdir);
3140
3141 Bad_StoreStatus:
3142 /* Update and store volume/vnode and parent vnodes back */
3143 PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
3144 volptr, &client);
3145 ViceLog(2, ("SAFS_StoreStatus returns %d\n", errorCode))do { if ((2) <= LogLevel) (FSLog ("SAFS_StoreStatus returns %d\n"
, errorCode)); } while (0)
;
3146 return errorCode;
3147
3148} /*SAFSS_StoreStatus */
3149
3150
3151afs_int32
3152SRXAFS_StoreStatus(struct rx_call * acall, struct AFSFid * Fid,
3153 struct AFSStoreStatus * InStatus,
3154 struct AFSFetchStatus * OutStatus,
3155 struct AFSVolSync * Sync)
3156{
3157 afs_int32 code;
3158 struct rx_connection *tcon;
3159 struct host *thost;
3160 struct client *t_client = NULL((void *)0); /* tmp ptr to client data */
3161 struct fsstats fsstats;
3162
3163 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_STORESTATUS5);
3164
3165 if ((code = CallPreamble(acall, ACTIVECALL1, &tcon, &thost)))
3166 goto Bad_StoreStatus;
3167
3168 code = SAFSS_StoreStatus(acall, Fid, InStatus, OutStatus, Sync);
3169
3170 Bad_StoreStatus:
3171 code = CallPostamble(tcon, code, thost);
3172
3173 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
3174
3175 fsstats_FinishOp(&fsstats, code);
3176
3177 osi_auditU(acall, StoreStatusEvent"AFS_SRX_StStat", code,
3178 AUD_ID10, t_client ? t_client->ViceId : 0,
3179 AUD_FID7, Fid, AUD_END0);
3180 return code;
3181
3182} /*SRXAFS_StoreStatus */
3183
3184
3185/*
3186 * This routine is called exclusively by SRXAFS_RemoveFile(), and should be
3187 * merged in when possible.
3188 */
3189static afs_int32
3190SAFSS_RemoveFile(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
3191 struct AFSFetchStatus *OutDirStatus, struct AFSVolSync *Sync)
3192{
3193 Vnode *parentptr = 0; /* vnode of input Directory */
3194 Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
3195 Vnode *targetptr = 0; /* file to be deleted */
3196 Volume *volptr = 0; /* pointer to the volume header */
3197 AFSFid fileFid; /* area for Fid from the directory */
3198 Errorbit32 errorCode = 0; /* error code */
3199 DirHandle dir; /* Handle for dir package I/O */
3200 struct client *client = 0; /* pointer to client structure */
3201 afs_int32 rights, anyrights; /* rights for this and any user */
3202 struct client *t_client; /* tmp ptr to client data */
3203 struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
3204 struct rx_connection *tcon = rx_ConnectionOf(acall)((acall)->conn);
3205
3206 FidZero(&dir);
3207 /* Get ptr to client data for user Id for logging */
3208 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
3209 logHostAddr.s_addr = rxr_HostOf(tcon)(((((struct rx_connection *)(tcon))->peer))->host);
3210 ViceLog(1,do { if ((1) <= LogLevel) (FSLog ("SAFS_RemoveFile %s, Did = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, DirFid->Volume, DirFid->Vnode, DirFid->Unique
, __inet_ntoa(logHostAddr), (__builtin_constant_p(((((((struct
rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
3211 ("SAFS_RemoveFile %s, Did = %u.%u.%u, Host %s:%d, Id %d\n", Name,do { if ((1) <= LogLevel) (FSLog ("SAFS_RemoveFile %s, Did = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, DirFid->Volume, DirFid->Vnode, DirFid->Unique
, __inet_ntoa(logHostAddr), (__builtin_constant_p(((((((struct
rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
3212 DirFid->Volume, DirFid->Vnode, DirFid->Unique,do { if ((1) <= LogLevel) (FSLog ("SAFS_RemoveFile %s, Did = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, DirFid->Volume, DirFid->Vnode, DirFid->Unique
, __inet_ntoa(logHostAddr), (__builtin_constant_p(((((((struct
rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
3213 inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId))do { if ((1) <= LogLevel) (FSLog ("SAFS_RemoveFile %s, Did = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, DirFid->Volume, DirFid->Vnode, DirFid->Unique
, __inet_ntoa(logHostAddr), (__builtin_constant_p(((((((struct
rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
;
3214 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 3214), 0));
;
3215 AFSCallStats.RemoveFile++, AFSCallStats.TotalCalls++;
3216 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 3216), 0));
;
3217 /*
3218 * Get volume/vnode for the parent dir; caller's access rights are
3219 * also returned
3220 */
3221 if ((errorCode =
3222 GetVolumePackage(tcon, DirFid, &volptr, &parentptr, MustBeDIR2,
3223 &parentwhentargetnotdir, &client, WRITE_LOCK2,
3224 &rights, &anyrights))) {
3225 goto Bad_RemoveFile;
3226 }
3227 /* set volume synchronization information */
3228 SetVolumeSync(Sync, volptr);
3229
3230 /* Does the caller has delete (& write) access to the parent directory? */
3231 if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_DELETE16))) {
3232 goto Bad_RemoveFile;
3233 }
3234
3235 /* Actually delete the desired file */
3236 if ((errorCode =
3237 DeleteTarget(parentptr, volptr, &targetptr, &dir, &fileFid, Name,
3238 MustNOTBeDIR1))) {
3239 goto Bad_RemoveFile;
3240 }
3241
3242 /* Update the vnode status of the parent dir */
3243#if FS_STATS_DETAILED1
3244 Update_ParentVnodeStatus(parentptr, volptr, &dir, client->ViceId,
3245 parentptr->disk.linkCount,
3246 client->InSameNetwork);
3247#else
3248 Update_ParentVnodeStatus(parentptr, volptr, &dir, client->ViceId,
3249 parentptr->disk.linkCount);
3250#endif /* FS_STATS_DETAILED */
3251
3252 /* Return the updated parent dir's status back to caller */
3253 GetStatus(parentptr, OutDirStatus, rights, anyrights, 0);
3254
3255 /* Handle internal callback state for the parent and the deleted file */
3256 if (targetptr->disk.linkCount == 0) {
3257 /* no references left, discard entry */
3258 DeleteFileCallBacks(&fileFid);
3259 /* convert the parent lock to a read lock before breaking callbacks */
3260 VVnodeWriteToRead(&errorCode, parentptr);
3261 osi_Assert(!errorCode || errorCode == VSALVAGE)(void)((!errorCode || errorCode == 101) || (osi_AssertFailU("!errorCode || errorCode == VSALVAGE"
, "./../viced/afsfileprocs.c", 3261), 0))
;
3262 } else {
3263 /* convert the parent lock to a read lock before breaking callbacks */
3264 VVnodeWriteToRead(&errorCode, parentptr);
3265 osi_Assert(!errorCode || errorCode == VSALVAGE)(void)((!errorCode || errorCode == 101) || (osi_AssertFailU("!errorCode || errorCode == VSALVAGE"
, "./../viced/afsfileprocs.c", 3265), 0))
;
3266 /* convert the target lock to a read lock before breaking callbacks */
3267 VVnodeWriteToRead(&errorCode, targetptr);
3268 osi_Assert(!errorCode || errorCode == VSALVAGE)(void)((!errorCode || errorCode == 101) || (osi_AssertFailU("!errorCode || errorCode == VSALVAGE"
, "./../viced/afsfileprocs.c", 3268), 0))
;
3269 /* tell all the file has changed */
3270 BreakCallBack(client->host, &fileFid, 1);
3271 }
3272
3273 /* break call back on the directory */
3274 BreakCallBack(client->host, DirFid, 0);
3275
3276 Bad_RemoveFile:
3277 /* Update and store volume/vnode and parent vnodes back */
3278 PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr,
3279 volptr, &client);
3280 FidZap(&dir);
3281 ViceLog(2, ("SAFS_RemoveFile returns %d\n", errorCode))do { if ((2) <= LogLevel) (FSLog ("SAFS_RemoveFile returns %d\n"
, errorCode)); } while (0)
;
3282 return errorCode;
3283
3284} /*SAFSS_RemoveFile */
3285
3286
3287afs_int32
3288SRXAFS_RemoveFile(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
3289 struct AFSFetchStatus * OutDirStatus,
3290 struct AFSVolSync * Sync)
3291{
3292 afs_int32 code;
3293 struct rx_connection *tcon;
3294 struct host *thost;
3295 struct client *t_client = NULL((void *)0); /* tmp ptr to client data */
3296 struct fsstats fsstats;
3297
3298 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_REMOVEFILE6);
3299
3300 if ((code = CallPreamble(acall, ACTIVECALL1, &tcon, &thost)))
3301 goto Bad_RemoveFile;
3302
3303 code = SAFSS_RemoveFile(acall, DirFid, Name, OutDirStatus, Sync);
3304
3305 Bad_RemoveFile:
3306 code = CallPostamble(tcon, code, thost);
3307
3308 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
3309
3310 fsstats_FinishOp(&fsstats, code);
3311
3312 osi_auditU(acall, RemoveFileEvent"AFS_SRX_RmFile", code,
3313 AUD_ID10, t_client ? t_client->ViceId : 0,
3314 AUD_FID7, DirFid, AUD_STR1, Name, AUD_END0);
3315 return code;
3316
3317} /*SRXAFS_RemoveFile */
3318
3319
3320/*
3321 * This routine is called exclusively from SRXAFS_CreateFile(), and should
3322 * be merged in when possible.
3323 */
3324static afs_int32
3325SAFSS_CreateFile(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
3326 struct AFSStoreStatus *InStatus, struct AFSFid *OutFid,
3327 struct AFSFetchStatus *OutFidStatus,
3328 struct AFSFetchStatus *OutDirStatus,
3329 struct AFSCallBack *CallBack, struct AFSVolSync *Sync)
3330{
3331 Vnode *parentptr = 0; /* vnode of input Directory */
3332 Vnode *targetptr = 0; /* vnode of the new file */
3333 Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
3334 Volume *volptr = 0; /* pointer to the volume header */
3335 Errorbit32 errorCode = 0; /* error code */
3336 DirHandle dir; /* Handle for dir package I/O */
3337 struct client *client = 0; /* pointer to client structure */
3338 afs_int32 rights, anyrights; /* rights for this and any user */
3339 struct client *t_client; /* tmp ptr to client data */
3340 struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
3341 struct rx_connection *tcon = rx_ConnectionOf(acall)((acall)->conn);
3342
3343 FidZero(&dir);
3344
3345 /* Get ptr to client data for user Id for logging */
3346 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
3347 logHostAddr.s_addr = rxr_HostOf(tcon)(((((struct rx_connection *)(tcon))->peer))->host);
3348 ViceLog(1,do { if ((1) <= LogLevel) (FSLog ("SAFS_CreateFile %s, Did = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, DirFid->Volume, DirFid->Vnode, DirFid->Unique
, __inet_ntoa(logHostAddr), (__builtin_constant_p(((((((struct
rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
3349 ("SAFS_CreateFile %s, Did = %u.%u.%u, Host %s:%d, Id %d\n", Name,do { if ((1) <= LogLevel) (FSLog ("SAFS_CreateFile %s, Did = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, DirFid->Volume, DirFid->Vnode, DirFid->Unique
, __inet_ntoa(logHostAddr), (__builtin_constant_p(((((((struct
rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
3350 DirFid->Volume, DirFid->Vnode, DirFid->Unique,do { if ((1) <= LogLevel) (FSLog ("SAFS_CreateFile %s, Did = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, DirFid->Volume, DirFid->Vnode, DirFid->Unique
, __inet_ntoa(logHostAddr), (__builtin_constant_p(((((((struct
rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
3351 inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId))do { if ((1) <= LogLevel) (FSLog ("SAFS_CreateFile %s, Did = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, DirFid->Volume, DirFid->Vnode, DirFid->Unique
, __inet_ntoa(logHostAddr), (__builtin_constant_p(((((((struct
rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
;
3352 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 3352), 0));
;
3353 AFSCallStats.CreateFile++, AFSCallStats.TotalCalls++;
3354 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 3354), 0));
;
3355 if (!FileNameOK(Name)) {
3356 errorCode = EINVAL22;
3357 goto Bad_CreateFile;
3358 }
3359
3360 /*
3361 * Get associated volume/vnode for the parent dir; caller long are
3362 * also returned
3363 */
3364 if ((errorCode =
3365 GetVolumePackage(tcon, DirFid, &volptr, &parentptr, MustBeDIR2,
3366 &parentwhentargetnotdir, &client, WRITE_LOCK2,
3367 &rights, &anyrights))) {
3368 goto Bad_CreateFile;
3369 }
3370
3371 /* set volume synchronization information */
3372 SetVolumeSync(Sync, volptr);
3373
3374 /* Can we write (and insert) onto the parent directory? */
3375 if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT4))) {
3376 goto Bad_CreateFile;
3377 }
3378 /* get a new vnode for the file to be created and set it up */
3379 if ((errorCode =
3380 Alloc_NewVnode(parentptr, &dir, volptr, &targetptr, Name, OutFid,
3381 vFile1, nBlocks(0)((afs_sfsize_t)((0) == 0? 1: (((afs_sfsize_t)(0))+1023)/1024)
)
))) {
3382 goto Bad_CreateFile;
3383 }
3384
3385 /* update the status of the parent vnode */
3386#if FS_STATS_DETAILED1
3387 Update_ParentVnodeStatus(parentptr, volptr, &dir, client->ViceId,
3388 parentptr->disk.linkCount,
3389 client->InSameNetwork);
3390#else
3391 Update_ParentVnodeStatus(parentptr, volptr, &dir, client->ViceId,
3392 parentptr->disk.linkCount);
3393#endif /* FS_STATS_DETAILED */
3394
3395 /* update the status of the new file's vnode */
3396 Update_TargetVnodeStatus(targetptr, TVS_CFILE4, client, InStatus,
3397 parentptr, volptr, 0);
3398
3399 /* set up the return status for the parent dir and the newly created file, and since the newly created file is owned by the creator, give it PRSFS_ADMINISTER to tell the client its the owner of the file */
3400 GetStatus(targetptr, OutFidStatus, rights | PRSFS_ADMINISTER64, anyrights, parentptr);
3401 GetStatus(parentptr, OutDirStatus, rights, anyrights, 0);
3402
3403 /* convert the write lock to a read lock before breaking callbacks */
3404 VVnodeWriteToRead(&errorCode, parentptr);
3405 osi_Assert(!errorCode || errorCode == VSALVAGE)(void)((!errorCode || errorCode == 101) || (osi_AssertFailU("!errorCode || errorCode == VSALVAGE"
, "./../viced/afsfileprocs.c", 3405), 0))
;
3406
3407 /* break call back on parent dir */
3408 BreakCallBack(client->host, DirFid, 0);
3409
3410 /* Return a callback promise for the newly created file to the caller */
3411 SetCallBackStruct(AddCallBack(client->host, OutFid)AddCallBack1((client->host), (OutFid), (afs_uint32 *)0, 1 ,
0)
, CallBack);
3412
3413 Bad_CreateFile:
3414 /* Update and store volume/vnode and parent vnodes back */
3415 (void)PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr,
3416 volptr, &client);
3417 FidZap(&dir);
3418 ViceLog(2, ("SAFS_CreateFile returns %d\n", errorCode))do { if ((2) <= LogLevel) (FSLog ("SAFS_CreateFile returns %d\n"
, errorCode)); } while (0)
;
3419 return errorCode;
3420
3421} /*SAFSS_CreateFile */
3422
3423
3424afs_int32
3425SRXAFS_CreateFile(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
3426 struct AFSStoreStatus * InStatus, struct AFSFid * OutFid,
3427 struct AFSFetchStatus * OutFidStatus,
3428 struct AFSFetchStatus * OutDirStatus,
3429 struct AFSCallBack * CallBack, struct AFSVolSync * Sync)
3430{
3431 afs_int32 code;
3432 struct rx_connection *tcon;
3433 struct host *thost;
3434 struct client *t_client = NULL((void *)0); /* tmp ptr to client data */
3435 struct fsstats fsstats;
3436
3437 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_CREATEFILE7);
3438
3439 memset(OutFid, 0, sizeof(struct AFSFid));
3440
3441 if ((code = CallPreamble(acall, ACTIVECALL1, &tcon, &thost)))
3442 goto Bad_CreateFile;
3443
3444 code =
3445 SAFSS_CreateFile(acall, DirFid, Name, InStatus, OutFid, OutFidStatus,
3446 OutDirStatus, CallBack, Sync);
3447
3448 Bad_CreateFile:
3449 code = CallPostamble(tcon, code, thost);
3450
3451 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
3452
3453 fsstats_FinishOp(&fsstats, code);
3454
3455 osi_auditU(acall, CreateFileEvent"AFS_SRX_CrFile", code,
3456 AUD_ID10, t_client ? t_client->ViceId : 0,
3457 AUD_FID7, DirFid, AUD_STR1, Name, AUD_FID7, OutFid, AUD_END0);
3458 return code;
3459
3460} /*SRXAFS_CreateFile */
3461
3462
3463/*
3464 * This routine is called exclusively from SRXAFS_Rename(), and should be
3465 * merged in when possible.
3466 */
3467static afs_int32
3468SAFSS_Rename(struct rx_call *acall, struct AFSFid *OldDirFid, char *OldName,
3469 struct AFSFid *NewDirFid, char *NewName,
3470 struct AFSFetchStatus *OutOldDirStatus,
3471 struct AFSFetchStatus *OutNewDirStatus, struct AFSVolSync *Sync)
3472{
3473 Vnode *oldvptr = 0; /* vnode of the old Directory */
3474 Vnode *newvptr = 0; /* vnode of the new Directory */
3475 Vnode *fileptr = 0; /* vnode of the file to move */
3476 Vnode *newfileptr = 0; /* vnode of the file to delete */
3477 Vnode *testvptr = 0; /* used in directory tree walk */
3478 Vnode *parent = 0; /* parent for use in SetAccessList */
3479 Errorbit32 errorCode = 0; /* error code */
3480 Errorbit32 fileCode = 0; /* used when writing Vnodes */
3481 VnodeId testnode; /* used in directory tree walk */
3482 AFSFid fileFid; /* Fid of file to move */
3483 AFSFid newFileFid; /* Fid of new file */
3484 DirHandle olddir; /* Handle for dir package I/O */
3485 DirHandle newdir; /* Handle for dir package I/O */
3486 DirHandle filedir; /* Handle for dir package I/O */
3487 DirHandle newfiledir; /* Handle for dir package I/O */
3488 Volume *volptr = 0; /* pointer to the volume header */
3489 struct client *client = 0; /* pointer to client structure */
3490 afs_int32 rights, anyrights; /* rights for this and any user */
3491 afs_int32 newrights; /* rights for this user */
3492 afs_int32 newanyrights; /* rights for any user */
3493 int doDelete; /* deleted the rename target (ref count now 0) */
3494 int code;
3495 int updatefile = 0; /* are we changing the renamed file? (we do this
3496 * if we need to update .. on a renamed dir) */
3497 struct client *t_client; /* tmp ptr to client data */
3498 struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
3499 struct rx_connection *tcon = rx_ConnectionOf(acall)((acall)->conn);
3500 afs_ino_str_t stmp;
3501
3502 FidZero(&olddir);
3503 FidZero(&newdir);
3504 FidZero(&filedir);
3505 FidZero(&newfiledir);
3506
3507 /* Get ptr to client data for user Id for logging */
3508 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
3509 logHostAddr.s_addr = rxr_HostOf(tcon)(((((struct rx_connection *)(tcon))->peer))->host);
3510 ViceLog(1,do { if ((1) <= LogLevel) (FSLog ("SAFS_Rename %s to %s, Fid = %u.%u.%u to %u.%u.%u, Host %s:%d, Id %d\n"
, OldName, NewName, OldDirFid->Volume, OldDirFid->Vnode
, OldDirFid->Unique, NewDirFid->Volume, NewDirFid->Vnode
, NewDirFid->Unique, __inet_ntoa(logHostAddr), (__builtin_constant_p
(((((((struct rx_connection *)(tcon)))->peer))->port)) ?
(__uint16_t)(((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) << 8 | ((__uint16_t)(((((((struct
rx_connection *)(tcon)))->peer))->port))) >> 8) :
__bswap16_var(((((((struct rx_connection *)(tcon)))->peer
))->port))), t_client->ViceId)); } while (0)
3511 ("SAFS_Rename %s to %s, Fid = %u.%u.%u to %u.%u.%u, Host %s:%d, Id %d\n",do { if ((1) <= LogLevel) (FSLog ("SAFS_Rename %s to %s, Fid = %u.%u.%u to %u.%u.%u, Host %s:%d, Id %d\n"
, OldName, NewName, OldDirFid->Volume, OldDirFid->Vnode
, OldDirFid->Unique, NewDirFid->Volume, NewDirFid->Vnode
, NewDirFid->Unique, __inet_ntoa(logHostAddr), (__builtin_constant_p
(((((((struct rx_connection *)(tcon)))->peer))->port)) ?
(__uint16_t)(((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) << 8 | ((__uint16_t)(((((((struct
rx_connection *)(tcon)))->peer))->port))) >> 8) :
__bswap16_var(((((((struct rx_connection *)(tcon)))->peer
))->port))), t_client->ViceId)); } while (0)
3512 OldName, NewName, OldDirFid->Volume, OldDirFid->Vnode,do { if ((1) <= LogLevel) (FSLog ("SAFS_Rename %s to %s, Fid = %u.%u.%u to %u.%u.%u, Host %s:%d, Id %d\n"
, OldName, NewName, OldDirFid->Volume, OldDirFid->Vnode
, OldDirFid->Unique, NewDirFid->Volume, NewDirFid->Vnode
, NewDirFid->Unique, __inet_ntoa(logHostAddr), (__builtin_constant_p
(((((((struct rx_connection *)(tcon)))->peer))->port)) ?
(__uint16_t)(((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) << 8 | ((__uint16_t)(((((((struct
rx_connection *)(tcon)))->peer))->port))) >> 8) :
__bswap16_var(((((((struct rx_connection *)(tcon)))->peer
))->port))), t_client->ViceId)); } while (0)
3513 OldDirFid->Unique, NewDirFid->Volume, NewDirFid->Vnode,do { if ((1) <= LogLevel) (FSLog ("SAFS_Rename %s to %s, Fid = %u.%u.%u to %u.%u.%u, Host %s:%d, Id %d\n"
, OldName, NewName, OldDirFid->Volume, OldDirFid->Vnode
, OldDirFid->Unique, NewDirFid->Volume, NewDirFid->Vnode
, NewDirFid->Unique, __inet_ntoa(logHostAddr), (__builtin_constant_p
(((((((struct rx_connection *)(tcon)))->peer))->port)) ?
(__uint16_t)(((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) << 8 | ((__uint16_t)(((((((struct
rx_connection *)(tcon)))->peer))->port))) >> 8) :
__bswap16_var(((((((struct rx_connection *)(tcon)))->peer
))->port))), t_client->ViceId)); } while (0)
3514 NewDirFid->Unique, inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId))do { if ((1) <= LogLevel) (FSLog ("SAFS_Rename %s to %s, Fid = %u.%u.%u to %u.%u.%u, Host %s:%d, Id %d\n"
, OldName, NewName, OldDirFid->Volume, OldDirFid->Vnode
, OldDirFid->Unique, NewDirFid->Volume, NewDirFid->Vnode
, NewDirFid->Unique, __inet_ntoa(logHostAddr), (__builtin_constant_p
(((((((struct rx_connection *)(tcon)))->peer))->port)) ?
(__uint16_t)(((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) << 8 | ((__uint16_t)(((((((struct
rx_connection *)(tcon)))->peer))->port))) >> 8) :
__bswap16_var(((((((struct rx_connection *)(tcon)))->peer
))->port))), t_client->ViceId)); } while (0)
;
3515 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 3515), 0));
;
3516 AFSCallStats.Rename++, AFSCallStats.TotalCalls++;
3517 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 3517), 0));
;
3518 if (!FileNameOK(NewName)) {
3519 errorCode = EINVAL22;
3520 goto Bad_Rename;
3521 }
3522 if (OldDirFid->Volume != NewDirFid->Volume) {
3523 DFlush();
3524 errorCode = EXDEV18;
3525 goto Bad_Rename;
3526 }
3527 if ((strcmp(OldName, ".") == 0) || (strcmp(OldName, "..") == 0)
3528 || (strcmp(NewName, ".") == 0) || (strcmp(NewName, "..") == 0)
3529 || (strlen(NewName) == 0) || (strlen(OldName) == 0)) {
3530 DFlush();
3531 errorCode = EINVAL22;
3532 goto Bad_Rename;
3533 }
3534
3535 if (OldDirFid->Vnode <= NewDirFid->Vnode) {
3536 if ((errorCode =
3537 GetVolumePackage(tcon, OldDirFid, &volptr, &oldvptr, MustBeDIR2,
3538 &parent, &client, WRITE_LOCK2, &rights,
3539 &anyrights))) {
3540 DFlush();
3541 goto Bad_Rename;
3542 }
3543 if (OldDirFid->Vnode == NewDirFid->Vnode) {
3544 newvptr = oldvptr;
3545 newrights = rights, newanyrights = anyrights;
3546 } else
3547 if ((errorCode =
3548 GetVolumePackage(tcon, NewDirFid, &volptr, &newvptr,
3549 MustBeDIR2, &parent, &client, WRITE_LOCK2,
3550 &newrights, &newanyrights))) {
3551 DFlush();
3552 goto Bad_Rename;
3553 }
3554 } else {
3555 if ((errorCode =
3556 GetVolumePackage(tcon, NewDirFid, &volptr, &newvptr, MustBeDIR2,
3557 &parent, &client, WRITE_LOCK2, &newrights,
3558 &newanyrights))) {
3559 DFlush();
3560 goto Bad_Rename;
3561 }
3562 if ((errorCode =
3563 GetVolumePackage(tcon, OldDirFid, &volptr, &oldvptr, MustBeDIR2,
3564 &parent, &client, WRITE_LOCK2, &rights,
3565 &anyrights))) {
3566 DFlush();
3567 goto Bad_Rename;
3568 }
3569 }
3570
3571 /* set volume synchronization information */
3572 SetVolumeSync(Sync, volptr);
3573
3574 if ((errorCode = CheckWriteMode(oldvptr, rights, PRSFS_DELETE16))) {
3575 goto Bad_Rename;
3576 }
3577 if ((errorCode = CheckWriteMode(newvptr, newrights, PRSFS_INSERT4))) {
3578 goto Bad_Rename;
3579 }
3580
3581 if (CheckLength(volptr, oldvptr, -1) ||
3582 CheckLength(volptr, newvptr, -1)) {
3583 VTakeOffline(volptr);
3584 errorCode = VSALVAGE101;
3585 goto Bad_Rename;
3586 }
3587
3588 /* The CopyOnWrite might return ENOSPC ( disk full). Even if the second
3589 * call to CopyOnWrite returns error, it is not necessary to revert back
3590 * the effects of the first call because the contents of the volume is
3591 * not modified, it is only replicated.
3592 */
3593 if (oldvptr->disk.cloned) {
3594 ViceLog(25, ("Rename : calling CopyOnWrite on old dir\n"))do { if ((25) <= LogLevel) (FSLog ("Rename : calling CopyOnWrite on old dir\n"
)); } while (0)
;
3595 if ((errorCode = CopyOnWrite(oldvptr, volptr, 0, MAXFSIZE(~(afs_fsize_t) 0))))
3596 goto Bad_Rename;
3597 }
3598 SetDirHandle(&olddir, oldvptr);
3599 if (newvptr->disk.cloned) {
3600 ViceLog(25, ("Rename : calling CopyOnWrite on new dir\n"))do { if ((25) <= LogLevel) (FSLog ("Rename : calling CopyOnWrite on new dir\n"
)); } while (0)
;
3601 if ((errorCode = CopyOnWrite(newvptr, volptr, 0, MAXFSIZE(~(afs_fsize_t) 0))))
3602 goto Bad_Rename;
3603 }
3604
3605 SetDirHandle(&newdir, newvptr);
3606
3607 /* Lookup the file to delete its vnode */
3608 if (afs_dir_Lookup(&olddir, OldName, &fileFid)) {
3609 errorCode = ENOENT2;
3610 goto Bad_Rename;
3611 }
3612 if (fileFid.Vnode == oldvptr->vnodeNumber
3613 || fileFid.Vnode == newvptr->vnodeNumber) {
3614 errorCode = FSERR_ELOOP90;
3615 goto Bad_Rename;
3616 }
3617 fileFid.Volume = V_id(volptr)((volptr)->header->diskstuff.id);
3618 fileptr = VGetVnode(&errorCode, volptr, fileFid.Vnode, WRITE_LOCK2);
3619 if (errorCode != 0) {
3620 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("SAFSS_Rename(): Error in VGetVnode() for old file %s, code %d\n"
, OldName, errorCode)); } while (0)
3621 ("SAFSS_Rename(): Error in VGetVnode() for old file %s, code %d\n",do { if ((0) <= LogLevel) (FSLog ("SAFSS_Rename(): Error in VGetVnode() for old file %s, code %d\n"
, OldName, errorCode)); } while (0)
3622 OldName, errorCode))do { if ((0) <= LogLevel) (FSLog ("SAFSS_Rename(): Error in VGetVnode() for old file %s, code %d\n"
, OldName, errorCode)); } while (0)
;
3623 VTakeOffline(volptr);
3624 goto Bad_Rename;
3625 }
3626 if (fileptr->disk.uniquifier != fileFid.Unique) {
3627 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("SAFSS_Rename(): Old file %s uniquifier mismatch\n"
, OldName)); } while (0)
3628 ("SAFSS_Rename(): Old file %s uniquifier mismatch\n",do { if ((0) <= LogLevel) (FSLog ("SAFSS_Rename(): Old file %s uniquifier mismatch\n"
, OldName)); } while (0)
3629 OldName))do { if ((0) <= LogLevel) (FSLog ("SAFSS_Rename(): Old file %s uniquifier mismatch\n"
, OldName)); } while (0)
;
3630 VTakeOffline(volptr);
3631 errorCode = EIO5;
3632 goto Bad_Rename;
3633 }
3634
3635 if (fileptr->disk.type != vDirectory2 && oldvptr != newvptr
3636 && fileptr->disk.linkCount != 1) {
3637 /*
3638 * Hard links exist to this file - cannot move one of the links to
3639 * a new directory because of AFS restrictions (this is the same
3640 * reason that links cannot be made across directories, i.e.
3641 * access lists)
3642 */
3643 errorCode = EXDEV18;
3644 goto Bad_Rename;
3645 }
3646
3647 /* Lookup the new file */
3648 if (!(afs_dir_Lookup(&newdir, NewName, &newFileFid))) {
3649 if (readonlyServer) {
3650 errorCode = VREADONLY30;
3651 goto Bad_Rename;
3652 }
3653 if (!(newrights & PRSFS_DELETE16)) {
3654 errorCode = EACCES13;
3655 goto Bad_Rename;
3656 }
3657 if (newFileFid.Vnode == oldvptr->vnodeNumber
3658 || newFileFid.Vnode == newvptr->vnodeNumber
3659 || newFileFid.Vnode == fileFid.Vnode) {
3660 errorCode = EINVAL22;
3661 goto Bad_Rename;
3662 }
3663 newFileFid.Volume = V_id(volptr)((volptr)->header->diskstuff.id);
3664 newfileptr =
3665 VGetVnode(&errorCode, volptr, newFileFid.Vnode, WRITE_LOCK2);
3666 if (errorCode != 0) {
3667 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("SAFSS_Rename(): Error in VGetVnode() for new file %s, code %d\n"
, NewName, errorCode)); } while (0)
3668 ("SAFSS_Rename(): Error in VGetVnode() for new file %s, code %d\n",do { if ((0) <= LogLevel) (FSLog ("SAFSS_Rename(): Error in VGetVnode() for new file %s, code %d\n"
, NewName, errorCode)); } while (0)
3669 NewName, errorCode))do { if ((0) <= LogLevel) (FSLog ("SAFSS_Rename(): Error in VGetVnode() for new file %s, code %d\n"
, NewName, errorCode)); } while (0)
;
3670 VTakeOffline(volptr);
3671 goto Bad_Rename;
3672 }
3673 if (fileptr->disk.uniquifier != fileFid.Unique) {
3674 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("SAFSS_Rename(): New file %s uniquifier mismatch\n"
, NewName)); } while (0)
3675 ("SAFSS_Rename(): New file %s uniquifier mismatch\n",do { if ((0) <= LogLevel) (FSLog ("SAFSS_Rename(): New file %s uniquifier mismatch\n"
, NewName)); } while (0)
3676 NewName))do { if ((0) <= LogLevel) (FSLog ("SAFSS_Rename(): New file %s uniquifier mismatch\n"
, NewName)); } while (0)
;
3677 VTakeOffline(volptr);
3678 errorCode = EIO5;
3679 goto Bad_Rename;
3680 }
3681 SetDirHandle(&newfiledir, newfileptr);
3682 /* Now check that we're moving directories over directories properly, etc.
3683 * return proper POSIX error codes:
3684 * if fileptr is a file and new is a dir: EISDIR.
3685 * if fileptr is a dir and new is a file: ENOTDIR.
3686 * Also, dir to be removed must be empty, of course.
3687 */
3688 if (newfileptr->disk.type == vDirectory2) {
3689 if (fileptr->disk.type != vDirectory2) {
3690 errorCode = EISDIR21;
3691 goto Bad_Rename;
3692 }
3693 if ((afs_dir_IsEmpty(&newfiledir))) {
3694 errorCode = EEXIST17;
3695 goto Bad_Rename;
3696 }
3697 } else {
3698 if (fileptr->disk.type == vDirectory2) {
3699 errorCode = ENOTDIR20;
3700 goto Bad_Rename;
3701 }
3702 }
3703 }
3704
3705 /*
3706 * ok - now we check that the old name is not above new name in the
3707 * directory structure. This is to prevent removing a subtree alltogether
3708 */
3709 if ((oldvptr != newvptr) && (fileptr->disk.type == vDirectory2)) {
3710 afs_int32 forpass = 0, vnum = 0, top = 0;
3711 for (testnode = newvptr->disk.parent; testnode != 0; forpass++) {
3712 if (testnode > vnum) vnum = testnode;
3713 if (forpass > vnum) {
3714 errorCode = FSERR_ELOOP90;
3715 goto Bad_Rename;
3716 }
3717 if (testnode == oldvptr->vnodeNumber) {
3718 testnode = oldvptr->disk.parent;
3719 continue;
3720 }
3721 if ((testnode == fileptr->vnodeNumber)
3722 || (testnode == newvptr->vnodeNumber)) {
3723 errorCode = FSERR_ELOOP90;
3724 goto Bad_Rename;
3725 }
3726 if ((newfileptr) && (testnode == newfileptr->vnodeNumber)) {
3727 errorCode = FSERR_ELOOP90;
3728 goto Bad_Rename;
3729 }
3730 if (testnode == 1) top = 1;
3731 testvptr = VGetVnode(&errorCode, volptr, testnode, READ_LOCK1);
3732 osi_Assert(errorCode == 0)(void)((errorCode == 0) || (osi_AssertFailU("errorCode == 0",
"./../viced/afsfileprocs.c", 3732), 0))
;
3733 testnode = testvptr->disk.parent;
3734 VPutVnode(&errorCode, testvptr);
3735 if ((top == 1) && (testnode != 0)) {
3736 VTakeOffline(volptr);
3737 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
3738 ("Volume %u now offline, must be salvaged.\n",do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
3739 volptr->hashid))do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
;
3740 errorCode = EIO5;
3741 goto Bad_Rename;
3742 }
3743 osi_Assert(errorCode == 0)(void)((errorCode == 0) || (osi_AssertFailU("errorCode == 0",
"./../viced/afsfileprocs.c", 3743), 0))
;
3744 }
3745 }
3746
3747 if (fileptr->disk.type == vDirectory2) {
3748 SetDirHandle(&filedir, fileptr);
3749 if (oldvptr != newvptr) {
3750 /* we always need to update .. if we've moving fileptr to a
3751 * different directory */
3752 updatefile = 1;
3753 } else {
3754 struct AFSFid unused;
3755
3756 code = afs_dir_Lookup(&filedir, "..", &unused);
3757 if (code == ENOENT2) {
3758 /* only update .. if it doesn't already exist */
3759 updatefile = 1;
3760 }
3761 }
3762 }
3763
3764 /* Do the CopyonWrite first before modifying anything else. Copying is
3765 * required when we have to change entries for ..
3766 */
3767 if (updatefile && (fileptr->disk.cloned)) {
3768 ViceLog(25, ("Rename : calling CopyOnWrite on target dir\n"))do { if ((25) <= LogLevel) (FSLog ("Rename : calling CopyOnWrite on target dir\n"
)); } while (0)
;
3769 if ((errorCode = CopyOnWrite(fileptr, volptr, 0, MAXFSIZE(~(afs_fsize_t) 0))))
3770 goto Bad_Rename;
3771 }
3772
3773 /* If the new name exists already, delete it and the file it points to */
3774 doDelete = 0;
3775 if (newfileptr) {
3776 /* Delete NewName from its directory */
3777 code = afs_dir_Delete(&newdir, NewName);
3778 osi_Assert(code == 0)(void)((code == 0) || (osi_AssertFailU("code == 0", "./../viced/afsfileprocs.c"
, 3778), 0))
;
3779
3780 /* Drop the link count */
3781 newfileptr->disk.linkCount--;
3782 if (newfileptr->disk.linkCount == 0) { /* Link count 0 - delete */
3783 afs_fsize_t newSize;
3784 VN_GET_LEN(newSize, newfileptr)(newSize) = ((afs_int64)((newfileptr)->disk.vn_length_hi) <<
32) | ((newfileptr)->disk.length);
;
3785 VAdjustDiskUsage((Errorbit32 *) & errorCode, volptr,
3786 (afs_sfsize_t) - nBlocks(newSize)((afs_sfsize_t)((newSize) == 0? 1: (((afs_sfsize_t)(newSize))
+1023)/1024))
, 0);
3787 if (VN_GET_INO(newfileptr)((Inode)((newfileptr)->disk.vn_ino_lo | ((newfileptr)->
disk.vn_ino_hi ? (((Inode)(newfileptr)->disk.vn_ino_hi)<<
32) : 0)))
) {
3788 IH_REALLYCLOSE(newfileptr->handle)ih_reallyclose(newfileptr->handle);
3789 errorCode =
3790 IH_DEC(V_linkHandle(volptr), VN_GET_INO(newfileptr),namei_dec(((volptr)->linkHandle), ((Inode)((newfileptr)->
disk.vn_ino_lo | ((newfileptr)->disk.vn_ino_hi ? (((Inode)
(newfileptr)->disk.vn_ino_hi)<<32) : 0))), ((volptr)
->header->diskstuff.parentId))
3791 V_parentId(volptr))namei_dec(((volptr)->linkHandle), ((Inode)((newfileptr)->
disk.vn_ino_lo | ((newfileptr)->disk.vn_ino_hi ? (((Inode)
(newfileptr)->disk.vn_ino_hi)<<32) : 0))), ((volptr)
->header->diskstuff.parentId))
;
3792 IH_RELEASE(newfileptr->handle)(ih_release(newfileptr->handle), (newfileptr->handle)=(
(void *)0), 0)
;
3793 if (errorCode == -1) {
3794 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("Del: inode=%s, name=%s, errno=%d\n"
, PrintInode(stmp, ((Inode)((newfileptr)->disk.vn_ino_lo |
((newfileptr)->disk.vn_ino_hi ? (((Inode)(newfileptr)->
disk.vn_ino_hi)<<32) : 0)))), NewName, (* __error())));
} while (0)
3795 ("Del: inode=%s, name=%s, errno=%d\n",do { if ((0) <= LogLevel) (FSLog ("Del: inode=%s, name=%s, errno=%d\n"
, PrintInode(stmp, ((Inode)((newfileptr)->disk.vn_ino_lo |
((newfileptr)->disk.vn_ino_hi ? (((Inode)(newfileptr)->
disk.vn_ino_hi)<<32) : 0)))), NewName, (* __error())));
} while (0)
3796 PrintInode(stmp, VN_GET_INO(newfileptr)),do { if ((0) <= LogLevel) (FSLog ("Del: inode=%s, name=%s, errno=%d\n"
, PrintInode(stmp, ((Inode)((newfileptr)->disk.vn_ino_lo |
((newfileptr)->disk.vn_ino_hi ? (((Inode)(newfileptr)->
disk.vn_ino_hi)<<32) : 0)))), NewName, (* __error())));
} while (0)
3797 NewName, errno))do { if ((0) <= LogLevel) (FSLog ("Del: inode=%s, name=%s, errno=%d\n"
, PrintInode(stmp, ((Inode)((newfileptr)->disk.vn_ino_lo |
((newfileptr)->disk.vn_ino_hi ? (((Inode)(newfileptr)->
disk.vn_ino_hi)<<32) : 0)))), NewName, (* __error())));
} while (0)
;
3798 if ((errno(* __error()) != ENOENT2) && (errno(* __error()) != EIO5)
3799 && (errno(* __error()) != ENXIO6))
3800 ViceLog(0, ("Do we need to fsck?"))do { if ((0) <= LogLevel) (FSLog ("Do we need to fsck?"));
} while (0)
;
3801 }
3802 }
3803 VN_SET_INO(newfileptr, (Inode) 0)((newfileptr)->disk.vn_ino_lo = (int)(((Inode) 0)&0xffffffff
), ((newfileptr)->disk.vn_ino_hi = ((Inode) 0) ? (int)((((
Inode) 0)>>32)&0xffffffff) : 0))
;
3804 newfileptr->delete = 1; /* Mark NewName vnode to delete */
3805 doDelete = 1;
3806 } else {
3807 /* Link count did not drop to zero.
3808 * Mark NewName vnode as changed - updates stime.
3809 */
3810 newfileptr->changed_newTime = 1;
3811 }
3812 }
3813
3814 /*
3815 * If the create below fails, and the delete above worked, we have
3816 * removed the new name and not replaced it. This is not very likely,
3817 * but possible. We could try to put the old file back, but it is
3818 * highly unlikely that it would work since it would involve issuing
3819 * another create.
3820 */
3821 if ((errorCode = afs_dir_Create(&newdir, NewName, &fileFid)))
3822 goto Bad_Rename;
3823
3824 /* Delete the old name */
3825 osi_Assert(afs_dir_Delete(&olddir, OldName) == 0)(void)((afs_dir_Delete(&olddir, OldName) == 0) || (osi_AssertFailU
("afs_dir_Delete(&olddir, OldName) == 0", "./../viced/afsfileprocs.c"
, 3825), 0))
;
3826
3827 /* if the directory length changes, reflect it in the statistics */
3828#if FS_STATS_DETAILED1
3829 Update_ParentVnodeStatus(oldvptr, volptr, &olddir, client->ViceId,
3830 oldvptr->disk.linkCount, client->InSameNetwork);
3831 Update_ParentVnodeStatus(newvptr, volptr, &newdir, client->ViceId,
3832 newvptr->disk.linkCount, client->InSameNetwork);
3833#else
3834 Update_ParentVnodeStatus(oldvptr, volptr, &olddir, client->ViceId,
3835 oldvptr->disk.linkCount);
3836 Update_ParentVnodeStatus(newvptr, volptr, &newdir, client->ViceId,
3837 newvptr->disk.linkCount);
3838#endif /* FS_STATS_DETAILED */
3839
3840 if (oldvptr == newvptr)
3841 oldvptr->disk.dataVersion--; /* Since it was bumped by 2! */
3842
3843 if (fileptr->disk.parent != newvptr->vnodeNumber) {
3844 fileptr->disk.parent = newvptr->vnodeNumber;
3845 fileptr->changed_newTime = 1;
3846 }
3847
3848 /* if we are dealing with a rename of a directory, and we need to
3849 * update the .. entry of that directory */
3850 if (updatefile) {
3851 osi_Assert(!fileptr->disk.cloned)(void)((!fileptr->disk.cloned) || (osi_AssertFailU("!fileptr->disk.cloned"
, "./../viced/afsfileprocs.c", 3851), 0))
;
3852
3853 fileptr->changed_newTime = 1; /* status change of moved file */
3854
3855 /* fix .. to point to the correct place */
3856 afs_dir_Delete(&filedir, ".."); /* No assert--some directories may be bad */
3857 osi_Assert(afs_dir_Create(&filedir, "..", NewDirFid) == 0)(void)((afs_dir_Create(&filedir, "..", NewDirFid) == 0) ||
(osi_AssertFailU("afs_dir_Create(&filedir, \"..\", NewDirFid) == 0"
, "./../viced/afsfileprocs.c", 3857), 0))
;
3858 fileptr->disk.dataVersion++;
3859
3860 /* if the parent directories are different the link counts have to be */
3861 /* changed due to .. in the renamed directory */
3862 if (oldvptr != newvptr) {
3863 oldvptr->disk.linkCount--;
3864 newvptr->disk.linkCount++;
3865 }
3866 }
3867
3868 /* set up return status */
3869 GetStatus(oldvptr, OutOldDirStatus, rights, anyrights, 0);
3870 GetStatus(newvptr, OutNewDirStatus, newrights, newanyrights, 0);
3871 if (newfileptr && doDelete) {
3872 DeleteFileCallBacks(&newFileFid); /* no other references */
3873 }
3874
3875 DFlush();
3876
3877 /* convert the write locks to a read locks before breaking callbacks */
3878 VVnodeWriteToRead(&errorCode, newvptr);
3879 osi_Assert(!errorCode || errorCode == VSALVAGE)(void)((!errorCode || errorCode == 101) || (osi_AssertFailU("!errorCode || errorCode == VSALVAGE"
, "./../viced/afsfileprocs.c", 3879), 0))
;
3880 if (oldvptr != newvptr) {
3881 VVnodeWriteToRead(&errorCode, oldvptr);
3882 osi_Assert(!errorCode || errorCode == VSALVAGE)(void)((!errorCode || errorCode == 101) || (osi_AssertFailU("!errorCode || errorCode == VSALVAGE"
, "./../viced/afsfileprocs.c", 3882), 0))
;
3883 }
3884 if (newfileptr && !doDelete) {
3885 /* convert the write lock to a read lock before breaking callbacks */
3886 VVnodeWriteToRead(&errorCode, newfileptr);
3887 osi_Assert(!errorCode || errorCode == VSALVAGE)(void)((!errorCode || errorCode == 101) || (osi_AssertFailU("!errorCode || errorCode == VSALVAGE"
, "./../viced/afsfileprocs.c", 3887), 0))
;
3888 }
3889
3890 /* break call back on NewDirFid, OldDirFid, NewDirFid and newFileFid */
3891 BreakCallBack(client->host, NewDirFid, 0);
3892 if (oldvptr != newvptr) {
3893 BreakCallBack(client->host, OldDirFid, 0);
3894 }
3895 if (updatefile) {
3896 /* if a dir moved, .. changed */
3897 /* we do not give an AFSFetchStatus structure back to the
3898 * originating client, and the file's status has changed, so be
3899 * sure to send a callback break. In theory the client knows
3900 * enough to know that the callback could be broken implicitly,
3901 * but that may not be clear, and some client implementations
3902 * may not know to. */
3903 BreakCallBack(client->host, &fileFid, 1);
3904 }
3905 if (newfileptr) {
3906 /* Note: it is not necessary to break the callback */
3907 if (doDelete)
3908 DeleteFileCallBacks(&newFileFid); /* no other references */
3909 else
3910 /* other's still exist (with wrong link count) */
3911 BreakCallBack(client->host, &newFileFid, 1);
3912 }
3913
3914 Bad_Rename:
3915 if (newfileptr) {
3916 VPutVnode(&fileCode, newfileptr);
3917 osi_Assert(fileCode == 0)(void)((fileCode == 0) || (osi_AssertFailU("fileCode == 0", "./../viced/afsfileprocs.c"
, 3917), 0))
;
3918 }
3919 (void)PutVolumePackage(fileptr, (newvptr && newvptr != oldvptr ?
3920 newvptr : 0), oldvptr, volptr, &client);
3921 FidZap(&olddir);
3922 FidZap(&newdir);
3923 FidZap(&filedir);
3924 FidZap(&newfiledir);
3925 ViceLog(2, ("SAFS_Rename returns %d\n", errorCode))do { if ((2) <= LogLevel) (FSLog ("SAFS_Rename returns %d\n"
, errorCode)); } while (0)
;
3926 return errorCode;
3927
3928} /*SAFSS_Rename */
3929
3930
3931afs_int32
3932SRXAFS_Rename(struct rx_call * acall, struct AFSFid * OldDirFid,
3933 char *OldName, struct AFSFid * NewDirFid, char *NewName,
3934 struct AFSFetchStatus * OutOldDirStatus,
3935 struct AFSFetchStatus * OutNewDirStatus,
3936 struct AFSVolSync * Sync)
3937{
3938 afs_int32 code;
3939 struct rx_connection *tcon;
3940 struct host *thost;
3941 struct client *t_client = NULL((void *)0); /* tmp ptr to client data */
3942 struct fsstats fsstats;
3943
3944 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_RENAME8);
3945
3946 if ((code = CallPreamble(acall, ACTIVECALL1, &tcon, &thost)))
3947 goto Bad_Rename;
3948
3949 code =
3950 SAFSS_Rename(acall, OldDirFid, OldName, NewDirFid, NewName,
3951 OutOldDirStatus, OutNewDirStatus, Sync);
3952
3953 Bad_Rename:
3954 code = CallPostamble(tcon, code, thost);
3955
3956 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
3957
3958 fsstats_FinishOp(&fsstats, code);
3959
3960 osi_auditU(acall, RenameFileEvent"AFS_SRX_RNmFile", code,
3961 AUD_ID10, t_client ? t_client->ViceId : 0,
3962 AUD_FID7, OldDirFid, AUD_STR1, OldName,
3963 AUD_FID7, NewDirFid, AUD_STR1, NewName, AUD_END0);
3964 return code;
3965
3966} /*SRXAFS_Rename */
3967
3968
3969/*
3970 * This routine is called exclusively by SRXAFS_Symlink(), and should be
3971 * merged into it when possible.
3972 */
3973static afs_int32
3974SAFSS_Symlink(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
3975 char *LinkContents, struct AFSStoreStatus *InStatus,
3976 struct AFSFid *OutFid, struct AFSFetchStatus *OutFidStatus,
3977 struct AFSFetchStatus *OutDirStatus, struct AFSVolSync *Sync)
3978{
3979 Vnode *parentptr = 0; /* vnode of input Directory */
3980 Vnode *targetptr = 0; /* vnode of the new link */
3981 Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
3982 Errorbit32 errorCode = 0; /* error code */
3983 afs_sfsize_t len;
3984 int code = 0;
3985 DirHandle dir; /* Handle for dir package I/O */
3986 Volume *volptr = 0; /* pointer to the volume header */
3987 struct client *client = 0; /* pointer to client structure */
3988 afs_int32 rights, anyrights; /* rights for this and any user */
3989 struct client *t_client; /* tmp ptr to client data */
3990 struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
3991 FdHandle_t *fdP;
3992 struct rx_connection *tcon = rx_ConnectionOf(acall)((acall)->conn);
3993
3994 FidZero(&dir);
3995
3996 /* Get ptr to client data for user Id for logging */
3997 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
3998 logHostAddr.s_addr = rxr_HostOf(tcon)(((((struct rx_connection *)(tcon))->peer))->host);
3999 ViceLog(1,do { if ((1) <= LogLevel) (FSLog ("SAFS_Symlink %s to %s, Did = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, LinkContents, DirFid->Volume, DirFid->Vnode, DirFid
->Unique, __inet_ntoa(logHostAddr), (__builtin_constant_p(
((((((struct rx_connection *)(tcon)))->peer))->port)) ?
(__uint16_t)(((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) << 8 | ((__uint16_t)(((((((struct
rx_connection *)(tcon)))->peer))->port))) >> 8) :
__bswap16_var(((((((struct rx_connection *)(tcon)))->peer
))->port))), t_client->ViceId)); } while (0)
4000 ("SAFS_Symlink %s to %s, Did = %u.%u.%u, Host %s:%d, Id %d\n", Name,do { if ((1) <= LogLevel) (FSLog ("SAFS_Symlink %s to %s, Did = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, LinkContents, DirFid->Volume, DirFid->Vnode, DirFid
->Unique, __inet_ntoa(logHostAddr), (__builtin_constant_p(
((((((struct rx_connection *)(tcon)))->peer))->port)) ?
(__uint16_t)(((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) << 8 | ((__uint16_t)(((((((struct
rx_connection *)(tcon)))->peer))->port))) >> 8) :
__bswap16_var(((((((struct rx_connection *)(tcon)))->peer
))->port))), t_client->ViceId)); } while (0)
4001 LinkContents, DirFid->Volume, DirFid->Vnode, DirFid->Unique,do { if ((1) <= LogLevel) (FSLog ("SAFS_Symlink %s to %s, Did = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, LinkContents, DirFid->Volume, DirFid->Vnode, DirFid
->Unique, __inet_ntoa(logHostAddr), (__builtin_constant_p(
((((((struct rx_connection *)(tcon)))->peer))->port)) ?
(__uint16_t)(((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) << 8 | ((__uint16_t)(((((((struct
rx_connection *)(tcon)))->peer))->port))) >> 8) :
__bswap16_var(((((((struct rx_connection *)(tcon)))->peer
))->port))), t_client->ViceId)); } while (0)
4002 inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId))do { if ((1) <= LogLevel) (FSLog ("SAFS_Symlink %s to %s, Did = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, LinkContents, DirFid->Volume, DirFid->Vnode, DirFid
->Unique, __inet_ntoa(logHostAddr), (__builtin_constant_p(
((((((struct rx_connection *)(tcon)))->peer))->port)) ?
(__uint16_t)(((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) << 8 | ((__uint16_t)(((((((struct
rx_connection *)(tcon)))->peer))->port))) >> 8) :
__bswap16_var(((((((struct rx_connection *)(tcon)))->peer
))->port))), t_client->ViceId)); } while (0)
;
4003 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 4003), 0));
;
4004 AFSCallStats.Symlink++, AFSCallStats.TotalCalls++;
4005 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 4005), 0));
;
4006 if (!FileNameOK(Name)) {
4007 errorCode = EINVAL22;
4008 goto Bad_SymLink;
4009 }
4010
4011 /*
4012 * Get the vnode and volume for the parent dir along with the caller's
4013 * rights to it
4014 */
4015 if ((errorCode =
4016 GetVolumePackage(tcon, DirFid, &volptr, &parentptr, MustBeDIR2,
4017 &parentwhentargetnotdir, &client, WRITE_LOCK2,
4018 &rights, &anyrights))) {
4019 goto Bad_SymLink;
4020 }
4021
4022 /* set volume synchronization information */
4023 SetVolumeSync(Sync, volptr);
4024
4025 /* Does the caller has insert (and write) access to the parent directory? */
4026 if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT4))) {
4027 goto Bad_SymLink;
4028 }
4029
4030 /*
4031 * If we're creating a mount point (any x bits clear), we must have
4032 * administer access to the directory, too. Always allow sysadmins
4033 * to do this.
4034 */
4035 if ((InStatus->Mask & AFS_SETMODE8) && !(InStatus->UnixModeBits & 0111)) {
4036 if (readonlyServer) {
4037 errorCode = VREADONLY30;
4038 goto Bad_SymLink;
4039 }
4040 /*
4041 * We have a mountpoint, 'cause we're trying to set the Unix mode
4042 * bits to something with some x bits missing (default mode bits
4043 * if AFS_SETMODE is false is 0777)
4044 */
4045 if (VanillaUser(client) && !(rights & PRSFS_ADMINISTER64)) {
4046 errorCode = EACCES13;
4047 goto Bad_SymLink;
4048 }
4049 }
4050
4051 /* get a new vnode for the symlink and set it up */
4052 if ((errorCode =
4053 Alloc_NewVnode(parentptr, &dir, volptr, &targetptr, Name, OutFid,
4054 vSymlink3, nBlocks(strlen((char *)LinkContents))((afs_sfsize_t)((strlen((char *)LinkContents)) == 0? 1: (((afs_sfsize_t
)(strlen((char *)LinkContents)))+1023)/1024))
))) {
4055 goto Bad_SymLink;
4056 }
4057
4058 /* update the status of the parent vnode */
4059#if FS_STATS_DETAILED1
4060 Update_ParentVnodeStatus(parentptr, volptr, &dir, client->ViceId,
4061 parentptr->disk.linkCount,
4062 client->InSameNetwork);
4063#else
4064 Update_ParentVnodeStatus(parentptr, volptr, &dir, client->ViceId,
4065 parentptr->disk.linkCount);
4066#endif /* FS_STATS_DETAILED */
4067
4068 /* update the status of the new symbolic link file vnode */
4069 Update_TargetVnodeStatus(targetptr, TVS_SLINK8, client, InStatus,
4070 parentptr, volptr, strlen((char *)LinkContents));
4071
4072 /* Write the contents of the symbolic link name into the target inode */
4073 fdP = IH_OPEN(targetptr->handle)ih_open(targetptr->handle);
4074 if (fdP == NULL((void *)0)) {
4075 (void)PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr,
4076 volptr, &client);
4077 VTakeOffline(volptr);
4078 ViceLog(0, ("Volume %u now offline, must be salvaged.\n",do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
4079 volptr->hashid))do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
;
4080 return EIO5;
4081 }
4082 len = strlen((char *) LinkContents);
4083 code = (len == FDH_PWRITE(fdP, (char *) LinkContents, len, 0)pwrite((fdP)->fd_fd, (char *) LinkContents, len, 0)) ? 0 : VDISKFULL108;
4084 if (code)
4085 ViceLog(0, ("SAFSS_Symlink FDH_PWRITE failed for len=%d, Fid=%u.%d.%d\n", (int)len, OutFid->Volume, OutFid->Vnode, OutFid->Unique))do { if ((0) <= LogLevel) (FSLog ("SAFSS_Symlink FDH_PWRITE failed for len=%d, Fid=%u.%d.%d\n"
, (int)len, OutFid->Volume, OutFid->Vnode, OutFid->Unique
)); } while (0)
;
4086 FDH_CLOSE(fdP)(fd_close(fdP), (fdP)=((void *)0), 0);
4087 /*
4088 * Set up and return modified status for the parent dir and new symlink
4089 * to caller.
4090 */
4091 GetStatus(targetptr, OutFidStatus, rights, anyrights, parentptr);
4092 GetStatus(parentptr, OutDirStatus, rights, anyrights, 0);
4093
4094 /* convert the write lock to a read lock before breaking callbacks */
4095 VVnodeWriteToRead(&errorCode, parentptr);
4096 osi_Assert(!errorCode || errorCode == VSALVAGE)(void)((!errorCode || errorCode == 101) || (osi_AssertFailU("!errorCode || errorCode == VSALVAGE"
, "./../viced/afsfileprocs.c", 4096), 0))
;
4097
4098 /* break call back on the parent dir */
4099 BreakCallBack(client->host, DirFid, 0);
4100
4101 Bad_SymLink:
4102 /* Write the all modified vnodes (parent, new files) and volume back */
4103 (void)PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr,
4104 volptr, &client);
4105 FidZap(&dir);
4106 ViceLog(2, ("SAFS_Symlink returns %d\n", errorCode))do { if ((2) <= LogLevel) (FSLog ("SAFS_Symlink returns %d\n"
, errorCode)); } while (0)
;
4107 return ( errorCode ? errorCode : code );
4108
4109} /*SAFSS_Symlink */
4110
4111
4112afs_int32
4113SRXAFS_Symlink(struct rx_call *acall, /* Rx call */
4114 struct AFSFid *DirFid, /* Parent dir's fid */
4115 char *Name, /* File name to create */
4116 char *LinkContents, /* Contents of the new created file */
4117 struct AFSStoreStatus *InStatus, /* Input status for the new symbolic link */
4118 struct AFSFid *OutFid, /* Fid for newly created symbolic link */
4119 struct AFSFetchStatus *OutFidStatus, /* Output status for new symbolic link */
4120 struct AFSFetchStatus *OutDirStatus, /* Output status for parent dir */
4121 struct AFSVolSync *Sync)
4122{
4123 afs_int32 code;
4124 struct rx_connection *tcon;
4125 struct host *thost;
4126 struct client *t_client = NULL((void *)0); /* tmp ptr to client data */
4127 struct fsstats fsstats;
4128
4129 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_SYMLINK9);
4130
4131 if ((code = CallPreamble(acall, ACTIVECALL1, &tcon, &thost)))
4132 goto Bad_Symlink;
4133
4134 code =
4135 SAFSS_Symlink(acall, DirFid, Name, LinkContents, InStatus, OutFid,
4136 OutFidStatus, OutDirStatus, Sync);
4137
4138 Bad_Symlink:
4139 code = CallPostamble(tcon, code, thost);
4140
4141 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
4142
4143 fsstats_FinishOp(&fsstats, code);
4144
4145 osi_auditU(acall, SymlinkEvent"AFS_SRX_SymLink", code,
4146 AUD_ID10, t_client ? t_client->ViceId : 0,
4147 AUD_FID7, DirFid, AUD_STR1, Name,
4148 AUD_FID7, OutFid, AUD_STR1, LinkContents, AUD_END0);
4149 return code;
4150
4151} /*SRXAFS_Symlink */
4152
4153
4154/*
4155 * This routine is called exclusively by SRXAFS_Link(), and should be
4156 * merged into it when possible.
4157 */
4158static afs_int32
4159SAFSS_Link(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
4160 struct AFSFid *ExistingFid, struct AFSFetchStatus *OutFidStatus,
4161 struct AFSFetchStatus *OutDirStatus, struct AFSVolSync *Sync)
4162{
4163 Vnode *parentptr = 0; /* vnode of input Directory */
4164 Vnode *targetptr = 0; /* vnode of the new file */
4165 Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
4166 Volume *volptr = 0; /* pointer to the volume header */
4167 Errorbit32 errorCode = 0; /* error code */
4168 DirHandle dir; /* Handle for dir package I/O */
4169 struct client *client = 0; /* pointer to client structure */
4170 afs_int32 rights, anyrights; /* rights for this and any user */
4171 struct client *t_client; /* tmp ptr to client data */
4172 struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
4173 struct rx_connection *tcon = rx_ConnectionOf(acall)((acall)->conn);
4174
4175 FidZero(&dir);
4176
4177 /* Get ptr to client data for user Id for logging */
4178 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
4179 logHostAddr.s_addr = rxr_HostOf(tcon)(((((struct rx_connection *)(tcon))->peer))->host);
4180 ViceLog(1,do { if ((1) <= LogLevel) (FSLog ("SAFS_Link %s, Did = %u.%u.%u, Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, DirFid->Volume, DirFid->Vnode, DirFid->Unique
, ExistingFid->Volume, ExistingFid->Vnode, ExistingFid->
Unique, __inet_ntoa(logHostAddr), (__builtin_constant_p((((((
(struct rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
4181 ("SAFS_Link %s, Did = %u.%u.%u, Fid = %u.%u.%u, Host %s:%d, Id %d\n",do { if ((1) <= LogLevel) (FSLog ("SAFS_Link %s, Did = %u.%u.%u, Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, DirFid->Volume, DirFid->Vnode, DirFid->Unique
, ExistingFid->Volume, ExistingFid->Vnode, ExistingFid->
Unique, __inet_ntoa(logHostAddr), (__builtin_constant_p((((((
(struct rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
4182 Name, DirFid->Volume, DirFid->Vnode, DirFid->Unique,do { if ((1) <= LogLevel) (FSLog ("SAFS_Link %s, Did = %u.%u.%u, Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, DirFid->Volume, DirFid->Vnode, DirFid->Unique
, ExistingFid->Volume, ExistingFid->Vnode, ExistingFid->
Unique, __inet_ntoa(logHostAddr), (__builtin_constant_p((((((
(struct rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
4183 ExistingFid->Volume, ExistingFid->Vnode, ExistingFid->Unique,do { if ((1) <= LogLevel) (FSLog ("SAFS_Link %s, Did = %u.%u.%u, Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, DirFid->Volume, DirFid->Vnode, DirFid->Unique
, ExistingFid->Volume, ExistingFid->Vnode, ExistingFid->
Unique, __inet_ntoa(logHostAddr), (__builtin_constant_p((((((
(struct rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
4184 inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId))do { if ((1) <= LogLevel) (FSLog ("SAFS_Link %s, Did = %u.%u.%u, Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, DirFid->Volume, DirFid->Vnode, DirFid->Unique
, ExistingFid->Volume, ExistingFid->Vnode, ExistingFid->
Unique, __inet_ntoa(logHostAddr), (__builtin_constant_p((((((
(struct rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
;
4185 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 4185), 0));
;
4186 AFSCallStats.Link++, AFSCallStats.TotalCalls++;
4187 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 4187), 0));
;
4188 if (DirFid->Volume != ExistingFid->Volume) {
4189 errorCode = EXDEV18;
4190 goto Bad_Link;
4191 }
4192 if (!FileNameOK(Name)) {
4193 errorCode = EINVAL22;
4194 goto Bad_Link;
4195 }
4196
4197 /*
4198 * Get the vnode and volume for the parent dir along with the caller's
4199 * rights to it
4200 */
4201 if ((errorCode =
4202 GetVolumePackage(tcon, DirFid, &volptr, &parentptr, MustBeDIR2,
4203 &parentwhentargetnotdir, &client, WRITE_LOCK2,
4204 &rights, &anyrights))) {
4205 goto Bad_Link;
4206 }
4207
4208 /* set volume synchronization information */
4209 SetVolumeSync(Sync, volptr);
4210
4211 /* Can the caller insert into the parent directory? */
4212 if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT4))) {
4213 goto Bad_Link;
4214 }
4215
4216 if (((DirFid->Vnode & 1) && (ExistingFid->Vnode & 1)) || (DirFid->Vnode == ExistingFid->Vnode)) { /* at present, */
4217 /* AFS fileservers always have directory vnodes that are odd. */
4218 errorCode = EISDIR21;
4219 goto Bad_Link;
4220 }
4221
4222 if (CheckLength(volptr, parentptr, -1)) {
4223 VTakeOffline(volptr);
4224 errorCode = VSALVAGE101;
4225 goto Bad_Link;
4226 }
4227
4228 /* get the file vnode */
4229 if ((errorCode =
4230 CheckVnode(ExistingFid, &volptr, &targetptr, WRITE_LOCK2))) {
4231 goto Bad_Link;
4232 }
4233 if (targetptr->disk.type != vFile1) {
4234 errorCode = EISDIR21;
4235 goto Bad_Link;
4236 }
4237 if (targetptr->disk.parent != DirFid->Vnode) {
4238 errorCode = EXDEV18;
4239 goto Bad_Link;
4240 }
4241 if (parentptr->disk.cloned) {
4242 ViceLog(25, ("Link : calling CopyOnWrite on target dir\n"))do { if ((25) <= LogLevel) (FSLog ("Link : calling CopyOnWrite on target dir\n"
)); } while (0)
;
4243 if ((errorCode = CopyOnWrite(parentptr, volptr, 0, MAXFSIZE(~(afs_fsize_t) 0))))
4244 goto Bad_Link; /* disk full error */
4245 }
4246
4247 /* add the name to the directory */
4248 SetDirHandle(&dir, parentptr);
4249 if ((errorCode = afs_dir_Create(&dir, Name, ExistingFid)))
4250 goto Bad_Link;
4251 DFlush();
4252
4253 /* update the status in the parent vnode */
4254 /**WARNING** --> disk.author SHOULDN'T be modified???? */
4255#if FS_STATS_DETAILED1
4256 Update_ParentVnodeStatus(parentptr, volptr, &dir, client->ViceId,
4257 parentptr->disk.linkCount,
4258 client->InSameNetwork);
4259#else
4260 Update_ParentVnodeStatus(parentptr, volptr, &dir, client->ViceId,
4261 parentptr->disk.linkCount);
4262#endif /* FS_STATS_DETAILED */
4263
4264 targetptr->disk.linkCount++;
4265 targetptr->disk.author = client->ViceId;
4266 targetptr->changed_newTime = 1; /* Status change of linked-to file */
4267
4268 /* set up return status */
4269 GetStatus(targetptr, OutFidStatus, rights, anyrights, parentptr);
4270 GetStatus(parentptr, OutDirStatus, rights, anyrights, 0);
4271
4272 /* convert the write locks to read locks before breaking callbacks */
4273 VVnodeWriteToRead(&errorCode, targetptr);
4274 osi_Assert(!errorCode || errorCode == VSALVAGE)(void)((!errorCode || errorCode == 101) || (osi_AssertFailU("!errorCode || errorCode == VSALVAGE"
, "./../viced/afsfileprocs.c", 4274), 0))
;
4275 VVnodeWriteToRead(&errorCode, parentptr);
4276 osi_Assert(!errorCode || errorCode == VSALVAGE)(void)((!errorCode || errorCode == 101) || (osi_AssertFailU("!errorCode || errorCode == VSALVAGE"
, "./../viced/afsfileprocs.c", 4276), 0))
;
4277
4278 /* break call back on DirFid */
4279 BreakCallBack(client->host, DirFid, 0);
4280 /*
4281 * We also need to break the callback for the file that is hard-linked since part
4282 * of its status (like linkcount) is changed
4283 */
4284 BreakCallBack(client->host, ExistingFid, 0);
4285
4286 Bad_Link:
4287 /* Write the all modified vnodes (parent, new files) and volume back */
4288 (void)PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr,
4289 volptr, &client);
4290 FidZap(&dir);
4291 ViceLog(2, ("SAFS_Link returns %d\n", errorCode))do { if ((2) <= LogLevel) (FSLog ("SAFS_Link returns %d\n"
, errorCode)); } while (0)
;
4292 return errorCode;
4293
4294} /*SAFSS_Link */
4295
4296
4297afs_int32
4298SRXAFS_Link(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
4299 struct AFSFid * ExistingFid, struct AFSFetchStatus * OutFidStatus,
4300 struct AFSFetchStatus * OutDirStatus, struct AFSVolSync * Sync)
4301{
4302 afs_int32 code;
4303 struct rx_connection *tcon;
4304 struct host *thost;
4305 struct client *t_client = NULL((void *)0); /* tmp ptr to client data */
4306 struct fsstats fsstats;
4307
4308 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_LINK10);
4309
4310 if ((code = CallPreamble(acall, ACTIVECALL1, &tcon, &thost)))
4311 goto Bad_Link;
4312
4313 code =
4314 SAFSS_Link(acall, DirFid, Name, ExistingFid, OutFidStatus,
4315 OutDirStatus, Sync);
4316
4317 Bad_Link:
4318 code = CallPostamble(tcon, code, thost);
4319
4320 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
4321
4322 fsstats_FinishOp(&fsstats, code);
4323
4324 osi_auditU(acall, LinkEvent"AFS_SRX_Link", code,
4325 AUD_ID10, t_client ? t_client->ViceId : 0,
4326 AUD_FID7, DirFid, AUD_STR1, Name,
4327 AUD_FID7, ExistingFid, AUD_END0);
4328 return code;
4329
4330} /*SRXAFS_Link */
4331
4332
4333/*
4334 * This routine is called exclusively by SRXAFS_MakeDir(), and should be
4335 * merged into it when possible.
4336 */
4337static afs_int32
4338SAFSS_MakeDir(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
4339 struct AFSStoreStatus *InStatus, struct AFSFid *OutFid,
4340 struct AFSFetchStatus *OutFidStatus,
4341 struct AFSFetchStatus *OutDirStatus,
4342 struct AFSCallBack *CallBack, struct AFSVolSync *Sync)
4343{
4344 Vnode *parentptr = 0; /* vnode of input Directory */
4345 Vnode *targetptr = 0; /* vnode of the new file */
4346 Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
4347 Volume *volptr = 0; /* pointer to the volume header */
4348 Errorbit32 errorCode = 0; /* error code */
4349 struct acl_accessList *newACL; /* Access list */
4350 int newACLSize; /* Size of access list */
4351 DirHandle dir; /* Handle for dir package I/O */
4352 DirHandle parentdir; /* Handle for dir package I/O */
4353 struct client *client = 0; /* pointer to client structure */
4354 afs_int32 rights, anyrights; /* rights for this and any user */
4355 struct client *t_client; /* tmp ptr to client data */
4356 struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
4357 struct rx_connection *tcon = rx_ConnectionOf(acall)((acall)->conn);
4358
4359 FidZero(&dir);
4360 FidZero(&parentdir);
4361
4362 /* Get ptr to client data for user Id for logging */
4363 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
4364 logHostAddr.s_addr = rxr_HostOf(tcon)(((((struct rx_connection *)(tcon))->peer))->host);
4365 ViceLog(1,do { if ((1) <= LogLevel) (FSLog ("SAFS_MakeDir %s, Did = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, DirFid->Volume, DirFid->Vnode, DirFid->Unique
, __inet_ntoa(logHostAddr), (__builtin_constant_p(((((((struct
rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
4366 ("SAFS_MakeDir %s, Did = %u.%u.%u, Host %s:%d, Id %d\n", Name,do { if ((1) <= LogLevel) (FSLog ("SAFS_MakeDir %s, Did = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, DirFid->Volume, DirFid->Vnode, DirFid->Unique
, __inet_ntoa(logHostAddr), (__builtin_constant_p(((((((struct
rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
4367 DirFid->Volume, DirFid->Vnode, DirFid->Unique,do { if ((1) <= LogLevel) (FSLog ("SAFS_MakeDir %s, Did = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, DirFid->Volume, DirFid->Vnode, DirFid->Unique
, __inet_ntoa(logHostAddr), (__builtin_constant_p(((((((struct
rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
4368 inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId))do { if ((1) <= LogLevel) (FSLog ("SAFS_MakeDir %s, Did = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, DirFid->Volume, DirFid->Vnode, DirFid->Unique
, __inet_ntoa(logHostAddr), (__builtin_constant_p(((((((struct
rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
;
4369 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 4369), 0));
;
4370 AFSCallStats.MakeDir++, AFSCallStats.TotalCalls++;
4371 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 4371), 0));
;
4372 if (!FileNameOK(Name)) {
4373 errorCode = EINVAL22;
4374 goto Bad_MakeDir;
4375 }
4376
4377 /*
4378 * Get the vnode and volume for the parent dir along with the caller's
4379 * rights to it.
4380 */
4381 if ((errorCode =
4382 GetVolumePackage(tcon, DirFid, &volptr, &parentptr, MustBeDIR2,
4383 &parentwhentargetnotdir, &client, WRITE_LOCK2,
4384 &rights, &anyrights))) {
4385 goto Bad_MakeDir;
4386 }
4387
4388 /* set volume synchronization information */
4389 SetVolumeSync(Sync, volptr);
4390
4391 /* Write access to the parent directory? */
4392#ifdef DIRCREATE_NEED_WRITE
4393 /*
4394 * requires w access for the user to create a directory. this
4395 * closes a loophole in the current security arrangement, since a
4396 * user with i access only can create a directory and get the
4397 * implcit a access that goes with dir ownership, and proceed to
4398 * subvert quota in the volume.
4399 */
4400 if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT4))
4401 || (errorCode = CheckWriteMode(parentptr, rights, PRSFS_WRITE2))) {
4402#else
4403 if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT4))) {
4404#endif /* DIRCREATE_NEED_WRITE */
4405 goto Bad_MakeDir;
4406 }
4407#define EMPTYDIRBLOCKS2 2
4408 /* get a new vnode and set it up */
4409 if ((errorCode =
4410 Alloc_NewVnode(parentptr, &parentdir, volptr, &targetptr, Name,
4411 OutFid, vDirectory2, EMPTYDIRBLOCKS2))) {
4412 goto Bad_MakeDir;
4413 }
4414
4415 /* Update the status for the parent dir */
4416#if FS_STATS_DETAILED1
4417 Update_ParentVnodeStatus(parentptr, volptr, &parentdir, client->ViceId,
4418 parentptr->disk.linkCount + 1,
4419 client->InSameNetwork);
4420#else
4421 Update_ParentVnodeStatus(parentptr, volptr, &parentdir, client->ViceId,
4422 parentptr->disk.linkCount + 1);
4423#endif /* FS_STATS_DETAILED */
4424
4425 /* Point to target's ACL buffer and copy the parent's ACL contents to it */
4426 osi_Assert((SetAccessList(void)(((SetAccessList (&targetptr, &volptr, &newACL
, &newACLSize, &parentwhentargetnotdir, (AFSFid *) 0,
0)) == 0) || (osi_AssertFailU("(SetAccessList (&targetptr, &volptr, &newACL, &newACLSize, &parentwhentargetnotdir, (AFSFid *) 0, 0)) == 0"
, "./../viced/afsfileprocs.c", 4428), 0))
4427 (&targetptr, &volptr, &newACL, &newACLSize,(void)(((SetAccessList (&targetptr, &volptr, &newACL
, &newACLSize, &parentwhentargetnotdir, (AFSFid *) 0,
0)) == 0) || (osi_AssertFailU("(SetAccessList (&targetptr, &volptr, &newACL, &newACLSize, &parentwhentargetnotdir, (AFSFid *) 0, 0)) == 0"
, "./../viced/afsfileprocs.c", 4428), 0))
4428 &parentwhentargetnotdir, (AFSFid *) 0, 0)) == 0)(void)(((SetAccessList (&targetptr, &volptr, &newACL
, &newACLSize, &parentwhentargetnotdir, (AFSFid *) 0,
0)) == 0) || (osi_AssertFailU("(SetAccessList (&targetptr, &volptr, &newACL, &newACLSize, &parentwhentargetnotdir, (AFSFid *) 0, 0)) == 0"
, "./../viced/afsfileprocs.c", 4428), 0))
;
4429 osi_Assert(parentwhentargetnotdir == 0)(void)((parentwhentargetnotdir == 0) || (osi_AssertFailU("parentwhentargetnotdir == 0"
, "./../viced/afsfileprocs.c", 4429), 0))
;
4430 memcpy((char *)newACL, (char *)VVnodeACL(parentptr)(((AL_AccessList *) (((byte *)(&(parentptr)->disk))+64
)))
, VAclSize(parentptr)(256 - 64));
4431
4432 /* update the status for the target vnode */
4433 Update_TargetVnodeStatus(targetptr, TVS_MKDIR0x10, client, InStatus,
4434 parentptr, volptr, 0);
4435
4436 /* Actually create the New directory in the directory package */
4437 SetDirHandle(&dir, targetptr);
4438 osi_Assert(!(afs_dir_MakeDir(&dir, (afs_int32 *)OutFid, (afs_int32 *)DirFid)))(void)((!(afs_dir_MakeDir(&dir, (afs_int32 *)OutFid, (afs_int32
*)DirFid))) || (osi_AssertFailU("!(afs_dir_MakeDir(&dir, (afs_int32 *)OutFid, (afs_int32 *)DirFid))"
, "./../viced/afsfileprocs.c", 4438), 0))
;
4439 DFlush();
4440 VN_SET_LEN(targetptr, (afs_fsize_t) afs_dir_Length(&dir))((targetptr)->disk.vn_length_hi) = ((afs_int64)(afs_fsize_t
) afs_dir_Length(&dir)) >> 32; ((targetptr)->disk
.length) = ((afs_fsize_t) afs_dir_Length(&dir)) & 0xFFFFFFFF
;
;
4441
4442 /* set up return status */
4443 GetStatus(targetptr, OutFidStatus, rights, anyrights, parentptr);
4444 GetStatus(parentptr, OutDirStatus, rights, anyrights, NULL((void *)0));
4445
4446 /* convert the write lock to a read lock before breaking callbacks */
4447 VVnodeWriteToRead(&errorCode, parentptr);
4448 osi_Assert(!errorCode || errorCode == VSALVAGE)(void)((!errorCode || errorCode == 101) || (osi_AssertFailU("!errorCode || errorCode == VSALVAGE"
, "./../viced/afsfileprocs.c", 4448), 0))
;
4449
4450 /* break call back on DirFid */
4451 BreakCallBack(client->host, DirFid, 0);
4452
4453 /* Return a callback promise to caller */
4454 SetCallBackStruct(AddCallBack(client->host, OutFid)AddCallBack1((client->host), (OutFid), (afs_uint32 *)0, 1 ,
0)
, CallBack);
4455
4456 Bad_MakeDir:
4457 /* Write the all modified vnodes (parent, new files) and volume back */
4458 (void)PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr,
4459 volptr, &client);
4460 FidZap(&dir);
4461 FidZap(&parentdir);
4462 ViceLog(2, ("SAFS_MakeDir returns %d\n", errorCode))do { if ((2) <= LogLevel) (FSLog ("SAFS_MakeDir returns %d\n"
, errorCode)); } while (0)
;
4463 return errorCode;
4464
4465} /*SAFSS_MakeDir */
4466
4467
4468afs_int32
4469SRXAFS_MakeDir(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
4470 struct AFSStoreStatus * InStatus, struct AFSFid * OutFid,
4471 struct AFSFetchStatus * OutFidStatus,
4472 struct AFSFetchStatus * OutDirStatus,
4473 struct AFSCallBack * CallBack, struct AFSVolSync * Sync)
4474{
4475 afs_int32 code;
4476 struct rx_connection *tcon;
4477 struct host *thost;
4478 struct client *t_client = NULL((void *)0); /* tmp ptr to client data */
4479 struct fsstats fsstats;
4480
4481 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_MAKEDIR11);
4482
4483 if ((code = CallPreamble(acall, ACTIVECALL1, &tcon, &thost)))
4484 goto Bad_MakeDir;
4485
4486 code =
4487 SAFSS_MakeDir(acall, DirFid, Name, InStatus, OutFid, OutFidStatus,
4488 OutDirStatus, CallBack, Sync);
4489
4490 Bad_MakeDir:
4491 code = CallPostamble(tcon, code, thost);
4492
4493 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
4494
4495 fsstats_FinishOp(&fsstats, code);
4496
4497 osi_auditU(acall, MakeDirEvent"AFS_SRX_MakeDir", code,
4498 AUD_ID10, t_client ? t_client->ViceId : 0,
4499 AUD_FID7, DirFid, AUD_STR1, Name,
4500 AUD_FID7, OutFid, AUD_END0);
4501 return code;
4502
4503} /*SRXAFS_MakeDir */
4504
4505
4506/*
4507 * This routine is called exclusively by SRXAFS_RemoveDir(), and should be
4508 * merged into it when possible.
4509 */
4510static afs_int32
4511SAFSS_RemoveDir(struct rx_call *acall, struct AFSFid *DirFid, char *Name,
4512 struct AFSFetchStatus *OutDirStatus, struct AFSVolSync *Sync)
4513{
4514 Vnode *parentptr = 0; /* vnode of input Directory */
4515 Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
4516 Vnode *targetptr = 0; /* file to be deleted */
4517 AFSFid fileFid; /* area for Fid from the directory */
4518 Errorbit32 errorCode = 0; /* error code */
4519 DirHandle dir; /* Handle for dir package I/O */
4520 Volume *volptr = 0; /* pointer to the volume header */
4521 struct client *client = 0; /* pointer to client structure */
4522 afs_int32 rights, anyrights; /* rights for this and any user */
4523 struct client *t_client; /* tmp ptr to client data */
4524 struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
4525 struct rx_connection *tcon = rx_ConnectionOf(acall)((acall)->conn);
4526
4527 FidZero(&dir);
4528
4529 /* Get ptr to client data for user Id for logging */
4530 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
4531 logHostAddr.s_addr = rxr_HostOf(tcon)(((((struct rx_connection *)(tcon))->peer))->host);
4532 ViceLog(1,do { if ((1) <= LogLevel) (FSLog ("SAFS_RemoveDir %s, Did = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, DirFid->Volume, DirFid->Vnode, DirFid->Unique
, __inet_ntoa(logHostAddr), (__builtin_constant_p(((((((struct
rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
4533 ("SAFS_RemoveDir %s, Did = %u.%u.%u, Host %s:%d, Id %d\n", Name,do { if ((1) <= LogLevel) (FSLog ("SAFS_RemoveDir %s, Did = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, DirFid->Volume, DirFid->Vnode, DirFid->Unique
, __inet_ntoa(logHostAddr), (__builtin_constant_p(((((((struct
rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
4534 DirFid->Volume, DirFid->Vnode, DirFid->Unique,do { if ((1) <= LogLevel) (FSLog ("SAFS_RemoveDir %s, Did = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, DirFid->Volume, DirFid->Vnode, DirFid->Unique
, __inet_ntoa(logHostAddr), (__builtin_constant_p(((((((struct
rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
4535 inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId))do { if ((1) <= LogLevel) (FSLog ("SAFS_RemoveDir %s, Did = %u.%u.%u, Host %s:%d, Id %d\n"
, Name, DirFid->Volume, DirFid->Vnode, DirFid->Unique
, __inet_ntoa(logHostAddr), (__builtin_constant_p(((((((struct
rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
;
4536 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 4536), 0));
;
4537 AFSCallStats.RemoveDir++, AFSCallStats.TotalCalls++;
4538 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 4538), 0));
;
4539 /*
4540 * Get the vnode and volume for the parent dir along with the caller's
4541 * rights to it
4542 */
4543 if ((errorCode =
4544 GetVolumePackage(tcon, DirFid, &volptr, &parentptr, MustBeDIR2,
4545 &parentwhentargetnotdir, &client, WRITE_LOCK2,
4546 &rights, &anyrights))) {
4547 goto Bad_RemoveDir;
4548 }
4549
4550 /* set volume synchronization information */
4551 SetVolumeSync(Sync, volptr);
4552
4553 /* Does the caller has delete (&write) access to the parent dir? */
4554 if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_DELETE16))) {
4555 goto Bad_RemoveDir;
4556 }
4557
4558 /* Do the actual delete of the desired (empty) directory, Name */
4559 if ((errorCode =
4560 DeleteTarget(parentptr, volptr, &targetptr, &dir, &fileFid, Name,
4561 MustBeDIR2))) {
4562 goto Bad_RemoveDir;
4563 }
4564
4565 /* Update the status for the parent dir; link count is also adjusted */
4566#if FS_STATS_DETAILED1
4567 Update_ParentVnodeStatus(parentptr, volptr, &dir, client->ViceId,
4568 parentptr->disk.linkCount - 1,
4569 client->InSameNetwork);
4570#else
4571 Update_ParentVnodeStatus(parentptr, volptr, &dir, client->ViceId,
4572 parentptr->disk.linkCount - 1);
4573#endif /* FS_STATS_DETAILED */
4574
4575 /* Return to the caller the updated parent dir status */
4576 GetStatus(parentptr, OutDirStatus, rights, anyrights, NULL((void *)0));
4577
4578 /*
4579 * Note: it is not necessary to break the callback on fileFid, since
4580 * refcount is now 0, so no one should be able to refer to the dir
4581 * any longer
4582 */
4583 DeleteFileCallBacks(&fileFid);
4584
4585 /* convert the write lock to a read lock before breaking callbacks */
4586 VVnodeWriteToRead(&errorCode, parentptr);
4587 osi_Assert(!errorCode || errorCode == VSALVAGE)(void)((!errorCode || errorCode == 101) || (osi_AssertFailU("!errorCode || errorCode == VSALVAGE"
, "./../viced/afsfileprocs.c", 4587), 0))
;
4588
4589 /* break call back on DirFid and fileFid */
4590 BreakCallBack(client->host, DirFid, 0);
4591
4592 Bad_RemoveDir:
4593 /* Write the all modified vnodes (parent, new files) and volume back */
4594 (void)PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr,
4595 volptr, &client);
4596 FidZap(&dir);
4597 ViceLog(2, ("SAFS_RemoveDir returns %d\n", errorCode))do { if ((2) <= LogLevel) (FSLog ("SAFS_RemoveDir returns %d\n"
, errorCode)); } while (0)
;
4598 return errorCode;
4599
4600} /*SAFSS_RemoveDir */
4601
4602
4603afs_int32
4604SRXAFS_RemoveDir(struct rx_call * acall, struct AFSFid * DirFid, char *Name,
4605 struct AFSFetchStatus * OutDirStatus,
4606 struct AFSVolSync * Sync)
4607{
4608 afs_int32 code;
4609 struct rx_connection *tcon;
4610 struct host *thost;
4611 struct client *t_client = NULL((void *)0); /* tmp ptr to client data */
4612 struct fsstats fsstats;
4613
4614 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_REMOVEDIR12);
4615
4616 if ((code = CallPreamble(acall, ACTIVECALL1, &tcon, &thost)))
4617 goto Bad_RemoveDir;
4618
4619 code = SAFSS_RemoveDir(acall, DirFid, Name, OutDirStatus, Sync);
4620
4621 Bad_RemoveDir:
4622 code = CallPostamble(tcon, code, thost);
4623
4624 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
4625
4626 fsstats_FinishOp(&fsstats, code);
4627
4628 osi_auditU(acall, RemoveDirEvent"AFS_SRX_RmDir", code,
4629 AUD_ID10, t_client ? t_client->ViceId : 0,
4630 AUD_FID7, DirFid, AUD_STR1, Name, AUD_END0);
4631 return code;
4632
4633} /*SRXAFS_RemoveDir */
4634
4635
4636/*
4637 * This routine is called exclusively by SRXAFS_SetLock(), and should be
4638 * merged into it when possible.
4639 */
4640static afs_int32
4641SAFSS_SetLock(struct rx_call *acall, struct AFSFid *Fid, ViceLockType type,
4642 struct AFSVolSync *Sync)
4643{
4644 Vnode *targetptr = 0; /* vnode of input file */
4645 Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
4646 Errorbit32 errorCode = 0; /* error code */
4647 Volume *volptr = 0; /* pointer to the volume header */
4648 struct client *client = 0; /* pointer to client structure */
4649 afs_int32 rights, anyrights; /* rights for this and any user */
4650 struct client *t_client; /* tmp ptr to client data */
4651 struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
4652 static char *locktype[4] = { "LockRead", "LockWrite", "LockExtend", "LockRelease" };
4653 struct rx_connection *tcon = rx_ConnectionOf(acall)((acall)->conn);
4654
4655 if (type != LockRead0 && type != LockWrite1) {
4656 errorCode = EINVAL22;
4657 goto Bad_SetLock;
4658 }
4659 /* Get ptr to client data for user Id for logging */
4660 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
4661 logHostAddr.s_addr = rxr_HostOf(tcon)(((((struct rx_connection *)(tcon))->peer))->host);
4662 ViceLog(1,do { if ((1) <= LogLevel) (FSLog ("SAFS_SetLock type = %s Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, locktype[(int)type], Fid->Volume, Fid->Vnode, Fid->
Unique, __inet_ntoa(logHostAddr), (__builtin_constant_p((((((
(struct rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
4663 ("SAFS_SetLock type = %s Fid = %u.%u.%u, Host %s:%d, Id %d\n",do { if ((1) <= LogLevel) (FSLog ("SAFS_SetLock type = %s Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, locktype[(int)type], Fid->Volume, Fid->Vnode, Fid->
Unique, __inet_ntoa(logHostAddr), (__builtin_constant_p((((((
(struct rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
4664 locktype[(int)type], Fid->Volume, Fid->Vnode, Fid->Unique,do { if ((1) <= LogLevel) (FSLog ("SAFS_SetLock type = %s Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, locktype[(int)type], Fid->Volume, Fid->Vnode, Fid->
Unique, __inet_ntoa(logHostAddr), (__builtin_constant_p((((((
(struct rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
4665 inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId))do { if ((1) <= LogLevel) (FSLog ("SAFS_SetLock type = %s Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, locktype[(int)type], Fid->Volume, Fid->Vnode, Fid->
Unique, __inet_ntoa(logHostAddr), (__builtin_constant_p((((((
(struct rx_connection *)(tcon)))->peer))->port)) ? (__uint16_t
)(((__uint16_t)(((((((struct rx_connection *)(tcon)))->peer
))->port))) << 8 | ((__uint16_t)(((((((struct rx_connection
*)(tcon)))->peer))->port))) >> 8) : __bswap16_var
(((((((struct rx_connection *)(tcon)))->peer))->port)))
, t_client->ViceId)); } while (0)
;
4666 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 4666), 0));
;
4667 AFSCallStats.SetLock++, AFSCallStats.TotalCalls++;
4668 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 4668), 0));
;
4669 /*
4670 * Get the vnode and volume for the desired file along with the caller's
4671 * rights to it
4672 */
4673 if ((errorCode =
4674 GetVolumePackage(tcon, Fid, &volptr, &targetptr, DONTCHECK0,
4675 &parentwhentargetnotdir, &client, WRITE_LOCK2,
4676 &rights, &anyrights))) {
4677 goto Bad_SetLock;
4678 }
4679
4680 /* set volume synchronization information */
4681 SetVolumeSync(Sync, volptr);
4682
4683 /* Handle the particular type of set locking, type */
4684 errorCode = HandleLocking(targetptr, client, rights, type);
4685
4686 Bad_SetLock:
4687 /* Write the all modified vnodes (parent, new files) and volume back */
4688 (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
4689 volptr, &client);
4690
4691 if ((errorCode == VREADONLY30) && (type == LockRead0))
4692 errorCode = 0; /* allow read locks on RO volumes without saving state */
4693
4694 ViceLog(2, ("SAFS_SetLock returns %d\n", errorCode))do { if ((2) <= LogLevel) (FSLog ("SAFS_SetLock returns %d\n"
, errorCode)); } while (0)
;
4695 return (errorCode);
4696
4697} /*SAFSS_SetLock */
4698
4699
4700afs_int32
4701SRXAFS_OldSetLock(struct rx_call * acall, struct AFSFid * Fid,
4702 ViceLockType type, struct AFSVolSync * Sync)
4703{
4704 return SRXAFS_SetLock(acall, Fid, type, Sync);
4705} /*SRXAFS_OldSetLock */
4706
4707
4708afs_int32
4709SRXAFS_SetLock(struct rx_call * acall, struct AFSFid * Fid, ViceLockType type,
4710 struct AFSVolSync * Sync)
4711{
4712 afs_int32 code;
4713 struct rx_connection *tcon;
4714 struct host *thost;
4715 struct client *t_client = NULL((void *)0); /* tmp ptr to client data */
4716 struct fsstats fsstats;
4717
4718 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_SETLOCK13);
4719
4720 if ((code = CallPreamble(acall, ACTIVECALL1, &tcon, &thost)))
4721 goto Bad_SetLock;
4722
4723 code = SAFSS_SetLock(acall, Fid, type, Sync);
4724
4725 Bad_SetLock:
4726 code = CallPostamble(tcon, code, thost);
4727
4728 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
4729
4730 fsstats_FinishOp(&fsstats, code);
4731
4732 osi_auditU(acall, SetLockEvent"AFS_SRX_SetLock", code,
4733 AUD_ID10, t_client ? t_client->ViceId : 0,
4734 AUD_FID7, Fid, AUD_LONG5, type, AUD_END0);
4735 return code;
4736} /*SRXAFS_SetLock */
4737
4738
4739/*
4740 * This routine is called exclusively by SRXAFS_ExtendLock(), and should be
4741 * merged into it when possible.
4742 */
4743static afs_int32
4744SAFSS_ExtendLock(struct rx_call *acall, struct AFSFid *Fid,
4745 struct AFSVolSync *Sync)
4746{
4747 Vnode *targetptr = 0; /* vnode of input file */
4748 Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
4749 Errorbit32 errorCode = 0; /* error code */
4750 Volume *volptr = 0; /* pointer to the volume header */
4751 struct client *client = 0; /* pointer to client structure */
4752 afs_int32 rights, anyrights; /* rights for this and any user */
4753 struct client *t_client; /* tmp ptr to client data */
4754 struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
4755 struct rx_connection *tcon = rx_ConnectionOf(acall)((acall)->conn);
4756
4757 /* Get ptr to client data for user Id for logging */
4758 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
4759 logHostAddr.s_addr = rxr_HostOf(tcon)(((((struct rx_connection *)(tcon))->peer))->host);
4760 ViceLog(1,do { if ((1) <= LogLevel) (FSLog ("SAFS_ExtendLock Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
4761 ("SAFS_ExtendLock Fid = %u.%u.%u, Host %s:%d, Id %d\n", Fid->Volume,do { if ((1) <= LogLevel) (FSLog ("SAFS_ExtendLock Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
4762 Fid->Vnode, Fid->Unique, inet_ntoa(logHostAddr),do { if ((1) <= LogLevel) (FSLog ("SAFS_ExtendLock Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
4763 ntohs(rxr_PortOf(tcon)), t_client->ViceId))do { if ((1) <= LogLevel) (FSLog ("SAFS_ExtendLock Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
;
4764 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 4764), 0));
;
4765 AFSCallStats.ExtendLock++, AFSCallStats.TotalCalls++;
4766 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 4766), 0));
;
4767 /*
4768 * Get the vnode and volume for the desired file along with the caller's
4769 * rights to it
4770 */
4771 if ((errorCode =
4772 GetVolumePackage(tcon, Fid, &volptr, &targetptr, DONTCHECK0,
4773 &parentwhentargetnotdir, &client, WRITE_LOCK2,
4774 &rights, &anyrights))) {
4775 goto Bad_ExtendLock;
4776 }
4777
4778 /* set volume synchronization information */
4779 SetVolumeSync(Sync, volptr);
4780
4781 /* Handle the actual lock extension */
4782 errorCode = HandleLocking(targetptr, client, rights, LockExtend2);
4783
4784 Bad_ExtendLock:
4785 /* Put back file's vnode and volume */
4786 (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
4787 volptr, &client);
4788
4789 if ((errorCode == VREADONLY30)) /* presumably, we already granted this lock */
4790 errorCode = 0; /* under our generous policy re RO vols */
4791
4792 ViceLog(2, ("SAFS_ExtendLock returns %d\n", errorCode))do { if ((2) <= LogLevel) (FSLog ("SAFS_ExtendLock returns %d\n"
, errorCode)); } while (0)
;
4793 return (errorCode);
4794
4795} /*SAFSS_ExtendLock */
4796
4797
4798afs_int32
4799SRXAFS_OldExtendLock(struct rx_call * acall, struct AFSFid * Fid,
4800 struct AFSVolSync * Sync)
4801{
4802 return SRXAFS_ExtendLock(acall, Fid, Sync);
4803} /*SRXAFS_OldExtendLock */
4804
4805
4806afs_int32
4807SRXAFS_ExtendLock(struct rx_call * acall, struct AFSFid * Fid,
4808 struct AFSVolSync * Sync)
4809{
4810 afs_int32 code;
4811 struct rx_connection *tcon;
4812 struct host *thost;
4813 struct client *t_client = NULL((void *)0); /* tmp ptr to client data */
4814 struct fsstats fsstats;
4815
4816 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_EXTENDLOCK14);
4817
4818 if ((code = CallPreamble(acall, ACTIVECALL1, &tcon, &thost)))
4819 goto Bad_ExtendLock;
4820
4821 code = SAFSS_ExtendLock(acall, Fid, Sync);
4822
4823 Bad_ExtendLock:
4824 code = CallPostamble(tcon, code, thost);
4825
4826 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
4827
4828 fsstats_FinishOp(&fsstats, code);
4829
4830 osi_auditU(acall, ExtendLockEvent"AFS_SRX_ExtLock", code,
4831 AUD_ID10, t_client ? t_client->ViceId : 0,
4832 AUD_FID7, Fid, AUD_END0);
4833 return code;
4834
4835} /*SRXAFS_ExtendLock */
4836
4837
4838/*
4839 * This routine is called exclusively by SRXAFS_ReleaseLock(), and should be
4840 * merged into it when possible.
4841 */
4842static afs_int32
4843SAFSS_ReleaseLock(struct rx_call *acall, struct AFSFid *Fid,
4844 struct AFSVolSync *Sync)
4845{
4846 Vnode *targetptr = 0; /* vnode of input file */
4847 Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
4848 Errorbit32 errorCode = 0; /* error code */
4849 Volume *volptr = 0; /* pointer to the volume header */
4850 struct client *client = 0; /* pointer to client structure */
4851 afs_int32 rights, anyrights; /* rights for this and any user */
4852 struct client *t_client; /* tmp ptr to client data */
4853 struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
4854 struct rx_connection *tcon = rx_ConnectionOf(acall)((acall)->conn);
4855
4856 /* Get ptr to client data for user Id for logging */
4857 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
4858 logHostAddr.s_addr = rxr_HostOf(tcon)(((((struct rx_connection *)(tcon))->peer))->host);
4859 ViceLog(1,do { if ((1) <= LogLevel) (FSLog ("SAFS_ReleaseLock Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
4860 ("SAFS_ReleaseLock Fid = %u.%u.%u, Host %s:%d, Id %d\n", Fid->Volume,do { if ((1) <= LogLevel) (FSLog ("SAFS_ReleaseLock Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
4861 Fid->Vnode, Fid->Unique, inet_ntoa(logHostAddr),do { if ((1) <= LogLevel) (FSLog ("SAFS_ReleaseLock Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
4862 ntohs(rxr_PortOf(tcon)), t_client->ViceId))do { if ((1) <= LogLevel) (FSLog ("SAFS_ReleaseLock Fid = %u.%u.%u, Host %s:%d, Id %d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, __inet_ntoa(
logHostAddr), (__builtin_constant_p(((((((struct rx_connection
*)(tcon)))->peer))->port)) ? (__uint16_t)(((__uint16_t
)(((((((struct rx_connection *)(tcon)))->peer))->port))
) << 8 | ((__uint16_t)(((((((struct rx_connection *)(tcon
)))->peer))->port))) >> 8) : __bswap16_var(((((((
struct rx_connection *)(tcon)))->peer))->port))), t_client
->ViceId)); } while (0)
;
4863 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 4863), 0));
;
4864 AFSCallStats.ReleaseLock++, AFSCallStats.TotalCalls++;
4865 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 4865), 0));
;
4866 /*
4867 * Get the vnode and volume for the desired file along with the caller's
4868 * rights to it
4869 */
4870 if ((errorCode =
4871 GetVolumePackage(tcon, Fid, &volptr, &targetptr, DONTCHECK0,
4872 &parentwhentargetnotdir, &client, WRITE_LOCK2,
4873 &rights, &anyrights))) {
4874 goto Bad_ReleaseLock;
4875 }
4876
4877 /* set volume synchronization information */
4878 SetVolumeSync(Sync, volptr);
4879
4880 /* Handle the actual lock release */
4881 if ((errorCode = HandleLocking(targetptr, client, rights, LockRelease3)))
4882 goto Bad_ReleaseLock;
4883
4884 /* if no more locks left, a callback would be triggered here */
4885 if (targetptr->disk.lock.lockCount <= 0) {
4886 /* convert the write lock to a read lock before breaking callbacks */
4887 VVnodeWriteToRead(&errorCode, targetptr);
4888 osi_Assert(!errorCode || errorCode == VSALVAGE)(void)((!errorCode || errorCode == 101) || (osi_AssertFailU("!errorCode || errorCode == VSALVAGE"
, "./../viced/afsfileprocs.c", 4888), 0))
;
4889 BreakCallBack(client->host, Fid, 0);
4890 }
4891
4892 Bad_ReleaseLock:
4893 /* Put back file's vnode and volume */
4894 (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
4895 volptr, &client);
4896
4897 if ((errorCode == VREADONLY30)) /* presumably, we already granted this lock */
4898 errorCode = 0; /* under our generous policy re RO vols */
4899
4900 ViceLog(2, ("SAFS_ReleaseLock returns %d\n", errorCode))do { if ((2) <= LogLevel) (FSLog ("SAFS_ReleaseLock returns %d\n"
, errorCode)); } while (0)
;
4901 return (errorCode);
4902
4903} /*SAFSS_ReleaseLock */
4904
4905
4906afs_int32
4907SRXAFS_OldReleaseLock(struct rx_call * acall, struct AFSFid * Fid,
4908 struct AFSVolSync * Sync)
4909{
4910 return SRXAFS_ReleaseLock(acall, Fid, Sync);
4911} /*SRXAFS_OldReleaseLock */
4912
4913
4914afs_int32
4915SRXAFS_ReleaseLock(struct rx_call * acall, struct AFSFid * Fid,
4916 struct AFSVolSync * Sync)
4917{
4918 afs_int32 code;
4919 struct rx_connection *tcon;
4920 struct host *thost;
4921 struct client *t_client = NULL((void *)0); /* tmp ptr to client data */
4922 struct fsstats fsstats;
4923
4924 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_RELEASELOCK15);
4925
4926 if ((code = CallPreamble(acall, ACTIVECALL1, &tcon, &thost)))
4927 goto Bad_ReleaseLock;
4928
4929 code = SAFSS_ReleaseLock(acall, Fid, Sync);
4930
4931 Bad_ReleaseLock:
4932 code = CallPostamble(tcon, code, thost);
4933
4934 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
4935
4936 fsstats_FinishOp(&fsstats, code);
4937
4938 osi_auditU(acall, ReleaseLockEvent"AFS_SRX_RelLock", code,
4939 AUD_ID10, t_client ? t_client->ViceId : 0,
4940 AUD_FID7, Fid, AUD_END0);
4941 return code;
4942
4943} /*SRXAFS_ReleaseLock */
4944
4945
4946void
4947SetSystemStats(struct AFSStatistics *stats)
4948{
4949 /* Fix this sometime soon.. */
4950 /* Because hey, it's not like we have a network monitoring protocol... */
4951 struct timeval time;
4952
4953 /* this works on all system types */
4954 FT_GetTimeOfDay(&time, 0);
4955 stats->CurrentTime = time.tv_sec;
4956} /*SetSystemStats */
4957
4958void
4959SetAFSStats(struct AFSStatistics *stats)
4960{
4961 extern afs_int32 StartTime, CurrentConnections;
4962 int seconds;
4963
4964 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 4964), 0));
;
4965 stats->CurrentMsgNumber = 0;
4966 stats->OldestMsgNumber = 0;
4967 stats->StartTime = StartTime;
4968 stats->CurrentConnections = CurrentConnections;
4969 stats->TotalAFSCalls = AFSCallStats.TotalCalls;
4970 stats->TotalFetchs =
4971 AFSCallStats.FetchData + AFSCallStats.FetchACL +
4972 AFSCallStats.FetchStatus;
4973 stats->FetchDatas = AFSCallStats.FetchData;
4974 stats->FetchedBytes = AFSCallStats.TotalFetchedBytes;
4975 seconds = AFSCallStats.AccumFetchTime / 1000;
4976 if (seconds <= 0)
4977 seconds = 1;
4978 stats->FetchDataRate = AFSCallStats.TotalFetchedBytes / seconds;
4979 stats->TotalStores =
4980 AFSCallStats.StoreData + AFSCallStats.StoreACL +
4981 AFSCallStats.StoreStatus;
4982 stats->StoreDatas = AFSCallStats.StoreData;
4983 stats->StoredBytes = AFSCallStats.TotalStoredBytes;
4984 seconds = AFSCallStats.AccumStoreTime / 1000;
4985 if (seconds <= 0)
4986 seconds = 1;
4987 stats->StoreDataRate = AFSCallStats.TotalStoredBytes / seconds;
4988#ifdef AFS_NT40_ENV
4989 stats->ProcessSize = -1; /* TODO: */
4990#else
4991 stats->ProcessSize = (afs_int32) ((long)sbrk(0) >> 10);
4992#endif
4993 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 4993), 0));
;
4994 h_GetWorkStats((int *)&(stats->WorkStations),
4995 (int *)&(stats->ActiveWorkStations), (int *)0,
4996 (afs_int32) (FT_ApproxTime()) - (15 * 60));
4997
4998} /*SetAFSStats */
4999
5000/* Get disk related information from all AFS partitions. */
5001
5002void
5003SetVolumeStats(struct AFSStatistics *stats)
5004{
5005 struct DiskPartition64 *part;
5006 int i = 0;
5007
5008 for (part = DiskPartitionList; part && i < AFS_MSTATDISKS10;
5009 part = part->next) {
5010 stats->Disks[i].TotalBlocks = RoundInt64ToInt32(part->totalUsable)(part->totalUsable > 0xFFFFFFFF) ? 0xFFFFFFFF : part->
totalUsable;
;
5011 stats->Disks[i].BlocksAvailable = RoundInt64ToInt32(part->free)(part->free > 0xFFFFFFFF) ? 0xFFFFFFFF : part->free;;
5012 memset(stats->Disks[i].Name, 0, AFS_DISKNAMESIZE32);
5013 strncpy(stats->Disks[i].Name, part->name, AFS_DISKNAMESIZE32);
5014 i++;
5015 }
5016 while (i < AFS_MSTATDISKS10) {
5017 stats->Disks[i].TotalBlocks = -1;
5018 i++;
5019 }
5020} /*SetVolumeStats */
5021
5022afs_int32
5023SRXAFS_GetStatistics(struct rx_call *acall, struct ViceStatistics *Statistics)
5024{
5025 afs_int32 code;
5026 struct rx_connection *tcon = rx_ConnectionOf(acall)((acall)->conn);
5027 struct host *thost;
5028 struct client *t_client = NULL((void *)0); /* tmp ptr to client data */
5029 struct fsstats fsstats;
5030
5031 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETSTATISTICS16);
5032
5033 if ((code = CallPreamble(acall, NOTACTIVECALL0, &tcon, &thost)))
5034 goto Bad_GetStatistics;
5035
5036 ViceLog(1, ("SAFS_GetStatistics Received\n"))do { if ((1) <= LogLevel) (FSLog ("SAFS_GetStatistics Received\n"
)); } while (0)
;
5037 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 5037), 0));
;
5038 AFSCallStats.GetStatistics++, AFSCallStats.TotalCalls++;
5039 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 5039), 0));
;
5040 memset(Statistics, 0, sizeof(*Statistics));
5041 SetAFSStats((struct AFSStatistics *)Statistics);
5042 SetVolumeStats((struct AFSStatistics *)Statistics);
5043 SetSystemStats((struct AFSStatistics *)Statistics);
5044
5045 Bad_GetStatistics:
5046 code = CallPostamble(tcon, code, thost);
5047
5048 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
5049
5050 fsstats_FinishOp(&fsstats, code);
5051
5052 osi_auditU(acall, GetStatisticsEvent"AFS_SRX_GetStats", code,
5053 AUD_ID10, t_client ? t_client->ViceId : 0, AUD_END0);
5054 return code;
5055} /*SRXAFS_GetStatistics */
5056
5057
5058afs_int32
5059SRXAFS_GetStatistics64(struct rx_call *acall, afs_int32 statsVersion, ViceStatistics64 *Statistics)
5060{
5061 extern afs_int32 StartTime, CurrentConnections;
5062 int seconds;
5063 afs_int32 code;
5064 struct rx_connection *tcon = rx_ConnectionOf(acall)((acall)->conn);
5065 struct host *thost;
5066 struct client *t_client = NULL((void *)0); /* tmp ptr to client data */
5067 struct timeval time;
5068 struct fsstats fsstats;
5069
5070 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETSTATISTICS16);
5071
5072 if ((code = CallPreamble(acall, NOTACTIVECALL0, &tcon, &thost)))
5073 goto Bad_GetStatistics64;
5074
5075 ViceLog(1, ("SAFS_GetStatistics64 Received\n"))do { if ((1) <= LogLevel) (FSLog ("SAFS_GetStatistics64 Received\n"
)); } while (0)
;
5076 Statistics->ViceStatistics64_val =
5077 malloc(statsVersion*sizeof(afs_int64));
5078 Statistics->ViceStatistics64_len = statsVersion;
5079 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 5079), 0));
;
5080 AFSCallStats.GetStatistics++, AFSCallStats.TotalCalls++;
5081 Statistics->ViceStatistics64_val[STATS64_STARTTIME2] = StartTime;
5082 Statistics->ViceStatistics64_val[STATS64_CURRENTCONNECTIONS3] =
5083 CurrentConnections;
5084 Statistics->ViceStatistics64_val[STATS64_TOTALVICECALLS12] =
5085 AFSCallStats.TotalCalls;
5086 Statistics->ViceStatistics64_val[STATS64_TOTALFETCHES4] =
5087 AFSCallStats.FetchData + AFSCallStats.FetchACL +
5088 AFSCallStats.FetchStatus;
5089 Statistics->ViceStatistics64_val[STATS64_FETCHDATAS5] =
5090 AFSCallStats.FetchData;
5091 Statistics->ViceStatistics64_val[STATS64_FETCHEDBYTES6] =
5092 AFSCallStats.TotalFetchedBytes;
5093 seconds = AFSCallStats.AccumFetchTime / 1000;
5094 if (seconds <= 0)
5095 seconds = 1;
5096 Statistics->ViceStatistics64_val[STATS64_FETCHDATARATE7] =
5097 AFSCallStats.TotalFetchedBytes / seconds;
5098 Statistics->ViceStatistics64_val[STATS64_TOTALSTORES8] =
5099 AFSCallStats.StoreData + AFSCallStats.StoreACL +
5100 AFSCallStats.StoreStatus;
5101 Statistics->ViceStatistics64_val[STATS64_STOREDATAS9] =
5102 AFSCallStats.StoreData;
5103 Statistics->ViceStatistics64_val[STATS64_STOREDBYTES10] =
5104 AFSCallStats.TotalStoredBytes;
5105 seconds = AFSCallStats.AccumStoreTime / 1000;
5106 if (seconds <= 0)
5107 seconds = 1;
5108 Statistics->ViceStatistics64_val[STATS64_STOREDATARATE11] =
5109 AFSCallStats.TotalStoredBytes / seconds;
5110#ifdef AFS_NT40_ENV
5111 Statistics->ViceStatistics64_val[STATS64_PROCESSSIZE15] = -1;
5112#else
5113 Statistics->ViceStatistics64_val[STATS64_PROCESSSIZE15] =
5114 (afs_int32) ((long)sbrk(0) >> 10);
5115#endif
5116 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 5116), 0));
;
5117 h_GetWorkStats64(&(Statistics->ViceStatistics64_val[STATS64_WORKSTATIONS13]),
5118 &(Statistics->ViceStatistics64_val[STATS64_ACTIVEWORKSTATIONS14]),
5119 0,
5120 (afs_int32) (FT_ApproxTime()) - (15 * 60));
5121
5122
5123
5124 /* this works on all system types */
5125 FT_GetTimeOfDay(&time, 0);
5126 Statistics->ViceStatistics64_val[STATS64_CURRENTTIME0] = time.tv_sec;
5127
5128 Bad_GetStatistics64:
5129 code = CallPostamble(tcon, code, thost);
5130
5131 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
5132
5133 fsstats_FinishOp(&fsstats, code);
5134
5135 osi_auditU(acall, GetStatisticsEvent"AFS_SRX_GetStats", code,
5136 AUD_ID10, t_client ? t_client->ViceId : 0, AUD_END0);
5137 return code;
5138} /*SRXAFS_GetStatistics */
5139
5140
5141/*------------------------------------------------------------------------
5142 * EXPORTED SRXAFS_XStatsVersion
5143 *
5144 * Description:
5145 * Routine called by the server-side RPC interface to implement
5146 * pulling out the xstat version number for the File Server.
5147 *
5148 * Arguments:
5149 * a_versionP : Ptr to the version number variable to set.
5150 *
5151 * Returns:
5152 * 0 (always)
5153 *
5154 * Environment:
5155 * Nothing interesting.
5156 *
5157 * Side Effects:
5158 * As advertised.
5159 *------------------------------------------------------------------------*/
5160
5161afs_int32
5162SRXAFS_XStatsVersion(struct rx_call * a_call, afs_int32 * a_versionP)
5163{ /*SRXAFS_XStatsVersion */
5164
5165 struct client *t_client = NULL((void *)0); /* tmp ptr to client data */
5166 struct rx_connection *tcon = rx_ConnectionOf(a_call)((a_call)->conn);
5167 struct fsstats fsstats;
5168
5169 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_XSTATSVERSION26);
5170
5171 *a_versionP = AFS_XSTAT_VERSION2;
5172
5173 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
5174
5175 fsstats_FinishOp(&fsstats, 0);
5176
5177 osi_auditU(a_call, XStatsVersionEvent"AFS_SRX_XStatsVer", 0,
5178 AUD_ID10, t_client ? t_client->ViceId : 0, AUD_END0);
5179 return (0);
5180} /*SRXAFS_XStatsVersion */
5181
5182
5183/*------------------------------------------------------------------------
5184 * PRIVATE FillPerfValues
5185 *
5186 * Description:
5187 * Routine called to fill a regular performance data structure.
5188 *
5189 * Arguments:
5190 * a_perfP : Ptr to perf structure to fill
5191 *
5192 * Returns:
5193 * Nothing.
5194 *
5195 * Environment:
5196 * Various collections need this info, so the guts were put in
5197 * this separate routine.
5198 *
5199 * Side Effects:
5200 * As advertised.
5201 *------------------------------------------------------------------------*/
5202
5203static void
5204FillPerfValues(struct afs_PerfStats *a_perfP)
5205{ /*FillPerfValues */
5206 int dir_Buffers; /*# buffers in use by dir package */
5207 int dir_Calls; /*# read calls in dir package */
5208 int dir_IOs; /*# I/O ops in dir package */
5209 struct rx_statistics *stats;
5210
5211 /*
5212 * Vnode cache section.
5213 */
5214 a_perfP->vcache_L_Entries = VnodeClassInfo[vLarge0].cacheSize;
5215 a_perfP->vcache_L_Allocs = VnodeClassInfo[vLarge0].allocs;
5216 a_perfP->vcache_L_Gets = VnodeClassInfo[vLarge0].gets;
5217 a_perfP->vcache_L_Reads = VnodeClassInfo[vLarge0].reads;
5218 a_perfP->vcache_L_Writes = VnodeClassInfo[vLarge0].writes;
5219 a_perfP->vcache_S_Entries = VnodeClassInfo[vSmall1].cacheSize;
5220 a_perfP->vcache_S_Allocs = VnodeClassInfo[vSmall1].allocs;
5221 a_perfP->vcache_S_Gets = VnodeClassInfo[vSmall1].gets;
5222 a_perfP->vcache_S_Reads = VnodeClassInfo[vSmall1].reads;
5223 a_perfP->vcache_S_Writes = VnodeClassInfo[vSmall1].writes;
5224 a_perfP->vcache_H_Entries = VStats.hdr_cache_size;
5225 a_perfP->vcache_H_Gets = (int)VStats.hdr_gets;
5226 a_perfP->vcache_H_Replacements = (int)VStats.hdr_loads;
5227
5228 /*
5229 * Directory section.
5230 */
5231 DStat(&dir_Buffers, &dir_Calls, &dir_IOs);
5232 a_perfP->dir_Buffers = (afs_int32) dir_Buffers;
5233 a_perfP->dir_Calls = (afs_int32) dir_Calls;
5234 a_perfP->dir_IOs = (afs_int32) dir_IOs;
5235
5236 /*
5237 * Rx section.
5238 */
5239 stats = rx_GetStatistics();
5240
5241 a_perfP->rx_packetRequests = (afs_int32) stats->packetRequests;
5242 a_perfP->rx_noPackets_RcvClass =
5243 (afs_int32) stats->receivePktAllocFailures;
5244 a_perfP->rx_noPackets_SendClass =
5245 (afs_int32) stats->sendPktAllocFailures;
5246 a_perfP->rx_noPackets_SpecialClass =
5247 (afs_int32) stats->specialPktAllocFailures;
5248 a_perfP->rx_socketGreedy = (afs_int32) stats->socketGreedy;
5249 a_perfP->rx_bogusPacketOnRead = (afs_int32) stats->bogusPacketOnRead;
5250 a_perfP->rx_bogusHost = (afs_int32) stats->bogusHost;
5251 a_perfP->rx_noPacketOnRead = (afs_int32) stats->noPacketOnRead;
5252 a_perfP->rx_noPacketBuffersOnRead =
5253 (afs_int32) stats->noPacketBuffersOnRead;
5254 a_perfP->rx_selects = (afs_int32) stats->selects;
5255 a_perfP->rx_sendSelects = (afs_int32) stats->sendSelects;
5256 a_perfP->rx_packetsRead_RcvClass =
5257 (afs_int32) stats->packetsRead[RX_PACKET_CLASS_RECEIVE0];
5258 a_perfP->rx_packetsRead_SendClass =
5259 (afs_int32) stats->packetsRead[RX_PACKET_CLASS_SEND1];
5260 a_perfP->rx_packetsRead_SpecialClass =
5261 (afs_int32) stats->packetsRead[RX_PACKET_CLASS_SPECIAL2];
5262 a_perfP->rx_dataPacketsRead = (afs_int32) stats->dataPacketsRead;
5263 a_perfP->rx_ackPacketsRead = (afs_int32) stats->ackPacketsRead;
5264 a_perfP->rx_dupPacketsRead = (afs_int32) stats->dupPacketsRead;
5265 a_perfP->rx_spuriousPacketsRead =
5266 (afs_int32) stats->spuriousPacketsRead;
5267 a_perfP->rx_packetsSent_RcvClass =
5268 (afs_int32) stats->packetsSent[RX_PACKET_CLASS_RECEIVE0];
5269 a_perfP->rx_packetsSent_SendClass =
5270 (afs_int32) stats->packetsSent[RX_PACKET_CLASS_SEND1];
5271 a_perfP->rx_packetsSent_SpecialClass =
5272 (afs_int32) stats->packetsSent[RX_PACKET_CLASS_SPECIAL2];
5273 a_perfP->rx_ackPacketsSent = (afs_int32) stats->ackPacketsSent;
5274 a_perfP->rx_pingPacketsSent = (afs_int32) stats->pingPacketsSent;
5275 a_perfP->rx_abortPacketsSent = (afs_int32) stats->abortPacketsSent;
5276 a_perfP->rx_busyPacketsSent = (afs_int32) stats->busyPacketsSent;
5277 a_perfP->rx_dataPacketsSent = (afs_int32) stats->dataPacketsSent;
5278 a_perfP->rx_dataPacketsReSent = (afs_int32) stats->dataPacketsReSent;
5279 a_perfP->rx_dataPacketsPushed = (afs_int32) stats->dataPacketsPushed;
5280 a_perfP->rx_ignoreAckedPacket = (afs_int32) stats->ignoreAckedPacket;
5281 a_perfP->rx_totalRtt_Sec = (afs_int32) stats->totalRtt.sec;
5282 a_perfP->rx_totalRtt_Usec = (afs_int32) stats->totalRtt.usec;
5283 a_perfP->rx_minRtt_Sec = (afs_int32) stats->minRtt.sec;
5284 a_perfP->rx_minRtt_Usec = (afs_int32) stats->minRtt.usec;
5285 a_perfP->rx_maxRtt_Sec = (afs_int32) stats->maxRtt.sec;
5286 a_perfP->rx_maxRtt_Usec = (afs_int32) stats->maxRtt.usec;
5287 a_perfP->rx_nRttSamples = (afs_int32) stats->nRttSamples;
5288 a_perfP->rx_nServerConns = (afs_int32) stats->nServerConns;
5289 a_perfP->rx_nClientConns = (afs_int32) stats->nClientConns;
5290 a_perfP->rx_nPeerStructs = (afs_int32) stats->nPeerStructs;
5291 a_perfP->rx_nCallStructs = (afs_int32) stats->nCallStructs;
5292 a_perfP->rx_nFreeCallStructs = (afs_int32) stats->nFreeCallStructs;
5293
5294 a_perfP->host_NumHostEntries = HTs;
5295 a_perfP->host_HostBlocks = HTBlocks;
5296 h_GetHostNetStats(&(a_perfP->host_NonDeletedHosts),
5297 &(a_perfP->host_HostsInSameNetOrSubnet),
5298 &(a_perfP->host_HostsInDiffSubnet),
5299 &(a_perfP->host_HostsInDiffNetwork));
5300 a_perfP->host_NumClients = CEs;
5301 a_perfP->host_ClientBlocks = CEBlocks;
5302
5303 a_perfP->sysname_ID = afs_perfstats.sysname_ID;
5304 a_perfP->rx_nBusies = (afs_int32) stats->nBusies;
5305 a_perfP->fs_nBusies = afs_perfstats.fs_nBusies;
5306 rx_FreeStatistics(&stats);
5307} /*FillPerfValues */
5308
5309
5310/*------------------------------------------------------------------------
5311 * EXPORTED SRXAFS_GetXStats
5312 *
5313 * Description:
5314 * Routine called by the server-side callback RPC interface to
5315 * implement getting the given data collection from the extended
5316 * File Server statistics.
5317 *
5318 * Arguments:
5319 * a_call : Ptr to Rx call on which this request came in.
5320 * a_clientVersionNum : Client version number.
5321 * a_opCode : Desired operation.
5322 * a_serverVersionNumP : Ptr to version number to set.
5323 * a_timeP : Ptr to time value (seconds) to set.
5324 * a_dataP : Ptr to variable array structure to return
5325 * stuff in.
5326 *
5327 * Returns:
5328 * 0 (always).
5329 *
5330 * Environment:
5331 * Nothing interesting.
5332 *
5333 * Side Effects:
5334 * As advertised.
5335 *------------------------------------------------------------------------*/
5336
5337afs_int32
5338SRXAFS_GetXStats(struct rx_call *a_call, afs_int32 a_clientVersionNum,
5339 afs_int32 a_collectionNumber, afs_int32 * a_srvVersionNumP,
5340 afs_int32 * a_timeP, AFS_CollData * a_dataP)
5341{ /*SRXAFS_GetXStats */
5342
5343 int code; /*Return value */
5344 afs_int32 *dataBuffP; /*Ptr to data to be returned */
5345 afs_int32 dataBytes; /*Bytes in data buffer */
5346 struct fsstats fsstats;
5347
5348 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETXSTATS27);
5349
5350 /*
5351 * Record the time of day and the server version number.
5352 */
5353 *a_srvVersionNumP = AFS_XSTAT_VERSION2;
5354 *a_timeP = FT_ApproxTime();
5355
5356 /*
5357 * Stuff the appropriate data in there (assume victory)
5358 */
5359 code = 0;
5360
5361 ViceLog(1,do { if ((1) <= LogLevel) (FSLog ("Received GetXStats call for collection %d\n"
, a_collectionNumber)); } while (0)
5362 ("Received GetXStats call for collection %d\n",do { if ((1) <= LogLevel) (FSLog ("Received GetXStats call for collection %d\n"
, a_collectionNumber)); } while (0)
5363 a_collectionNumber))do { if ((1) <= LogLevel) (FSLog ("Received GetXStats call for collection %d\n"
, a_collectionNumber)); } while (0)
;
5364
5365#if 0
5366 /*
5367 * We're not keeping stats, so just return successfully with
5368 * no data.
5369 */
5370 a_dataP->AFS_CollData_len = 0;
5371 a_dataP->AFS_CollData_val = NULL((void *)0);
5372#endif /* 0 */
5373
5374 switch (a_collectionNumber) {
5375 case AFS_XSTATSCOLL_CALL_INFO0:
5376 /*
5377 * Pass back all the call-count-related data.
5378 *
5379 * >>> We are forced to allocate a separate area in which to
5380 * >>> put this stuff in by the RPC stub generator, since it
5381 * >>> will be freed at the tail end of the server stub code.
5382 */
5383#if 0
5384 /*
5385 * I don't think call-level stats are being collected yet
5386 * for the File Server.
5387 */
5388 dataBytes = sizeof(struct afs_Stats);
5389 dataBuffP = (afs_int32 *) malloc(dataBytes);
5390 memcpy(dataBuffP, &afs_cmstats, dataBytes);
5391 a_dataP->AFS_CollData_len = dataBytes >> 2;
5392 a_dataP->AFS_CollData_val = dataBuffP;
5393#else
5394 a_dataP->AFS_CollData_len = 0;
5395 a_dataP->AFS_CollData_val = NULL((void *)0);
5396#endif /* 0 */
5397 break;
5398
5399 case AFS_XSTATSCOLL_PERF_INFO1:
5400 /*
5401 * Pass back all the regular performance-related data.
5402 *
5403 * >>> We are forced to allocate a separate area in which to
5404 * >>> put this stuff in by the RPC stub generator, since it
5405 * >>> will be freed at the tail end of the server stub code.
5406 */
5407
5408 afs_perfstats.numPerfCalls++;
5409 FillPerfValues(&afs_perfstats);
5410
5411 /*
5412 * Don't overwrite the spares at the end.
5413 */
5414
5415 dataBytes = sizeof(struct afs_PerfStats);
5416 dataBuffP = (afs_int32 *) malloc(dataBytes);
5417 memcpy(dataBuffP, &afs_perfstats, dataBytes);
5418 a_dataP->AFS_CollData_len = dataBytes >> 2;
5419 a_dataP->AFS_CollData_val = dataBuffP;
5420 break;
5421
5422 case AFS_XSTATSCOLL_FULL_PERF_INFO2:
5423 /*
5424 * Pass back the full collection of performance-related data.
5425 * We have to stuff the basic, overall numbers in, but the
5426 * detailed numbers are kept in the structure already.
5427 *
5428 * >>> We are forced to allocate a separate area in which to
5429 * >>> put this stuff in by the RPC stub generator, since it
5430 * >>> will be freed at the tail end of the server stub code.
5431 */
5432
5433 afs_perfstats.numPerfCalls++;
5434#if FS_STATS_DETAILED1
5435 afs_FullPerfStats.overall.numPerfCalls = afs_perfstats.numPerfCalls;
5436 FillPerfValues(&afs_FullPerfStats.overall);
5437
5438 /*
5439 * Don't overwrite the spares at the end.
5440 */
5441
5442 dataBytes = sizeof(struct fs_stats_FullPerfStats);
5443 dataBuffP = (afs_int32 *) malloc(dataBytes);
5444 memcpy(dataBuffP, &afs_FullPerfStats, dataBytes);
5445 a_dataP->AFS_CollData_len = dataBytes >> 2;
5446 a_dataP->AFS_CollData_val = dataBuffP;
5447#endif
5448 break;
5449
5450 case AFS_XSTATSCOLL_CBSTATS3:
5451 afs_perfstats.numPerfCalls++;
5452
5453 dataBytes = sizeof(struct cbcounters);
5454 dataBuffP = (afs_int32 *) malloc(dataBytes);
5455 {
5456 extern struct cbcounters cbstuff;
5457 dataBuffP[0]=cbstuff.DeleteFiles;
5458 dataBuffP[1]=cbstuff.DeleteCallBacks;
5459 dataBuffP[2]=cbstuff.BreakCallBacks;
5460 dataBuffP[3]=cbstuff.AddCallBacks;
5461 dataBuffP[4]=cbstuff.GotSomeSpaces;
5462 dataBuffP[5]=cbstuff.DeleteAllCallBacks;
5463 dataBuffP[6]=cbstuff.nFEs;
5464 dataBuffP[7]=cbstuff.nCBs;
5465 dataBuffP[8]=cbstuff.nblks;
5466 dataBuffP[9]=cbstuff.CBsTimedOut;
5467 dataBuffP[10]=cbstuff.nbreakers;
5468 dataBuffP[11]=cbstuff.GSS1;
5469 dataBuffP[12]=cbstuff.GSS2;
5470 dataBuffP[13]=cbstuff.GSS3;
5471 dataBuffP[14]=cbstuff.GSS4;
5472 dataBuffP[15]=cbstuff.GSS5;
5473 }
5474
5475 a_dataP->AFS_CollData_len = dataBytes >> 2;
5476 a_dataP->AFS_CollData_val = dataBuffP;
5477 break;
5478
5479
5480 default:
5481 /*
5482 * Illegal collection number.
5483 */
5484 a_dataP->AFS_CollData_len = 0;
5485 a_dataP->AFS_CollData_val = NULL((void *)0);
5486 code = 1;
5487 } /*Switch on collection number */
5488
5489 fsstats_FinishOp(&fsstats, code);
5490
5491 return (code);
5492
5493} /*SRXAFS_GetXStats */
5494
5495
5496static afs_int32
5497common_GiveUpCallBacks(struct rx_call *acall, struct AFSCBFids *FidArray,
5498 struct AFSCBs *CallBackArray)
5499{
5500 afs_int32 errorCode = 0;
5501 int i;
5502 struct client *client = 0;
5503 struct rx_connection *tcon;
5504 struct host *thost;
5505 struct fsstats fsstats;
5506
5507 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GIVEUPCALLBACKS17);
5508
5509 if (FidArray)
5510 ViceLog(1,do { if ((1) <= LogLevel) (FSLog ("SAFS_GiveUpCallBacks (Noffids=%d)\n"
, FidArray->AFSCBFids_len)); } while (0)
5511 ("SAFS_GiveUpCallBacks (Noffids=%d)\n",do { if ((1) <= LogLevel) (FSLog ("SAFS_GiveUpCallBacks (Noffids=%d)\n"
, FidArray->AFSCBFids_len)); } while (0)
5512 FidArray->AFSCBFids_len))do { if ((1) <= LogLevel) (FSLog ("SAFS_GiveUpCallBacks (Noffids=%d)\n"
, FidArray->AFSCBFids_len)); } while (0)
;
5513
5514 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 5514), 0));
;
5515 AFSCallStats.GiveUpCallBacks++, AFSCallStats.TotalCalls++;
5516 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 5516), 0));
;
5517 if ((errorCode = CallPreamble(acall, ACTIVECALL1, &tcon, &thost)))
5518 goto Bad_GiveUpCallBacks;
5519
5520 if (!FidArray && !CallBackArray) {
5521 ViceLog(1,do { if ((1) <= LogLevel) (FSLog ("SAFS_GiveUpAllCallBacks: host=%x\n"
, (tcon->peer ? tcon->peer->host : 0))); } while (0)
5522 ("SAFS_GiveUpAllCallBacks: host=%x\n",do { if ((1) <= LogLevel) (FSLog ("SAFS_GiveUpAllCallBacks: host=%x\n"
, (tcon->peer ? tcon->peer->host : 0))); } while (0)
5523 (tcon->peer ? tcon->peer->host : 0)))do { if ((1) <= LogLevel) (FSLog ("SAFS_GiveUpAllCallBacks: host=%x\n"
, (tcon->peer ? tcon->peer->host : 0))); } while (0)
;
5524 errorCode = GetClient(tcon, &client);
5525 if (!errorCode) {
5526 H_LOCK(void)((pthread_mutex_lock(&host_glock_mutex) == 0) || (osi_AssertFailU
("pthread_mutex_lock(&host_glock_mutex) == 0", "./../viced/afsfileprocs.c"
, 5526), 0));
;
5527 DeleteAllCallBacks_r(client->host, 1);
5528 H_UNLOCK(void)((pthread_mutex_unlock(&host_glock_mutex) == 0) || (
osi_AssertFailU("pthread_mutex_unlock(&host_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 5528), 0));
;
5529 PutClient(&client);
5530 }
5531 } else {
5532 if (FidArray->AFSCBFids_len < CallBackArray->AFSCBs_len) {
5533 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("GiveUpCallBacks: #Fids %d < #CallBacks %d, host=%x\n"
, FidArray->AFSCBFids_len, CallBackArray->AFSCBs_len, (
tcon->peer ? tcon->peer->host : 0))); } while (0)
5534 ("GiveUpCallBacks: #Fids %d < #CallBacks %d, host=%x\n",do { if ((0) <= LogLevel) (FSLog ("GiveUpCallBacks: #Fids %d < #CallBacks %d, host=%x\n"
, FidArray->AFSCBFids_len, CallBackArray->AFSCBs_len, (
tcon->peer ? tcon->peer->host : 0))); } while (0)
5535 FidArray->AFSCBFids_len, CallBackArray->AFSCBs_len,do { if ((0) <= LogLevel) (FSLog ("GiveUpCallBacks: #Fids %d < #CallBacks %d, host=%x\n"
, FidArray->AFSCBFids_len, CallBackArray->AFSCBs_len, (
tcon->peer ? tcon->peer->host : 0))); } while (0)
5536 (tcon->peer ? tcon->peer->host : 0)))do { if ((0) <= LogLevel) (FSLog ("GiveUpCallBacks: #Fids %d < #CallBacks %d, host=%x\n"
, FidArray->AFSCBFids_len, CallBackArray->AFSCBs_len, (
tcon->peer ? tcon->peer->host : 0))); } while (0)
;
5537 errorCode = EINVAL22;
5538 goto Bad_GiveUpCallBacks;
5539 }
5540
5541 errorCode = GetClient(tcon, &client);
5542 if (!errorCode) {
5543 for (i = 0; i < FidArray->AFSCBFids_len; i++) {
5544 struct AFSFid *fid = &(FidArray->AFSCBFids_val[i]);
5545 DeleteCallBack(client->host, fid);
5546 }
5547 PutClient(&client);
5548 }
5549 }
5550
5551 Bad_GiveUpCallBacks:
5552 errorCode = CallPostamble(tcon, errorCode, thost);
5553
5554 fsstats_FinishOp(&fsstats, errorCode);
5555
5556 return errorCode;
5557
5558} /*common_GiveUpCallBacks */
5559
5560
5561afs_int32
5562SRXAFS_GiveUpCallBacks(struct rx_call * acall, struct AFSCBFids * FidArray,
5563 struct AFSCBs * CallBackArray)
5564{
5565 return common_GiveUpCallBacks(acall, FidArray, CallBackArray);
5566} /*SRXAFS_GiveUpCallBacks */
5567
5568afs_int32
5569SRXAFS_GiveUpAllCallBacks(struct rx_call * acall)
5570{
5571 return common_GiveUpCallBacks(acall, 0, 0);
5572} /*SRXAFS_GiveUpAllCallBacks */
5573
5574
5575afs_int32
5576SRXAFS_NGetVolumeInfo(struct rx_call * acall, char *avolid,
5577 struct AFSVolumeInfo * avolinfo)
5578{
5579 return (VNOVOL103); /* XXX Obsolete routine XXX */
5580
5581} /*SRXAFS_NGetVolumeInfo */
5582
5583
5584/*
5585 * Dummy routine. Should never be called (the cache manager should only
5586 * invoke this interface when communicating with a AFS/DFS Protocol
5587 * Translator).
5588 */
5589afs_int32
5590SRXAFS_Lookup(struct rx_call * call_p, struct AFSFid * afs_dfid_p,
5591 char *afs_name_p, struct AFSFid * afs_fid_p,
5592 struct AFSFetchStatus * afs_status_p,
5593 struct AFSFetchStatus * afs_dir_status_p,
5594 struct AFSCallBack * afs_callback_p,
5595 struct AFSVolSync * afs_sync_p)
5596{
5597 return EINVAL22;
5598}
5599
5600
5601afs_int32
5602SRXAFS_GetCapabilities(struct rx_call * acall, Capabilities * capabilities)
5603{
5604 afs_int32 code;
5605 struct rx_connection *tcon;
5606 struct host *thost;
5607 afs_uint32 *dataBuffP;
5608 afs_int32 dataBytes;
5609
5610 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 5610), 0));
;
5611 AFSCallStats.GetCapabilities++, AFSCallStats.TotalCalls++;
5612 afs_FullPerfStats.overall.fs_nGetCaps++;
5613 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 5613), 0));
;
5614 ViceLog(2, ("SAFS_GetCapabilties\n"))do { if ((2) <= LogLevel) (FSLog ("SAFS_GetCapabilties\n")
); } while (0)
;
5615
5616 if ((code = CallPreamble(acall, NOTACTIVECALL0, &tcon, &thost)))
5617 goto Bad_GetCaps;
5618
5619 dataBytes = 1 * sizeof(afs_int32);
5620 dataBuffP = (afs_uint32 *) malloc(dataBytes);
5621 dataBuffP[0] = VICED_CAPABILITY_ERRORTRANS0x0001 | VICED_CAPABILITY_WRITELOCKACL0x0004;
5622 dataBuffP[0] |= VICED_CAPABILITY_64BITFILES0x0002;
5623 if (saneacls)
5624 dataBuffP[0] |= VICED_CAPABILITY_SANEACLS0x0008;
5625
5626 capabilities->Capabilities_len = dataBytes / sizeof(afs_int32);
5627 capabilities->Capabilities_val = dataBuffP;
5628
5629 Bad_GetCaps:
5630 code = CallPostamble(tcon, code, thost);
5631
5632
5633 return 0;
5634}
5635
5636afs_int32
5637SRXAFS_FlushCPS(struct rx_call * acall, struct ViceIds * vids,
5638 struct IPAddrs * addrs, afs_int32 spare1, afs_int32 * spare2,
5639 afs_int32 * spare3)
5640{
5641 int i;
5642 afs_int32 nids, naddrs;
5643 afs_int32 *vd, *addr;
5644 Errorbit32 errorCode = 0; /* return code to caller */
5645 struct client *client = 0;
5646
5647 ViceLog(1, ("SRXAFS_FlushCPS\n"))do { if ((1) <= LogLevel) (FSLog ("SRXAFS_FlushCPS\n")); }
while (0)
;
5648 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 5648), 0));
;
5649 AFSCallStats.TotalCalls++;
5650 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 5650), 0));
;
5651 nids = vids->ViceIds_len; /* # of users in here */
5652 naddrs = addrs->IPAddrs_len; /* # of hosts in here */
5653 if (nids < 0 || naddrs < 0) {
5654 errorCode = EINVAL22;
5655 goto Bad_FlushCPS;
5656 }
5657
5658 vd = vids->ViceIds_val;
5659 for (i = 0; i < nids; i++, vd++) {
5660 if (!*vd)
5661 continue;
5662 client = h_ID2Client(*vd); /* returns write locked and refCounted, or NULL */
5663 if (!client)
5664 continue;
5665
5666 client->prfail = 2; /* Means re-eval client's cps */
5667#ifdef notdef
5668 if (client->tcon) {
5669 rx_SetRock(((struct rx_connection *)client->tcon), 0);
5670 }
5671#endif
5672 if ((client->ViceId != ANONYMOUSID32766) && client->CPS.prlist_val) {
5673 free(client->CPS.prlist_val);
5674 client->CPS.prlist_val = NULL((void *)0);
5675 client->CPS.prlist_len = 0;
5676 }
5677 ReleaseWriteLock(&client->lock)do { (void)((pthread_mutex_lock(&(&client->lock)->
mutex) == 0) || (osi_AssertFailU("pthread_mutex_lock(&(&client->lock)->mutex) == 0"
, "./../viced/afsfileprocs.c", 5677), 0));; (&client->
lock)->excl_locked &= ~2; if ((&client->lock)->
wait_states) Afs_Lock_ReleaseR(&client->lock); (void)(
(pthread_mutex_unlock(&(&client->lock)->mutex) ==
0) || (osi_AssertFailU("pthread_mutex_unlock(&(&client->lock)->mutex) == 0"
, "./../viced/afsfileprocs.c", 5677), 0));; } while (0)
;
5678 PutClient(&client);
5679 }
5680
5681 addr = addrs->IPAddrs_val;
5682 for (i = 0; i < naddrs; i++, addr++) {
5683 if (*addr)
5684 h_flushhostcps(*addr, htons(7001)(__builtin_constant_p(7001) ? (__uint16_t)(((__uint16_t)(7001
)) << 8 | ((__uint16_t)(7001)) >> 8) : __bswap16_var
(7001))
);
5685 }
5686
5687 Bad_FlushCPS:
5688 ViceLog(2, ("SAFS_FlushCPS returns %d\n", errorCode))do { if ((2) <= LogLevel) (FSLog ("SAFS_FlushCPS returns %d\n"
, errorCode)); } while (0)
;
5689 return errorCode;
5690} /*SRXAFS_FlushCPS */
5691
5692/* worthless hack to let CS keep running ancient software */
5693static int
5694afs_vtoi(char *aname)
5695{
5696 afs_int32 temp;
5697 int tc;
5698
5699 temp = 0;
5700 while ((tc = *aname++)) {
5701 if (tc > '9' || tc < '0')
5702 return 0; /* invalid name */
5703 temp *= 10;
5704 temp += tc - '0';
5705 }
5706 return temp;
5707}
5708
5709/*
5710 * may get name or #, but must handle all weird cases (recognize readonly
5711 * or backup volumes by name or #
5712 */
5713static afs_int32
5714CopyVolumeEntry(char *aname, struct vldbentry *ave,
5715 struct VolumeInfo *av)
5716{
5717 int i, j, vol;
5718 afs_int32 mask, whichType;
5719 afs_uint32 *serverHost, *typePtr;
5720
5721 /* figure out what type we want if by name */
5722 i = strlen(aname);
5723 if (i >= 8 && strcmp(aname + i - 7, ".backup") == 0)
5724 whichType = BACKVOL2;
5725 else if (i >= 10 && strcmp(aname + i - 9, ".readonly") == 0)
5726 whichType = ROVOL1;
5727 else
5728 whichType = RWVOL0;
5729
5730 vol = afs_vtoi(aname);
5731 if (vol == 0)
5732 vol = ave->volumeId[whichType];
5733
5734 /*
5735 * Now vol has volume # we're interested in. Next, figure out the type
5736 * of the volume by looking finding it in the vldb entry
5737 */
5738 if ((ave->flags & VLF_RWEXISTS0x1000) && vol == ave->volumeId[RWVOL0]) {
5739 mask = VLSF_RWVOL0x04;
5740 whichType = RWVOL0;
5741 } else if ((ave->flags & VLF_ROEXISTS0x2000) && vol == ave->volumeId[ROVOL1]) {
5742 mask = VLSF_ROVOL0x02;
5743 whichType = ROVOL1;
5744 } else if ((ave->flags & VLF_BACKEXISTS0x4000) && vol == ave->volumeId[BACKVOL2]) {
5745 mask = VLSF_RWVOL0x04; /* backup always is on the same volume as parent */
5746 whichType = BACKVOL2;
5747 } else
5748 return EINVAL22; /* error: can't find volume in vldb entry */
5749
5750 typePtr = &av->Type0;
5751 serverHost = &av->Server0;
5752 av->Vid = vol;
5753 av->Type = whichType;
5754 av->Type0 = av->Type1 = av->Type2 = av->Type3 = av->Type4 = 0;
5755 if (ave->flags & VLF_RWEXISTS0x1000)
5756 typePtr[RWVOL0] = ave->volumeId[RWVOL0];
5757 if (ave->flags & VLF_ROEXISTS0x2000)
5758 typePtr[ROVOL1] = ave->volumeId[ROVOL1];
5759 if (ave->flags & VLF_BACKEXISTS0x4000)
5760 typePtr[BACKVOL2] = ave->volumeId[BACKVOL2];
5761
5762 for (i = 0, j = 0; i < ave->nServers; i++) {
5763 if ((ave->serverFlags[i] & mask) == 0)
5764 continue; /* wrong volume */
5765 serverHost[j] = ave->serverNumber[i];
5766 j++;
5767 }
5768 av->ServerCount = j;
5769 if (j < 8)
5770 serverHost[j++] = 0; /* bogus 8, but compat only now */
5771 return 0;
5772}
5773
5774static afs_int32
5775TryLocalVLServer(char *avolid, struct VolumeInfo *avolinfo)
5776{
5777 static struct rx_connection *vlConn = 0;
5778 static int down = 0;
5779 static afs_int32 lastDownTime = 0;
5780 struct vldbentry tve;
5781 struct rx_securityClass *vlSec;
5782 afs_int32 code;
5783
5784 if (!vlConn) {
5785 vlSec = rxnull_NewClientSecurityObject();
5786 vlConn =
5787 rx_NewConnection(htonl(0x7f000001)(__builtin_constant_p(0x7f000001) ? ((((__uint32_t)(0x7f000001
)) >> 24) | ((((__uint32_t)(0x7f000001)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(0x7f000001)) & (0xff <<
8)) << 8) | (((__uint32_t)(0x7f000001)) << 24)) :
__bswap32_var(0x7f000001))
, htons(7003)(__builtin_constant_p(7003) ? (__uint16_t)(((__uint16_t)(7003
)) << 8 | ((__uint16_t)(7003)) >> 8) : __bswap16_var
(7003))
, 52, vlSec, 0);
5788 rx_SetConnDeadTime(vlConn, 15); /* don't wait long */
5789 }
5790 if (down && (FT_ApproxTime() < lastDownTime + 180)) {
5791 return 1; /* failure */
5792 }
5793
5794 code = VL_GetEntryByNameO(vlConn, avolid, &tve);
5795 if (code >= 0)
5796 down = 0; /* call worked */
5797 if (code) {
5798 if (code < 0) {
5799 lastDownTime = FT_ApproxTime(); /* last time we tried an RPC */
5800 down = 1;
5801 }
5802 return code;
5803 }
5804
5805 /* otherwise convert to old format vldb entry */
5806 code = CopyVolumeEntry(avolid, &tve, avolinfo);
5807 return code;
5808}
5809
5810
5811
5812
5813
5814
5815afs_int32
5816SRXAFS_GetVolumeInfo(struct rx_call * acall, char *avolid,
5817 struct VolumeInfo * avolinfo)
5818{
5819 afs_int32 code;
5820 struct rx_connection *tcon;
5821 struct host *thost;
5822 struct fsstats fsstats;
5823
5824 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETVOLUMEINFO18);
5825
5826 if ((code = CallPreamble(acall, ACTIVECALL1, &tcon, &thost)))
5827 goto Bad_GetVolumeInfo;
5828
5829 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 5829), 0));
;
5830 AFSCallStats.GetVolumeInfo++, AFSCallStats.TotalCalls++;
5831 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 5831), 0));
;
5832 code = TryLocalVLServer(avolid, avolinfo);
5833 ViceLog(1,do { if ((1) <= LogLevel) (FSLog ("SAFS_GetVolumeInfo returns %d, Volume %u, type %x, servers %x %x %x %x...\n"
, code, avolinfo->Vid, avolinfo->Type, avolinfo->Server0
, avolinfo->Server1, avolinfo->Server2, avolinfo->Server3
)); } while (0)
5834 ("SAFS_GetVolumeInfo returns %d, Volume %u, type %x, servers %x %x %x %x...\n",do { if ((1) <= LogLevel) (FSLog ("SAFS_GetVolumeInfo returns %d, Volume %u, type %x, servers %x %x %x %x...\n"
, code, avolinfo->Vid, avolinfo->Type, avolinfo->Server0
, avolinfo->Server1, avolinfo->Server2, avolinfo->Server3
)); } while (0)
5835 code, avolinfo->Vid, avolinfo->Type, avolinfo->Server0,do { if ((1) <= LogLevel) (FSLog ("SAFS_GetVolumeInfo returns %d, Volume %u, type %x, servers %x %x %x %x...\n"
, code, avolinfo->Vid, avolinfo->Type, avolinfo->Server0
, avolinfo->Server1, avolinfo->Server2, avolinfo->Server3
)); } while (0)
5836 avolinfo->Server1, avolinfo->Server2, avolinfo->Server3))do { if ((1) <= LogLevel) (FSLog ("SAFS_GetVolumeInfo returns %d, Volume %u, type %x, servers %x %x %x %x...\n"
, code, avolinfo->Vid, avolinfo->Type, avolinfo->Server0
, avolinfo->Server1, avolinfo->Server2, avolinfo->Server3
)); } while (0)
;
5837 avolinfo->Type4 = 0xabcd9999; /* tell us to try new vldb */
5838
5839 Bad_GetVolumeInfo:
5840 code = CallPostamble(tcon, code, thost);
5841
5842 fsstats_FinishOp(&fsstats, code);
5843
5844 return code;
5845
5846} /*SRXAFS_GetVolumeInfo */
5847
5848
5849afs_int32
5850SRXAFS_GetVolumeStatus(struct rx_call * acall, afs_int32 avolid,
5851 AFSFetchVolumeStatus * FetchVolStatus, char **Name,
5852 char **OfflineMsg, char **Motd)
5853{
5854 Vnode *targetptr = 0; /* vnode of the new file */
5855 Vnode *parentwhentargetnotdir = 0; /* vnode of parent */
5856 Errorbit32 errorCode = 0; /* error code */
5857 Volume *volptr = 0; /* pointer to the volume header */
5858 struct client *client = 0; /* pointer to client entry */
5859 afs_int32 rights, anyrights; /* rights for this and any user */
5860 AFSFid dummyFid;
5861 struct rx_connection *tcon;
5862 struct host *thost;
5863 struct client *t_client = NULL((void *)0); /* tmp ptr to client data */
5864 struct fsstats fsstats;
5865
5866 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETVOLUMESTATUS19);
5867
5868 ViceLog(1, ("SAFS_GetVolumeStatus for volume %u\n", avolid))do { if ((1) <= LogLevel) (FSLog ("SAFS_GetVolumeStatus for volume %u\n"
, avolid)); } while (0)
;
5869 if ((errorCode = CallPreamble(acall, ACTIVECALL1, &tcon, &thost)))
5870 goto Bad_GetVolumeStatus;
5871
5872 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 5872), 0));
;
5873 AFSCallStats.GetVolumeStatus++, AFSCallStats.TotalCalls++;
5874 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 5874), 0));
;
5875 if (avolid == 0) {
5876 errorCode = EINVAL22;
5877 goto Bad_GetVolumeStatus;
5878 }
5879 dummyFid.Volume = avolid, dummyFid.Vnode =
5880 (afs_int32) ROOTVNODE1, dummyFid.Unique = 1;
5881
5882 if ((errorCode =
5883 GetVolumePackage(tcon, &dummyFid, &volptr, &targetptr, MustBeDIR2,
5884 &parentwhentargetnotdir, &client, READ_LOCK1,
5885 &rights, &anyrights)))
5886 goto Bad_GetVolumeStatus;
5887
5888 if ((VanillaUser(client)) && (!(rights & PRSFS_READ1))) {
5889 errorCode = EACCES13;
5890 goto Bad_GetVolumeStatus;
5891 }
5892 (void)RXGetVolumeStatus(FetchVolStatus, Name, OfflineMsg, Motd, volptr);
5893
5894 Bad_GetVolumeStatus:
5895 (void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
5896 volptr, &client);
5897 ViceLog(2, ("SAFS_GetVolumeStatus returns %d\n", errorCode))do { if ((2) <= LogLevel) (FSLog ("SAFS_GetVolumeStatus returns %d\n"
, errorCode)); } while (0)
;
5898 /* next is to guarantee out strings exist for stub */
5899 if (*Name == 0) {
5900 *Name = (char *)malloc(1);
5901 **Name = 0;
5902 }
5903 if (*Motd == 0) {
5904 *Motd = (char *)malloc(1);
5905 **Motd = 0;
5906 }
5907 if (*OfflineMsg == 0) {
5908 *OfflineMsg = (char *)malloc(1);
5909 **OfflineMsg = 0;
5910 }
5911 errorCode = CallPostamble(tcon, errorCode, thost);
5912
5913 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
5914
5915 fsstats_FinishOp(&fsstats, errorCode);
5916
5917 osi_auditU(acall, GetVolumeStatusEvent"AFS_SRX_GetVolS", errorCode,
5918 AUD_ID10, t_client ? t_client->ViceId : 0,
5919 AUD_LONG5, avolid, AUD_STR1, *Name, AUD_END0);
5920 return (errorCode);
5921
5922} /*SRXAFS_GetVolumeStatus */
5923
5924
5925afs_int32
5926SRXAFS_SetVolumeStatus(struct rx_call * acall, afs_int32 avolid,
5927 AFSStoreVolumeStatus * StoreVolStatus, char *Name,
5928 char *OfflineMsg, char *Motd)
5929{
5930 Vnode *targetptr = 0; /* vnode of the new file */
5931 Vnode *parentwhentargetnotdir = 0; /* vnode of parent */
5932 Errorbit32 errorCode = 0; /* error code */
5933 Volume *volptr = 0; /* pointer to the volume header */
5934 struct client *client = 0; /* pointer to client entry */
5935 afs_int32 rights, anyrights; /* rights for this and any user */
5936 AFSFid dummyFid;
5937 struct rx_connection *tcon = rx_ConnectionOf(acall)((acall)->conn);
5938 struct host *thost;
5939 struct client *t_client = NULL((void *)0); /* tmp ptr to client data */
5940 struct fsstats fsstats;
5941
5942 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_SETVOLUMESTATUS20);
5943
5944 ViceLog(1, ("SAFS_SetVolumeStatus for volume %u\n", avolid))do { if ((1) <= LogLevel) (FSLog ("SAFS_SetVolumeStatus for volume %u\n"
, avolid)); } while (0)
;
5945 if ((errorCode = CallPreamble(acall, ACTIVECALL1, &tcon, &thost)))
5946 goto Bad_SetVolumeStatus;
5947
5948 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 5948), 0));
;
5949 AFSCallStats.SetVolumeStatus++, AFSCallStats.TotalCalls++;
5950 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 5950), 0));
;
5951 if (avolid == 0) {
5952 errorCode = EINVAL22;
5953 goto Bad_SetVolumeStatus;
5954 }
5955 dummyFid.Volume = avolid, dummyFid.Vnode =
5956 (afs_int32) ROOTVNODE1, dummyFid.Unique = 1;
5957
5958 if ((errorCode =
5959 GetVolumePackage(tcon, &dummyFid, &volptr, &targetptr, MustBeDIR2,
5960 &parentwhentargetnotdir, &client, READ_LOCK1,
5961 &rights, &anyrights)))
5962 goto Bad_SetVolumeStatus;
5963
5964 if (readonlyServer) {
5965 errorCode = VREADONLY30;
5966 goto Bad_SetVolumeStatus;
5967 }
5968 if (VanillaUser(client)) {
5969 errorCode = EACCES13;
5970 goto Bad_SetVolumeStatus;
5971 }
5972
5973 errorCode =
5974 RXUpdate_VolumeStatus(volptr, StoreVolStatus, Name, OfflineMsg, Motd);
5975
5976 Bad_SetVolumeStatus:
5977 PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
5978 volptr, &client);
5979 ViceLog(2, ("SAFS_SetVolumeStatus returns %d\n", errorCode))do { if ((2) <= LogLevel) (FSLog ("SAFS_SetVolumeStatus returns %d\n"
, errorCode)); } while (0)
;
5980 errorCode = CallPostamble(tcon, errorCode, thost);
5981
5982 t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
5983
5984 fsstats_FinishOp(&fsstats, errorCode);
5985
5986 osi_auditU(acall, SetVolumeStatusEvent"AFS_SRX_SetVolS", errorCode,
5987 AUD_ID10, t_client ? t_client->ViceId : 0,
5988 AUD_LONG5, avolid, AUD_STR1, Name, AUD_END0);
5989 return (errorCode);
5990} /*SRXAFS_SetVolumeStatus */
5991
5992#define DEFAULTVOLUME"root.afs" "root.afs"
5993
5994afs_int32
5995SRXAFS_GetRootVolume(struct rx_call * acall, char **VolumeName)
5996{
5997#ifdef notdef
5998 int fd;
5999 int len;
6000 char *temp;
6001 struct rx_connection *tcon;
6002 struct host *thost;
6003 Errorbit32 errorCode = 0;
6004#endif
6005 struct fsstats fsstats;
6006
6007 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETROOTVOLUME21);
6008
6009 return FSERR_EOPNOTSUPP122;
6010
6011#ifdef notdef
6012 if (errorCode = CallPreamble(acall, ACTIVECALL1, &tcon, &thost))
6013 goto Bad_GetRootVolume;
6014 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 6014), 0));
;
6015 AFSCallStats.GetRootVolume++, AFSCallStats.TotalCalls++;
6016 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 6016), 0));
;
6017 temp = malloc(256);
6018 fd = afs_openopen(AFSDIR_SERVER_ROOTVOL_FILEPATHgetDirPath(AFSDIR_SERVER_ROOTVOL_FILEPATH_ID), O_RDONLY0x0000, 0666);
6019 if (fd <= 0)
6020 strcpy(temp, DEFAULTVOLUME"root.afs");
6021 else {
6022#if defined (AFS_AIX_ENV) || defined (AFS_HPUX_ENV)
6023 lockf(fd, F_LOCK1, 0);
6024#else
6025 flock(fd, LOCK_EX0x02);
6026#endif
6027 len = read(fd, temp, 256);
6028#if defined (AFS_AIX_ENV) || defined (AFS_HPUX_ENV)
6029 lockf(fd, F_ULOCK0, 0);
6030#else
6031 flock(fd, LOCK_UN0x08);
6032#endif
6033 close(fd);
6034 if (temp[len - 1] == '\n')
6035 len--;
6036 temp[len] = '\0';
6037 }
6038 *VolumeName = temp; /* freed by rx server-side stub */
6039
6040 Bad_GetRootVolume:
6041 errorCode = CallPostamble(tcon, errorCode, thost);
6042
6043 fsstats_FinishOp(&fsstats, errorCode);
6044
6045 return (errorCode);
6046#endif /* notdef */
6047
6048} /*SRXAFS_GetRootVolume */
6049
6050
6051/* still works because a struct CBS is the same as a struct AFSOpaque */
6052afs_int32
6053SRXAFS_CheckToken(struct rx_call * acall, afs_int32 AfsId,
6054 struct AFSOpaque * Token)
6055{
6056 afs_int32 code;
6057 struct rx_connection *tcon;
6058 struct host *thost;
6059 struct fsstats fsstats;
6060
6061 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_CHECKTOKEN22);
6062
6063 if ((code = CallPreamble(acall, ACTIVECALL1, &tcon, &thost)))
6064 goto Bad_CheckToken;
6065
6066 code = FSERR_ECONNREFUSED130;
6067
6068 Bad_CheckToken:
6069 code = CallPostamble(tcon, code, thost);
6070
6071 fsstats_FinishOp(&fsstats, code);
6072
6073 return code;
6074
6075} /*SRXAFS_CheckToken */
6076
6077afs_int32
6078SRXAFS_GetTime(struct rx_call * acall, afs_uint32 * Seconds,
6079 afs_uint32 * USeconds)
6080{
6081 afs_int32 code;
6082 struct rx_connection *tcon;
6083 struct host *thost;
6084 struct timeval tpl;
6085 struct fsstats fsstats;
6086
6087 fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETTIME23);
6088
6089 if ((code = CallPreamble(acall, NOTACTIVECALL0, &tcon, &thost)))
6090 goto Bad_GetTime;
6091
6092 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 6092), 0));
;
6093 AFSCallStats.GetTime++, AFSCallStats.TotalCalls++;
6094 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 6094), 0));
;
6095 FT_GetTimeOfDay(&tpl, 0);
6096 *Seconds = tpl.tv_sec;
6097 *USeconds = tpl.tv_usec;
6098
6099 ViceLog(2, ("SAFS_GetTime returns %u, %u\n", *Seconds, *USeconds))do { if ((2) <= LogLevel) (FSLog ("SAFS_GetTime returns %u, %u\n"
, *Seconds, *USeconds)); } while (0)
;
6100
6101 Bad_GetTime:
6102 code = CallPostamble(tcon, code, thost);
6103
6104 fsstats_FinishOp(&fsstats, code);
6105
6106 return code;
6107
6108} /*SRXAFS_GetTime */
6109
6110
6111/*
6112 * FetchData_RXStyle
6113 *
6114 * Purpose:
6115 * Implement a client's data fetch using Rx.
6116 *
6117 * Arguments:
6118 * volptr : Ptr to the given volume's info.
6119 * targetptr : Pointer to the vnode involved.
6120 * Call : Ptr to the Rx call involved.
6121 * Pos : Offset within the file.
6122 * Len : Length in bytes to read; this value is bogus!
6123 * a_bytesToFetchP : Set to the number of bytes to be fetched from
6124 * the File Server.
6125 * a_bytesFetchedP : Set to the actual number of bytes fetched from
6126 * the File Server.
6127 */
6128
6129static afs_int32
6130FetchData_RXStyle(Volume * volptr, Vnode * targetptr,
6131 struct rx_call * Call, afs_sfsize_t Pos,
6132 afs_sfsize_t Len, afs_int32 Int64Mode,
6133 afs_sfsize_t * a_bytesToFetchP,
6134 afs_sfsize_t * a_bytesFetchedP)
6135{
6136 struct timeval StartTime, StopTime; /* used to calculate file transfer rates */
6137 IHandle_t *ihP;
6138 FdHandle_t *fdP;
6139#ifndef HAVE_PIOV
6140 char *tbuffer;
6141#else /* HAVE_PIOV */
6142 struct iovec tiov[RX_MAXIOVECS16];
6143 int tnio;
6144#endif /* HAVE_PIOV */
6145 afs_sfsize_t tlen;
6146 afs_int32 optSize;
6147
6148 /*
6149 * Initialize the byte count arguments.
6150 */
6151 (*a_bytesToFetchP) = 0;
6152 (*a_bytesFetchedP) = 0;
6153
6154 ViceLog(25,do { if ((25) <= LogLevel) (FSLog ("FetchData_RXStyle: Pos %llu, Len %llu\n"
, (afs_uintmax_t) Pos, (afs_uintmax_t) Len)); } while (0)
6155 ("FetchData_RXStyle: Pos %llu, Len %llu\n", (afs_uintmax_t) Pos,do { if ((25) <= LogLevel) (FSLog ("FetchData_RXStyle: Pos %llu, Len %llu\n"
, (afs_uintmax_t) Pos, (afs_uintmax_t) Len)); } while (0)
6156 (afs_uintmax_t) Len))do { if ((25) <= LogLevel) (FSLog ("FetchData_RXStyle: Pos %llu, Len %llu\n"
, (afs_uintmax_t) Pos, (afs_uintmax_t) Len)); } while (0)
;
6157
6158 if (!VN_GET_INO(targetptr)((Inode)((targetptr)->disk.vn_ino_lo | ((targetptr)->disk
.vn_ino_hi ? (((Inode)(targetptr)->disk.vn_ino_hi)<<
32) : 0)))
) {
6159 afs_int32 zero = htonl(0)(__builtin_constant_p(0) ? ((((__uint32_t)(0)) >> 24) |
((((__uint32_t)(0)) & (0xff << 16)) >> 8) | (
(((__uint32_t)(0)) & (0xff << 8)) << 8) | (((
__uint32_t)(0)) << 24)) : __bswap32_var(0))
;
6160 /*
6161 * This is used for newly created files; we simply send 0 bytes
6162 * back to make the cache manager happy...
6163 */
6164 if (Int64Mode)
6165 rx_Write(Call, (char *)&zero, sizeof(afs_int32))rx_WriteProc(Call, (char *)&zero, sizeof(afs_int32)); /* send 0-length */
6166 rx_Write(Call, (char *)&zero, sizeof(afs_int32))rx_WriteProc(Call, (char *)&zero, sizeof(afs_int32)); /* send 0-length */
6167 return (0);
6168 }
6169 FT_GetTimeOfDay(&StartTime, 0);
6170 ihP = targetptr->handle;
6171 fdP = IH_OPEN(ihP)ih_open(ihP);
6172 if (fdP == NULL((void *)0)) {
6173 VTakeOffline(volptr);
6174 ViceLog(0, ("Volume %u now offline, must be salvaged.\n",do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
6175 volptr->hashid))do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
;
6176 return EIO5;
6177 }
6178 optSize = sendBufSize;
6179 tlen = FDH_SIZE(fdP)ih_size((fdP)->fd_fd);
6180 ViceLog(25,do { if ((25) <= LogLevel) (FSLog ("FetchData_RXStyle: file size %llu\n"
, (afs_uintmax_t) tlen)); } while (0)
6181 ("FetchData_RXStyle: file size %llu\n", (afs_uintmax_t) tlen))do { if ((25) <= LogLevel) (FSLog ("FetchData_RXStyle: file size %llu\n"
, (afs_uintmax_t) tlen)); } while (0)
;
6182 if (tlen < 0) {
6183 FDH_CLOSE(fdP)(fd_close(fdP), (fdP)=((void *)0), 0);
6184 VTakeOffline(volptr);
6185 ViceLog(0, ("Volume %u now offline, must be salvaged.\n",do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
6186 volptr->hashid))do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
;
6187 return EIO5;
6188 }
6189 if (CheckLength(volptr, targetptr, tlen)) {
6190 FDH_CLOSE(fdP)(fd_close(fdP), (fdP)=((void *)0), 0);
6191 VTakeOffline(volptr);
6192 return VSALVAGE101;
6193 }
6194 if (Pos > tlen) {
6195 Len = 0;
6196 }
6197
6198 if (Pos + Len > tlen) /* get length we should send */
6199 Len = ((tlen - Pos) < 0) ? 0 : tlen - Pos;
6200
6201 {
6202 afs_int32 high, low;
6203 SplitOffsetOrSize(Len, high, low)(high) = ((afs_int64)Len) >> 32; (low) = (Len) & 0xFFFFFFFF
;
;
6204 osi_Assert(Int64Mode || (Len >= 0 && high == 0) || Len < 0)(void)((Int64Mode || (Len >= 0 && high == 0) || Len
< 0) || (osi_AssertFailU("Int64Mode || (Len >= 0 && high == 0) || Len < 0"
, "./../viced/afsfileprocs.c", 6204), 0))
;
6205 if (Int64Mode) {
6206 high = htonl(high)(__builtin_constant_p(high) ? ((((__uint32_t)(high)) >>
24) | ((((__uint32_t)(high)) & (0xff << 16)) >>
8) | ((((__uint32_t)(high)) & (0xff << 8)) <<
8) | (((__uint32_t)(high)) << 24)) : __bswap32_var(high
))
;
6207 rx_Write(Call, (char *)&high, sizeof(afs_int32))rx_WriteProc(Call, (char *)&high, sizeof(afs_int32)); /* High order bits */
6208 }
6209 low = htonl(low)(__builtin_constant_p(low) ? ((((__uint32_t)(low)) >> 24
) | ((((__uint32_t)(low)) & (0xff << 16)) >> 8
) | ((((__uint32_t)(low)) & (0xff << 8)) << 8
) | (((__uint32_t)(low)) << 24)) : __bswap32_var(low))
;
6210 rx_Write(Call, (char *)&low, sizeof(afs_int32))rx_WriteProc(Call, (char *)&low, sizeof(afs_int32)); /* send length on fetch */
6211 }
6212 (*a_bytesToFetchP) = Len;
6213#ifndef HAVE_PIOV
6214 tbuffer = AllocSendBuffer();
6215#endif /* HAVE_PIOV */
6216 while (Len > 0) {
6217 size_t wlen;
6218 ssize_t nBytes;
6219 if (Len > optSize)
6220 wlen = optSize;
6221 else
6222 wlen = Len;
6223#ifndef HAVE_PIOV
6224 nBytes = FDH_PREAD(fdP, tbuffer, wlen, Pos)pread((fdP)->fd_fd, tbuffer, wlen, Pos);
6225 if (nBytes != wlen) {
6226 FDH_CLOSE(fdP)(fd_close(fdP), (fdP)=((void *)0), 0);
6227 FreeSendBuffer((struct afs_buffer *)tbuffer);
6228 VTakeOffline(volptr);
6229 ViceLog(0, ("Volume %u now offline, must be salvaged.\n",do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
6230 volptr->hashid))do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
;
6231 return EIO5;
6232 }
6233 nBytes = rx_Write(Call, tbuffer, wlen)rx_WriteProc(Call, tbuffer, wlen);
6234#else /* HAVE_PIOV */
6235 nBytes = rx_WritevAlloc(Call, tiov, &tnio, RX_MAXIOVECS16, wlen);
6236 if (nBytes <= 0) {
6237 FDH_CLOSE(fdP)(fd_close(fdP), (fdP)=((void *)0), 0);
6238 return EIO5;
6239 }
6240 wlen = nBytes;
6241 nBytes = FDH_PREADV(fdP, tiov, tnio, Pos);
6242 if (nBytes != wlen) {
6243 FDH_CLOSE(fdP)(fd_close(fdP), (fdP)=((void *)0), 0);
6244 VTakeOffline(volptr);
6245 ViceLog(0, ("Volume %u now offline, must be salvaged.\n",do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
6246 volptr->hashid))do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
;
6247 return EIO5;
6248 }
6249 nBytes = rx_Writev(Call, tiov, tnio, wlen)rx_WritevProc(Call, tiov, tnio, wlen);
6250#endif /* HAVE_PIOV */
6251 Pos += wlen;
6252 /*
6253 * Bump the number of bytes actually sent by the number from this
6254 * latest iteration
6255 */
6256 (*a_bytesFetchedP) += nBytes;
6257 if (nBytes != wlen) {
6258 afs_int32 err;
6259 FDH_CLOSE(fdP)(fd_close(fdP), (fdP)=((void *)0), 0);
6260#ifndef HAVE_PIOV
6261 FreeSendBuffer((struct afs_buffer *)tbuffer);
6262#endif /* HAVE_PIOV */
6263 err = VIsGoingOffline(volptr);
6264 if (err) {
6265 return err;
6266 }
6267 return -31;
6268 }
6269 Len -= wlen;
6270 }
6271#ifndef HAVE_PIOV
6272 FreeSendBuffer((struct afs_buffer *)tbuffer);
6273#endif /* HAVE_PIOV */
6274 FDH_CLOSE(fdP)(fd_close(fdP), (fdP)=((void *)0), 0);
6275 FT_GetTimeOfDay(&StopTime, 0);
6276
6277 /* Adjust all Fetch Data related stats */
6278 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 6278), 0));
;
6279 if (AFSCallStats.TotalFetchedBytes > 2000000000) /* Reset if over 2 billion */
6280 AFSCallStats.TotalFetchedBytes = AFSCallStats.AccumFetchTime = 0;
6281 AFSCallStats.AccumFetchTime +=
6282 ((StopTime.tv_sec - StartTime.tv_sec) * 1000) +
6283 ((StopTime.tv_usec - StartTime.tv_usec) / 1000);
6284 {
6285 afs_fsize_t targLen;
6286 VN_GET_LEN(targLen, targetptr)(targLen) = ((afs_int64)((targetptr)->disk.vn_length_hi) <<
32) | ((targetptr)->disk.length);
;
6287 AFSCallStats.TotalFetchedBytes += targLen;
6288 AFSCallStats.FetchSize1++;
6289 if (targLen < SIZE21024*8)
6290 AFSCallStats.FetchSize2++;
6291 else if (targLen < SIZE31024*8*8)
6292 AFSCallStats.FetchSize3++;
6293 else if (targLen < SIZE41024*8*8*8)
6294 AFSCallStats.FetchSize4++;
6295 else
6296 AFSCallStats.FetchSize5++;
6297 }
6298 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 6298), 0));
;
6299 return (0);
6300
6301} /*FetchData_RXStyle */
6302
6303static int
6304GetLinkCountAndSize(Volume * vp, FdHandle_t * fdP, int *lc,
6305 afs_sfsize_t * size)
6306{
6307#ifdef AFS_NAMEI_ENV1
6308 FdHandle_t *lhp;
6309 lhp = IH_OPEN(V_linkHandle(vp))ih_open(((vp)->linkHandle));
6310 if (!lhp)
6311 return EIO5;
6312 *lc = namei_GetLinkCount(lhp, fdP->fd_ih->ih_ino, 0, 0, 1);
6313 FDH_CLOSE(lhp)(fd_close(lhp), (lhp)=((void *)0), 0);
6314 if (*lc < 0)
6315 return -1;
6316 *size = OS_SIZE(fdP->fd_fd)ih_size(fdP->fd_fd);
6317 return (*size == -1) ? -1 : 0;
6318#else
6319 struct afs_statstat status;
6320
6321 if (afs_fstatfstat(fdP->fd_fd, &status) < 0) {
6322 return -1;
6323 }
6324
6325 *lc = GetLinkCount(vp, &status)(&status)->st_nlink;
6326 *size = status.st_size;
6327 return 0;
6328#endif
6329}
6330
6331/*
6332 * StoreData_RXStyle
6333 *
6334 * Purpose:
6335 * Implement a client's data store using Rx.
6336 *
6337 * Arguments:
6338 * volptr : Ptr to the given volume's info.
6339 * targetptr : Pointer to the vnode involved.
6340 * Call : Ptr to the Rx call involved.
6341 * Pos : Offset within the file.
6342 * Len : Length in bytes to store; this value is bogus!
6343 * a_bytesToStoreP : Set to the number of bytes to be stored to
6344 * the File Server.
6345 * a_bytesStoredP : Set to the actual number of bytes stored to
6346 * the File Server.
6347 */
6348afs_int32
6349StoreData_RXStyle(Volume * volptr, Vnode * targetptr, struct AFSFid * Fid,
6350 struct client * client, struct rx_call * Call,
6351 afs_fsize_t Pos, afs_fsize_t Length, afs_fsize_t FileLength,
6352 int sync,
6353 afs_sfsize_t * a_bytesToStoreP,
6354 afs_sfsize_t * a_bytesStoredP)
6355{
6356 afs_sfsize_t bytesTransfered; /* number of bytes actually transfered */
6357 struct timeval StartTime, StopTime; /* Used to measure how long the store takes */
6358 Errorbit32 errorCode = 0; /* Returned error code to caller */
6359#ifndef HAVE_PIOV
6360 char *tbuffer; /* data copying buffer */
6361#else /* HAVE_PIOV */
6362 struct iovec tiov[RX_MAXIOVECS16]; /* no data copying with iovec */
6363 int tnio; /* temp for iovec size */
6364#endif /* HAVE_PIOV */
6365 afs_sfsize_t tlen; /* temp for xfr length */
6366 Inode tinode; /* inode for I/O */
6367 afs_int32 optSize; /* optimal transfer size */
6368 afs_sfsize_t DataLength = 0; /* size of inode */
6369 afs_sfsize_t TruncatedLength; /* size after ftruncate */
6370 afs_fsize_t NewLength; /* size after this store completes */
6371 afs_sfsize_t adjustSize; /* bytes to call VAdjust... with */
6372 int linkCount = 0; /* link count on inode */
6373 afs_fsize_t CoW_off, CoW_len;
6374 ssize_t nBytes;
6375 FdHandle_t *fdP, *origfdP = NULL((void *)0);
6376 struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
6377 afs_ino_str_t stmp;
6378
6379 /*
6380 * Initialize the byte count arguments.
6381 */
6382 (*a_bytesToStoreP) = 0;
6383 (*a_bytesStoredP) = 0;
6384
6385 /*
6386 * We break the callbacks here so that the following signal will not
6387 * leave a window.
6388 */
6389 BreakCallBack(client->host, Fid, 0);
6390
6391 if (Pos == -1 || VN_GET_INO(targetptr)((Inode)((targetptr)->disk.vn_ino_lo | ((targetptr)->disk
.vn_ino_hi ? (((Inode)(targetptr)->disk.vn_ino_hi)<<
32) : 0)))
== 0) {
6392 /* the inode should have been created in Alloc_NewVnode */
6393 logHostAddr.s_addr = rxr_HostOf(rx_ConnectionOf(Call))(((((struct rx_connection *)(((Call)->conn)))->peer))->
host)
;
6394 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("StoreData_RXStyle : Inode non-existent Fid = %u.%u.%u, inode = %llu, Pos %llu Host %s:%d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, (afs_uintmax_t
) ((Inode)((targetptr)->disk.vn_ino_lo | ((targetptr)->
disk.vn_ino_hi ? (((Inode)(targetptr)->disk.vn_ino_hi)<<
32) : 0))), (afs_uintmax_t) Pos, __inet_ntoa(logHostAddr), (__builtin_constant_p
(((((((struct rx_connection *)(((Call)->conn))))->peer)
)->port)) ? (__uint16_t)(((__uint16_t)(((((((struct rx_connection
*)(((Call)->conn))))->peer))->port))) << 8 | (
(__uint16_t)(((((((struct rx_connection *)(((Call)->conn))
))->peer))->port))) >> 8) : __bswap16_var(((((((struct
rx_connection *)(((Call)->conn))))->peer))->port)))
)); } while (0)
6395 ("StoreData_RXStyle : Inode non-existent Fid = %u.%u.%u, inode = %llu, Pos %llu Host %s:%d\n",do { if ((0) <= LogLevel) (FSLog ("StoreData_RXStyle : Inode non-existent Fid = %u.%u.%u, inode = %llu, Pos %llu Host %s:%d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, (afs_uintmax_t
) ((Inode)((targetptr)->disk.vn_ino_lo | ((targetptr)->
disk.vn_ino_hi ? (((Inode)(targetptr)->disk.vn_ino_hi)<<
32) : 0))), (afs_uintmax_t) Pos, __inet_ntoa(logHostAddr), (__builtin_constant_p
(((((((struct rx_connection *)(((Call)->conn))))->peer)
)->port)) ? (__uint16_t)(((__uint16_t)(((((((struct rx_connection
*)(((Call)->conn))))->peer))->port))) << 8 | (
(__uint16_t)(((((((struct rx_connection *)(((Call)->conn))
))->peer))->port))) >> 8) : __bswap16_var(((((((struct
rx_connection *)(((Call)->conn))))->peer))->port)))
)); } while (0)
6396 Fid->Volume, Fid->Vnode, Fid->Unique,do { if ((0) <= LogLevel) (FSLog ("StoreData_RXStyle : Inode non-existent Fid = %u.%u.%u, inode = %llu, Pos %llu Host %s:%d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, (afs_uintmax_t
) ((Inode)((targetptr)->disk.vn_ino_lo | ((targetptr)->
disk.vn_ino_hi ? (((Inode)(targetptr)->disk.vn_ino_hi)<<
32) : 0))), (afs_uintmax_t) Pos, __inet_ntoa(logHostAddr), (__builtin_constant_p
(((((((struct rx_connection *)(((Call)->conn))))->peer)
)->port)) ? (__uint16_t)(((__uint16_t)(((((((struct rx_connection
*)(((Call)->conn))))->peer))->port))) << 8 | (
(__uint16_t)(((((((struct rx_connection *)(((Call)->conn))
))->peer))->port))) >> 8) : __bswap16_var(((((((struct
rx_connection *)(((Call)->conn))))->peer))->port)))
)); } while (0)
6397 (afs_uintmax_t) VN_GET_INO(targetptr), (afs_uintmax_t) Pos,do { if ((0) <= LogLevel) (FSLog ("StoreData_RXStyle : Inode non-existent Fid = %u.%u.%u, inode = %llu, Pos %llu Host %s:%d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, (afs_uintmax_t
) ((Inode)((targetptr)->disk.vn_ino_lo | ((targetptr)->
disk.vn_ino_hi ? (((Inode)(targetptr)->disk.vn_ino_hi)<<
32) : 0))), (afs_uintmax_t) Pos, __inet_ntoa(logHostAddr), (__builtin_constant_p
(((((((struct rx_connection *)(((Call)->conn))))->peer)
)->port)) ? (__uint16_t)(((__uint16_t)(((((((struct rx_connection
*)(((Call)->conn))))->peer))->port))) << 8 | (
(__uint16_t)(((((((struct rx_connection *)(((Call)->conn))
))->peer))->port))) >> 8) : __bswap16_var(((((((struct
rx_connection *)(((Call)->conn))))->peer))->port)))
)); } while (0)
6398 inet_ntoa(logHostAddr), ntohs(rxr_PortOf(rx_ConnectionOf(Call)))))do { if ((0) <= LogLevel) (FSLog ("StoreData_RXStyle : Inode non-existent Fid = %u.%u.%u, inode = %llu, Pos %llu Host %s:%d\n"
, Fid->Volume, Fid->Vnode, Fid->Unique, (afs_uintmax_t
) ((Inode)((targetptr)->disk.vn_ino_lo | ((targetptr)->
disk.vn_ino_hi ? (((Inode)(targetptr)->disk.vn_ino_hi)<<
32) : 0))), (afs_uintmax_t) Pos, __inet_ntoa(logHostAddr), (__builtin_constant_p
(((((((struct rx_connection *)(((Call)->conn))))->peer)
)->port)) ? (__uint16_t)(((__uint16_t)(((((((struct rx_connection
*)(((Call)->conn))))->peer))->port))) << 8 | (
(__uint16_t)(((((((struct rx_connection *)(((Call)->conn))
))->peer))->port))) >> 8) : __bswap16_var(((((((struct
rx_connection *)(((Call)->conn))))->peer))->port)))
)); } while (0)
;
6399 return ENOENT2; /* is this proper error code? */
6400 } else {
6401 /*
6402 * See if the file has several links (from other volumes). If it
6403 * does, then we have to make a copy before changing it to avoid
6404 *changing read-only clones of this dude
6405 */
6406 ViceLog(25,do { if ((25) <= LogLevel) (FSLog ("StoreData_RXStyle : Opening inode %s\n"
, PrintInode(stmp, ((Inode)((targetptr)->disk.vn_ino_lo | (
(targetptr)->disk.vn_ino_hi ? (((Inode)(targetptr)->disk
.vn_ino_hi)<<32) : 0)))))); } while (0)
6407 ("StoreData_RXStyle : Opening inode %s\n",do { if ((25) <= LogLevel) (FSLog ("StoreData_RXStyle : Opening inode %s\n"
, PrintInode(stmp, ((Inode)((targetptr)->disk.vn_ino_lo | (
(targetptr)->disk.vn_ino_hi ? (((Inode)(targetptr)->disk
.vn_ino_hi)<<32) : 0)))))); } while (0)
6408 PrintInode(stmp, VN_GET_INO(targetptr))))do { if ((25) <= LogLevel) (FSLog ("StoreData_RXStyle : Opening inode %s\n"
, PrintInode(stmp, ((Inode)((targetptr)->disk.vn_ino_lo | (
(targetptr)->disk.vn_ino_hi ? (((Inode)(targetptr)->disk
.vn_ino_hi)<<32) : 0)))))); } while (0)
;
6409 fdP = IH_OPEN(targetptr->handle)ih_open(targetptr->handle);
6410 if (fdP == NULL((void *)0))
6411 return ENOENT2;
6412 if (GetLinkCountAndSize(volptr, fdP, &linkCount, &DataLength) < 0) {
6413 FDH_CLOSE(fdP)(fd_close(fdP), (fdP)=((void *)0), 0);
6414 VTakeOffline(volptr);
6415 ViceLog(0, ("Volume %u now offline, must be salvaged.\n",do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
6416 volptr->hashid))do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
;
6417 return EIO5;
6418 }
6419 if (CheckLength(volptr, targetptr, DataLength)) {
6420 FDH_CLOSE(fdP)(fd_close(fdP), (fdP)=((void *)0), 0);
6421 VTakeOffline(volptr);
6422 return VSALVAGE101;
6423 }
6424
6425 if (linkCount != 1) {
6426 afs_fsize_t size;
6427 ViceLog(25,do { if ((25) <= LogLevel) (FSLog ("StoreData_RXStyle : inode %s has more than onelink\n"
, PrintInode(stmp, ((Inode)((targetptr)->disk.vn_ino_lo | (
(targetptr)->disk.vn_ino_hi ? (((Inode)(targetptr)->disk
.vn_ino_hi)<<32) : 0)))))); } while (0)
6428 ("StoreData_RXStyle : inode %s has more than onelink\n",do { if ((25) <= LogLevel) (FSLog ("StoreData_RXStyle : inode %s has more than onelink\n"
, PrintInode(stmp, ((Inode)((targetptr)->disk.vn_ino_lo | (
(targetptr)->disk.vn_ino_hi ? (((Inode)(targetptr)->disk
.vn_ino_hi)<<32) : 0)))))); } while (0)
6429 PrintInode(stmp, VN_GET_INO(targetptr))))do { if ((25) <= LogLevel) (FSLog ("StoreData_RXStyle : inode %s has more than onelink\n"
, PrintInode(stmp, ((Inode)((targetptr)->disk.vn_ino_lo | (
(targetptr)->disk.vn_ino_hi ? (((Inode)(targetptr)->disk
.vn_ino_hi)<<32) : 0)))))); } while (0)
;
6430 /* other volumes share this data, better copy it first */
6431
6432 /* Adjust the disk block count by the creation of the new inode.
6433 * We call the special VDiskUsage so we don't adjust the volume's
6434 * quota since we don't want to penalyze the user for afs's internal
6435 * mechanisms (i.e. copy on write overhead.) Also the right size
6436 * of the disk will be recorded...
6437 */
6438 origfdP = fdP;
6439 VN_GET_LEN(size, targetptr)(size) = ((afs_int64)((targetptr)->disk.vn_length_hi) <<
32) | ((targetptr)->disk.length);
;
6440 volptr->partition->flags &= ~PART_DONTUPDATE1;
6441 VSetPartitionDiskUsage(volptr->partition);
6442 volptr->partition->flags |= PART_DONTUPDATE1;
6443 if ((errorCode = VDiskUsage(volptr, nBlocks(size)((afs_sfsize_t)((size) == 0? 1: (((afs_sfsize_t)(size))+1023)
/1024))
))) {
6444 volptr->partition->flags &= ~PART_DONTUPDATE1;
6445 FDH_CLOSE(origfdP)(fd_close(origfdP), (origfdP)=((void *)0), 0);
6446 return (errorCode);
6447 }
6448
6449 CoW_len = (FileLength >= (Length + Pos)) ? FileLength - Length : Pos;
6450 CopyOnWrite_calls++;
6451 if (CoW_len == 0) CopyOnWrite_size0++;
6452 if (Pos == 0) CopyOnWrite_off0++;
6453 if (CoW_len > CopyOnWrite_maxsize) CopyOnWrite_maxsize = CoW_len;
6454
6455 ViceLog(1, ("StoreData : calling CopyOnWrite on vnode %u.%u (%s) "do { if ((1) <= LogLevel) (FSLog ("StoreData : calling CopyOnWrite on vnode %u.%u (%s) "
"off 0x0 size 0x%llx\n", afs_printable_VolumeId_u(((volptr)->
header->diskstuff.id)), afs_printable_VnodeId_u(targetptr->
vnodeNumber), ((volptr)->header->diskstuff.name), Pos))
; } while (0)
6456 "off 0x0 size 0x%llx\n",do { if ((1) <= LogLevel) (FSLog ("StoreData : calling CopyOnWrite on vnode %u.%u (%s) "
"off 0x0 size 0x%llx\n", afs_printable_VolumeId_u(((volptr)->
header->diskstuff.id)), afs_printable_VnodeId_u(targetptr->
vnodeNumber), ((volptr)->header->diskstuff.name), Pos))
; } while (0)
6457 afs_printable_VolumeId_u(V_id(volptr)),do { if ((1) <= LogLevel) (FSLog ("StoreData : calling CopyOnWrite on vnode %u.%u (%s) "
"off 0x0 size 0x%llx\n", afs_printable_VolumeId_u(((volptr)->
header->diskstuff.id)), afs_printable_VnodeId_u(targetptr->
vnodeNumber), ((volptr)->header->diskstuff.name), Pos))
; } while (0)
6458 afs_printable_VnodeId_u(targetptr->vnodeNumber),do { if ((1) <= LogLevel) (FSLog ("StoreData : calling CopyOnWrite on vnode %u.%u (%s) "
"off 0x0 size 0x%llx\n", afs_printable_VolumeId_u(((volptr)->
header->diskstuff.id)), afs_printable_VnodeId_u(targetptr->
vnodeNumber), ((volptr)->header->diskstuff.name), Pos))
; } while (0)
6459 V_name(volptr), Pos))do { if ((1) <= LogLevel) (FSLog ("StoreData : calling CopyOnWrite on vnode %u.%u (%s) "
"off 0x0 size 0x%llx\n", afs_printable_VolumeId_u(((volptr)->
header->diskstuff.id)), afs_printable_VnodeId_u(targetptr->
vnodeNumber), ((volptr)->header->diskstuff.name), Pos))
; } while (0)
;
6460 if ((errorCode = CopyOnWrite(targetptr, volptr, 0, Pos))) {
6461 ViceLog(25, ("StoreData : CopyOnWrite failed\n"))do { if ((25) <= LogLevel) (FSLog ("StoreData : CopyOnWrite failed\n"
)); } while (0)
;
6462 volptr->partition->flags &= ~PART_DONTUPDATE1;
6463 FDH_CLOSE(origfdP)(fd_close(origfdP), (origfdP)=((void *)0), 0);
6464 return (errorCode);
6465 }
6466 volptr->partition->flags &= ~PART_DONTUPDATE1;
6467 VSetPartitionDiskUsage(volptr->partition);
6468 fdP = IH_OPEN(targetptr->handle)ih_open(targetptr->handle);
6469 if (fdP == NULL((void *)0)) {
6470 ViceLog(25,do { if ((25) <= LogLevel) (FSLog ("StoreData : Reopen after CopyOnWrite failed\n"
)); } while (0)
6471 ("StoreData : Reopen after CopyOnWrite failed\n"))do { if ((25) <= LogLevel) (FSLog ("StoreData : Reopen after CopyOnWrite failed\n"
)); } while (0)
;
6472 FDH_REALLYCLOSE(origfdP)(fd_reallyclose(origfdP), (origfdP)=((void *)0), 0);
6473 return ENOENT2;
6474 }
6475 }
6476 tinode = VN_GET_INO(targetptr)((Inode)((targetptr)->disk.vn_ino_lo | ((targetptr)->disk
.vn_ino_hi ? (((Inode)(targetptr)->disk.vn_ino_hi)<<
32) : 0)))
;
6477 }
6478 if (!VALID_INO(tinode)((tinode) != (Inode)-1 && (tinode) != (Inode)0)) {
6479 VTakeOffline(volptr);
6480 ViceLog(0,("Volume %u now offline, must be salvaged.\n",do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
6481 volptr->hashid))do { if ((0) <= LogLevel) (FSLog ("Volume %u now offline, must be salvaged.\n"
, volptr->hashid)); } while (0)
;
6482 return EIO5;
6483 }
6484
6485 /* compute new file length */
6486 NewLength = DataLength;
6487 if (FileLength < NewLength)
6488 /* simulate truncate */
6489 NewLength = FileLength;
6490 TruncatedLength = NewLength; /* remember length after possible ftruncate */
6491 if (Pos + Length > NewLength)
6492 NewLength = Pos + Length; /* and write */
6493
6494 /* adjust the disk block count by the difference in the files */
6495 {
6496 afs_fsize_t targSize;
6497 VN_GET_LEN(targSize, targetptr)(targSize) = ((afs_int64)((targetptr)->disk.vn_length_hi) <<
32) | ((targetptr)->disk.length);
;
6498 adjustSize = nBlocks(NewLength)((afs_sfsize_t)((NewLength) == 0? 1: (((afs_sfsize_t)(NewLength
))+1023)/1024))
- nBlocks(targSize)((afs_sfsize_t)((targSize) == 0? 1: (((afs_sfsize_t)(targSize
))+1023)/1024))
;
6499 }
6500 if ((errorCode =
6501 AdjustDiskUsage(volptr, adjustSize,
6502 adjustSize - SpareComp(volptr)))) {
6503 FDH_CLOSE(fdP)(fd_close(fdP), (fdP)=((void *)0), 0);
6504 if (origfdP) FDH_REALLYCLOSE(origfdP)(fd_reallyclose(origfdP), (origfdP)=((void *)0), 0);
6505 return (errorCode);
6506 }
6507
6508 /* can signal cache manager to proceed from close now */
6509 /* this bit means that the locks are set and protections are OK */
6510 rx_SetLocalStatus(Call, 1)((Call)->localStatus = (1));
6511
6512 FT_GetTimeOfDay(&StartTime, 0);
6513
6514 optSize = sendBufSize;
6515 ViceLog(25,do { if ((25) <= LogLevel) (FSLog ("StoreData_RXStyle: Pos %llu, DataLength %llu, FileLength %llu, Length %llu\n"
, (afs_uintmax_t) Pos, (afs_uintmax_t) DataLength, (afs_uintmax_t
) FileLength, (afs_uintmax_t) Length)); } while (0)
6516 ("StoreData_RXStyle: Pos %llu, DataLength %llu, FileLength %llu, Length %llu\n",do { if ((25) <= LogLevel) (FSLog ("StoreData_RXStyle: Pos %llu, DataLength %llu, FileLength %llu, Length %llu\n"
, (afs_uintmax_t) Pos, (afs_uintmax_t) DataLength, (afs_uintmax_t
) FileLength, (afs_uintmax_t) Length)); } while (0)
6517 (afs_uintmax_t) Pos, (afs_uintmax_t) DataLength,do { if ((25) <= LogLevel) (FSLog ("StoreData_RXStyle: Pos %llu, DataLength %llu, FileLength %llu, Length %llu\n"
, (afs_uintmax_t) Pos, (afs_uintmax_t) DataLength, (afs_uintmax_t
) FileLength, (afs_uintmax_t) Length)); } while (0)
6518 (afs_uintmax_t) FileLength, (afs_uintmax_t) Length))do { if ((25) <= LogLevel) (FSLog ("StoreData_RXStyle: Pos %llu, DataLength %llu, FileLength %llu, Length %llu\n"
, (afs_uintmax_t) Pos, (afs_uintmax_t) DataLength, (afs_uintmax_t
) FileLength, (afs_uintmax_t) Length)); } while (0)
;
6519
6520 /* truncate the file iff it needs it (ftruncate is slow even when its a noop) */
6521 if (FileLength < DataLength)
6522 FDH_TRUNC(fdP, FileLength)ftruncate((fdP)->fd_fd, (off_t) (FileLength));
6523 bytesTransfered = 0;
6524#ifndef HAVE_PIOV
6525 tbuffer = AllocSendBuffer();
6526#endif /* HAVE_PIOV */
6527 /* if length == 0, the loop below isn't going to do anything, including
6528 * extend the length of the inode, which it must do, since the file system
6529 * assumes that the inode length == vnode's file length. So, we extend
6530 * the file length manually if need be. Note that if file is bigger than
6531 * Pos+(Length==0), we dont' have to do anything, and certainly shouldn't
6532 * do what we're going to do below.
6533 */
6534 if (Length == 0 && Pos > TruncatedLength) {
6535 /* Set the file's length; we've already done an lseek to the right
6536 * spot above.
6537 */
6538 nBytes = FDH_PWRITE(fdP, &tlen, 1, Pos)pwrite((fdP)->fd_fd, &tlen, 1, Pos);
6539 if (nBytes != 1) {
6540 errorCode = -1;
6541 goto done;
6542 }
6543 errorCode = FDH_TRUNC(fdP, Pos)ftruncate((fdP)->fd_fd, (off_t) (Pos));
6544 } else {
6545 /* have some data to copy */
6546 (*a_bytesToStoreP) = Length;
6547 while (1) {
6548 int rlen;
6549 if (bytesTransfered >= Length) {
6550 errorCode = 0;
6551 break;
6552 }
6553 tlen = Length - bytesTransfered; /* how much more to do */
6554 if (tlen > optSize)
6555 rlen = optSize; /* bound by buffer size */
6556 else
6557 rlen = (int)tlen;
6558#ifndef HAVE_PIOV
6559 errorCode = rx_Read(Call, tbuffer, rlen)rx_ReadProc(Call, tbuffer, rlen);
6560#else /* HAVE_PIOV */
6561 errorCode = rx_Readv(Call, tiov, &tnio, RX_MAXIOVECS, rlen)rx_ReadvProc(Call, tiov, &tnio, 16, rlen);
6562#endif /* HAVE_PIOV */
6563 if (errorCode <= 0) {
6564 errorCode = -32;
6565 break;
6566 }
6567 (*a_bytesStoredP) += errorCode;
6568 rlen = errorCode;
6569#ifndef HAVE_PIOV
6570 nBytes = FDH_PWRITE(fdP, tbuffer, rlen, Pos)pwrite((fdP)->fd_fd, tbuffer, rlen, Pos);
6571#else /* HAVE_PIOV */
6572 nBytes = FDH_PWRITEV(fdP, tiov, tnio, Pos);
6573#endif /* HAVE_PIOV */
6574 if (nBytes != rlen) {
6575 errorCode = VDISKFULL108;
6576 break;
6577 }
6578 bytesTransfered += rlen;
6579 Pos += rlen;
6580 }
6581 }
6582 done:
6583#ifndef HAVE_PIOV
6584 FreeSendBuffer((struct afs_buffer *)tbuffer);
6585#endif /* HAVE_PIOV */
6586 if (sync) {
6587 FDH_SYNC(fdP)((fdP->fd_ih!=((void *)0)) ? ( fdP->fd_ih->ih_synced
= 1) - 1 : 1)
;
6588 }
6589 if (errorCode) {
6590 afs_sfsize_t nfSize = FDH_SIZE(fdP)ih_size((fdP)->fd_fd);
6591 osi_Assert(nfSize >= 0)(void)((nfSize >= 0) || (osi_AssertFailU("nfSize >= 0",
"./../viced/afsfileprocs.c", 6591), 0))
;
6592 /* something went wrong: adjust size and return */
6593 VN_SET_LEN(targetptr, nfSize)((targetptr)->disk.vn_length_hi) = ((afs_int64)nfSize) >>
32; ((targetptr)->disk.length) = (nfSize) & 0xFFFFFFFF
;
; /* set new file size. */
6594 /* changed_newTime is tested in StoreData to detemine if we
6595 * need to update the target vnode.
6596 */
6597 targetptr->changed_newTime = 1;
6598 if (origfdP && (bytesTransfered < Length)) /* Need to "finish" CopyOnWrite still */
6599 CopyOnWrite2(origfdP, fdP, Pos + bytesTransfered, NewLength - Pos - bytesTransfered);
6600 if (origfdP) FDH_REALLYCLOSE(origfdP)(fd_reallyclose(origfdP), (origfdP)=((void *)0), 0);
6601 FDH_CLOSE(fdP)(fd_close(fdP), (fdP)=((void *)0), 0);
6602 /* set disk usage to be correct */
6603 VAdjustDiskUsage(&errorCode, volptr,
6604 (afs_sfsize_t) (nBlocks(nfSize)((afs_sfsize_t)((nfSize) == 0? 1: (((afs_sfsize_t)(nfSize))+1023
)/1024))
-
6605 nBlocks(NewLength)((afs_sfsize_t)((NewLength) == 0? 1: (((afs_sfsize_t)(NewLength
))+1023)/1024))
), 0);
6606 return errorCode;
6607 }
6608 if (origfdP) { /* finish CopyOnWrite */
6609 if ( (CoW_off = Pos + Length) < NewLength) {
6610 errorCode = CopyOnWrite2(origfdP, fdP, CoW_off, CoW_len = NewLength - CoW_off);
6611 ViceLog(1, ("StoreData : CopyOnWrite2 on vnode %u.%u (%s) "do { if ((1) <= LogLevel) (FSLog ("StoreData : CopyOnWrite2 on vnode %u.%u (%s) "
"off 0x%llx size 0x%llx returns %d\n", afs_printable_VolumeId_u
(((volptr)->header->diskstuff.id)), afs_printable_VnodeId_u
(targetptr->vnodeNumber), ((volptr)->header->diskstuff
.name), CoW_off, CoW_len, errorCode)); } while (0)
6612 "off 0x%llx size 0x%llx returns %d\n",do { if ((1) <= LogLevel) (FSLog ("StoreData : CopyOnWrite2 on vnode %u.%u (%s) "
"off 0x%llx size 0x%llx returns %d\n", afs_printable_VolumeId_u
(((volptr)->header->diskstuff.id)), afs_printable_VnodeId_u
(targetptr->vnodeNumber), ((volptr)->header->diskstuff
.name), CoW_off, CoW_len, errorCode)); } while (0)
6613 afs_printable_VolumeId_u(V_id(volptr)),do { if ((1) <= LogLevel) (FSLog ("StoreData : CopyOnWrite2 on vnode %u.%u (%s) "
"off 0x%llx size 0x%llx returns %d\n", afs_printable_VolumeId_u
(((volptr)->header->diskstuff.id)), afs_printable_VnodeId_u
(targetptr->vnodeNumber), ((volptr)->header->diskstuff
.name), CoW_off, CoW_len, errorCode)); } while (0)
6614 afs_printable_VnodeId_u(targetptr->vnodeNumber),do { if ((1) <= LogLevel) (FSLog ("StoreData : CopyOnWrite2 on vnode %u.%u (%s) "
"off 0x%llx size 0x%llx returns %d\n", afs_printable_VolumeId_u
(((volptr)->header->diskstuff.id)), afs_printable_VnodeId_u
(targetptr->vnodeNumber), ((volptr)->header->diskstuff
.name), CoW_off, CoW_len, errorCode)); } while (0)
6615 V_name(volptr), CoW_off, CoW_len, errorCode))do { if ((1) <= LogLevel) (FSLog ("StoreData : CopyOnWrite2 on vnode %u.%u (%s) "
"off 0x%llx size 0x%llx returns %d\n", afs_printable_VolumeId_u
(((volptr)->header->diskstuff.id)), afs_printable_VnodeId_u
(targetptr->vnodeNumber), ((volptr)->header->diskstuff
.name), CoW_off, CoW_len, errorCode)); } while (0)
;
6616 }
6617 FDH_REALLYCLOSE(origfdP)(fd_reallyclose(origfdP), (origfdP)=((void *)0), 0);
6618 }
6619 FDH_CLOSE(fdP)(fd_close(fdP), (fdP)=((void *)0), 0);
6620
6621 FT_GetTimeOfDay(&StopTime, 0);
6622
6623 VN_SET_LEN(targetptr, NewLength)((targetptr)->disk.vn_length_hi) = ((afs_int64)NewLength) >>
32; ((targetptr)->disk.length) = (NewLength) & 0xFFFFFFFF
;
;
6624
6625 /* Update all StoreData related stats */
6626 FS_LOCK(void)((pthread_mutex_lock(&fileproc_glock_mutex) == 0) ||
(osi_AssertFailU("pthread_mutex_lock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 6626), 0));
;
6627 if (AFSCallStats.TotalStoredBytes > 2000000000) /* reset if over 2 billion */
6628 AFSCallStats.TotalStoredBytes = AFSCallStats.AccumStoreTime = 0;
6629 AFSCallStats.StoreSize1++; /* Piggybacked data */
6630 {
6631 afs_fsize_t targLen;
6632 VN_GET_LEN(targLen, targetptr)(targLen) = ((afs_int64)((targetptr)->disk.vn_length_hi) <<
32) | ((targetptr)->disk.length);
;
6633 if (targLen < SIZE21024*8)
6634 AFSCallStats.StoreSize2++;
6635 else if (targLen < SIZE31024*8*8)
6636 AFSCallStats.StoreSize3++;
6637 else if (targLen < SIZE41024*8*8*8)
6638 AFSCallStats.StoreSize4++;
6639 else
6640 AFSCallStats.StoreSize5++;
6641 }
6642 FS_UNLOCK(void)((pthread_mutex_unlock(&fileproc_glock_mutex) == 0)
|| (osi_AssertFailU("pthread_mutex_unlock(&fileproc_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 6642), 0));
;
6643 return (errorCode);
6644
6645} /*StoreData_RXStyle */
6646
6647static int sys2et[512];
6648
6649void
6650init_sys_error_to_et(void)
6651{
6652 memset(&sys2et, 0, sizeof(sys2et));
6653 sys2et[EPERM1] = UAEPERM(49733376L);
6654 sys2et[ENOENT2] = UAENOENT(49733377L);
6655 sys2et[ESRCH3] = UAESRCH(49733378L);
6656 sys2et[EINTR4] = UAEINTR(49733379L);
6657 sys2et[EIO5] = UAEIO(49733380L);
6658 sys2et[ENXIO6] = UAENXIO(49733381L);
6659 sys2et[E2BIG7] = UAE2BIG(49733382L);
6660 sys2et[ENOEXEC8] = UAENOEXEC(49733383L);
6661 sys2et[EBADF9] = UAEBADF(49733384L);
6662 sys2et[ECHILD10] = UAECHILD(49733385L);
6663 sys2et[EAGAIN35] = UAEAGAIN(49733386L);
6664 sys2et[ENOMEM12] = UAENOMEM(49733387L);
6665 sys2et[EACCES13] = UAEACCES(49733388L);
6666 sys2et[EFAULT14] = UAEFAULT(49733389L);
6667 sys2et[ENOTBLK15] = UAENOTBLK(49733390L);
6668 sys2et[EBUSY16] = UAEBUSY(49733391L);
6669 sys2et[EEXIST17] = UAEEXIST(49733392L);
6670 sys2et[EXDEV18] = UAEXDEV(49733393L);
6671 sys2et[ENODEV19] = UAENODEV(49733394L);
6672 sys2et[ENOTDIR20] = UAENOTDIR(49733395L);
6673 sys2et[EISDIR21] = UAEISDIR(49733396L);
6674 sys2et[EINVAL22] = UAEINVAL(49733397L);
6675 sys2et[ENFILE23] = UAENFILE(49733398L);
6676 sys2et[EMFILE24] = UAEMFILE(49733399L);
6677 sys2et[ENOTTY25] = UAENOTTY(49733400L);
6678 sys2et[ETXTBSY26] = UAETXTBSY(49733401L);
6679 sys2et[EFBIG27] = UAEFBIG(49733402L);
6680 sys2et[ENOSPC28] = UAENOSPC(49733403L);
6681 sys2et[ESPIPE29] = UAESPIPE(49733404L);
6682 sys2et[EROFS30] = UAEROFS(49733405L);
6683 sys2et[EMLINK31] = UAEMLINK(49733406L);
6684 sys2et[EPIPE32] = UAEPIPE(49733407L);
6685 sys2et[EDOM33] = UAEDOM(49733408L);
6686 sys2et[ERANGE34] = UAERANGE(49733409L);
6687 sys2et[EDEADLK11] = UAEDEADLK(49733410L);
6688 sys2et[ENAMETOOLONG63] = UAENAMETOOLONG(49733411L);
6689 sys2et[ENOLCK77] = UAENOLCK(49733412L);
6690 sys2et[ENOSYS78] = UAENOSYS(49733413L);
6691#if (ENOTEMPTY66 != EEXIST17)
6692 sys2et[ENOTEMPTY66] = UAENOTEMPTY(49733414L);
6693#endif
6694 sys2et[ELOOP62] = UAELOOP(49733415L);
6695#if (EWOULDBLOCK35 != EAGAIN35)
6696 sys2et[EWOULDBLOCK35] = UAEWOULDBLOCK(49733416L);
6697#endif
6698 sys2et[ENOMSG83] = UAENOMSG(49733417L);
6699 sys2et[EIDRM82] = UAEIDRM(49733418L);
6700 sys2et[ECHRNG5] = UAECHRNG(49733419L);
6701 sys2et[EL2NSYNC5] = UAEL2NSYNC(49733420L);
6702 sys2et[EL3HLT5] = UAEL3HLT(49733421L);
6703 sys2et[EL3RST5] = UAEL3RST(49733422L);
6704 sys2et[ELNRNG5] = UAELNRNG(49733423L);
6705 sys2et[EUNATCH5] = UAEUNATCH(49733424L);
6706 sys2et[ENOCSI5] = UAENOCSI(49733425L);
6707 sys2et[EL2HLT5] = UAEL2HLT(49733426L);
6708 sys2et[EBADE5] = UAEBADE(49733427L);
6709 sys2et[EBADR5] = UAEBADR(49733428L);
6710 sys2et[EXFULL5] = UAEXFULL(49733429L);
6711 sys2et[ENOANO5] = UAENOANO(49733430L);
6712 sys2et[EBADRQC5] = UAEBADRQC(49733431L);
6713 sys2et[EBADSLT5] = UAEBADSLT(49733432L);
6714 sys2et[EDEADLK11] = UAEDEADLK(49733410L);
6715 sys2et[EBFONT5] = UAEBFONT(49733433L);
6716 sys2et[ENOSTR5] = UAENOSTR(49733434L);
6717 sys2et[ENODATA5] = UAENODATA(49733435L);
6718 sys2et[ETIME5] = UAETIME(49733436L);
6719 sys2et[ENOSR5] = UAENOSR(49733437L);
6720 sys2et[ENONET5] = UAENONET(49733438L);
6721 sys2et[ENOPKG5] = UAENOPKG(49733439L);
6722 sys2et[EREMOTE71] = UAEREMOTE(49733440L);
6723 sys2et[ENOLINK91] = UAENOLINK(49733441L);
6724 sys2et[EADV5] = UAEADV(49733442L);
6725 sys2et[ESRMNT5] = UAESRMNT(49733443L);
6726 sys2et[ECOMM5] = UAECOMM(49733444L);
6727 sys2et[EPROTO92] = UAEPROTO(49733445L);
6728 sys2et[EMULTIHOP90] = UAEMULTIHOP(49733446L);
6729 sys2et[EDOTDOT5] = UAEDOTDOT(49733447L);
6730 sys2et[EBADMSG89] = UAEBADMSG(49733448L);
6731 sys2et[EOVERFLOW84] = UAEOVERFLOW(49733449L);
6732 sys2et[ENOTUNIQ5] = UAENOTUNIQ(49733450L);
6733 sys2et[EBADFD5] = UAEBADFD(49733451L);
6734 sys2et[EREMCHG5] = UAEREMCHG(49733452L);
6735 sys2et[ELIBACC5] = UAELIBACC(49733453L);
6736 sys2et[ELIBBAD5] = UAELIBBAD(49733454L);
6737 sys2et[ELIBSCN5] = UAELIBSCN(49733455L);
6738 sys2et[ELIBMAX5] = UAELIBMAX(49733456L);
6739 sys2et[ELIBEXEC5] = UAELIBEXEC(49733457L);
6740 sys2et[EILSEQ86] = UAEILSEQ(49733458L);
6741 sys2et[ERESTART5] = UAERESTART(49733459L);
6742 sys2et[ESTRPIPE5] = UAESTRPIPE(49733460L);
6743 sys2et[EUSERS68] = UAEUSERS(49733461L);
6744 sys2et[ENOTSOCK38] = UAENOTSOCK(49733462L);
6745 sys2et[EDESTADDRREQ39] = UAEDESTADDRREQ(49733463L);
6746 sys2et[EMSGSIZE40] = UAEMSGSIZE(49733464L);
6747 sys2et[EPROTOTYPE41] = UAEPROTOTYPE(49733465L);
6748 sys2et[ENOPROTOOPT42] = UAENOPROTOOPT(49733466L);
6749 sys2et[EPROTONOSUPPORT43] = UAEPROTONOSUPPORT(49733467L);
6750 sys2et[ESOCKTNOSUPPORT44] = UAESOCKTNOSUPPORT(49733468L);
6751 sys2et[EOPNOTSUPP45] = UAEOPNOTSUPP(49733469L);
6752 sys2et[EPFNOSUPPORT46] = UAEPFNOSUPPORT(49733470L);
6753 sys2et[EAFNOSUPPORT47] = UAEAFNOSUPPORT(49733471L);
6754 sys2et[EADDRINUSE48] = UAEADDRINUSE(49733472L);
6755 sys2et[EADDRNOTAVAIL49] = UAEADDRNOTAVAIL(49733473L);
6756 sys2et[ENETDOWN50] = UAENETDOWN(49733474L);
6757 sys2et[ENETUNREACH51] = UAENETUNREACH(49733475L);
6758 sys2et[ENETRESET52] = UAENETRESET(49733476L);
6759 sys2et[ECONNABORTED53] = UAECONNABORTED(49733477L);
6760 sys2et[ECONNRESET54] = UAECONNRESET(49733478L);
6761 sys2et[ENOBUFS55] = UAENOBUFS(49733479L);
6762 sys2et[EISCONN56] = UAEISCONN(49733480L);
6763 sys2et[ENOTCONN57] = UAENOTCONN(49733481L);
6764 sys2et[ESHUTDOWN58] = UAESHUTDOWN(49733482L);
6765 sys2et[ETOOMANYREFS59] = UAETOOMANYREFS(49733483L);
6766 sys2et[ETIMEDOUT60] = UAETIMEDOUT(49733484L);
6767 sys2et[ECONNREFUSED61] = UAECONNREFUSED(49733485L);
6768 sys2et[EHOSTDOWN64] = UAEHOSTDOWN(49733486L);
6769 sys2et[EHOSTUNREACH65] = UAEHOSTUNREACH(49733487L);
6770 sys2et[EALREADY37] = UAEALREADY(49733488L);
6771 sys2et[EINPROGRESS36] = UAEINPROGRESS(49733489L);
6772 sys2et[ESTALE70] = UAESTALE(49733490L);
6773 sys2et[EUCLEAN5] = UAEUCLEAN(49733491L);
6774 sys2et[ENOTNAM5] = UAENOTNAM(49733492L);
6775 sys2et[ENAVAIL5] = UAENAVAIL(49733493L);
6776 sys2et[EISNAM5] = UAEISNAM(49733494L);
6777 sys2et[EREMOTEIO5] = UAEREMOTEIO(49733495L);
6778 sys2et[EDQUOT69] = UAEDQUOT(49733496L);
6779 sys2et[ENOMEDIUM5] = UAENOMEDIUM(49733497L);
6780 sys2et[EMEDIUMTYPE5] = UAEMEDIUMTYPE(49733498L);
6781
6782 sys2et[EIO5] = UAEIO(49733380L);
6783}
6784
6785/* NOTE: 2006-03-01
6786 * SRXAFS_CallBackRxConnAddr should be re-written as follows:
6787 * - pass back the connection, client, and host from CallPreamble
6788 * - keep a ref on the client, which we don't now
6789 * - keep a hold on the host, which we already do
6790 * - pass the connection, client, and host down into SAFSS_*, and use
6791 * them instead of independently discovering them via rx_ConnectionOf
6792 * (safe) and rx_GetSpecific (not so safe)
6793 * The idea being that we decide what client and host we're going to use
6794 * when CallPreamble is called, and stay consistent throughout the call.
6795 * This change is too invasive for 1.4.1 but should be made in 1.5.x.
6796 */
6797
6798afs_int32
6799SRXAFS_CallBackRxConnAddr (struct rx_call * acall, afs_int32 *addr)
6800{
6801 Errorbit32 errorCode = 0;
6802 struct rx_connection *tcon;
6803 struct host *tcallhost;
6804#ifdef __EXPERIMENTAL_CALLBACK_CONN_MOVING
6805 struct host *thost;
6806 struct client *tclient;
6807 static struct rx_securityClass *sc = 0;
6808 int i,j;
6809 struct rx_connection *conn;
6810#endif
6811
6812 if ((errorCode = CallPreamble(acall, ACTIVECALL1, &tcon, &tcallhost)))
6813 goto Bad_CallBackRxConnAddr1;
6814
6815#ifndef __EXPERIMENTAL_CALLBACK_CONN_MOVING
6816 errorCode = 1;
6817#else
6818 H_LOCK(void)((pthread_mutex_lock(&host_glock_mutex) == 0) || (osi_AssertFailU
("pthread_mutex_lock(&host_glock_mutex) == 0", "./../viced/afsfileprocs.c"
, 6818), 0));
;
6819 tclient = h_FindClient_r(tcon);
6820 if (!tclient) {
6821 errorCode = VBUSY110;
6822 goto Bad_CallBackRxConnAddr;
6823 }
6824 thost = tclient->host;
6825
6826 /* nothing more can be done */
6827 if ( !thost->interface )
6828 goto Bad_CallBackRxConnAddr;
6829
6830 /* the only address is the primary interface */
6831 /* can't change when there's only 1 address, anyway */
6832 if ( thost->interface->numberOfInterfaces <= 1 )
6833 goto Bad_CallBackRxConnAddr;
6834
6835 /* initialise a security object only once */
6836 if ( !sc )
6837 sc = (struct rx_securityClass *) rxnull_NewClientSecurityObject();
6838
6839 for ( i=0; i < thost->interface->numberOfInterfaces; i++)
6840 {
6841 if ( *addr == thost->interface->addr[i] ) {
6842 break;
6843 }
6844 }
6845
6846 if ( *addr != thost->interface->addr[i] )
6847 goto Bad_CallBackRxConnAddr;
6848
6849 conn = rx_NewConnection (thost->interface->addr[i],
6850 thost->port, 1, sc, 0);
6851 rx_SetConnDeadTime(conn, 2);
6852 rx_SetConnHardDeadTime(conn, AFS_HARDDEADTIME120);
6853 H_UNLOCK(void)((pthread_mutex_unlock(&host_glock_mutex) == 0) || (
osi_AssertFailU("pthread_mutex_unlock(&host_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 6853), 0));
;
6854 errorCode = RXAFSCB_Probe(conn);
6855 H_LOCK(void)((pthread_mutex_lock(&host_glock_mutex) == 0) || (osi_AssertFailU
("pthread_mutex_lock(&host_glock_mutex) == 0", "./../viced/afsfileprocs.c"
, 6855), 0));
;
6856 if (!errorCode) {
6857 if ( thost->callback_rxcon )
6858 rx_DestroyConnection(thost->callback_rxcon);
6859 thost->callback_rxcon = conn;
6860 thost->host = addr;
6861 rx_SetConnDeadTime(thost->callback_rxcon, 50);
6862 rx_SetConnHardDeadTime(thost->callback_rxcon, AFS_HARDDEADTIME120);
6863 h_ReleaseClient_r(tclient);
6864 /* The hold on thost will be released by CallPostamble */
6865 H_UNLOCK(void)((pthread_mutex_unlock(&host_glock_mutex) == 0) || (
osi_AssertFailU("pthread_mutex_unlock(&host_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 6865), 0));
;
6866 errorCode = CallPostamble(tcon, errorCode, tcallhost);
6867 return errorCode;
6868 } else {
6869 rx_DestroyConnection(conn);
6870 }
6871 Bad_CallBackRxConnAddr:
6872 h_ReleaseClient_r(tclient);
6873 /* The hold on thost will be released by CallPostamble */
6874 H_UNLOCK(void)((pthread_mutex_unlock(&host_glock_mutex) == 0) || (
osi_AssertFailU("pthread_mutex_unlock(&host_glock_mutex) == 0"
, "./../viced/afsfileprocs.c", 6874), 0));
;
6875#endif
6876
6877 errorCode = CallPostamble(tcon, errorCode, tcallhost);
6878 Bad_CallBackRxConnAddr1:
6879 return errorCode; /* failure */
6880}
6881
6882afs_int32
6883sys_error_to_et(afs_int32 in)
6884{
6885 if (in == 0)
6886 return 0;
6887 if (in < 0 || in > 511)
6888 return in;
6889 if ((in >= VICE_SPECIAL_ERRORS101 && in <= VIO112) || in == VRESTRICTED120)
6890 return in;
6891 if (sys2et[in] != 0)
6892 return sys2et[in];
6893 return in;
6894}