--- olpc-2.6-master.00/fs/jfs/ioctl.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/jfs/ioctl.c	2007-03-01 11:52:20.000000000 -0500
@@ -65,7 +66,8 @@ int jfs_ioctl(struct inode * inode, stru
 	case JFS_IOC_SETFLAGS: {
 		unsigned int oldflags;
 
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) ||
+			(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 			return -EROFS;
 
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
--- olpc-2.6-master.00/arch/sparc64/solaris/fs.c	2007-02-28 20:05:26.000000000 -0500
+++ olpc-2.6-master-vs22x.02/arch/sparc64/solaris/fs.c	2007-03-01 11:52:20.000000000 -0500
@@ -368,7 +368,7 @@ static int report_statvfs(struct vfsmoun
 		int j = strlen (p);
 		
 		if (j > 15) j = 15;
-		if (IS_RDONLY(inode)) i = 1;
+		if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt)) i = 1;
 		if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
 		if (!sysv_valid_dev(inode->i_sb->s_dev))
 			return -EOVERFLOW;
--- olpc-2.6-master.00/arch/sparc64/solaris/fs.c	2007-02-28 20:05:26.000000000 -0500
+++ olpc-2.6-master-vs22x.02/arch/sparc64/solaris/fs.c	2007-03-01 11:52:20.000000000 -0500
@@ -404,7 +404,7 @@ static int report_statvfs64(struct vfsmo
 		int j = strlen (p);
 		
 		if (j > 15) j = 15;
-		if (IS_RDONLY(inode)) i = 1;
+		if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt)) i = 1;
 		if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
 		if (!sysv_valid_dev(inode->i_sb->s_dev))
 			return -EOVERFLOW;
--- olpc-2.6-master.00/fs/ecryptfs/inode.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/ecryptfs/inode.c	2007-03-01 11:52:20.000000000 -0500
@@ -426,7 +426,7 @@ static int ecryptfs_link(struct dentry *
 	dget(lower_new_dentry);
 	lower_dir_dentry = lock_parent(lower_new_dentry);
 	rc = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode,
-		      lower_new_dentry);
+		      lower_new_dentry, NULL);
 	if (rc || !lower_new_dentry->d_inode)
 		goto out_lock;
 	rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0);
--- olpc-2.6-master.00/fs/ecryptfs/inode.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/ecryptfs/inode.c	2007-03-01 11:52:20.000000000 -0500
@@ -454,7 +454,7 @@ static int ecryptfs_unlink(struct inode 
 	struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir);
 
 	lock_parent(lower_dentry);
-	rc = vfs_unlink(lower_dir_inode, lower_dentry);
+	rc = vfs_unlink(lower_dir_inode, lower_dentry, NULL);
 	if (rc) {
 		printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc);
 		goto out_unlock;
--- olpc-2.6-master.00/fs/ecryptfs/inode.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/ecryptfs/inode.c	2007-03-01 11:52:20.000000000 -0500
@@ -491,7 +491,7 @@ static int ecryptfs_symlink(struct inode
 		goto out_lock;
 	}
 	rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry,
-			 encoded_symname, mode);
+			 encoded_symname, mode, NULL);
 	kfree(encoded_symname);
 	if (rc || !lower_dentry->d_inode)
 		goto out_lock;
--- olpc-2.6-master.00/fs/ecryptfs/inode.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/ecryptfs/inode.c	2007-03-01 11:52:20.000000000 -0500
@@ -516,7 +516,7 @@ static int ecryptfs_mkdir(struct inode *
 
 	lower_dentry = ecryptfs_dentry_to_lower(dentry);
 	lower_dir_dentry = lock_parent(lower_dentry);
-	rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, mode);
+	rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, mode, NULL);
 	if (rc || !lower_dentry->d_inode)
 		goto out;
 	rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
--- olpc-2.6-master.00/fs/ecryptfs/inode.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/ecryptfs/inode.c	2007-03-01 11:52:20.000000000 -0500
@@ -542,7 +542,7 @@ static int ecryptfs_rmdir(struct inode *
 	dget(dentry);
 	lower_dir_dentry = lock_parent(lower_dentry);
 	dget(lower_dentry);
-	rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
+	rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry, NULL);
 	dput(lower_dentry);
 	if (!rc)
 		d_delete(lower_dentry);
--- olpc-2.6-master.00/fs/ecryptfs/inode.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/ecryptfs/inode.c	2007-03-01 11:52:20.000000000 -0500
@@ -564,7 +564,7 @@ ecryptfs_mknod(struct inode *dir, struct
 
 	lower_dentry = ecryptfs_dentry_to_lower(dentry);
 	lower_dir_dentry = lock_parent(lower_dentry);
-	rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev);
+	rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev, NULL);
 	if (rc || !lower_dentry->d_inode)
 		goto out;
 	rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
