[CIFS] Fix oops in cifs_create when nfsd server exports cifs mount
authorSteve French <sfrench@us.ibm.com>
Wed, 11 Jul 2007 18:30:34 +0000 (18:30 +0000)
committerSteve French <sfrench@us.ibm.com>
Wed, 11 Jul 2007 18:30:34 +0000 (18:30 +0000)
nfsd is passing null nameidata (probably the only one doing that)
on call to create - cifs was missing one check for this.

Note that running nfsd over a cifs mount requires specifying fsid on
the nfs exports entry and requires mounting cifs with serverino mount
option.

Signed-off-by: Steve French <sfrench@us.ibm.com>
fs/cifs/CHANGES
fs/cifs/README
fs/cifs/cifsfs.c
fs/cifs/dir.c
fs/cifs/export.c
fs/cifs/file.c

index ee276f62bcf4368c6a3722af84ec13096fa90262..f92e0ee661ae1cf9dfd93c5b34ff5e9271beff14 100644 (file)
@@ -1,6 +1,7 @@
 Version 1.50
 ------------
-Fix NTLMv2 signing
+Fix NTLMv2 signing. NFS server mounted over cifs works (if cifs mount is
+done with "serverino" mount option).
 
 Version 1.49
 ------------
index eb3efd5a6a81554c8238f70a56f9101eceab8bc3..85f1eb14083eb2c3057027f60863f80db82df1b8 100644 (file)
@@ -370,7 +370,7 @@ A partial list of the supported mount options follows:
                Note that this does not affect the normal ACL check on the
                target machine done by the server software (of the server
                ACL against the user name provided at mount time).
-  serverino    Use servers inode numbers instead of generating automatically
+  serverino    Use server's inode numbers instead of generating automatically
                incrementing inode numbers on the client.  Although this will
                make it easier to spot hardlinked files (as they will have
                the same inode numbers) and inode numbers may be persistent,
@@ -378,12 +378,11 @@ A partial list of the supported mount options follows:
                are unique if multiple server side mounts are exported under a
                single share (since inode numbers on the servers might not
                be unique if multiple filesystems are mounted under the same
-               shared higher level directory).  Note that this requires that
-               the server support the CIFS Unix Extensions as other servers
-               do not return a unique IndexNumber on SMB FindFirst (most
-               servers return zero as the IndexNumber).  Parameter has no
-               effect to Windows servers and others which do not support the
-               CIFS Unix Extensions.
+               shared higher level directory).  Note that some older
+               (e.g. pre-Windows 2000) do not support returning UniqueIDs
+               or the CIFS Unix Extensions equivalent and for those
+               this mount option will have no effect.  Exporting cifs mounts
+               under nfsd requires this mount option on the cifs mount.
   noserverino   Client generates inode numbers (rather than using the actual one
                from the server) by default.
   setuids       If the CIFS Unix extensions are negotiated with the server
index 17ed7cf750af7bd474bbdb3b06514f133a175fa2..40f35f0263ac907c43a50346f11adaf5d5bc063c 100644 (file)
@@ -114,10 +114,6 @@ cifs_read_super(struct super_block *sb, void *data,
 
        sb->s_magic = CIFS_MAGIC_NUMBER;
        sb->s_op = &cifs_super_ops;
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-       if (experimEnabled != 0)
-               sb->s_export_op = &cifs_export_ops;
-#endif /* EXPERIMENTAL */
 /*     if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
            sb->s_blocksize =
                cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
@@ -139,6 +135,13 @@ cifs_read_super(struct super_block *sb, void *data,
                rc = -ENOMEM;
                goto out_no_root;
        }
+       
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
+               cFYI(1, ("export ops supported"));
+               sb->s_export_op = &cifs_export_ops;
+       }
+#endif /* EXPERIMENTAL */
 
        return 0;
 
index 38706e8496a320a693c16f4e6be74910d8f605f5..def89f23fe554237f56e62549fc74ebd176ac487 100644 (file)
@@ -264,7 +264,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
                                direntry->d_op = &cifs_dentry_ops;
                        d_instantiate(direntry, newinode);
                }
-               if ((nd->flags & LOOKUP_OPEN) == FALSE) {
+               if ((nd == NULL /* nfsd case - nfs srv does not set nd */) ||
+                       ((nd->flags & LOOKUP_OPEN) == FALSE)) {
                        /* mknod case - do not leave file open */
                        CIFSSMBClose(xid, pTcon, fileHandle);
                } else if (newinode) {
index 5a08effda0ae7b176aa55ef90bde15d9f73da40e..6e66bc19f0aee71de61754aa3d1338aaebc31650 100644 (file)
  /*
   * See Documentation/filesystems/Exporting
   * and examples in fs/exportfs
+  *
+  * Since cifs is a network file system, an "fsid" must be included for
+  * any nfs exports file entries which refer to cifs paths.  In addition
+  * the cifs mount must be mounted with the "serverino" option (ie use stable
+  * server inode numbers instead of locally generated temporary ones).
+  * Although cifs inodes do not use generation numbers (have generation number
+  * of zero) - the inode number alone should be good enough for simple cases
+  * in which users want to export cifs shares with NFS. The decode and encode
+  * could be improved by using a new routine which expects 64 bit inode numbers
+  * instead of the default 32 bit routines in fs/exportfs
+  *
   */
 
 #include <linux/fs.h>
+#include "cifsglob.h"
+#include "cifs_debug.h"
+
  
 #ifdef CONFIG_CIFS_EXPERIMENTAL
  
 static struct dentry *cifs_get_parent(struct dentry *dentry)
 {
        /* BB need to add code here eventually to enable export via NFSD */
+       cFYI(1, ("get parent for %p", dentry));
        return ERR_PTR(-EACCES);
 }
  
index 7d6fb6f3adebbc3918504f8ce6ec73726a2b0b9c..d83eca4231e7fe50adf3ef7e17f2b3b1526310a5 100644 (file)
@@ -212,7 +212,7 @@ int cifs_open(struct inode *inode, struct file *file)
                return -ENOMEM;
        }
 
-       cFYI(1, (" inode = 0x%p file flags are 0x%x for %s",
+       cFYI(1, ("inode = 0x%p file flags are 0x%x for %s",
                 inode, file->f_flags, full_path));
        desiredAccess = cifs_convert_flags(file->f_flags);