#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/seq_file.h>
-#include <linux/msdos_fs.h>
#include <linux/pagemap.h>
#include <linux/mpage.h>
#include <linux/buffer_head.h>
#include <linux/writeback.h>
#include <linux/log2.h>
#include <asm/unaligned.h>
+#include "fat.h"
#ifndef CONFIG_FAT_DEFAULT_IOCHARSET
/* if user don't select VFAT, this is undefined. */
if (rw == WRITE) {
/*
- * FIXME: blockdev_direct_IO() doesn't use ->prepare_write(),
+ * FIXME: blockdev_direct_IO() doesn't use ->write_begin(),
* so we need to update the ->mmu_private to block boundary.
*
* But we must fill the remaining area or hole by nul for
struct buffer_head *bh;
struct msdos_dir_entry *raw_entry;
loff_t i_pos;
- int err = 0;
+ int err;
retry:
i_pos = MSDOS_I(inode)->i_pos;
if (inode->i_ino == MSDOS_ROOT_INO || !i_pos)
return 0;
- lock_super(sb);
bh = sb_bread(sb, i_pos >> sbi->dir_per_block_bits);
if (!bh) {
printk(KERN_ERR "FAT: unable to read inode block "
"for updating (i_pos %lld)\n", i_pos);
- err = -EIO;
- goto out;
+ return -EIO;
}
spin_lock(&sbi->inode_hash_lock);
if (i_pos != MSDOS_I(inode)->i_pos) {
spin_unlock(&sbi->inode_hash_lock);
brelse(bh);
- unlock_super(sb);
goto retry;
}
}
spin_unlock(&sbi->inode_hash_lock);
mark_buffer_dirty(bh);
+ err = 0;
if (wait)
err = sync_dirty_buffer(bh);
brelse(bh);
-out:
- unlock_super(sb);
return err;
}
inode = NULL;
}
}
- if (!inode) {
- /* For now, do nothing
- * What we could do is:
- * follow the file starting at fh[4], and record
- * the ".." entry, and the name of the fh[2] entry.
- * The follow the ".." file finding the next step up.
- * This way we build a path to the root of
- * the tree. If this works, we lookup the path and so
- * get this inode into the cache.
- * Finally try the fat_iget lookup again
- * If that fails, then weare totally out of luck
- * But all that is for another day
- */
- }
- if (!inode)
- return ERR_PTR(-ESTALE);
-
- /* now to find a dentry.
- * If possible, get a well-connected one
+ /*
+ * For now, do nothing if the inode is not found.
+ *
+ * What we could do is:
+ *
+ * - follow the file starting at fh[4], and record the ".." entry,
+ * and the name of the fh[2] entry.
+ * - then follow the ".." file finding the next step up.
+ *
+ * This way we build a path to the root of the tree. If this works, we
+ * lookup the path and so get this inode into the cache. Finally try
+ * the fat_iget lookup again. If that fails, then we are totally out
+ * of luck. But all that is for another day
*/
- result = d_alloc_anon(inode);
- if (result == NULL) {
- iput(inode);
- return ERR_PTR(-ENOMEM);
- }
- result->d_op = sb->s_root->d_op;
+ result = d_obtain_alias(inode);
+ if (!IS_ERR(result))
+ result->d_op = sb->s_root->d_op;
return result;
}
}
inode = fat_build_inode(sb, de, i_pos);
brelse(bh);
- if (IS_ERR(inode)) {
- parent = ERR_CAST(inode);
- goto out;
- }
- parent = d_alloc_anon(inode);
- if (!parent) {
- iput(inode);
- parent = ERR_PTR(-ENOMEM);
- }
+
+ parent = d_obtain_alias(inode);
out:
unlock_super(sb);
Opt_obsolate, Opt_flush, Opt_tz_utc, Opt_err,
};
-static match_table_t fat_tokens = {
+static const match_table_t fat_tokens = {
{Opt_check_r, "check=relaxed"},
{Opt_check_s, "check=strict"},
{Opt_check_n, "check=normal"},
{Opt_tz_utc, "tz=UTC"},
{Opt_err, NULL},
};
-static match_table_t msdos_tokens = {
+static const match_table_t msdos_tokens = {
{Opt_nodots, "nodots"},
{Opt_nodots, "dotsOK=no"},
{Opt_dots, "dots"},
{Opt_dots, "dotsOK=yes"},
{Opt_err, NULL}
};
-static match_table_t vfat_tokens = {
+static const match_table_t vfat_tokens = {
{Opt_charset, "iocharset=%s"},
{Opt_shortname_lower, "shortname=lower"},
{Opt_shortname_win95, "shortname=win95"},