Consolidate all dentry manipulation code in libfs in a single
source file.

Signed-off-by: Arnd Bergmann <[EMAIL PROTECTED]>

Index: linux-2.6/fs/libfs.c
===================================================================
--- linux-2.6.orig/fs/libfs.c
+++ linux-2.6/fs/libfs.c
@@ -12,188 +12,6 @@
 
 #include <asm/uaccess.h>
 
-int simple_getattr(struct vfsmount *mnt, struct dentry *dentry,
-                  struct kstat *stat)
-{
-       struct inode *inode = dentry->d_inode;
-       generic_fillattr(inode, stat);
-       stat->blocks = inode->i_mapping->nrpages << (PAGE_CACHE_SHIFT - 9);
-       return 0;
-}
-
-int simple_statfs(struct dentry *dentry, struct kstatfs *buf)
-{
-       buf->f_type = dentry->d_sb->s_magic;
-       buf->f_bsize = PAGE_CACHE_SIZE;
-       buf->f_namelen = NAME_MAX;
-       return 0;
-}
-
-/*
- * Retaining negative dentries for an in-memory filesystem just wastes
- * memory and lookup time: arrange for them to be deleted immediately.
- */
-static int simple_delete_dentry(struct dentry *dentry)
-{
-       return 1;
-}
-
-/*
- * Lookup the data. This is trivial - if the dentry didn't already
- * exist, we know it is negative.  Set d_op to delete negative dentries.
- */
-struct dentry *simple_lookup(struct inode *dir, struct dentry *dentry, struct 
nameidata *nd)
-{
-       static struct dentry_operations simple_dentry_operations = {
-               .d_delete = simple_delete_dentry,
-       };
-
-       if (dentry->d_name.len > NAME_MAX)
-               return ERR_PTR(-ENAMETOOLONG);
-       dentry->d_op = &simple_dentry_operations;
-       d_add(dentry, NULL);
-       return NULL;
-}
-
-int simple_sync_file(struct file * file, struct dentry *dentry, int datasync)
-{
-       return 0;
-}
- 
-int dcache_dir_open(struct inode *inode, struct file *file)
-{
-       static struct qstr cursor_name = {.len = 1, .name = "."};
-
-       file->private_data = d_alloc(file->f_path.dentry, &cursor_name);
-
-       return file->private_data ? 0 : -ENOMEM;
-}
-
-int dcache_dir_close(struct inode *inode, struct file *file)
-{
-       dput(file->private_data);
-       return 0;
-}
-
-loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin)
-{
-       mutex_lock(&file->f_path.dentry->d_inode->i_mutex);
-       switch (origin) {
-               case 1:
-                       offset += file->f_pos;
-               case 0:
-                       if (offset >= 0)
-                               break;
-               default:
-                       mutex_unlock(&file->f_path.dentry->d_inode->i_mutex);
-                       return -EINVAL;
-       }
-       if (offset != file->f_pos) {
-               file->f_pos = offset;
-               if (file->f_pos >= 2) {
-                       struct list_head *p;
-                       struct dentry *cursor = file->private_data;
-                       loff_t n = file->f_pos - 2;
-
-                       spin_lock(&dcache_lock);
-                       list_del(&cursor->d_u.d_child);
-                       p = file->f_path.dentry->d_subdirs.next;
-                       while (n && p != &file->f_path.dentry->d_subdirs) {
-                               struct dentry *next;
-                               next = list_entry(p, struct dentry, 
d_u.d_child);
-                               if (!d_unhashed(next) && next->d_inode)
-                                       n--;
-                               p = p->next;
-                       }
-                       list_add_tail(&cursor->d_u.d_child, p);
-                       spin_unlock(&dcache_lock);
-               }
-       }
-       mutex_unlock(&file->f_path.dentry->d_inode->i_mutex);
-       return offset;
-}
-
-/* Relationship between i_mode and the DT_xxx types */
-static inline unsigned char dt_type(struct inode *inode)
-{
-       return (inode->i_mode >> 12) & 15;
-}
-
-/*
- * Directory is locked and all positive dentries in it are safe, since
- * for ramfs-type trees they can't go away without unlink() or rmdir(),
- * both impossible due to the lock on directory.
- */
-
-int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
-{
-       struct dentry *dentry = filp->f_path.dentry;
-       struct dentry *cursor = filp->private_data;
-       struct list_head *p, *q = &cursor->d_u.d_child;
-       ino_t ino;
-       int i = filp->f_pos;
-
-       switch (i) {
-               case 0:
-                       ino = dentry->d_inode->i_ino;
-                       if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
-                               break;
-                       filp->f_pos++;
-                       i++;
-                       /* fallthrough */
-               case 1:
-                       ino = parent_ino(dentry);
-                       if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
-                               break;
-                       filp->f_pos++;
-                       i++;
-                       /* fallthrough */
-               default:
-                       spin_lock(&dcache_lock);
-                       if (filp->f_pos == 2)
-                               list_move(q, &dentry->d_subdirs);
-
-                       for (p=q->next; p != &dentry->d_subdirs; p=p->next) {
-                               struct dentry *next;
-                               next = list_entry(p, struct dentry, 
d_u.d_child);
-                               if (d_unhashed(next) || !next->d_inode)
-                                       continue;
-
-                               spin_unlock(&dcache_lock);
-                               if (filldir(dirent, next->d_name.name, 
-                                           next->d_name.len, filp->f_pos, 
-                                           next->d_inode->i_ino, 
-                                           dt_type(next->d_inode)) < 0)
-                                       return 0;
-                               spin_lock(&dcache_lock);
-                               /* next is still alive */
-                               list_move(q, p);
-                               p = q;
-                               filp->f_pos++;
-                       }
-                       spin_unlock(&dcache_lock);
-       }
-       return 0;
-}
-
-ssize_t generic_read_dir(struct file *filp, char __user *buf, size_t siz, 
loff_t *ppos)
-{
-       return -EISDIR;
-}
-
-const struct file_operations simple_dir_operations = {
-       .open           = dcache_dir_open,
-       .release        = dcache_dir_close,
-       .llseek         = dcache_dir_lseek,
-       .read           = generic_read_dir,
-       .readdir        = dcache_readdir,
-       .fsync          = simple_sync_file,
-};
-
-const struct inode_operations simple_dir_inode_operations = {
-       .lookup         = simple_lookup,
-};
-
 static const struct super_operations simple_super_operations = {
        .statfs         = simple_statfs,
 };
