]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/cifs/file.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/shaggy...
[linux-2.6-omap-h63xx.git] / fs / cifs / file.c
index e9c5ba9084fc6a477ea13fdd26c0a666ddebc2f3..0f05cab5d24ad245ec6f42bf8efa7e44dad58bc2 100644 (file)
 #include <linux/backing-dev.h>
 #include <linux/stat.h>
 #include <linux/fcntl.h>
-#include <linux/mpage.h>
 #include <linux/pagemap.h>
 #include <linux/pagevec.h>
 #include <linux/smp_lock.h>
 #include <linux/writeback.h>
+#include <linux/task_io_accounting_ops.h>
 #include <linux/delay.h>
 #include <asm/div64.h>
 #include "cifsfs.h"
@@ -123,34 +123,34 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file,
        /* if not oplocked, invalidate inode pages if mtime or file
           size changed */
        temp = cifs_NTtimeToUnix(le64_to_cpu(buf->LastWriteTime));
-       if (timespec_equal(&file->f_dentry->d_inode->i_mtime, &temp) && 
-                          (file->f_dentry->d_inode->i_size == 
+       if (timespec_equal(&file->f_path.dentry->d_inode->i_mtime, &temp) &&
+                          (file->f_path.dentry->d_inode->i_size ==
                            (loff_t)le64_to_cpu(buf->EndOfFile))) {
                cFYI(1, ("inode unchanged on server"));
        } else {
-               if (file->f_dentry->d_inode->i_mapping) {
+               if (file->f_path.dentry->d_inode->i_mapping) {
                /* BB no need to lock inode until after invalidate
                   since namei code should already have it locked? */
-                       filemap_write_and_wait(file->f_dentry->d_inode->i_mapping);
+                       filemap_write_and_wait(file->f_path.dentry->d_inode->i_mapping);
                }
                cFYI(1, ("invalidating remote inode since open detected it "
                         "changed"));
-               invalidate_remote_inode(file->f_dentry->d_inode);
+               invalidate_remote_inode(file->f_path.dentry->d_inode);
        }
 
 client_can_cache:
        if (pTcon->ses->capabilities & CAP_UNIX)
-               rc = cifs_get_inode_info_unix(&file->f_dentry->d_inode,
+               rc = cifs_get_inode_info_unix(&file->f_path.dentry->d_inode,
                        full_path, inode->i_sb, xid);
        else
-               rc = cifs_get_inode_info(&file->f_dentry->d_inode,
+               rc = cifs_get_inode_info(&file->f_path.dentry->d_inode,
                        full_path, buf, inode->i_sb, xid);
 
        if ((*oplock & 0xF) == OPLOCK_EXCLUSIVE) {
                pCifsInode->clientCanCacheAll = TRUE;
                pCifsInode->clientCanCacheRead = TRUE;
                cFYI(1, ("Exclusive Oplock granted on inode %p",
-                        file->f_dentry->d_inode));
+                        file->f_path.dentry->d_inode));
        } else if ((*oplock & 0xF) == OPLOCK_READ)
                pCifsInode->clientCanCacheRead = TRUE;
 
@@ -179,7 +179,7 @@ int cifs_open(struct inode *inode, struct file *file)
 
        if (file->f_flags & O_CREAT) {
                /* search inode for this file and fill in file->private_data */
-               pCifsInode = CIFS_I(file->f_dentry->d_inode);
+               pCifsInode = CIFS_I(file->f_path.dentry->d_inode);
                read_lock(&GlobalSMBSeslock);
                list_for_each(tmp, &pCifsInode->openFileList) {
                        pCifsFile = list_entry(tmp, struct cifsFileInfo,
@@ -207,7 +207,7 @@ int cifs_open(struct inode *inode, struct file *file)
                }
        }
 
-       full_path = build_path_from_dentry(file->f_dentry);
+       full_path = build_path_from_dentry(file->f_path.dentry);
        if (full_path == NULL) {
                FreeXid(xid);
                return -ENOMEM;
@@ -292,7 +292,7 @@ int cifs_open(struct inode *inode, struct file *file)
        write_lock(&GlobalSMBSeslock);
        list_add(&pCifsFile->tlist, &pTcon->openFileList);
 
-       pCifsInode = CIFS_I(file->f_dentry->d_inode);
+       pCifsInode = CIFS_I(file->f_path.dentry->d_inode);
        if (pCifsInode) {
                rc = cifs_open_inode_helper(inode, file, pCifsInode,
                                            pCifsFile, pTcon,
@@ -367,7 +367,7 @@ static int cifs_reopen_file(struct inode *inode, struct file *file,
                return 0;
        }
 
-       if (file->f_dentry == NULL) {
+       if (file->f_path.dentry == NULL) {
                up(&pCifsFile->fh_sem);
                cFYI(1, ("failed file reopen, no valid name if dentry freed"));
                FreeXid(xid);
@@ -379,7 +379,7 @@ static int cifs_reopen_file(struct inode *inode, struct file *file,
    those that already have the rename sem can end up causing writepage
    to get called and if the server was down that means we end up here,
    and we can never tell if the caller already has the rename_sem */
-       full_path = build_path_from_dentry(file->f_dentry);
+       full_path = build_path_from_dentry(file->f_path.dentry);
        if (full_path == NULL) {
                up(&pCifsFile->fh_sem);
                FreeXid(xid);
@@ -445,7 +445,7 @@ static int cifs_reopen_file(struct inode *inode, struct file *file,
                                pCifsInode->clientCanCacheAll = TRUE;
                                pCifsInode->clientCanCacheRead = TRUE;
                                cFYI(1, ("Exclusive Oplock granted on inode %p",
-                                        file->f_dentry->d_inode));
+                                        file->f_path.dentry->d_inode));
                        } else if ((oplock & 0xF) == OPLOCK_READ) {
                                pCifsInode->clientCanCacheRead = TRUE;
                                pCifsInode->clientCanCacheAll = FALSE;
@@ -493,10 +493,14 @@ int cifs_close(struct inode *inode, struct file *file)
                                        the struct would be in each open file,
                                        but this should give enough time to 
                                        clear the socket */
-                                       cERROR(1,("close with pending writes"));
+#ifdef CONFIG_CIFS_DEBUG2
+                                       cFYI(1,("close delay, write pending"));
+#endif /* DEBUG2 */
                                        msleep(timeout);
                                        timeout *= 4;
-                               } 
+                               }
+                               if(atomic_read(&pSMBFile->wrtPending))
+                                       cERROR(1,("close with pending writes"));
                                rc = CIFSSMBClose(xid, pTcon,
                                                  pSMBFile->netfid);
                        }
@@ -548,7 +552,7 @@ int cifs_closedir(struct inode *inode, struct file *file)
 
        if (pCFileStruct) {
                struct cifsTconInfo *pTcon;
-               struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_dentry->d_sb);
+               struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
 
                pTcon = cifs_sb->tcon;
 
@@ -661,7 +665,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
        } else
                cFYI(1, ("Unknown type of lock"));
 
-       cifs_sb = CIFS_SB(file->f_dentry->d_sb);
+       cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
        pTcon = cifs_sb->tcon;
 
        if (file->private_data == NULL) {
@@ -752,6 +756,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
                        int stored_rc = 0;
                        struct cifsLockInfo *li, *tmp;
 
+                       rc = 0;
                        down(&fid->lock_sem);
                        list_for_each_entry_safe(li, tmp, &fid->llist, llist) {
                                if (pfLock->fl_start <= li->offset &&
@@ -766,7 +771,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
                                        kfree(li);
                                }
                        }
-               up(&fid->lock_sem);
+                       up(&fid->lock_sem);
                }
        }
 
@@ -787,10 +792,10 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
        int xid, long_op;
        struct cifsFileInfo *open_file;
 
-       if (file->f_dentry == NULL)
+       if (file->f_path.dentry == NULL)
                return -EBADF;
 
-       cifs_sb = CIFS_SB(file->f_dentry->d_sb);
+       cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
        if (cifs_sb == NULL)
                return -EBADF;
 
@@ -798,7 +803,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
 
        /* cFYI(1,
           (" write %d bytes to offset %lld of %s", write_size,
-          *poffset, file->f_dentry->d_name.name)); */
+          *poffset, file->f_path.dentry->d_name.name)); */
 
        if (file->private_data == NULL)
                return -EBADF;
@@ -806,12 +811,12 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
                open_file = (struct cifsFileInfo *) file->private_data;
        
        xid = GetXid();
-       if (file->f_dentry->d_inode == NULL) {
+       if (file->f_path.dentry->d_inode == NULL) {
                FreeXid(xid);
                return -EBADF;
        }
 
-       if (*poffset > file->f_dentry->d_inode->i_size)
+       if (*poffset > file->f_path.dentry->d_inode->i_size)
                long_op = 2; /* writes past end of file can take a long time */
        else
                long_op = 1;
@@ -836,8 +841,8 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
                                        return -EBADF;
                        }
                        if (open_file->invalidHandle) {
-                               if ((file->f_dentry == NULL) ||
-                                   (file->f_dentry->d_inode == NULL)) {
+                               if ((file->f_path.dentry == NULL) ||
+                                   (file->f_path.dentry->d_inode == NULL)) {
                                        FreeXid(xid);
                                        return total_written;
                                }
@@ -845,7 +850,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
                                   filemap_fdatawait from here so tell
                                   reopen_file not to flush data to server
                                   now */
-                               rc = cifs_reopen_file(file->f_dentry->d_inode,
+                               rc = cifs_reopen_file(file->f_path.dentry->d_inode,
                                        file, FALSE);
                                if (rc != 0)
                                        break;
@@ -874,17 +879,17 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
        cifs_stats_bytes_written(pTcon, total_written);
 
        /* since the write may have blocked check these pointers again */
-       if (file->f_dentry) {
-               if (file->f_dentry->d_inode) {
-                       struct inode *inode = file->f_dentry->d_inode;
+       if (file->f_path.dentry) {
+               if (file->f_path.dentry->d_inode) {
+                       struct inode *inode = file->f_path.dentry->d_inode;
                        inode->i_ctime = inode->i_mtime =
                                current_fs_time(inode->i_sb);
                        if (total_written > 0) {
-                               if (*poffset > file->f_dentry->d_inode->i_size)
-                                       i_size_write(file->f_dentry->d_inode,
+                               if (*poffset > file->f_path.dentry->d_inode->i_size)
+                                       i_size_write(file->f_path.dentry->d_inode,
                                        *poffset);
                        }
-                       mark_inode_dirty_sync(file->f_dentry->d_inode);
+                       mark_inode_dirty_sync(file->f_path.dentry->d_inode);
                }
        }
        FreeXid(xid);
@@ -902,17 +907,17 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
        int xid, long_op;
        struct cifsFileInfo *open_file;
 
-       if (file->f_dentry == NULL)
+       if (file->f_path.dentry == NULL)
                return -EBADF;
 
-       cifs_sb = CIFS_SB(file->f_dentry->d_sb);
+       cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
        if (cifs_sb == NULL)
                return -EBADF;
 
        pTcon = cifs_sb->tcon;
 
        cFYI(1,("write %zd bytes to offset %lld of %s", write_size,
-          *poffset, file->f_dentry->d_name.name));
+          *poffset, file->f_path.dentry->d_name.name));
 
        if (file->private_data == NULL)
                return -EBADF;
@@ -920,12 +925,12 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
                open_file = (struct cifsFileInfo *)file->private_data;
        
        xid = GetXid();
-       if (file->f_dentry->d_inode == NULL) {
+       if (file->f_path.dentry->d_inode == NULL) {
                FreeXid(xid);
                return -EBADF;
        }
 
-       if (*poffset > file->f_dentry->d_inode->i_size)
+       if (*poffset > file->f_path.dentry->d_inode->i_size)
                long_op = 2; /* writes past end of file can take a long time */
        else
                long_op = 1;
@@ -951,8 +956,8 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
                                        return -EBADF;
                        }
                        if (open_file->invalidHandle) {
-                               if ((file->f_dentry == NULL) ||
-                                  (file->f_dentry->d_inode == NULL)) {
+                               if ((file->f_path.dentry == NULL) ||
+                                  (file->f_path.dentry->d_inode == NULL)) {
                                        FreeXid(xid);
                                        return total_written;
                                }
@@ -960,7 +965,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
                                   filemap_fdatawait from here so tell
                                   reopen_file not to flush data to 
                                   server now */
-                               rc = cifs_reopen_file(file->f_dentry->d_inode,
+                               rc = cifs_reopen_file(file->f_path.dentry->d_inode,
                                        file, FALSE);
                                if (rc != 0)
                                        break;
@@ -1007,16 +1012,16 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
        cifs_stats_bytes_written(pTcon, total_written);
 
        /* since the write may have blocked check these pointers again */
-       if (file->f_dentry) {
-               if (file->f_dentry->d_inode) {
-                       file->f_dentry->d_inode->i_ctime = 
-                       file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
+       if (file->f_path.dentry) {
+               if (file->f_path.dentry->d_inode) {
+                       file->f_path.dentry->d_inode->i_ctime =
+                       file->f_path.dentry->d_inode->i_mtime = CURRENT_TIME;
                        if (total_written > 0) {
-                               if (*poffset > file->f_dentry->d_inode->i_size)
-                                       i_size_write(file->f_dentry->d_inode, 
+                               if (*poffset > file->f_path.dentry->d_inode->i_size)
+                                       i_size_write(file->f_path.dentry->d_inode,
                                                     *poffset);
                        }
-                       mark_inode_dirty_sync(file->f_dentry->d_inode);
+                       mark_inode_dirty_sync(file->f_path.dentry->d_inode);
                }
        }
        FreeXid(xid);
@@ -1380,7 +1385,7 @@ static int cifs_commit_write(struct file *file, struct page *page,
                                if ((open_file->invalidHandle) && 
                                    (!open_file->closePend)) {
                                        rc = cifs_reopen_file(
-                                               file->f_dentry->d_inode, file);
+                                               file->f_path.dentry->d_inode, file);
                                        if (rc != 0)
                                                break;
                                }
@@ -1430,7 +1435,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
 {
        int xid;
        int rc = 0;
-       struct inode *inode = file->f_dentry->d_inode;
+       struct inode *inode = file->f_path.dentry->d_inode;
 
        xid = GetXid();
 
@@ -1478,7 +1483,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
  */
 int cifs_flush(struct file *file, fl_owner_t id)
 {
-       struct inode * inode = file->f_dentry->d_inode;
+       struct inode * inode = file->f_path.dentry->d_inode;
        int rc = 0;
 
        /* Rather than do the steps manually:
@@ -1515,7 +1520,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
        struct smb_com_read_rsp *pSMBr;
 
        xid = GetXid();
-       cifs_sb = CIFS_SB(file->f_dentry->d_sb);
+       cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
        pTcon = cifs_sb->tcon;
 
        if (file->private_data == NULL) {
@@ -1538,7 +1543,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
                        int buf_type = CIFS_NO_BUFFER;
                        if ((open_file->invalidHandle) && 
                            (!open_file->closePend)) {
-                               rc = cifs_reopen_file(file->f_dentry->d_inode,
+                               rc = cifs_reopen_file(file->f_path.dentry->d_inode,
                                        file, TRUE);
                                if (rc != 0)
                                        break;
@@ -1597,7 +1602,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
        int buf_type = CIFS_NO_BUFFER;
 
        xid = GetXid();
-       cifs_sb = CIFS_SB(file->f_dentry->d_sb);
+       cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
        pTcon = cifs_sb->tcon;
 
        if (file->private_data == NULL) {
@@ -1625,7 +1630,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
                while (rc == -EAGAIN) {
                        if ((open_file->invalidHandle) && 
                            (!open_file->closePend)) {
-                               rc = cifs_reopen_file(file->f_dentry->d_inode,
+                               rc = cifs_reopen_file(file->f_path.dentry->d_inode,
                                        file, TRUE);
                                if (rc != 0)
                                        break;
@@ -1654,7 +1659,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
 
 int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
 {
-       struct dentry *dentry = file->f_dentry;
+       struct dentry *dentry = file->f_path.dentry;
        int rc, xid;
 
        xid = GetXid();
@@ -1740,7 +1745,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
                return -EBADF;
        }
        open_file = (struct cifsFileInfo *)file->private_data;
-       cifs_sb = CIFS_SB(file->f_dentry->d_sb);
+       cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
        pTcon = cifs_sb->tcon;
 
        pagevec_init(&lru_pvec, 0);
@@ -1782,7 +1787,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
                while (rc == -EAGAIN) {
                        if ((open_file->invalidHandle) && 
                            (!open_file->closePend)) {
-                               rc = cifs_reopen_file(file->f_dentry->d_inode,
+                               rc = cifs_reopen_file(file->f_path.dentry->d_inode,
                                        file, TRUE);
                                if (rc != 0)
                                        break;
@@ -1806,15 +1811,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
                }
                if ((rc < 0) || (smb_read_data == NULL)) {
                        cFYI(1, ("Read error in readpages: %d", rc));
-                       /* clean up remaing pages off list */
-                       while (!list_empty(page_list) && (i < num_pages)) {
-                               page = list_entry(page_list->prev, struct page,
-                                                 lru);
-                               list_del(&page->lru);
-                               page_cache_release(page);
-                       }
                        break;
                } else if (bytes_read > 0) {
+                       task_io_account_read(bytes_read);
                        pSMBr = (struct smb_com_read_rsp *)smb_read_data;
                        cifs_copy_cache_pages(mapping, page_list, bytes_read,
                                smb_read_data + 4 /* RFC1001 hdr */ +
@@ -1831,13 +1830,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
                                   this case is ok - if we are at server EOF 
                                   we will hit it on next read */
 
-                       /* while (!list_empty(page_list) && (i < num_pages)) {
-                                       page = list_entry(page_list->prev, 
-                                                         struct page, list);
-                                       list_del(&page->list);
-                                       page_cache_release(page);
-                               }
-                               break; */
+                               /* break; */
                        }
                } else {
                        cFYI(1, ("No bytes read (%d) at offset %lld . "
@@ -1845,14 +1838,6 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
                                 bytes_read, offset));
                        /* BB turn off caching and do new lookup on 
                           file size at server? */
-                       while (!list_empty(page_list) && (i < num_pages)) {
-                               page = list_entry(page_list->prev, struct page,
-                                                 lru);
-                               list_del(&page->lru);
-
-                               /* BB removeme - replace with zero of page? */
-                               page_cache_release(page);
-                       }
                        break;
                }
                if (smb_read_data) {
@@ -1897,8 +1882,8 @@ static int cifs_readpage_worker(struct file *file, struct page *page,
        else
                cFYI(1, ("Bytes read %d",rc));
                                                                                                                            
-       file->f_dentry->d_inode->i_atime =
-               current_fs_time(file->f_dentry->d_inode->i_sb);
+       file->f_path.dentry->d_inode->i_atime =
+               current_fs_time(file->f_path.dentry->d_inode->i_sb);
                                                                                                                            
        if (PAGE_CACHE_SIZE > rc)
                memset(read_data + rc, 0, PAGE_CACHE_SIZE - rc);