]> err.no Git - linux-2.6/blobdiff - fs/cifs/file.c
Merge master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb
[linux-2.6] / fs / cifs / file.c
index 670ec1e84da081b668a0f1a712ed30c9192da21d..165d67426381df8aa814ba904266b2b227da1980 100644 (file)
@@ -127,8 +127,7 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file,
                if (file->f_dentry->d_inode->i_mapping) {
                /* BB no need to lock inode until after invalidate
                   since namei code should already have it locked? */
-                       filemap_fdatawrite(file->f_dentry->d_inode->i_mapping);
-                       filemap_fdatawait(file->f_dentry->d_inode->i_mapping);
+                       filemap_write_and_wait(file->f_dentry->d_inode->i_mapping);
                }
                cFYI(1, ("invalidating remote inode since open detected it "
                         "changed"));
@@ -204,9 +203,9 @@ int cifs_open(struct inode *inode, struct file *file)
                }
        }
 
-       down(&inode->i_sb->s_vfs_rename_sem);
+       mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(file->f_dentry);
-       up(&inode->i_sb->s_vfs_rename_sem);
+       mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
        if (full_path == NULL) {
                FreeXid(xid);
                return -ENOMEM;
@@ -419,8 +418,7 @@ static int cifs_reopen_file(struct inode *inode, struct file *file,
                pCifsInode = CIFS_I(inode);
                if (pCifsInode) {
                        if (can_flush) {
-                               filemap_fdatawrite(inode->i_mapping);
-                               filemap_fdatawait(inode->i_mapping);
+                               filemap_write_and_wait(inode->i_mapping);
                        /* temporarily disable caching while we
                           go to server to get inode info */
                                pCifsInode->clientCanCacheAll = FALSE;
@@ -1192,7 +1190,6 @@ retry:
                                        /* BB what if continued retry is
                                           requested via mount flags? */
                                        set_bit(AS_EIO, &mapping->flags);
-                                       SetPageError(page);
                                } else {
                                        cifs_stats_bytes_written(cifs_sb->tcon,
                                                                 bytes_written);
@@ -1200,6 +1197,13 @@ retry:
                        }
                        for (i = 0; i < n_iov; i++) {
                                page = pvec.pages[first + i];
+                               /* Should we also set page error on
+                               success rc but too little data written? */
+                               /* BB investigate retry logic on temporary
+                               server crash cases and how recovery works
+                               when page marked as error */ 
+                               if(rc)
+                                       SetPageError(page);
                                kunmap(page);
                                unlock_page(page);
                                page_cache_release(page);
@@ -1438,13 +1442,15 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
                                         &bytes_read, &smb_read_data,
                                         &buf_type);
                        pSMBr = (struct smb_com_read_rsp *)smb_read_data;
-                       if (copy_to_user(current_offset, 
-                                        smb_read_data + 4 /* RFC1001 hdr */
-                                        + le16_to_cpu(pSMBr->DataOffset), 
-                                        bytes_read)) {
-                               rc = -EFAULT;
-                       }
                        if (smb_read_data) {
+                               if (copy_to_user(current_offset,
+                                               smb_read_data +
+                                               4 /* RFC1001 length field */ +
+                                               le16_to_cpu(pSMBr->DataOffset),
+                                               bytes_read)) {
+                                       rc = -EFAULT;
+                               }
+
                                if(buf_type == CIFS_SMALL_BUFFER)
                                        cifs_small_buf_release(smb_read_data);
                                else if(buf_type == CIFS_LARGE_BUFFER)
@@ -1756,7 +1762,10 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
 
 /* need to free smb_read_data buf before exit */
        if (smb_read_data) {
-               cifs_buf_release(smb_read_data);
+               if(buf_type == CIFS_SMALL_BUFFER)
+                       cifs_small_buf_release(smb_read_data);
+               else if(buf_type == CIFS_LARGE_BUFFER)
+                       cifs_buf_release(smb_read_data);
                smb_read_data = NULL;
        }