@@ -420,113 +238,14 @@ ssize_t simple_read_from_buffer(void __u
        return count;
 }
 
-/*
- * This is what d_alloc_anon should have been.  Once the exportfs
- * argument transition has been finished I will update d_alloc_anon
- * to this prototype and this wrapper will go away.   --hch
- */
-static struct dentry *exportfs_d_alloc(struct inode *inode)
-{
-       struct dentry *dentry;
-
-       if (!inode)
-               return NULL;
-       if (IS_ERR(inode))
-               return ERR_PTR(PTR_ERR(inode));
-
-       dentry = d_alloc_anon(inode);
-       if (!dentry) {
-               iput(inode);
-               dentry = ERR_PTR(-ENOMEM);
-       }
-       return dentry;
-}
-
-/**
- * generic_fh_to_dentry - generic helper for the fh_to_dentry export operation
- * @sb:                filesystem to do the file handle conversion on
- * @fid:       file handle to convert
- * @fh_len:    length of the file handle in bytes
- * @fh_type:   type of file handle
- * @get_inode: filesystem callback to retrieve inode
- *
- * This function decodes @fid as long as it has one of the well-known
- * Linux filehandle types and calls @get_inode on it to retrieve the
- * inode for the object specified in the file handle.
- */
-struct dentry *generic_fh_to_dentry(struct super_block *sb, struct fid *fid,
-               int fh_len, int fh_type, struct inode *(*get_inode)
-                       (struct super_block *sb, u64 ino, u32 gen))
-{
-       struct inode *inode = NULL;
-
-       if (fh_len < 2)
-               return NULL;
-
-       switch (fh_type) {
-       case FILEID_INO32_GEN:
-       case FILEID_INO32_GEN_PARENT:
-               inode = get_inode(sb, fid->i32.ino, fid->i32.gen);
-               break;
-       }
-
-       return exportfs_d_alloc(inode);
-}
-EXPORT_SYMBOL_GPL(generic_fh_to_dentry);
-
-/**
- * generic_fh_to_dentry - generic helper for the fh_to_parent export operation
- * @sb:                filesystem to do the file handle conversion on
- * @fid:       file handle to convert
- * @fh_len:    length of the file handle in bytes
- * @fh_type:   type of file handle
- * @get_inode: filesystem callback to retrieve inode
- *
- * This function decodes @fid as long as it has one of the well-known
- * Linux filehandle types and calls @get_inode on it to retrieve the
- * inode for the _parent_ object specified in the file handle if it
- * is specified in the file handle, or NULL otherwise.
- */
-struct dentry *generic_fh_to_parent(struct super_block *sb, struct fid *fid,
-               int fh_len, int fh_type, struct inode *(*get_inode)
-                       (struct super_block *sb, u64 ino, u32 gen))
-{
-       struct inode *inode = NULL;
-
-       if (fh_len <= 2)
-               return NULL;
-
-       switch (fh_type) {
-       case FILEID_INO32_GEN_PARENT:
-               inode = get_inode(sb, fid->i32.parent_ino,
-                                 (fh_len > 3 ? fid->i32.parent_gen : 0));
-               break;
-       }
-
-       return exportfs_d_alloc(inode);
-}
-EXPORT_SYMBOL_GPL(generic_fh_to_parent);
-
-EXPORT_SYMBOL(dcache_dir_close);
-EXPORT_SYMBOL(dcache_dir_lseek);
-EXPORT_SYMBOL(dcache_dir_open);
-EXPORT_SYMBOL(dcache_readdir);
-EXPORT_SYMBOL(generic_read_dir);
 EXPORT_SYMBOL(get_sb_pseudo);
 EXPORT_SYMBOL(simple_write_begin);
 EXPORT_SYMBOL(simple_write_end);
