[CIFS] Fix oops in cifs_create when nfsd server exports cifs mount

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>
This commit is contained in:
Steve French 2007-07-11 18:30:34 +00:00
parent fb8c4b14d9
commit 7521a3c566
6 changed files with 33 additions and 14 deletions

View File

@ -1,6 +1,7 @@
Version 1.50 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 Version 1.49
------------ ------------

View 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 Note that this does not affect the normal ACL check on the
target machine done by the server software (of the server target machine done by the server software (of the server
ACL against the user name provided at mount time). 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 incrementing inode numbers on the client. Although this will
make it easier to spot hardlinked files (as they will have make it easier to spot hardlinked files (as they will have
the same inode numbers) and inode numbers may be persistent, 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 are unique if multiple server side mounts are exported under a
single share (since inode numbers on the servers might not single share (since inode numbers on the servers might not
be unique if multiple filesystems are mounted under the same be unique if multiple filesystems are mounted under the same
shared higher level directory). Note that this requires that shared higher level directory). Note that some older
the server support the CIFS Unix Extensions as other servers (e.g. pre-Windows 2000) do not support returning UniqueIDs
do not return a unique IndexNumber on SMB FindFirst (most or the CIFS Unix Extensions equivalent and for those
servers return zero as the IndexNumber). Parameter has no this mount option will have no effect. Exporting cifs mounts
effect to Windows servers and others which do not support the under nfsd requires this mount option on the cifs mount.
CIFS Unix Extensions.
noserverino Client generates inode numbers (rather than using the actual one noserverino Client generates inode numbers (rather than using the actual one
from the server) by default. from the server) by default.
setuids If the CIFS Unix extensions are negotiated with the server setuids If the CIFS Unix extensions are negotiated with the server

View File

@ -114,10 +114,6 @@ cifs_read_super(struct super_block *sb, void *data,
sb->s_magic = CIFS_MAGIC_NUMBER; sb->s_magic = CIFS_MAGIC_NUMBER;
sb->s_op = &cifs_super_ops; 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) /* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
sb->s_blocksize = sb->s_blocksize =
cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */ 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; rc = -ENOMEM;
goto out_no_root; 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; return 0;

View File

@ -264,7 +264,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
direntry->d_op = &cifs_dentry_ops; direntry->d_op = &cifs_dentry_ops;
d_instantiate(direntry, newinode); 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 */ /* mknod case - do not leave file open */
CIFSSMBClose(xid, pTcon, fileHandle); CIFSSMBClose(xid, pTcon, fileHandle);
} else if (newinode) { } else if (newinode) {

View File

@ -26,15 +26,30 @@
/* /*
* See Documentation/filesystems/Exporting * See Documentation/filesystems/Exporting
* and examples in fs/exportfs * 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 <linux/fs.h>
#include "cifsglob.h"
#include "cifs_debug.h"
#ifdef CONFIG_CIFS_EXPERIMENTAL #ifdef CONFIG_CIFS_EXPERIMENTAL
static struct dentry *cifs_get_parent(struct dentry *dentry) static struct dentry *cifs_get_parent(struct dentry *dentry)
{ {
/* BB need to add code here eventually to enable export via NFSD */ /* BB need to add code here eventually to enable export via NFSD */
cFYI(1, ("get parent for %p", dentry));
return ERR_PTR(-EACCES); return ERR_PTR(-EACCES);
} }

View File

@ -212,7 +212,7 @@ int cifs_open(struct inode *inode, struct file *file)
return -ENOMEM; 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)); inode, file->f_flags, full_path));
desiredAccess = cifs_convert_flags(file->f_flags); desiredAccess = cifs_convert_flags(file->f_flags);