lkml.org 
[lkml]   [2004]   [Jan]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[PATCH] [2.4.24-pre3] 2/5 EXT2/3 Updates
    From
    Date

    # This is a BitKeeper generated patch for the following project:
    # Project Name: Linux kernel tree
    # This patch format is intended for GNU patch command version 2.5 or higher.
    # This patch includes the following deltas:
    # ChangeSet 1.1357 -> 1.1358
    # fs/ext2/inode.c 1.19 -> 1.20
    # fs/ext3/inode.c 1.16 -> 1.17
    #
    # The following is the BitKeeper ChangeSet Log
    # --------------------------------------------
    # 04/01/01 tytso@think.thunk.org 1.1358
    # Applied 4208-ext23-symlink-ea-compat.patch from sct@redhat.com
    #
    # I found why people running SELinux on 2.6 were having trouble booting
    # again on 2.4 kernels, and it's nothing to do with SELinux per-se. It's
    # a compatibility problem with extended attributes.
    #
    # The trouble is that setting an EA on a fast symlink upsets the kernel's
    # symlink detection code. Older kernels will see a symlink with non-zero
    # i_blocks, and will assume that the symlink is a slow one --- ie. that
    # the first direct block of the inode points to the symlink contents ---
    # and will end up doing a block lookup from what is in fact the first four
    # ascii chars from the symlink path.
    #
    # 2.6 kernels deal with this by detecting a non-zero i_file_acl field and
    # subtracting the EA's blocks from i_blocks before checking if the block
    # count is zero. The patch below adds the same compatibility code to
    # 2.4. Booting a SELinux partition results in immediate death via access
    # beyond end-of-device as soon as the kernel tries to dereference /bin/sh
    # (a symlink to /bin/bash on this box); with the fix, it's fine.
    #
    # --------------------------------------------
    #
    diff -Nru a/fs/ext2/inode.c b/fs/ext2/inode.c
    --- a/fs/ext2/inode.c Thu Jan 1 16:29:13 2004
    +++ b/fs/ext2/inode.c Thu Jan 1 16:29:13 2004
    @@ -35,6 +35,17 @@
    MODULE_DESCRIPTION("Second Extended Filesystem");
    MODULE_LICENSE("GPL");

    +/*
    + * Test whether an inode is a fast symlink.
    + */
    +static inline int ext2_inode_is_fast_symlink(struct inode *inode)
    +{
    + int ea_blocks = inode->u.ext2_i.i_file_acl ?
    + (inode->i_sb->s_blocksize >> 9) : 0;
    +
    + return (S_ISLNK(inode->i_mode) &&
    + inode->i_blocks - ea_blocks == 0);
    +}

    static int ext2_update_inode(struct inode * inode, int do_sync);

    @@ -801,6 +812,8 @@
    if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
    S_ISLNK(inode->i_mode)))
    return;
    + if (ext2_inode_is_fast_symlink(inode))
    + return;
    if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
    return;

    @@ -1001,7 +1014,7 @@
    inode->i_fop = &ext2_dir_operations;
    inode->i_mapping->a_ops = &ext2_aops;
    } else if (S_ISLNK(inode->i_mode)) {
    - if (!inode->i_blocks)
    + if (ext2_inode_is_fast_symlink(inode))
    inode->i_op = &ext2_fast_symlink_inode_operations;
    else {
    inode->i_op = &page_symlink_inode_operations;
    diff -Nru a/fs/ext3/inode.c b/fs/ext3/inode.c
    --- a/fs/ext3/inode.c Thu Jan 1 16:29:13 2004
    +++ b/fs/ext3/inode.c Thu Jan 1 16:29:13 2004
    @@ -39,6 +39,18 @@
    */
    #undef SEARCH_FROM_ZERO

    +/*
    + * Test whether an inode is a fast symlink.
    + */
    +static inline int ext3_inode_is_fast_symlink(struct inode *inode)
    +{
    + int ea_blocks = EXT3_I(inode)->i_file_acl ?
    + (inode->i_sb->s_blocksize >> 9) : 0;
    +
    + return (S_ISLNK(inode->i_mode) &&
    + inode->i_blocks - ea_blocks == 0);
    +}
    +
    /* The ext3 forget function must perform a revoke if we are freeing data
    * which has been journaled. Metadata (eg. indirect blocks) must be
    * revoked in all cases.
    @@ -1870,6 +1882,8 @@
    if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
    S_ISLNK(inode->i_mode)))
    return;
    + if (ext3_inode_is_fast_symlink(inode))
    + return;
    if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
    return;

    @@ -2170,7 +2184,7 @@
    inode->i_op = &ext3_dir_inode_operations;
    inode->i_fop = &ext3_dir_operations;
    } else if (S_ISLNK(inode->i_mode)) {
    - if (!inode->i_blocks)
    + if (ext3_inode_is_fast_symlink(inode))
    inode->i_op = &ext3_fast_symlink_inode_operations;
    else {
    inode->i_op = &page_symlink_inode_operations;
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2005-03-22 13:59    [W:0.040 / U:0.056 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site