Page MenuHomeFreeBSD

D37885.diff
No OneTemporary

D37885.diff

diff --git a/sys/kern/kern_sendfile.c b/sys/kern/kern_sendfile.c
--- a/sys/kern/kern_sendfile.c
+++ b/sys/kern/kern_sendfile.c
@@ -563,7 +563,6 @@
struct vnode **vp_res, struct shmfd **shmfd_res, off_t *obj_size,
int *bsize)
{
- struct vattr va;
vm_object_t obj;
struct vnode *vp;
struct shmfd *shmfd;
@@ -602,10 +601,9 @@
VM_OBJECT_RLOCK(obj);
*obj_size = obj->un_pager.vnp.vnp_size;
} else {
- error = VOP_GETATTR(vp, &va, td->td_ucred);
+ error = vn_getsize_locked(vp, obj_size, td->td_ucred);
if (error != 0)
goto out;
- *obj_size = va.va_size;
VM_OBJECT_RLOCK(obj);
}
} else if (fp->f_type == DTYPE_SHM) {
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -6377,7 +6377,7 @@
filt_vfsread(struct knote *kn, long hint)
{
struct vnode *vp = (struct vnode *)kn->kn_hook;
- struct vattr va;
+ off_t size;
int res;
/*
@@ -6391,11 +6391,11 @@
return (1);
}
- if (VOP_GETATTR(vp, &va, curthread->td_ucred))
+ if (vn_getsize_locked(vp, &size, curthread->td_ucred) != 0)
return (0);
VI_LOCK(vp);
- kn->kn_data = va.va_size - kn->kn_fp->f_offset;
+ kn->kn_data = size - kn->kn_fp->f_offset;
res = (kn->kn_sfflags & NOTE_FILE_POLL) != 0 || kn->kn_data != 0;
VI_UNLOCK(vp);
return (res);
@@ -7116,6 +7116,30 @@
VI_UNLOCK(vp);
}
+int
+vn_getsize_locked(struct vnode *vp, off_t *size, struct ucred *cred)
+{
+ struct vattr vattr;
+ int error;
+
+ ASSERT_VOP_LOCKED(vp, __func__);
+ error = VOP_GETATTR(vp, &vattr, cred);
+ if (__predict_true(error == 0))
+ *size = vattr.va_size;
+ return (error);
+}
+
+int
+vn_getsize(struct vnode *vp, off_t *size, struct ucred *cred)
+{
+ int error;
+
+ VOP_LOCK(vp, LK_SHARED);
+ error = vn_getsize_locked(vp, size, cred);
+ VOP_UNLOCK(vp);
+ return (error);
+}
+
#ifdef INVARIANTS
void
vn_set_state_validate(struct vnode *vp, enum vstate state)
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -1690,9 +1690,9 @@
vn_ioctl(struct file *fp, u_long com, void *data, struct ucred *active_cred,
struct thread *td)
{
- struct vattr vattr;
struct vnode *vp;
struct fiobmap2_arg *bmarg;
+ off_t size;
int error;
vp = fp->f_vnode;
@@ -1701,11 +1701,9 @@
case VREG:
switch (com) {
case FIONREAD:
- vn_lock(vp, LK_SHARED | LK_RETRY);
- error = VOP_GETATTR(vp, &vattr, active_cred);
- VOP_UNLOCK(vp);
+ error = vn_getsize(vp, &size, active_cred);
if (error == 0)
- *(int *)data = vattr.va_size - fp->f_offset;
+ *(int *)data = size - fp->f_offset;
return (error);
case FIOBMAP2:
bmarg = (struct fiobmap2_arg *)data;
@@ -2558,7 +2556,7 @@
vn_bmap_seekhole_locked(struct vnode *vp, u_long cmd, off_t *off,
struct ucred *cred)
{
- struct vattr va;
+ off_t size;
daddr_t bn, bnp;
uint64_t bsize;
off_t noff;
@@ -2572,16 +2570,16 @@
error = ENOTTY;
goto out;
}
- error = VOP_GETATTR(vp, &va, cred);
+ error = vn_getsize_locked(vp, &size, cred);
if (error != 0)
goto out;
noff = *off;
- if (noff < 0 || noff >= va.va_size) {
+ if (noff < 0 || noff >= size) {
error = ENXIO;
goto out;
}
bsize = vp->v_mount->mnt_stat.f_iosize;
- for (bn = noff / bsize; noff < va.va_size; bn++, noff += bsize -
+ for (bn = noff / bsize; noff < size; bn++, noff += bsize -
noff % bsize) {
error = VOP_BMAP(vp, bn, NULL, &bnp, NULL, NULL);
if (error == EOPNOTSUPP) {
@@ -2596,9 +2594,9 @@
goto out;
}
}
- if (noff > va.va_size)
- noff = va.va_size;
- /* noff == va.va_size. There is an implicit hole at the end of file. */
+ if (noff > size)
+ noff = size;
+ /* noff == size. There is an implicit hole at the end of file. */
if (cmd == FIOSEEKDATA)
error = ENXIO;
out:
@@ -2627,8 +2625,7 @@
{
struct ucred *cred;
struct vnode *vp;
- struct vattr vattr;
- off_t foffset, size;
+ off_t foffset, fsize, size;
int error, noneg;
cred = td->td_ucred;
@@ -2647,10 +2644,8 @@
offset += foffset;
break;
case L_XTND:
- vn_lock(vp, LK_SHARED | LK_RETRY);
- error = VOP_GETATTR(vp, &vattr, cred);
- VOP_UNLOCK(vp);
- if (error)
+ error = vn_getsize(vp, &fsize, cred);
+ if (error != 0)
break;
/*
@@ -2658,16 +2653,16 @@
* the media size and use that to determine the ending
* offset.
*/
- if (vattr.va_size == 0 && vp->v_type == VCHR &&
+ if (fsize == 0 && vp->v_type == VCHR &&
fo_ioctl(fp, DIOCGMEDIASIZE, &size, cred, td) == 0)
- vattr.va_size = size;
+ fsize = size;
if (noneg &&
- (vattr.va_size > OFF_MAX ||
- (offset > 0 && vattr.va_size > OFF_MAX - offset))) {
+ (fsize > OFF_MAX ||
+ (offset > 0 && fsize > OFF_MAX - offset))) {
error = EOVERFLOW;
break;
}
- offset += vattr.va_size;
+ offset += fsize;
break;
case L_SET:
break;
@@ -3259,7 +3254,6 @@
struct vnode *outvp, off_t *outoffp, size_t *lenp, unsigned int flags,
struct ucred *incred, struct ucred *outcred, struct thread *fsize_td)
{
- struct vattr va, inva;
struct mount *mp;
off_t startoff, endoff, xfer, xfer2;
u_long blksize;
@@ -3267,6 +3261,7 @@
bool cantseek, readzeros, eof, lastblock, holetoeof;
ssize_t aresid, r = 0;
size_t copylen, len, savlen;
+ off_t insize, outsize;
char *dat;
long holein, holeout;
struct timespec curts, endts;
@@ -3283,7 +3278,7 @@
if (VOP_PATHCONF(invp, _PC_MIN_HOLE_SIZE, &holein) != 0)
holein = 0;
if (holein > 0)
- error = VOP_GETATTR(invp, &inva, incred);
+ error = vn_getsize_locked(invp, &insize, incred);
VOP_UNLOCK(invp);
if (error != 0)
goto out;
@@ -3314,13 +3309,12 @@
/*
* Holes that are past EOF do not need to be written as a block
* of zero bytes. So, truncate the output file as far as
- * possible and then use va.va_size to decide if writing 0
+ * possible and then use size to decide if writing 0
* bytes is necessary in the loop below.
*/
if (error == 0)
- error = VOP_GETATTR(outvp, &va, outcred);
- if (error == 0 && va.va_size > *outoffp && va.va_size <=
- *outoffp + len) {
+ error = vn_getsize_locked(outvp, &outsize, outcred);
+ if (error == 0 && outsize > *outoffp && outsize <= *outoffp + len) {
#ifdef MAC
error = mac_vnode_check_write(curthread->td_ucred,
outcred, outvp);
@@ -3329,7 +3323,7 @@
error = vn_truncate_locked(outvp, *outoffp,
false, outcred);
if (error == 0)
- va.va_size = *outoffp;
+ outsize = *outoffp;
}
VOP_UNLOCK(outvp);
}
@@ -3409,7 +3403,7 @@
error = VOP_IOCTL(invp, FIOSEEKDATA, &startoff, 0,
incred, curthread);
if (error == ENXIO) {
- startoff = endoff = inva.va_size;
+ startoff = endoff = insize;
eof = holetoeof = true;
error = 0;
}
@@ -3434,9 +3428,9 @@
if (startoff > *inoffp) {
/* Found hole before data block. */
xfer = MIN(startoff - *inoffp, len);
- if (*outoffp < va.va_size) {
+ if (*outoffp < outsize) {
/* Must write 0s to punch hole. */
- xfer2 = MIN(va.va_size - *outoffp,
+ xfer2 = MIN(outsize - *outoffp,
xfer);
memset(dat, 0, MIN(xfer2, blksize));
error = vn_write_outvp(outvp, dat,
@@ -3445,7 +3439,7 @@
}
if (error == 0 && *outoffp + xfer >
- va.va_size && (xfer == len || holetoeof)) {
+ outsize && (xfer == len || holetoeof)) {
/* Grow output file (hole at end). */
error = vn_write_outvp(outvp, dat,
*outoffp, xfer, blksize, true,
@@ -3515,12 +3509,12 @@
false;
if (xfer == len)
lastblock = true;
- if (!cantseek || *outoffp < va.va_size ||
+ if (!cantseek || *outoffp < outsize ||
lastblock || !readzeros)
error = vn_write_outvp(outvp, dat,
*outoffp, xfer, blksize,
readzeros && lastblock &&
- *outoffp >= va.va_size, false,
+ *outoffp >= outsize, false,
outcred);
if (error == 0) {
*inoffp += xfer;
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -1135,6 +1135,8 @@
struct thread *td);
int vn_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred,
struct thread *td);
+int vn_getsize_locked(struct vnode *vp, off_t *size, struct ucred *active_cred);
+int vn_getsize(struct vnode *vp, off_t *size, struct ucred *active_cred);
void vn_fsid(struct vnode *vp, struct vattr *va);
diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c
--- a/sys/vm/vnode_pager.c
+++ b/sys/vm/vnode_pager.c
@@ -155,7 +155,6 @@
{
vm_object_t object;
vm_ooffset_t size = isize;
- struct vattr va;
bool last;
if (!vn_isdisk(vp) && vn_canvmio(vp) == FALSE)
@@ -169,9 +168,8 @@
if (vn_isdisk(vp)) {
size = IDX_TO_OFF(INT_MAX);
} else {
- if (VOP_GETATTR(vp, &va, td->td_ucred))
+ if (vn_getsize_locked(vp, &size, td->td_ucred) != 0)
return (0);
- size = va.va_size;
}
}

File Metadata

Mime Type
text/plain
Expires
Mon, Jan 20, 11:35 AM (21 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15977260
Default Alt Text
D37885.diff (8 KB)

Event Timeline