]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/cifs/dir.c
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-for-linus-2.6
[linux-2.6-omap-h63xx.git] / fs / cifs / dir.c
index 12ba81d7b07f6d1baefc380a43fb24261a583991..d335269bd91cfe5b626aba8a45eae25136b450dc 100644 (file)
@@ -101,68 +101,15 @@ cifs_bp_rename_retry:
        return full_path;
 }
 
-/* Note: caller must free return buffer */
-char *
-build_wildcard_path_from_dentry(struct dentry *direntry)
+/* char * build_wildcard_path_from_dentry(struct dentry *direntry)
 {
-       struct dentry *temp;
-       int namelen = 0;
-       char *full_path;
-
-       if(direntry == NULL)
-               return NULL;  /* not much we can do if dentry is freed and
-               we need to reopen the file after it was closed implicitly
-               when the server crashed */
-
-cifs_bwp_rename_retry:
-       for (temp = direntry; !IS_ROOT(temp);) {
-               namelen += (1 + temp->d_name.len);
-               temp = temp->d_parent;
-               if(temp == NULL) {
-                       cERROR(1,("corrupt dentry"));
-                       return NULL;
-               }
-       }
-
-       full_path = kmalloc(namelen+3, GFP_KERNEL);
        if(full_path == NULL)
                return full_path;
 
        full_path[namelen] = '\\';
        full_path[namelen+1] = '*';
-       full_path[namelen+2] = 0;  /* trailing null */
-
-       for (temp = direntry; !IS_ROOT(temp);) {
-               namelen -= 1 + temp->d_name.len;
-               if (namelen < 0) {
-                       break;
-               } else {
-                       full_path[namelen] = '\\';
-                       strncpy(full_path + namelen + 1, temp->d_name.name,
-                               temp->d_name.len);
-                       cFYI(0, (" name: %s ", full_path + namelen));
-               }
-               temp = temp->d_parent;
-               if(temp == NULL) {
-                       cERROR(1,("corrupt dentry"));
-                       kfree(full_path);
-                       return NULL;
-               }
-       }
-       if (namelen != 0) {
-               cERROR(1,
-                      ("We did not end path lookup where we expected namelen is %d",
-                       namelen));
-               /* presumably this is only possible if we were racing with a rename 
-               of one of the parent directories  (we can not lock the dentries
-               above us to prevent this, but retrying should be harmless) */
-               kfree(full_path);
-               namelen = 0;
-               goto cifs_bwp_rename_retry;
-       }
-
-       return full_path;
-}
+       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 */
 
@@ -198,24 +145,23 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
                return -ENOMEM;
        }
 
-       if(nd) {
-               if ((nd->intent.open.flags & O_ACCMODE) == O_RDONLY)
-                       desiredAccess = GENERIC_READ;
-               else if ((nd->intent.open.flags & O_ACCMODE) == O_WRONLY) {
-                       desiredAccess = GENERIC_WRITE;
-                       write_only = TRUE;
-               } else if ((nd->intent.open.flags & O_ACCMODE) == O_RDWR) {
-                       /* GENERIC_ALL is too much permission to request */
-                       /* can cause unnecessary access denied on create */
-                       /* desiredAccess = GENERIC_ALL; */
-                       desiredAccess = GENERIC_READ | GENERIC_WRITE;
+       if(nd && (nd->flags & LOOKUP_OPEN)) {
+               int oflags = nd->intent.open.flags;
+
+               desiredAccess = 0;
+               if (oflags & FMODE_READ)
+                       desiredAccess |= GENERIC_READ;
+               if (oflags & FMODE_WRITE) {
+                       desiredAccess |= GENERIC_WRITE;
+                       if (!(oflags & FMODE_READ))
+                               write_only = TRUE;
                }
 
-               if((nd->intent.open.flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
+               if((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
                        disposition = FILE_CREATE;
-               else if((nd->intent.open.flags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
+               else if((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
                        disposition = FILE_OVERWRITE_IF;
-               else if((nd->intent.open.flags & O_CREAT) == O_CREAT)
+               else if((oflags & O_CREAT) == O_CREAT)
                        disposition = FILE_OPEN_IF;
                else {
                        cFYI(1,("Create flag not set in create function"));
@@ -235,7 +181,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
 
        rc = CIFSSMBOpen(xid, pTcon, full_path, disposition,
                         desiredAccess, CREATE_NOT_DIR,
-                        &fileHandle, &oplock, buf, cifs_sb->local_nls);
+                        &fileHandle, &oplock, buf, cifs_sb->local_nls,
+                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
        if (rc) {
                cFYI(1, ("cifs_create returned 0x%x ", rc));
        } else {
@@ -248,13 +195,17 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
                                        (__u64)current->euid,
                                        (__u64)current->egid,
                                        0 /* dev */,
-                                       cifs_sb->local_nls);
+                                       cifs_sb->local_nls, 
+                                       cifs_sb->mnt_cifs_flags & 
+                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
                        } else {
                                CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
                                        (__u64)-1,
                                        (__u64)-1,
                                        0 /* dev */,
-                                       cifs_sb->local_nls);
+                                       cifs_sb->local_nls,
+                                       cifs_sb->mnt_cifs_flags & 
+                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
                        }
                else {
                        /* BB implement via Windows security descriptors */
@@ -356,11 +307,15 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev
                if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
                        rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path,
                                mode,(__u64)current->euid,(__u64)current->egid,
-                               device_number, cifs_sb->local_nls);
+                               device_number, cifs_sb->local_nls,
+                               cifs_sb->mnt_cifs_flags & 
+                                       CIFS_MOUNT_MAP_SPECIAL_CHR);
                } else {
                        rc = CIFSSMBUnixSetPerms(xid, pTcon,
                                full_path, mode, (__u64)-1, (__u64)-1,
-                               device_number, cifs_sb->local_nls);
+                               device_number, cifs_sb->local_nls,
+                               cifs_sb->mnt_cifs_flags & 
+                                       CIFS_MOUNT_MAP_SPECIAL_CHR);
                }
 
                if(!rc) {
@@ -436,7 +391,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
                rc = 0;
                d_add(direntry, NULL);
        } else {
-               cERROR(1,("Error 0x%x or on cifs_get_inode_info in lookup",rc));
+               cERROR(1,("Error 0x%x on cifs_get_inode_info in lookup of %s",
+                          rc,full_path));
                /* BB special case check for Access Denied - watch security 
                exposure of returning dir info implicitly via different rc 
                if file exists or not but no access BB */
@@ -447,36 +403,6 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
        return ERR_PTR(rc);
 }
 
-int
-cifs_dir_open(struct inode *inode, struct file *file)
-{                              /* NB: currently unused since searches are opened in readdir */
-       int rc = 0;
-       int xid;
-       struct cifs_sb_info *cifs_sb;
-       struct cifsTconInfo *pTcon;
-       char *full_path = NULL;
-
-       xid = GetXid();
-
-       cifs_sb = CIFS_SB(inode->i_sb);
-       pTcon = cifs_sb->tcon;
-
-       if(file->f_dentry) {
-               down(&file->f_dentry->d_sb->s_vfs_rename_sem);
-               full_path = build_wildcard_path_from_dentry(file->f_dentry);
-               up(&file->f_dentry->d_sb->s_vfs_rename_sem);
-       } else {
-               FreeXid(xid);
-               return -EIO;
-       }
-
-       cFYI(1, ("inode = 0x%p and full path is %s", inode, full_path));
-
-       kfree(full_path);
-       FreeXid(xid);
-       return rc;
-}
-
 static int
 cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
 {