diff options
author | Conrad Meyer <cem@FreeBSD.org> | 2017-01-08 06:21:49 +0000 |
---|---|---|
committer | Conrad Meyer <cem@FreeBSD.org> | 2017-01-08 06:21:49 +0000 |
commit | dbaab6e66f856662798722aa992a1641300d989d (patch) | |
tree | 7f08603b3ef76df68a40b69b80adc9ca1fc65414 /sys/fs/cd9660 | |
parent | 0c6393a265bfbf26e8337d123c5839de409da0ac (diff) | |
download | src-dbaab6e66f856662798722aa992a1641300d989d.tar.gz src-dbaab6e66f856662798722aa992a1641300d989d.zip |
cd9660: Expand internal inum size to 64 bits
Inums in cd9660 refer to byte offsets on the media. DVD and BD media
can have entries above 4GB, especially with multi-session images.
PR: 190655
Reported by: Thomas Schmitt <scdbackup at gmx.net>
Notes
Notes:
svn path=/head/; revision=311665
Diffstat (limited to 'sys/fs/cd9660')
-rw-r--r-- | sys/fs/cd9660/cd9660_lookup.c | 6 | ||||
-rw-r--r-- | sys/fs/cd9660/cd9660_node.c | 4 | ||||
-rw-r--r-- | sys/fs/cd9660/cd9660_node.h | 2 | ||||
-rw-r--r-- | sys/fs/cd9660/cd9660_rrip.c | 2 | ||||
-rw-r--r-- | sys/fs/cd9660/cd9660_vfsops.c | 27 | ||||
-rw-r--r-- | sys/fs/cd9660/cd9660_vnops.c | 11 | ||||
-rw-r--r-- | sys/fs/cd9660/iso.h | 17 | ||||
-rw-r--r-- | sys/fs/cd9660/iso_rrip.h | 4 |
8 files changed, 50 insertions, 23 deletions
diff --git a/sys/fs/cd9660/cd9660_lookup.c b/sys/fs/cd9660/cd9660_lookup.c index 274fb3e05c22..498e33fc61e9 100644 --- a/sys/fs/cd9660/cd9660_lookup.c +++ b/sys/fs/cd9660/cd9660_lookup.c @@ -51,8 +51,8 @@ __FBSDID("$FreeBSD$"); #include <fs/cd9660/iso_rrip.h> struct cd9660_ino_alloc_arg { - ino_t ino; - ino_t i_ino; + cd_ino_t ino; + cd_ino_t i_ino; struct iso_directory_record *ep; }; @@ -124,7 +124,7 @@ cd9660_lookup(ap) struct cd9660_ino_alloc_arg dd_arg; u_long bmask; /* block offset mask */ int error; - ino_t ino, i_ino; + cd_ino_t ino, i_ino; int ltype, reclen; u_short namelen; int isoflags; diff --git a/sys/fs/cd9660/cd9660_node.c b/sys/fs/cd9660/cd9660_node.c index 19d723e1e6e2..359a30445f3c 100644 --- a/sys/fs/cd9660/cd9660_node.c +++ b/sys/fs/cd9660/cd9660_node.c @@ -309,12 +309,12 @@ cd9660_tstamp_conv17(pi,pu) return cd9660_tstamp_conv7(buf, pu, ISO_FTYPE_DEFAULT); } -ino_t +cd_ino_t isodirino(isodir, imp) struct iso_directory_record *isodir; struct iso_mnt *imp; { - ino_t ino; + cd_ino_t ino; ino = (isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length)) << imp->im_bshift; diff --git a/sys/fs/cd9660/cd9660_node.h b/sys/fs/cd9660/cd9660_node.h index 80e233e769be..cd8f90caca84 100644 --- a/sys/fs/cd9660/cd9660_node.h +++ b/sys/fs/cd9660/cd9660_node.h @@ -58,7 +58,7 @@ typedef struct { struct iso_node { struct vnode *i_vnode; /* vnode associated with this inode */ - ino_t i_number; /* the identity of the inode */ + cd_ino_t i_number; /* the identity of the inode */ /* we use the actual starting block of the file */ struct iso_mnt *i_mnt; /* filesystem associated with this inode */ struct lockf *i_lockf; /* head of byte-level lock list */ diff --git a/sys/fs/cd9660/cd9660_rrip.c b/sys/fs/cd9660/cd9660_rrip.c index a6880393c01c..7ddb7db0f211 100644 --- a/sys/fs/cd9660/cd9660_rrip.c +++ b/sys/fs/cd9660/cd9660_rrip.c @@ -628,7 +628,7 @@ cd9660_rrip_getname(isodir,outbuf,outlen,inump,imp) struct iso_directory_record *isodir; char *outbuf; u_short *outlen; - ino_t *inump; + cd_ino_t *inump; struct iso_mnt *imp; { ISO_RRIP_ANALYZE analyze; diff --git a/sys/fs/cd9660/cd9660_vfsops.c b/sys/fs/cd9660/cd9660_vfsops.c index a55846403316..7473f97dceef 100644 --- a/sys/fs/cd9660/cd9660_vfsops.c +++ b/sys/fs/cd9660/cd9660_vfsops.c @@ -540,7 +540,7 @@ cd9660_root(mp, flags, vpp) struct iso_mnt *imp = VFSTOISOFS(mp); struct iso_directory_record *dp = (struct iso_directory_record *)imp->root; - ino_t ino = isodirino(dp, imp); + cd_ino_t ino = isodirino(dp, imp); /* * With RRIP we must use the `.' entry of the root directory. @@ -617,6 +617,11 @@ cd9660_fhtovp(mp, fhp, flags, vpp) return (0); } +/* + * Conform to standard VFS interface; can't vget arbitrary inodes beyond 4GB + * into media with current inode scheme and 32-bit ino_t. This shouldn't be + * needed for anything other than nfsd, and who exports a mounted DVD over NFS? + */ static int cd9660_vget(mp, ino, flags, vpp) struct mount *mp; @@ -640,10 +645,22 @@ cd9660_vget(mp, ino, flags, vpp) (struct iso_directory_record *)0)); } +/* Use special comparator for full 64-bit ino comparison. */ +static int +cd9660_vfs_hash_cmp(vp, pino) + struct vnode *vp; + cd_ino_t *pino; +{ + struct iso_node *ip; + + ip = VTOI(vp); + return (ip->i_number != *pino); +} + int cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir) struct mount *mp; - ino_t ino; + cd_ino_t ino; int flags; struct vnode **vpp; int relocated; @@ -658,7 +675,8 @@ cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir) struct thread *td; td = curthread; - error = vfs_hash_get(mp, ino, flags, td, vpp, NULL, NULL); + error = vfs_hash_get(mp, ino, flags, td, vpp, cd9660_vfs_hash_cmp, + &ino); if (error || *vpp != NULL) return (error); @@ -699,7 +717,8 @@ cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir) *vpp = NULLVP; return (error); } - error = vfs_hash_insert(vp, ino, flags, td, vpp, NULL, NULL); + error = vfs_hash_insert(vp, ino, flags, td, vpp, cd9660_vfs_hash_cmp, + &ino); if (error || *vpp != NULL) return (error); diff --git a/sys/fs/cd9660/cd9660_vnops.c b/sys/fs/cd9660/cd9660_vnops.c index 04c0ff5ceeb4..59d8dc106bec 100644 --- a/sys/fs/cd9660/cd9660_vnops.c +++ b/sys/fs/cd9660/cd9660_vnops.c @@ -481,6 +481,7 @@ cd9660_readdir(ap) u_short namelen; int ncookies = 0; u_long *cookies = NULL; + cd_ino_t ino; dp = VTOI(vdp); imp = dp->i_mnt; @@ -576,8 +577,10 @@ cd9660_readdir(ap) switch (imp->iso_ftype) { case ISO_FTYPE_RRIP: - cd9660_rrip_getname(ep,idp->current.d_name, &namelen, - &idp->current.d_fileno,imp); + ino = idp->current.d_fileno; + cd9660_rrip_getname(ep, idp->current.d_name, &namelen, + &ino, imp); + idp->current.d_fileno = ino; idp->current.d_namlen = (u_char)namelen; if (idp->current.d_namlen) error = iso_uiodir(idp,&idp->current,idp->curroff); @@ -831,8 +834,8 @@ cd9660_vptofh(ap) memcpy(ap->a_fhp, &ifh, sizeof(ifh)); #ifdef ISOFS_DBG - printf("vptofh: ino %d, start %ld\n", - ifh.ifid_ino, ifh.ifid_start); + printf("vptofh: ino %jd, start %ld\n", + (uintmax_t)ifh.ifid_ino, ifh.ifid_start); #endif return (0); diff --git a/sys/fs/cd9660/iso.h b/sys/fs/cd9660/iso.h index a831d7b881c4..53f005c870f0 100644 --- a/sys/fs/cd9660/iso.h +++ b/sys/fs/cd9660/iso.h @@ -219,6 +219,11 @@ enum ISO_FTYPE { ISO_FTYPE_DEFAULT, ISO_FTYPE_9660, ISO_FTYPE_RRIP, #define ISOFSMNT_ROOT 0 #endif +/* + * When ino_t becomes 64-bit, we can remove this definition in favor of ino_t. + */ +#define cd_ino_t uint64_t + struct iso_mnt { uint64_t im_flags; @@ -250,10 +255,10 @@ struct iso_mnt { }; struct ifid { - u_short ifid_len; - u_short ifid_pad; - int ifid_ino; - long ifid_start; + u_short ifid_len; + u_short ifid_pad; + cd_ino_t ifid_ino; + long ifid_start; }; #define VFSTOISOFS(mp) ((struct iso_mnt *)((mp)->mnt_data)) @@ -263,7 +268,7 @@ struct ifid { #define lblkno(imp, loc) ((loc) >> (imp)->im_bshift) #define blksize(imp, ip, lbn) ((imp)->logical_block_size) -int cd9660_vget_internal(struct mount *, ino_t, int, struct vnode **, int, +int cd9660_vget_internal(struct mount *, cd_ino_t, int, struct vnode **, int, struct iso_directory_record *); #define cd9660_sysctl ((int (*)(int *, u_int, void *, size_t *, void *, \ size_t, struct proc *))eopnotsupp) @@ -274,7 +279,7 @@ extern struct vop_vector cd9660_fifoops; int isochar(u_char *, u_char *, int, u_short *, int *, int, void *); int isofncmp(u_char *, int, u_char *, int, int, int, void *, void *); void isofntrans(u_char *, int, u_char *, u_short *, int, int, int, int, void *); -ino_t isodirino(struct iso_directory_record *, struct iso_mnt *); +cd_ino_t isodirino(struct iso_directory_record *, struct iso_mnt *); u_short sgetrune(const char *, size_t, char const **, int, void *); #endif /* _KERNEL */ diff --git a/sys/fs/cd9660/iso_rrip.h b/sys/fs/cd9660/iso_rrip.h index 75c004c40b62..f3aafe00ec29 100644 --- a/sys/fs/cd9660/iso_rrip.h +++ b/sys/fs/cd9660/iso_rrip.h @@ -61,7 +61,7 @@ typedef struct { off_t iso_ce_off; /* offset of continuation area */ int iso_ce_len; /* length of continuation area */ struct iso_mnt *imp; /* mount structure */ - ino_t *inump; /* inode number pointer */ + cd_ino_t *inump; /* inode number pointer */ char *outbuf; /* name/symbolic link output area */ u_short *outlen; /* length of above */ u_short maxlen; /* maximum length of above */ @@ -74,7 +74,7 @@ int cd9660_rrip_analyze(struct iso_directory_record *isodir, struct iso_node *inop, struct iso_mnt *imp); int cd9660_rrip_getname(struct iso_directory_record *isodir, char *outbuf, u_short *outlen, - ino_t *inump, struct iso_mnt *imp); + cd_ino_t *inump, struct iso_mnt *imp); int cd9660_rrip_getsymname(struct iso_directory_record *isodir, char *outbuf, u_short *outlen, struct iso_mnt *imp); |