Merge branch 'omap-boards' into omap-for-linus
[pandora-kernel.git] / fs / ocfs2 / file.c
index 558ce03..a5fbd9c 100644 (file)
@@ -107,6 +107,9 @@ static int ocfs2_file_open(struct inode *inode, struct file *file)
        mlog_entry("(0x%p, 0x%p, '%.*s')\n", inode, file,
                   file->f_path.dentry->d_name.len, file->f_path.dentry->d_name.name);
 
+       if (file->f_mode & FMODE_WRITE)
+               dquot_initialize(inode);
+
        spin_lock(&oi->ip_lock);
 
        /* Check that the inode hasn't been wiped from disk by another
@@ -629,11 +632,10 @@ restart_all:
        }
 
 restarted_transaction:
-       if (vfs_dq_alloc_space_nodirty(inode, ocfs2_clusters_to_bytes(osb->sb,
-           clusters_to_add))) {
-               status = -EDQUOT;
+       status = dquot_alloc_space_nodirty(inode,
+                       ocfs2_clusters_to_bytes(osb->sb, clusters_to_add));
+       if (status)
                goto leave;
-       }
        did_quota = 1;
 
        /* reserve a write to the file entry early on - that we if we
@@ -674,7 +676,7 @@ restarted_transaction:
        clusters_to_add -= (OCFS2_I(inode)->ip_clusters - prev_clusters);
        spin_unlock(&OCFS2_I(inode)->ip_lock);
        /* Release unused quota reservation */
-       vfs_dq_free_space(inode,
+       dquot_free_space(inode,
                        ocfs2_clusters_to_bytes(osb->sb, clusters_to_add));
        did_quota = 0;
 
@@ -682,6 +684,7 @@ restarted_transaction:
                if (why == RESTART_META) {
                        mlog(0, "restarting function.\n");
                        restart_func = 1;
+                       status = 0;
                } else {
                        BUG_ON(why != RESTART_TRANS);
 
@@ -710,7 +713,7 @@ restarted_transaction:
 
 leave:
        if (status < 0 && did_quota)
-               vfs_dq_free_space(inode,
+               dquot_free_space(inode,
                        ocfs2_clusters_to_bytes(osb->sb, clusters_to_add));
        if (handle) {
                ocfs2_commit_trans(osb, handle);
@@ -978,6 +981,8 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
 
        size_change = S_ISREG(inode->i_mode) && attr->ia_valid & ATTR_SIZE;
        if (size_change) {
+               dquot_initialize(inode);
+
                status = ocfs2_rw_lock(inode, 1);
                if (status < 0) {
                        mlog_errno(status);
@@ -993,10 +998,9 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
        }
 
        if (size_change && attr->ia_size != i_size_read(inode)) {
-               if (attr->ia_size > sb->s_maxbytes) {
-                       status = -EFBIG;
+               status = inode_newsize_ok(inode, attr->ia_size);
+               if (status)
                        goto bail_unlock;
-               }
 
                if (i_size_read(inode) > attr->ia_size) {
                        if (ocfs2_should_order_data(inode)) {
@@ -1021,7 +1025,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
                /*
                 * Gather pointers to quota structures so that allocation /
                 * freeing of quota structures happens here and not inside
-                * vfs_dq_transfer() where we have problems with lock ordering
+                * dquot_transfer() where we have problems with lock ordering
                 */
                if (attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid
                    && OCFS2_HAS_RO_COMPAT_FEATURE(sb,
@@ -1054,7 +1058,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
                        mlog_errno(status);
                        goto bail_unlock;
                }
-               status = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0;
+               status = dquot_transfer(inode, attr);
                if (status < 0)
                        goto bail_commit;
        } else {
@@ -1836,6 +1840,8 @@ static int ocfs2_prepare_inode_for_write(struct dentry *dentry,
                                                               &meta_level);
                        if (has_refcount)
                                *has_refcount = 1;
+                       if (direct_io)
+                               *direct_io = 0;
                }
 
                if (ret < 0) {
@@ -1859,10 +1865,6 @@ static int ocfs2_prepare_inode_for_write(struct dentry *dentry,
                        break;
                }
 
-               if (has_refcount && *has_refcount == 1) {
-                       *direct_io = 0;
-                       break;
-               }
                /*
                 * Allowing concurrent direct writes means
                 * i_size changes wouldn't be synchronized, so
@@ -1980,18 +1982,18 @@ relock:
        /* communicate with ocfs2_dio_end_io */
        ocfs2_iocb_set_rw_locked(iocb, rw_level);
 
-       if (direct_io) {
-               ret = generic_segment_checks(iov, &nr_segs, &ocount,
-                                            VERIFY_READ);
-               if (ret)
-                       goto out_dio;
+       ret = generic_segment_checks(iov, &nr_segs, &ocount,
+                                    VERIFY_READ);
+       if (ret)
+               goto out_dio;
 
-               count = ocount;
-               ret = generic_write_checks(file, ppos, &count,
-                                          S_ISBLK(inode->i_mode));
-               if (ret)
-                       goto out_dio;
+       count = ocount;
+       ret = generic_write_checks(file, ppos, &count,
+                                  S_ISBLK(inode->i_mode));
+       if (ret)
+               goto out_dio;
 
+       if (direct_io) {
                written = generic_file_direct_write(iocb, iov, &nr_segs, *ppos,
                                                    ppos, count, ocount);
                if (written < 0) {
@@ -2006,7 +2008,10 @@ relock:
                        goto out_dio;
                }
        } else {
-               written = __generic_file_aio_write(iocb, iov, nr_segs, ppos);
+               current->backing_dev_info = file->f_mapping->backing_dev_info;
+               written = generic_file_buffered_write(iocb, iov, nr_segs, *ppos,
+                                                     ppos, count, 0);
+               current->backing_dev_info = NULL;
        }
 
 out_dio:
@@ -2020,9 +2025,9 @@ out_dio:
                if (ret < 0)
                        written = ret;
 
-               if (!ret && (old_size != i_size_read(inode) ||
-                   old_clusters != OCFS2_I(inode)->ip_clusters ||
-                   has_refcount)) {
+               if (!ret && ((old_size != i_size_read(inode)) ||
+                            (old_clusters != OCFS2_I(inode)->ip_clusters) ||
+                            has_refcount)) {
                        ret = jbd2_journal_force_commit(osb->journal->j_journal);
                        if (ret < 0)
                                written = ret;
@@ -2043,7 +2048,7 @@ out_dio:
         * async dio is going to do it in the future or an end_io after an
         * error has already done it.
         */
-       if (ret == -EIOCBQUEUED || !ocfs2_iocb_is_rw_locked(iocb)) {
+       if ((ret == -EIOCBQUEUED) || (!ocfs2_iocb_is_rw_locked(iocb))) {
                rw_level = -1;
                have_alloc_sem = 0;
        }