patch-2.4.20 linux-2.4.20/fs/nfsd/vfs.c

Next file: linux-2.4.20/fs/nls/Config.in
Previous file: linux-2.4.20/fs/nfsd/nfsxdr.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.19/fs/nfsd/vfs.c linux-2.4.20/fs/nfsd/vfs.c
@@ -114,35 +114,31 @@
 	if (isdotent(name, len)) {
 		if (len==1)
 			dentry = dget(dparent);
-		else  { /* must be ".." */
+		else if (dparent != exp->ex_dentry)
+			dentry = dget(dparent->d_parent);
+		else if (!EX_CROSSMNT(exp))
+			dentry = dget(dparent); /* .. == . just like at / */
+		else {
 			/* checking mountpoint crossing is very different when stepping up */
-			if (dparent == exp->ex_dentry) {
-				if (!EX_CROSSMNT(exp))
-					dentry = dget(dparent); /* .. == . just like at / */
-				else
-				{
-					struct svc_export *exp2 = NULL;
-					struct dentry *dp;
-					struct vfsmount *mnt = mntget(exp->ex_mnt);
-					dentry = dget(dparent);
-					while(follow_up(&mnt, &dentry))
-						;
-					dp = dget(dentry->d_parent);
-					dput(dentry);
-					dentry = dp;
-					for ( ; exp2 == NULL && dp->d_parent != dp;
-					      dp=dp->d_parent)
-						exp2 = exp_get(exp->ex_client, dp->d_inode->i_dev, dp->d_inode->i_ino);
-					if (exp2==NULL) {
-						dput(dentry);
-						dentry = dget(dparent);
-					} else {
-						exp = exp2;
-					}
-					mntput(mnt);
-				}
-			} else
-				dentry = dget(dparent->d_parent);
+			struct svc_export *exp2 = NULL;
+			struct dentry *dp;
+			struct vfsmount *mnt = mntget(exp->ex_mnt);
+			dentry = dget(dparent);
+			while(follow_up(&mnt, &dentry))
+				;
+			dp = dget(dentry->d_parent);
+			dput(dentry);
+			dentry = dp;
+			for ( ; exp2 == NULL && dp->d_parent != dp;
+			      dp=dp->d_parent)
+				exp2 = exp_get(exp->ex_client, dp->d_inode->i_dev, dp->d_inode->i_ino);
+			if (exp2==NULL) {
+				dput(dentry);
+				dentry = dget(dparent);
+			} else {
+				exp = exp2;
+			}
+			mntput(mnt);
 		}
 	} else {
 		fh_lock(fhp);
@@ -1497,17 +1493,21 @@
 		inode->i_uid, inode->i_gid, current->fsuid, current->fsgid);
 #endif
 
-	/* only care about readonly exports for files and
-	 * directories. links don't have meaningful write access,
-	 * and all else is local to the client
-	 */
-	if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)) 
-		if (acc & (MAY_WRITE | MAY_SATTR | MAY_TRUNC)) {
-			if (EX_RDONLY(exp) || IS_RDONLY(inode))
-				return nfserr_rofs;
-			if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode))
-				return nfserr_perm;
-		}
+	/* The following code is here to make IRIX happy, which
+	 * does a permission check every time a user does
+	 *	echo yaddayadda > special-file
+	 * by sending a CREATE request.
+	 * The original code would check read-only export status
+	 * only for regular files and directories, allowing
+	 * clients to chown/chmod device files and fifos even
+	 * on volumes exported read-only. */
+	if (!(acc & _NFSD_IRIX_BOGOSITY)
+	 && (acc & (MAY_WRITE | MAY_SATTR | MAY_TRUNC))) {
+		if (EX_RDONLY(exp) || IS_RDONLY(inode))
+			return nfserr_rofs;
+		if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode))
+			return nfserr_perm;
+	}
 	if ((acc & MAY_TRUNC) && IS_APPEND(inode))
 		return nfserr_perm;
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)