static void test_nfsfh(void){ dev_t dev=0; u32 unfs=0, u32ptr[2]; ino_t ino=0; struct svc_fh A1; int i=20; u32_to_dev_t((__u32)unfs); ino_t_to_u32(ino); u32_to_ino_t((__u32)unfs); mk_fsid_v0(u32ptr, dev, ino); mk_fsid_v1(u32ptr, unfs); SVCFH_fmt(&A1); fh_init(&A1,i); fh_lock(&A1); fh_unlock(&A1); printk("finished nfsfh test\n"); }
int fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, struct svc_fh *ref_fh) { /* ref_fh is a reference file handle. * if it is non-null, then we should compose a filehandle which is * of the same version, where possible. * Currently, that means that if ref_fh->fh_handle.fh_version == 0xca * Then create a 32byte filehandle using nfs_fhbase_old * */ u8 ref_fh_version = 0; u8 ref_fh_fsid_type = 0; struct inode * inode = dentry->d_inode; struct dentry *parent = dentry->d_parent; __u32 *datap; dev_t ex_dev = exp->ex_dentry->d_inode->i_sb->s_dev; dprintk("nfsd: fh_compose(exp %02x:%02x/%ld %s/%s, ino=%ld)\n", MAJOR(ex_dev), MINOR(ex_dev), (long) exp->ex_dentry->d_inode->i_ino, parent->d_name.name, dentry->d_name.name, (inode ? inode->i_ino : 0)); if (ref_fh) { ref_fh_version = ref_fh->fh_handle.fh_version; if (ref_fh_version == 0xca) ref_fh_fsid_type = 0; else ref_fh_fsid_type = ref_fh->fh_handle.fh_fsid_type; if (ref_fh_fsid_type > 3) ref_fh_fsid_type = 0; } /* make sure ref_fh type works for given export */ if (ref_fh_fsid_type == 1 && !(exp->ex_flags & NFSEXP_FSID)) { /* if we don't have an fsid, we cannot provide one... */ ref_fh_fsid_type = 0; } if (!old_valid_dev(ex_dev) && ref_fh_fsid_type == 0) { /* for newer device numbers, we must use a newer fsid format */ ref_fh_version = 1; ref_fh_fsid_type = 3; } if (old_valid_dev(ex_dev) && (ref_fh_fsid_type == 2 || ref_fh_fsid_type == 3)) /* must use type1 for smaller device numbers */ ref_fh_fsid_type = 0; if (ref_fh == fhp) fh_put(ref_fh); if (fhp->fh_locked || fhp->fh_dentry) { printk(KERN_ERR "fh_compose: fh %s/%s not initialized!\n", parent->d_name.name, dentry->d_name.name); } if (fhp->fh_maxsize < NFS_FHSIZE) printk(KERN_ERR "fh_compose: called with maxsize %d! %s/%s\n", fhp->fh_maxsize, parent->d_name.name, dentry->d_name.name); fhp->fh_dentry = dget(dentry); /* our internal copy */ fhp->fh_export = exp; cache_get(&exp->h); if (ref_fh_version == 0xca) { /* old style filehandle please */ memset(&fhp->fh_handle.fh_base, 0, NFS_FHSIZE); fhp->fh_handle.fh_size = NFS_FHSIZE; fhp->fh_handle.ofh_dcookie = 0xfeebbaca; fhp->fh_handle.ofh_dev = old_encode_dev(ex_dev); fhp->fh_handle.ofh_xdev = fhp->fh_handle.ofh_dev; fhp->fh_handle.ofh_xino = ino_t_to_u32(exp->ex_dentry->d_inode->i_ino); fhp->fh_handle.ofh_dirino = ino_t_to_u32(parent_ino(dentry)); if (inode) _fh_update_old(dentry, exp, &fhp->fh_handle); } else { int len; fhp->fh_handle.fh_version = 1; fhp->fh_handle.fh_auth_type = 0; datap = fhp->fh_handle.fh_auth+0; fhp->fh_handle.fh_fsid_type = ref_fh_fsid_type; switch (ref_fh_fsid_type) { case 0: /* * fsid_type 0: * 2byte major, 2byte minor, 4byte inode */ mk_fsid_v0(datap, ex_dev, exp->ex_dentry->d_inode->i_ino); break; case 1: /* fsid_type 1 == 4 bytes filesystem id */ mk_fsid_v1(datap, exp->ex_fsid); break; case 2: /* * fsid_type 2: * 4byte major, 4byte minor, 4byte inode */ mk_fsid_v2(datap, ex_dev, exp->ex_dentry->d_inode->i_ino); break; case 3: /* * fsid_type 3: * 4byte devicenumber, 4byte inode */ mk_fsid_v3(datap, ex_dev, exp->ex_dentry->d_inode->i_ino); break; } len = key_len(ref_fh_fsid_type); datap += len/4; fhp->fh_handle.fh_size = 4 + len; if (inode) { int size = (fhp->fh_maxsize-len-4)/4; fhp->fh_handle.fh_fileid_type = _fh_update(dentry, exp, datap, &size); fhp->fh_handle.fh_size += size*4; } if (fhp->fh_handle.fh_fileid_type == 255) return nfserr_opnotsupp; } nfsd_nr_verified++; return 0; }