mirror of
https://git.FreeBSD.org/src.git
synced 2025-02-06 18:29:47 +00:00
Don't panic if a VOP_READ() gets through on a short link, Just Do It
(because we can :-). This means you can open a link file (or pseudo-file in the case of short links where the data is stored in the inode rather than disk blocks) and read the contents. However, trap any writes from the user as it's difficult to do the right thing in all cases. A link may be short and the user may be trying to extend it beyond the limit and so on. Although.. being able to re-target a symlink without deleting it first might have been nice. This stuff is a bit perverse since symlink() and readlink() calls can end up actually being implemented as read/write vnode ops. Reviewed by: phk
This commit is contained in:
parent
7e3426aa1f
commit
b587fd008d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=35083
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ufs_readwrite.c 8.11 (Berkeley) 5/8/95
|
||||
* $Id: ufs_readwrite.c,v 1.46 1998/03/09 22:12:52 dyson Exp $
|
||||
* $Id: ufs_readwrite.c,v 1.47 1998/03/30 09:56:31 phk Exp $
|
||||
*/
|
||||
|
||||
#define BLKSIZE(a, b, c) blksize(a, b, c)
|
||||
@ -71,7 +71,7 @@ READ(ap)
|
||||
ufs_daddr_t lbn, nextlbn;
|
||||
off_t bytesinfile;
|
||||
long size, xfersize, blkoffset;
|
||||
int error;
|
||||
int error, isize;
|
||||
u_short mode;
|
||||
int seqcount;
|
||||
int ioflag;
|
||||
@ -88,16 +88,23 @@ READ(ap)
|
||||
if (uio->uio_rw != UIO_READ)
|
||||
panic("%s: mode", READ_S);
|
||||
|
||||
if (vp->v_type == VLNK) {
|
||||
if ((int)ip->i_size < vp->v_mount->mnt_maxsymlinklen)
|
||||
panic("%s: short symlink", READ_S);
|
||||
} else if (vp->v_type != VREG && vp->v_type != VDIR)
|
||||
if (vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK)
|
||||
panic("%s: type %d", READ_S, vp->v_type);
|
||||
#endif
|
||||
fs = ip->I_FS;
|
||||
if ((u_int64_t)uio->uio_offset > fs->fs_maxfilesize)
|
||||
return (EFBIG);
|
||||
|
||||
/* handle a read() on a VLNK obtained via O_NOFOLLOW */
|
||||
if (vp->v_type == VLNK) {
|
||||
isize = ip->i_size;
|
||||
if ((isize < vp->v_mount->mnt_maxsymlinklen) ||
|
||||
(ip->i_din.di_blocks == 0)) { /* XXX - for old fastlink support */
|
||||
uiomove((char *)ip->i_shortlink, isize, ap->a_uio);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
object = vp->v_object;
|
||||
|
||||
bytesinfile = ip->i_size - uio->uio_offset;
|
||||
@ -282,8 +289,11 @@ WRITE(ap)
|
||||
vm_object_vndeallocate(object);
|
||||
return (EPERM);
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
break;
|
||||
case VLNK:
|
||||
/* bail out if this is from the user, it's too hard */
|
||||
if (uio->uio_segflg != UIO_SYSSPACE)
|
||||
return (EOPNOTSUPP);
|
||||
break;
|
||||
case VDIR:
|
||||
if ((ioflag & IO_SYNC) == 0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user