]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
libext2fs: make symlinks safe for 64bit blocks and extents
authorDarrick J. Wong <darrick.wong@oracle.com>
Thu, 12 Dec 2013 17:48:33 +0000 (12:48 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 12 Dec 2013 17:48:39 +0000 (12:48 -0500)
If we have to create a big symlink (i.e. one that doesn't fit into
i_block[]), we are not 64bit block safe and the namei code does not
handle extents at all.  Fix both.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
lib/ext2fs/namei.c
lib/ext2fs/symlink.c

index efcc02b7e663a4bd02c85b9128184f04351c6109..307aecc88d878e08b675fe0bd0cc7ab2953d6dee 100644 (file)
@@ -34,6 +34,7 @@ static errcode_t follow_link(ext2_filsys fs, ext2_ino_t root, ext2_ino_t dir,
        char *buffer = 0;
        errcode_t retval;
        struct ext2_inode ei;
+       blk64_t blk;
 
 #ifdef NAMEI_DEBUG
        printf("follow_link: root=%lu, dir=%lu, inode=%lu, lc=%d\n",
@@ -49,12 +50,16 @@ static errcode_t follow_link(ext2_filsys fs, ext2_ino_t root, ext2_ino_t dir,
        if (link_count++ >= EXT2FS_MAX_NESTED_LINKS)
                return EXT2_ET_SYMLINK_LOOP;
 
-       /* FIXME-64: Actually, this is FIXME EXTENTS */
        if (ext2fs_inode_data_blocks(fs,&ei)) {
+               retval = ext2fs_bmap2(fs, inode, &ei, NULL, 0, 0, NULL, &blk);
+               if (retval)
+                       return retval;
+
                retval = ext2fs_get_mem(fs->blocksize, &buffer);
                if (retval)
                        return retval;
-               retval = io_channel_read_blk(fs->io, ei.i_block[0], 1, buffer);
+
+               retval = io_channel_read_blk64(fs->io, blk, 1, buffer);
                if (retval) {
                        ext2fs_free_mem(&buffer);
                        return retval;
index e943412e169182eb6dd7880bfe349501bb837495..ad80444165caf1ef762c44303b9059a8104c57da 100644 (file)
@@ -91,14 +91,12 @@ errcode_t ext2fs_symlink(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t ino,
                memset(block_buf, 0, fs->blocksize);
                strcpy(block_buf, target);
                if (fs->super->s_feature_incompat &
-                  EXT3_FEATURE_INCOMPAT_EXTENTS) {
+                   EXT3_FEATURE_INCOMPAT_EXTENTS) {
                        /*
                         * The extent bmap is setup after the inode and block
                         * have been written out below.
                         */
                        inode.i_flags |= EXT4_EXTENTS_FL;
-               } else {
-                       inode.i_block[0] = blk;
                }
        }
 
@@ -112,20 +110,14 @@ errcode_t ext2fs_symlink(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t ino,
                goto cleanup;
 
        if (!fastlink) {
-               retval = io_channel_write_blk(fs->io, blk, 1, block_buf);
+               retval = ext2fs_bmap2(fs, ino, &inode, NULL, BMAP_SET, 0, NULL,
+                                     &blk);
                if (retval)
                        goto cleanup;
 
-               if (fs->super->s_feature_incompat &
-                   EXT3_FEATURE_INCOMPAT_EXTENTS) {
-                       retval = ext2fs_extent_open2(fs, ino, &inode, &handle);
-                       if (retval)
-                               goto cleanup;
-                       retval = ext2fs_extent_set_bmap(handle, 0, blk, 0);
-                       ext2fs_extent_free(handle);
-                       if (retval)
-                               goto cleanup;
-               }
+               retval = io_channel_write_blk64(fs->io, blk, 1, block_buf);
+               if (retval)
+                       goto cleanup;
        }
 
        /*