Greetings,
Wondering if anyone here has some experience with this. I have been trying to track this down and have no idea how this is happening. Its not making any sense at all.
We have a case where we have a system that is doing some successive reading and writing to a file.
Here is the specific Code:
--snip--
First, we're given an inode 'ainode', which should be the correct inode
for the file we're looking at. (If it were incorrect, we would have
gotten an error much earlier.)
If we have iget, we call iget. The 2.6.16.60-* kernels lack iget, I
believe, so instead we do:
fid.i32.ino = ainode;
fid.i32.gen = 0;
dp = afs_cacheSBp->s_export_op->fh_to_dentry(afs_cacheSBp,
&fid, sizeof(fid), FILEID_INO32_GEN);
filp = dentry_open(dp, mntget(afs_cacheMnt), O_RDWR);
(I'm not including error-checking. afs_cacheSBp is the superblock for
the cache filesystem, so ext2 or ext3. afs_cacheMnt is the vfsmount for
the cache FS) Then, to write to the file we do basically:
(we're writing 'count' bytes from 'buf' to 'offset' in file 'filp'; I'm
paraphrasing the code here, but I think I'm maintaining what it does)
mm_segment_t _fs_space_decl;
int code = 0;
savelim = current->TASK_STRUCT_RLIM[RLIMIT_FSIZE].rlim_cur;
current->TASK_STRUCT_RLIM[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
_fs_space_decl = get_fs();
set_fs(get_ds());
if (filp->f_op->llseek) {
if (filp->f_op->llseek(filp, offset, 0) != offset)
return -1;
} else {
filp->f_pos = offset;
}
while (code == 0 && count > 0) {
code = filp->f_op->write(filp, buf, count, &f->f_pos);
if (code < 0) {
code = -code;
break;
} else if (code == 0) {
code = EIO;
break;
}
buf += code;
count -= code;
code = 0;
}
set_fs(_fs_space_decl);
current->TASK_STRUCT_RLIM[RLIMIT_FSIZE].rlim_cur = savelim;
return code;
It is here we are getting -ENOMEM from filp->f_op->write.
Finally, normally to close a file, we do this:
if (filp->f_dentry->d_inode) {
filp_close(filp, NULL);
}
--snip--
It's not intended to be written to constantly, but in this case it
probably is written to several times successively (due to certain
parameters set a bit low, and the high load for these clients).
I believe this function was called about 644203 times in the core I'm
looking at, which means that file was written to at least around 644000
times... I'm assuming at least most of those were right after another.
However, there would almost always be several reads of the same file
between successive writes. (Again, in an 'open(); read(); close();'
fashion) But they are probably all happening very quickly; I assume the
cache for the stuff in this file is thrashing.
How can we avoid this or make this much more stream-lined?
Any help would be appreciated.
Thanks,
Cameron
--
To unsubscribe, e-mail: opensuse-programming+unsubscribe(a)opensuse.org
For additional commands, e-mail: opensuse-programming+help(a)opensuse.org