[PATCH] dm: noflush resizing (1/3) Add bdlookup()

2007-10-24 Thread Jun'ichi Nomura
This patch adds bdlookup() and bdlookup_disk().
They are lookup-only variant of bdget()/bdget_disk().

The function can be used when
  - the caller wants to get bdev only if somebody already got it
(i.e. there is already bd_inode allocated in memory)
  - the race between bdlookup() and bdget() is acceptable

The patch is a preparation for the 2nd part of this patchset.

Background:
  inode is initialized with I_LOCK and I_NEW turned on.
  After initialization, both flags are turned off.

  bdget() uses iget5_locked(), which waits until I_LOCK is removed.
  It could take so long or forever.


Signed-off-by: Jun'ichi Nomura <[EMAIL PROTECTED]>

---
 fs/block_dev.c|   27 +++
 include/linux/fs.h|4 +++-
 include/linux/genhd.h |6 ++
 3 files changed, 36 insertions(+), 1 deletion(-)

Index: linux-2.6.23.work/fs/block_dev.c
===
--- linux-2.6.23.work.orig/fs/block_dev.c
+++ linux-2.6.23.work/fs/block_dev.c
@@ -586,6 +586,33 @@ struct block_device *bdget(dev_t dev)
 
 EXPORT_SYMBOL(bdget);
 
+/*
+ * Variant of bdget(), which returns bdev only when it is already gotten.
+ *
+ * The function can be used when:
+ *   - the caller wants to get bdev only if somebody already got it
+ * (i.e. there is already bd_inode allocated in memory)
+ * and
+ *   - the race between bdlookup() and bdget() is acceptable
+ */
+struct block_device *bdlookup(dev_t dev)
+{
+   struct inode *inode;
+
+   might_sleep();
+
+   /* Use _nowait because we don't want to wait for I_LOCK */
+   inode = ilookup5_nowait(bd_mnt->mnt_sb, hash(dev), bdev_test, );
+
+   if (!inode)
+   return NULL;
+
+   wait_on_bit(>i_state, __I_NEW, inode_wait, TASK_UNINTERRUPTIBLE);
+
+   return _I(inode)->bdev;
+}
+EXPORT_SYMBOL(bdlookup);
+
 long nr_blockdev_pages(void)
 {
struct block_device *bdev;
Index: linux-2.6.23.work/include/linux/fs.h
===
--- linux-2.6.23.work.orig/include/linux/fs.h
+++ linux-2.6.23.work/include/linux/fs.h
@@ -1211,10 +1211,11 @@ struct super_operations {
 #define I_DIRTY_DATASYNC   2 /* Data-related inode changes pending */
 #define I_DIRTY_PAGES  4 /* Data-related inode changes pending */
 #define __I_LOCK   3
+#define __I_NEW6
 #define I_LOCK (1 << __I_LOCK)
 #define I_FREEING  16
 #define I_CLEAR32
-#define I_NEW  64
+#define I_NEW  (1 << __I_NEW)
 #define I_WILL_FREE128
 
 #define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)
@@ -1431,6 +1432,7 @@ extern void putname(const char *name);
 extern int register_blkdev(unsigned int, const char *);
 extern void unregister_blkdev(unsigned int, const char *);
 extern struct block_device *bdget(dev_t);
+extern struct block_device *bdlookup(dev_t);
 extern void bd_set_size(struct block_device *, loff_t size);
 extern void bd_forget(struct inode *inode);
 extern void bdput(struct block_device *);
Index: linux-2.6.23.work/include/linux/genhd.h
===
--- linux-2.6.23.work.orig/include/linux/genhd.h
+++ linux-2.6.23.work/include/linux/genhd.h
@@ -435,6 +435,12 @@ static inline struct block_device *bdget
return bdget(MKDEV(disk->major, disk->first_minor) + index);
 }
 
+static inline struct block_device *bdlookup_disk(struct gendisk *disk,
+int index)
+{
+   return bdlookup(MKDEV(disk->major, disk->first_minor) + index);
+}
+
 #endif
 
 #else /* CONFIG_BLOCK */
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] dm: noflush resizing (1/3) Add bdlookup()

