[CIFS] fix small memory leak in an error path in new posix mkdir
[cascardo/linux.git] / fs / cifs / inode.c
index dd41677..9dffa93 100644 (file)
@@ -919,6 +919,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
                        goto mkdir_out;
                }
 
+               mode &= ~current->fs->umask;
                rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT,
                                mode, NULL /* netfid */, pInfo, &oplock,
                                full_path, cifs_sb->local_nls,
@@ -929,8 +930,10 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
                        d_drop(direntry);
                } else {
                        int obj_type;
-                       if (pInfo->Type == -1) /* no return info - go query */
+                       if (pInfo->Type == -1) /* no return info - go query */ {
+                               kfree(pInfo);
                                goto mkdir_get_info;
+                       }
 /*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need
        to set uid/gid */
                        inc_nlink(inode);
@@ -940,8 +943,10 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
                                direntry->d_op = &cifs_dentry_ops;
 
                        newinode = new_inode(inode->i_sb);
-                       if (newinode == NULL)
+                       if (newinode == NULL) {
+                               kfree(pInfo);
                                goto mkdir_get_info;
+                       }
                        /* Is an i_ino of zero legal? */
                        /* Are there sanity checks we can use to ensure that
                           the server is really filling in that field? */
@@ -1377,8 +1382,17 @@ static int cifs_vmtruncate(struct inode *inode, loff_t offset)
        }
        i_size_write(inode, offset);
        spin_unlock(&inode->i_lock);
+       /*
+        * unmap_mapping_range is called twice, first simply for efficiency
+        * so that truncate_inode_pages does fewer single-page unmaps. However
+        * after this first call, and before truncate_inode_pages finishes,
+        * it is possible for private pages to be COWed, which remain after
+        * truncate_inode_pages finishes, hence the second unmap_mapping_range
+        * call must be made for correctness.
+        */
        unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
        truncate_inode_pages(mapping, offset);
+       unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
        goto out_truncate;
 
 do_expand:
@@ -1469,7 +1483,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
                        atomic_dec(&open_file->wrtPending);
                        cFYI(1, ("SetFSize for attrs rc = %d", rc));
                        if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
-                               int bytes_written;
+                               unsigned int bytes_written;
                                rc = CIFSSMBWrite(xid, pTcon,
                                                  nfid, 0, attrs->ia_size,
                                                  &bytes_written, NULL, NULL,
@@ -1502,7 +1516,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
                                        cifs_sb->mnt_cifs_flags &
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
                                if (rc == 0) {
-                                       int bytes_written;
+                                       unsigned int bytes_written;
                                        rc = CIFSSMBWrite(xid, pTcon,
                                                        netfid, 0,
                                                        attrs->ia_size,