CIFS: Create routine find_writable_file to reduce redundant code

Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:
Steve French
2005-10-05 12:23:19 -07:00
parent 04c08816d6
commit 6148a742b2
3 changed files with 50 additions and 119 deletions

View File

@@ -904,6 +904,25 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
return total_written;
}
static struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
{
struct cifsFileInfo *open_file;
read_lock(&GlobalSMBSeslock);
list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
if (open_file->closePend)
continue;
if (open_file->pfile &&
((open_file->pfile->f_flags & O_RDWR) ||
(open_file->pfile->f_flags & O_WRONLY))) {
read_unlock(&GlobalSMBSeslock);
return open_file;
}
}
read_unlock(&GlobalSMBSeslock);
return NULL;
}
static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
{
struct address_space *mapping = page->mapping;
@@ -914,10 +933,7 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
struct inode *inode;
struct cifsInodeInfo *cifsInode;
struct cifsFileInfo *open_file = NULL;
struct list_head *tmp;
struct list_head *tmp1;
struct cifsFileInfo *open_file;
if (!mapping || !mapping->host)
return -EFAULT;
@@ -945,49 +961,19 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
if (mapping->host->i_size - offset < (loff_t)to)
to = (unsigned)(mapping->host->i_size - offset);
cifsInode = CIFS_I(mapping->host);
read_lock(&GlobalSMBSeslock);
/* BB we should start at the end */
list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {
open_file = list_entry(tmp, struct cifsFileInfo, flist);
if (open_file->closePend)
continue;
/* We check if file is open for writing first */
if ((open_file->pfile) &&
((open_file->pfile->f_flags & O_RDWR) ||
(open_file->pfile->f_flags & O_WRONLY))) {
read_unlock(&GlobalSMBSeslock);
bytes_written = cifs_write(open_file->pfile,
write_data, to-from,
&offset);
read_lock(&GlobalSMBSeslock);
open_file = find_writable_file(CIFS_I(mapping->host));
if (open_file) {
bytes_written = cifs_write(open_file->pfile, write_data,
to-from, &offset);
/* Does mm or vfs already set times? */
inode->i_atime =
inode->i_mtime = current_fs_time(inode->i_sb);
if ((bytes_written > 0) && (offset)) {
rc = 0;
} else if (bytes_written < 0) {
if (rc == -EBADF) {
/* have seen a case in which kernel seemed to
have closed/freed a file even with writes
active so we might as well see if there are
other file structs to try for the same
inode before giving up */
continue;
} else
rc = bytes_written;
}
break; /* now that we found a valid file handle and
tried to write to it we are done, no sense
continuing to loop looking for another */
inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb);
if ((bytes_written > 0) && (offset)) {
rc = 0;
} else if (bytes_written < 0) {
if (rc != -EBADF)
rc = bytes_written;
}
if (tmp->next == NULL) {
cFYI(1, ("File instance %p removed", tmp));
break;
}
}
read_unlock(&GlobalSMBSeslock);
if (open_file == NULL) {
} else {
cFYI(1, ("No writeable filehandles for inode"));
rc = -EIO;
}
@@ -1604,40 +1590,12 @@ static int cifs_readpage(struct file *file, struct page *page)
page caching in the current Linux kernel design */
int is_size_safe_to_change(struct cifsInodeInfo *cifsInode)
{
struct list_head *tmp;
struct list_head *tmp1;
struct cifsFileInfo *open_file = NULL;
int rc = TRUE;
if (cifsInode == NULL)
return rc;
read_lock(&GlobalSMBSeslock);
list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {
open_file = list_entry(tmp, struct cifsFileInfo, flist);
if (open_file == NULL)
break;
if (open_file->closePend)
continue;
/* We check if file is open for writing,
BB we could supplement this with a check to see if file size
changes have been flushed to server - ie inode metadata dirty */
if ((open_file->pfile) &&
((open_file->pfile->f_flags & O_RDWR) ||
(open_file->pfile->f_flags & O_WRONLY))) {
rc = FALSE;
break;
}
if (tmp->next == NULL) {
cFYI(1, ("File instance %p removed", tmp));
break;
}
}
read_unlock(&GlobalSMBSeslock);
return rc;
if (cifsInode && find_writable_file(cifsInode))
return 0;
else
return 1;
}
static int cifs_prepare_write(struct file *file, struct page *page,
unsigned from, unsigned to)
{