2007-10-24 Thread Jun'ichi Nomura
This patch adds bdlookup() and bdlookup_disk().
They are lookup-only variant of bdget()/bdget_disk().

The function can be used when
  - the caller wants to get bdev only if somebody already got it
(i.e. there is already bd_inode allocated in memory)
  - the race between bdlookup() and bdget() is acceptable

The patch is a preparation for the 2nd part of this patchset.

Background:
  inode is initialized with I_LOCK and I_NEW turned on.
  After initialization, both flags are turned off.

  bdget() uses iget5_locked(), which waits until I_LOCK is removed.
  It could take so long or forever.


Signed-off-by: Jun'ichi Nomura [EMAIL PROTECTED]

---
 fs/block_dev.c|   27 +++
 include/linux/fs.h|4 +++-
 include/linux/genhd.h |6 ++
 3 files changed, 36 insertions(+), 1 deletion(-)

Index: linux-2.6.23.work/fs/block_dev.c
===
--- linux-2.6.23.work.orig/fs/block_dev.c
+++ linux-2.6.23.work/fs/block_dev.c
@@ -586,6 +586,33 @@ struct block_device *bdget(dev_t dev)
 
 EXPORT_SYMBOL(bdget);
 
+/*
+ * Variant of bdget(), which returns bdev only when it is already gotten.
+ *
+ * The function can be used when:
+ *   - the caller wants to get bdev only if somebody already got it
+ * (i.e. there is already bd_inode allocated in memory)
+ * and
+ *   - the race between bdlookup() and bdget() is acceptable
+ */
+struct block_device *bdlookup(dev_t dev)
+{
+   struct inode *inode;
+
+   might_sleep();
+
+   /* Use _nowait because we don't want to wait for I_LOCK */
+   inode = ilookup5_nowait(bd_mnt-mnt_sb, hash(dev), bdev_test, dev);
+
+   if (!inode)
+   return NULL;
+
+   wait_on_bit(inode-i_state, __I_NEW, inode_wait, TASK_UNINTERRUPTIBLE);
+
+   return BDEV_I(inode)-bdev;
+}
+EXPORT_SYMBOL(bdlookup);
+
 long nr_blockdev_pages(void)
 {
struct block_device *bdev;
Index: linux-2.6.23.work/include/linux/fs.h
===
--- linux-2.6.23.work.orig/include/linux/fs.h
+++ linux-2.6.23.work/include/linux/fs.h
@@ -1211,10 +1211,11 @@ struct super_operations {
 #define I_DIRTY_DATASYNC   2 /* Data-related inode changes pending */
 #define I_DIRTY_PAGES  4 /* Data-related inode changes pending */
 #define __I_LOCK   3
+#define __I_NEW6
 #define I_LOCK (1  __I_LOCK)
 #define I_FREEING  16
 #define I_CLEAR32
-#define I_NEW  64
+#define I_NEW  (1  __I_NEW)
 #define I_WILL_FREE128
 
 #define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)
@@ -1431,6 +1432,7 @@ extern void putname(const char *name);
 extern int register_blkdev(unsigned int, const char *);
 extern void unregister_blkdev(unsigned int, const char *);
 extern struct block_device *bdget(dev_t);
+extern struct block_device *bdlookup(dev_t);
 extern void bd_set_size(struct block_device *, loff_t size);
 extern void bd_forget(struct inode *inode);
 extern void bdput(struct block_device *);
Index: linux-2.6.23.work/include/linux/genhd.h
===
--- linux-2.6.23.work.orig/include/linux/genhd.h
+++ linux-2.6.23.work/include/linux/genhd.h
@@ -435,6 +435,12 @@ static inline struct block_device *bdget
return bdget(MKDEV(disk-major, disk-first_minor) + index);
 }
 
+static inline struct block_device *bdlookup_disk(struct gendisk *disk,
+int index)
+{
+   return bdlookup(MKDEV(disk-major, disk-first_minor) + index);
+}
+
 #endif
 
 #else /* CONFIG_BLOCK */
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/