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>
This commit is contained in:
parent
0c6393a265
commit
dbaab6e66f
@ -51,8 +51,8 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <fs/cd9660/iso_rrip.h>
|
#include <fs/cd9660/iso_rrip.h>
|
||||||
|
|
||||||
struct cd9660_ino_alloc_arg {
|
struct cd9660_ino_alloc_arg {
|
||||||
ino_t ino;
|
cd_ino_t ino;
|
||||||
ino_t i_ino;
|
cd_ino_t i_ino;
|
||||||
struct iso_directory_record *ep;
|
struct iso_directory_record *ep;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ cd9660_lookup(ap)
|
|||||||
struct cd9660_ino_alloc_arg dd_arg;
|
struct cd9660_ino_alloc_arg dd_arg;
|
||||||
u_long bmask; /* block offset mask */
|
u_long bmask; /* block offset mask */
|
||||||
int error;
|
int error;
|
||||||
ino_t ino, i_ino;
|
cd_ino_t ino, i_ino;
|
||||||
int ltype, reclen;
|
int ltype, reclen;
|
||||||
u_short namelen;
|
u_short namelen;
|
||||||
int isoflags;
|
int isoflags;
|
||||||
|
@ -309,12 +309,12 @@ cd9660_tstamp_conv17(pi,pu)
|
|||||||
return cd9660_tstamp_conv7(buf, pu, ISO_FTYPE_DEFAULT);
|
return cd9660_tstamp_conv7(buf, pu, ISO_FTYPE_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
ino_t
|
cd_ino_t
|
||||||
isodirino(isodir, imp)
|
isodirino(isodir, imp)
|
||||||
struct iso_directory_record *isodir;
|
struct iso_directory_record *isodir;
|
||||||
struct iso_mnt *imp;
|
struct iso_mnt *imp;
|
||||||
{
|
{
|
||||||
ino_t ino;
|
cd_ino_t ino;
|
||||||
|
|
||||||
ino = (isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length))
|
ino = (isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length))
|
||||||
<< imp->im_bshift;
|
<< imp->im_bshift;
|
||||||
|
@ -58,7 +58,7 @@ typedef struct {
|
|||||||
|
|
||||||
struct iso_node {
|
struct iso_node {
|
||||||
struct vnode *i_vnode; /* vnode associated with this inode */
|
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 */
|
/* we use the actual starting block of the file */
|
||||||
struct iso_mnt *i_mnt; /* filesystem associated with this inode */
|
struct iso_mnt *i_mnt; /* filesystem associated with this inode */
|
||||||
struct lockf *i_lockf; /* head of byte-level lock list */
|
struct lockf *i_lockf; /* head of byte-level lock list */
|
||||||
|
@ -628,7 +628,7 @@ cd9660_rrip_getname(isodir,outbuf,outlen,inump,imp)
|
|||||||
struct iso_directory_record *isodir;
|
struct iso_directory_record *isodir;
|
||||||
char *outbuf;
|
char *outbuf;
|
||||||
u_short *outlen;
|
u_short *outlen;
|
||||||
ino_t *inump;
|
cd_ino_t *inump;
|
||||||
struct iso_mnt *imp;
|
struct iso_mnt *imp;
|
||||||
{
|
{
|
||||||
ISO_RRIP_ANALYZE analyze;
|
ISO_RRIP_ANALYZE analyze;
|
||||||
|
@ -540,7 +540,7 @@ cd9660_root(mp, flags, vpp)
|
|||||||
struct iso_mnt *imp = VFSTOISOFS(mp);
|
struct iso_mnt *imp = VFSTOISOFS(mp);
|
||||||
struct iso_directory_record *dp =
|
struct iso_directory_record *dp =
|
||||||
(struct iso_directory_record *)imp->root;
|
(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.
|
* With RRIP we must use the `.' entry of the root directory.
|
||||||
@ -617,6 +617,11 @@ cd9660_fhtovp(mp, fhp, flags, vpp)
|
|||||||
return (0);
|
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
|
static int
|
||||||
cd9660_vget(mp, ino, flags, vpp)
|
cd9660_vget(mp, ino, flags, vpp)
|
||||||
struct mount *mp;
|
struct mount *mp;
|
||||||
@ -640,10 +645,22 @@ cd9660_vget(mp, ino, flags, vpp)
|
|||||||
(struct iso_directory_record *)0));
|
(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
|
int
|
||||||
cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir)
|
cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir)
|
||||||
struct mount *mp;
|
struct mount *mp;
|
||||||
ino_t ino;
|
cd_ino_t ino;
|
||||||
int flags;
|
int flags;
|
||||||
struct vnode **vpp;
|
struct vnode **vpp;
|
||||||
int relocated;
|
int relocated;
|
||||||
@ -658,7 +675,8 @@ cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir)
|
|||||||
struct thread *td;
|
struct thread *td;
|
||||||
|
|
||||||
td = curthread;
|
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)
|
if (error || *vpp != NULL)
|
||||||
return (error);
|
return (error);
|
||||||
|
|
||||||
@ -699,7 +717,8 @@ cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir)
|
|||||||
*vpp = NULLVP;
|
*vpp = NULLVP;
|
||||||
return (error);
|
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)
|
if (error || *vpp != NULL)
|
||||||
return (error);
|
return (error);
|
||||||
|
|
||||||
|
@ -481,6 +481,7 @@ cd9660_readdir(ap)
|
|||||||
u_short namelen;
|
u_short namelen;
|
||||||
int ncookies = 0;
|
int ncookies = 0;
|
||||||
u_long *cookies = NULL;
|
u_long *cookies = NULL;
|
||||||
|
cd_ino_t ino;
|
||||||
|
|
||||||
dp = VTOI(vdp);
|
dp = VTOI(vdp);
|
||||||
imp = dp->i_mnt;
|
imp = dp->i_mnt;
|
||||||
@ -576,8 +577,10 @@ cd9660_readdir(ap)
|
|||||||
|
|
||||||
switch (imp->iso_ftype) {
|
switch (imp->iso_ftype) {
|
||||||
case ISO_FTYPE_RRIP:
|
case ISO_FTYPE_RRIP:
|
||||||
cd9660_rrip_getname(ep,idp->current.d_name, &namelen,
|
ino = idp->current.d_fileno;
|
||||||
&idp->current.d_fileno,imp);
|
cd9660_rrip_getname(ep, idp->current.d_name, &namelen,
|
||||||
|
&ino, imp);
|
||||||
|
idp->current.d_fileno = ino;
|
||||||
idp->current.d_namlen = (u_char)namelen;
|
idp->current.d_namlen = (u_char)namelen;
|
||||||
if (idp->current.d_namlen)
|
if (idp->current.d_namlen)
|
||||||
error = iso_uiodir(idp,&idp->current,idp->curroff);
|
error = iso_uiodir(idp,&idp->current,idp->curroff);
|
||||||
@ -831,8 +834,8 @@ cd9660_vptofh(ap)
|
|||||||
memcpy(ap->a_fhp, &ifh, sizeof(ifh));
|
memcpy(ap->a_fhp, &ifh, sizeof(ifh));
|
||||||
|
|
||||||
#ifdef ISOFS_DBG
|
#ifdef ISOFS_DBG
|
||||||
printf("vptofh: ino %d, start %ld\n",
|
printf("vptofh: ino %jd, start %ld\n",
|
||||||
ifh.ifid_ino, ifh.ifid_start);
|
(uintmax_t)ifh.ifid_ino, ifh.ifid_start);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -219,6 +219,11 @@ enum ISO_FTYPE { ISO_FTYPE_DEFAULT, ISO_FTYPE_9660, ISO_FTYPE_RRIP,
|
|||||||
#define ISOFSMNT_ROOT 0
|
#define ISOFSMNT_ROOT 0
|
||||||
#endif
|
#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 {
|
struct iso_mnt {
|
||||||
uint64_t im_flags;
|
uint64_t im_flags;
|
||||||
|
|
||||||
@ -250,10 +255,10 @@ struct iso_mnt {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct ifid {
|
struct ifid {
|
||||||
u_short ifid_len;
|
u_short ifid_len;
|
||||||
u_short ifid_pad;
|
u_short ifid_pad;
|
||||||
int ifid_ino;
|
cd_ino_t ifid_ino;
|
||||||
long ifid_start;
|
long ifid_start;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define VFSTOISOFS(mp) ((struct iso_mnt *)((mp)->mnt_data))
|
#define VFSTOISOFS(mp) ((struct iso_mnt *)((mp)->mnt_data))
|
||||||
@ -263,7 +268,7 @@ struct ifid {
|
|||||||
#define lblkno(imp, loc) ((loc) >> (imp)->im_bshift)
|
#define lblkno(imp, loc) ((loc) >> (imp)->im_bshift)
|
||||||
#define blksize(imp, ip, lbn) ((imp)->logical_block_size)
|
#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 *);
|
struct iso_directory_record *);
|
||||||
#define cd9660_sysctl ((int (*)(int *, u_int, void *, size_t *, void *, \
|
#define cd9660_sysctl ((int (*)(int *, u_int, void *, size_t *, void *, \
|
||||||
size_t, struct proc *))eopnotsupp)
|
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 isochar(u_char *, u_char *, int, u_short *, int *, int, void *);
|
||||||
int isofncmp(u_char *, int, u_char *, int, int, int, void *, 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 *);
|
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 *);
|
u_short sgetrune(const char *, size_t, char const **, int, void *);
|
||||||
|
|
||||||
#endif /* _KERNEL */
|
#endif /* _KERNEL */
|
||||||
|
@ -61,7 +61,7 @@ typedef struct {
|
|||||||
off_t iso_ce_off; /* offset of continuation area */
|
off_t iso_ce_off; /* offset of continuation area */
|
||||||
int iso_ce_len; /* length of continuation area */
|
int iso_ce_len; /* length of continuation area */
|
||||||
struct iso_mnt *imp; /* mount structure */
|
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 */
|
char *outbuf; /* name/symbolic link output area */
|
||||||
u_short *outlen; /* length of above */
|
u_short *outlen; /* length of above */
|
||||||
u_short maxlen; /* maximum 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);
|
struct iso_node *inop, struct iso_mnt *imp);
|
||||||
int cd9660_rrip_getname(struct iso_directory_record *isodir,
|
int cd9660_rrip_getname(struct iso_directory_record *isodir,
|
||||||
char *outbuf, u_short *outlen,
|
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,
|
int cd9660_rrip_getsymname(struct iso_directory_record *isodir,
|
||||||
char *outbuf, u_short *outlen,
|
char *outbuf, u_short *outlen,
|
||||||
struct iso_mnt *imp);
|
struct iso_mnt *imp);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user