]> err.no Git - linux-2.6/blobdiff - fs/cifs/file.c
[PATCH] writeback: fix range handling
[linux-2.6] / fs / cifs / file.c
index 5c497c529772a43396a567b515f3927fbe6a1437..487ea8b3baaa4f512db3b802b7329e79a7f94d00 100644 (file)
@@ -84,6 +84,8 @@ static inline int cifs_get_disposition(unsigned int flags)
                return FILE_OVERWRITE_IF;
        else if ((flags & O_CREAT) == O_CREAT)
                return FILE_OPEN_IF;
+       else if ((flags & O_TRUNC) == O_TRUNC)
+               return FILE_OVERWRITE;
        else
                return FILE_OPEN;
 }
@@ -203,9 +205,7 @@ int cifs_open(struct inode *inode, struct file *file)
                }
        }
 
-       mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(file->f_dentry);
-       mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
        if (full_path == NULL) {
                FreeXid(xid);
                return -ENOMEM;
@@ -658,7 +658,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
                        else
                                posix_lock_type = CIFS_WRLCK;
                        rc = CIFSSMBPosixLock(xid, pTcon, netfid, 1 /* get */,
-                                       length, pfLock->fl_start,
+                                       length, pfLock,
                                        posix_lock_type, wait_flag);
                        FreeXid(xid);
                        return rc;
@@ -706,7 +706,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
                        return -EOPNOTSUPP;
                }
                rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */,
-                                     length, pfLock->fl_start,
+                                     length, pfLock,
                                      posix_lock_type, wait_flag);
        } else
                rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start,
@@ -906,9 +906,10 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
                                if (rc != 0)
                                        break;
                        }
-                       /* BB FIXME We can not sign across two buffers yet */
-                       if((pTcon->ses->server->secMode & 
-                        (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0) {
+                       if(experimEnabled || (pTcon->ses->server &&
+                               ((pTcon->ses->server->secMode & 
+                               (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
+                               == 0))) {
                                struct kvec iov[2];
                                unsigned int len;
 
@@ -923,13 +924,13 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
                                                *poffset, &bytes_written,
                                                iov, 1, long_op);
                        } else
-                       /* BB FIXME fixup indentation of line below */
-                       rc = CIFSSMBWrite(xid, pTcon,
-                                open_file->netfid,
-                                min_t(const int, cifs_sb->wsize, 
-                                      write_size - total_written),
-                                *poffset, &bytes_written,
-                                write_data + total_written, NULL, long_op);
+                               rc = CIFSSMBWrite(xid, pTcon,
+                                        open_file->netfid,
+                                        min_t(const int, cifs_sb->wsize,
+                                              write_size - total_written),
+                                        *poffset, &bytes_written,
+                                        write_data + total_written,
+                                        NULL, long_op);
                }
                if (rc || (bytes_written == 0)) {
                        if (total_written)
@@ -968,6 +969,16 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
        struct cifsFileInfo *open_file;
        int rc;
 
+       /* Having a null inode here (because mapping->host was set to zero by
+       the VFS or MM) should not happen but we had reports of on oops (due to
+       it being zero) during stress testcases so we need to check for it */
+
+       if(cifs_inode == NULL) {
+               cERROR(1,("Null inode passed to cifs_writeable_file"));
+               dump_stack();
+               return NULL;
+       }
+
        read_lock(&GlobalSMBSeslock);
        list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
                if (open_file->closePend)
@@ -1068,9 +1079,9 @@ static int cifs_writepages(struct address_space *mapping,
        unsigned int bytes_written;
        struct cifs_sb_info *cifs_sb;
        int done = 0;
-       pgoff_t end = -1;
+       pgoff_t end;
        pgoff_t index;
-       int is_range = 0;
+       int range_whole = 0;
        struct kvec iov[32];
        int len;
        int n_iov = 0;
@@ -1093,12 +1104,11 @@ static int cifs_writepages(struct address_space *mapping,
        if (cifs_sb->wsize < PAGE_CACHE_SIZE)
                return generic_writepages(mapping, wbc);
 
-       /* BB FIXME we do not have code to sign across multiple buffers yet,
-          so go to older writepage style write which we can sign if needed */
        if((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server))
                if(cifs_sb->tcon->ses->server->secMode &
                           (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
-                       return generic_writepages(mapping, wbc);
+                       if(!experimEnabled)
+                               return generic_writepages(mapping, wbc);
 
        /*
         * BB: Is this meaningful for a non-block-device file system?
@@ -1112,16 +1122,14 @@ static int cifs_writepages(struct address_space *mapping,
        xid = GetXid();
 
        pagevec_init(&pvec, 0);
-       if (wbc->sync_mode == WB_SYNC_NONE)
+       if (wbc->range_cyclic) {
                index = mapping->writeback_index; /* Start from prev offset */
-       else {
-               index = 0;
-               scanned = 1;
-       }
-       if (wbc->start || wbc->end) {
-               index = wbc->start >> PAGE_CACHE_SHIFT;
-               end = wbc->end >> PAGE_CACHE_SHIFT;
-               is_range = 1;
+               end = -1;
+       } else {
+               index = wbc->range_start >> PAGE_CACHE_SHIFT;
+               end = wbc->range_end >> PAGE_CACHE_SHIFT;
+               if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
+                       range_whole = 1;
                scanned = 1;
        }
 retry:
@@ -1157,7 +1165,7 @@ retry:
                                break;
                        }
 
-                       if (unlikely(is_range) && (page->index > end)) {
+                       if (!wbc->range_cyclic && page->index > end) {
                                done = 1;
                                unlock_page(page);
                                break;
@@ -1261,7 +1269,7 @@ retry:
                index = 0;
                goto retry;
        }
-       if (!is_range)
+       if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
                mapping->writeback_index = index;
 
        FreeXid(xid);