}
reiserfs_write_lock(inode->i_sb);
- down(&inode->i_sem);
+ mutex_lock(&inode->i_mutex);
/* freeing preallocation only involves relogging blocks that
* are already in the current transaction. preallocation gets
* freed at the end of each transaction, so it is impossible for
err = reiserfs_truncate_file(inode, 0);
}
out:
- up(&inode->i_sem);
+ mutex_unlock(&inode->i_mutex);
reiserfs_write_unlock(inode->i_sb);
return err;
}
allocated_blocks = kmalloc((blocks_to_allocate + will_prealloc) *
sizeof(b_blocknr_t), GFP_NOFS);
+ if (!allocated_blocks)
+ return -ENOMEM;
/* First we compose a key to point at the writing position, we want to do
that outside of any locking region. */
struct reiserfs_transaction_handle th;
th.t_trans_id = 0;
+ /* If a filesystem is converted from 3.5 to 3.6, we'll have v3.5 items
+ * lying around (most of the disk, in fact). Despite the filesystem
+ * now being a v3.6 format, the old items still can't support large
+ * file sizes. Catch this case here, as the rest of the VFS layer is
+ * oblivious to the different limitations between old and new items.
+ * reiserfs_setattr catches this for truncates. This chunk is lifted
+ * from generic_write_checks. */
+ if (get_inode_item_key_version (inode) == KEY_FORMAT_3_5 &&
+ *ppos + count > MAX_NON_LFS) {
+ if (*ppos >= MAX_NON_LFS) {
+ send_sig(SIGXFSZ, current, 0);
+ return -EFBIG;
+ }
+ if (count > MAX_NON_LFS - (unsigned long)*ppos)
+ count = MAX_NON_LFS - (unsigned long)*ppos;
+ }
+
if (file->f_flags & O_DIRECT) { // Direct IO needs treatment
ssize_t result, after_file_end = 0;
if ((*ppos + count >= inode->i_size)
if (unlikely(!access_ok(VERIFY_READ, buf, count)))
return -EFAULT;
- down(&inode->i_sem); // locks the entire file for just us
+ mutex_lock(&inode->i_mutex); // locks the entire file for just us
pos = *ppos;
if (res)
goto out;
- inode_update_time(inode, 1); /* Both mtime and ctime */
+ file_update_time(file);
// Ok, we are done with all the checks.
partially overwritten pages, if needed. And lock the pages,
so that nobody else can access these until we are done.
We get number of actual blocks needed as a result. */
- blocks_to_allocate =
- reiserfs_prepare_file_region_for_write(inode, pos,
- num_pages,
- write_bytes,
- prepared_pages);
- if (blocks_to_allocate < 0) {
- res = blocks_to_allocate;
+ res = reiserfs_prepare_file_region_for_write(inode, pos,
+ num_pages,
+ write_bytes,
+ prepared_pages);
+ if (res < 0) {
reiserfs_release_claimed_blocks(inode->i_sb,
num_pages <<
(PAGE_CACHE_SHIFT -
break;
}
+ blocks_to_allocate = res;
+
/* First we correct our estimate of how many blocks we need */
reiserfs_release_claimed_blocks(inode->i_sb,
(num_pages <<
buf += write_bytes;
*ppos = pos += write_bytes;
count -= write_bytes;
- balance_dirty_pages_ratelimited(inode->i_mapping);
+ balance_dirty_pages_ratelimited_nr(inode->i_mapping, num_pages);
}
/* this is only true on error */
}
}
- if ((file->f_flags & O_SYNC) || IS_SYNC(inode))
- res =
- generic_osync_inode(inode, file->f_mapping,
- OSYNC_METADATA | OSYNC_DATA);
+ if (likely(res >= 0) &&
+ (unlikely((file->f_flags & O_SYNC) || IS_SYNC(inode))))
+ res = generic_osync_inode(inode, file->f_mapping,
+ OSYNC_METADATA | OSYNC_DATA);
- up(&inode->i_sem);
+ mutex_unlock(&inode->i_mutex);
reiserfs_async_progress_wait(inode->i_sb);
return (already_written != 0) ? already_written : res;
out:
- up(&inode->i_sem); // unlock the file on exit.
+ mutex_unlock(&inode->i_mutex); // unlock the file on exit.
return res;
}