]> err.no Git - linux-2.6/blobdiff - fs/cifs/dir.c
[CIFS] Fix setattr of mode only (e.g. in some chmod cases) to Windows
[linux-2.6] / fs / cifs / dir.c
index cf90c9ad2c870f1dd1b02fce8fcee2da74a717c0..16b21522e8fe1bbd06a97a7da2297e38cc8056d3 100644 (file)
@@ -146,24 +146,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"));
@@ -293,7 +292,8 @@ cifs_create_out:
        return rc;
 }
 
-int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t device_number) 
+int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, 
+               dev_t device_number) 
 {
        int rc = -EPERM;
        int xid;
@@ -369,7 +369,34 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev
 
                        if(!rc) {
                                /* BB Do not bother to decode buf since no
-                                  local inode yet to put timestamps in */
+                                  local inode yet to put timestamps in,
+                                  but we can reuse it safely */
+                               int bytes_written;
+                               struct win_dev *pdev;
+                               pdev = (struct win_dev *)buf;
+                               if(S_ISCHR(mode)) {
+                                       memcpy(pdev->type, "IntxCHR", 8);
+                                       pdev->major =
+                                             cpu_to_le64(MAJOR(device_number));
+                                       pdev->minor = 
+                                             cpu_to_le64(MINOR(device_number));
+                                       rc = CIFSSMBWrite(xid, pTcon,
+                                               fileHandle,
+                                               sizeof(struct win_dev),
+                                               0, &bytes_written, (char *)pdev,
+                                               NULL, 0);
+                               } else if(S_ISBLK(mode)) {
+                                       memcpy(pdev->type, "IntxBLK", 8);
+                                       pdev->major =
+                                             cpu_to_le64(MAJOR(device_number));
+                                       pdev->minor =
+                                             cpu_to_le64(MINOR(device_number));
+                                       rc = CIFSSMBWrite(xid, pTcon,
+                                               fileHandle,
+                                               sizeof(struct win_dev),
+                                               0, &bytes_written, (char *)pdev,
+                                               NULL, 0);
+                               } /* else if(S_ISFIFO */
                                CIFSSMBClose(xid, pTcon, fileHandle);
                                d_drop(direntry);
                        }