aboutsummaryrefslogtreecommitdiffstats
path: root/fs/reiserfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/reiserfs/inode.c')
-rw-r--r--fs/reiserfs/inode.c44
1 files changed, 34 insertions, 10 deletions
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 3a28e7751b3c..2df0f5c7c60b 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -31,11 +31,12 @@ void reiserfs_delete_inode(struct inode *inode)
31 JOURNAL_PER_BALANCE_CNT * 2 + 31 JOURNAL_PER_BALANCE_CNT * 2 +
32 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb); 32 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb);
33 struct reiserfs_transaction_handle th; 33 struct reiserfs_transaction_handle th;
34 int depth;
34 int err; 35 int err;
35 36
36 truncate_inode_pages(&inode->i_data, 0); 37 truncate_inode_pages(&inode->i_data, 0);
37 38
38 reiserfs_write_lock(inode->i_sb); 39 depth = reiserfs_write_lock_once(inode->i_sb);
39 40
40 /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */ 41 /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */
41 if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */ 42 if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */
@@ -74,7 +75,7 @@ void reiserfs_delete_inode(struct inode *inode)
74 out: 75 out:
75 clear_inode(inode); /* note this must go after the journal_end to prevent deadlock */ 76 clear_inode(inode); /* note this must go after the journal_end to prevent deadlock */
76 inode->i_blocks = 0; 77 inode->i_blocks = 0;
77 reiserfs_write_unlock(inode->i_sb); 78 reiserfs_write_unlock_once(inode->i_sb, depth);
78} 79}
79 80
80static void _make_cpu_key(struct cpu_key *key, int version, __u32 dirid, 81static void _make_cpu_key(struct cpu_key *key, int version, __u32 dirid,
@@ -1496,9 +1497,11 @@ struct inode *reiserfs_iget(struct super_block *s, const struct cpu_key *key)
1496 1497
1497 args.objectid = key->on_disk_key.k_objectid; 1498 args.objectid = key->on_disk_key.k_objectid;
1498 args.dirid = key->on_disk_key.k_dir_id; 1499 args.dirid = key->on_disk_key.k_dir_id;
1500 reiserfs_write_unlock(s);
1499 inode = iget5_locked(s, key->on_disk_key.k_objectid, 1501 inode = iget5_locked(s, key->on_disk_key.k_objectid,
1500 reiserfs_find_actor, reiserfs_init_locked_inode, 1502 reiserfs_find_actor, reiserfs_init_locked_inode,
1501 (void *)(&args)); 1503 (void *)(&args));
1504 reiserfs_write_lock(s);
1502 if (!inode) 1505 if (!inode)
1503 return ERR_PTR(-ENOMEM); 1506 return ERR_PTR(-ENOMEM);
1504 1507
@@ -2538,6 +2541,12 @@ static int reiserfs_writepage(struct page *page, struct writeback_control *wbc)
2538 return reiserfs_write_full_page(page, wbc); 2541 return reiserfs_write_full_page(page, wbc);
2539} 2542}
2540 2543
2544static void reiserfs_truncate_failed_write(struct inode *inode)
2545{
2546 truncate_inode_pages(inode->i_mapping, inode->i_size);
2547 reiserfs_truncate_file(inode, 0);
2548}
2549
2541static int reiserfs_write_begin(struct file *file, 2550static int reiserfs_write_begin(struct file *file,
2542 struct address_space *mapping, 2551 struct address_space *mapping,
2543 loff_t pos, unsigned len, unsigned flags, 2552 loff_t pos, unsigned len, unsigned flags,
@@ -2604,6 +2613,8 @@ static int reiserfs_write_begin(struct file *file,
2604 if (ret) { 2613 if (ret) {
2605 unlock_page(page); 2614 unlock_page(page);
2606 page_cache_release(page); 2615 page_cache_release(page);
2616 /* Truncate allocated blocks */
2617 reiserfs_truncate_failed_write(inode);
2607 } 2618 }
2608 return ret; 2619 return ret;
2609} 2620}
@@ -2701,9 +2712,7 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
2701 ** transaction tracking stuff when the size changes. So, we have 2712 ** transaction tracking stuff when the size changes. So, we have
2702 ** to do the i_size updates here. 2713 ** to do the i_size updates here.
2703 */ 2714 */
2704 pos += copied; 2715 if (pos + copied > inode->i_size) {
2705
2706 if (pos > inode->i_size) {
2707 struct reiserfs_transaction_handle myth; 2716 struct reiserfs_transaction_handle myth;
2708 lock_depth = reiserfs_write_lock_once(inode->i_sb); 2717 lock_depth = reiserfs_write_lock_once(inode->i_sb);
2709 locked = true; 2718 locked = true;
@@ -2721,7 +2730,7 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
2721 goto journal_error; 2730 goto journal_error;
2722 2731
2723 reiserfs_update_inode_transaction(inode); 2732 reiserfs_update_inode_transaction(inode);
2724 inode->i_size = pos; 2733 inode->i_size = pos + copied;
2725 /* 2734 /*
2726 * this will just nest into our transaction. It's important 2735 * this will just nest into our transaction. It's important
2727 * to use mark_inode_dirty so the inode gets pushed around on the 2736 * to use mark_inode_dirty so the inode gets pushed around on the
@@ -2751,6 +2760,10 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
2751 reiserfs_write_unlock_once(inode->i_sb, lock_depth); 2760 reiserfs_write_unlock_once(inode->i_sb, lock_depth);
2752 unlock_page(page); 2761 unlock_page(page);
2753 page_cache_release(page); 2762 page_cache_release(page);
2763
2764 if (pos + len > inode->i_size)
2765 reiserfs_truncate_failed_write(inode);
2766
2754 return ret == 0 ? copied : ret; 2767 return ret == 0 ? copied : ret;
2755 2768
2756 journal_error: 2769 journal_error:
@@ -3051,13 +3064,14 @@ static ssize_t reiserfs_direct_IO(int rw, struct kiocb *iocb,
3051int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) 3064int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
3052{ 3065{
3053 struct inode *inode = dentry->d_inode; 3066 struct inode *inode = dentry->d_inode;
3054 int error;
3055 unsigned int ia_valid; 3067 unsigned int ia_valid;
3068 int depth;
3069 int error;
3056 3070
3057 /* must be turned off for recursive notify_change calls */ 3071 /* must be turned off for recursive notify_change calls */
3058 ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID); 3072 ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID);
3059 3073
3060 reiserfs_write_lock(inode->i_sb); 3074 depth = reiserfs_write_lock_once(inode->i_sb);
3061 if (attr->ia_valid & ATTR_SIZE) { 3075 if (attr->ia_valid & ATTR_SIZE) {
3062 /* version 2 items will be caught by the s_maxbytes check 3076 /* version 2 items will be caught by the s_maxbytes check
3063 ** done for us in vmtruncate 3077 ** done for us in vmtruncate
@@ -3138,8 +3152,17 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
3138 journal_end(&th, inode->i_sb, jbegin_count); 3152 journal_end(&th, inode->i_sb, jbegin_count);
3139 } 3153 }
3140 } 3154 }
3141 if (!error) 3155 if (!error) {
3156 /*
3157 * Relax the lock here, as it might truncate the
3158 * inode pages and wait for inode pages locks.
3159 * To release such page lock, the owner needs the
3160 * reiserfs lock
3161 */
3162 reiserfs_write_unlock_once(inode->i_sb, depth);
3142 error = inode_setattr(inode, attr); 3163 error = inode_setattr(inode, attr);
3164 depth = reiserfs_write_lock_once(inode->i_sb);
3165 }
3143 } 3166 }
3144 3167
3145 if (!error && reiserfs_posixacl(inode->i_sb)) { 3168 if (!error && reiserfs_posixacl(inode->i_sb)) {
@@ -3148,7 +3171,8 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
3148 } 3171 }
3149 3172
3150 out: 3173 out:
3151 reiserfs_write_unlock(inode->i_sb); 3174 reiserfs_write_unlock_once(inode->i_sb, depth);
3175
3152 return error; 3176 return error;
3153} 3177}
3154 3178