X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=fs%2Fcifs%2Ffile.c;h=d62e29fe91f2267bd51f8bbe6800c6b29c2c078a;hb=273d81d6ada951ba99f10b755d6f849dbb352730;hp=5c497c529772a43396a567b515f3927fbe6a1437;hpb=cd5e25d93e6efeb93db7b6731b0a674495270621;p=linux-2.6 diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 5c497c5297..d62e29fe91 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -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; } @@ -199,13 +201,11 @@ int cifs_open(struct inode *inode, struct file *file) } else { if (file->f_flags & O_EXCL) cERROR(1, ("could not find file instance for " - "new file %p ", file)); + "new file %p", 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; @@ -272,7 +272,7 @@ int cifs_open(struct inode *inode, struct file *file) & CIFS_MOUNT_MAP_SPECIAL_CHR); } if (rc) { - cFYI(1, ("cifs_open returned 0x%x ", rc)); + cFYI(1, ("cifs_open returned 0x%x", rc)); goto out; } file->private_data = @@ -409,8 +409,8 @@ static int cifs_reopen_file(struct inode *inode, struct file *file, CIFS_MOUNT_MAP_SPECIAL_CHR); if (rc) { up(&pCifsFile->fh_sem); - cFYI(1, ("cifs_open returned 0x%x ", rc)); - cFYI(1, ("oplock: %d ", oplock)); + cFYI(1, ("cifs_open returned 0x%x", rc)); + cFYI(1, ("oplock: %d", oplock)); } else { pCifsFile->netfid = netfid; pCifsFile->invalidHandle = FALSE; @@ -531,7 +531,7 @@ int cifs_closedir(struct inode *inode, struct file *file) (struct cifsFileInfo *)file->private_data; char *ptmp; - cFYI(1, ("Closedir inode = 0x%p with ", inode)); + cFYI(1, ("Closedir inode = 0x%p", inode)); xid = GetXid(); @@ -605,7 +605,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) } if (pfLock->fl_flags & FL_ACCESS) cFYI(1, ("Process suspended by mandatory locking - " - "not implemented yet ")); + "not implemented yet")); if (pfLock->fl_flags & FL_LEASE) cFYI(1, ("Lease on file - not implemented yet")); if (pfLock->fl_flags & @@ -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) @@ -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? @@ -1367,7 +1377,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync) xid = GetXid(); - cFYI(1, ("Sync file - name: %s datasync: 0x%x ", + cFYI(1, ("Sync file - name: %s datasync: 0x%x", dentry->d_name.name, datasync)); rc = filemap_fdatawrite(inode->i_mapping); @@ -1396,7 +1406,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync) /* fill in rpages then result = cifs_pagein_inode(inode, index, rpages); */ /* BB finish */ -/* cFYI(1, ("rpages is %d for sync page of Index %ld ", rpages, index)); +/* cFYI(1, ("rpages is %d for sync page of Index %ld", rpages, index)); #if 0 if (rc < 0) @@ -1828,7 +1838,7 @@ static int cifs_readpage_worker(struct file *file, struct page *page, if (rc < 0) goto io_error; else - cFYI(1, ("Bytes read %d ",rc)); + cFYI(1, ("Bytes read %d",rc)); file->f_dentry->d_inode->i_atime = current_fs_time(file->f_dentry->d_inode->i_sb); @@ -1949,3 +1959,19 @@ struct address_space_operations cifs_addr_ops = { /* .sync_page = cifs_sync_page, */ /* .direct_IO = */ }; + +/* + * cifs_readpages requires the server to support a buffer large enough to + * contain the header plus one complete page of data. Otherwise, we need + * to leave cifs_readpages out of the address space operations. + */ +struct address_space_operations cifs_addr_ops_smallbuf = { + .readpage = cifs_readpage, + .writepage = cifs_writepage, + .writepages = cifs_writepages, + .prepare_write = cifs_prepare_write, + .commit_write = cifs_commit_write, + .set_page_dirty = __set_page_dirty_nobuffers, + /* .sync_page = cifs_sync_page, */ + /* .direct_IO = */ +};