diff options
Diffstat (limited to 'fs/reiserfs/inode.c')
| -rw-r--r-- | fs/reiserfs/inode.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 290ae38fca8a..9087b10209e6 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 | ||
| 80 | static void _make_cpu_key(struct cpu_key *key, int version, __u32 dirid, | 81 | static void _make_cpu_key(struct cpu_key *key, int version, __u32 dirid, |
| @@ -3061,13 +3062,14 @@ static ssize_t reiserfs_direct_IO(int rw, struct kiocb *iocb, | |||
| 3061 | int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | 3062 | int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) |
| 3062 | { | 3063 | { |
| 3063 | struct inode *inode = dentry->d_inode; | 3064 | struct inode *inode = dentry->d_inode; |
| 3064 | int error; | ||
| 3065 | unsigned int ia_valid; | 3065 | unsigned int ia_valid; |
| 3066 | int depth; | ||
| 3067 | int error; | ||
| 3066 | 3068 | ||
| 3067 | /* must be turned off for recursive notify_change calls */ | 3069 | /* must be turned off for recursive notify_change calls */ |
| 3068 | ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID); | 3070 | ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID); |
| 3069 | 3071 | ||
| 3070 | reiserfs_write_lock(inode->i_sb); | 3072 | depth = reiserfs_write_lock_once(inode->i_sb); |
| 3071 | if (attr->ia_valid & ATTR_SIZE) { | 3073 | if (attr->ia_valid & ATTR_SIZE) { |
| 3072 | /* version 2 items will be caught by the s_maxbytes check | 3074 | /* version 2 items will be caught by the s_maxbytes check |
| 3073 | ** done for us in vmtruncate | 3075 | ** done for us in vmtruncate |
| @@ -3148,8 +3150,17 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
| 3148 | journal_end(&th, inode->i_sb, jbegin_count); | 3150 | journal_end(&th, inode->i_sb, jbegin_count); |
| 3149 | } | 3151 | } |
| 3150 | } | 3152 | } |
| 3151 | if (!error) | 3153 | if (!error) { |
| 3154 | /* | ||
| 3155 | * Relax the lock here, as it might truncate the | ||
| 3156 | * inode pages and wait for inode pages locks. | ||
| 3157 | * To release such page lock, the owner needs the | ||
| 3158 | * reiserfs lock | ||
| 3159 | */ | ||
| 3160 | reiserfs_write_unlock_once(inode->i_sb, depth); | ||
| 3152 | error = inode_setattr(inode, attr); | 3161 | error = inode_setattr(inode, attr); |
| 3162 | depth = reiserfs_write_lock_once(inode->i_sb); | ||
| 3163 | } | ||
| 3153 | } | 3164 | } |
| 3154 | 3165 | ||
| 3155 | if (!error && reiserfs_posixacl(inode->i_sb)) { | 3166 | if (!error && reiserfs_posixacl(inode->i_sb)) { |
| @@ -3158,7 +3169,8 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
| 3158 | } | 3169 | } |
| 3159 | 3170 | ||
| 3160 | out: | 3171 | out: |
| 3161 | reiserfs_write_unlock(inode->i_sb); | 3172 | reiserfs_write_unlock_once(inode->i_sb, depth); |
| 3173 | |||
| 3162 | return error; | 3174 | return error; |
| 3163 | } | 3175 | } |
| 3164 | 3176 | ||
