aboutsummaryrefslogtreecommitdiff
path: root/sys/fs/cd9660
diff options
context:
space:
mode:
authorConrad Meyer <cem@FreeBSD.org>2017-01-08 06:21:49 +0000
committerConrad Meyer <cem@FreeBSD.org>2017-01-08 06:21:49 +0000
commitdbaab6e66f856662798722aa992a1641300d989d (patch)
tree7f08603b3ef76df68a40b69b80adc9ca1fc65414 /sys/fs/cd9660
parent0c6393a265bfbf26e8337d123c5839de409da0ac (diff)
downloadsrc-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.c6
-rw-r--r--sys/fs/cd9660/cd9660_node.c4
-rw-r--r--sys/fs/cd9660/cd9660_node.h2
-rw-r--r--sys/fs/cd9660/cd9660_rrip.c2
-rw-r--r--sys/fs/cd9660/cd9660_vfsops.c27
-rw-r--r--sys/fs/cd9660/cd9660_vnops.c11
-rw-r--r--sys/fs/cd9660/iso.h17
-rw-r--r--sys/fs/cd9660/iso_rrip.h4
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);