code: plan9front

Download patch

ref: 9ab48ee37050e2676ae0ddbf253bb3ae5567eb45
parent: 13ec55922f0819aaa2cbb95a9f9bdbed5ae73e2b
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon Jun 15 04:28:10 EDT 2015

hjfs: defer parent directory permission check for wstat

check parent directory permission *after* we determined
that the new name does not exist in the parent, so that
when the new name is the same as old name then no write
permission is required in the parent directory.

--- a/sys/src/cmd/hjfs/fs2.c
+++ b/sys/src/cmd/hjfs/fs2.c
@@ -698,18 +698,17 @@
 		d = getdent(ch->loc->next, pb);
 		if(d == nil)
 			goto error;
-		if((ch->flags & CHFNOPERM) == 0)
-			if(!permcheck(ch->fs, d, ch->uid, OWRITE))
-				goto perm;
 		rc = findentry(ch->fs, ch->loc->next, pb, di->name, &f, ch->flags & CHFDUMP);
-		if(rc > 0){
-			if(f.blk == ch->loc->blk && f.deind == ch->loc->deind)
-				rc = 0;
-			else
-				werrstr(Eexists);
-		}
-		if(rc != 0)
+		if(rc < 0)
 			goto error;
+		else if(rc == 0){
+			if((ch->flags & CHFNOPERM) == 0)
+				if(!permcheck(ch->fs, d, ch->uid, OWRITE))
+					goto perm;
+		} else if(f.blk != ch->loc->blk || f.deind != ch->loc->deind){
+			werrstr(Eexists);
+			goto error;
+		}
 	}
 	b = getbuf(ch->fs->d, ch->loc->blk, TDENTRY, 0);
 	if(b == nil)