Hi Linus
sys_{link, symlink, unlink, mkmod} acquired the kernel lock earlier than
needed. The patch below moves these calls as near as possible to the
actual VFS calls.
It's tested on SMP i386 with 2.3.39, and 2.3.40-1 doesn't touch
fs/namei.c.
-- Manfred ------------------------ diff -ur 2.3/fs/namei.c build-2.3/fs/namei.c --- 2.3/fs/namei.c Thu Jan 6 22:57:20 2000 +++ build-2.3/fs/namei.c Wed Jan 12 19:53:59 2000 @@ -780,16 +780,14 @@ char * tmp; struct dentry * dentry; - lock_kernel(); - error = -EPERM; if (S_ISDIR(mode) || (!S_ISFIFO(mode) && !capable(CAP_MKNOD))) - goto out; + return -EPERM; tmp = getname(filename); - error = PTR_ERR(tmp); if (IS_ERR(tmp)) - goto out; + return PTR_ERR(tmp); error = -EINVAL; + lock_kernel(); switch (mode & S_IFMT) { case 0: mode |= S_IFREG; /* fallthrough */ @@ -815,10 +813,9 @@ } break; } + unlock_kernel(); putname(tmp); -out: - unlock_kernel(); return error; } @@ -870,14 +867,14 @@ int error; char * tmp; - lock_kernel(); tmp = getname(pathname); - error = PTR_ERR(tmp); - if (!IS_ERR(tmp)) { - error = do_mkdir(tmp,mode); - putname(tmp); - } + if(IS_ERR(tmp)) + return PTR_ERR(tmp); + lock_kernel(); + error = do_mkdir(tmp,mode); unlock_kernel(); + putname(tmp); + return error; } @@ -965,14 +962,15 @@ int error; char * tmp; - lock_kernel(); tmp = getname(pathname); - error = PTR_ERR(tmp); - if (!IS_ERR(tmp)) { - error = do_rmdir(tmp); - putname(tmp); - } + if(IS_ERR(tmp)) + return PTR_ERR(tmp); + lock_kernel(); + error = do_rmdir(tmp); unlock_kernel(); + + putname(tmp); + return error; } @@ -1018,14 +1016,14 @@ int error; char * tmp; - lock_kernel(); tmp = getname(pathname); - error = PTR_ERR(tmp); - if (!IS_ERR(tmp)) { - error = do_unlink(tmp); - putname(tmp); - } + if(IS_ERR(tmp)) + return PTR_ERR(tmp); + lock_kernel(); + error = do_unlink(tmp); unlock_kernel(); + putname(tmp); + return error; } @@ -1068,21 +1066,20 @@ { int error; char * from; + char * to; - lock_kernel(); from = getname(oldname); - error = PTR_ERR(from); - if (!IS_ERR(from)) { - char * to; - to = getname(newname); - error = PTR_ERR(to); - if (!IS_ERR(to)) { - error = do_symlink(from,to); - putname(to); - } - putname(from); + if(IS_ERR(from)) + return PTR_ERR(from); + to = getname(newname); + error = PTR_ERR(to); + if (!IS_ERR(to)) { + lock_kernel(); + error = do_symlink(from,to); + unlock_kernel(); + putname(to); } - unlock_kernel(); + putname(from); return error; } @@ -1156,21 +1153,21 @@ { int error; char * from; + char * to; - lock_kernel(); from = getname(oldname); - error = PTR_ERR(from); - if (!IS_ERR(from)) { - char * to; - to = getname(newname); - error = PTR_ERR(to); - if (!IS_ERR(to)) { - error = do_link(from,to); - putname(to); - } - putname(from); + if(IS_ERR(from)) + return PTR_ERR(from); + to = getname(newname); + error = PTR_ERR(to); + if (!IS_ERR(to)) { + lock_kernel(); + error = do_link(from,to); + unlock_kernel(); + putname(to); } - unlock_kernel(); + putname(from); + return error; } @@ -1327,21 +1324,20 @@ { int error; char * from; + char * to; - lock_kernel(); from = getname(oldname); - error = PTR_ERR(from); - if (!IS_ERR(from)) { - char * to; - to = getname(newname); - error = PTR_ERR(to); - if (!IS_ERR(to)) { - error = do_rename(from,to); - putname(to); - } - putname(from); + if(IS_ERR(from)) + return PTR_ERR(from); + to = getname(newname); + error = PTR_ERR(to); + if (!IS_ERR(to)) { + lock_kernel(); + error = do_rename(from,to); + unlock_kernel(); + putname(to); } - unlock_kernel(); + putname(from); return error; } ------------------------- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Sat Jan 15 2000 - 21:00:21 EST