@@ -3249,6 +3249,32 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
32493249 return retval ;
32503250}
32513251
3252+ static int ext4_init_symlink_block (handle_t * handle , struct inode * inode ,
3253+ struct fscrypt_str * disk_link )
3254+ {
3255+ struct buffer_head * bh ;
3256+ char * kaddr ;
3257+ int err = 0 ;
3258+
3259+ bh = ext4_bread (handle , inode , 0 , EXT4_GET_BLOCKS_CREATE );
3260+ if (IS_ERR (bh ))
3261+ return PTR_ERR (bh );
3262+
3263+ BUFFER_TRACE (bh , "get_write_access" );
3264+ err = ext4_journal_get_write_access (handle , inode -> i_sb , bh , EXT4_JTR_NONE );
3265+ if (err )
3266+ goto out ;
3267+
3268+ kaddr = (char * )bh -> b_data ;
3269+ memcpy (kaddr , disk_link -> name , disk_link -> len );
3270+ inode -> i_size = disk_link -> len - 1 ;
3271+ EXT4_I (inode )-> i_disksize = inode -> i_size ;
3272+ err = ext4_handle_dirty_metadata (handle , inode , bh );
3273+ out :
3274+ brelse (bh );
3275+ return err ;
3276+ }
3277+
32523278static int ext4_symlink (struct user_namespace * mnt_userns , struct inode * dir ,
32533279 struct dentry * dentry , const char * symname )
32543280{
@@ -3257,6 +3283,7 @@ static int ext4_symlink(struct user_namespace *mnt_userns, struct inode *dir,
32573283 int err , len = strlen (symname );
32583284 int credits ;
32593285 struct fscrypt_str disk_link ;
3286+ int retries = 0 ;
32603287
32613288 if (unlikely (ext4_forced_shutdown (EXT4_SB (dir -> i_sb ))))
32623289 return - EIO ;
@@ -3270,109 +3297,69 @@ static int ext4_symlink(struct user_namespace *mnt_userns, struct inode *dir,
32703297 if (err )
32713298 return err ;
32723299
3273- if ((disk_link .len > EXT4_N_BLOCKS * 4 )) {
3274- /*
3275- * For non-fast symlinks, we just allocate inode and put it on
3276- * orphan list in the first transaction => we need bitmap,
3277- * group descriptor, sb, inode block, quota blocks, and
3278- * possibly selinux xattr blocks.
3279- */
3280- credits = 4 + EXT4_MAXQUOTAS_INIT_BLOCKS (dir -> i_sb ) +
3281- EXT4_XATTR_TRANS_BLOCKS ;
3282- } else {
3283- /*
3284- * Fast symlink. We have to add entry to directory
3285- * (EXT4_DATA_TRANS_BLOCKS + EXT4_INDEX_EXTRA_TRANS_BLOCKS),
3286- * allocate new inode (bitmap, group descriptor, inode block,
3287- * quota blocks, sb is already counted in previous macros).
3288- */
3289- credits = EXT4_DATA_TRANS_BLOCKS (dir -> i_sb ) +
3290- EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 ;
3291- }
3292-
3300+ /*
3301+ * EXT4_INDEX_EXTRA_TRANS_BLOCKS for addition of entry into the
3302+ * directory. +3 for inode, inode bitmap, group descriptor allocation.
3303+ * EXT4_DATA_TRANS_BLOCKS for the data block allocation and
3304+ * modification.
3305+ */
3306+ credits = EXT4_DATA_TRANS_BLOCKS (dir -> i_sb ) +
3307+ EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 ;
3308+ retry :
32933309 inode = ext4_new_inode_start_handle (mnt_userns , dir , S_IFLNK |S_IRWXUGO ,
32943310 & dentry -> d_name , 0 , NULL ,
32953311 EXT4_HT_DIR , credits );
32963312 handle = ext4_journal_current_handle ();
32973313 if (IS_ERR (inode )) {
32983314 if (handle )
32993315 ext4_journal_stop (handle );
3300- return PTR_ERR (inode );
3316+ err = PTR_ERR (inode );
3317+ goto out_retry ;
33013318 }
33023319
33033320 if (IS_ENCRYPTED (inode )) {
33043321 err = fscrypt_encrypt_symlink (inode , symname , len , & disk_link );
33053322 if (err )
33063323 goto err_drop_inode ;
33073324 inode -> i_op = & ext4_encrypted_symlink_inode_operations ;
3325+ } else {
3326+ if ((disk_link .len > EXT4_N_BLOCKS * 4 )) {
3327+ inode -> i_op = & ext4_symlink_inode_operations ;
3328+ } else {
3329+ inode -> i_op = & ext4_fast_symlink_inode_operations ;
3330+ inode -> i_link = (char * )& EXT4_I (inode )-> i_data ;
3331+ }
33083332 }
33093333
33103334 if ((disk_link .len > EXT4_N_BLOCKS * 4 )) {
3311- if (!IS_ENCRYPTED (inode ))
3312- inode -> i_op = & ext4_symlink_inode_operations ;
3313- inode_nohighmem (inode );
3314- ext4_set_aops (inode );
3315- /*
3316- * We cannot call page_symlink() with transaction started
3317- * because it calls into ext4_write_begin() which can wait
3318- * for transaction commit if we are running out of space
3319- * and thus we deadlock. So we have to stop transaction now
3320- * and restart it when symlink contents is written.
3321- *
3322- * To keep fs consistent in case of crash, we have to put inode
3323- * to orphan list in the mean time.
3324- */
3325- drop_nlink (inode );
3326- err = ext4_orphan_add (handle , inode );
3327- if (handle )
3328- ext4_journal_stop (handle );
3329- handle = NULL ;
3330- if (err )
3331- goto err_drop_inode ;
3332- err = __page_symlink (inode , disk_link .name , disk_link .len , 1 );
3333- if (err )
3334- goto err_drop_inode ;
3335- /*
3336- * Now inode is being linked into dir (EXT4_DATA_TRANS_BLOCKS
3337- * + EXT4_INDEX_EXTRA_TRANS_BLOCKS), inode is also modified
3338- */
3339- handle = ext4_journal_start (dir , EXT4_HT_DIR ,
3340- EXT4_DATA_TRANS_BLOCKS (dir -> i_sb ) +
3341- EXT4_INDEX_EXTRA_TRANS_BLOCKS + 1 );
3342- if (IS_ERR (handle )) {
3343- err = PTR_ERR (handle );
3344- handle = NULL ;
3345- goto err_drop_inode ;
3346- }
3347- set_nlink (inode , 1 );
3348- err = ext4_orphan_del (handle , inode );
3335+ /* alloc symlink block and fill it */
3336+ err = ext4_init_symlink_block (handle , inode , & disk_link );
33493337 if (err )
33503338 goto err_drop_inode ;
33513339 } else {
33523340 /* clear the extent format for fast symlink */
33533341 ext4_clear_inode_flag (inode , EXT4_INODE_EXTENTS );
3354- if (!IS_ENCRYPTED (inode )) {
3355- inode -> i_op = & ext4_fast_symlink_inode_operations ;
3356- inode -> i_link = (char * )& EXT4_I (inode )-> i_data ;
3357- }
33583342 memcpy ((char * )& EXT4_I (inode )-> i_data , disk_link .name ,
33593343 disk_link .len );
33603344 inode -> i_size = disk_link .len - 1 ;
3345+ EXT4_I (inode )-> i_disksize = inode -> i_size ;
33613346 }
3362- EXT4_I (inode )-> i_disksize = inode -> i_size ;
33633347 err = ext4_add_nondir (handle , dentry , & inode );
33643348 if (handle )
33653349 ext4_journal_stop (handle );
33663350 iput (inode );
3367- goto out_free_encrypted_link ;
3351+ goto out_retry ;
33683352
33693353err_drop_inode :
3370- if (handle )
3371- ext4_journal_stop (handle );
33723354 clear_nlink (inode );
3355+ ext4_orphan_add (handle , inode );
33733356 unlock_new_inode (inode );
3357+ if (handle )
3358+ ext4_journal_stop (handle );
33743359 iput (inode );
3375- out_free_encrypted_link :
3360+ out_retry :
3361+ if (err == - ENOSPC && ext4_should_retry_alloc (dir -> i_sb , & retries ))
3362+ goto retry ;
33763363 if (disk_link .name != (unsigned char * )symname )
33773364 kfree (disk_link .name );
33783365 return err ;
0 commit comments