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