#include <linux/time.h>
#include <linux/reiserfs_fs.h>
+#include <linux/reiserfs_acl.h>
+#include <linux/reiserfs_xattr.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <linux/pagemap.h>
+#include <linux/swap.h>
#include <linux/writeback.h>
#include <linux/blkdev.h>
#include <linux/buffer_head.h>
+#include <linux/quotaops.h>
/*
** We pack the tails of files on file close, not at the time they are written.
return ( n_err < 0 ) ? -EIO : 0;
}
-int reiserfs_setattr_flags(struct inode *inode, unsigned int flags)
-{
- unsigned int oldflags, newflags;
-
- oldflags = REISERFS_I(inode)->i_flags;
- newflags = oldflags & ~(REISERFS_IMMUTABLE_FL |
- REISERFS_IUNLINK_FL | REISERFS_BARRIER_FL);
- if (flags & ATTR_FLAG_IMMUTABLE)
- newflags |= REISERFS_IMMUTABLE_FL;
- if (flags & ATTR_FLAG_IUNLINK)
- newflags |= REISERFS_IUNLINK_FL;
- if (flags & ATTR_FLAG_BARRIER)
- newflags |= REISERFS_BARRIER_FL;
-
- if (oldflags ^ newflags) {
- REISERFS_I(inode)->i_flags = newflags;
- inode->i_ctime = CURRENT_TIME;
- }
- return 0;
-}
-
-int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
- struct inode *inode = dentry->d_inode ;
- int error ;
-
- reiserfs_write_lock(inode->i_sb);
- if (S_ISDIR(inode->i_mode))
- goto is_dir;
-
- if (attr->ia_valid & ATTR_SIZE) {
- /* version 2 items will be caught by the s_maxbytes check
- ** done for us in vmtruncate
- */
- if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 &&
- attr->ia_size > MAX_NON_LFS) {
- error = -EFBIG ;
- goto out;
- }
- /* fill in hole pointers in the expanding truncate case. */
- if (attr->ia_size > inode->i_size) {
- error = generic_cont_expand(inode, attr->ia_size) ;
- if (REISERFS_I(inode)->i_prealloc_count > 0) {
- struct reiserfs_transaction_handle th ;
- /* we're changing at most 2 bitmaps, inode + super */
- journal_begin(&th, inode->i_sb, 4) ;
- reiserfs_discard_prealloc (&th, inode);
- journal_end(&th, inode->i_sb, 4) ;
- }
- if (error)
- goto out;
- }
- }
-
- if ((((attr->ia_valid & ATTR_UID) && (attr->ia_uid & ~0xffff)) ||
- ((attr->ia_valid & ATTR_GID) && (attr->ia_gid & ~0xffff))) &&
- (get_inode_sd_version (inode) == STAT_DATA_V1)) {
- /* stat data of format v3.5 has 16 bit uid and gid */
- error = -EINVAL;
- goto out;
- }
-
-is_dir:
- error = inode_change_ok(inode, attr) ;
-
- if (!error && attr->ia_valid & ATTR_ATTR_FLAG)
- reiserfs_setattr_flags(inode, attr->ia_attr_flags);
-
- if (!error)
- inode_setattr(inode, attr) ;
-
-out:
- reiserfs_write_unlock(inode->i_sb);
- return error ;
-}
-
/* I really do not want to play with memory shortage right now, so
to simplify the code, we are not going to write more than this much pages at
a time. This still should considerably improve performance compared to 4k
/* Ok, there is existing indirect item already. Need to append it */
/* Calculate position past inserted item */
make_cpu_key( &key, inode, le_key_k_offset( get_inode_item_key_version(inode), &(ih->ih_key)) + op_bytes_number(ih, inode->i_sb->s_blocksize), TYPE_INDIRECT, 3);
- res = reiserfs_paste_into_item( th, &path, &key, (char *)zeros, UNFM_P_SIZE*to_paste);
+ res = reiserfs_paste_into_item( th, &path, &key, inode, (char *)zeros, UNFM_P_SIZE*to_paste);
if ( res ) {
kfree(zeros);
goto error_exit_free_blocks;
if ( res != ITEM_NOT_FOUND ) {
/* item should not exist, otherwise we have error */
if ( res != -ENOSPC ) {
- reiserfs_warning ("green-9008: search_by_key (%K) returned %d\n",
- &key, res);
+ reiserfs_warning (inode->i_sb,
+ "green-9008: search_by_key (%K) returned %d",
+ &key, res);
}
res = -EIO;
kfree(zeros);
goto error_exit_free_blocks;
}
- res = reiserfs_insert_item( th, &path, &key, &ins_ih, (char *)zeros);
+ res = reiserfs_insert_item( th, &path, &key, &ins_ih, inode, (char *)zeros);
} else {
reiserfs_panic(inode->i_sb, "green-9011: Unexpected key type %K\n", &key);
}
// position. We do not need to recalculate path as it should
// already point to correct place.
make_cpu_key( &key, inode, le_key_k_offset( get_inode_item_key_version(inode), &(ih->ih_key)) + op_bytes_number(ih, inode->i_sb->s_blocksize), TYPE_INDIRECT, 3);
- res = reiserfs_paste_into_item( th, &path, &key, (char *)(allocated_blocks+curr_block), UNFM_P_SIZE*(blocks_to_allocate-curr_block));
+ res = reiserfs_paste_into_item( th, &path, &key, inode, (char *)(allocated_blocks+curr_block), UNFM_P_SIZE*(blocks_to_allocate-curr_block));
if ( res ) {
goto error_exit_free_blocks;
}
/* Well, if we have found such item already, or some error
occured, we need to warn user and return error */
if ( res != -ENOSPC ) {
- reiserfs_warning ("green-9009: search_by_key (%K) returned %d\n",
- &key, res);
+ reiserfs_warning (inode->i_sb,
+ "green-9009: search_by_key (%K) "
+ "returned %d", &key, res);
}
res = -EIO;
goto error_exit_free_blocks;
}
/* Insert item into the tree with the data as its body */
- res = reiserfs_insert_item( th, &path, &key, &ins_ih, (char *)(allocated_blocks+curr_block));
+ res = reiserfs_insert_item( th, &path, &key, &ins_ih, inode, (char *)(allocated_blocks+curr_block));
} else {
reiserfs_panic(inode->i_sb, "green-9010: unexpected item type for key %K\n",&key);
}
// unless we return an error, they are also responsible for logging
// the inode.
//
- inode->i_blocks += blocks_to_allocate << (inode->i_blkbits - 9);
pathrelse(&path);
reiserfs_write_unlock(inode->i_sb);
pathrelse(&path);
// free blocks
for( i = 0; i < blocks_to_allocate; i++ )
- reiserfs_free_block(th, le32_to_cpu(allocated_blocks[i]));
+ reiserfs_free_block(th, inode, le32_to_cpu(allocated_blocks[i]), 1);
error_exit:
reiserfs_update_sd(th, inode); // update any changes we made to blk count
array to
prepared pages
*/
- const char *buf /* Pointer to user-supplied
+ const char __user *buf /* Pointer to user-supplied
data*/
)
{
// we only remember error status to report it on
// exit.
write_bytes-=count;
- SetPageReferenced(page);
- unlock_page(page); // We unlock the page as it was locked by earlier call
- // to grab_cache_page
- page_cache_release(page);
}
/* now that we've gotten all the ordered buffers marked dirty,
* we can safely update i_size and close any running transaction
reiserfs_write_unlock(inode->i_sb);
}
th->t_trans_id = 0;
+
+ /*
+ * we have to unlock the pages after updating i_size, otherwise
+ * we race with writepage
+ */
+ for ( i = 0; i < num_pages ; i++) {
+ struct page *page=prepared_pages[i];
+ unlock_page(page);
+ mark_page_accessed(page);
+ page_cache_release(page);
+ }
return retval;
}
if ( num_pages < 1 ) {
- reiserfs_warning("green-9001: reiserfs_prepare_file_region_for_write called with zero number of pages to process\n");
+ reiserfs_warning (inode->i_sb,
+ "green-9001: reiserfs_prepare_file_region_for_write "
+ "called with zero number of pages to process");
return -EFAULT;
}
*/
ssize_t reiserfs_file_write( struct file *file, /* the file we are going to write into */
- const char *buf, /* pointer to user supplied data
+ const char __user *buf, /* pointer to user supplied data
(in userspace) */
size_t count, /* amount of bytes to write */
loff_t *ppos /* pointer to position in file that we start writing at. Should be updated to
struct inode_operations reiserfs_file_inode_operations = {
.truncate = reiserfs_vfs_truncate_file,
.setattr = reiserfs_setattr,
+ .setxattr = reiserfs_setxattr,
+ .getxattr = reiserfs_getxattr,
+ .listxattr = reiserfs_listxattr,
+ .removexattr = reiserfs_removexattr,
+ .permission = reiserfs_permission,
};