diff options
Diffstat (limited to 'fs/reiserfs/inode.c')
| -rw-r--r-- | fs/reiserfs/inode.c | 136 |
1 files changed, 81 insertions, 55 deletions
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 0f22fdaf54ac..ae35413dcbe1 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
| @@ -25,7 +25,7 @@ int reiserfs_commit_write(struct file *f, struct page *page, | |||
| 25 | int reiserfs_prepare_write(struct file *f, struct page *page, | 25 | int reiserfs_prepare_write(struct file *f, struct page *page, |
| 26 | unsigned from, unsigned to); | 26 | unsigned from, unsigned to); |
| 27 | 27 | ||
| 28 | void reiserfs_delete_inode(struct inode *inode) | 28 | void reiserfs_evict_inode(struct inode *inode) |
| 29 | { | 29 | { |
| 30 | /* We need blocks for transaction + (user+group) quota update (possibly delete) */ | 30 | /* We need blocks for transaction + (user+group) quota update (possibly delete) */ |
| 31 | int jbegin_count = | 31 | int jbegin_count = |
| @@ -35,10 +35,12 @@ void reiserfs_delete_inode(struct inode *inode) | |||
| 35 | int depth; | 35 | int depth; |
| 36 | int err; | 36 | int err; |
| 37 | 37 | ||
| 38 | if (!is_bad_inode(inode)) | 38 | if (!inode->i_nlink && !is_bad_inode(inode)) |
| 39 | dquot_initialize(inode); | 39 | dquot_initialize(inode); |
| 40 | 40 | ||
| 41 | truncate_inode_pages(&inode->i_data, 0); | 41 | truncate_inode_pages(&inode->i_data, 0); |
| 42 | if (inode->i_nlink) | ||
| 43 | goto no_delete; | ||
| 42 | 44 | ||
| 43 | depth = reiserfs_write_lock_once(inode->i_sb); | 45 | depth = reiserfs_write_lock_once(inode->i_sb); |
| 44 | 46 | ||
| @@ -77,9 +79,14 @@ void reiserfs_delete_inode(struct inode *inode) | |||
| 77 | ; | 79 | ; |
| 78 | } | 80 | } |
| 79 | out: | 81 | out: |
| 80 | clear_inode(inode); /* note this must go after the journal_end to prevent deadlock */ | 82 | end_writeback(inode); /* note this must go after the journal_end to prevent deadlock */ |
| 83 | dquot_drop(inode); | ||
| 81 | inode->i_blocks = 0; | 84 | inode->i_blocks = 0; |
| 82 | reiserfs_write_unlock_once(inode->i_sb, depth); | 85 | reiserfs_write_unlock_once(inode->i_sb, depth); |
| 86 | |||
| 87 | no_delete: | ||
| 88 | end_writeback(inode); | ||
| 89 | dquot_drop(inode); | ||
| 83 | } | 90 | } |
| 84 | 91 | ||
| 85 | static void _make_cpu_key(struct cpu_key *key, int version, __u32 dirid, | 92 | static void _make_cpu_key(struct cpu_key *key, int version, __u32 dirid, |
| @@ -1138,7 +1145,6 @@ static void init_inode(struct inode *inode, struct treepath *path) | |||
| 1138 | REISERFS_I(inode)->i_prealloc_count = 0; | 1145 | REISERFS_I(inode)->i_prealloc_count = 0; |
| 1139 | REISERFS_I(inode)->i_trans_id = 0; | 1146 | REISERFS_I(inode)->i_trans_id = 0; |
| 1140 | REISERFS_I(inode)->i_jl = NULL; | 1147 | REISERFS_I(inode)->i_jl = NULL; |
| 1141 | mutex_init(&(REISERFS_I(inode)->i_mmap)); | ||
| 1142 | reiserfs_init_xattr_rwsem(inode); | 1148 | reiserfs_init_xattr_rwsem(inode); |
| 1143 | 1149 | ||
| 1144 | if (stat_data_v1(ih)) { | 1150 | if (stat_data_v1(ih)) { |
| @@ -1221,7 +1227,7 @@ static void init_inode(struct inode *inode, struct treepath *path) | |||
| 1221 | inode_set_bytes(inode, | 1227 | inode_set_bytes(inode, |
| 1222 | to_real_used_space(inode, inode->i_blocks, | 1228 | to_real_used_space(inode, inode->i_blocks, |
| 1223 | SD_V2_SIZE)); | 1229 | SD_V2_SIZE)); |
| 1224 | /* read persistent inode attributes from sd and initalise | 1230 | /* read persistent inode attributes from sd and initialise |
| 1225 | generic inode flags from them */ | 1231 | generic inode flags from them */ |
| 1226 | REISERFS_I(inode)->i_attrs = sd_v2_attrs(sd); | 1232 | REISERFS_I(inode)->i_attrs = sd_v2_attrs(sd); |
| 1227 | sd_attrs_to_i_attrs(sd_v2_attrs(sd), inode); | 1233 | sd_attrs_to_i_attrs(sd_v2_attrs(sd), inode); |
| @@ -1841,7 +1847,6 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, | |||
| 1841 | REISERFS_I(inode)->i_attrs = | 1847 | REISERFS_I(inode)->i_attrs = |
| 1842 | REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK; | 1848 | REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK; |
| 1843 | sd_attrs_to_i_attrs(REISERFS_I(inode)->i_attrs, inode); | 1849 | sd_attrs_to_i_attrs(REISERFS_I(inode)->i_attrs, inode); |
| 1844 | mutex_init(&(REISERFS_I(inode)->i_mmap)); | ||
| 1845 | reiserfs_init_xattr_rwsem(inode); | 1850 | reiserfs_init_xattr_rwsem(inode); |
| 1846 | 1851 | ||
| 1847 | /* key to search for correct place for new stat data */ | 1852 | /* key to search for correct place for new stat data */ |
| @@ -2587,8 +2592,7 @@ static int reiserfs_write_begin(struct file *file, | |||
| 2587 | old_ref = th->t_refcount; | 2592 | old_ref = th->t_refcount; |
| 2588 | th->t_refcount++; | 2593 | th->t_refcount++; |
| 2589 | } | 2594 | } |
| 2590 | ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, | 2595 | ret = __block_write_begin(page, pos, len, reiserfs_get_block); |
| 2591 | reiserfs_get_block); | ||
| 2592 | if (ret && reiserfs_transaction_running(inode->i_sb)) { | 2596 | if (ret && reiserfs_transaction_running(inode->i_sb)) { |
| 2593 | struct reiserfs_transaction_handle *th = current->journal_info; | 2597 | struct reiserfs_transaction_handle *th = current->journal_info; |
| 2594 | /* this gets a little ugly. If reiserfs_get_block returned an | 2598 | /* this gets a little ugly. If reiserfs_get_block returned an |
| @@ -3059,10 +3063,25 @@ static ssize_t reiserfs_direct_IO(int rw, struct kiocb *iocb, | |||
| 3059 | { | 3063 | { |
| 3060 | struct file *file = iocb->ki_filp; | 3064 | struct file *file = iocb->ki_filp; |
| 3061 | struct inode *inode = file->f_mapping->host; | 3065 | struct inode *inode = file->f_mapping->host; |
| 3066 | ssize_t ret; | ||
| 3062 | 3067 | ||
| 3063 | return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, | 3068 | ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, |
| 3064 | offset, nr_segs, | 3069 | offset, nr_segs, |
| 3065 | reiserfs_get_blocks_direct_io, NULL); | 3070 | reiserfs_get_blocks_direct_io, NULL); |
| 3071 | |||
| 3072 | /* | ||
| 3073 | * In case of error extending write may have instantiated a few | ||
| 3074 | * blocks outside i_size. Trim these off again. | ||
| 3075 | */ | ||
| 3076 | if (unlikely((rw & WRITE) && ret < 0)) { | ||
| 3077 | loff_t isize = i_size_read(inode); | ||
| 3078 | loff_t end = offset + iov_length(iov, nr_segs); | ||
| 3079 | |||
| 3080 | if (end > isize) | ||
| 3081 | vmtruncate(inode, isize); | ||
| 3082 | } | ||
| 3083 | |||
| 3084 | return ret; | ||
| 3066 | } | 3085 | } |
| 3067 | 3086 | ||
| 3068 | int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | 3087 | int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) |
| @@ -3072,6 +3091,10 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
| 3072 | int depth; | 3091 | int depth; |
| 3073 | int error; | 3092 | int error; |
| 3074 | 3093 | ||
| 3094 | error = inode_change_ok(inode, attr); | ||
| 3095 | if (error) | ||
| 3096 | return error; | ||
| 3097 | |||
| 3075 | /* must be turned off for recursive notify_change calls */ | 3098 | /* must be turned off for recursive notify_change calls */ |
| 3076 | ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID); | 3099 | ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID); |
| 3077 | 3100 | ||
| @@ -3121,55 +3144,58 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
| 3121 | goto out; | 3144 | goto out; |
| 3122 | } | 3145 | } |
| 3123 | 3146 | ||
| 3124 | error = inode_change_ok(inode, attr); | 3147 | if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || |
| 3125 | if (!error) { | 3148 | (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { |
| 3126 | if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || | 3149 | struct reiserfs_transaction_handle th; |
| 3127 | (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { | 3150 | int jbegin_count = |
| 3128 | error = reiserfs_chown_xattrs(inode, attr); | 3151 | 2 * |
| 3152 | (REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb) + | ||
| 3153 | REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb)) + | ||
| 3154 | 2; | ||
| 3129 | 3155 | ||
| 3130 | if (!error) { | 3156 | error = reiserfs_chown_xattrs(inode, attr); |
| 3131 | struct reiserfs_transaction_handle th; | 3157 | |
| 3132 | int jbegin_count = | 3158 | if (error) |
| 3133 | 2 * | 3159 | return error; |
| 3134 | (REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb) + | 3160 | |
| 3135 | REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb)) + | 3161 | /* (user+group)*(old+new) structure - we count quota info and , inode write (sb, inode) */ |
| 3136 | 2; | 3162 | error = journal_begin(&th, inode->i_sb, jbegin_count); |
| 3137 | 3163 | if (error) | |
| 3138 | /* (user+group)*(old+new) structure - we count quota info and , inode write (sb, inode) */ | 3164 | goto out; |
| 3139 | error = | 3165 | error = dquot_transfer(inode, attr); |
| 3140 | journal_begin(&th, inode->i_sb, | 3166 | if (error) { |
| 3141 | jbegin_count); | 3167 | journal_end(&th, inode->i_sb, jbegin_count); |
| 3142 | if (error) | 3168 | goto out; |
| 3143 | goto out; | ||
| 3144 | error = dquot_transfer(inode, attr); | ||
| 3145 | if (error) { | ||
| 3146 | journal_end(&th, inode->i_sb, | ||
| 3147 | jbegin_count); | ||
| 3148 | goto out; | ||
| 3149 | } | ||
| 3150 | /* Update corresponding info in inode so that everything is in | ||
| 3151 | * one transaction */ | ||
| 3152 | if (attr->ia_valid & ATTR_UID) | ||
| 3153 | inode->i_uid = attr->ia_uid; | ||
| 3154 | if (attr->ia_valid & ATTR_GID) | ||
| 3155 | inode->i_gid = attr->ia_gid; | ||
| 3156 | mark_inode_dirty(inode); | ||
| 3157 | error = | ||
| 3158 | journal_end(&th, inode->i_sb, jbegin_count); | ||
| 3159 | } | ||
| 3160 | } | ||
| 3161 | if (!error) { | ||
| 3162 | /* | ||
| 3163 | * Relax the lock here, as it might truncate the | ||
| 3164 | * inode pages and wait for inode pages locks. | ||
| 3165 | * To release such page lock, the owner needs the | ||
| 3166 | * reiserfs lock | ||
| 3167 | */ | ||
| 3168 | reiserfs_write_unlock_once(inode->i_sb, depth); | ||
| 3169 | error = inode_setattr(inode, attr); | ||
| 3170 | depth = reiserfs_write_lock_once(inode->i_sb); | ||
| 3171 | } | 3169 | } |
| 3170 | |||
| 3171 | /* Update corresponding info in inode so that everything is in | ||
| 3172 | * one transaction */ | ||
| 3173 | if (attr->ia_valid & ATTR_UID) | ||
| 3174 | inode->i_uid = attr->ia_uid; | ||
| 3175 | if (attr->ia_valid & ATTR_GID) | ||
| 3176 | inode->i_gid = attr->ia_gid; | ||
| 3177 | mark_inode_dirty(inode); | ||
| 3178 | error = journal_end(&th, inode->i_sb, jbegin_count); | ||
| 3179 | if (error) | ||
| 3180 | goto out; | ||
| 3181 | } | ||
| 3182 | |||
| 3183 | /* | ||
| 3184 | * Relax the lock here, as it might truncate the | ||
| 3185 | * inode pages and wait for inode pages locks. | ||
| 3186 | * To release such page lock, the owner needs the | ||
| 3187 | * reiserfs lock | ||
| 3188 | */ | ||
| 3189 | reiserfs_write_unlock_once(inode->i_sb, depth); | ||
| 3190 | if ((attr->ia_valid & ATTR_SIZE) && | ||
| 3191 | attr->ia_size != i_size_read(inode)) | ||
| 3192 | error = vmtruncate(inode, attr->ia_size); | ||
| 3193 | |||
| 3194 | if (!error) { | ||
| 3195 | setattr_copy(inode, attr); | ||
| 3196 | mark_inode_dirty(inode); | ||
| 3172 | } | 3197 | } |
| 3198 | depth = reiserfs_write_lock_once(inode->i_sb); | ||
| 3173 | 3199 | ||
| 3174 | if (!error && reiserfs_posixacl(inode->i_sb)) { | 3200 | if (!error && reiserfs_posixacl(inode->i_sb)) { |
| 3175 | if (attr->ia_valid & ATTR_MODE) | 3201 | if (attr->ia_valid & ATTR_MODE) |
