Lines Matching +full:use +full:- +full:case

1 // SPDX-License-Identifier: GPL-2.0
7 * Extensive rewrite by Neil Brown <neilb@cse.unsw.edu.au> Southern-Spring 1999
8 * ... and again Southern-Winter 2001 to support export_operations
25 * if not, require that we can walk up to exp->ex_dentry
35 if (exp->ex_flags & NFSEXP_NOSUBTREECHECK) in nfsd_acceptable()
39 while (tdentry != exp->ex_path.dentry && !IS_ROOT(tdentry)) { in nfsd_acceptable()
52 if (tdentry != exp->ex_path.dentry) in nfsd_acceptable()
54 rv = (tdentry == exp->ex_path.dentry); in nfsd_acceptable()
60 * generally agreed upon. SunOS seems to use EISDIR if file isn't S_IFREG; a
68 umode_t mode = d_inode(dentry)->i_mode & S_IFMT; in nfsd_mode_check()
83 if (rqstp->rq_vers == 4 && mode == S_IFLNK) in nfsd_mode_check()
96 /* We don't require gss requests to use low ports: */ in nfsd_originating_port_ok()
97 if (rqstp->rq_cred.cr_flavor >= RPC_AUTH_GSS) in nfsd_originating_port_ok()
99 return test_bit(RQ_SECURE, &rqstp->rq_flags); in nfsd_originating_port_ok()
122 if (!(exp->ex_flags & NFSEXP_V4ROOT)) in check_pseudo_root()
125 * v2/v3 clients have no need for the V4ROOT export--they use in check_pseudo_root()
127 * in v4-specific code, in which case v2/v3 clients could bypass in check_pseudo_root()
144 if (unlikely(dentry != exp->ex_path.dentry)) in check_pseudo_root()
150 * Use the given filehandle to look up the corresponding export and
156 struct knfsd_fh *fh = &fhp->fh_handle; in nfsd_set_fh_dentry()
161 int data_left = fh->fh_size/4; in nfsd_set_fh_dentry()
166 if (rqstp->rq_vers > 2) in nfsd_set_fh_dentry()
168 if (rqstp->rq_vers == 4 && fh->fh_size == 0) in nfsd_set_fh_dentry()
171 if (fh->fh_version != 1) in nfsd_set_fh_dentry()
174 if (--data_left < 0) in nfsd_set_fh_dentry()
176 if (fh->fh_auth_type != 0) in nfsd_set_fh_dentry()
178 len = key_len(fh->fh_fsid_type) / 4; in nfsd_set_fh_dentry()
181 if (fh->fh_fsid_type == FSID_MAJOR_MINOR) { in nfsd_set_fh_dentry()
184 fh->fh_fsid_type = FSID_ENCODE_DEV; in nfsd_set_fh_dentry()
186 * struct knfsd_fh uses host-endian fields, which are in nfsd_set_fh_dentry()
187 * sometimes used to hold net-endian values. This in nfsd_set_fh_dentry()
188 * confuses sparse, so we must use __force here to in nfsd_set_fh_dentry()
191 fh->fh_fsid[0] = new_encode_dev(MKDEV(ntohl((__force __be32)fh->fh_fsid[0]), in nfsd_set_fh_dentry()
192 ntohl((__force __be32)fh->fh_fsid[1]))); in nfsd_set_fh_dentry()
193 fh->fh_fsid[1] = fh->fh_fsid[2]; in nfsd_set_fh_dentry()
195 data_left -= len; in nfsd_set_fh_dentry()
198 exp = rqst_exp_find(rqstp, fh->fh_fsid_type, fh->fh_fsid); in nfsd_set_fh_dentry()
199 fid = (struct fid *)(fh->fh_fsid + len); in nfsd_set_fh_dentry()
205 if (PTR_ERR(exp) == -ENOENT) in nfsd_set_fh_dentry()
211 if (exp->ex_flags & NFSEXP_NOSUBTREECHECK) { in nfsd_set_fh_dentry()
219 * fix that case easily. in nfsd_set_fh_dentry()
223 error = nfserrno(-ENOMEM); in nfsd_set_fh_dentry()
226 new->cap_effective = in nfsd_set_fh_dentry()
227 cap_raise_nfsd_set(new->cap_effective, in nfsd_set_fh_dentry()
228 new->cap_permitted); in nfsd_set_fh_dentry()
241 if (rqstp->rq_vers > 2) in nfsd_set_fh_dentry()
244 fileid_type = fh->fh_fileid_type; in nfsd_set_fh_dentry()
247 dentry = dget(exp->ex_path.dentry); in nfsd_set_fh_dentry()
249 dentry = exportfs_decode_fh_raw(exp->ex_path.mnt, fid, in nfsd_set_fh_dentry()
254 dentry ? PTR_ERR(dentry) : -ESTALE); in nfsd_set_fh_dentry()
256 case -ENOMEM: in nfsd_set_fh_dentry()
257 case -ETIMEDOUT: in nfsd_set_fh_dentry()
260 dentry = ERR_PTR(-ESTALE); in nfsd_set_fh_dentry()
267 if (PTR_ERR(dentry) != -EINVAL) in nfsd_set_fh_dentry()
273 (dentry->d_flags & DCACHE_DISCONNECTED)) { in nfsd_set_fh_dentry()
278 fhp->fh_dentry = dentry; in nfsd_set_fh_dentry()
279 fhp->fh_export = exp; in nfsd_set_fh_dentry()
281 switch (rqstp->rq_vers) { in nfsd_set_fh_dentry()
282 case 4: in nfsd_set_fh_dentry()
283 if (dentry->d_sb->s_export_op->flags & EXPORT_OP_NOATOMIC_ATTR) in nfsd_set_fh_dentry()
284 fhp->fh_no_atomic_attr = true; in nfsd_set_fh_dentry()
286 case 3: in nfsd_set_fh_dentry()
287 if (dentry->d_sb->s_export_op->flags & EXPORT_OP_NOWCC) in nfsd_set_fh_dentry()
288 fhp->fh_no_wcc = true; in nfsd_set_fh_dentry()
290 case 2: in nfsd_set_fh_dentry()
291 fhp->fh_no_wcc = true; in nfsd_set_fh_dentry()
301 * fh_verify - filehandle lookup and access checking
307 * Look up a dentry from the on-the-wire filehandle, check the client's
315 * up a dentry using the on-the-wire filehandle. Subsequent calls will
320 * constants defined in include/linux/stat.h. The caller may use zero
334 if (!fhp->fh_dentry) { in fh_verify()
339 dentry = fhp->fh_dentry; in fh_verify()
340 exp = fhp->fh_export; in fh_verify()
347 * - fh_verify may be called multiple times with different in fh_verify()
351 * - in the NFSv4 case, the filehandle may have been filled in fh_verify()
354 * still need permissions checks. In the worst case, a in fh_verify()
356 * options, and we may now need to use a different uid in fh_verify()
357 * (for example, if different id-squashing options are in in fh_verify()
374 * which clients virtually always use auth_sys for, in fh_verify()
380 * Clients may expect to be able to use auth_sys during mount, in fh_verify()
381 * even if they use gss for everything else; see section 2.3.2 in fh_verify()
385 && exp->ex_path.dentry == dentry) in fh_verify()
407 * an inode. In this case a call to fh_update should be made
413 if (dentry != exp->ex_path.dentry) { in _fh_update()
415 (fhp->fh_handle.fh_fsid + fhp->fh_handle.fh_size/4 - 1); in _fh_update()
416 int maxsize = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4; in _fh_update()
417 int subtreecheck = !(exp->ex_flags & NFSEXP_NOSUBTREECHECK); in _fh_update()
419 fhp->fh_handle.fh_fileid_type = in _fh_update()
421 fhp->fh_handle.fh_size += maxsize * 4; in _fh_update()
423 fhp->fh_handle.fh_fileid_type = FILEID_ROOT; in _fh_update()
429 return exp->ex_path.dentry == exp->ex_path.dentry->d_sb->s_root; in is_root_export()
434 return exp->ex_path.dentry->d_sb; in exp_sb()
440 case FSID_DEV: in fsid_type_ok_for_exp()
441 if (!old_valid_dev(exp_sb(exp)->s_dev)) in fsid_type_ok_for_exp()
444 case FSID_MAJOR_MINOR: in fsid_type_ok_for_exp()
445 case FSID_ENCODE_DEV: in fsid_type_ok_for_exp()
446 return exp_sb(exp)->s_type->fs_flags & FS_REQUIRES_DEV; in fsid_type_ok_for_exp()
447 case FSID_NUM: in fsid_type_ok_for_exp()
448 return exp->ex_flags & NFSEXP_FSID; in fsid_type_ok_for_exp()
449 case FSID_UUID8: in fsid_type_ok_for_exp()
450 case FSID_UUID16: in fsid_type_ok_for_exp()
454 case FSID_UUID4_INUM: in fsid_type_ok_for_exp()
455 case FSID_UUID16_INUM: in fsid_type_ok_for_exp()
456 return exp->ex_uuid != NULL; in fsid_type_ok_for_exp()
468 if (ref_fh && ref_fh->fh_export == exp) { in set_version_and_fsid_type()
469 version = ref_fh->fh_handle.fh_version; in set_version_and_fsid_type()
470 fsid_type = ref_fh->fh_handle.fh_fsid_type; in set_version_and_fsid_type()
475 case 0xca: in set_version_and_fsid_type()
478 case 1: in set_version_and_fsid_type()
485 * As the fsid -> filesystem mapping was guided by in set_version_and_fsid_type()
486 * user-space, there is no guarantee that the filesystem in set_version_and_fsid_type()
492 } else if (exp->ex_flags & NFSEXP_FSID) { in set_version_and_fsid_type()
494 } else if (exp->ex_uuid) { in set_version_and_fsid_type()
495 if (fhp->fh_maxsize >= 64) { in set_version_and_fsid_type()
506 } else if (!old_valid_dev(exp_sb(exp)->s_dev)) in set_version_and_fsid_type()
507 /* for newer device numbers, we must use a newer fsid format */ in set_version_and_fsid_type()
511 fhp->fh_handle.fh_version = version; in set_version_and_fsid_type()
513 fhp->fh_handle.fh_fsid_type = fsid_type; in set_version_and_fsid_type()
521 * if it is non-null and for the same filesystem, then we should compose in fh_compose()
526 dev_t ex_dev = exp_sb(exp)->s_dev; in fh_compose()
530 (long) d_inode(exp->ex_path.dentry)->i_ino, in fh_compose()
532 (inode ? inode->i_ino : 0)); in fh_compose()
541 fhp->fh_no_wcc = ref_fh ? ref_fh->fh_no_wcc : false; in fh_compose()
546 if (fhp->fh_dentry) { in fh_compose()
550 if (fhp->fh_maxsize < NFS_FHSIZE) in fh_compose()
552 fhp->fh_maxsize, in fh_compose()
555 fhp->fh_dentry = dget(dentry); /* our internal copy */ in fh_compose()
556 fhp->fh_export = exp_get(exp); in fh_compose()
558 fhp->fh_handle.fh_size = in fh_compose()
559 key_len(fhp->fh_handle.fh_fsid_type) + 4; in fh_compose()
560 fhp->fh_handle.fh_auth_type = 0; in fh_compose()
562 mk_fsid(fhp->fh_handle.fh_fsid_type, in fh_compose()
563 fhp->fh_handle.fh_fsid, in fh_compose()
565 d_inode(exp->ex_path.dentry)->i_ino, in fh_compose()
566 exp->ex_fsid, exp->ex_uuid); in fh_compose()
570 if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID) { in fh_compose()
587 if (!fhp->fh_dentry) in fh_update()
590 dentry = fhp->fh_dentry; in fh_update()
593 if (fhp->fh_handle.fh_fileid_type != FILEID_ROOT) in fh_update()
596 _fh_update(fhp, fhp->fh_export, dentry); in fh_update()
597 if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID) in fh_update()
610 * fh_fill_pre_attrs - Fill in pre-op attributes
616 bool v4 = (fhp->fh_maxsize == NFS4_FHSIZE); in fh_fill_pre_attrs()
621 if (fhp->fh_no_wcc || fhp->fh_pre_saved) in fh_fill_pre_attrs()
624 inode = d_inode(fhp->fh_dentry); in fh_fill_pre_attrs()
628 stat.mtime = inode->i_mtime; in fh_fill_pre_attrs()
629 stat.ctime = inode->i_ctime; in fh_fill_pre_attrs()
630 stat.size = inode->i_size; in fh_fill_pre_attrs()
633 fhp->fh_pre_change = nfsd4_change_attribute(&stat, inode); in fh_fill_pre_attrs()
635 fhp->fh_pre_mtime = stat.mtime; in fh_fill_pre_attrs()
636 fhp->fh_pre_ctime = stat.ctime; in fh_fill_pre_attrs()
637 fhp->fh_pre_size = stat.size; in fh_fill_pre_attrs()
638 fhp->fh_pre_saved = true; in fh_fill_pre_attrs()
642 * fh_fill_post_attrs - Fill in post-op attributes
648 bool v4 = (fhp->fh_maxsize == NFS4_FHSIZE); in fh_fill_post_attrs()
649 struct inode *inode = d_inode(fhp->fh_dentry); in fh_fill_post_attrs()
652 if (fhp->fh_no_wcc) in fh_fill_post_attrs()
655 if (fhp->fh_post_saved) in fh_fill_post_attrs()
658 err = fh_getattr(fhp, &fhp->fh_post_attr); in fh_fill_post_attrs()
660 fhp->fh_post_saved = false; in fh_fill_post_attrs()
661 fhp->fh_post_attr.ctime = inode->i_ctime; in fh_fill_post_attrs()
663 fhp->fh_post_saved = true; in fh_fill_post_attrs()
665 fhp->fh_post_change = in fh_fill_post_attrs()
666 nfsd4_change_attribute(&fhp->fh_post_attr, inode); in fh_fill_post_attrs()
670 * fh_fill_both_attrs - Fill pre-op and post-op attributes
679 if (!fhp->fh_post_saved) in fh_fill_both_attrs()
681 fhp->fh_pre_change = fhp->fh_post_change; in fh_fill_both_attrs()
682 fhp->fh_pre_mtime = fhp->fh_post_attr.mtime; in fh_fill_both_attrs()
683 fhp->fh_pre_ctime = fhp->fh_post_attr.ctime; in fh_fill_both_attrs()
684 fhp->fh_pre_size = fhp->fh_post_attr.size; in fh_fill_both_attrs()
685 fhp->fh_pre_saved = true; in fh_fill_both_attrs()
694 struct dentry * dentry = fhp->fh_dentry; in fh_put()
695 struct svc_export * exp = fhp->fh_export; in fh_put()
697 fhp->fh_dentry = NULL; in fh_put()
704 fhp->fh_export = NULL; in fh_put()
706 fhp->fh_no_wcc = false; in fh_put()
715 struct knfsd_fh *fh = &fhp->fh_handle; in SVCFH_fmt()
718 if (fh->fh_size < 0 || fh->fh_size> 64) in SVCFH_fmt()
719 return "bad-fh"; in SVCFH_fmt()
720 sprintf(buf, "%d: %*ph", fh->fh_size, fh->fh_size, fh->fh_raw); in SVCFH_fmt()
726 if (fhp->fh_handle.fh_version != 1) in fsid_source()
728 switch(fhp->fh_handle.fh_fsid_type) { in fsid_source()
729 case FSID_DEV: in fsid_source()
730 case FSID_ENCODE_DEV: in fsid_source()
731 case FSID_MAJOR_MINOR: in fsid_source()
732 if (exp_sb(fhp->fh_export)->s_type->fs_flags & FS_REQUIRES_DEV) in fsid_source()
735 case FSID_NUM: in fsid_source()
736 if (fhp->fh_export->ex_flags & NFSEXP_FSID) in fsid_source()
745 if (fhp->fh_export->ex_flags & NFSEXP_FSID) in fsid_source()
747 if (fhp->fh_export->ex_uuid) in fsid_source()