diff -urNX ../kernels/exclude linux+lock-F/fs/locks.c linux+lock/fs/locks.c
--- linux+lock-F/fs/locks.c	Wed Jun 14 22:01:03 2000
+++ linux+lock/fs/locks.c	Thu Jun 15 04:25:57 2000
@@ -216,6 +216,10 @@
 	case LOCK_UN:
 		return F_UNLCK;
 	}
+
+	if (cmd & LOCK_MAND)
+		return cmd & (LOCK_MAND | LOCK_RW);
+
 	return -EINVAL;
 }
 
@@ -360,10 +364,9 @@
 		
 	case F_WRLCK:
 		return 1;
-
-	default:
-		BUG();
 	}
+	BUG();
+	return 0; /* I'm a liar */
 }
 
 /* Determine if lock sys_fl blocks lock caller_fl. FLOCK specific
@@ -384,10 +387,9 @@
 		
 	case F_WRLCK:
 		return 1;
-
-	default:
-		BUG();
 	}
+	BUG();
+	return 0; /* I'm a liar */
 }
 
 /* Insert file lock fl into an inode's lock list at the position indicated
@@ -1322,7 +1324,7 @@
 
 	error = flock_translate_cmd(cmd);
 	if (error < 0)
-		goto out;
+		goto out_putf;
 	type = error;
 
 	error = -EBADF;
@@ -1444,6 +1446,59 @@
 	acquire_fl_sem();
 	locks_delete_block(waiter);
 	release_fl_sem();
+}
+
+/*
+ * Emulate windows share modes
+ */
+int lock_may_read(struct inode *inode, loff_t start, unsigned long len)
+{
+	struct file_lock *fl;
+	int result = 1;
+	acquire_fl_sem();
+	for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
+		printk("flock_may_read: lock = %x, %x\n", fl->fl_flags, fl->fl_type);
+		if (fl->fl_flags == FL_POSIX) {
+			if (fl->fl_type == F_RDLCK)
+				continue;
+			if ((fl->fl_end < start) || (fl->fl_start > (start + len)))
+				continue;
+		} else {
+			if (!(fl->fl_type & LOCK_MAND))
+				continue;
+			if (fl->fl_type & LOCK_READ)
+				continue;
+		}
+		result = 0;
+		break;
+	}
+	release_fl_sem();
+printk("flock_may_read: %x\n", result);
+	return result;
+}
+
+int lock_may_write(struct inode *inode, loff_t start, unsigned long len)
+{
+	struct file_lock *fl;
+	int result = 1;
+	acquire_fl_sem();
+	for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
+		printk("flock_may_write: lock = %x, %x\n", fl->fl_flags, fl->fl_type);
+		if (fl->fl_flags == FL_POSIX) {
+			if ((fl->fl_end < start) || (fl->fl_start > (start + len)))
+				continue;
+		} else {
+			if (!(fl->fl_type & LOCK_MAND))
+				continue;
+			if (fl->fl_type & LOCK_WRITE)
+				continue;
+		}
+		result = 0;
+		break;
+	}
+	release_fl_sem();
+printk("flock_may_write: %x\n", result);
+	return result;
 }
 
 void __init filelock_init(void)
diff -urNX ../kernels/exclude linux+lock-F/fs/nfsd/vfs.c linux+lock/fs/nfsd/vfs.c
--- linux+lock-F/fs/nfsd/vfs.c	Mon May  8 18:54:17 2000
+++ linux+lock/fs/nfsd/vfs.c	Thu Jun 15 01:14:06 2000
@@ -585,6 +585,9 @@
 	err = nfserr_perm;
 	if (!file.f_op->read)
 		goto out_close;
+	if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
+		(!lock_may_read(file.f_dentry->d_inode, offset, *count)))
+		goto out_close;
 
 	/* Get readahead parameters */
 	ra = nfsd_get_raparms(fhp->fh_export->ex_dev, fhp->fh_dentry->d_inode->i_ino);
@@ -654,6 +657,9 @@
 	err = nfserr_perm;
 	if (!file.f_op->write)
 		goto out_close;
+	if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
+		(!lock_may_write(file.f_dentry->d_inode, offset, cnt)))
+		goto out_close;
 
 	dentry = file.f_dentry;
 	inode = dentry->d_inode;
@@ -1255,7 +1261,12 @@
 	fill_pre_wcc(tfhp);
 #endif /* CONFIG_NFSD_V3 */
 
-	err = vfs_rename(fdir, odentry, tdir, ndentry);
+	if ((ffhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
+		((odentry->d_count > 1) || (ndentry->d_count > 1))) {
+			err = nfserr_perm;
+	} else {
+		err = vfs_rename(fdir, odentry, tdir, ndentry);
+	}
 	if (!err && EX_ISSYNC(tfhp->fh_export)) {
 		nfsd_sync_dir(tdentry);
 		nfsd_sync_dir(fdentry);
@@ -1317,7 +1328,12 @@
 	}
 
 	if (type != S_IFDIR) { /* It's UNLINK */
-		err = vfs_unlink(dirp, rdentry);
+		if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
+			(rdentry->d_count > 1)) {
+			err = nfserr_perm;
+		} else {
+			err = vfs_unlink(dirp, rdentry);
+		}
 	} else { /* It's RMDIR */
 		err = vfs_rmdir(dirp, rdentry);
 	}
diff -urNX ../kernels/exclude linux+lock-F/include/linux/fs.h linux+lock/include/linux/fs.h
--- linux+lock-F/include/linux/fs.h	Wed Jun 14 22:01:04 2000
+++ linux+lock/include/linux/fs.h	Thu Jun 15 01:15:09 2000
@@ -549,6 +549,8 @@
 extern void posix_block_lock(struct file_lock *, struct file_lock *);
 extern void posix_unblock_lock(struct file_lock *);
 extern int __get_lease(struct inode *inode, unsigned int flags);
+extern int lock_may_read(struct inode *, loff_t start, unsigned long count);
+extern int lock_may_write(struct inode *, loff_t start, unsigned long count);
 
 #define FASYNC_MAGIC 0x4601
 
