1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright (c) 1999 by Sun Microsystems, Inc.
24 * All rights reserved.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 /*
30 * Code to maintain the runtime and on-disk filehandle mapping table for
31 * nfslog.
32 */
33
34 #include <assert.h>
35 #include <errno.h>
36 #include <nfs/nfs.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <strings.h>
40 #include <syslog.h>
41 #include <libintl.h>
42 #include <unistd.h>
43 #include <nfs/nfs.h>
44 #include <nfs/nfs_log.h>
45 #include "fhtab.h"
46 #include "nfslogd.h"
47
48 #define ROUNDUP32(val) (((val) + 3) & ~3)
49
50 #define IS_DOT_FILENAME(name) \
51 ((strcmp(name, ".") == 0) || (strcmp(name, "..") == 0))
52
53 #define PRINT_LINK_DATA(fp, func, dfh, name, str) \
54 (void) fprintf(fp, "%s: name '%s', dfh ", \
55 func, (((name) != NULL) ? name : "")); \
56 debug_opaque_print(fp, dfh, sizeof (*(dfh))); \
57 (void) fprintf(fp, "%s\n", str);
58
59
60 #define PRINT_FULL_DATA(fp, func, dfh, fh, name, str) \
61 (void) fprintf(fp, "%s: name '%s', dfh ", \
62 func, (((name) != NULL) ? name : "")); \
63 debug_opaque_print(fp, dfh, sizeof (*(dfh))); \
64 if ((fh) != NULL) { \
65 (void) fprintf(fp, ", fh "); \
66 debug_opaque_print(fp, fh, sizeof (*(fh))); \
67 } \
68 (void) fprintf(fp, "%s\n", str);
69
70 /*
71 * export handle cache
72 */
73 struct export_handle_cache {
74 fhandle_t fh;
75 char *name;
76 struct export_handle_cache *next;
77 };
78
79 static struct export_handle_cache *exp_handle_cache = NULL;
80
81 extern bool_t nfsl_prin_fh;
82
83 static int fh_add(char *, fhandle_t *, fhandle_t *, char *);
84
85 static char *get_export_path(fhandle_t *, char *);
86 static void sprint_fid(char *, uint_t, const fhandle_t *);
87 static void fh_print_all_keys(char *fhpath, fhandle_t *fh);
88 static int fh_compare(fhandle_t *fh1, fhandle_t *fh2);
89 static fhlist_ent *fh_lookup(char *fhpath, fhandle_t *fh, fhlist_ent *fhrecp,
90 int *errorp);
91 static int fh_remove_mc_link(char *fhpath, fhandle_t *dfh, char *name,
92 char **pathp);
93 static int fh_remove(char *fhpath, fhandle_t *dfh, char *name, char **pathp);
94 static int fh_rename(char *fhpath, fhandle_t *from_dfh, char *from_name,
95 char **from_pathp, fhandle_t *to_dfh, char *to_name);
96
97 static fhlist_ent *fh_lookup_link(char *fhpath, fhandle_t *dfh, fhandle_t *fh,
98 char *name, fhlist_ent *fhrecp, int *errorp);
99 static struct nfsl_fh_proc_disp *nfslog_find_fh_dispatch(
100 nfslog_request_record *);
101 static struct export_handle_cache *find_fh_in_export_cache(fhandle_t *fh);
102 static void add_fh_to_export_cache(fhandle_t *fh, char *path);
103 static char *update_export_point(char *fhpath, fhandle_t *fh, char *path);
104 static char *fh_print_absolute(char *fhpath, fhandle_t *fh, char *name);
105 static void nfslog_null_fhargs(caddr_t *nfsl_args, caddr_t *nfsl_res,
106 char *fhpath, char **pathp1, char **pathp2);
107 static void nfslog_LOOKUP_calc(fhandle_t *dfh, char *name, fhandle_t *fh,
108 char *fhpath, char **pathp1, char **pathp2, char *str);
109
110 /*
111 * NFS VERSION 2
112 */
113
114 /*
115 * Functions for updating the fhtable for fhtoppath and for returning
116 * the absolute pathname
117 */
118 static void nfslog_GETATTR2_fhargs(fhandle_t *,
119 nfsstat *, char *fhpath, char **, char **);
120 static void nfslog_SETATTR2_fhargs(nfslog_setattrargs *, nfsstat *,
121 char *, char **, char **);
122 static void nfslog_LOOKUP2_fhargs(nfslog_diropargs *, nfslog_diropres *,
123 char *, char **, char **);
124 static void nfslog_READLINK2_fhargs(fhandle_t *, nfslog_rdlnres *,
125 char *, char **, char **);
126 static void nfslog_READ2_fhargs(nfslog_nfsreadargs *, nfslog_rdresult *,
127 char *, char **, char **);
128 static void nfslog_WRITE2_fhargs(nfslog_writeargs *, nfslog_writeresult *,
129 char *, char **, char **);
130 static void nfslog_CREATE2_fhargs(nfslog_createargs *, nfslog_diropres*,
131 char *, char **, char **);
132 static void nfslog_REMOVE2_fhargs(nfslog_diropargs *, nfsstat *,
133 char *, char **, char **);
134 static void nfslog_RENAME2_fhargs(nfslog_rnmargs *, nfsstat *,
135 char *, char **, char **);
136 static void nfslog_LINK2_fhargs(nfslog_linkargs *, nfsstat *,
137 char *, char **, char **);
138 static void nfslog_SYMLINK2_fhargs(nfslog_symlinkargs *, nfsstat *,
139 char *, char **, char **);
140 static void nfslog_READDIR2_fhargs(nfslog_rddirargs *, nfslog_rddirres *,
141 char *, char **, char **);
142 static void nfslog_STATFS2_fhargs(fhandle_t *, nfsstat *,
143 char *, char **, char **);
144
145 /*
146 * NFS VERSION 3
147 *
148 * Functions for updating the fhtable for fhtoppath
149 */
150 static void nfslog_GETATTR3_fhargs(nfs_fh3 *, nfsstat3 *,
151 char *, char **, char **);
152 static void nfslog_SETATTR3_fhargs(nfslog_SETATTR3args *, nfsstat3 *,
153 char *, char **, char **);
154 static void nfslog_LOOKUP3_fhargs(nfslog_diropargs3 *, nfslog_LOOKUP3res *,
155 char *, char **, char **);
156 static void nfslog_ACCESS3_fhargs(nfs_fh3 *, nfsstat3 *,
157 char *, char **, char **);
158 static void nfslog_READLINK3_fhargs(nfs_fh3 *, nfslog_READLINK3res *,
159 char *, char **, char **);
160 static void nfslog_READ3_fhargs(nfslog_READ3args *, nfslog_READ3res *,
161 char *, char **, char **);
162 static void nfslog_WRITE3_fhargs(nfslog_WRITE3args *, nfslog_WRITE3res *,
163 char *, char **, char **);
164 static void nfslog_CREATE3_fhargs(nfslog_CREATE3args *, nfslog_CREATE3res *,
165 char *, char **, char **);
166 static void nfslog_MKDIR3_fhargs(nfslog_MKDIR3args *, nfslog_MKDIR3res *,
167 char *, char **, char **);
168 static void nfslog_SYMLINK3_fhargs(nfslog_SYMLINK3args *, nfslog_SYMLINK3res *,
169 char *, char **, char **);
170 static void nfslog_MKNOD3_fhargs(nfslog_MKNOD3args *, nfslog_MKNOD3res *,
171 char *, char **, char **);
172 static void nfslog_REMOVE3_fhargs(nfslog_REMOVE3args *, nfsstat3 *,
173 char *, char **, char **);
174 static void nfslog_RMDIR3_fhargs(nfslog_RMDIR3args *, nfsstat3 *,
175 char *, char **, char **);
176 static void nfslog_RENAME3_fhargs(nfslog_RENAME3args *, nfsstat3 *,
177 char *, char **, char **);
178 static void nfslog_LINK3_fhargs(nfslog_LINK3args *, nfsstat3 *,
179 char *, char **, char **);
180 static void nfslog_READDIR3_fhargs(nfs_fh3 *, nfsstat3 *,
181 char *, char **, char **);
182 static void nfslog_READDIRPLUS3_fhargs(nfslog_READDIRPLUS3args *,
183 nfslog_READDIRPLUS3res *,
184 char *, char **, char **);
185 static void nfslog_FSSTAT3_fhargs(nfs_fh3 *, nfsstat3 *,
186 char *, char **, char **);
187 static void nfslog_FSINFO3_fhargs(nfs_fh3 *, nfsstat3 *,
188 char *, char **, char **);
189 static void nfslog_PATHCONF3_fhargs(nfs_fh3 *, nfsstat3 *,
190 char *, char **, char **);
191 static void nfslog_COMMIT3_fhargs(nfslog_COMMIT3args *, nfsstat3 *,
192 char *, char **, char **);
193
194 /*
195 * NFSLOG VERSION 1
196 *
197 * Functions for updating the fhtable for fhtoppath
198 */
199 static void nfslog_SHARE_fhargs(nfslog_sharefsargs *, nfslog_sharefsres *,
200 char *, char **, char **);
201 static void nfslog_UNSHARE_fhargs(nfslog_sharefsargs *, nfslog_sharefsres *,
202 char *, char **, char **);
203 static void nfslog_GETFH_fhargs(nfslog_getfhargs *, nfsstat *,
204 char *, char **, char **);
205
206 /*
207 * Define the actions taken per prog/vers/proc:
208 *
209 * In some cases, the nl types are the same as the nfs types and a simple
210 * bcopy should suffice. Rather that define tens of identical procedures,
211 * simply define these to bcopy. Similarly this takes care of different
212 * procs that use same parameter struct.
213 */
214
215 static struct nfsl_fh_proc_disp nfsl_fh_proc_v2[] = {
216 /*
217 * NFS VERSION 2
218 */
219
220 /* RFS_NULL = 0 */
221 {nfslog_null_fhargs, xdr_void, xdr_void, 0, 0},
222
223 /* RFS_GETATTR = 1 */
224 {nfslog_GETATTR2_fhargs, xdr_fhandle, xdr_nfsstat,
225 sizeof (fhandle_t), sizeof (nfsstat)},
226
227 /* RFS_SETATTR = 2 */
228 {nfslog_SETATTR2_fhargs, xdr_nfslog_setattrargs, xdr_nfsstat,
229 sizeof (nfslog_setattrargs), sizeof (nfsstat)},
230
231 /* RFS_ROOT = 3 *** NO LONGER SUPPORTED *** */
232 {nfslog_null_fhargs, xdr_void, xdr_void, 0, 0},
233
234 /* RFS_LOOKUP = 4 */
235 {nfslog_LOOKUP2_fhargs, xdr_nfslog_diropargs, xdr_nfslog_diropres,
236 sizeof (nfslog_diropargs), sizeof (nfslog_diropres)},
237
238 /* RFS_READLINK = 5 */
239 {nfslog_READLINK2_fhargs, xdr_fhandle, xdr_nfslog_rdlnres,
240 sizeof (fhandle_t), sizeof (nfslog_rdlnres)},
241
242 /* RFS_READ = 6 */
243 {nfslog_READ2_fhargs, xdr_nfslog_nfsreadargs, xdr_nfslog_rdresult,
244 sizeof (nfslog_nfsreadargs), sizeof (nfslog_rdresult)},
245
246 /* RFS_WRITECACHE = 7 *** NO LONGER SUPPORTED *** */
247 {nfslog_null_fhargs, xdr_void, xdr_void, 0, 0},
248
249 /* RFS_WRITE = 8 */
250 {nfslog_WRITE2_fhargs, xdr_nfslog_writeargs, xdr_nfslog_writeresult,
251 sizeof (nfslog_writeargs), sizeof (nfslog_writeresult)},
252
253 /* RFS_CREATE = 9 */
254 {nfslog_CREATE2_fhargs, xdr_nfslog_createargs, xdr_nfslog_diropres,
255 sizeof (nfslog_createargs), sizeof (nfslog_diropres)},
256
257 /* RFS_REMOVE = 10 */
258 {nfslog_REMOVE2_fhargs, xdr_nfslog_diropargs, xdr_nfsstat,
259 sizeof (nfslog_diropargs), sizeof (nfsstat)},
260
261 /* RFS_RENAME = 11 */
262 {nfslog_RENAME2_fhargs, xdr_nfslog_rnmargs, xdr_nfsstat,
263 sizeof (nfslog_rnmargs), sizeof (nfsstat)},
264
265 /* RFS_LINK = 12 */
266 {nfslog_LINK2_fhargs, xdr_nfslog_linkargs, xdr_nfsstat,
267 sizeof (nfslog_linkargs), sizeof (nfsstat)},
268
269 /* RFS_SYMLINK = 13 */
270 {nfslog_SYMLINK2_fhargs, xdr_nfslog_symlinkargs, xdr_nfsstat,
271 sizeof (nfslog_symlinkargs), sizeof (nfsstat)},
272
273 /* RFS_MKDIR = 14 */
274 {nfslog_CREATE2_fhargs, xdr_nfslog_createargs, xdr_nfslog_diropres,
275 sizeof (nfslog_createargs), sizeof (nfslog_diropres)},
276
277 /* RFS_RMDIR = 15 */
278 {nfslog_REMOVE2_fhargs, xdr_nfslog_diropargs, xdr_nfsstat,
279 sizeof (nfslog_diropargs), sizeof (nfsstat)},
280
281 /* RFS_READDIR = 16 */
282 {nfslog_READDIR2_fhargs, xdr_nfslog_rddirargs, xdr_nfslog_rddirres,
283 sizeof (nfslog_rddirargs), sizeof (nfslog_rddirres)},
284
285 /* RFS_STATFS = 17 */
286 {nfslog_STATFS2_fhargs, xdr_fhandle, xdr_nfsstat,
287 sizeof (fhandle_t), sizeof (nfsstat)},
288 };
289
290
291 /*
292 * NFS VERSION 3
293 */
294
295 static struct nfsl_fh_proc_disp nfsl_fh_proc_v3[] = {
296
297 /* RFS_NULL = 0 */
298 {nfslog_null_fhargs, xdr_void, xdr_void, 0, 0},
299
300 /* RFS3_GETATTR = 1 */
301 {nfslog_GETATTR3_fhargs, xdr_nfs_fh3, xdr_nfsstat3,
302 sizeof (nfs_fh3), sizeof (nfsstat3)},
303
304 /* RFS3_SETATTR = 2 */
305 {nfslog_SETATTR3_fhargs, xdr_nfslog_SETATTR3args, xdr_nfsstat3,
306 sizeof (nfslog_SETATTR3args), sizeof (nfsstat3)},
307
308 /* RFS3_LOOKUP = 3 */
309 {nfslog_LOOKUP3_fhargs, xdr_nfslog_diropargs3, xdr_nfslog_LOOKUP3res,
310 sizeof (nfslog_diropargs3), sizeof (nfslog_LOOKUP3res)},
311
312 /* RFS3_ACCESS = 4 */
313 {nfslog_ACCESS3_fhargs, xdr_nfs_fh3, xdr_nfsstat3,
314 sizeof (nfs_fh3), sizeof (nfsstat3)},
315
316 /* RFS3_READLINK = 5 */
317 {nfslog_READLINK3_fhargs, xdr_nfs_fh3, xdr_nfslog_READLINK3res,
318 sizeof (nfs_fh3), sizeof (nfslog_READLINK3res)},
319
320 /* RFS3_READ = 6 */
321 {nfslog_READ3_fhargs, xdr_nfslog_READ3args, xdr_nfslog_READ3res,
322 sizeof (nfslog_READ3args), sizeof (nfslog_READ3res)},
323
324 /* RFS3_WRITE = 7 */
325 {nfslog_WRITE3_fhargs, xdr_nfslog_WRITE3args, xdr_nfslog_WRITE3res,
326 sizeof (nfslog_WRITE3args), sizeof (nfslog_WRITE3res)},
327
328 /* RFS3_CREATE = 8 */
329 {nfslog_CREATE3_fhargs, xdr_nfslog_CREATE3args, xdr_nfslog_CREATE3res,
330 sizeof (nfslog_CREATE3args), sizeof (nfslog_CREATE3res)},
331
332 /* RFS3_MKDIR = 9 */
333 {nfslog_MKDIR3_fhargs, xdr_nfslog_MKDIR3args, xdr_nfslog_MKDIR3res,
334 sizeof (nfslog_MKDIR3args), sizeof (nfslog_MKDIR3res)},
335
336 /* RFS3_SYMLINK = 10 */
337 {nfslog_SYMLINK3_fhargs, xdr_nfslog_SYMLINK3args,
338 xdr_nfslog_SYMLINK3res,
339 sizeof (nfslog_SYMLINK3args), sizeof (nfslog_SYMLINK3res)},
340
341 /* RFS3_MKNOD = 11 */
342 {nfslog_MKNOD3_fhargs, xdr_nfslog_MKNOD3args, xdr_nfslog_MKNOD3res,
343 sizeof (nfslog_MKNOD3args), sizeof (nfslog_MKNOD3res)},
344
345 /* RFS3_REMOVE = 12 */
346 {nfslog_REMOVE3_fhargs, xdr_nfslog_REMOVE3args, xdr_nfsstat3,
347 sizeof (nfslog_REMOVE3args), sizeof (nfsstat3)},
348
349 /* RFS3_RMDIR = 13 */
350 {nfslog_RMDIR3_fhargs, xdr_nfslog_RMDIR3args, xdr_nfsstat3,
351 sizeof (nfslog_RMDIR3args), sizeof (nfsstat3)},
352
353 /* RFS3_RENAME = 14 */
354 {nfslog_RENAME3_fhargs, xdr_nfslog_RENAME3args, xdr_nfsstat3,
355 sizeof (nfslog_RENAME3args), sizeof (nfsstat3)},
356
357 /* RFS3_LINK = 15 */
358 {nfslog_LINK3_fhargs, xdr_nfslog_LINK3args, xdr_nfsstat3,
359 sizeof (nfslog_LINK3args), sizeof (nfsstat3)},
360
361 /* RFS3_READDIR = 16 */
362 {nfslog_READDIR3_fhargs, xdr_nfs_fh3, xdr_nfsstat3,
363 sizeof (nfs_fh3), sizeof (nfsstat3)},
364
365 /* RFS3_READDIRPLUS = 17 */
366 {nfslog_READDIRPLUS3_fhargs,
367 xdr_nfslog_READDIRPLUS3args, xdr_nfslog_READDIRPLUS3res,
368 sizeof (nfslog_READDIRPLUS3args),
369 sizeof (nfslog_READDIRPLUS3res)},
370
371 /* RFS3_FSSTAT = 18 */
372 {nfslog_FSSTAT3_fhargs, xdr_nfs_fh3, xdr_nfsstat3,
373 sizeof (nfs_fh3), sizeof (nfsstat3)},
374
375 /* RFS3_FSINFO = 19 */
376 {nfslog_FSINFO3_fhargs, xdr_nfs_fh3, xdr_nfsstat3,
377 sizeof (nfs_fh3), sizeof (nfsstat3)},
378
379 /* RFS3_PATHCONF = 20 */
380 {nfslog_PATHCONF3_fhargs, xdr_nfs_fh3, xdr_nfsstat3,
381 sizeof (nfs_fh3), sizeof (nfsstat3)},
382
383 /* RFS3_COMMIT = 21 */
384 {nfslog_COMMIT3_fhargs, xdr_nfslog_COMMIT3args, xdr_nfsstat3,
385 sizeof (nfslog_COMMIT3args), sizeof (nfsstat3)},
386 };
387
388 /*
389 * NFSLOG VERSION 1
390 */
391
392 static struct nfsl_fh_proc_disp nfsl_log_fh_proc_v1[] = {
393
394 /* NFSLOG_NULL = 0 */
395 {nfslog_null_fhargs, xdr_void, xdr_void, 0, 0},
396
397 /* NFSLOG_SHARE = 1 */
398 {nfslog_SHARE_fhargs, xdr_nfslog_sharefsargs, xdr_nfslog_sharefsres,
399 sizeof (nfslog_sharefsargs), sizeof (nfslog_sharefsres)},
400
401 /* NFSLOG_UNSHARE = 2 */
402 {nfslog_UNSHARE_fhargs, xdr_nfslog_sharefsargs, xdr_nfslog_sharefsres,
403 sizeof (nfslog_sharefsargs), sizeof (nfslog_sharefsres)},
404
405 /* NFSLOG_LOOKUP3 = 3 */
406 {nfslog_LOOKUP3_fhargs, xdr_nfslog_diropargs3, xdr_nfslog_LOOKUP3res,
407 sizeof (nfslog_diropargs3), sizeof (nfslog_LOOKUP3res)},
408
409 /* NFSLOG_GETFH = 4 */
410 {nfslog_GETFH_fhargs, xdr_nfslog_getfhargs, xdr_nfsstat,
411 sizeof (nfslog_getfhargs), sizeof (nfsstat)},
412 };
413
414 static struct nfsl_fh_vers_disp nfsl_fh_vers_disptable[] = {
415 {sizeof (nfsl_fh_proc_v2) / sizeof (nfsl_fh_proc_v2[0]),
416 nfsl_fh_proc_v2},
417 {sizeof (nfsl_fh_proc_v3) / sizeof (nfsl_fh_proc_v3[0]),
418 nfsl_fh_proc_v3},
419 };
420
421 static struct nfsl_fh_vers_disp nfsl_log_fh_vers_disptable[] = {
422 {sizeof (nfsl_log_fh_proc_v1) / sizeof (nfsl_log_fh_proc_v1[0]),
423 nfsl_log_fh_proc_v1},
424 };
425
426 static struct nfsl_fh_prog_disp nfsl_fh_dispatch_table[] = {
427 {NFS_PROGRAM,
428 NFS_VERSMIN,
429 sizeof (nfsl_fh_vers_disptable) /
430 sizeof (nfsl_fh_vers_disptable[0]),
431 nfsl_fh_vers_disptable},
432 {NFSLOG_PROGRAM,
433 NFSLOG_VERSMIN,
434 sizeof (nfsl_log_fh_vers_disptable) /
435 sizeof (nfsl_log_fh_vers_disptable[0]),
436 nfsl_log_fh_vers_disptable},
437 };
438
439 static int nfsl_fh_dispatch_table_arglen =
440 sizeof (nfsl_fh_dispatch_table) /
441 sizeof (nfsl_fh_dispatch_table[0]);
442
443 extern int debug;
444
445 /*
446 * print the fid into the given string as a series of hex digits.
447 * XXX Ideally, we'd like to just convert the filehandle into an i-number,
448 * but the fid encoding is a little tricky (see nfs_fhtovp() and
449 * ufs_vget()) and may be private to UFS.
450 */
451
452 static void
sprint_fid(char * buf,uint_t buflen,const fhandle_t * fh)453 sprint_fid(char *buf, uint_t buflen, const fhandle_t *fh)
454 {
455 int i;
456 uchar_t byte;
457 uint_t fhlen;
458
459 /*
460 * If the filehandle somehow got corrupted, only print the part
461 * that makes sense.
462 */
463 if (fh->fh_len > NFS_FHMAXDATA)
464 fhlen = NFS_FHMAXDATA;
465 else
466 fhlen = fh->fh_len;
467 assert(2 * fhlen < buflen);
468
469 for (i = 0; i < fhlen; i++) {
470 byte = fh->fh_data[i];
471 (void) sprintf(buf + 2 * i, "%02x", byte);
472 }
473 }
474
475 static void
fh_print_all_keys(char * fhpath,fhandle_t * fh)476 fh_print_all_keys(char *fhpath, fhandle_t *fh)
477 {
478 if ((fhpath == NULL) || (fh == NULL) || (debug <= 1))
479 return;
480 (void) printf("\nBegin all database keys\n");
481 db_print_all_keys(fhpath, &fh->fh_fsid, stdout);
482 (void) printf("\nEnd all database keys\n");
483 }
484
485 #define FH_ADD(path, dfh, fh, name) \
486 fh_add(path, dfh, fh, name)
487
488 /*
489 * Add the filehandle "fh", which has the name "name" and lives in
490 * directory "dfh", to the table "fhlist". "fhlist" will be updated if the
491 * entry is added to the front of the list.
492 * Return 0 for success, error code otherwise.
493 */
494 static int
fh_add(char * fhpath,fhandle_t * dfh,fhandle_t * fh,char * name)495 fh_add(char *fhpath, fhandle_t *dfh, fhandle_t *fh, char *name)
496 {
497 uint_t flags = 0;
498 int error;
499
500 if (IS_DOT_FILENAME(name)) {
501 /* we don't insert these to the database but not an error */
502 if (debug > 3) {
503 PRINT_FULL_DATA(stdout, "fh_add", dfh, fh, name,
504 " - no dot files")
505 }
506 return (0);
507 }
508 if (dfh && (memcmp(fh, dfh, NFS_FHSIZE) == 0)) {
509 flags |= EXPORT_POINT;
510 }
511
512 /* Add to database */
513 error = db_add(fhpath, dfh, name, fh, flags);
514 if (debug > 1) {
515 if (error != 0) {
516 (void) printf("db_add error %s:\n",
517 ((error >= 0) ? strerror(error) : "Unknown"));
518 PRINT_FULL_DATA(stdout, "fh_add", dfh, fh, name, "")
519 } else if (debug > 2) {
520 PRINT_FULL_DATA(stdout, "fh_add", dfh, fh, name, "")
521 }
522 }
523 return (error);
524 }
525
526 /*
527 * fh_compare returns 0 if the file handles match, error code otherwise
528 */
529 static int
fh_compare(fhandle_t * fh1,fhandle_t * fh2)530 fh_compare(fhandle_t *fh1, fhandle_t *fh2)
531 {
532 if (memcmp(fh1, fh2, NFS_FHSIZE))
533 return (errno);
534 else
535 return (0);
536 }
537
538 /*
539 * Try to find the filehandle "fh" in the table. Returns 0 and the
540 * corresponding table entry if found, error otherwise.
541 * If successfull and fhrecpp is non-null then *fhrecpp points to the
542 * returned record. If *fhrecpp was initially null, that record had
543 * been malloc'd and must be freed by caller.
544 */
545
546 static fhlist_ent *
fh_lookup(char * fhpath,fhandle_t * fh,fhlist_ent * fhrecp,int * errorp)547 fh_lookup(char *fhpath, fhandle_t *fh, fhlist_ent *fhrecp, int *errorp)
548 {
549 if (debug > 3) {
550 (void) printf("fh_lookup: fh ");
551 debug_opaque_print(stdout, fh, sizeof (*fh));
552 (void) printf("\n");
553 }
554 return (db_lookup(fhpath, fh, fhrecp, errorp));
555 }
556
557 /*
558 * Remove the mc link if exists when removing a regular link.
559 * Return 0 for success, error code otherwise.
560 */
561 static int
fh_remove_mc_link(char * fhpath,fhandle_t * dfh,char * name,char ** pathp)562 fh_remove_mc_link(char *fhpath, fhandle_t *dfh, char *name, char **pathp)
563 {
564 int error;
565 char *str, *str1;
566
567 /* Delete the multi-component path if exists */
568 if ((pathp == NULL) || (*pathp == NULL)) {
569 str = nfslog_get_path(dfh, name, fhpath, "remove_mc_link");
570 str1 = str;
571 } else {
572 str = *pathp;
573 str1 = NULL;
574 }
575 error = db_delete_link(fhpath, &public_fh, str);
576 if (str1 != NULL)
577 free(str1);
578 return (error);
579 }
580
581 /*
582 * Remove the link entry from the fh table.
583 * Return 0 for success, error code otherwise.
584 */
585 static int
fh_remove(char * fhpath,fhandle_t * dfh,char * name,char ** pathp)586 fh_remove(char *fhpath, fhandle_t *dfh, char *name, char **pathp)
587 {
588 /*
589 * disconnect element from list
590 *
591 * Remove the link entry for the file. Remove fh entry if last link.
592 */
593 if (IS_DOT_FILENAME(name)) {
594 /* we don't insert these to the database but not an error */
595 if (debug > 2) {
596 PRINT_LINK_DATA(stdout, "fh_remove", dfh, name,
597 " - no dot files")
598 }
599 return (0);
600 }
601 if (debug > 2) {
602 PRINT_LINK_DATA(stdout, "fh_remove", dfh, name, "")
603 }
604 /* Delete the multi-component path if exists */
605 (void) fh_remove_mc_link(fhpath, dfh, name, pathp);
606 return (db_delete_link(fhpath, dfh, name));
607 }
608
609 /*
610 * fh_rename - renames a link in the database (adds the new one if from link
611 * did not exist).
612 * Return 0 for success, error code otherwise.
613 */
614 static int
fh_rename(char * fhpath,fhandle_t * from_dfh,char * from_name,char ** from_pathp,fhandle_t * to_dfh,char * to_name)615 fh_rename(char *fhpath, fhandle_t *from_dfh, char *from_name, char **from_pathp,
616 fhandle_t *to_dfh, char *to_name)
617 {
618 if (debug > 2) {
619 PRINT_LINK_DATA(stdout, "fh_rename: from:", from_dfh,
620 from_name, "")
621 PRINT_LINK_DATA(stdout, "fh_rename: to :", to_dfh,
622 to_name, "")
623 }
624 /*
625 * if any of these are dot files (should not happen), the rename
626 * becomes a "delete" or "add" operation because the dot files
627 * don't get in the database
628 */
629 if (IS_DOT_FILENAME(to_name)) {
630 /* it is just a delete op */
631 if (debug > 2) {
632 (void) printf("to: no dot files\nDelete from: '%s'\n",
633 from_name);
634 }
635 return (fh_remove(fhpath, from_dfh, from_name, from_pathp));
636 } else if (IS_DOT_FILENAME(from_name)) {
637 /* we don't insert these to the database */
638 if (debug > 2) {
639 (void) printf("rename - from: no dot files\n");
640 }
641 /* can't insert the target, because don't have a handle */
642 return (EINVAL);
643 }
644 /* Delete the multi-component path if exists */
645 (void) fh_remove_mc_link(fhpath, from_dfh, from_name, from_pathp);
646 return (db_rename_link(fhpath, from_dfh, from_name, to_dfh, to_name));
647 }
648
649 /*
650 * fh_lookup_link - search the fhtable for the link defined by (dfh,name,fh).
651 * Return 0 and set *fhrecpp to the fhlist item corresponding to it if found,
652 * or error if not found.
653 * Possible configurations:
654 * 1. dfh, fh, name are all non-null: Only exact match accepted.
655 * 2. dfh,name non-null, fh null: return first match found.
656 * 3. fh,name non-null, dfh null: return first match found.
657 * 3. fh non-null, dfh, name null: return first match found.
658 * If successfull and fhrecpp is non-null then *fhrecpp points to the
659 * returned record. If *fhrecpp was initially null, that record had
660 * been malloc'd and must be freed by caller.
661 */
662 static fhlist_ent *
fh_lookup_link(char * fhpath,fhandle_t * dfh,fhandle_t * fh,char * name,fhlist_ent * fhrecp,int * errorp)663 fh_lookup_link(char *fhpath, fhandle_t *dfh, fhandle_t *fh, char *name,
664 fhlist_ent *fhrecp, int *errorp)
665 {
666 fhlist_ent *in_fhrecp = fhrecp;
667
668 if ((name != NULL) && IS_DOT_FILENAME(name)) {
669 /* we don't insert these to the database but not an error */
670 if (debug > 2) {
671 PRINT_FULL_DATA(stdout, "fh_lookup_link", dfh, fh, name,
672 " - no dot files\n")
673 }
674 *errorp = 0;
675 return (NULL);
676 }
677 if (debug > 3) {
678 PRINT_FULL_DATA(stdout, "fh_lookup_link", dfh, fh, name, "")
679 }
680 /* Add to database */
681 if (fh != NULL) {
682 fhrecp = db_lookup(fhpath, fh, fhrecp, errorp);
683 if (fhrecp == NULL) {
684 if (debug > 3)
685 (void) printf("fh_lookup_link: fh not found\n");
686 return (NULL);
687 }
688 /* Check if name and dfh match, if not search link */
689 if (((dfh == NULL) || !fh_compare(dfh, &fhrecp->dfh)) &&
690 ((name == NULL) || (strcmp(name, fhrecp->name) == 0))) {
691 /* found it */
692 goto exit;
693 }
694 /* Found the primary record, but it's a different link */
695 if (debug == 3) { /* Only log if >2 but already printed */
696 PRINT_FULL_DATA(stdout, "fh_lookup_link", dfh, fh,
697 name, "")
698 }
699 if (debug > 2) {
700 PRINT_LINK_DATA(stdout, "Different primary link",
701 &fhrecp->dfh, fhrecp->name, "")
702 }
703 /* can now free the record unless it was supplied by caller */
704 if (fhrecp != in_fhrecp) {
705 free(fhrecp);
706 fhrecp = NULL;
707 }
708 }
709 /* If here, we must search by link */
710 if ((dfh == NULL) || (name == NULL)) {
711 if (debug > 2)
712 (void) printf("fh_lookup_link: invalid params\n");
713 *errorp = EINVAL;
714 return (NULL);
715 }
716 fhrecp = db_lookup_link(fhpath, dfh, name, fhrecp, errorp);
717 if (fhrecp == NULL) {
718 if (debug > 3)
719 (void) printf("fh_lookup_link: link not found: %s\n",
720 ((*errorp >= 0) ? strerror(*errorp) : "Unknown"));
721 return (NULL);
722 }
723 /* If all args supplied, check if an exact match */
724 if ((fh != NULL) && fh_compare(fh, &fhrecp->fh)) {
725 if (debug > 2) {
726 PRINT_FULL_DATA(stderr, "fh_lookup_link", dfh, fh,
727 name, "")
728 PRINT_LINK_DATA(stderr, "Different primary link",
729 &fhrecp->dfh, fhrecp->name, "")
730 }
731 if (fhrecp != in_fhrecp)
732 free(fhrecp);
733 *errorp = EINVAL;
734 return (NULL);
735 }
736 exit:
737 if (debug > 3)
738 (void) printf("lookup: found '%s' in fhtable\n", name);
739 *errorp = 0;
740 return (fhrecp);
741 }
742
743 /*
744 * Export handle cache is maintained if we see an export handle that either
745 * cannot have the path for it determined, or we failed store it.
746 * Usually the path of an export handle can be identified in the NFSLOGTAB
747 * and since every path for that filesystem will be affected, it's worth
748 * caching the ones we had problem identifying.
749 */
750
751 /*
752 * find_fh_in_export_cache - given an export fh, find it in the cache and
753 * return the handle
754 */
755 static struct export_handle_cache *
find_fh_in_export_cache(fhandle_t * fh)756 find_fh_in_export_cache(fhandle_t *fh)
757 {
758 struct export_handle_cache *p;
759
760 for (p = exp_handle_cache; p != NULL; p = p->next) {
761 if (memcmp(fh, &p->fh, sizeof (*fh)) == 0)
762 break;
763 }
764 return (p);
765 }
766
767 static void
add_fh_to_export_cache(fhandle_t * fh,char * path)768 add_fh_to_export_cache(fhandle_t *fh, char *path)
769 {
770 struct export_handle_cache *new;
771
772 if ((new = malloc(sizeof (*new))) == NULL) {
773 syslog(LOG_ERR, gettext(
774 "add_fh_to_export_cache: alloc new for '%s' Error %s\n"),
775 ((path != NULL) ? path : ""), strerror(errno));
776 return;
777 }
778 if (path != NULL) {
779 if ((new->name = malloc(strlen(path) + 1)) == NULL) {
780 syslog(LOG_ERR, gettext(
781 "add_fh_to_export_cache: alloc '%s'"
782 " Error %s\n"), path, strerror(errno));
783 free(new);
784 return;
785 }
786 (void) strcpy(new->name, path);
787 } else {
788 new->name = NULL;
789 }
790 (void) memcpy(&new->fh, fh, sizeof (*fh));
791 new->next = exp_handle_cache;
792 exp_handle_cache = new;
793 }
794
795 /*
796 * update_export_point - called when the path for fh cannot be determined.
797 * In the past it called get_export_path() to get the name of the
798 * export point given a filehandle. This was a hack, since there's no
799 * reason why the filehandle should be lost.
800 *
801 * If a match is found, insert the path to the database.
802 * Return the inserted fhrecp is found,
803 * and NULL if not. If it is an exported fs but not in the list, log a
804 * error.
805 * If input fhrecp is non-null, it is a valid address for result,
806 * otherwise malloc it.
807 */
808 static char *
update_export_point(char * fhpath,fhandle_t * fh,char * path)809 update_export_point(char *fhpath, fhandle_t *fh, char *path)
810 {
811 struct export_handle_cache *p;
812
813 if ((fh == NULL) || memcmp(&fh->fh_data, &fh->fh_xdata, fh->fh_len)) {
814 /* either null fh or not the root of a shared directory */
815 return (NULL);
816 }
817 /* Did we already see (and fail) this one? */
818 if ((p = find_fh_in_export_cache(fh)) != NULL) {
819 /* Found it! */
820 if (debug > 2) {
821 PRINT_LINK_DATA(stdout, "update_export_point",
822 fh, ((p->name != NULL) ? p->name : ""), "");
823 }
824 if (p->name == NULL)
825 return (NULL);
826 /*
827 * We should not normally be here - only add to cache if
828 * fh_add failed.
829 */
830 if ((path == NULL) &&
831 ((path = malloc(strlen(p->name) + 1)) == NULL)) {
832 syslog(LOG_ERR, gettext(
833 "update_export_point: malloc '%s' Error %s"),
834 p->name, strerror(errno));
835 return (NULL);
836 }
837 (void) strcpy(path, p->name);
838 return (path);
839 }
840 if ((path = get_export_path(fh, path)) == NULL) {
841 add_fh_to_export_cache(fh, NULL);
842 return (NULL);
843 }
844 /* Found it! */
845 if (debug > 2) {
846 PRINT_LINK_DATA(stdout, "update_export_point", fh, path, "")
847 }
848 if (FH_ADD(fhpath, fh, fh, path)) {
849 /* cache this handle so we don't repeat the search */
850 add_fh_to_export_cache(fh, path);
851 }
852 return (path);
853 }
854
855 /*
856 * HACK!!! To get rid of get_export_path() use
857 */
858 /* ARGSUSED */
859 static char *
get_export_path(fhandle_t * fh,char * path)860 get_export_path(fhandle_t *fh, char *path)
861 {
862 return (NULL);
863 }
864
865 /*
866 * Return the absolute pathname for the filehandle "fh", using the mapping
867 * table "fhlist". The caller must free the return string.
868 * name is an optional dir component name, to be appended at the end
869 * (if name is non-null, the function assumes the fh is the parent directory)
870 *
871 * Note: The original code was recursive, which was much more elegant but
872 * ran out of stack...
873 */
874
875 static char *
fh_print_absolute(char * fhpath,fhandle_t * fh,char * name)876 fh_print_absolute(char *fhpath, fhandle_t *fh, char *name)
877 {
878 char *str, *rootname, parent[MAXPATHLEN];
879 int i, j, k, len, error;
880 fhlist_ent fhrec, *fhrecp;
881 fhandle_t prevfh;
882 int namelen;
883
884 if (debug > 3)
885 (void) printf("fh_print_absolute: input name '%s'\n",
886 ((name != NULL) ? name : ""));
887 /* If name starts with '/' we are done */
888 if ((name != NULL) && (name[0] == '/')) {
889 if ((str = strdup(name)) == NULL) {
890 syslog(LOG_ERR, gettext(
891 "fh_print_absolute: strdup '%s' error %s\n"),
892 name, strerror(errno));
893 }
894 return (str);
895 }
896 namelen = ((name != NULL) ? strlen(name) + 2 : 0);
897 parent[0] = '\0';
898
899 /* remember the last filehandle we've seen */
900 (void) memcpy((void *) &prevfh, (void *) fh, sizeof (*fh));
901 fh = &prevfh;
902
903 /* dump all names in reverse order */
904 while ((fhrecp = fh_lookup(fhpath, fh, &fhrec, &error)) != NULL &&
905 !(fhrecp->flags & (EXPORT_POINT | PUBLIC_PATH))) {
906
907 if (debug > 3) {
908 (void) printf("fh_print_absolute: name '%s'%s\n",
909 fhrecp->name,
910 ((fhrecp->flags & EXPORT_POINT) ? "root" : ""));
911 }
912 if (memcmp(&prevfh, &fhrecp->dfh, sizeof (*fh)) == 0) {
913 /* dfh == prevfh but not an export point */
914 if (debug > 1) {
915 (void) printf(
916 "fh_print_absolute: fhrec loop:\n");
917 debug_opaque_print(stdout, fhrecp,
918 fhrecp->reclen);
919 }
920 break;
921 }
922 (void) strcat(parent, "/");
923 (void) strcat(parent, fhrecp->name);
924
925 /* remember the last filehandle we've seen */
926 (void) memcpy(&prevfh, &fhrecp->dfh, sizeof (fhrecp->dfh));
927 }
928 assert(fh == &prevfh);
929
930 if (fhrecp != NULL) {
931 rootname = fhrecp->name;
932 } else {
933 /* Check if export point, just in case... */
934 /* There should be enough room in parent, leave the '\0' */
935 rootname = update_export_point(
936 fhpath, fh, &parent[strlen(parent) + 1]);
937 }
938 /* Now need to reverse the order */
939 if (rootname != NULL) { /* *fhrecp is the export point */
940 len = strlen(rootname) + 2;
941 } else {
942 len = 2 * (NFS_FHMAXDATA + fh->fh_len); /* fid instead */
943 }
944 len = ROUNDUP32(len + namelen + strlen(parent));
945 if ((str = malloc(len)) == NULL) {
946 syslog(LOG_ERR, gettext(
947 "fh_print_absolute: malloc %d error %s\n"),
948 len, strerror(errno));
949 return (NULL);
950 }
951 /* first put the export point path in */
952 if (rootname != NULL) { /* *fhrecp is the export point */
953 (void) strcpy(str, rootname);
954 } else {
955 sprint_fid(str, len, fh);
956 }
957 for (k = strlen(str), i = strlen(parent); (k < len) && (i >= 0); i--) {
958 for (j = i; (j >= 0) && (parent[j] != '/'); j--);
959 if (j < 0)
960 break;
961 (void) strcpy(&str[k], &parent[j]);
962 k += strlen(&str[k]);
963 parent[j] = '\0';
964 }
965 if ((name != NULL) && ((k + namelen) <= len)) {
966 str[k] = '/';
967 (void) strcpy(&str[k + 1], name);
968 }
969 if (debug > 3)
970 (void) printf("fh_print_absolute: path '%s'\n", str);
971 return (str);
972 }
973
974 /*
975 * nfslog_find_fh_dispatch - get the dispatch struct for this request
976 */
977 static struct nfsl_fh_proc_disp *
nfslog_find_fh_dispatch(nfslog_request_record * logrec)978 nfslog_find_fh_dispatch(nfslog_request_record *logrec)
979 {
980 nfslog_record_header *logrechdr = &logrec->re_header;
981 struct nfsl_fh_prog_disp *progtable; /* prog struct */
982 struct nfsl_fh_vers_disp *verstable; /* version struct */
983 int i, vers;
984
985 /* Find prog element - search because can't use prog as array index */
986 for (i = 0; (i < nfsl_fh_dispatch_table_arglen) &&
987 (logrechdr->rh_prognum != nfsl_fh_dispatch_table[i].nfsl_dis_prog);
988 i++);
989 if (i >= nfsl_fh_dispatch_table_arglen) { /* program not logged */
990 /* not an error */
991 return (NULL);
992 }
993 progtable = &nfsl_fh_dispatch_table[i];
994 /* Find vers element - no validity check - if here it's valid vers */
995 vers = logrechdr->rh_version - progtable->nfsl_dis_versmin;
996 verstable = &progtable->nfsl_dis_vers_table[vers];
997 /* Find proc element - no validity check - if here it's valid proc */
998 return (&verstable->nfsl_dis_proc_table[logrechdr->rh_procnum]);
999 }
1000
1001 /* ARGSUSED */
1002 static void
nfslog_null_fhargs(caddr_t * nfsl_args,caddr_t * nfsl_res,char * fhpath,char ** pathp1,char ** pathp2)1003 nfslog_null_fhargs(caddr_t *nfsl_args, caddr_t *nfsl_res,
1004 char *fhpath, char **pathp1, char **pathp2)
1005 {
1006 *pathp1 = NULL;
1007 *pathp2 = NULL;
1008 }
1009
1010 /*
1011 * nfslog_LOOKUP_calc - called by both lookup3 and lookup2. Handles the
1012 * mclookup as well as normal lookups.
1013 */
1014 /* ARGSUSED */
1015 static void
nfslog_LOOKUP_calc(fhandle_t * dfh,char * name,fhandle_t * fh,char * fhpath,char ** pathp1,char ** pathp2,char * str)1016 nfslog_LOOKUP_calc(fhandle_t *dfh, char *name, fhandle_t *fh,
1017 char *fhpath, char **pathp1, char **pathp2, char *str)
1018 {
1019 int error;
1020 fhlist_ent fhrec;
1021 char *name1 = NULL;
1022
1023 if (fh == &public_fh) {
1024 /* a fake lookup to inform us of the public fs path */
1025 if (error = FH_ADD(fhpath, fh, fh, name)) {
1026 syslog(LOG_ERR, gettext(
1027 "%s: Add Public fs '%s' failed: %s\n"),
1028 str, name,
1029 ((error >= 0) ? strerror(error) : "Unknown"));
1030 }
1031 if (pathp1 != NULL) {
1032 *pathp1 = nfslog_get_path(dfh, NULL, fhpath, str);
1033 *pathp2 = NULL;
1034 }
1035 return;
1036 }
1037 if (pathp1 != NULL) {
1038 *pathp1 = nfslog_get_path(dfh, name, fhpath, str);
1039 *pathp2 = NULL;
1040 }
1041
1042 /* If public fh mclookup, then insert complete path */
1043 if (dfh == &public_fh) {
1044 if (pathp1 != NULL) {
1045 name = *pathp1;
1046 } else {
1047 name = nfslog_get_path(dfh, name, fhpath, str);
1048 name1 = name;
1049 }
1050 }
1051 if (fh_lookup_link(fhpath, dfh, fh, name, &fhrec, &error) != NULL) {
1052 /* link already in table */
1053 if (name1 != NULL)
1054 free(name1);
1055 return;
1056 }
1057 /* A new link so add it */
1058 if (error = FH_ADD(fhpath, dfh, fh, name)) {
1059 syslog(LOG_ERR, gettext(
1060 "%s: Add fh for '%s' failed: %s\n"), str,
1061 name, ((error >= 0) ? strerror(error) : "Unknown"));
1062 }
1063 if (name1 != NULL)
1064 free(name1);
1065 }
1066
1067 /*
1068 * NFS VERSION 2
1069 */
1070
1071 /* Functions for updating the fhtable for fhtoppath */
1072
1073 /*
1074 * nfslog_GETATTR2_fhargs - updates path1 but no fhtable changes
1075 */
1076 /* ARGSUSED */
1077 static void
nfslog_GETATTR2_fhargs(fhandle_t * args,nfsstat * res,char * fhpath,char ** pathp1,char ** pathp2)1078 nfslog_GETATTR2_fhargs(fhandle_t *args, nfsstat *res,
1079 char *fhpath, char **pathp1, char **pathp2)
1080 {
1081 if (debug > 2) {
1082 (void) printf("=============\nGETATTR2: fh ");
1083 debug_opaque_print(stdout, args, sizeof (*args));
1084 (void) printf("\n");
1085 }
1086 if (pathp1 != NULL) {
1087 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE2(args),
1088 NULL, fhpath, "getattr2");
1089 *pathp2 = NULL;
1090 }
1091 }
1092
1093 /*
1094 * nfslog_SETATTR2_fhargs - updates path1 but no fhtable changes
1095 */
1096 /* ARGSUSED */
1097 static void
nfslog_SETATTR2_fhargs(nfslog_setattrargs * args,nfsstat * res,char * fhpath,char ** pathp1,char ** pathp2)1098 nfslog_SETATTR2_fhargs(nfslog_setattrargs *args, nfsstat *res,
1099 char *fhpath, char **pathp1, char **pathp2)
1100 {
1101 if (debug > 2) {
1102 (void) printf("=============\nSETATTR2: fh ");
1103 debug_opaque_print(stdout, &args->saa_fh,
1104 sizeof (args->saa_fh));
1105 (void) printf("\n");
1106 }
1107 if (pathp1 != NULL) {
1108 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE2(&args->saa_fh),
1109 NULL, fhpath, "setattr2");
1110 *pathp2 = NULL;
1111 }
1112 }
1113
1114 /*
1115 * nfslog_LOOKUP2_fhargs - search the table to ensure we have not added this
1116 * one already. Note that if the response status was anything but okay,
1117 * there is no fh to check...
1118 */
1119 /* ARGSUSED */
1120 static void
nfslog_LOOKUP2_fhargs(nfslog_diropargs * args,nfslog_diropres * res,char * fhpath,char ** pathp1,char ** pathp2)1121 nfslog_LOOKUP2_fhargs(nfslog_diropargs *args, nfslog_diropres *res,
1122 char *fhpath, char **pathp1, char **pathp2)
1123 {
1124 char *name;
1125 fhandle_t *dfh, *fh;
1126
1127 dfh = &args->da_fhandle;
1128 name = args->da_name;
1129 if (debug > 2) {
1130 if (res->dr_status == NFS_OK)
1131 fh = &res->nfslog_diropres_u.dr_ok.drok_fhandle;
1132 else
1133 fh = NULL;
1134 PRINT_FULL_DATA(stdout, "=============\nLOOKUP2",
1135 dfh, fh, name, "")
1136 if (res->dr_status != NFS_OK)
1137 (void) printf("status %d\n", res->dr_status);
1138 }
1139 dfh = NFSLOG_GET_FHANDLE2(dfh);
1140 if ((dfh == &public_fh) && (name[0] == '\x80')) {
1141 /* special mclookup */
1142 name = &name[1];
1143 }
1144 if (res->dr_status != NFS_OK) {
1145 if (pathp1 != NULL) {
1146 *pathp1 = nfslog_get_path(dfh, name, fhpath, "lookup2");
1147 *pathp2 = NULL;
1148 }
1149 return;
1150 }
1151 fh = NFSLOG_GET_FHANDLE2(&res->nfslog_diropres_u.dr_ok.drok_fhandle);
1152 nfslog_LOOKUP_calc(dfh, name, fh, fhpath, pathp1, pathp2, "Lookup2");
1153 }
1154
1155 /*
1156 * nfslog_READLINK2_fhargs - updates path1 but no fhtable changes
1157 */
1158 /* ARGSUSED */
1159 static void
nfslog_READLINK2_fhargs(fhandle_t * args,nfslog_rdlnres * res,char * fhpath,char ** pathp1,char ** pathp2)1160 nfslog_READLINK2_fhargs(fhandle_t *args, nfslog_rdlnres *res,
1161 char *fhpath, char **pathp1, char **pathp2)
1162 {
1163 if (debug > 2) {
1164 (void) printf("=============\nREADLINK2: fh ");
1165 debug_opaque_print(stdout, args, sizeof (*args));
1166 (void) printf("\n");
1167 }
1168 if (pathp1 != NULL) {
1169 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE2(args),
1170 NULL, fhpath, "readlink2");
1171 *pathp2 = NULL;
1172 }
1173 }
1174
1175 /*
1176 * nfslog_READ2_fhargs - updates path1 but no fhtable changes
1177 */
1178 /* ARGSUSED */
1179 static void
nfslog_READ2_fhargs(nfslog_nfsreadargs * args,nfslog_rdresult * res,char * fhpath,char ** pathp1,char ** pathp2)1180 nfslog_READ2_fhargs(nfslog_nfsreadargs *args, nfslog_rdresult *res,
1181 char *fhpath, char **pathp1, char **pathp2)
1182 {
1183 if (debug > 2) {
1184 (void) printf("=============\nREAD2: fh ");
1185 debug_opaque_print(stdout, &args->ra_fhandle,
1186 sizeof (args->ra_fhandle));
1187 (void) printf("\n");
1188 }
1189 if (pathp1 != NULL) {
1190 *pathp1 = nfslog_get_path(
1191 NFSLOG_GET_FHANDLE2(&args->ra_fhandle),
1192 NULL, fhpath, "read2");
1193 *pathp2 = NULL;
1194 }
1195 }
1196
1197 /*
1198 * nfslog_WRITE2_fhargs - updates path1 but no fhtable changes
1199 */
1200 /* ARGSUSED */
1201 static void
nfslog_WRITE2_fhargs(nfslog_writeargs * args,nfslog_writeresult * res,char * fhpath,char ** pathp1,char ** pathp2)1202 nfslog_WRITE2_fhargs(nfslog_writeargs *args, nfslog_writeresult *res,
1203 char *fhpath, char **pathp1, char **pathp2)
1204 {
1205 if (debug > 2) {
1206 (void) printf("=============\nWRITE2: fh ");
1207 debug_opaque_print(stdout, &args->waargs_fhandle,
1208 sizeof (args->waargs_fhandle));
1209 (void) printf("\n");
1210 }
1211 if (pathp1 != NULL) {
1212 *pathp1 = nfslog_get_path(
1213 NFSLOG_GET_FHANDLE2(&args->waargs_fhandle),
1214 NULL, fhpath, "write2");
1215 *pathp2 = NULL;
1216 }
1217 }
1218
1219 /*
1220 * nfslog_CREATE2_fhargs - if the operation succeeded, we are sure there can
1221 * be no such link in the fhtable, so just add it.
1222 */
1223 /* ARGSUSED */
1224 static void
nfslog_CREATE2_fhargs(nfslog_createargs * args,nfslog_diropres * res,char * fhpath,char ** pathp1,char ** pathp2)1225 nfslog_CREATE2_fhargs(nfslog_createargs *args, nfslog_diropres *res,
1226 char *fhpath, char **pathp1, char **pathp2)
1227 {
1228 char *name;
1229 fhandle_t *dfh, *fh;
1230 int error;
1231
1232 name = args->ca_da.da_name;
1233 dfh = &args->ca_da.da_fhandle;
1234 if (debug > 2) {
1235 if (res->dr_status == NFS_OK)
1236 fh = &res->nfslog_diropres_u.dr_ok.drok_fhandle;
1237 else
1238 fh = NULL;
1239 PRINT_FULL_DATA(stdout, "=============\nCREATE2",
1240 dfh, fh, name, "")
1241 if (res->dr_status != NFS_OK)
1242 (void) printf("status %d\n", res->dr_status);
1243 }
1244 dfh = NFSLOG_GET_FHANDLE2(dfh);
1245 if (pathp1 != NULL) {
1246 *pathp1 = nfslog_get_path(dfh, name, fhpath, "create2");
1247 *pathp2 = NULL;
1248 }
1249
1250 if (res->dr_status != NFS_OK)
1251 /* no returned fh so nothing to add */
1252 return;
1253
1254 /* A new file handle so add it */
1255 fh = NFSLOG_GET_FHANDLE2(&res->nfslog_diropres_u.dr_ok.drok_fhandle);
1256 if (error = FH_ADD(fhpath, dfh, fh, name)) {
1257 syslog(LOG_ERR, gettext(
1258 "Create2: Add fh for '%s' failed: %s\n"),
1259 name, ((error >= 0) ? strerror(error) : "Unknown"));
1260 }
1261 }
1262
1263 /*
1264 * nfslog_REMOVE2_fhargs - if the operation succeeded, remove the link from
1265 * the fhtable.
1266 */
1267 /* ARGSUSED */
1268 static void
nfslog_REMOVE2_fhargs(nfslog_diropargs * args,nfsstat * res,char * fhpath,char ** pathp1,char ** pathp2)1269 nfslog_REMOVE2_fhargs(nfslog_diropargs *args, nfsstat *res,
1270 char *fhpath, char **pathp1, char **pathp2)
1271 {
1272 char *name;
1273 fhandle_t *dfh;
1274 int error;
1275
1276 name = args->da_name;
1277 dfh = &args->da_fhandle;
1278 if (debug > 2) {
1279 PRINT_LINK_DATA(stdout, "=============\nREMOVE2", dfh, name, "")
1280 if (*res != NFS_OK)
1281 (void) printf("status %d\n", *res);
1282 }
1283 dfh = NFSLOG_GET_FHANDLE2(dfh);
1284 if (pathp1 != NULL) {
1285 *pathp1 = nfslog_get_path(dfh, name, fhpath, "remove2");
1286 *pathp2 = NULL;
1287 }
1288
1289 if (*res != NFS_OK)
1290 /* remove failed so nothing to update */
1291 return;
1292
1293 if (error = fh_remove(fhpath, dfh, name, pathp1)) {
1294 syslog(LOG_ERR, gettext("Remove2: '%s' failed: %s\n"),
1295 name, ((error >= 0) ? strerror(error) : "Unknown"));
1296 }
1297 }
1298
1299 /*
1300 * nfsl_RENAME2_fhargs - updates the dfh and name fields for the given fh
1301 * to change them to the new name.
1302 */
1303 /* ARGSUSED */
1304 static void
nfslog_RENAME2_fhargs(nfslog_rnmargs * args,nfsstat * res,char * fhpath,char ** pathp1,char ** pathp2)1305 nfslog_RENAME2_fhargs(nfslog_rnmargs *args, nfsstat *res,
1306 char *fhpath, char **pathp1, char **pathp2)
1307 {
1308 char *from_name, *to_name;
1309 fhandle_t *from_dfh, *to_dfh;
1310 int error;
1311
1312 from_name = args->rna_from.da_name;
1313 from_dfh = &args->rna_from.da_fhandle;
1314 to_name = args->rna_to.da_name;
1315 to_dfh = &args->rna_to.da_fhandle;
1316 if (debug > 2) {
1317 PRINT_LINK_DATA(stdout, "=============\nRENAME2: from",
1318 from_dfh, from_name, "")
1319 PRINT_LINK_DATA(stdout, "RENAME2: to ", to_dfh,
1320 to_name, "")
1321 if (*res != NFS_OK)
1322 (void) printf("status %d\n", *res);
1323 }
1324 from_dfh = NFSLOG_GET_FHANDLE2(from_dfh);
1325 to_dfh = NFSLOG_GET_FHANDLE2(to_dfh);
1326 if (pathp1 != NULL) {
1327 *pathp1 = nfslog_get_path(from_dfh, from_name, fhpath,
1328 "rename2 from");
1329 *pathp2 = nfslog_get_path(to_dfh, to_name, fhpath,
1330 "rename2 to");
1331 }
1332
1333 if (*res != NFS_OK)
1334 /* rename failed so nothing to update */
1335 return;
1336
1337 /* Rename the link in the database */
1338 if (error = fh_rename(fhpath, from_dfh, from_name, pathp1,
1339 to_dfh, to_name)) {
1340 syslog(LOG_ERR, gettext(
1341 "Rename2: Update from '%s' to '%s' failed: %s\n"),
1342 from_name, to_name,
1343 ((error >= 0) ? strerror(error) : "Unknown"));
1344 }
1345 }
1346
1347 /*
1348 * nfslog_LINK2_fhargs - adds link name and fh to fhlist. Note that as a
1349 * result we may have more than one name for an fh.
1350 */
1351 /* ARGSUSED */
1352 static void
nfslog_LINK2_fhargs(nfslog_linkargs * args,nfsstat * res,char * fhpath,char ** pathp1,char ** pathp2)1353 nfslog_LINK2_fhargs(nfslog_linkargs *args, nfsstat *res,
1354 char *fhpath, char **pathp1, char **pathp2)
1355 {
1356 char *name;
1357 fhandle_t *dfh, *fh;
1358 int error;
1359
1360 fh = &args->la_from;
1361 name = args->la_to.da_name;
1362 dfh = &args->la_to.da_fhandle;
1363 if (debug > 2) {
1364 PRINT_FULL_DATA(stdout, "=============\nLINK2",
1365 dfh, fh, name, "")
1366 if (*res != NFS_OK)
1367 (void) printf("status %d\n", *res);
1368 }
1369 dfh = NFSLOG_GET_FHANDLE2(dfh);
1370 fh = NFSLOG_GET_FHANDLE2(fh);
1371 if (pathp1 != NULL) {
1372 *pathp1 = nfslog_get_path(fh, NULL, fhpath, "link2 from");
1373 *pathp2 = nfslog_get_path(dfh, name, fhpath, "link2 to");
1374 }
1375
1376 if (*res != NFS_OK)
1377 /* no returned fh so nothing to add */
1378 return;
1379
1380 /* A new link so add it, have fh_add find the link count */
1381 if (error = FH_ADD(fhpath, dfh, fh, name)) {
1382 syslog(LOG_ERR, gettext(
1383 "Link2: Add fh for '%s' failed: %s\n"),
1384 name, ((error >= 0) ? strerror(error) : "Unknown"));
1385 }
1386 }
1387
1388 /*
1389 * nfslog_SYMLINK2_fhargs - adds symlink name and fh to fhlist if fh returned.
1390 */
1391 /* ARGSUSED */
1392 static void
nfslog_SYMLINK2_fhargs(nfslog_symlinkargs * args,nfsstat * res,char * fhpath,char ** pathp1,char ** pathp2)1393 nfslog_SYMLINK2_fhargs(nfslog_symlinkargs *args, nfsstat *res,
1394 char *fhpath, char **pathp1, char **pathp2)
1395 {
1396 char *name;
1397 fhandle_t *dfh;
1398
1399 name = args->sla_from.da_name;
1400 dfh = &args->sla_from.da_fhandle;
1401 if (debug > 2) {
1402 PRINT_LINK_DATA(stdout, "=============\nSYMLINK2",
1403 dfh, name, "")
1404 }
1405 dfh = NFSLOG_GET_FHANDLE2(dfh);
1406 if (pathp1 != NULL) {
1407 *pathp1 = nfslog_get_path(dfh, name, fhpath, "symlink2");
1408 *pathp2 = NULL;
1409 }
1410 }
1411
1412 /*
1413 * nfslog_READDIR2_fhargs - updates path1 but no fhtable changes
1414 */
1415 /* ARGSUSED */
1416 static void
nfslog_READDIR2_fhargs(nfslog_rddirargs * args,nfslog_rddirres * res,char * fhpath,char ** pathp1,char ** pathp2)1417 nfslog_READDIR2_fhargs(nfslog_rddirargs *args, nfslog_rddirres *res,
1418 char *fhpath, char **pathp1, char **pathp2)
1419 {
1420 if (debug > 2) {
1421 (void) printf("=============\nREADDIR2: fh ");
1422 debug_opaque_print(stdout, &args->rda_fh,
1423 sizeof (args->rda_fh));
1424 (void) printf("\n");
1425 }
1426 if (pathp1 != NULL) {
1427 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE2(&args->rda_fh),
1428 NULL, fhpath, "readdir2");
1429 *pathp2 = NULL;
1430 }
1431 }
1432
1433 /*
1434 * nfslog_STATFS2_fhargs - updates path1 but no fhtable changes
1435 */
1436 /* ARGSUSED */
1437 static void
nfslog_STATFS2_fhargs(fhandle_t * args,nfsstat * res,char * fhpath,char ** pathp1,char ** pathp2)1438 nfslog_STATFS2_fhargs(fhandle_t *args, nfsstat *res,
1439 char *fhpath, char **pathp1, char **pathp2)
1440 {
1441 if (debug > 2) {
1442 (void) printf("=============\nSTATFS2: fh ");
1443 debug_opaque_print(stdout, args, sizeof (*args));
1444 (void) printf("\n");
1445 }
1446 if (pathp1 != NULL) {
1447 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE2(args),
1448 NULL, fhpath, "statfs2");
1449 *pathp2 = NULL;
1450 }
1451 }
1452
1453 /*
1454 * NFS VERSION 3
1455 */
1456
1457 /* Functions for updating the fhtable for fhtoppath */
1458
1459 /*
1460 * nfslog_GETATTR3_fhargs - updates path1 but no fhtable changes
1461 */
1462 /* ARGSUSED */
1463 static void
nfslog_GETATTR3_fhargs(nfs_fh3 * args,nfsstat3 * res,char * fhpath,char ** pathp1,char ** pathp2)1464 nfslog_GETATTR3_fhargs(nfs_fh3 *args, nfsstat3 *res,
1465 char *fhpath, char **pathp1, char **pathp2)
1466 {
1467 if (debug > 2) {
1468 (void) printf("=============\nGETATTR3: fh ");
1469 debug_opaque_print(stdout, args, sizeof (*args));
1470 (void) printf("\n");
1471 }
1472 if (pathp1 != NULL) {
1473 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(args), NULL,
1474 fhpath, "getattr3");
1475 *pathp2 = NULL;
1476 }
1477 }
1478
1479 /*
1480 * nfslog_SETATTR3_fhargs - updates path1 but no fhtable changes
1481 */
1482 /* ARGSUSED */
1483 static void
nfslog_SETATTR3_fhargs(nfslog_SETATTR3args * args,nfsstat3 * res,char * fhpath,char ** pathp1,char ** pathp2)1484 nfslog_SETATTR3_fhargs(nfslog_SETATTR3args *args, nfsstat3 *res,
1485 char *fhpath, char **pathp1, char **pathp2)
1486 {
1487 if (debug > 2) {
1488 (void) printf("=============\nSETATTR3: fh ");
1489 debug_opaque_print(stdout, &args->object,
1490 sizeof (args->object));
1491 (void) printf("\n");
1492 }
1493 if (pathp1 != NULL) {
1494 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->object),
1495 NULL, fhpath, "setattr3");
1496 *pathp2 = NULL;
1497 }
1498 }
1499
1500 /*
1501 * nfslog_LOOKUP3_fhargs - search the table to ensure we have not added this
1502 * one already. Note that if the response status was anything but okay,
1503 * there is no fh to check...
1504 */
1505 /* ARGSUSED */
1506 static void
nfslog_LOOKUP3_fhargs(nfslog_diropargs3 * args,nfslog_LOOKUP3res * res,char * fhpath,char ** pathp1,char ** pathp2)1507 nfslog_LOOKUP3_fhargs(nfslog_diropargs3 *args, nfslog_LOOKUP3res *res,
1508 char *fhpath, char **pathp1, char **pathp2)
1509 {
1510 char *name;
1511 fhandle_t *dfh, *fh;
1512
1513 name = args->name;
1514 dfh = NFSLOG_GET_FHANDLE3(&args->dir);
1515
1516 if (debug > 2) {
1517 if (res->status == NFS3_OK)
1518 fh = NFSLOG_GET_FHANDLE3(
1519 &res->nfslog_LOOKUP3res_u.object);
1520 else
1521 fh = NULL;
1522 PRINT_FULL_DATA(stdout, "=============\nLOOKUP3",
1523 dfh, fh, name, "")
1524 if (res->status != NFS3_OK)
1525 (void) printf("status %d\n", res->status);
1526 }
1527 if ((dfh == &public_fh) && (name[0] == '\x80')) {
1528 /* special mclookup */
1529 name = &name[1];
1530 }
1531 if (res->status != NFS3_OK) {
1532 if (pathp1 != NULL) {
1533 *pathp1 = nfslog_get_path(dfh, name, fhpath, "lookup3");
1534 *pathp2 = NULL;
1535 }
1536 return;
1537 }
1538 fh = NFSLOG_GET_FHANDLE3(&res->nfslog_LOOKUP3res_u.object);
1539 nfslog_LOOKUP_calc(dfh, name, fh, fhpath, pathp1, pathp2, "Lookup3");
1540 }
1541
1542 /*
1543 * nfslog_ACCESS3_fhargs - updates path1 but no fhtable changes
1544 */
1545 /* ARGSUSED */
1546 static void
nfslog_ACCESS3_fhargs(nfs_fh3 * args,nfsstat3 * res,char * fhpath,char ** pathp1,char ** pathp2)1547 nfslog_ACCESS3_fhargs(nfs_fh3 *args, nfsstat3 *res,
1548 char *fhpath, char **pathp1, char **pathp2)
1549 {
1550 if (debug > 2) {
1551 (void) printf("=============\nACCESS3: fh ");
1552 debug_opaque_print(stdout, args,
1553 sizeof (*args));
1554 (void) printf("\n");
1555 }
1556 if (pathp1 != NULL) {
1557 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(args),
1558 NULL, fhpath, "access3");
1559 *pathp2 = NULL;
1560 }
1561 }
1562
1563 /*
1564 * nfslog_READLINK3_fhargs - updates path1 but no fhtable changes
1565 */
1566 /* ARGSUSED */
1567 static void
nfslog_READLINK3_fhargs(nfs_fh3 * args,nfslog_READLINK3res * res,char * fhpath,char ** pathp1,char ** pathp2)1568 nfslog_READLINK3_fhargs(nfs_fh3 *args, nfslog_READLINK3res *res,
1569 char *fhpath, char **pathp1, char **pathp2)
1570 {
1571 if (debug > 2) {
1572 (void) printf("=============\nREADLINK3: fh ");
1573 debug_opaque_print(stdout, args, sizeof (*args));
1574 (void) printf("\n");
1575 }
1576 if (pathp1 != NULL) {
1577 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(args), NULL,
1578 fhpath, "readlink3");
1579 *pathp2 = NULL;
1580 }
1581 }
1582
1583 /*
1584 * nfslog_READ3_fhargs - updates path1 but no fhtable changes
1585 */
1586 /* ARGSUSED */
1587 static void
nfslog_READ3_fhargs(nfslog_READ3args * args,nfslog_READ3res * res,char * fhpath,char ** pathp1,char ** pathp2)1588 nfslog_READ3_fhargs(nfslog_READ3args *args, nfslog_READ3res *res,
1589 char *fhpath, char **pathp1, char **pathp2)
1590 {
1591 if (debug > 2) {
1592 (void) printf("=============\nREAD3: fh ");
1593 debug_opaque_print(stdout, &args->file,
1594 sizeof (args->file));
1595 (void) printf("\n");
1596 }
1597 if (pathp1 != NULL) {
1598 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->file),
1599 NULL, fhpath, "read3");
1600 *pathp2 = NULL;
1601 }
1602 }
1603
1604 /*
1605 * nfslog_WRITE3_fhargs - updates path1 but no fhtable changes
1606 */
1607 /* ARGSUSED */
1608 static void
nfslog_WRITE3_fhargs(nfslog_WRITE3args * args,nfslog_WRITE3res * res,char * fhpath,char ** pathp1,char ** pathp2)1609 nfslog_WRITE3_fhargs(nfslog_WRITE3args *args, nfslog_WRITE3res *res,
1610 char *fhpath, char **pathp1, char **pathp2)
1611 {
1612 if (debug > 2) {
1613 (void) printf("=============\nWRITE3: fh ");
1614 debug_opaque_print(stdout, &args->file,
1615 sizeof (args->file));
1616 (void) printf("\n");
1617 }
1618 if (pathp1 != NULL) {
1619 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->file),
1620 NULL, fhpath, "write3");
1621 *pathp2 = NULL;
1622 }
1623 }
1624
1625 /*
1626 * nfslog_CREATE3_fhargs - if the operation succeeded, we are sure there can
1627 * be no such link in the fhtable, so just add it.
1628 */
1629 /* ARGSUSED */
1630 static void
nfslog_CREATE3_fhargs(nfslog_CREATE3args * args,nfslog_CREATE3res * res,char * fhpath,char ** pathp1,char ** pathp2)1631 nfslog_CREATE3_fhargs(nfslog_CREATE3args *args, nfslog_CREATE3res *res,
1632 char *fhpath, char **pathp1, char **pathp2)
1633 {
1634 char *name;
1635 fhandle_t *dfh, *fh;
1636 int error;
1637
1638 name = args->where.name;
1639 dfh = NFSLOG_GET_FHANDLE3(&args->where.dir);
1640
1641 if (debug > 2) {
1642 if (res->status == NFS3_OK)
1643 fh = NFSLOG_GET_FHANDLE3(
1644 &res->nfslog_CREATE3res_u.ok.obj.handle);
1645 else
1646 fh = NULL;
1647 PRINT_FULL_DATA(stdout, "=============\nCREATE3",
1648 dfh, fh, name, "")
1649 if (res->status != NFS3_OK)
1650 (void) printf("status %d\n", res->status);
1651 }
1652 if (pathp1 != NULL) {
1653 *pathp1 = nfslog_get_path(dfh, name, fhpath, "create3");
1654 *pathp2 = NULL;
1655 }
1656
1657 if ((res->status != NFS3_OK) ||
1658 !res->nfslog_CREATE3res_u.ok.obj.handle_follows)
1659 /* no returned fh so nothing to add */
1660 return;
1661
1662 /* A new file handle so add it */
1663 fh = NFSLOG_GET_FHANDLE3(&res->nfslog_CREATE3res_u.ok.obj.handle);
1664 if (error = FH_ADD(fhpath, dfh, fh, name)) {
1665 syslog(LOG_ERR, gettext(
1666 "Create3: Add fh for '%s' failed: %s\n"),
1667 name, ((error >= 0) ? strerror(error) : "Unknown"));
1668 }
1669 }
1670
1671 /*
1672 * nfslog_MKDIR3_fhargs - if the operation succeeded, we are sure there can
1673 * be no such link in the fhtable, so just add it.
1674 */
1675 /* ARGSUSED */
1676 static void
nfslog_MKDIR3_fhargs(nfslog_MKDIR3args * args,nfslog_MKDIR3res * res,char * fhpath,char ** pathp1,char ** pathp2)1677 nfslog_MKDIR3_fhargs(nfslog_MKDIR3args *args, nfslog_MKDIR3res *res,
1678 char *fhpath, char **pathp1, char **pathp2)
1679 {
1680 char *name;
1681 fhandle_t *dfh, *fh;
1682 int error;
1683
1684 name = args->where.name;
1685 dfh = NFSLOG_GET_FHANDLE3(&args->where.dir);
1686
1687 if (debug > 2) {
1688 if (res->status == NFS3_OK)
1689 fh = NFSLOG_GET_FHANDLE3(
1690 &res->nfslog_MKDIR3res_u.obj.handle);
1691 else
1692 fh = NULL;
1693 PRINT_FULL_DATA(stdout, "=============\nMKDIR3",
1694 dfh, fh, name, "")
1695 if (res->status != NFS3_OK)
1696 (void) printf("status %d\n", res->status);
1697 }
1698 if (pathp1 != NULL) {
1699 *pathp1 = nfslog_get_path(dfh, name, fhpath, "mkdir3");
1700 *pathp2 = NULL;
1701 }
1702
1703 if ((res->status != NFS3_OK) ||
1704 !res->nfslog_MKDIR3res_u.obj.handle_follows)
1705 /* no returned fh so nothing to add */
1706 return;
1707
1708 /* A new file handle so add it */
1709 fh = NFSLOG_GET_FHANDLE3(&res->nfslog_MKDIR3res_u.obj.handle);
1710 if (error = FH_ADD(fhpath, dfh, fh, name)) {
1711 syslog(LOG_ERR, gettext(
1712 "Mkdir3: Add fh for '%s' failed: %s\n"),
1713 name, ((error >= 0) ? strerror(error) : "Unknown"));
1714 }
1715 }
1716
1717 /*
1718 * nfslog_REMOVE3_fhargs - if the operation succeeded, remove the link from
1719 * the fhtable.
1720 */
1721 /* ARGSUSED */
1722 static void
nfslog_REMOVE3_fhargs(nfslog_REMOVE3args * args,nfsstat3 * res,char * fhpath,char ** pathp1,char ** pathp2)1723 nfslog_REMOVE3_fhargs(nfslog_REMOVE3args *args, nfsstat3 *res,
1724 char *fhpath, char **pathp1, char **pathp2)
1725 {
1726 char *name;
1727 fhandle_t *dfh;
1728 int error;
1729
1730 name = args->object.name;
1731 dfh = NFSLOG_GET_FHANDLE3(&args->object.dir);
1732
1733 if (debug > 2) {
1734 PRINT_LINK_DATA(stdout, "=============\nREMOVE3", dfh, name, "")
1735 if (*res != NFS3_OK)
1736 (void) printf("status %d\n", *res);
1737 }
1738 if (pathp1 != NULL) {
1739 *pathp1 = nfslog_get_path(dfh, name, fhpath, "remove3");
1740 *pathp2 = NULL;
1741 }
1742
1743 if (*res != NFS3_OK)
1744 /* remove failed so nothing to update */
1745 return;
1746
1747 if (error = fh_remove(fhpath, dfh, name, pathp1)) {
1748 syslog(LOG_ERR, gettext("Remove3: '%s' failed: %s\n"),
1749 name, ((error >= 0) ? strerror(error) : "Unknown"));
1750 }
1751 }
1752
1753 /*
1754 * nfslog_RMDIR3_fhargs - if the operation succeeded, remove the link from
1755 * the fhtable.
1756 */
1757 /* ARGSUSED */
1758 static void
nfslog_RMDIR3_fhargs(nfslog_RMDIR3args * args,nfsstat3 * res,char * fhpath,char ** pathp1,char ** pathp2)1759 nfslog_RMDIR3_fhargs(nfslog_RMDIR3args *args, nfsstat3 *res,
1760 char *fhpath, char **pathp1, char **pathp2)
1761 {
1762 char *name;
1763 fhandle_t *dfh;
1764 int error;
1765
1766 name = args->object.name;
1767 dfh = NFSLOG_GET_FHANDLE3(&args->object.dir);
1768
1769 if (debug > 2) {
1770 PRINT_LINK_DATA(stdout, "=============\nRMDIR3", dfh, name, "")
1771 if (*res != NFS3_OK)
1772 (void) printf("status %d\n", *res);
1773 }
1774 if (pathp1 != NULL) {
1775 *pathp1 = nfslog_get_path(dfh, name, fhpath, "rmdir3");
1776 *pathp2 = NULL;
1777 }
1778
1779 if (*res != NFS3_OK)
1780 /* rmdir failed so nothing to update */
1781 return;
1782
1783 if (error = fh_remove(fhpath, dfh, name, pathp1)) {
1784 syslog(LOG_ERR, gettext("Rmdir3: '%s' failed: %s\n"),
1785 name, ((error >= 0) ? strerror(error) : "Unknown"));
1786 }
1787 }
1788
1789 /*
1790 * nfslog_RENAME3_fhargs - if the operation succeeded, update the existing
1791 * fhtable entry to point to new dir and name.
1792 */
1793 /* ARGSUSED */
1794 static void
nfslog_RENAME3_fhargs(nfslog_RENAME3args * args,nfsstat3 * res,char * fhpath,char ** pathp1,char ** pathp2)1795 nfslog_RENAME3_fhargs(nfslog_RENAME3args *args, nfsstat3 *res,
1796 char *fhpath, char **pathp1, char **pathp2)
1797 {
1798 char *from_name, *to_name;
1799 fhandle_t *from_dfh, *to_dfh;
1800 int error;
1801
1802 from_name = args->from.name;
1803 from_dfh = NFSLOG_GET_FHANDLE3(&args->from.dir);
1804 to_name = args->to.name;
1805 to_dfh = NFSLOG_GET_FHANDLE3(&args->to.dir);
1806
1807 if (debug > 2) {
1808 PRINT_LINK_DATA(stdout, "=============\nRENAME3: from",
1809 from_dfh, from_name, "")
1810 PRINT_LINK_DATA(stdout, "=============\nRENAME3: to ",
1811 to_dfh, to_name, "")
1812 if (*res != NFS3_OK)
1813 (void) printf("status %d\n", *res);
1814 }
1815 if (pathp1 != NULL) {
1816 *pathp1 = nfslog_get_path(from_dfh, from_name, fhpath,
1817 "rename3 from");
1818 *pathp2 = nfslog_get_path(to_dfh, to_name, fhpath,
1819 "rename3 to");
1820 }
1821 if (*res != NFS3_OK)
1822 /* rename failed so nothing to update */
1823 return;
1824
1825 if (error = fh_rename(fhpath, from_dfh, from_name, pathp1,
1826 to_dfh, to_name)) {
1827 syslog(LOG_ERR, gettext(
1828 "Rename3: Update from '%s' to '%s' failed: %s\n"),
1829 from_name, to_name,
1830 ((error >= 0) ? strerror(error) : "Unknown"));
1831 }
1832 }
1833
1834 /*
1835 * nfslog_LINK3_fhargs - if the operation succeeded, we are sure there can
1836 * be no such link in the fhtable, so just add it.
1837 */
1838 /* ARGSUSED */
1839 static void
nfslog_LINK3_fhargs(nfslog_LINK3args * args,nfsstat3 * res,char * fhpath,char ** pathp1,char ** pathp2)1840 nfslog_LINK3_fhargs(nfslog_LINK3args *args, nfsstat3 *res,
1841 char *fhpath, char **pathp1, char **pathp2)
1842 {
1843 char *name;
1844 fhandle_t *dfh, *fh;
1845 int error;
1846
1847 fh = NFSLOG_GET_FHANDLE3(&args->file);
1848 name = args->link.name;
1849 dfh = NFSLOG_GET_FHANDLE3(&args->link.dir);
1850
1851 if (debug > 2) {
1852 PRINT_FULL_DATA(stdout, "=============\nLINK3",
1853 dfh, fh, name, "")
1854 if (*res != NFS3_OK)
1855 (void) printf("status %d\n", *res);
1856 }
1857 if (pathp1 != NULL) {
1858 *pathp1 = nfslog_get_path(fh, NULL, fhpath, "link3 from");
1859 *pathp2 = nfslog_get_path(dfh, name, fhpath, "link3 to");
1860 }
1861
1862 if (*res != NFS3_OK)
1863 /* link failed so nothing to add */
1864 return;
1865
1866 /* A new link so add it, have fh_add find link count */
1867 if (error = FH_ADD(fhpath, dfh, fh, name)) {
1868 syslog(LOG_ERR, gettext(
1869 "Link3: Add fh for '%s' failed: %s\n"),
1870 name, ((error >= 0) ? strerror(error) : "Unknown"));
1871 }
1872 }
1873
1874 /*
1875 * nfslog_MKNOD3_fhargs - if the operation succeeded, we are sure there can
1876 * be no such link in the fhtable, so just add it.
1877 */
1878 /* ARGSUSED */
1879 static void
nfslog_MKNOD3_fhargs(nfslog_MKNOD3args * args,nfslog_MKNOD3res * res,char * fhpath,char ** pathp1,char ** pathp2)1880 nfslog_MKNOD3_fhargs(nfslog_MKNOD3args *args, nfslog_MKNOD3res *res,
1881 char *fhpath, char **pathp1, char **pathp2)
1882 {
1883 char *name;
1884 fhandle_t *dfh, *fh;
1885 int error;
1886
1887 name = args->where.name;
1888 dfh = NFSLOG_GET_FHANDLE3(&args->where.dir);
1889
1890 if (debug > 2) {
1891 if (res->status == NFS3_OK)
1892 fh = NFSLOG_GET_FHANDLE3(
1893 &res->nfslog_MKNOD3res_u.obj.handle);
1894 else
1895 fh = NULL;
1896 PRINT_FULL_DATA(stdout, "=============\nMKNOD3",
1897 dfh, fh, name, "")
1898 if (res->status != NFS3_OK)
1899 (void) printf("status %d\n", res->status);
1900 }
1901 if (pathp1 != NULL) {
1902 *pathp1 = nfslog_get_path(dfh, name, fhpath, "mknod3");
1903 *pathp2 = NULL;
1904 }
1905 if ((res->status != NFS3_OK) ||
1906 !res->nfslog_MKNOD3res_u.obj.handle_follows)
1907 /* no returned fh so nothing to add */
1908 return;
1909
1910 /* A new file handle so add it */
1911 fh = NFSLOG_GET_FHANDLE3(&res->nfslog_MKNOD3res_u.obj.handle);
1912 if (error = FH_ADD(fhpath, dfh, fh, name)) {
1913 syslog(LOG_ERR, gettext("Mknod3: Add fh for '%s' failed: %s\n"),
1914 name, ((error >= 0) ? strerror(error) : "Unknown"));
1915 }
1916 }
1917
1918 /*
1919 * nfslog_SYMLINK3_fhargs - if the operation succeeded, we are sure there can
1920 * be no such link in the fhtable, so just add it.
1921 */
1922 /* ARGSUSED */
1923 static void
nfslog_SYMLINK3_fhargs(nfslog_SYMLINK3args * args,nfslog_SYMLINK3res * res,char * fhpath,char ** pathp1,char ** pathp2)1924 nfslog_SYMLINK3_fhargs(nfslog_SYMLINK3args *args, nfslog_SYMLINK3res *res,
1925 char *fhpath, char **pathp1, char **pathp2)
1926 {
1927 char *name;
1928 fhandle_t *dfh, *fh;
1929 int error;
1930
1931 name = args->where.name;
1932 dfh = NFSLOG_GET_FHANDLE3(&args->where.dir);
1933
1934 if (debug > 2) {
1935 if (res->status == NFS3_OK)
1936 fh = NFSLOG_GET_FHANDLE3(
1937 &res->nfslog_SYMLINK3res_u.obj.handle);
1938 else
1939 fh = NULL;
1940 PRINT_FULL_DATA(stdout, "=============\nSYMLINK3",
1941 dfh, fh, name, "")
1942 if (res->status != NFS3_OK)
1943 (void) printf("status %d\n", res->status);
1944 }
1945 if (pathp1 != NULL) {
1946 *pathp1 = nfslog_get_path(dfh, name, fhpath, "symlink3");
1947 *pathp2 = NULL;
1948 }
1949
1950 if ((res->status != NFS3_OK) ||
1951 !res->nfslog_SYMLINK3res_u.obj.handle_follows)
1952 /* no returned fh so nothing to add */
1953 return;
1954
1955 /* A new file handle so add it */
1956 fh = NFSLOG_GET_FHANDLE3(&res->nfslog_SYMLINK3res_u.obj.handle);
1957 if (error = FH_ADD(fhpath, dfh, fh, name)) {
1958 syslog(LOG_ERR, gettext(
1959 "Symlink3: Add fh for '%s' failed: %s\n"),
1960 name, ((error >= 0) ? strerror(error) : "Unknown"));
1961 }
1962 }
1963
1964 /*
1965 * nfslog_READDIR3_fhargs - updates path1 but no fhtable changes
1966 */
1967 /* ARGSUSED */
1968 static void
nfslog_READDIR3_fhargs(nfs_fh3 * args,nfsstat3 * res,char * fhpath,char ** pathp1,char ** pathp2)1969 nfslog_READDIR3_fhargs(nfs_fh3 *args, nfsstat3 *res,
1970 char *fhpath, char **pathp1, char **pathp2)
1971 {
1972 if (debug > 2) {
1973 (void) printf("=============\nREADDIR3: fh ");
1974 debug_opaque_print(stdout, args,
1975 sizeof (*args));
1976 (void) printf("\n");
1977 }
1978 if (pathp1 != NULL) {
1979 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(args),
1980 NULL, fhpath, "readdir3");
1981 *pathp2 = NULL;
1982 }
1983 }
1984
1985 /*
1986 * nfslog_READDIRPLUS3_fhargs - updates path1 but no fhtable changes
1987 */
1988 /* ARGSUSED */
1989 static void
nfslog_READDIRPLUS3_fhargs(nfslog_READDIRPLUS3args * args,nfslog_READDIRPLUS3res * res,char * fhpath,char ** pathp1,char ** pathp2)1990 nfslog_READDIRPLUS3_fhargs(nfslog_READDIRPLUS3args *args,
1991 nfslog_READDIRPLUS3res *res,
1992 char *fhpath, char **pathp1, char **pathp2)
1993 {
1994 char *name;
1995 fhandle_t *dfh, *fh;
1996 nfslog_entryplus3 *ep;
1997
1998 if (debug > 2) {
1999 (void) printf("=============\nREADDIRPLUS3: fh ");
2000 debug_opaque_print(stdout, &args->dir,
2001 sizeof (args->dir));
2002 (void) printf("\n");
2003 }
2004 if (pathp1 != NULL) {
2005 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->dir),
2006 NULL, fhpath, "readdirplus3");
2007 *pathp2 = NULL;
2008 }
2009
2010 if (res->status == NFS3_OK) {
2011
2012 dfh = NFSLOG_GET_FHANDLE3(&args->dir);
2013
2014 /*
2015 * Loop through the fh/name pair and add them
2016 * to the mappings.
2017 */
2018 for (ep = res->nfslog_READDIRPLUS3res_u.ok.reply.entries;
2019 ep != NULL;
2020 ep = ep->nextentry) {
2021
2022 name = ep->name;
2023
2024 fh = NFSLOG_GET_FHANDLE3(&ep->name_handle.handle);
2025
2026 nfslog_LOOKUP_calc(dfh, name, fh,
2027 fhpath, NULL, NULL,
2028 "ReaddirPlus3");
2029 }
2030 }
2031 }
2032
2033 /*
2034 * nfslog_FSSTAT3_fhargs - updates path1 but no fhtable changes
2035 */
2036 /* ARGSUSED */
2037 static void
nfslog_FSSTAT3_fhargs(nfs_fh3 * args,nfsstat3 * res,char * fhpath,char ** pathp1,char ** pathp2)2038 nfslog_FSSTAT3_fhargs(nfs_fh3 *args, nfsstat3 *res,
2039 char *fhpath, char **pathp1, char **pathp2)
2040 {
2041 if (debug > 2) {
2042 (void) printf("=============\nFSSTAT3: fh ");
2043 debug_opaque_print(stdout, args,
2044 sizeof (*args));
2045 (void) printf("\n");
2046 }
2047 if (pathp1 != NULL) {
2048 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(args), NULL,
2049 fhpath, "fsstat3");
2050 *pathp2 = NULL;
2051 }
2052 }
2053
2054 /*
2055 * nfslog_FSINFO3_fhargs - updates path1 but no fhtable changes
2056 */
2057 /* ARGSUSED */
2058 static void
nfslog_FSINFO3_fhargs(nfs_fh3 * args,nfsstat3 * res,char * fhpath,char ** pathp1,char ** pathp2)2059 nfslog_FSINFO3_fhargs(nfs_fh3 *args, nfsstat3 *res,
2060 char *fhpath, char **pathp1, char **pathp2)
2061 {
2062 if (debug > 2) {
2063 (void) printf("=============\nFSINFO3: fh ");
2064 debug_opaque_print(stdout, args,
2065 sizeof (*args));
2066 (void) printf("\n");
2067 }
2068 if (pathp1 != NULL) {
2069 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(args), NULL,
2070 fhpath, "fsinfo3");
2071 *pathp2 = NULL;
2072 }
2073 }
2074
2075 /*
2076 * nfslog_PATHCONF3_fhargs - updates path1 but no fhtable changes
2077 */
2078 /* ARGSUSED */
2079 static void
nfslog_PATHCONF3_fhargs(nfs_fh3 * args,nfsstat3 * res,char * fhpath,char ** pathp1,char ** pathp2)2080 nfslog_PATHCONF3_fhargs(nfs_fh3 *args, nfsstat3 *res,
2081 char *fhpath, char **pathp1, char **pathp2)
2082 {
2083 if (debug > 2) {
2084 (void) printf("=============\nPATHCONF3: fh ");
2085 debug_opaque_print(stdout, args,
2086 sizeof (*args));
2087 (void) printf("\n");
2088 }
2089 if (pathp1 != NULL) {
2090 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(args), NULL,
2091 fhpath, "pathconf3");
2092 *pathp2 = NULL;
2093 }
2094 }
2095
2096 /*
2097 * nfslog_COMMIT3_fhargs - updates path1 but no fhtable changes
2098 */
2099 /* ARGSUSED */
2100 static void
nfslog_COMMIT3_fhargs(nfslog_COMMIT3args * args,nfsstat3 * res,char * fhpath,char ** pathp1,char ** pathp2)2101 nfslog_COMMIT3_fhargs(nfslog_COMMIT3args *args, nfsstat3 *res,
2102 char *fhpath, char **pathp1, char **pathp2)
2103 {
2104 if (debug > 2) {
2105 (void) printf("=============\nCOMMIT3: fh ");
2106 debug_opaque_print(stdout, &args->file,
2107 sizeof (args->file));
2108 (void) printf("\n");
2109 }
2110 if (pathp1 != NULL) {
2111 *pathp1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->file),
2112 NULL, fhpath, "commit3");
2113 *pathp2 = NULL;
2114 }
2115 }
2116
2117 /*
2118 * NFSLOG VERSION 1
2119 */
2120
2121 /*
2122 * nfslog_SHARE_fhargs - adds export path and handle to fhlist
2123 */
2124 /* ARGSUSED */
2125 static void
nfslog_SHARE_fhargs(nfslog_sharefsargs * args,nfslog_sharefsres * res,char * fhpath,char ** pathp1,char ** pathp2)2126 nfslog_SHARE_fhargs(nfslog_sharefsargs *args, nfslog_sharefsres *res,
2127 char *fhpath, char **pathp1, char **pathp2)
2128 {
2129 fhlist_ent fhrec;
2130 fhandle_t *fh;
2131 int error;
2132
2133 if (debug > 2) {
2134 (void) printf(
2135 "=============\nSHARE: name '%s', fh ", args->sh_path);
2136 debug_opaque_print(stdout, &args->sh_fh_buf,
2137 sizeof (fhandle_t));
2138 (void) printf("\n");
2139 }
2140
2141 fh = &args->sh_fh_buf;
2142
2143 /*
2144 * This bcopy is done because the fh_data for the export/share directory
2145 * is not meaningful with respect to the database keys. Therefore, we
2146 * copy the export or fh_xdata fid to the fh_data so that a reasonable
2147 * entry will be added in the data base.
2148 */
2149 bcopy(fh->fh_xdata, fh->fh_data, fh->fh_xlen);
2150
2151 /* If debug print the database */
2152 if (debug > 10) {
2153 fh_print_all_keys(fhpath, fh);
2154 }
2155 if (fh_lookup_link(fhpath, fh, fh,
2156 args->sh_path, &fhrec, &error) == NULL) {
2157 if (error = FH_ADD(fhpath, fh, fh, args->sh_path)) {
2158 syslog(LOG_ERR, gettext(
2159 "Share: Add fh for '%s' failed: %s\n"),
2160 args->sh_path, ((error >= 0) ?
2161 strerror(error) : "Unknown"));
2162 }
2163 }
2164 if (pathp1 != NULL) {
2165 *pathp1 = nfslog_get_path(fh, NULL, fhpath, "share");
2166 *pathp2 = NULL;
2167 }
2168 }
2169
2170 /*
2171 * nfslog_UNSHARE_fhargs - remove export path and handle from fhlist
2172 */
2173 /* ARGSUSED */
2174 static void
nfslog_UNSHARE_fhargs(nfslog_sharefsargs * args,nfslog_sharefsres * res,char * fhpath,char ** pathp1,char ** pathp2)2175 nfslog_UNSHARE_fhargs(nfslog_sharefsargs *args, nfslog_sharefsres *res,
2176 char *fhpath, char **pathp1, char **pathp2)
2177 {
2178 fhandle_t *fh;
2179 int error;
2180
2181 if (debug > 2) {
2182 (void) printf("=============\nUNSHARE: name '%s', fh ",
2183 args->sh_path);
2184 debug_opaque_print(stdout, &args->sh_fh_buf,
2185 sizeof (fhandle_t));
2186 (void) printf("\n");
2187 }
2188
2189 fh = &args->sh_fh_buf;
2190
2191 /*
2192 * This bcopy is done because the fh_data for the export/share directory
2193 * is not meaningful with respect to the database keys. Therefore, we
2194 * copy the export or fh_xdata fid to the fh_data so that a reasonable
2195 * entry will be added in the data base.
2196 */
2197 bcopy(fh->fh_xdata, fh->fh_data, fh->fh_xlen);
2198
2199 /* If debug print the database */
2200 if (debug > 10) {
2201 fh_print_all_keys(fhpath, fh);
2202 }
2203 if (pathp1 != NULL) {
2204 *pathp1 = nfslog_get_path(fh, NULL, fhpath, "share");
2205 *pathp2 = NULL;
2206 }
2207 if (error = fh_remove(fhpath, fh, args->sh_path, pathp1)) {
2208 syslog(LOG_ERR, gettext("Unshare: '%s' failed: %s\n"),
2209 args->sh_path, ((error >= 0) ? strerror(error) :
2210 "Unknown"));
2211 }
2212 }
2213
2214 /* ARGSUSED */
2215 static void
nfslog_GETFH_fhargs(nfslog_getfhargs * args,nfsstat * res,char * fhpath,char ** pathp1,char ** pathp2)2216 nfslog_GETFH_fhargs(nfslog_getfhargs *args, nfsstat *res,
2217 char *fhpath, char **pathp1, char **pathp2)
2218 {
2219 fhlist_ent fhrec;
2220 fhandle_t *fh;
2221 int error;
2222
2223 if (debug > 2) {
2224 (void) printf("=============\nGETFH3: name '%s', fh ",
2225 args->gfh_path);
2226 debug_opaque_print(stdout, &args->gfh_fh_buf,
2227 sizeof (fhandle_t));
2228 (void) printf("\n");
2229 }
2230
2231 fh = &args->gfh_fh_buf;
2232
2233 /* If debug print the database */
2234 if (debug > 10) {
2235 fh_print_all_keys(fhpath, fh);
2236 }
2237 if (fh_lookup_link(fhpath, fh, fh,
2238 args->gfh_path, &fhrec, &error) == NULL) {
2239 if (error = FH_ADD(fhpath, fh, fh, args->gfh_path)) {
2240 syslog(LOG_ERR, gettext(
2241 "Getfh: Add fh for '%s' failed: %s\n"),
2242 args->gfh_path, ((error >= 0) ?
2243 strerror(error) : "Unknown"));
2244 }
2245 }
2246 if (pathp1 != NULL) {
2247 *pathp1 = nfslog_get_path(fh, NULL, fhpath, "getfh");
2248 *pathp2 = NULL;
2249 }
2250 }
2251
2252 /*
2253 * Exported function
2254 */
2255
2256 /*
2257 * nfslog_get_path - gets the path for this file. fh must be supplied,
2258 * name may be null. If name is supplied, fh is assumed to be a directory
2259 * filehandle, with name as its component. fhpath is the generic path for the
2260 * fhtopath table and prtstr is the name of the caller (for debug purposes).
2261 * Returns the malloc'd path. The caller must free it later.
2262 */
2263 char *
nfslog_get_path(fhandle_t * fh,char * name,char * fhpath,char * prtstr)2264 nfslog_get_path(fhandle_t *fh, char *name, char *fhpath, char *prtstr)
2265 {
2266 char *pathp = fh_print_absolute(fhpath, fh, name);
2267
2268 if (debug > 3) {
2269 (void) printf(" %s: path '%s', fh ", prtstr, pathp);
2270 debug_opaque_print(stdout, fh, sizeof (*fh));
2271 (void) printf("\n");
2272 }
2273 return (pathp);
2274 }
2275
2276 /*
2277 * nfslog_process_fh_rec - updates the fh table based on the rpc req
2278 * Return 0 for success, error otherwise. If success return the path
2279 * for the input file handle(s) if so indicated.
2280 */
2281 int
nfslog_process_fh_rec(struct nfslog_lr * lrp,char * fhpath,char ** pathp1,char ** pathp2,bool_t return_path)2282 nfslog_process_fh_rec(struct nfslog_lr *lrp, char *fhpath, char **pathp1,
2283 char **pathp2, bool_t return_path)
2284 {
2285 struct nfsl_fh_proc_disp *disp;
2286 nfslog_request_record *logrec = &lrp->log_record;
2287 nfslog_record_header *logrechdr = &logrec->re_header;
2288
2289 if ((disp = nfslog_find_fh_dispatch(logrec)) != NULL) {
2290 /*
2291 * Allocate space for the args and results and decode
2292 */
2293 logrec->re_rpc_arg = calloc(1, disp->args_size);
2294
2295 if (!(*disp->xdr_args)(&lrp->xdrs, logrec->re_rpc_arg)) {
2296 free(logrec->re_rpc_arg);
2297 logrec->re_rpc_arg = NULL;
2298 syslog(LOG_ERR, gettext("argument decode failed"));
2299 return (FALSE);
2300 }
2301 /* used later for free of data structures */
2302 lrp->xdrargs = disp->xdr_args;
2303
2304 logrec->re_rpc_res = calloc(1, disp->res_size);
2305 if (!(*disp->xdr_res)(&lrp->xdrs, logrec->re_rpc_res)) {
2306 free(logrec->re_rpc_res);
2307 logrec->re_rpc_res = NULL;
2308 syslog(LOG_ERR, gettext("results decode failed"));
2309 return (FALSE);
2310 }
2311 /* used later for free of data structures */
2312 lrp->xdrres = disp->xdr_res;
2313
2314 /*
2315 * Process the operation within the context of the file handle
2316 * mapping process
2317 */
2318 if (return_path) {
2319 (*disp->nfsl_dis_args)(logrec->re_rpc_arg,
2320 logrec->re_rpc_res, fhpath, pathp1, pathp2);
2321 } else {
2322 if ((logrechdr->rh_version == NFS_VERSION &&
2323 logrechdr->rh_procnum == RFS_LINK) ||
2324 (logrechdr->rh_version == NFS_V3 &&
2325 logrechdr->rh_procnum == NFSPROC3_LINK)) {
2326
2327 (*disp->nfsl_dis_args)(logrec->re_rpc_arg,
2328 logrec->re_rpc_res,
2329 fhpath, pathp1, pathp2);
2330 } else {
2331 (*disp->nfsl_dis_args)(logrec->re_rpc_arg,
2332 logrec->re_rpc_res,
2333 fhpath, NULL, NULL);
2334 }
2335 }
2336 return (TRUE);
2337 } else {
2338 syslog(LOG_ERR, gettext("procedure unknown"));
2339 return (FALSE);
2340 }
2341 }
2342