@@ -2189,17 +2189,34 @@ static int ext3_symlink (struct inode * dir,
2189
2189
handle_t * handle ;
2190
2190
struct inode * inode ;
2191
2191
int l , err , retries = 0 ;
2192
+ int credits ;
2192
2193
2193
2194
l = strlen (symname )+ 1 ;
2194
2195
if (l > dir -> i_sb -> s_blocksize )
2195
2196
return - ENAMETOOLONG ;
2196
2197
2197
2198
dquot_initialize (dir );
2198
2199
2200
+ if (l > EXT3_N_BLOCKS * 4 ) {
2201
+ /*
2202
+ * For non-fast symlinks, we just allocate inode and put it on
2203
+ * orphan list in the first transaction => we need bitmap,
2204
+ * group descriptor, sb, inode block, quota blocks.
2205
+ */
2206
+ credits = 4 + EXT3_MAXQUOTAS_INIT_BLOCKS (dir -> i_sb );
2207
+ } else {
2208
+ /*
2209
+ * Fast symlink. We have to add entry to directory
2210
+ * (EXT3_DATA_TRANS_BLOCKS + EXT3_INDEX_EXTRA_TRANS_BLOCKS),
2211
+ * allocate new inode (bitmap, group descriptor, inode block,
2212
+ * quota blocks, sb is already counted in previous macros).
2213
+ */
2214
+ credits = EXT3_DATA_TRANS_BLOCKS (dir -> i_sb ) +
2215
+ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 +
2216
+ EXT3_MAXQUOTAS_INIT_BLOCKS (dir -> i_sb );
2217
+ }
2199
2218
retry :
2200
- handle = ext3_journal_start (dir , EXT3_DATA_TRANS_BLOCKS (dir -> i_sb ) +
2201
- EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5 +
2202
- EXT3_MAXQUOTAS_INIT_BLOCKS (dir -> i_sb ));
2219
+ handle = ext3_journal_start (dir , credits );
2203
2220
if (IS_ERR (handle ))
2204
2221
return PTR_ERR (handle );
2205
2222
@@ -2211,21 +2228,45 @@ static int ext3_symlink (struct inode * dir,
2211
2228
if (IS_ERR (inode ))
2212
2229
goto out_stop ;
2213
2230
2214
- if (l > sizeof ( EXT3_I ( inode ) -> i_data ) ) {
2231
+ if (l > EXT3_N_BLOCKS * 4 ) {
2215
2232
inode -> i_op = & ext3_symlink_inode_operations ;
2216
2233
ext3_set_aops (inode );
2217
2234
/*
2218
- * page_symlink() calls into ext3_prepare/commit_write.
2219
- * We have a transaction open. All is sweetness. It also sets
2220
- * i_size in generic_commit_write().
2235
+ * We cannot call page_symlink() with transaction started
2236
+ * because it calls into ext3_write_begin() which acquires page
2237
+ * lock which ranks below transaction start (and it can also
2238
+ * wait for journal commit if we are running out of space). So
2239
+ * we have to stop transaction now and restart it when symlink
2240
+ * contents is written.
2241
+ *
2242
+ * To keep fs consistent in case of crash, we have to put inode
2243
+ * to orphan list in the mean time.
2221
2244
*/
2245
+ drop_nlink (inode );
2246
+ err = ext3_orphan_add (handle , inode );
2247
+ ext3_journal_stop (handle );
2248
+ if (err )
2249
+ goto err_drop_inode ;
2222
2250
err = __page_symlink (inode , symname , l , 1 );
2251
+ if (err )
2252
+ goto err_drop_inode ;
2253
+ /*
2254
+ * Now inode is being linked into dir (EXT3_DATA_TRANS_BLOCKS
2255
+ * + EXT3_INDEX_EXTRA_TRANS_BLOCKS), inode is also modified
2256
+ */
2257
+ handle = ext3_journal_start (dir ,
2258
+ EXT3_DATA_TRANS_BLOCKS (dir -> i_sb ) +
2259
+ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 1 );
2260
+ if (IS_ERR (handle )) {
2261
+ err = PTR_ERR (handle );
2262
+ goto err_drop_inode ;
2263
+ }
2264
+ inc_nlink (inode );
2265
+ err = ext3_orphan_del (handle , inode );
2223
2266
if (err ) {
2267
+ ext3_journal_stop (handle );
2224
2268
drop_nlink (inode );
2225
- unlock_new_inode (inode );
2226
- ext3_mark_inode_dirty (handle , inode );
2227
- iput (inode );
2228
- goto out_stop ;
2269
+ goto err_drop_inode ;
2229
2270
}
2230
2271
} else {
2231
2272
inode -> i_op = & ext3_fast_symlink_inode_operations ;
@@ -2239,6 +2280,10 @@ static int ext3_symlink (struct inode * dir,
2239
2280
if (err == - ENOSPC && ext3_should_retry_alloc (dir -> i_sb , & retries ))
2240
2281
goto retry ;
2241
2282
return err ;
2283
+ err_drop_inode :
2284
+ unlock_new_inode (inode );
2285
+ iput (inode );
2286
+ return err ;
2242
2287
}
2243
2288
2244
2289
static int ext3_link (struct dentry * old_dentry ,
0 commit comments