Merge tag 'for-linus' of git://github.com/prasad-joshi/logfs_upstream
Linus Torvalds [Tue, 31 Jan 2012 17:23:59 +0000 (09:23 -0800)]
There are few important bug fixes for LogFS

* tag 'for-linus' of git://github.com/prasad-joshi/logfs_upstream:
  Logfs: Allow NULL block_isbad() methods
  logfs: Grow inode in delete path
  logfs: Free areas before calling generic_shutdown_super()
  logfs: remove useless BUG_ON
  MAINTAINERS: Add Prasad Joshi in LogFS maintiners
  logfs: Propagate page parameter to __logfs_write_inode
  logfs: set superblock shutdown flag after generic sb shutdown
  logfs: take write mutex lock during fsync and sync
  logfs: Prevent memory corruption
  logfs: update page reference count for pined pages

Fix up conflict in fs/logfs/dev_mtd.c due to semantic change in what
"mtd->block_isbad" means in commit f2933e86ad93: "Logfs: Allow NULL
block_isbad() methods" clashing with the abstraction changes in the
commits 7086c19d0742: "mtd: introduce mtd_block_isbad interface" and
d58b27ed58a3: "logfs: do not use 'mtd->block_isbad' directly".

This resolution takes the semantics from commit f2933e86ad93, and just
makes mtd_block_isbad() return zero (false) if the 'block_isbad'
function is NULL.  But that also means that now "mtd_can_have_bb()"
always returns 0.

Now, "mtd_block_markbad()" will obviously return an error if the
low-level driver doesn't support bad blocks, so this is somewhat
non-symmetric, but it actually makes sense if a NULL "block_isbad"
function is considered to mean "I assume that all my blocks are always
good".

1  2 
MAINTAINERS
fs/logfs/dir.c
fs/logfs/inode.c
fs/logfs/logfs.h
include/linux/mtd/mtd.h

