[PATCH 11/21] fat: Fix/Cleanup dcache handling for vfat - Kernel

This is a discussion on [PATCH 11/21] fat: Fix/Cleanup dcache handling for vfat - Kernel ; - Add comments for handling dcache of vfat. - Separate case-sensitive case and case-insensitive to vfat_revalidate() and vfat_ci_revalidate(). vfat_revalidate() doesn't need to drop case-insensitive negative dentry on creation path. - Current code is missing to set ->d_revalidate to the negative ...

+ Reply to Thread
Results 1 to 6 of 6

Thread: [PATCH 11/21] fat: Fix/Cleanup dcache handling for vfat

  1. [PATCH 11/21] fat: Fix/Cleanup dcache handling for vfat


    - Add comments for handling dcache of vfat.

    - Separate case-sensitive case and case-insensitive to
    vfat_revalidate() and vfat_ci_revalidate().

    vfat_revalidate() doesn't need to drop case-insensitive negative
    dentry on creation path.

    - Current code is missing to set ->d_revalidate to the negative dentry
    created by unlink/etc..

    This sets ->d_revalidate always, and returns 1 for positive
    dentry. Now, we don't need to change ->d_op dynamically anymore,
    so this just uses sb->s_root->d_op to set ->d_op.

    - d_find_alias() may return DCACHE_DISCONNECTED dentry. It's not
    the interesting dentry there. This checks it.

    - Add missing LOOKUP_PARENT check. We don't need to drop the valid
    negative dentry for (LOOKUP_CREATE | LOOKUP_PARENT) lookup.

    - For consistent filename on creation path, this drops negative dentry
    if we can't see intent.

    Signed-off-by: OGAWA Hirofumi
    ---

    fs/fat/namei_vfat.c | 124 ++++++++++++++++++++++++++++++++-------------------
    1 file changed, 80 insertions(+), 44 deletions(-)

    diff -puN fs/fat/namei_vfat.c~vfat-dcache-fixes fs/fat/namei_vfat.c
    --- linux-2.6/fs/fat/namei_vfat.c~vfat-dcache-fixes 2008-08-27 14:57:52.000000000 +0900
    +++ linux-2.6-hirofumi/fs/fat/namei_vfat.c 2008-08-27 18:41:22.000000000 +0900
    @@ -24,27 +24,67 @@
    #include
    #include "fat.h"

    -static int vfat_revalidate(struct dentry *dentry, struct nameidata *nd)
    +/*
    + * If new entry was created in the parent, it could create the 8.3
    + * alias (the shortname of logname). So, the parent may have the
    + * negative-dentry which matches the created 8.3 alias.
    + *
    + * If it happened, the negative dentry isn't actually negative
    + * anymore. So, drop it.
    + */
    +static int vfat_revalidate_shortname(struct dentry *dentry)
    {
    int ret = 1;
    -
    - if (!dentry->d_inode &&
    - nd && !(nd->flags & LOOKUP_CONTINUE) && (nd->flags & LOOKUP_CREATE))
    - /*
    - * negative dentry is dropped, in order to make sure
    - * to use the name which a user desires if this is
    - * create path.
    - */
    + spin_lock(&dentry->d_lock);
    + if (dentry->d_time != dentry->d_parent->d_inode->i_version)
    ret = 0;
    - else {
    - spin_lock(&dentry->d_lock);
    - if (dentry->d_time != dentry->d_parent->d_inode->i_version)
    - ret = 0;
    - spin_unlock(&dentry->d_lock);
    - }
    + spin_unlock(&dentry->d_lock);
    return ret;
    }

    +static int vfat_revalidate(struct dentry *dentry, struct nameidata *nd)
    +{
    + /* This is not negative dentry. Always valid. */
    + if (dentry->d_inode)
    + return 1;
    + return vfat_revalidate_shortname(dentry);
    +}
    +
    +static int vfat_revalidate_ci(struct dentry *dentry, struct nameidata *nd)
    +{
    + /*
    + * This is not negative dentry. Always valid.
    + *
    + * Note, rename() to existing directory entry will have ->d_inode,
    + * and will use existing name which isn't specified name by user.
    + *
    + * We may be able to drop this positive dentry here. But dropping
    + * positive dentry isn't good idea. So it's unsupported like
    + * rename("filename", "FILENAME") for now.
    + */
    + if (dentry->d_inode)
    + return 1;
    +
    + /*
    + * This may be nfsd (or something), anyway, we can't see the
    + * intent of this. So, since this can be for creation, drop it.
    + */
    + if (!nd)
    + return 0;
    +
    + /*
    + * Drop the negative dentry, in order to make sure to use the
    + * case sensitive name which is specified by user if this is
    + * for creation.
    + */
    + if (!(nd->flags & (LOOKUP_CONTINUE | LOOKUP_PARENT))) {
    + if (nd->flags & LOOKUP_CREATE)
    + return 0;
    + }
    +
    + return vfat_revalidate_shortname(dentry);
    +}
    +
    /* returns the length of a struct qstr, ignoring trailing dots */
    static unsigned int vfat_striptail_len(struct qstr *qstr)
    {
    @@ -126,25 +166,16 @@ static int vfat_cmp(struct dentry *dentr
    return 1;
    }

    -static struct dentry_operations vfat_dentry_ops[4] = {
    - {
    - .d_hash = vfat_hashi,
    - .d_compare = vfat_cmpi,
    - },
    - {
    - .d_revalidate = vfat_revalidate,
    - .d_hash = vfat_hashi,
    - .d_compare = vfat_cmpi,
    - },
    - {
    - .d_hash = vfat_hash,
    - .d_compare = vfat_cmp,
    - },
    - {
    - .d_revalidate = vfat_revalidate,
    - .d_hash = vfat_hash,
    - .d_compare = vfat_cmp,
    - }
    +static struct dentry_operations vfat_ci_dentry_ops = {
    + .d_revalidate = vfat_revalidate_ci,
    + .d_hash = vfat_hashi,
    + .d_compare = vfat_cmpi,
    +};
    +
    +static struct dentry_operations vfat_dentry_ops = {
    + .d_revalidate = vfat_revalidate,
    + .d_hash = vfat_hash,
    + .d_compare = vfat_cmp,
    };

    /* Characters that are undesirable in an MS-DOS file name */
    @@ -685,29 +716,35 @@ static struct dentry *vfat_lookup(struct
    struct fat_slot_info sinfo;
    struct inode *inode;
    struct dentry *alias;
    - int err, table;
    + int err;

    lock_super(sb);
    - table = (MSDOS_SB(sb)->options.name_check == 's') ? 2 : 0;
    - dentry->d_op = &vfat_dentry_ops[table];

    err = vfat_find(dir, &dentry->d_name, &sinfo);
    if (err) {
    if (err == -ENOENT) {
    - table++;
    inode = NULL;
    goto out;
    }
    goto error;
    }
    +
    inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos);
    brelse(sinfo.bh);
    if (IS_ERR(inode)) {
    err = PTR_ERR(inode);
    goto error;
    }
    +
    alias = d_find_alias(inode);
    - if (alias) {
    + if (alias && !(alias->d_flags & DCACHE_DISCONNECTED)) {
    + /*
    + * This inode has non DCACHE_DISCONNECTED dentry. This
    + * means, the user did ->lookup() by an another name
    + * (longname vs 8.3 alias of it) in past.
    + *
    + * Switch to new one for reason of locality if possible.
    + */
    if (d_invalidate(alias) == 0)
    dput(alias);
    else {
    @@ -715,15 +752,14 @@ static struct dentry *vfat_lookup(struct
    unlock_super(sb);
    return alias;
    }
    -
    }
    out:
    unlock_super(sb);
    - dentry->d_op = &vfat_dentry_ops[table];
    + dentry->d_op = sb->s_root->d_op;
    dentry->d_time = dentry->d_parent->d_inode->i_version;
    dentry = d_splice_alias(inode, dentry);
    if (dentry) {
    - dentry->d_op = &vfat_dentry_ops[table];
    + dentry->d_op = sb->s_root->d_op;
    dentry->d_time = dentry->d_parent->d_inode->i_version;
    }
    return dentry;
    @@ -1022,9 +1058,9 @@ static int vfat_fill_super(struct super_
    return res;

    if (MSDOS_SB(sb)->options.name_check != 's')
    - sb->s_root->d_op = &vfat_dentry_ops[0];
    + sb->s_root->d_op = &vfat_ci_dentry_ops;
    else
    - sb->s_root->d_op = &vfat_dentry_ops[2];
    + sb->s_root->d_op = &vfat_dentry_ops;

    return 0;
    }
    _
    --
    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/

  2. [PATCH 13/21] fat: Cleanup msdos_lookup()


    Use same style with vfat_lookup().

    Signed-off-by: OGAWA Hirofumi
    ---

    fs/fat/namei_msdos.c | 38 +++++++++++++++++++++-----------------
    1 file changed, 21 insertions(+), 17 deletions(-)

    diff -puN fs/fat/namei_msdos.c~msdos-lookup-cleanup fs/fat/namei_msdos.c
    --- linux-2.6/fs/fat/namei_msdos.c~msdos-lookup-cleanup 2008-08-27 19:28:14.000000000 +0900
    +++ linux-2.6-hirofumi/fs/fat/namei_msdos.c 2008-08-27 19:28:14.000000000 +0900
    @@ -203,33 +203,37 @@ static struct dentry *msdos_lookup(struc
    {
    struct super_block *sb = dir->i_sb;
    struct fat_slot_info sinfo;
    - struct inode *inode = NULL;
    - int res;
    -
    - dentry->d_op = &msdos_dentry_operations;
    + struct inode *inode;
    + int err;

    lock_super(sb);
    - res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo);
    - if (res == -ENOENT)
    - goto add;
    - if (res < 0)
    - goto out;
    +
    + err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo);
    + if (err) {
    + if (err == -ENOENT) {
    + inode = NULL;
    + goto out;
    + }
    + goto error;
    + }
    +
    inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos);
    brelse(sinfo.bh);
    if (IS_ERR(inode)) {
    - res = PTR_ERR(inode);
    - goto out;
    + err = PTR_ERR(inode);
    + goto error;
    }
    -add:
    - res = 0;
    +out:
    + unlock_super(sb);
    + dentry->d_op = &msdos_dentry_operations;
    dentry = d_splice_alias(inode, dentry);
    if (dentry)
    dentry->d_op = &msdos_dentry_operations;
    -out:
    + return dentry;
    +
    +error:
    unlock_super(sb);
    - if (!res)
    - return dentry;
    - return ERR_PTR(res);
    + return ERR_PTR(err);
    }

    /***** Creates a directory entry (name is already formatted). */
    _
    --
    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/

  3. [PATCH 20/21] fat: ->i_pos race fix


    i_pos is 64bits value, hence it's not atomic to update.

    Important place is fat_write_inode() only, other places without lock
    are just for printk().

    This adds lock for "BITS_PER_LONG == 32" kernel.

    Signed-off-by: OGAWA Hirofumi
    ---

    fs/fat/inode.c | 21 +++++++++++++++++++--
    1 file changed, 19 insertions(+), 2 deletions(-)

    diff -puN fs/fat/inode.c~fat_i_pos-race-fix fs/fat/inode.c
    --- linux-2.6/fs/fat/inode.c~fat_i_pos-race-fix 2008-09-29 19:04:03.000000000 +0900
    +++ linux-2.6-hirofumi/fs/fat/inode.c 2008-09-29 19:04:03.000000000 +0900
    @@ -542,6 +542,20 @@ static int fat_statfs(struct dentry *den
    return 0;
    }

    +static inline loff_t fat_i_pos_read(struct msdos_sb_info *sbi,
    + struct inode *inode)
    +{
    + loff_t i_pos;
    +#if BITS_PER_LONG == 32
    + spin_lock(&sbi->inode_hash_lock);
    +#endif
    + i_pos = MSDOS_I(inode)->i_pos;
    +#if BITS_PER_LONG == 32
    + spin_unlock(&sbi->inode_hash_lock);
    +#endif
    + return i_pos;
    +}
    +
    static int fat_write_inode(struct inode *inode, int wait)
    {
    struct super_block *sb = inode->i_sb;
    @@ -551,9 +565,12 @@ static int fat_write_inode(struct inode
    loff_t i_pos;
    int err;

    + if (inode->i_ino == MSDOS_ROOT_INO)
    + return 0;
    +
    retry:
    - i_pos = MSDOS_I(inode)->i_pos;
    - if (inode->i_ino == MSDOS_ROOT_INO || !i_pos)
    + i_pos = fat_i_pos_read(sbi, inode);
    + if (!i_pos)
    return 0;

    bh = sb_bread(sb, i_pos >> sbi->dir_per_block_bits);
    _
    --
    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/

  4. [PATCH 15/21] fat: Fix ATTR_RO in the case of (~umask & S_WUGO) == 0


    If inode->i_mode doesn't have S_WUGO, current code assumes it means
    ATTR_RO. However, if (~[ufd]mask & S_WUGO) == 0, inode->i_mode can't
    hold S_WUGO. Therefore the updated directory entry will always have
    ATTR_RO.

    This adds fat_mode_can_hold_ro() to check it. And if inode->i_mode
    can't hold, uses -i_attrs to hold ATTR_RO instead.

    With this, we don't set ATTR_RO unless users change it via ioctl() if
    (~[ufd]mask & S_WUGO) == 0.

    And on FAT_IOCTL_GET_ATTRIBUTES path, this adds ->i_mutex to it for
    not returning the partially updated attributes by FAT_IOCTL_SET_ATTRIBUTES
    to userland.

    Signed-off-by: OGAWA Hirofumi
    ---

    fs/fat/fat.h | 33 +++++++++++++++++++++++++++++----
    fs/fat/file.c | 7 ++++++-
    2 files changed, 35 insertions(+), 5 deletions(-)

    diff -puN fs/fat/fat.h~fat-attrs-fixes fs/fat/fat.h
    --- linux-2.6/fs/fat/fat.h~fat-attrs-fixes 2008-10-13 01:49:49.000000000 +0900
    +++ linux-2.6-hirofumi/fs/fat/fat.h 2008-10-13 01:49:49.000000000 +0900
    @@ -117,6 +117,25 @@ static inline struct msdos_inode_info *M
    return container_of(inode, struct msdos_inode_info, vfs_inode);
    }

    +/*
    + * If ->i_mode can't hold S_IWUGO (i.e. ATTR_RO), we use ->i_attrs to
    + * save ATTR_RO instead of ->i_mode.
    + */
    +static inline int fat_mode_can_hold_ro(struct inode *inode)
    +{
    + struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
    + mode_t mask;
    +
    + if (S_ISDIR(inode->i_mode))
    + mask = ~sbi->options.fs_dmask;
    + else
    + mask = ~sbi->options.fs_fmask;
    +
    + if (!(mask & S_IWUGO))
    + return 0;
    + return 1;
    +}
    +
    /* Convert attribute bits and a mask to the UNIX mode. */
    static inline mode_t fat_make_mode(struct msdos_sb_info *sbi,
    u8 attrs, mode_t mode)
    @@ -133,14 +152,20 @@ static inline mode_t fat_make_mode(struc
    /* Return the FAT attribute byte for this inode */
    static inline u8 fat_make_attrs(struct inode *inode)
    {
    - return ((inode->i_mode & S_IWUGO) ? ATTR_NONE : ATTR_RO) |
    - (S_ISDIR(inode->i_mode) ? ATTR_DIR : ATTR_NONE) |
    - MSDOS_I(inode)->i_attrs;
    + u8 attrs = MSDOS_I(inode)->i_attrs;
    + if (S_ISDIR(inode->i_mode))
    + attrs |= ATTR_DIR;
    + if (fat_mode_can_hold_ro(inode) && !(inode->i_mode & S_IWUGO))
    + attrs |= ATTR_RO;
    + return attrs;
    }

    static inline void fat_save_attrs(struct inode *inode, u8 attrs)
    {
    - MSDOS_I(inode)->i_attrs = attrs & ATTR_UNUSED;
    + if (fat_mode_can_hold_ro(inode))
    + MSDOS_I(inode)->i_attrs = attrs & ATTR_UNUSED;
    + else
    + MSDOS_I(inode)->i_attrs = attrs & (ATTR_UNUSED | ATTR_RO);
    }

    static inline unsigned char fat_checksum(const __u8 *name)
    diff -puN fs/fat/file.c~fat-attrs-fixes fs/fat/file.c
    --- linux-2.6/fs/fat/file.c~fat-attrs-fixes 2008-10-13 01:49:49.000000000 +0900
    +++ linux-2.6-hirofumi/fs/fat/file.c 2008-10-13 01:49:49.000000000 +0900
    @@ -27,7 +27,12 @@ int fat_generic_ioctl(struct inode *inod
    switch (cmd) {
    case FAT_IOCTL_GET_ATTRIBUTES:
    {
    - u32 attr = fat_make_attrs(inode);
    + u32 attr;
    +
    + mutex_lock(&inode->i_mutex);
    + attr = fat_make_attrs(inode);
    + mutex_unlock(&inode->i_mutex);
    +
    return put_user(attr, user_attr);
    }
    case FAT_IOCTL_SET_ATTRIBUTES:
    _
    --
    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/

  5. [PATCH 17/21] fat: Fix _fat_bmap() race


    fat_get_cluster() assumes the requested blocknr isn't truncated during
    read. _fat_bmap() doesn't follow this rule.

    This protects it by ->i_mutex.

    Signed-off-by: OGAWA Hirofumi
    ---

    fs/fat/inode.c | 9 ++++++++-
    1 file changed, 8 insertions(+), 1 deletion(-)

    diff -puN fs/fat/inode.c~fat_fat_bmap-fix fs/fat/inode.c
    --- linux-2.6/fs/fat/inode.c~fat_fat_bmap-fix 2008-09-14 05:25:34.000000000 +0900
    +++ linux-2.6-hirofumi/fs/fat/inode.c 2008-09-14 06:28:26.000000000 +0900
    @@ -199,7 +199,14 @@ static ssize_t fat_direct_IO(int rw, str

    static sector_t _fat_bmap(struct address_space *mapping, sector_t block)
    {
    - return generic_block_bmap(mapping, block, fat_get_block);
    + sector_t blocknr;
    +
    + /* fat_get_cluster() assumes the requested blocknr isn't truncated. */
    + mutex_lock(&mapping->host->i_mutex);
    + blocknr = generic_block_bmap(mapping, block, fat_get_block);
    + mutex_unlock(&mapping->host->i_mutex);
    +
    + return blocknr;
    }

    static const struct address_space_operations fat_aops = {
    _
    --
    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/

  6. [PATCH 19/21] fat: mmu_private race fix


    mmu_private is 64bits value, hence it's not atomic to update.

    So, the access rule for mmu_private is we must hold ->i_mutex. But,
    fat_get_block() path doesn't follow the rule on non-allocation path.

    This fixes by using i_size instead if non-allocation path.

    Signed-off-by: OGAWA Hirofumi
    ---

    fs/fat/cache.c | 23 ++++++++++++++++++-----
    fs/fat/dir.c | 2 +-
    fs/fat/fat.h | 6 ++++--
    fs/fat/inode.c | 4 ++--
    4 files changed, 25 insertions(+), 10 deletions(-)

    diff -puN fs/fat/cache.c~fat-mmu_private-race-fix fs/fat/cache.c
    --- linux-2.6/fs/fat/cache.c~fat-mmu_private-race-fix 2008-09-29 13:58:53.000000000 +0900
    +++ linux-2.6-hirofumi/fs/fat/cache.c 2008-09-29 19:08:39.000000000 +0900
    @@ -293,10 +293,12 @@ static int fat_bmap_cluster(struct inode
    }

    int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys,
    - unsigned long *mapped_blocks)
    + unsigned long *mapped_blocks, int create)
    {
    struct super_block *sb = inode->i_sb;
    struct msdos_sb_info *sbi = MSDOS_SB(sb);
    + const unsigned long blocksize = sb->s_blocksize;
    + const unsigned char blocksize_bits = sb->s_blocksize_bits;
    sector_t last_block;
    int cluster, offset;

    @@ -309,10 +311,21 @@ int fat_bmap(struct inode *inode, sector
    }
    return 0;
    }
    - last_block = (MSDOS_I(inode)->mmu_private + (sb->s_blocksize - 1))
    - >> sb->s_blocksize_bits;
    - if (sector >= last_block)
    - return 0;
    +
    + last_block = (i_size_read(inode) + (blocksize - 1)) >> blocksize_bits;
    + if (sector >= last_block) {
    + if (!create)
    + return 0;
    +
    + /*
    + * ->mmu_private can access on only allocation path.
    + * (caller must hold ->i_mutex)
    + */
    + last_block = (MSDOS_I(inode)->mmu_private + (blocksize - 1))
    + >> blocksize_bits;
    + if (sector >= last_block)
    + return 0;
    + }

    cluster = sector >> (sbi->cluster_bits - sb->s_blocksize_bits);
    offset = sector & (sbi->sec_per_clus - 1);
    diff -puN fs/fat/dir.c~fat-mmu_private-race-fix fs/fat/dir.c
    --- linux-2.6/fs/fat/dir.c~fat-mmu_private-race-fix 2008-09-29 13:58:53.000000000 +0900
    +++ linux-2.6-hirofumi/fs/fat/dir.c 2008-09-29 19:08:39.000000000 +0900
    @@ -77,7 +77,7 @@ next:

    *bh = NULL;
    iblock = *pos >> sb->s_blocksize_bits;
    - err = fat_bmap(dir, iblock, &phys, &mapped_blocks);
    + err = fat_bmap(dir, iblock, &phys, &mapped_blocks, 0);
    if (err || !phys)
    return -1; /* beyond EOF or error */

    diff -puN fs/fat/fat.h~fat-mmu_private-race-fix fs/fat/fat.h
    --- linux-2.6/fs/fat/fat.h~fat-mmu_private-race-fix 2008-09-29 13:58:53.000000000 +0900
    +++ linux-2.6-hirofumi/fs/fat/fat.h 2008-09-29 19:14:24.000000000 +0900
    @@ -91,7 +91,9 @@ struct msdos_inode_info {
    /* for avoiding the race between fat_free() and fat_get_cluster() */
    unsigned int cache_valid_id;

    - loff_t mmu_private;
    + /* NOTE: mmu_private is 64bits, so must hold ->i_mutex to access */
    + loff_t mmu_private; /* physically allocated size */
    +
    int i_start; /* first cluster or 0 */
    int i_logstart; /* logical first cluster */
    int i_attrs; /* unused attribute bits */
    @@ -222,7 +224,7 @@ extern void fat_cache_inval_inode(struct
    extern int fat_get_cluster(struct inode *inode, int cluster,
    int *fclus, int *dclus);
    extern int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys,
    - unsigned long *mapped_blocks);
    + unsigned long *mapped_blocks, int create);

    /* fat/dir.c */
    extern const struct file_operations fat_dir_operations;
    diff -puN fs/fat/inode.c~fat-mmu_private-race-fix fs/fat/inode.c
    --- linux-2.6/fs/fat/inode.c~fat-mmu_private-race-fix 2008-09-29 13:58:53.000000000 +0900
    +++ linux-2.6-hirofumi/fs/fat/inode.c 2008-09-29 19:08:40.000000000 +0900
    @@ -64,7 +64,7 @@ static inline int __fat_get_block(struct
    sector_t phys;
    int err, offset;

    - err = fat_bmap(inode, iblock, &phys, &mapped_blocks);
    + err = fat_bmap(inode, iblock, &phys, &mapped_blocks, create);
    if (err)
    return err;
    if (phys) {
    @@ -94,7 +94,7 @@ static inline int __fat_get_block(struct
    *max_blocks = min(mapped_blocks, *max_blocks);
    MSDOS_I(inode)->mmu_private += *max_blocks << sb->s_blocksize_bits;

    - err = fat_bmap(inode, iblock, &phys, &mapped_blocks);
    + err = fat_bmap(inode, iblock, &phys, &mapped_blocks, create);
    if (err)
    return err;

    _
    --
    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/

+ Reply to Thread