--- olpc-2.6-master.00/fs/ext2/ioctl.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/ext2/ioctl.c	2007-03-01 11:52:20.000000000 -0500
@@ -32,7 +33,8 @@ int ext2_ioctl (struct inode * inode, st
 	case EXT2_IOC_SETFLAGS: {
 		unsigned int oldflags;
 
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) ||
+			(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 			return -EROFS;
 
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
--- olpc-2.6-master.00/fs/ext2/ioctl.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/ext2/ioctl.c	2007-03-01 11:52:20.000000000 -0500
@@ -75,7 +79,8 @@ int ext2_ioctl (struct inode * inode, st
 	case EXT2_IOC_SETVERSION:
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
 			return -EPERM;
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) ||
+			(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 			return -EROFS;
 		if (get_user(inode->i_generation, (int __user *) arg))
 			return -EFAULT;	
--- olpc-2.6-master.00/fs/ext3/ioctl.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/ext3/ioctl.c	2007-03-01 17:09:59.000000000 -0500
@@ -37,7 +39,8 @@ int ext3_ioctl (struct inode * inode, st
 		unsigned int oldflags;
 		unsigned int jflag;
 
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) ||
+			(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 			return -EROFS;
 
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
--- olpc-2.6-master.00/fs/ext3/ioctl.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/ext3/ioctl.c	2007-03-01 17:09:59.000000000 -0500
@@ -123,7 +128,8 @@ flags_err:
 
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
 			return -EPERM;
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) ||
+			(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 			return -EROFS;
 		if (get_user(generation, (int __user *) arg))
 			return -EFAULT;
--- olpc-2.6-master.00/fs/ext3/ioctl.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/ext3/ioctl.c	2007-03-01 17:09:59.000000000 -0500
@@ -177,7 +183,8 @@ flags_err:
 		if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))
 			return -ENOTTY;
 
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) ||
+			(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 			return -EROFS;
 
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
--- olpc-2.6-master.00/fs/ext3/ioctl.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/ext3/ioctl.c	2007-03-01 17:09:59.000000000 -0500
@@ -212,7 +219,8 @@ flags_err:
 		if (!capable(CAP_SYS_RESOURCE))
 			return -EPERM;
 
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) ||
+			(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 			return -EROFS;
 
 		if (get_user(n_blocks_count, (__u32 __user *)arg))
--- olpc-2.6-master.00/fs/ext3/ioctl.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/ext3/ioctl.c	2007-03-01 17:09:59.000000000 -0500
@@ -233,7 +241,8 @@ flags_err:
 		if (!capable(CAP_SYS_RESOURCE))
 			return -EPERM;
 
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) ||
+			(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 			return -EROFS;
 
 		if (copy_from_user(&input, (struct ext3_new_group_input __user *)arg,
--- olpc-2.6-master.00/fs/ext4/ioctl.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/ext4/ioctl.c	2007-03-01 17:09:59.000000000 -0500
@@ -37,7 +39,8 @@ int ext4_ioctl (struct inode * inode, st
 		unsigned int oldflags;
 		unsigned int jflag;
 
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) ||
+			(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 			return -EROFS;
 
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
--- olpc-2.6-master.00/fs/ext4/ioctl.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/ext4/ioctl.c	2007-03-01 17:09:59.000000000 -0500
@@ -123,7 +128,8 @@ flags_err:
 
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
 			return -EPERM;
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) ||
+			(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 			return -EROFS;
 		if (get_user(generation, (int __user *) arg))
 			return -EFAULT;
--- olpc-2.6-master.00/fs/ext4/ioctl.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/ext4/ioctl.c	2007-03-01 17:09:59.000000000 -0500
@@ -177,7 +183,8 @@ flags_err:
 		if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))
 			return -ENOTTY;
 
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) ||
+			(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 			return -EROFS;
 
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
--- olpc-2.6-master.00/fs/ext4/ioctl.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/ext4/ioctl.c	2007-03-01 17:09:59.000000000 -0500
@@ -212,7 +219,8 @@ flags_err:
 		if (!capable(CAP_SYS_RESOURCE))
 			return -EPERM;
 
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) ||
+			(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 			return -EROFS;
 
 		if (get_user(n_blocks_count, (__u32 __user *)arg))
--- olpc-2.6-master.00/fs/ext4/ioctl.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/ext4/ioctl.c	2007-03-01 17:09:59.000000000 -0500
@@ -233,7 +241,8 @@ flags_err:
 		if (!capable(CAP_SYS_RESOURCE))
 			return -EPERM;
 
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) ||
+			(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 			return -EROFS;
 
 		if (copy_from_user(&input, (struct ext4_new_group_input __user *)arg,
--- olpc-2.6-master.00/fs/hfsplus/ioctl.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/hfsplus/ioctl.c	2007-03-01 11:52:20.000000000 -0500
@@ -35,7 +36,8 @@ int hfsplus_ioctl(struct inode *inode, s
 			flags |= FS_NODUMP_FL; /* EXT2_NODUMP_FL */
 		return put_user(flags, (int __user *)arg);
 	case HFSPLUS_IOC_EXT2_SETFLAGS: {
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) ||
+			(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 			return -EROFS;
 
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
--- olpc-2.6-master.00/fs/namei.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/namei.c	2007-03-01 11:52:20.000000000 -0500
@@ -235,7 +265,7 @@ int permission(struct inode *inode, int 
 		/*
 		 * Nobody gets write access to a read-only fs.
 		 */
-		if (IS_RDONLY(inode) &&
+		if ((IS_RDONLY(inode) || (nd && MNT_IS_RDONLY(nd->mnt))) &&
 		    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
 			return -EROFS;
 
--- olpc-2.6-master.00/fs/namei.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/namei.c	2007-03-01 11:52:20.000000000 -0500
@@ -1381,7 +1434,8 @@ static inline int check_sticky(struct in
  * 10. We don't allow removal of NFS sillyrenamed files; it's handled by
  *     nfs_async_unlink().
  */
-static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
+static int may_delete(struct inode *dir, struct dentry *victim,
+	int isdir, struct nameidata *nd)
 {
 	int error;
 
--- olpc-2.6-master.00/fs/namei.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/namei.c	2007-03-01 11:52:20.000000000 -0500
@@ -1391,7 +1445,7 @@ static int may_delete(struct inode *dir,
 	BUG_ON(victim->d_parent->d_inode != dir);
 	audit_inode_child(victim->d_name.name, victim->d_inode, dir);
 
-	error = permission(dir,MAY_WRITE | MAY_EXEC, NULL);
+	error = permission(dir,MAY_WRITE | MAY_EXEC, nd);
 	if (error)
 		return error;
 	if (IS_APPEND(dir))
--- olpc-2.6-master.00/fs/namei.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/namei.c	2007-03-01 11:52:20.000000000 -0500
@@ -1544,7 +1606,8 @@ int may_open(struct nameidata *nd, int a
 			return -EACCES;
 
 		flag &= ~O_TRUNC;
-	} else if (IS_RDONLY(inode) && (flag & FMODE_WRITE))
+	} else if ((IS_RDONLY(inode) || MNT_IS_RDONLY(nd->mnt))
+		&& (flag & FMODE_WRITE))
 		return -EROFS;
 	/*
 	 * An append-only file must be opened in append mode for writing.
--- olpc-2.6-master.00/fs/namei.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/namei.c	2007-03-01 11:52:20.000000000 -0500
@@ -1836,9 +1920,10 @@ fail:
 }
 EXPORT_SYMBOL_GPL(lookup_create);
 
-int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
+int vfs_mknod(struct inode *dir, struct dentry *dentry,
+	int mode, dev_t dev, struct nameidata *nd)
 {
-	int error = may_create(dir, dentry, NULL);
+	int error = may_create(dir, dentry, nd);
 
 	if (error)
 		return error;
--- olpc-2.6-master.00/fs/namei.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/namei.c	2007-03-01 11:52:20.000000000 -0500
@@ -1888,11 +1973,12 @@ asmlinkage long sys_mknodat(int dfd, con
 			error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
 			break;
 		case S_IFCHR: case S_IFBLK:
-			error = vfs_mknod(nd.dentry->d_inode,dentry,mode,
-					new_decode_dev(dev));
+			error = vfs_mknod(nd.dentry->d_inode, dentry, mode,
+					new_decode_dev(dev), &nd);
 			break;
 		case S_IFIFO: case S_IFSOCK:
-			error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0);
+			error = vfs_mknod(nd.dentry->d_inode, dentry, mode,
+					0, &nd);
 			break;
 		case S_IFDIR:
 			error = -EPERM;
--- olpc-2.6-master.00/fs/namei.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/namei.c	2007-03-01 11:52:20.000000000 -0500
@@ -1915,9 +2001,10 @@ asmlinkage long sys_mknod(const char __u
 	return sys_mknodat(AT_FDCWD, filename, mode, dev);
 }
 
-int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+int vfs_mkdir(struct inode *dir, struct dentry *dentry,
+	int mode, struct nameidata *nd)
 {
-	int error = may_create(dir, dentry, NULL);
+	int error = may_create(dir, dentry, nd);
 
 	if (error)
 		return error;
--- olpc-2.6-master.00/fs/namei.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/namei.c	2007-03-01 11:52:20.000000000 -0500
@@ -1959,7 +2046,7 @@ asmlinkage long sys_mkdirat(int dfd, con
 
 	if (!IS_POSIXACL(nd.dentry->d_inode))
 		mode &= ~current->fs->umask;
-	error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
+	error = vfs_mkdir(nd.dentry->d_inode, dentry, mode, &nd);
 	dput(dentry);
 out_unlock:
 	mutex_unlock(&nd.dentry->d_inode->i_mutex);
--- olpc-2.6-master.00/fs/namei.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/namei.c	2007-03-01 11:52:20.000000000 -0500
@@ -2002,9 +2089,10 @@ void dentry_unhash(struct dentry *dentry
 	spin_unlock(&dcache_lock);
 }
 
-int vfs_rmdir(struct inode *dir, struct dentry *dentry)
+int vfs_rmdir(struct inode *dir, struct dentry *dentry,
+	struct nameidata *nd)
 {
-	int error = may_delete(dir, dentry, 1);
+	int error = may_delete(dir, dentry, 1, nd);
 
 	if (error)
 		return error;
--- olpc-2.6-master.00/fs/namei.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/namei.c	2007-03-01 11:52:20.000000000 -0500
@@ -2066,7 +2154,7 @@ static long do_rmdir(int dfd, const char
 	error = PTR_ERR(dentry);
 	if (IS_ERR(dentry))
 		goto exit2;
-	error = vfs_rmdir(nd.dentry->d_inode, dentry);
+	error = vfs_rmdir(nd.dentry->d_inode, dentry, &nd);
 	dput(dentry);
 exit2:
 	mutex_unlock(&nd.dentry->d_inode->i_mutex);
--- olpc-2.6-master.00/fs/namei.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/namei.c	2007-03-01 11:52:20.000000000 -0500
@@ -2082,9 +2170,10 @@ asmlinkage long sys_rmdir(const char __u
 	return do_rmdir(AT_FDCWD, pathname);
 }
 
-int vfs_unlink(struct inode *dir, struct dentry *dentry)
+int vfs_unlink(struct inode *dir, struct dentry *dentry,
+	struct nameidata *nd)
 {
-	int error = may_delete(dir, dentry, 0);
+	int error = may_delete(dir, dentry, 0, nd);
 
 	if (error)
 		return error;
--- olpc-2.6-master.00/fs/namei.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/namei.c	2007-03-01 11:52:20.000000000 -0500
@@ -2146,7 +2235,7 @@ static long do_unlinkat(int dfd, const c
 		inode = dentry->d_inode;
 		if (inode)
 			atomic_inc(&inode->i_count);
-		error = vfs_unlink(nd.dentry->d_inode, dentry);
+		error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
 	exit2:
 		dput(dentry);
 	}
--- olpc-2.6-master.00/fs/namei.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/namei.c	2007-03-01 11:52:20.000000000 -0500
@@ -2181,9 +2270,10 @@ asmlinkage long sys_unlink(const char __
 	return do_unlinkat(AT_FDCWD, pathname);
 }
 
-int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode)
+int vfs_symlink(struct inode *dir, struct dentry *dentry,
+	const char *oldname, int mode, struct nameidata *nd)
 {
-	int error = may_create(dir, dentry, NULL);
+	int error = may_create(dir, dentry, nd);
 
 	if (error)
 		return error;
--- olpc-2.6-master.00/fs/namei.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/namei.c	2007-03-01 11:52:20.000000000 -0500
@@ -2227,7 +2317,7 @@ asmlinkage long sys_symlinkat(const char
 	if (IS_ERR(dentry))
 		goto out_unlock;
 
-	error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
+	error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO, &nd);
 	dput(dentry);
 out_unlock:
 	mutex_unlock(&nd.dentry->d_inode->i_mutex);
--- olpc-2.6-master.00/fs/namei.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/namei.c	2007-03-01 11:52:20.000000000 -0500
@@ -2244,7 +2334,8 @@ asmlinkage long sys_symlink(const char _
 	return sys_symlinkat(oldname, AT_FDCWD, newname);
 }
 
-int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
+int vfs_link(struct dentry *old_dentry, struct inode *dir,
+	struct dentry *new_dentry, struct nameidata *nd)
 {
 	struct inode *inode = old_dentry->d_inode;
 	int error;
--- olpc-2.6-master.00/fs/namei.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/namei.c	2007-03-01 11:52:20.000000000 -0500
@@ -2252,7 +2343,7 @@ int vfs_link(struct dentry *old_dentry, 
 	if (!inode)
 		return -ENOENT;
 
-	error = may_create(dir, new_dentry, NULL);
+	error = may_create(dir, new_dentry, nd);
 	if (error)
 		return error;
 
--- olpc-2.6-master.00/fs/namei.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/namei.c	2007-03-01 11:52:20.000000000 -0500
@@ -2322,7 +2413,7 @@ asmlinkage long sys_linkat(int olddfd, c
 	error = PTR_ERR(new_dentry);
 	if (IS_ERR(new_dentry))
 		goto out_unlock;
-	error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
+	error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry, &nd);
 	dput(new_dentry);
 out_unlock:
 	mutex_unlock(&nd.dentry->d_inode->i_mutex);
--- olpc-2.6-master.00/fs/namei.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/namei.c	2007-03-01 11:52:20.000000000 -0500
@@ -2454,7 +2545,7 @@ int vfs_rename(struct inode *old_dir, st
 	if (old_dentry->d_inode == new_dentry->d_inode)
  		return 0;
  
-	error = may_delete(old_dir, old_dentry, is_dir);
+	error = may_delete(old_dir, old_dentry, is_dir, NULL);
 	if (error)
 		return error;
 
--- olpc-2.6-master.00/fs/namei.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/namei.c	2007-03-01 11:52:20.000000000 -0500
@@ -2461,7 +2552,7 @@ *****
 	if (!new_dentry->d_inode)
 		error = may_create(new_dir, new_dentry, NULL);
 	else
-		error = may_delete(new_dir, new_dentry, is_dir);
+		error = may_delete(new_dir, new_dentry, is_dir, NULL);
 	if (error)
 		return error;
 
--- olpc-2.6-master.00/fs/namei.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/namei.c	2007-03-01 11:52:20.000000000 -0500
@@ -2539,6 +2630,9 @@ static int do_rename(int olddfd, const c
 	error = -EINVAL;
 	if (old_dentry == trap)
 		goto exit4;
+	error = -EROFS;
+	if (MNT_IS_RDONLY(newnd.mnt))
+		goto exit4;
 	new_dentry = lookup_hash(&newnd);
 	error = PTR_ERR(new_dentry);
 	if (IS_ERR(new_dentry))
--- olpc-2.6-master.00/fs/namespace.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/namespace.c	2007-03-01 11:52:20.000000000 -0500
@@ -353,39 +385,55 @@ *****
 	struct vfsmount *mnt = v;
 	int err = 0;
 	static struct proc_fs_info {
-		int flag;
-		char *str;
+		int s_flag;
+		int mnt_flag;
+		char *set_str;
+		char *unset_str;
 	} fs_info[] = {
-		{ MS_SYNCHRONOUS, ",sync" },
-		{ MS_DIRSYNC, ",dirsync" },
-		{ MS_MANDLOCK, ",mand" },
-		{ 0, NULL }
-	};
-	static struct proc_fs_info mnt_info[] = {
-		{ MNT_NOSUID, ",nosuid" },
-		{ MNT_NODEV, ",nodev" },
-		{ MNT_NOEXEC, ",noexec" },
-		{ MNT_NOATIME, ",noatime" },
-		{ MNT_NODIRATIME, ",nodiratime" },
-		{ MNT_RELATIME, ",relatime" },
-		{ 0, NULL }
+		{ MS_RDONLY, MNT_RDONLY, "ro", "rw" },
+		{ MS_SYNCHRONOUS, 0, ",sync", NULL },
+		{ MS_DIRSYNC, 0, ",dirsync", NULL },
+		{ MS_MANDLOCK, 0, ",mand", NULL },
+		{ MS_TAGGED, 0, ",tag", NULL },
+		{ MS_NOATIME, MNT_NOATIME, ",noatime", NULL },
+		{ MS_NODIRATIME, MNT_NODIRATIME, ",nodiratime", NULL },
+		{ MS_RELATIME, MNT_RELATIME, ",relatime", NULL },
+		{ 0, MNT_NOSUID, ",nosuid", NULL },
+		{ 0, MNT_NODEV, ",nodev", NULL },
+		{ 0, MNT_NOEXEC, ",noexec", NULL },
+		{ 0, 0, NULL, NULL }
 	};
-	struct proc_fs_info *fs_infop;
+	struct proc_fs_info *p;
+	unsigned long s_flags = mnt->mnt_sb->s_flags;
+	int mnt_flags = mnt->mnt_flags;
 
-	mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none");
-	seq_putc(m, ' ');
-	seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
-	seq_putc(m, ' ');
-	mangle(m, mnt->mnt_sb->s_type->name);
-	seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw");
-	for (fs_infop = fs_info; fs_infop->flag; fs_infop++) {
-		if (mnt->mnt_sb->s_flags & fs_infop->flag)
-			seq_puts(m, fs_infop->str);
+	if (vx_flags(VXF_HIDE_MOUNT, 0))
+		return 0;
+	if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
+		return 0;
+
+	if (!vx_check(0, VS_ADMIN|VS_WATCH) &&
+		mnt == current->fs->rootmnt) {
+		seq_puts(m, "/dev/root / ");
+	} else {
+		mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none");
+		seq_putc(m, ' ');
+		seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
+		seq_putc(m, ' ');
 	}
-	for (fs_infop = mnt_info; fs_infop->flag; fs_infop++) {
-		if (mnt->mnt_flags & fs_infop->flag)
-			seq_puts(m, fs_infop->str);
+	mangle(m, mnt->mnt_sb->s_type->name);
+	seq_putc(m, ' ');
+	for (p = fs_info; (p->s_flag | p->mnt_flag) ; p++) {
+		if ((s_flags & p->s_flag) || (mnt_flags & p->mnt_flag)) {
+			if (p->set_str)
+				seq_puts(m, p->set_str);
+		} else {
+			if (p->unset_str)
+				seq_puts(m, p->unset_str);
+		}
 	}
+	if (mnt->mnt_flags & MNT_TAGID)
+		seq_printf(m, ",tag=%d", mnt->mnt_tag);
 	if (mnt->mnt_sb->s_op->show_options)
 		err = mnt->mnt_sb->s_op->show_options(m, mnt);
 	seq_puts(m, " 0 0\n");
--- olpc-2.6-master.00/fs/nfs/dir.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/nfs/dir.c	2007-03-01 11:52:20.000000000 -0500
@@ -981,7 +983,8 @@ static int is_atomic_open(struct inode *
 	if (nd->flags & LOOKUP_DIRECTORY)
 		return 0;
 	/* Are we trying to write to a read only partition? */
-	if (IS_RDONLY(dir) && (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
+	if ((IS_RDONLY(dir) || MNT_IS_RDONLY(nd->mnt)) &&
+		(nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
 		return 0;
 	return 1;
 }
--- olpc-2.6-master.00/fs/nfsd/nfs4recover.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/nfsd/nfs4recover.c	2007-03-01 11:52:20.000000000 -0500
@@ -156,7 +156,7 @@ nfsd4_create_clid_dir(struct nfs4_client
 		dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n");
 		goto out_put;
 	}
-	status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU);
+	status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU, NULL);
 out_put:
 	dput(dentry);
 out_unlock:
--- olpc-2.6-master.00/fs/nfsd/nfs4recover.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/nfsd/nfs4recover.c	2007-03-01 11:52:20.000000000 -0500
@@ -260,7 +260,7 @@ nfsd4_remove_clid_file(struct dentry *di
 		return -EINVAL;
 	}
 	mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
-	status = vfs_unlink(dir->d_inode, dentry);
+	status = vfs_unlink(dir->d_inode, dentry, NULL);
 	mutex_unlock(&dir->d_inode->i_mutex);
 	return status;
 }
--- olpc-2.6-master.00/fs/nfsd/nfs4recover.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/nfsd/nfs4recover.c	2007-03-01 11:52:20.000000000 -0500
@@ -275,7 +275,7 @@ nfsd4_clear_clid_dir(struct dentry *dir,
 	 * a kernel from the future.... */
 	nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file);
 	mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
-	status = vfs_rmdir(dir->d_inode, dentry);
+	status = vfs_rmdir(dir->d_inode, dentry, NULL);
 	mutex_unlock(&dir->d_inode->i_mutex);
 	return status;
 }
--- olpc-2.6-master.00/fs/nfsd/vfs.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/nfsd/vfs.c	2007-03-01 11:52:20.000000000 -0500
@@ -1186,7 +1186,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
 		host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
 		break;
 	case S_IFDIR:
-		host_err = vfs_mkdir(dirp, dchild, iap->ia_mode);
+		host_err = vfs_mkdir(dirp, dchild, iap->ia_mode, NULL);
 		break;
 	case S_IFCHR:
 	case S_IFBLK:
--- olpc-2.6-master.00/fs/nfsd/vfs.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/nfsd/vfs.c	2007-03-01 11:52:20.000000000 -0500
@@ -1192,7 +1192,7 @@ *****
 	case S_IFBLK:
 	case S_IFIFO:
 	case S_IFSOCK:
-		host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
+		host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev, NULL);
 		break;
 	default:
 	        printk("nfsd: bad file type %o in nfsd_create\n", type);
--- olpc-2.6-master.00/fs/nfsd/vfs.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/nfsd/vfs.c	2007-03-01 11:52:20.000000000 -0500
@@ -1466,7 +1466,8 @@ nfsd_symlink(struct svc_rqst *rqstp, str
 		else {
 			strncpy(path_alloced, path, plen);
 			path_alloced[plen] = 0;
-			host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode);
+			host_err = vfs_symlink(dentry->d_inode, dnew,
+				path_alloced, mode, NULL);
 			kfree(path_alloced);
 		}
 	} else
--- olpc-2.6-master.00/fs/nfsd/vfs.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/nfsd/vfs.c	2007-03-01 11:52:20.000000000 -0500
@@ -1470,7 +1471,8 @@ *****
 			kfree(path_alloced);
 		}
 	} else
-		host_err = vfs_symlink(dentry->d_inode, dnew, path, mode);
+		host_err = vfs_symlink(dentry->d_inode, dnew,
+			path, mode, NULL);
 
 	if (!host_err) {
 		if (EX_ISSYNC(fhp->fh_export))
--- olpc-2.6-master.00/fs/nfsd/vfs.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/nfsd/vfs.c	2007-03-01 11:52:20.000000000 -0500
@@ -1529,7 +1531,7 @@ nfsd_link(struct svc_rqst *rqstp, struct
 	dold = tfhp->fh_dentry;
 	dest = dold->d_inode;
 
-	host_err = vfs_link(dold, dirp, dnew);
+	host_err = vfs_link(dold, dirp, dnew, NULL);
 	if (!host_err) {
 		if (EX_ISSYNC(ffhp->fh_export)) {
 			err = nfserrno(nfsd_sync_dir(ddir));
--- olpc-2.6-master.00/fs/nfsd/vfs.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/nfsd/vfs.c	2007-03-01 11:52:20.000000000 -0500
@@ -1694,9 +1696,9 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
 			host_err = -EPERM;
 		} else
 #endif
-		host_err = vfs_unlink(dirp, rdentry);
+		host_err = vfs_unlink(dirp, rdentry, NULL);
 	} else { /* It's RMDIR */
-		host_err = vfs_rmdir(dirp, rdentry);
+		host_err = vfs_rmdir(dirp, rdentry, NULL);
 	}
 
 	dput(rdentry);
--- olpc-2.6-master.00/fs/nfsd/vfs.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/nfsd/vfs.c	2007-03-01 11:52:20.000000000 -0500
@@ -1807,7 +1809,8 @@ nfsd_permission(struct svc_export *exp, 
 	 */
 	if (!(acc & MAY_LOCAL_ACCESS))
 		if (acc & (MAY_WRITE | MAY_SATTR | MAY_TRUNC)) {
-			if (EX_RDONLY(exp) || IS_RDONLY(inode))
+			if (EX_RDONLY(exp) || IS_RDONLY(inode)
+				|| MNT_IS_RDONLY(exp->ex_mnt))
 				return nfserr_rofs;
 			if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode))
 				return nfserr_perm;
--- olpc-2.6-master.00/fs/open.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/open.c	2007-03-01 11:52:20.000000000 -0500
@@ -246,7 +255,7 @@ static long do_sys_truncate(const char _
 		goto dput_and_out;
 
 	error = -EROFS;
-	if (IS_RDONLY(inode))
+	if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
 		goto dput_and_out;
 
 	error = -EPERM;
--- olpc-2.6-master.00/fs/open.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/open.c	2007-03-01 11:52:20.000000000 -0500
@@ -395,7 +404,7 @@ asmlinkage long sys_faccessat(int dfd, c
 	   special_file(nd.dentry->d_inode->i_mode))
 		goto out_path_release;
 
-	if(IS_RDONLY(nd.dentry->d_inode))
+	if(IS_RDONLY(nd.dentry->d_inode) || MNT_IS_RDONLY(nd.mnt))
 		res = -EROFS;
 
 out_path_release:
--- olpc-2.6-master.00/fs/open.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/open.c	2007-03-01 11:52:20.000000000 -0500
@@ -509,7 +518,7 @@ asmlinkage long sys_fchmod(unsigned int 
 	audit_inode(NULL, inode);
 
 	err = -EROFS;
-	if (IS_RDONLY(inode))
+	if (IS_RDONLY(inode) || MNT_IS_RDONLY(file->f_vfsmnt))
 		goto out_putf;
 	err = -EPERM;
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
--- olpc-2.6-master.00/fs/open.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/open.c	2007-03-01 11:52:20.000000000 -0500
@@ -568,7 +577,8 @@ asmlinkage long sys_chmod(const char __u
 	return sys_fchmodat(AT_FDCWD, filename, mode);
 }
 
-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
+static int chown_common(struct dentry *dentry, struct vfsmount *mnt,
+	uid_t user, gid_t group)
 {
 	struct inode * inode;
 	int error;
--- olpc-2.6-master.00/fs/open.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/open.c	2007-03-01 11:52:20.000000000 -0500
@@ -580,7 +590,7 @@ static int chown_common(struct dentry * 
 		goto out;
 	}
 	error = -EROFS;
-	if (IS_RDONLY(inode))
+	if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt))
 		goto out;
 	error = -EPERM;
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
--- olpc-2.6-master.00/fs/open.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/open.c	2007-03-01 11:52:20.000000000 -0500
@@ -664,7 +686,7 @@ asmlinkage long sys_fchown(unsigned int 
 
 	dentry = file->f_path.dentry;
 	audit_inode(NULL, dentry->d_inode);
-	error = chown_common(dentry, user, group);
+	error = chown_common(dentry, file->f_vfsmnt, user, group);
 	fput(file);
 out:
 	return error;
--- olpc-2.6-master.00/fs/reiserfs/ioctl.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/reiserfs/ioctl.c	2007-03-01 11:52:20.000000000 -0500
@@ -48,7 +50,8 @@ *****
 			if (!reiserfs_attrs(inode->i_sb))
 				return -ENOTTY;
 
-			if (IS_RDONLY(inode))
+			if (IS_RDONLY(inode) ||
+				(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 				return -EROFS;
 
 			if ((current->fsuid != inode->i_uid)
--- olpc-2.6-master.00/fs/reiserfs/ioctl.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/reiserfs/ioctl.c	2007-03-01 11:52:20.000000000 -0500
@@ -83,7 +91,8 @@ int reiserfs_ioctl(struct inode *inode, 
 	case REISERFS_IOC_SETVERSION:
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
 			return -EPERM;
-		if (IS_RDONLY(inode))
+		if (IS_RDONLY(inode) ||
+			(filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
 			return -EROFS;
 		if (get_user(inode->i_generation, (int __user *)arg))
 			return -EFAULT;
--- olpc-2.6-master.00/fs/reiserfs/xattr.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/reiserfs/xattr.c	2007-03-01 11:52:20.000000000 -0500
@@ -823,7 +824,7 @@ int reiserfs_delete_xattrs(struct inode 
 	if (dir->d_inode->i_nlink <= 2) {
 		root = get_xa_root(inode->i_sb);
 		reiserfs_write_lock_xattrs(inode->i_sb);
-		err = vfs_rmdir(root->d_inode, dir);
+		err = vfs_rmdir(root->d_inode, dir, NULL);
 		reiserfs_write_unlock_xattrs(inode->i_sb);
 		dput(root);
 	} else {
--- olpc-2.6-master.00/fs/utimes.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/utimes.c	2007-03-01 11:52:20.000000000 -0500
@@ -33,7 +35,7 @@ asmlinkage long sys_utime(char __user * 
 	inode = nd.dentry->d_inode;
 
 	error = -EROFS;
-	if (IS_RDONLY(inode))
+	if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
 		goto dput_and_out;
 
 	/* Don't worry, the checks are done in inode_change_ok() */
--- olpc-2.6-master.00/fs/xattr.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/xattr.c	2007-03-01 11:52:20.000000000 -0500
@@ -195,7 +196,7 @@ EXPORT_SYMBOL_GPL(vfs_removexattr);
  */
 static long
 setxattr(struct dentry *d, char __user *name, void __user *value,
-	 size_t size, int flags)
+	 size_t size, int flags, struct vfsmount *mnt)
 {
 	int error;
 	void *kvalue = NULL;
--- olpc-2.6-master.00/fs/xattr.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/xattr.c	2007-03-01 11:52:20.000000000 -0500
@@ -222,6 +223,9 @@ setxattr(struct dentry *d, char __user *
 		}
 	}
 
+	if (MNT_IS_RDONLY(mnt))
+		return -EROFS;
+
 	error = vfs_setxattr(d, kname, kvalue, size, flags);
 	kfree(kvalue);
 	return error;
--- olpc-2.6-master.00/fs/xattr.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/xattr.c	2007-03-01 11:52:20.000000000 -0500
@@ -237,7 +241,7 @@ sys_setxattr(char __user *path, char __u
 	error = user_path_walk(path, &nd);
 	if (error)
 		return error;
-	error = setxattr(nd.dentry, name, value, size, flags);
+	error = setxattr(nd.dentry, name, value, size, flags, nd.mnt);
 	path_release(&nd);
 	return error;
 }
--- olpc-2.6-master.00/fs/xattr.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/xattr.c	2007-03-01 11:52:20.000000000 -0500
@@ -252,7 +256,7 @@ sys_lsetxattr(char __user *path, char __
 	error = user_path_walk_link(path, &nd);
 	if (error)
 		return error;
-	error = setxattr(nd.dentry, name, value, size, flags);
+	error = setxattr(nd.dentry, name, value, size, flags, nd.mnt);
 	path_release(&nd);
 	return error;
 }
--- olpc-2.6-master.00/fs/xattr.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/xattr.c	2007-03-01 11:52:20.000000000 -0500
@@ -270,7 +274,7 @@ sys_fsetxattr(int fd, char __user *name,
 		return error;
 	dentry = f->f_path.dentry;
 	audit_inode(NULL, dentry->d_inode);
-	error = setxattr(dentry, name, value, size, flags);
+	error = setxattr(dentry, name, value, size, flags, f->f_vfsmnt);
 	fput(f);
 	return error;
 }
--- olpc-2.6-master.00/fs/xattr.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/xattr.c	2007-03-01 11:52:20.000000000 -0500
@@ -432,7 +436,7 @@ sys_flistxattr(int fd, char __user *list
  * Extended attribute REMOVE operations
  */
 static long
-removexattr(struct dentry *d, char __user *name)
+removexattr(struct dentry *d, char __user *name, struct vfsmount *mnt)
 {
 	int error;
 	char kname[XATTR_NAME_MAX + 1];
--- olpc-2.6-master.00/fs/xattr.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/xattr.c	2007-03-01 11:52:20.000000000 -0500
@@ -443,6 +447,9 @@ removexattr(struct dentry *d, char __use
 	if (error < 0)
 		return error;
 
+	if (MNT_IS_RDONLY(mnt))
+		return -EROFS;
+
 	return vfs_removexattr(d, kname);
 }
 
--- olpc-2.6-master.00/fs/xattr.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/xattr.c	2007-03-01 11:52:20.000000000 -0500
@@ -455,7 +462,7 @@ sys_removexattr(char __user *path, char 
 	error = user_path_walk(path, &nd);
 	if (error)
 		return error;
-	error = removexattr(nd.dentry, name);
+	error = removexattr(nd.dentry, name, nd.mnt);
 	path_release(&nd);
 	return error;
 }
--- olpc-2.6-master.00/fs/xattr.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/xattr.c	2007-03-01 11:52:20.000000000 -0500
@@ -469,7 +476,7 @@ sys_lremovexattr(char __user *path, char
 	error = user_path_walk_link(path, &nd);
 	if (error)
 		return error;
-	error = removexattr(nd.dentry, name);
+	error = removexattr(nd.dentry, name, nd.mnt);
 	path_release(&nd);
 	return error;
 }
--- olpc-2.6-master.00/fs/xattr.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/xattr.c	2007-03-01 11:52:20.000000000 -0500
@@ -486,7 +493,7 @@ sys_fremovexattr(int fd, char __user *na
 		return error;
 	dentry = f->f_path.dentry;
 	audit_inode(NULL, dentry->d_inode);
-	error = removexattr(dentry, name);
+	error = removexattr(dentry, name, f->f_vfsmnt);
 	fput(f);
 	return error;
 }
--- olpc-2.6-master.00/include/linux/fs.h	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/include/linux/fs.h	2007-03-01 17:09:59.000000000 -0500
@@ -163,7 +167,7 @@ extern int dir_notify_enable;
  */
 #define __IS_FLG(inode,flg) ((inode)->i_sb->s_flags & (flg))
 
-#define IS_RDONLY(inode) ((inode)->i_sb->s_flags & MS_RDONLY)
+#define IS_RDONLY(inode)	__IS_FLG(inode, MS_RDONLY)
 #define IS_SYNC(inode)		(__IS_FLG(inode, MS_SYNCHRONOUS) || \
 					((inode)->i_flags & S_SYNC))
 #define IS_DIRSYNC(inode)	(__IS_FLG(inode, MS_SYNCHRONOUS|MS_DIRSYNC) || \
--- olpc-2.6-master.00/include/linux/fs.h	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/include/linux/fs.h	2007-03-01 17:09:59.000000000 -0500
@@ -980,12 +1005,12 @@ extern void unlock_super(struct super_bl
  */
 extern int vfs_permission(struct nameidata *, int);
 extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *);
-extern int vfs_mkdir(struct inode *, struct dentry *, int);
-extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t);
-extern int vfs_symlink(struct inode *, struct dentry *, const char *, int);
-extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
-extern int vfs_rmdir(struct inode *, struct dentry *);
-extern int vfs_unlink(struct inode *, struct dentry *);
+extern int vfs_mkdir(struct inode *, struct dentry *, int, struct nameidata *);
+extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t, struct nameidata *);
+extern int vfs_symlink(struct inode *, struct dentry *, const char *, int, struct nameidata *);
+extern int vfs_link(struct dentry *, struct inode *, struct dentry *, struct nameidata *);
+extern int vfs_rmdir(struct inode *, struct dentry *, struct nameidata *);
+extern int vfs_unlink(struct inode *, struct dentry *, struct nameidata *);
 extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
 
 /*
--- olpc-2.6-master.00/include/linux/mount.h	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/include/linux/mount.h	2007-03-01 11:52:20.000000000 -0500
@@ -28,6 +28,9 @@ struct mnt_namespace;
 #define MNT_NOATIME	0x08
 #define MNT_NODIRATIME	0x10
 #define MNT_RELATIME	0x20
+#define MNT_RDONLY	0x40
+
+#define MNT_IS_RDONLY(m)	((m) && ((m)->mnt_flags & MNT_RDONLY))
 
 #define MNT_SHRINKABLE	0x100
 
--- olpc-2.6-master.00/ipc/mqueue.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/ipc/mqueue.c	2007-03-01 11:52:20.000000000 -0500
@@ -747,7 +756,7 @@ asmlinkage long sys_mq_unlink(const char
 	if (inode)
 		atomic_inc(&inode->i_count);
 
-	err = vfs_unlink(dentry->d_parent->d_inode, dentry);
+	err = vfs_unlink(dentry->d_parent->d_inode, dentry, NULL);
 out_err:
 	dput(dentry);
 
--- olpc-2.6-master.00/net/unix/af_unix.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/net/unix/af_unix.c	2007-03-01 11:52:20.000000000 -0500
@@ -808,7 +812,7 @@ static int unix_bind(struct socket *sock
 		 */
 		mode = S_IFSOCK |
 		       (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
-		err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
+		err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0, NULL);
 		if (err)
 			goto out_mknod_dput;
 		mutex_unlock(&nd.dentry->d_inode->i_mutex);
