]> Pileus Git - ~andy/linux/blobdiff - fs/cifs/dir.c
Merge branch 'nommu' of master.kernel.org:/home/rmk/linux-2.6-arm
[~andy/linux] / fs / cifs / dir.c
index ddd11fa1552804061b6459297ca274b122acc87a..ba4cbe9b0684dd0a6ae66d65f8486462ab80e778 100644 (file)
@@ -113,7 +113,7 @@ cifs_bp_rename_retry:
        full_path[namelen+2] = 0;
 BB remove above eight lines BB */
 
-/* Inode operations in similar order to how they appear in the Linux file fs.h */
+/* Inode operations in similar order to how they appear in Linux file fs.h */
 
 int
 cifs_create(struct inode *inode, struct dentry *direntry, int mode,
@@ -139,9 +139,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
        cifs_sb = CIFS_SB(inode->i_sb);
        pTcon = cifs_sb->tcon;
 
-       down(&direntry->d_sb->s_vfs_rename_sem);
        full_path = build_path_from_dentry(direntry);
-       up(&direntry->d_sb->s_vfs_rename_sem);
        if(full_path == NULL) {
                FreeXid(xid);
                return -ENOMEM;
@@ -180,11 +178,14 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
                FreeXid(xid);
                return -ENOMEM;
        }
-
-       rc = CIFSSMBOpen(xid, pTcon, full_path, disposition,
+       if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) 
+               rc = CIFSSMBOpen(xid, pTcon, full_path, disposition,
                         desiredAccess, CREATE_NOT_DIR,
                         &fileHandle, &oplock, buf, cifs_sb->local_nls,
                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+       else
+               rc = -EIO; /* no NT SMB support fall into legacy open below */
+
        if(rc == -EIO) {
                /* old server, retry the open legacy style */
                rc = SMBLegacyOpen(xid, pTcon, full_path, disposition,
@@ -193,7 +194,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
        } 
        if (rc) {
-               cFYI(1, ("cifs_create returned 0x%x ", rc));
+               cFYI(1, ("cifs_create returned 0x%x", rc));
        } else {
                /* If Open reported that we actually created a file
                then we now have to set the mode if possible */
@@ -316,9 +317,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
        cifs_sb = CIFS_SB(inode->i_sb);
        pTcon = cifs_sb->tcon;
 
-       down(&direntry->d_sb->s_vfs_rename_sem);
        full_path = build_path_from_dentry(direntry);
-       up(&direntry->d_sb->s_vfs_rename_sem);
        if(full_path == NULL)
                rc = -ENOMEM;
        else if (pTcon->ses->capabilities & CAP_UNIX) {
@@ -373,6 +372,10 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
                                         cifs_sb->mnt_cifs_flags & 
                                            CIFS_MOUNT_MAP_SPECIAL_CHR);
 
+                       /* BB FIXME - add handling for backlevel servers
+                          which need legacy open and check for all
+                          calls to SMBOpen for fallback to 
+                          SMBLeagcyOpen */
                        if(!rc) {
                                /* BB Do not bother to decode buf since no
                                   local inode yet to put timestamps in,
@@ -440,6 +443,20 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
        cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
        pTcon = cifs_sb->tcon;
 
+       /*
+        * Don't allow the separator character in a path component.
+        * The VFS will not allow "/", but "\" is allowed by posix.
+        */
+       if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
+               int i;
+               for (i = 0; i < direntry->d_name.len; i++)
+                       if (direntry->d_name.name[i] == '\\') {
+                               cFYI(1, ("Invalid file name"));
+                               FreeXid(xid);
+                               return ERR_PTR(-EINVAL);
+                       }
+       }
+
        /* can not grab the rename sem here since it would
        deadlock in the cases (beginning of sys_rename itself)
        in which we already have the sb rename sem */