* "Unimplemented system call" wrong?
@ 2006-03-31 11:54 Jan Engelhardt
2006-03-31 12:19 ` Andreas Schwab
0 siblings, 1 reply; 3+ messages in thread
From: Jan Engelhardt @ 2006-03-31 11:54 UTC (permalink / raw)
To: Linux Kernel Mailing List
Hello,
in the kernel log, I found this message the other day:
Mar 30 10:06:30 localhost kernel: Unimplemented SPARC system call 139
Looking it up in arch/sparc64/kernel/systbls.S shows that 139 maps to
compat_sys_stat64.
arch/sparc64/kernel/sys_sparc32.c contains a cp_compat_stat64() function
which is called from compat_sys_stat64(); here's a little excerpt:
int cp_compat_stat64(struct kstat *stat, struct compat_stat64 __user
*statbuf)
{
int err;
err = put_user(huge_encode_dev(stat->dev), &statbuf->st_dev);
err |= put_user(stat->ino, &statbuf->st_ino);
err |= put_user(stat->mode, &statbuf->st_mode);
...
return err;
}
I seriously doubt that put_user() can return -ENOSYS (the kernel would be
pretty useless then). I rather think someone borked the error reporting
here by ORing error values. Let's imagine that
err = put_user(huge_enc... returns ENOENT
err |= put_user(stat->in... returns EINTR
err |= put_user(stat->mo... returns EPIPE
ENOENT/EINTR/EPIPE may be dumb for put_user too, but it shows the problem
with |. err is now 00100110 in binary (sign omitted). ENOSYS. Although it
should have been, preferably ENOENT (in this example case).
Here are two patches (varying in coding style) that try to resolve this issue.
There are many more places within the kernel that use the |= technique.
Any thoughts on the issue?
--- arch/sparc64/kernel/sys_sparc32.c~ 2006-01-29 10:59:36.000000000 +0100
+++ arch/sparc64/kernel/sys_sparc32.c 2006-03-31 13:50:47.046525000 +0200
@@ -345,23 +345,40 @@ int cp_compat_stat(struct kstat *stat, s
return -EOVERFLOW;
err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
- err |= put_user(stat->ino, &statbuf->st_ino);
- err |= put_user(stat->mode, &statbuf->st_mode);
- err |= put_user(stat->nlink, &statbuf->st_nlink);
- err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid);
- err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid);
- err |= put_user(old_encode_dev(stat->rdev), &statbuf->st_rdev);
- err |= put_user(stat->size, &statbuf->st_size);
- err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
- err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
- err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
- err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
- err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
- err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
- err |= put_user(stat->blksize, &statbuf->st_blksize);
- err |= put_user(stat->blocks, &statbuf->st_blocks);
- err |= put_user(0, &statbuf->__unused4[0]);
- err |= put_user(0, &statbuf->__unused4[1]);
+ if(err != 0) return err;
+ err = put_user(stat->ino, &statbuf->st_ino);
+ if(err != 0) return err;
+ err = put_user(stat->mode, &statbuf->st_mode);
+ if(err != 0) return err;
+ err = put_user(stat->nlink, &statbuf->st_nlink);
+ if(err != 0) return err;
+ err = put_user(high2lowuid(stat->uid), &statbuf->st_uid);
+ if(err != 0) return err;
+ err = put_user(high2lowgid(stat->gid), &statbuf->st_gid);
+ if(err != 0) return err;
+ err = put_user(old_encode_dev(stat->rdev), &statbuf->st_rdev);
+ if(err != 0) return err;
+ err = put_user(stat->size, &statbuf->st_size);
+ if(err != 0) return err;
+ err = put_user(stat->atime.tv_sec, &statbuf->st_atime);
+ if(err != 0) return err;
+ err = put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
+ if(err != 0) return err;
+ err = put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
+ if(err != 0) return err;
+ err = put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
+ if(err != 0) return err;
+ err = put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
+ if(err != 0) return err;
+ err = put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
+ if(err != 0) return err;
+ err = put_user(stat->blksize, &statbuf->st_blksize);
+ if(err != 0) return err;
+ err = put_user(stat->blocks, &statbuf->st_blocks);
+ if(err != 0) return err;
+ err = put_user(0, &statbuf->__unused4[0]);
+ if(err != 0) return err;
+ err = put_user(0, &statbuf->__unused4[1]);
return err;
}
@@ -370,27 +387,47 @@ int cp_compat_stat64(struct kstat *stat,
{
int err;
- err = put_user(huge_encode_dev(stat->dev), &statbuf->st_dev);
- err |= put_user(stat->ino, &statbuf->st_ino);
- err |= put_user(stat->mode, &statbuf->st_mode);
- err |= put_user(stat->nlink, &statbuf->st_nlink);
- err |= put_user(stat->uid, &statbuf->st_uid);
- err |= put_user(stat->gid, &statbuf->st_gid);
- err |= put_user(huge_encode_dev(stat->rdev), &statbuf->st_rdev);
- err |= put_user(0, (unsigned long __user *) &statbuf->__pad3[0]);
- err |= put_user(stat->size, &statbuf->st_size);
- err |= put_user(stat->blksize, &statbuf->st_blksize);
- err |= put_user(0, (unsigned int __user *) &statbuf->__pad4[0]);
- err |= put_user(0, (unsigned int __user *) &statbuf->__pad4[4]);
- err |= put_user(stat->blocks, &statbuf->st_blocks);
- err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
- err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
- err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
- err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
- err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
- err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
- err |= put_user(0, &statbuf->__unused4);
- err |= put_user(0, &statbuf->__unused5);
+ err = put_user(huge_encode_dev(stat->dev), &statbuf->st_dev);
+ if(err != 0) return err;
+ err = put_user(stat->ino, &statbuf->st_ino);
+ if(err != 0) return err;
+ err = put_user(stat->mode, &statbuf->st_mode);
+ if(err != 0) return err;
+ err = put_user(stat->nlink, &statbuf->st_nlink);
+ if(err != 0) return err;
+ err = put_user(stat->uid, &statbuf->st_uid);
+ if(err != 0) return err;
+ err = put_user(stat->gid, &statbuf->st_gid);
+ if(err != 0) return err;
+ err = put_user(huge_encode_dev(stat->rdev), &statbuf->st_rdev);
+ if(err != 0) return err;
+ err = put_user(0, (unsigned long __user *) &statbuf->__pad3[0]);
+ if(err != 0) return err;
+ err = put_user(stat->size, &statbuf->st_size);
+ if(err != 0) return err;
+ err = put_user(stat->blksize, &statbuf->st_blksize);
+ if(err != 0) return err;
+ err = put_user(0, (unsigned int __user *) &statbuf->__pad4[0]);
+ if(err != 0) return err;
+ err = put_user(0, (unsigned int __user *) &statbuf->__pad4[4]);
+ if(err != 0) return err;
+ err = put_user(stat->blocks, &statbuf->st_blocks);
+ if(err != 0) return err;
+ err = put_user(stat->atime.tv_sec, &statbuf->st_atime);
+ if(err != 0) return err;
+ err = put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
+ if(err != 0) return err;
+ err = put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
+ if(err != 0) return err;
+ err = put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
+ if(err != 0) return err;
+ err = put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
+ if(err != 0) return err;
+ err = put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
+ if(err != 0) return err;
+ err = put_user(0, &statbuf->__unused4);
+ if(err != 0) return err;
+ err = put_user(0, &statbuf->__unused5);
return err;
}
#<<eof>>
--- arch/sparc64/kernel/sys_sparc32.c~ 2006-01-29 10:59:36.000000000 +0100
+++ arch/sparc64/kernel/sys_sparc32.c 2006-03-31 13:52:24.366525000 +0200
@@ -344,24 +344,25 @@ int cp_compat_stat(struct kstat *stat, s
!old_valid_dev(stat->rdev))
return -EOVERFLOW;
- err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
- err |= put_user(stat->ino, &statbuf->st_ino);
- err |= put_user(stat->mode, &statbuf->st_mode);
- err |= put_user(stat->nlink, &statbuf->st_nlink);
- err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid);
- err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid);
- err |= put_user(old_encode_dev(stat->rdev), &statbuf->st_rdev);
- err |= put_user(stat->size, &statbuf->st_size);
- err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
- err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
- err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
- err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
- err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
- err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
- err |= put_user(stat->blksize, &statbuf->st_blksize);
- err |= put_user(stat->blocks, &statbuf->st_blocks);
- err |= put_user(0, &statbuf->__unused4[0]);
- err |= put_user(0, &statbuf->__unused4[1]);
+ if((err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev)) == 0)
+ if((err = put_user(stat->ino, &statbuf->st_ino)) == 0)
+ if((err = put_user(stat->mode, &statbuf->st_mode) == 0)
+ if((err = put_user(stat->nlink, &statbuf->st_nlink) == 0)
+ if((err = put_user(high2lowuid(stat->uid), &statbuf->st_uid) == 0)
+ if((err = put_user(high2lowgid(stat->gid), &statbuf->st_gid) == 0)
+ if((err = put_user(old_encode_dev(stat->rdev), &statbuf->st_rdev) == 0)
+ if((err = put_user(stat->size, &statbuf->st_size) == 0)
+ if((err = put_user(stat->atime.tv_sec, &statbuf->st_atime) == 0)
+ if((err = put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec) == 0)
+ if((err = put_user(stat->mtime.tv_sec, &statbuf->st_mtime) == 0)
+ if((err = put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec) == 0)
+ if((err = put_user(stat->ctime.tv_sec, &statbuf->st_ctime) == 0)
+ if((err = put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec) == 0)
+ if((err = put_user(stat->blksize, &statbuf->st_blksize) == 0)
+ if((err = put_user(stat->blocks, &statbuf->st_blocks) == 0)
+ if((err = put_user(0, &statbuf->__unused4[0]) == 0)
+ if((err = put_user(0, &statbuf->__unused4[1]) == 0)
+ return 0;
return err;
}
@@ -370,27 +371,28 @@ int cp_compat_stat64(struct kstat *stat,
{
int err;
- err = put_user(huge_encode_dev(stat->dev), &statbuf->st_dev);
- err |= put_user(stat->ino, &statbuf->st_ino);
- err |= put_user(stat->mode, &statbuf->st_mode);
- err |= put_user(stat->nlink, &statbuf->st_nlink);
- err |= put_user(stat->uid, &statbuf->st_uid);
- err |= put_user(stat->gid, &statbuf->st_gid);
- err |= put_user(huge_encode_dev(stat->rdev), &statbuf->st_rdev);
- err |= put_user(0, (unsigned long __user *) &statbuf->__pad3[0]);
- err |= put_user(stat->size, &statbuf->st_size);
- err |= put_user(stat->blksize, &statbuf->st_blksize);
- err |= put_user(0, (unsigned int __user *) &statbuf->__pad4[0]);
- err |= put_user(0, (unsigned int __user *) &statbuf->__pad4[4]);
- err |= put_user(stat->blocks, &statbuf->st_blocks);
- err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
- err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
- err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
- err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
- err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
- err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
- err |= put_user(0, &statbuf->__unused4);
- err |= put_user(0, &statbuf->__unused5);
+ if((err = put_user(huge_encode_dev(stat->dev), &statbuf->st_dev) == 0)
+ if((err = put_user(stat->ino, &statbuf->st_ino) == 0)
+ if((err = put_user(stat->mode, &statbuf->st_mode) == 0)
+ if((err = put_user(stat->nlink, &statbuf->st_nlink) == 0)
+ if((err = put_user(stat->uid, &statbuf->st_uid) == 0)
+ if((err = put_user(stat->gid, &statbuf->st_gid) == 0)
+ if((err = put_user(huge_encode_dev(stat->rdev), &statbuf->st_rdev) == 0)
+ if((err = put_user(0, (unsigned long __user *) &statbuf->__pad3[0]) == 0)
+ if((err = put_user(stat->size, &statbuf->st_size) == 0)
+ if((err = put_user(stat->blksize, &statbuf->st_blksize) == 0)
+ if((err = put_user(0, (unsigned int __user *) &statbuf->__pad4[0]) == 0)
+ if((err = put_user(0, (unsigned int __user *) &statbuf->__pad4[4]) == 0)
+ if((err = put_user(stat->blocks, &statbuf->st_blocks) == 0)
+ if((err = put_user(stat->atime.tv_sec, &statbuf->st_atime) == 0)
+ if((err = put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec) == 0)
+ if((err = put_user(stat->mtime.tv_sec, &statbuf->st_mtime) == 0)
+ if((err = put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec) == 0)
+ if((err = put_user(stat->ctime.tv_sec, &statbuf->st_ctime) == 0)
+ if((err = put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec) == 0)
+ if((err = put_user(0, &statbuf->__unused4) == 0)
+ if((err = put_user(0, &statbuf->__unused5) == 0)
+ return 0;
return err;
}
#<<eof>>
Jan Engelhardt
--
| Software Engineer and Linux/Unix Network Administrator
| Alphagate Systems, http://alphagate.hopto.org/
| jengelh's site, http://jengelh.hopto.org/
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: "Unimplemented system call" wrong?
2006-03-31 11:54 "Unimplemented system call" wrong? Jan Engelhardt
@ 2006-03-31 12:19 ` Andreas Schwab
2006-04-01 20:06 ` Jan Engelhardt
0 siblings, 1 reply; 3+ messages in thread
From: Andreas Schwab @ 2006-03-31 12:19 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: Linux Kernel Mailing List
Jan Engelhardt <jengelh@linux01.gwdg.de> writes:
> I seriously doubt that put_user() can return -ENOSYS
put_user can only return -EFAULT or 0.
Andreas.
--
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: "Unimplemented system call" wrong?
2006-03-31 12:19 ` Andreas Schwab
@ 2006-04-01 20:06 ` Jan Engelhardt
0 siblings, 0 replies; 3+ messages in thread
From: Jan Engelhardt @ 2006-04-01 20:06 UTC (permalink / raw)
To: Andreas Schwab; +Cc: Linux Kernel Mailing List
>> I seriously doubt that put_user() can return -ENOSYS
>
>put_user can only return -EFAULT or 0.
>
But what may be causing ENOSYS then?
Jan Engelhardt
--
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2006-04-01 20:06 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-03-31 11:54 "Unimplemented system call" wrong? Jan Engelhardt
2006-03-31 12:19 ` Andreas Schwab
2006-04-01 20:06 ` Jan Engelhardt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®