-EXPORT_SYMBOL(simple_dir_inode_operations);
-EXPORT_SYMBOL(simple_dir_operations);
 EXPORT_SYMBOL(simple_empty);
-EXPORT_SYMBOL(d_alloc_name);
-EXPORT_SYMBOL(simple_getattr);
 EXPORT_SYMBOL(simple_link);
-EXPORT_SYMBOL(simple_lookup);
 EXPORT_SYMBOL(simple_prepare_write);
 EXPORT_SYMBOL(simple_readpage);
 EXPORT_SYMBOL(simple_rename);
 EXPORT_SYMBOL(simple_rmdir);
-EXPORT_SYMBOL(simple_statfs);
-EXPORT_SYMBOL(simple_sync_file);
 EXPORT_SYMBOL(simple_unlink);
 EXPORT_SYMBOL(simple_read_from_buffer);
Index: linux-2.6/fs/libfs/dentry.c
===================================================================
--- /dev/null
+++ linux-2.6/fs/libfs/dentry.c
@@ -0,0 +1,293 @@
+/*
+ *     fs/libfs/dentry.c
+ *     Library for filesystems writers -- directory operations
+ */
+
+#include <linux/libfs.h>
+#include <linux/fsnotify.h>
+#include <linux/module.h>
+#include <linux/vfs.h>
+#include <linux/mutex.h>
+#include <linux/exportfs.h>
+
+#include <asm/uaccess.h>
+
+int simple_getattr(struct vfsmount *mnt, struct dentry *dentry,
+                  struct kstat *stat)
+{
+       struct inode *inode = dentry->d_inode;
+       generic_fillattr(inode, stat);
+       stat->blocks = inode->i_mapping->nrpages << (PAGE_CACHE_SHIFT - 9);
+       return 0;
+}
+EXPORT_SYMBOL(simple_getattr);
+
+int simple_statfs(struct dentry *dentry, struct kstatfs *buf)
+{
+       buf->f_type = dentry->d_sb->s_magic;
+       buf->f_bsize = PAGE_CACHE_SIZE;
+       buf->f_namelen = NAME_MAX;
+       return 0;
+}
+EXPORT_SYMBOL(simple_statfs);
+
+/*
+ * Retaining negative dentries for an in-memory filesystem just wastes
+ * memory and lookup time: arrange for them to be deleted immediately.
+ */
+static int simple_delete_dentry(struct dentry *dentry)
+{
+       return 1;
+}
+
+/*
+ * Lookup the data. This is trivial - if the dentry didn't already
+ * exist, we know it is negative.  Set d_op to delete negative dentries.
+ */
+struct dentry *simple_lookup(struct inode *dir, struct dentry *dentry, struct 
nameidata *nd)
+{
+       static struct dentry_operations simple_dentry_operations = {
+               .d_delete = simple_delete_dentry,
+       };
+
+       if (dentry->d_name.len > NAME_MAX)
+               return ERR_PTR(-ENAMETOOLONG);
+       dentry->d_op = &simple_dentry_operations;
+       d_add(dentry, NULL);
+       return NULL;
+}
+EXPORT_SYMBOL(simple_lookup);
+
+int simple_sync_file(struct file *file, struct dentry *dentry, int datasync)
+{
+       return 0;
+}
+EXPORT_SYMBOL(simple_sync_file);
+
+int dcache_dir_open(struct inode *inode, struct file *file)
+{
+       static struct qstr cursor_name = {.len = 1, .name = "."};
+
+       file->private_data = d_alloc(file->f_path.dentry, &cursor_name);
+
+       return file->private_data ? 0 : -ENOMEM;
+}
+EXPORT_SYMBOL(dcache_dir_open);
+
+int dcache_dir_close(struct inode *inode, struct file *file)
+{
+       dput(file->private_data);
+       return 0;
+}
+EXPORT_SYMBOL(dcache_dir_close);
+
+loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin)
+{
+       mutex_lock(&file->f_path.dentry->d_inode->i_mutex);
+       switch (origin) {
+       case 1:
+               offset += file->f_pos;
+       case 0:
+               if (offset >= 0)
+                       break;
+       default:
+               mutex_unlock(&file->f_path.dentry->d_inode->i_mutex);
+               return -EINVAL;
+       }
+       if (offset != file->f_pos) {
+               file->f_pos = offset;
+               if (file->f_pos >= 2) {
+                       struct list_head *p;
+                       struct dentry *cursor = file->private_data;
+                       loff_t n = file->f_pos - 2;
+
+                       spin_lock(&dcache_lock);
+                       list_del(&cursor->d_u.d_child);
+                       p = file->f_path.dentry->d_subdirs.next;
+                       while (n && p != &file->f_path.dentry->d_subdirs) {
+                               struct dentry *next;
+                               next = list_entry(p, struct dentry, 
d_u.d_child);
+                               if (!d_unhashed(next) && next->d_inode)
+                                       n--;
+                               p = p->next;
+                       }
+                       list_add_tail(&cursor->d_u.d_child, p);
+                       spin_unlock(&dcache_lock);
+               }
+       }
+       mutex_unlock(&file->f_path.dentry->d_inode->i_mutex);
+       return offset;
+}
+EXPORT_SYMBOL(dcache_dir_lseek);
+
+/* Relationship between i_mode and the DT_xxx types */
+static inline unsigned char dt_type(struct inode *inode)
+{
+       return (inode->i_mode >> 12) & 15;
+}
+
+/*
+ * Directory is locked and all positive dentries in it are safe, since
+ * for ramfs-type trees they can't go away without unlink() or rmdir(),
+ * both impossible due to the lock on directory.
+ */
+
+int dcache_readdir(struct file *filp, void *dirent, filldir_t filldir)
+{
+       struct dentry *dentry = filp->f_path.dentry;
+       struct dentry *cursor = filp->private_data;
+       struct list_head *p, *q = &cursor->d_u.d_child;
+       ino_t ino;
+       int i = filp->f_pos;
+
+       switch (i) {
+       case 0:
+               ino = dentry->d_inode->i_ino;
+               if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
+                       break;
+               filp->f_pos++;
+               i++;
+               /* fallthrough */
+       case 1:
+               ino = parent_ino(dentry);
+               if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
+                       break;
+               filp->f_pos++;
+               i++;
+               /* fallthrough */
+       default:
+               spin_lock(&dcache_lock);
+               if (filp->f_pos == 2)
+                       list_move(q, &dentry->d_subdirs);
+
+               for (p = q->next; p != &dentry->d_subdirs; p = p->next) {
+                       struct dentry *next;
+                       next = list_entry(p, struct dentry, d_u.d_child);
+                       if (d_unhashed(next) || !next->d_inode)
+                               continue;
+
+                       spin_unlock(&dcache_lock);
+                       if (filldir(dirent, next->d_name.name,
+                                   next->d_name.len, filp->f_pos,
+                                   next->d_inode->i_ino,
+                                   dt_type(next->d_inode)) < 0)
+                               return 0;
+                       spin_lock(&dcache_lock);
+                       /* next is still alive */
+                       list_move(q, p);
+                       p = q;
+                       filp->f_pos++;
+               }
+               spin_unlock(&dcache_lock);
+       }
+       return 0;
+}
+EXPORT_SYMBOL(dcache_readdir);
+
+ssize_t generic_read_dir(struct file *filp, char __user *buf, size_t siz, 
loff_t *ppos)
+{
+       return -EISDIR;
+}
+EXPORT_SYMBOL(generic_read_dir);
+
+const struct file_operations simple_dir_operations = {
+       .open           = dcache_dir_open,
+       .release        = dcache_dir_close,
+       .llseek         = dcache_dir_lseek,
+       .read           = generic_read_dir,
+       .readdir        = dcache_readdir,
+       .fsync          = simple_sync_file,
+};
+EXPORT_SYMBOL(simple_dir_operations);
+
+const struct inode_operations simple_dir_inode_operations = {
+       .lookup         = simple_lookup,
+};
+EXPORT_SYMBOL(simple_dir_inode_operations);
+
+/*
+ * This is what d_alloc_anon should have been.  Once the exportfs
+ * argument transition has been finished I will update d_alloc_anon
+ * to this prototype and this wrapper will go away.   --hch
+ */
+static struct dentry *exportfs_d_alloc(struct inode *inode)
+{
+       struct dentry *dentry;
+
+       if (!inode)
+               return NULL;
+       if (IS_ERR(inode))
+               return ERR_PTR(PTR_ERR(inode));
+
+       dentry = d_alloc_anon(inode);
+       if (!dentry) {
+               iput(inode);
+               dentry = ERR_PTR(-ENOMEM);
+       }
+       return dentry;
+}
+
+/**
+ * generic_fh_to_dentry - generic helper for the fh_to_dentry export operation
+ * @sb:                filesystem to do the file handle conversion on
+ * @fid:       file handle to convert
+ * @fh_len:    length of the file handle in bytes
+ * @fh_type:   type of file handle
+ * @get_inode: filesystem callback to retrieve inode
+ *
+ * This function decodes @fid as long as it has one of the well-known
+ * Linux filehandle types and calls @get_inode on it to retrieve the
+ * inode for the object specified in the file handle.
+ */
+struct dentry *generic_fh_to_dentry(struct super_block *sb, struct fid *fid,
+               int fh_len, int fh_type, struct inode *(*get_inode)
+                       (struct super_block *sb, u64 ino, u32 gen))
+{
+       struct inode *inode = NULL;
+
+       if (fh_len < 2)
+               return NULL;
+
+       switch (fh_type) {
+       case FILEID_INO32_GEN:
+       case FILEID_INO32_GEN_PARENT:
+               inode = get_inode(sb, fid->i32.ino, fid->i32.gen);
+               break;
+       }
+
+       return exportfs_d_alloc(inode);
+}
+EXPORT_SYMBOL_GPL(generic_fh_to_dentry);
+
+/**
+ * generic_fh_to_dentry - generic helper for the fh_to_parent export operation
+ * @sb:                filesystem to do the file handle conversion on
+ * @fid:       file handle to convert
+ * @fh_len:    length of the file handle in bytes
+ * @fh_type:   type of file handle
+ * @get_inode: filesystem callback to retrieve inode
+ *
+ * This function decodes @fid as long as it has one of the well-known
+ * Linux filehandle types and calls @get_inode on it to retrieve the
+ * inode for the _parent_ object specified in the file handle if it
+ * is specified in the file handle, or NULL otherwise.
+ */
+struct dentry *generic_fh_to_parent(struct super_block *sb, struct fid *fid,
+               int fh_len, int fh_type, struct inode *(*get_inode)
+                       (struct super_block *sb, u64 ino, u32 gen))
+{
+       struct inode *inode = NULL;
+
+       if (fh_len <= 2)
+               return NULL;
+
+       switch (fh_type) {
+       case FILEID_INO32_GEN_PARENT:
+               inode = get_inode(sb, fid->i32.parent_ino,
+                                 (fh_len > 3 ? fid->i32.parent_gen : 0));
+               break;
+       }
+
+       return exportfs_d_alloc(inode);
+}
+EXPORT_SYMBOL_GPL(generic_fh_to_parent);
Index: linux-2.6/fs/libfs/Makefile
===================================================================
--- linux-2.6.orig/fs/libfs/Makefile
+++ linux-2.6/fs/libfs/Makefile
@@ -1,3 +1,3 @@
 libfs-y += file.o
 
-obj-$(CONFIG_LIBFS) += libfs.o inode.o super.o
+obj-$(CONFIG_LIBFS) += libfs.o inode.o super.o dentry.o

-- 

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to