ref: b222ebff6f05d02834c26d5dae0f96c8fd03d573
parent: 20533acd96fd7a8e154d8b550ba7d9615d3963b3
author: joe9 <joe9mail@gmail.com>
date: Thu Jul 22 05:38:38 EDT 2021
fix bug in direntry mode conversion Dir.mode is a u32 Sys_dir.mode is a WORD When converting a ~0 value from Dir.mode to Sys_dir.mode, it is not sign extended. The default value for Dir.mode (specified by nulldir) is ~0. When checking for mode's default value in Sys_dir, it should be checked for 16rFFFFFFFF along with ~0.
--- a/appl/cmd/disk/kfs.b
+++ b/appl/cmd/disk/kfs.b
@@ -1787,8 +1787,10 @@
# 'type' or'ed with the old directory mode;
# else neither are defaults, use the new mode but check
# it agrees with 'type'.
-
- if(dir.qid.qtype == 16rFF && dir.mode == ~0){
+ # checking for the default value of 16rFFFFFFFF also as the
+ # conversion from Dir.mode (u32) to Sys_Dir.mode(intptr)
+ # loses the top 4 bytes and ~0 will not match in those circumstances
+ if(dir.qid.qtype == 16rFF && (dir.mode == ~0||big dir.mode == big 16rFFFFFFFF)){
dir.mode = d.mode & 8r777;
if(d.mode & DLOCK)
dir.mode |= DMEXCL;
@@ -1800,8 +1802,9 @@
else if(dir.qid.qtype == 16rFF){
# nothing to do
}
- else if(dir.mode == ~0)
+ else if(dir.mode == ~0||big dir.mode == big 16rFFFFFFFF){
dir.mode = (dir.qid.qtype<<24)|(d.mode & 8r777);
+ }
else if(dir.qid.qtype != ((dir.mode>>24) & 16rFF)){
d.put();
return ferr(f, Eqidmode, file, p1);
--- a/os/port/inferno.c
+++ b/os/port/inferno.c
@@ -385,6 +385,13 @@
sd->qid.path = d->qid.path;
sd->qid.vers = d->qid.vers;
sd->qid.qtype = d->qid.type;
+ /* this is not proper. I should not
+ be checking just for ~0 but also for 16rffffffff
+ while checking for the default value of ~0 */
+ /*if(d->mode == ~0)
+ sd->mode = ~0;
+ else
+ sd->mode = d->mode;*/
sd->mode = d->mode;
sd->atime = d->atime;
sd->mtime = d->mtime;