1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * NFS server file handle treatment. 4 * 5 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> 6 * Portions Copyright (C) 1999 G. Allen Morris III <gam3@acm.org> 7 * Extensive rewrite by Neil Brown <neilb@cse.unsw.edu.au> Southern-Spring 1999 8 * ... and again Southern-Winter 2001 to support export_operations 9 */ 10 11 #include <linux/exportfs.h> 12 13 #include <linux/sunrpc/svcauth_gss.h> 14 #include "nfsd.h" 15 #include "vfs.h" 16 #include "auth.h" 17 #include "trace.h" 18 19 #define NFSDDBG_FACILITY NFSDDBG_FH 20 21 22 /* 23 * our acceptability function. 24 * if NOSUBTREECHECK, accept anything 25 * if not, require that we can walk up to exp->ex_dentry 26 * doing some checks on the 'x' bits 27 */ 28 static int nfsd_acceptable(void *expv, struct dentry *dentry) 29 { 30 struct svc_export *exp = expv; 31 int rv; 32 struct dentry *tdentry; 33 struct dentry *parent; 34 35 if (exp->ex_flags & NFSEXP_NOSUBTREECHECK) 36 return 1; 37 38 tdentry = dget(dentry); 39 while (tdentry != exp->ex_path.dentry && !IS_ROOT(tdentry)) { 40 /* make sure parents give x permission to user */ 41 int err; 42 parent = dget_parent(tdentry); 43 err = inode_permission(&nop_mnt_idmap, 44 d_inode(parent), MAY_EXEC); 45 if (err < 0) { 46 dput(parent); 47 break; 48 } 49 dput(tdentry); 50 tdentry = parent; 51 } 52 if (tdentry != exp->ex_path.dentry) 53 dprintk("nfsd_acceptable failed at %p %pd\n", tdentry, tdentry); 54 rv = (tdentry == exp->ex_path.dentry); 55 dput(tdentry); 56 return rv; 57 } 58 59 /* Type check. The correct error return for type mismatches does not seem to be 60 * generally agreed upon. SunOS seems to use EISDIR if file isn't S_IFREG; a 61 * comment in the NFSv3 spec says this is incorrect (implementation notes for 62 * the write call). 63 */ 64 static inline __be32 65 nfsd_mode_check(struct dentry *dentry, umode_t requested) 66 { 67 umode_t mode = d_inode(dentry)->i_mode & S_IFMT; 68 69 if (requested == 0) /* the caller doesn't care */ 70 return nfs_ok; 71 if (mode == requested) { 72 if (mode == S_IFDIR && !d_can_lookup(dentry)) { 73 WARN_ON_ONCE(1); 74 return nfserr_notdir; 75 } 76 return nfs_ok; 77 } 78 if (mode == S_IFLNK) { 79 if (requested == S_IFDIR) 80 return nfserr_symlink_not_dir; 81 return nfserr_symlink; 82 } 83 if (requested == S_IFDIR) 84 return nfserr_notdir; 85 if (mode == S_IFDIR) 86 return nfserr_isdir; 87 return nfserr_wrong_type; 88 } 89 90 static bool nfsd_originating_port_ok(struct svc_rqst *rqstp, 91 struct svc_cred *cred, 92 struct svc_export *exp) 93 { 94 if (nfsexp_flags(cred, exp) & NFSEXP_INSECURE_PORT) 95 return true; 96 /* We don't require gss requests to use low ports: */ 97 if (cred->cr_flavor >= RPC_AUTH_GSS) 98 return true; 99 return test_bit(RQ_SECURE, &rqstp->rq_flags); 100 } 101 102 static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp, 103 struct svc_cred *cred, 104 struct svc_export *exp) 105 { 106 /* Check if the request originated from a secure port. */ 107 if (rqstp && !nfsd_originating_port_ok(rqstp, cred, exp)) { 108 RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); 109 dprintk("nfsd: request from insecure port %s!\n", 110 svc_print_addr(rqstp, buf, sizeof(buf))); 111 return nfserr_perm; 112 } 113 114 /* Set user creds for this exportpoint */ 115 return nfserrno(nfsd_setuser(cred, exp)); 116 } 117 118 static inline __be32 check_pseudo_root(struct dentry *dentry, 119 struct svc_export *exp) 120 { 121 if (!(exp->ex_flags & NFSEXP_V4ROOT)) 122 return nfs_ok; 123 /* 124 * We're exposing only the directories and symlinks that have to be 125 * traversed on the way to real exports: 126 */ 127 if (unlikely(!d_is_dir(dentry) && 128 !d_is_symlink(dentry))) 129 return nfserr_stale; 130 /* 131 * A pseudoroot export gives permission to access only one 132 * single directory; the kernel has to make another upcall 133 * before granting access to anything else under it: 134 */ 135 if (unlikely(dentry != exp->ex_path.dentry)) 136 return nfserr_stale; 137 return nfs_ok; 138 } 139 140 /* 141 * Use the given filehandle to look up the corresponding export and 142 * dentry. On success, the results are used to set fh_export and 143 * fh_dentry. 144 */ 145 static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct net *net, 146 struct svc_cred *cred, 147 struct auth_domain *client, 148 struct auth_domain *gssclient, 149 struct svc_fh *fhp) 150 { 151 struct knfsd_fh *fh = &fhp->fh_handle; 152 struct fid *fid = NULL; 153 struct svc_export *exp; 154 struct dentry *dentry; 155 int fileid_type; 156 int data_left = fh->fh_size/4; 157 int len; 158 __be32 error; 159 160 error = nfserr_badhandle; 161 if (fh->fh_size == 0) 162 return nfserr_nofilehandle; 163 164 if (fh->fh_version != 1) 165 return error; 166 167 if (--data_left < 0) 168 return error; 169 if (fh->fh_auth_type != 0) 170 return error; 171 len = key_len(fh->fh_fsid_type) / 4; 172 if (len == 0) 173 return error; 174 if (fh->fh_fsid_type == FSID_MAJOR_MINOR) { 175 u32 *fsid = fh_fsid(fh); 176 177 /* deprecated, convert to type 3 */ 178 len = key_len(FSID_ENCODE_DEV)/4; 179 fh->fh_fsid_type = FSID_ENCODE_DEV; 180 /* 181 * struct knfsd_fh uses host-endian fields, which are 182 * sometimes used to hold net-endian values. This 183 * confuses sparse, so we must use __force here to 184 * keep it from complaining. 185 */ 186 fsid[0] = new_encode_dev(MKDEV(ntohl((__force __be32)fsid[0]), 187 ntohl((__force __be32)fsid[1]))); 188 fsid[1] = fsid[2]; 189 } 190 data_left -= len; 191 if (data_left < 0) 192 return error; 193 exp = rqst_exp_find(rqstp ? &rqstp->rq_chandle : NULL, 194 net, client, gssclient, 195 fh->fh_fsid_type, fh_fsid(fh)); 196 fid = (struct fid *)(fh_fsid(fh) + len); 197 198 error = nfserr_stale; 199 if (IS_ERR(exp)) { 200 trace_nfsd_set_fh_dentry_badexport(rqstp, fhp, PTR_ERR(exp)); 201 202 if (PTR_ERR(exp) == -ENOENT) 203 return error; 204 205 return nfserrno(PTR_ERR(exp)); 206 } 207 208 if (exp->ex_flags & NFSEXP_NOSUBTREECHECK) { 209 /* Elevate privileges so that the lack of 'r' or 'x' 210 * permission on some parent directory will 211 * not stop exportfs_decode_fh from being able 212 * to reconnect a directory into the dentry cache. 213 * The same problem can affect "SUBTREECHECK" exports, 214 * but as nfsd_acceptable depends on correct 215 * access control settings being in effect, we cannot 216 * fix that case easily. 217 */ 218 struct cred *new = prepare_creds(); 219 if (!new) { 220 error = nfserrno(-ENOMEM); 221 goto out; 222 } 223 new->cap_effective = 224 cap_raise_nfsd_set(new->cap_effective, 225 new->cap_permitted); 226 put_cred(override_creds(new)); 227 } else { 228 error = nfsd_setuser_and_check_port(rqstp, cred, exp); 229 if (error) 230 goto out; 231 } 232 233 /* 234 * Look up the dentry using the NFS file handle. 235 */ 236 error = nfserr_badhandle; 237 238 fileid_type = fh->fh_fileid_type; 239 240 if (fileid_type == FILEID_ROOT) 241 dentry = dget(exp->ex_path.dentry); 242 else { 243 dentry = exportfs_decode_fh_raw(exp->ex_path.mnt, fid, 244 data_left, fileid_type, 0, 245 nfsd_acceptable, exp); 246 if (IS_ERR_OR_NULL(dentry)) { 247 trace_nfsd_set_fh_dentry_badhandle(rqstp, fhp, 248 dentry ? PTR_ERR(dentry) : -ESTALE); 249 switch (PTR_ERR(dentry)) { 250 case -ENOMEM: 251 case -ETIMEDOUT: 252 break; 253 default: 254 dentry = ERR_PTR(-ESTALE); 255 } 256 } 257 } 258 if (dentry == NULL) 259 goto out; 260 if (IS_ERR(dentry)) { 261 if (PTR_ERR(dentry) != -EINVAL) 262 error = nfserrno(PTR_ERR(dentry)); 263 goto out; 264 } 265 266 if (d_is_dir(dentry) && 267 (dentry->d_flags & DCACHE_DISCONNECTED)) { 268 printk("nfsd: find_fh_dentry returned a DISCONNECTED directory: %pd2\n", 269 dentry); 270 } 271 272 fhp->fh_dentry = dentry; 273 fhp->fh_export = exp; 274 275 switch (fhp->fh_maxsize) { 276 case NFS4_FHSIZE: 277 if (dentry->d_sb->s_export_op->flags & EXPORT_OP_NOATOMIC_ATTR) 278 fhp->fh_no_atomic_attr = true; 279 fhp->fh_64bit_cookies = true; 280 break; 281 case NFS3_FHSIZE: 282 if (dentry->d_sb->s_export_op->flags & EXPORT_OP_NOWCC) 283 fhp->fh_no_wcc = true; 284 fhp->fh_64bit_cookies = true; 285 if (exp->ex_flags & NFSEXP_V4ROOT) 286 goto out; 287 break; 288 case NFS_FHSIZE: 289 fhp->fh_no_wcc = true; 290 if (EX_WGATHER(exp)) 291 fhp->fh_use_wgather = true; 292 if (exp->ex_flags & NFSEXP_V4ROOT) 293 goto out; 294 } 295 296 return 0; 297 out: 298 exp_put(exp); 299 return error; 300 } 301 302 /** 303 * __fh_verify - filehandle lookup and access checking 304 * @rqstp: RPC transaction context, or NULL 305 * @net: net namespace in which to perform the export lookup 306 * @cred: RPC user credential 307 * @client: RPC auth domain 308 * @gssclient: RPC GSS auth domain, or NULL 309 * @fhp: filehandle to be verified 310 * @type: expected type of object pointed to by filehandle 311 * @access: type of access needed to object 312 * 313 * See fh_verify() for further descriptions of @fhp, @type, and @access. 314 */ 315 static __be32 316 __fh_verify(struct svc_rqst *rqstp, 317 struct net *net, struct svc_cred *cred, 318 struct auth_domain *client, 319 struct auth_domain *gssclient, 320 struct svc_fh *fhp, umode_t type, int access) 321 { 322 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 323 struct svc_export *exp = NULL; 324 bool may_bypass_gss = false; 325 struct dentry *dentry; 326 __be32 error; 327 328 if (!fhp->fh_dentry) { 329 error = nfsd_set_fh_dentry(rqstp, net, cred, client, 330 gssclient, fhp); 331 if (error) 332 goto out; 333 } 334 dentry = fhp->fh_dentry; 335 exp = fhp->fh_export; 336 337 trace_nfsd_fh_verify(rqstp, fhp, type, access); 338 339 /* 340 * We still have to do all these permission checks, even when 341 * fh_dentry is already set: 342 * - fh_verify may be called multiple times with different 343 * "access" arguments (e.g. nfsd_proc_create calls 344 * fh_verify(...,NFSD_MAY_EXEC) first, then later (in 345 * nfsd_create) calls fh_verify(...,NFSD_MAY_CREATE). 346 * - in the NFSv4 case, the filehandle may have been filled 347 * in by fh_compose, and given a dentry, but further 348 * compound operations performed with that filehandle 349 * still need permissions checks. In the worst case, a 350 * mountpoint crossing may have changed the export 351 * options, and we may now need to use a different uid 352 * (for example, if different id-squashing options are in 353 * effect on the new filesystem). 354 */ 355 error = check_pseudo_root(dentry, exp); 356 if (error) 357 goto out; 358 359 error = nfsd_setuser_and_check_port(rqstp, cred, exp); 360 if (error) 361 goto out; 362 363 error = nfsd_mode_check(dentry, type); 364 if (error) 365 goto out; 366 367 if ((access & NFSD_MAY_NLM) && (exp->ex_flags & NFSEXP_NOAUTHNLM)) 368 /* NLM is allowed to fully bypass authentication */ 369 goto out; 370 371 if (access & NFSD_MAY_BYPASS_GSS) 372 may_bypass_gss = true; 373 /* 374 * Clients may expect to be able to use auth_sys during mount, 375 * even if they use gss for everything else; see section 2.3.2 376 * of rfc 2623. 377 */ 378 if (access & NFSD_MAY_BYPASS_GSS_ON_ROOT 379 && exp->ex_path.dentry == dentry) 380 may_bypass_gss = true; 381 382 error = check_nfsd_access(exp, rqstp, may_bypass_gss); 383 if (error) 384 goto out; 385 /* During LOCALIO call to fh_verify will be called with a NULL rqstp */ 386 if (rqstp) 387 svc_xprt_set_valid(rqstp->rq_xprt); 388 389 /* Finally, check access permissions. */ 390 error = nfsd_permission(cred, exp, dentry, access); 391 out: 392 trace_nfsd_fh_verify_err(rqstp, fhp, type, access, error); 393 if (error == nfserr_stale) 394 nfsd_stats_fh_stale_inc(nn, exp); 395 return error; 396 } 397 398 /** 399 * fh_verify_local - filehandle lookup and access checking 400 * @net: net namespace in which to perform the export lookup 401 * @cred: RPC user credential 402 * @client: RPC auth domain 403 * @fhp: filehandle to be verified 404 * @type: expected type of object pointed to by filehandle 405 * @access: type of access needed to object 406 * 407 * This API can be used by callers who do not have an RPC 408 * transaction context (ie are not running in an nfsd thread). 409 * 410 * See fh_verify() for further descriptions of @fhp, @type, and @access. 411 */ 412 __be32 413 fh_verify_local(struct net *net, struct svc_cred *cred, 414 struct auth_domain *client, struct svc_fh *fhp, 415 umode_t type, int access) 416 { 417 return __fh_verify(NULL, net, cred, client, NULL, 418 fhp, type, access); 419 } 420 421 /** 422 * fh_verify - filehandle lookup and access checking 423 * @rqstp: pointer to current rpc request 424 * @fhp: filehandle to be verified 425 * @type: expected type of object pointed to by filehandle 426 * @access: type of access needed to object 427 * 428 * Look up a dentry from the on-the-wire filehandle, check the client's 429 * access to the export, and set the current task's credentials. 430 * 431 * Regardless of success or failure of fh_verify(), fh_put() should be 432 * called on @fhp when the caller is finished with the filehandle. 433 * 434 * fh_verify() may be called multiple times on a given filehandle, for 435 * example, when processing an NFSv4 compound. The first call will look 436 * up a dentry using the on-the-wire filehandle. Subsequent calls will 437 * skip the lookup and just perform the other checks and possibly change 438 * the current task's credentials. 439 * 440 * @type specifies the type of object expected using one of the S_IF* 441 * constants defined in include/linux/stat.h. The caller may use zero 442 * to indicate that it doesn't care, or a negative integer to indicate 443 * that it expects something not of the given type. 444 * 445 * @access is formed from the NFSD_MAY_* constants defined in 446 * fs/nfsd/vfs.h. 447 */ 448 __be32 449 fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int access) 450 { 451 return __fh_verify(rqstp, SVC_NET(rqstp), &rqstp->rq_cred, 452 rqstp->rq_client, rqstp->rq_gssclient, 453 fhp, type, access); 454 } 455 456 /* 457 * Compose a file handle for an NFS reply. 458 * 459 * Note that when first composed, the dentry may not yet have 460 * an inode. In this case a call to fh_update should be made 461 * before the fh goes out on the wire ... 462 */ 463 static void _fh_update(struct svc_fh *fhp, struct svc_export *exp, 464 struct dentry *dentry) 465 { 466 if (dentry != exp->ex_path.dentry) { 467 struct fid *fid = (struct fid *) 468 (fh_fsid(&fhp->fh_handle) + fhp->fh_handle.fh_size/4 - 1); 469 int maxsize = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4; 470 int fh_flags = (exp->ex_flags & NFSEXP_NOSUBTREECHECK) ? 0 : 471 EXPORT_FH_CONNECTABLE; 472 int fileid_type = 473 exportfs_encode_fh(dentry, fid, &maxsize, fh_flags); 474 475 fhp->fh_handle.fh_fileid_type = 476 fileid_type > 0 ? fileid_type : FILEID_INVALID; 477 fhp->fh_handle.fh_size += maxsize * 4; 478 } else { 479 fhp->fh_handle.fh_fileid_type = FILEID_ROOT; 480 } 481 } 482 483 static bool is_root_export(struct svc_export *exp) 484 { 485 return exp->ex_path.dentry == exp->ex_path.dentry->d_sb->s_root; 486 } 487 488 static struct super_block *exp_sb(struct svc_export *exp) 489 { 490 return exp->ex_path.dentry->d_sb; 491 } 492 493 static bool fsid_type_ok_for_exp(u8 fsid_type, struct svc_export *exp) 494 { 495 switch (fsid_type) { 496 case FSID_DEV: 497 if (!old_valid_dev(exp_sb(exp)->s_dev)) 498 return false; 499 fallthrough; 500 case FSID_MAJOR_MINOR: 501 case FSID_ENCODE_DEV: 502 return exp_sb(exp)->s_type->fs_flags & FS_REQUIRES_DEV; 503 case FSID_NUM: 504 return exp->ex_flags & NFSEXP_FSID; 505 case FSID_UUID8: 506 case FSID_UUID16: 507 if (!is_root_export(exp)) 508 return false; 509 fallthrough; 510 case FSID_UUID4_INUM: 511 case FSID_UUID16_INUM: 512 return exp->ex_uuid != NULL; 513 } 514 return true; 515 } 516 517 518 static void set_version_and_fsid_type(struct svc_fh *fhp, struct svc_export *exp, struct svc_fh *ref_fh) 519 { 520 u8 version; 521 u8 fsid_type; 522 retry: 523 version = 1; 524 if (ref_fh && ref_fh->fh_export == exp) { 525 version = ref_fh->fh_handle.fh_version; 526 fsid_type = ref_fh->fh_handle.fh_fsid_type; 527 528 ref_fh = NULL; 529 530 switch (version) { 531 case 0xca: 532 fsid_type = FSID_DEV; 533 break; 534 case 1: 535 break; 536 default: 537 goto retry; 538 } 539 540 /* 541 * As the fsid -> filesystem mapping was guided by 542 * user-space, there is no guarantee that the filesystem 543 * actually supports that fsid type. If it doesn't we 544 * loop around again without ref_fh set. 545 */ 546 if (!fsid_type_ok_for_exp(fsid_type, exp)) 547 goto retry; 548 } else if (exp->ex_flags & NFSEXP_FSID) { 549 fsid_type = FSID_NUM; 550 } else if (exp->ex_uuid) { 551 if (fhp->fh_maxsize >= 64) { 552 if (is_root_export(exp)) 553 fsid_type = FSID_UUID16; 554 else 555 fsid_type = FSID_UUID16_INUM; 556 } else { 557 if (is_root_export(exp)) 558 fsid_type = FSID_UUID8; 559 else 560 fsid_type = FSID_UUID4_INUM; 561 } 562 } else if (!old_valid_dev(exp_sb(exp)->s_dev)) 563 /* for newer device numbers, we must use a newer fsid format */ 564 fsid_type = FSID_ENCODE_DEV; 565 else 566 fsid_type = FSID_DEV; 567 fhp->fh_handle.fh_version = version; 568 if (version) 569 fhp->fh_handle.fh_fsid_type = fsid_type; 570 } 571 572 __be32 573 fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, 574 struct svc_fh *ref_fh) 575 { 576 /* ref_fh is a reference file handle. 577 * if it is non-null and for the same filesystem, then we should compose 578 * a filehandle which is of the same version, where possible. 579 */ 580 581 struct inode * inode = d_inode(dentry); 582 dev_t ex_dev = exp_sb(exp)->s_dev; 583 584 dprintk("nfsd: fh_compose(exp %02x:%02x/%ld %pd2, ino=%ld)\n", 585 MAJOR(ex_dev), MINOR(ex_dev), 586 (long) d_inode(exp->ex_path.dentry)->i_ino, 587 dentry, 588 (inode ? inode->i_ino : 0)); 589 590 /* Choose filehandle version and fsid type based on 591 * the reference filehandle (if it is in the same export) 592 * or the export options. 593 */ 594 set_version_and_fsid_type(fhp, exp, ref_fh); 595 596 /* If we have a ref_fh, then copy the fh_no_wcc setting from it. */ 597 fhp->fh_no_wcc = ref_fh ? ref_fh->fh_no_wcc : false; 598 599 if (ref_fh == fhp) 600 fh_put(ref_fh); 601 602 if (fhp->fh_dentry) { 603 printk(KERN_ERR "fh_compose: fh %pd2 not initialized!\n", 604 dentry); 605 } 606 if (fhp->fh_maxsize < NFS_FHSIZE) 607 printk(KERN_ERR "fh_compose: called with maxsize %d! %pd2\n", 608 fhp->fh_maxsize, 609 dentry); 610 611 fhp->fh_dentry = dget(dentry); /* our internal copy */ 612 fhp->fh_export = exp_get(exp); 613 614 fhp->fh_handle.fh_size = 615 key_len(fhp->fh_handle.fh_fsid_type) + 4; 616 fhp->fh_handle.fh_auth_type = 0; 617 618 mk_fsid(fhp->fh_handle.fh_fsid_type, 619 fh_fsid(&fhp->fh_handle), 620 ex_dev, 621 d_inode(exp->ex_path.dentry)->i_ino, 622 exp->ex_fsid, exp->ex_uuid); 623 624 if (inode) 625 _fh_update(fhp, exp, dentry); 626 if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID) { 627 fh_put(fhp); 628 return nfserr_stale; 629 } 630 631 return 0; 632 } 633 634 /* 635 * Update file handle information after changing a dentry. 636 * This is only called by nfsd_create, nfsd_create_v3 and nfsd_proc_create 637 */ 638 __be32 639 fh_update(struct svc_fh *fhp) 640 { 641 struct dentry *dentry; 642 643 if (!fhp->fh_dentry) 644 goto out_bad; 645 646 dentry = fhp->fh_dentry; 647 if (d_really_is_negative(dentry)) 648 goto out_negative; 649 if (fhp->fh_handle.fh_fileid_type != FILEID_ROOT) 650 return 0; 651 652 _fh_update(fhp, fhp->fh_export, dentry); 653 if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID) 654 return nfserr_stale; 655 return 0; 656 out_bad: 657 printk(KERN_ERR "fh_update: fh not verified!\n"); 658 return nfserr_serverfault; 659 out_negative: 660 printk(KERN_ERR "fh_update: %pd2 still negative!\n", 661 dentry); 662 return nfserr_serverfault; 663 } 664 665 /** 666 * fh_fill_pre_attrs - Fill in pre-op attributes 667 * @fhp: file handle to be updated 668 * 669 */ 670 __be32 __must_check fh_fill_pre_attrs(struct svc_fh *fhp) 671 { 672 bool v4 = (fhp->fh_maxsize == NFS4_FHSIZE); 673 struct kstat stat; 674 __be32 err; 675 676 if (fhp->fh_no_wcc || fhp->fh_pre_saved) 677 return nfs_ok; 678 679 err = fh_getattr(fhp, &stat); 680 if (err) 681 return err; 682 683 if (v4) 684 fhp->fh_pre_change = nfsd4_change_attribute(&stat); 685 686 fhp->fh_pre_mtime = stat.mtime; 687 fhp->fh_pre_ctime = stat.ctime; 688 fhp->fh_pre_size = stat.size; 689 fhp->fh_pre_saved = true; 690 return nfs_ok; 691 } 692 693 /** 694 * fh_fill_post_attrs - Fill in post-op attributes 695 * @fhp: file handle to be updated 696 * 697 */ 698 __be32 fh_fill_post_attrs(struct svc_fh *fhp) 699 { 700 bool v4 = (fhp->fh_maxsize == NFS4_FHSIZE); 701 __be32 err; 702 703 if (fhp->fh_no_wcc) 704 return nfs_ok; 705 706 if (fhp->fh_post_saved) 707 printk("nfsd: inode locked twice during operation.\n"); 708 709 err = fh_getattr(fhp, &fhp->fh_post_attr); 710 if (err) 711 return err; 712 713 fhp->fh_post_saved = true; 714 if (v4) 715 fhp->fh_post_change = 716 nfsd4_change_attribute(&fhp->fh_post_attr); 717 return nfs_ok; 718 } 719 720 /** 721 * fh_fill_both_attrs - Fill pre-op and post-op attributes 722 * @fhp: file handle to be updated 723 * 724 * This is used when the directory wasn't changed, but wcc attributes 725 * are needed anyway. 726 */ 727 __be32 __must_check fh_fill_both_attrs(struct svc_fh *fhp) 728 { 729 __be32 err; 730 731 err = fh_fill_post_attrs(fhp); 732 if (err) 733 return err; 734 735 fhp->fh_pre_change = fhp->fh_post_change; 736 fhp->fh_pre_mtime = fhp->fh_post_attr.mtime; 737 fhp->fh_pre_ctime = fhp->fh_post_attr.ctime; 738 fhp->fh_pre_size = fhp->fh_post_attr.size; 739 fhp->fh_pre_saved = true; 740 return nfs_ok; 741 } 742 743 /* 744 * Release a file handle. 745 */ 746 void 747 fh_put(struct svc_fh *fhp) 748 { 749 struct dentry * dentry = fhp->fh_dentry; 750 struct svc_export * exp = fhp->fh_export; 751 if (dentry) { 752 fhp->fh_dentry = NULL; 753 dput(dentry); 754 fh_clear_pre_post_attrs(fhp); 755 } 756 fh_drop_write(fhp); 757 if (exp) { 758 exp_put(exp); 759 fhp->fh_export = NULL; 760 } 761 fhp->fh_no_wcc = false; 762 return; 763 } 764 765 /* 766 * Shorthand for dprintk()'s 767 */ 768 char * SVCFH_fmt(struct svc_fh *fhp) 769 { 770 struct knfsd_fh *fh = &fhp->fh_handle; 771 static char buf[2+1+1+64*3+1]; 772 773 if (fh->fh_size > 64) 774 return "bad-fh"; 775 sprintf(buf, "%d: %*ph", fh->fh_size, fh->fh_size, fh->fh_raw); 776 return buf; 777 } 778 779 enum fsid_source fsid_source(const struct svc_fh *fhp) 780 { 781 if (fhp->fh_handle.fh_version != 1) 782 return FSIDSOURCE_DEV; 783 switch(fhp->fh_handle.fh_fsid_type) { 784 case FSID_DEV: 785 case FSID_ENCODE_DEV: 786 case FSID_MAJOR_MINOR: 787 if (exp_sb(fhp->fh_export)->s_type->fs_flags & FS_REQUIRES_DEV) 788 return FSIDSOURCE_DEV; 789 break; 790 case FSID_NUM: 791 if (fhp->fh_export->ex_flags & NFSEXP_FSID) 792 return FSIDSOURCE_FSID; 793 break; 794 default: 795 break; 796 } 797 /* either a UUID type filehandle, or the filehandle doesn't 798 * match the export. 799 */ 800 if (fhp->fh_export->ex_flags & NFSEXP_FSID) 801 return FSIDSOURCE_FSID; 802 if (fhp->fh_export->ex_uuid) 803 return FSIDSOURCE_UUID; 804 return FSIDSOURCE_DEV; 805 } 806 807 /** 808 * nfsd4_change_attribute - Generate an NFSv4 change_attribute value 809 * @stat: inode attributes 810 * 811 * Caller must fill in @stat before calling, typically by invoking 812 * vfs_getattr() with STATX_MODE, STATX_CTIME, and STATX_CHANGE_COOKIE. 813 * Returns an unsigned 64-bit changeid4 value (RFC 8881 Section 3.2). 814 * 815 * We could use i_version alone as the change attribute. However, i_version 816 * can go backwards on a regular file after an unclean shutdown. On its own 817 * that doesn't necessarily cause a problem, but if i_version goes backwards 818 * and then is incremented again it could reuse a value that was previously 819 * used before boot, and a client who queried the two values might incorrectly 820 * assume nothing changed. 821 * 822 * By using both ctime and the i_version counter we guarantee that as long as 823 * time doesn't go backwards we never reuse an old value. If the filesystem 824 * advertises STATX_ATTR_CHANGE_MONOTONIC, then this mitigation is not 825 * needed. 826 * 827 * We only need to do this for regular files as well. For directories, we 828 * assume that the new change attr is always logged to stable storage in some 829 * fashion before the results can be seen. 830 */ 831 u64 nfsd4_change_attribute(const struct kstat *stat) 832 { 833 u64 chattr; 834 835 if (stat->result_mask & STATX_CHANGE_COOKIE) { 836 chattr = stat->change_cookie; 837 if (S_ISREG(stat->mode) && 838 !(stat->attributes & STATX_ATTR_CHANGE_MONOTONIC)) { 839 chattr += (u64)stat->ctime.tv_sec << 30; 840 chattr += stat->ctime.tv_nsec; 841 } 842 } else { 843 chattr = time_to_chattr(&stat->ctime); 844 } 845 return chattr; 846 } 847