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 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 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 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 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 * 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 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 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 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 * 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 * 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 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 * 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 * 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 * 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 * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 * 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 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