diff --cc MAINTAINERS
Simple merge
diff --cc fs/logfs/dir.c
Simple merge
Simple merge
Simple merge
@@@ -238,218 -265,18 +238,218 @@@ struct mtd_info 
        struct module *owner;
        struct device dev;
        int usecount;
 -
 -      /* If the driver is something smart, like UBI, it may need to maintain
 -       * its own reference counting. The below functions are only for driver.
 -       * The driver may register its callbacks. These callbacks are not
 -       * supposed to be called by MTD users */
 -      int (*get_device) (struct mtd_info *mtd);
 -      void (*put_device) (struct mtd_info *mtd);
  };
  
 -static inline struct mtd_info *dev_to_mtd(struct device *dev)
 +/*
 + * Erase is an asynchronous operation.  Device drivers are supposed
 + * to call instr->callback() whenever the operation completes, even
 + * if it completes with a failure.
 + * Callers are supposed to pass a callback function and wait for it
 + * to be called before writing to the block.
 + */
 +static inline int mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
 +{
 +      return mtd->erase(mtd, instr);
 +}
 +
 +/*
 + * This stuff for eXecute-In-Place. phys is optional and may be set to NULL.
 + */
 +static inline int mtd_point(struct mtd_info *mtd, loff_t from, size_t len,
 +                          size_t *retlen, void **virt, resource_size_t *phys)
 +{
 +      *retlen = 0;
 +      if (!mtd->point)
 +              return -EOPNOTSUPP;
 +      return mtd->point(mtd, from, len, retlen, virt, phys);
 +}
 +
 +/* We probably shouldn't allow XIP if the unpoint isn't a NULL */
 +static inline void mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
  {
 -      return dev ? dev_get_drvdata(dev) : NULL;
 +      return mtd->unpoint(mtd, from, len);
 +}
 +
 +/*
 + * Allow NOMMU mmap() to directly map the device (if not NULL)
 + * - return the address to which the offset maps
 + * - return -ENOSYS to indicate refusal to do the mapping
 + */
 +static inline unsigned long mtd_get_unmapped_area(struct mtd_info *mtd,
 +                                                unsigned long len,
 +                                                unsigned long offset,
 +                                                unsigned long flags)
 +{
 +      if (!mtd->get_unmapped_area)
 +              return -EOPNOTSUPP;
 +      return mtd->get_unmapped_area(mtd, len, offset, flags);
 +}
 +
 +static inline int mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
 +                         size_t *retlen, u_char *buf)
 +{
 +      return mtd->read(mtd, from, len, retlen, buf);
 +}
 +
 +static inline int mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
 +                          size_t *retlen, const u_char *buf)
 +{
 +      *retlen = 0;
 +      if (!mtd->write)
 +              return -EROFS;
 +      return mtd->write(mtd, to, len, retlen, buf);
 +}
 +
 +/*
 + * In blackbox flight recorder like scenarios we want to make successful writes
 + * in interrupt context. panic_write() is only intended to be called when its
 + * known the kernel is about to panic and we need the write to succeed. Since
 + * the kernel is not going to be running for much longer, this function can
 + * break locks and delay to ensure the write succeeds (but not sleep).
 + */
 +static inline int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
 +                                size_t *retlen, const u_char *buf)
 +{
 +      *retlen = 0;
 +      if (!mtd->panic_write)
 +              return -EOPNOTSUPP;
 +      return mtd->panic_write(mtd, to, len, retlen, buf);
 +}
 +
 +static inline int mtd_read_oob(struct mtd_info *mtd, loff_t from,
 +                             struct mtd_oob_ops *ops)
 +{
 +      ops->retlen = ops->oobretlen = 0;
 +      if (!mtd->read_oob)
 +              return -EOPNOTSUPP;
 +      return mtd->read_oob(mtd, from, ops);
 +}
 +
 +static inline int mtd_write_oob(struct mtd_info *mtd, loff_t to,
 +                              struct mtd_oob_ops *ops)
 +{
 +      ops->retlen = ops->oobretlen = 0;
 +      if (!mtd->write_oob)
 +              return -EOPNOTSUPP;
 +      return mtd->write_oob(mtd, to, ops);
 +}
 +
 +/*
 + * Method to access the protection register area, present in some flash
 + * devices. The user data is one time programmable but the factory data is read
 + * only.
 + */
 +static inline int mtd_get_fact_prot_info(struct mtd_info *mtd,
 +                                       struct otp_info *buf, size_t len)
 +{
 +      if (!mtd->get_fact_prot_info)
 +              return -EOPNOTSUPP;
 +      return mtd->get_fact_prot_info(mtd, buf, len);
 +}
 +
 +static inline int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
 +                                       size_t len, size_t *retlen,
 +                                       u_char *buf)
 +{
 +      *retlen = 0;
 +      if (!mtd->read_fact_prot_reg)
 +              return -EOPNOTSUPP;
 +      return mtd->read_fact_prot_reg(mtd, from, len, retlen, buf);
 +}
 +
 +static inline int mtd_get_user_prot_info(struct mtd_info *mtd,
 +                                       struct otp_info *buf,
 +                                       size_t len)
 +{
 +      if (!mtd->get_user_prot_info)
 +              return -EOPNOTSUPP;
 +      return mtd->get_user_prot_info(mtd, buf, len);
 +}
 +
 +static inline int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from,
 +                                       size_t len, size_t *retlen,
 +                                       u_char *buf)
 +{
 +      *retlen = 0;
 +      if (!mtd->read_user_prot_reg)
 +              return -EOPNOTSUPP;
 +      return mtd->read_user_prot_reg(mtd, from, len, retlen, buf);
 +}
 +
 +static inline int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to,
 +                                        size_t len, size_t *retlen,
 +                                        u_char *buf)
 +{
 +      *retlen = 0;
 +      if (!mtd->write_user_prot_reg)
 +              return -EOPNOTSUPP;
 +      return mtd->write_user_prot_reg(mtd, to, len, retlen, buf);
 +}
 +
 +static inline int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
 +                                       size_t len)
 +{
 +      if (!mtd->lock_user_prot_reg)
 +              return -EOPNOTSUPP;
 +      return mtd->lock_user_prot_reg(mtd, from, len);
 +}
 +
 +int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
 +             unsigned long count, loff_t to, size_t *retlen);
 +
 +static inline void mtd_sync(struct mtd_info *mtd)
 +{
 +      if (mtd->sync)
 +              mtd->sync(mtd);
 +}
 +
 +/* Chip-supported device locking */
 +static inline int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 +{
 +      if (!mtd->lock)
 +              return -EOPNOTSUPP;
 +      return mtd->lock(mtd, ofs, len);
 +}
 +
 +static inline int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 +{
 +      if (!mtd->unlock)
 +              return -EOPNOTSUPP;
 +      return mtd->unlock(mtd, ofs, len);
 +}
 +
 +static inline int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 +{
 +      if (!mtd->is_locked)
 +              return -EOPNOTSUPP;
 +      return mtd->is_locked(mtd, ofs, len);
 +}
 +
 +static inline int mtd_suspend(struct mtd_info *mtd)
 +{
 +      if (!mtd->suspend)
 +              return -EOPNOTSUPP;
 +      return mtd->suspend(mtd);
 +}
 +
 +static inline void mtd_resume(struct mtd_info *mtd)
 +{
 +      if (mtd->resume)
 +              mtd->resume(mtd);
 +}
 +
 +static inline int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs)
 +{
 +      if (!mtd->block_isbad)
-               return -EOPNOTSUPP;
++              return 0;
 +      return mtd->block_isbad(mtd, ofs);
 +}
 +
 +static inline int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs)
 +{
 +      if (!mtd->block_markbad)
 +              return -EOPNOTSUPP;
 +      return mtd->block_markbad(mtd, ofs);
  }
  
  static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd)
@@@ -482,16 -309,6 +482,16 @@@ static inline uint32_t mtd_mod_by_ws(ui
        return do_div(sz, mtd->writesize);
  }
  
 +static inline int mtd_has_oob(const struct mtd_info *mtd)
 +{
 +      return mtd->read_oob && mtd->write_oob;
 +}
 +
 +static inline int mtd_can_have_bb(const struct mtd_info *mtd)
 +{
-       return !!mtd->block_isbad;
++      return 0;
 +}
 +
        /* Kernel-side ioctl definitions */
  
  struct mtd_partition;