Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107921650
D37885.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D37885.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D37885: vfs: add vn_getsize
Attached
Detach File
Event Timeline
Log In to Comment