Whamcloud - gitweb
a working file system!
[fs/lustre-release.git] / lustre / obdfs / dir.c
index 56db69a..59e6fb0 100644 (file)
@@ -28,7 +28,6 @@
 
 #include <linux/errno.h>
 #include <linux/fs.h>
-#include <linux/ext2_fs.h>
 #include <linux/fcntl.h>
 #include <linux/sched.h>
 #include <linux/stat.h>
 #include <linux/obdfs.h>
 
 static ssize_t obdfs_dir_read (struct file * filp, char * buf,
-                             size_t count, loff_t *ppos)
+                              size_t count, loff_t *ppos)
 {
-       return -EISDIR;
+        return -EISDIR;
 }
 
 static int obdfs_readdir(struct file *, void *, filldir_t);
 
 struct file_operations obdfs_dir_operations = {
-       NULL,                   /* lseek - default */
-       obdfs_dir_read,         /* read */
-       NULL,                   /* write - bad */
-       obdfs_readdir,          /* readdir */
-       NULL,                   /* poll - default */
-       NULL,                   /* ioctl */
-       NULL,                   /* mmap */
-       NULL,                   /* no special open code */
-       NULL,                   /* flush */
-       NULL,                   /* no special release code */
-       NULL,                   /* fsync */
-       NULL,                   /* fasync */
-       NULL                    /* lock */
+        read: obdfs_dir_read,
+        readdir: obdfs_readdir
 };
 
 struct inode_operations obdfs_dir_inode_operations = {
-       &obdfs_dir_operations,  /* default directory file-ops */
-       obdfs_create,           /* create */
-       obdfs_lookup,           /* lookup */
-       obdfs_link,             /* link */
-       obdfs_unlink,           /* unlink */
-       obdfs_symlink,          /* symlink */
-       obdfs_mkdir,            /* mkdir */
-       obdfs_rmdir,            /* rmdir */
-       obdfs_mknod,            /* mknod */
-       obdfs_rename,           /* rename */
-       NULL,                   /* readlink */
-       NULL,                   /* follow_link */
-       NULL,                   /* get_block */
-       obdfs_readpage,         /* readpage */
-       obdfs_writepage,        /* writepage */
-       obdfs_truncate,         /* truncate */
-       NULL,                   /* permission */
-       NULL                    /* revalidate */
+        create: obdfs_create,
+        lookup: obdfs_lookup,
+        link: obdfs_link,
+        unlink: obdfs_unlink,
+        symlink: obdfs_symlink,
+        mkdir: obdfs_mkdir,
+        rmdir: obdfs_rmdir,
+        mknod: obdfs_mknod,
+        rename: obdfs_rename,
+        truncate: obdfs_truncate
 };
 
 int obdfs_check_dir_entry (const char * function, struct inode * dir,
-                         struct ext2_dir_entry_2 * de,
-                         struct page * page,
-                         unsigned long offset)
+                          struct ext2_dir_entry_2 * de,
+                          struct page * page,
+                          unsigned long offset)
 {
-       const char * error_msg = NULL;
-       return 1;
-
-       ENTRY;
-       if ( !de ) {
-               error_msg = "null de passed";
-               return 1;
-       }
-
-       if (le16_to_cpu(de->rec_len) < EXT2_DIR_REC_LEN(1))
-               error_msg = "rec_len is smaller than minimal";
-       else if (le16_to_cpu(de->rec_len) % 4 != 0)
-               error_msg = "rec_len % 4 != 0";
-       else if (le16_to_cpu(de->rec_len) < EXT2_DIR_REC_LEN(de->name_len))
-               error_msg = "rec_len is too small for name_len";
-       else if (dir && ((char *) de - (char *)page_address(page)) + le16_to_cpu(de->rec_len) >
-                dir->i_sb->s_blocksize)
-               error_msg = "directory entry across blocks";
+        const char * error_msg = NULL;
+        return 1;
+
+        ENTRY;
+        if ( !de ) {
+                error_msg = "null de passed";
+                return 1;
+        }
+
+        if (le16_to_cpu(de->rec_len) < EXT2_DIR_REC_LEN(1))
+                error_msg = "rec_len is smaller than minimal";
+        else if (le16_to_cpu(de->rec_len) % 4 != 0)
+                error_msg = "rec_len % 4 != 0";
+        else if (le16_to_cpu(de->rec_len) < EXT2_DIR_REC_LEN(de->name_len))
+                error_msg = "rec_len is too small for name_len";
+        else if (dir && ((char *) de - (char *)page_address(page)) + le16_to_cpu(de->rec_len) >
+                 dir->i_sb->s_blocksize)
+                error_msg = "directory entry across blocks";
 #if 0 /* this one doesn't yet work for OBDFS */
-       else 
+        else 
 
 if (dir && le32_to_cpu(de->inode) > le32_to_cpu(dir->i_sb->u.ext2_sb.s_es->s_inodes_count))
-               error_msg = "inode out of bounds";
+                error_msg = "inode out of bounds";
 #endif
-       if (error_msg != NULL)
-               ext2_error (dir->i_sb, function, "bad entry in directory #%lu: %s - "
-                           "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
-                           dir->i_ino, error_msg, offset,
-                           (unsigned long) le32_to_cpu(de->inode),
-                           le16_to_cpu(de->rec_len), de->name_len);
-       EXIT;
-       return error_msg == NULL ? 1 : 0;
+        if (error_msg != NULL)
+                ext2_error (dir->i_sb, function, "bad entry in directory #%lu: %s - "
+                            "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
+                            dir->i_ino, error_msg, offset,
+                            (unsigned long) le32_to_cpu(de->inode),
+                            le16_to_cpu(de->rec_len), de->name_len);
+        EXIT;
+        return error_msg == NULL ? 1 : 0;
 }
 
 
 static int obdfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
 {
-       int error = 0;
-       unsigned long offset;
-       int stored;
-       struct ext2_dir_entry_2 * de;
-       struct super_block * sb;
-       struct page *page;
-       struct inode *inode = filp->f_dentry->d_inode;
-
-       ENTRY;
-
-       sb = inode->i_sb;
-
-       stored = 0;
-       offset = filp->f_pos & (PAGE_SIZE - 1);
-
-       OIDEBUG(inode);
-       while (!error && !stored && filp->f_pos < inode->i_size) {
-               page = obdfs_getpage(inode, filp->f_pos, 0, LOCKED);
-               /* PDEBUG(page, "readdir"); */
-               if (!page) {
-                       ext2_error (sb, "ext2_readdir",
-                                   "directory #%lu contains a hole at offset %lu",
-                                   inode->i_ino, (unsigned long)filp->f_pos);
-                       filp->f_pos += PAGE_SIZE - offset;
-                       continue;
-               }
+        int error = 0;
+        unsigned long offset;
+        int stored;
+        struct ext2_dir_entry_2 * de;
+        struct super_block * sb;
+        struct page *page;
+        struct inode *inode = filp->f_dentry->d_inode;
+
+        ENTRY;
+
+        sb = inode->i_sb;
+
+        stored = 0;
+        offset = filp->f_pos & (PAGE_SIZE - 1);
+
+        OIDEBUG(inode);
+        while (!error && !stored && filp->f_pos < inode->i_size) {
+                page = obdfs_getpage(inode, filp->f_pos, 0, LOCKED);
+                /* PDEBUG(page, "readdir"); */
+                if (!page) {
+                        ext2_error (sb, "ext2_readdir",
+                                    "directory #%lu contains a hole at offset %lu",
+                                    inode->i_ino, (unsigned long)filp->f_pos);
+                        filp->f_pos += PAGE_SIZE - offset;
+                        continue;
+                }
 
 #if 0
-               /* XXX need to do read ahead and support stuff below */
+                /* XXX need to do read ahead and support stuff below */
 revalidate:
-               /* If the dir block has changed since the last call to
-                * readdir(2), then we might be pointing to an invalid
-                * dirent right now.  Scan from the start of the block
-                * to make sure. */
-               if (filp->f_version != inode->i_version) {
-                       for (i = 0; i < sb->s_blocksize && i < offset; ) {
-                               de = (struct ext2_dir_entry_2 *) 
-                                       (bh->b_data + i);
-                               /* It's too expensive to do a full
-                                * dirent test each time round this
-                                * loop, but we do have to test at
-                                * least that it is non-zero.  A
-                                * failure will be detected in the
-                                * dirent test below. */
-                               if (le16_to_cpu(de->rec_len) < EXT2_DIR_REC_LEN(1))
-                                       break;
-                               i += le16_to_cpu(de->rec_len);
-                       }
-                       offset = i;
-                       filp->f_pos = (filp->f_pos & ~(sb->s_blocksize - 1))
-                               | offset;
-                       filp->f_version = inode->i_version;
-               }
-#endif         
-               while (!error && filp->f_pos < inode->i_size 
-                      && offset < PAGE_SIZE) {
-                       de = (struct ext2_dir_entry_2 *) ((char *)page_address(page) + offset);
+                /* If the dir block has changed since the last call to
+                 * readdir(2), then we might be pointing to an invalid
+                 * dirent right now.  Scan from the start of the block
+                 * to make sure. */
+                if (filp->f_version != inode->i_version) {
+                        for (i = 0; i < sb->s_blocksize && i < offset; ) {
+                                de = (struct ext2_dir_entry_2 *) 
+                                        (bh->b_data + i);
+                                /* It's too expensive to do a full
+                                 * dirent test each time round this
+                                 * loop, but we do have to test at
+                                 * least that it is non-zero.  A
+                                 * failure will be detected in the
+                                 * dirent test below. */
+                                if (le16_to_cpu(de->rec_len) < EXT2_DIR_REC_LEN(1))
+                                        break;
+                                i += le16_to_cpu(de->rec_len);
+                        }
+                        offset = i;
+                        filp->f_pos = (filp->f_pos & ~(sb->s_blocksize - 1))
+                                | offset;
+                        filp->f_version = inode->i_version;
+                }
+#endif          
+                while (!error && filp->f_pos < inode->i_size 
+                       && offset < PAGE_SIZE) {
+                        de = (struct ext2_dir_entry_2 *) ((char *)page_address(page) + offset);
 #if 0
-                       if (!obdfs_check_dir_entry ("ext2_readdir", inode, de,
-                                                  bh, offset)) {
-                               /* On error, skip the f_pos to the
+                        if (!obdfs_check_dir_entry ("ext2_readdir", inode, de,
+                                                   bh, offset)) {
+                                /* On error, skip the f_pos to the
                                    next block. */
-                               filp->f_pos = (filp->f_pos & (sb->s_blocksize - 1))
-                                             + sb->s_blocksize;
-                               brelse (bh);
-                               return stored;
-                       }
+                                filp->f_pos = (filp->f_pos & (sb->s_blocksize - 1))
+                                              + sb->s_blocksize;
+                                brelse (bh);
+                                return stored;
+                        }
 #endif
-                       offset += le16_to_cpu(de->rec_len);
-                       if (le32_to_cpu(de->inode)) {
-                               /* We might block in the next section
-                                * if the data destination is
-                                * currently swapped out.  So, use a
-                                * version stamp to detect whether or
-                                * not the directory has been modified
-                                * during the copy operation.
-                                */
-                               /* XXX
-                               unsigned long version = inode->i_version;
-                                */
-                               error = filldir(dirent, de->name,
-                                               de->name_len,
-                                               filp->f_pos, le32_to_cpu(de->inode));
-                               if (error)
-                                       break;
+                        offset += le16_to_cpu(de->rec_len);
+                        if (le32_to_cpu(de->inode)) {
+                                unsigned char d_type = DT_UNKNOWN;
+                                /* We might block in the next section
+                                 * if the data destination is
+                                 * currently swapped out.  So, use a
+                                 * version stamp to detect whether or
+                                 * not the directory has been modified
+                                 * during the copy operation.
+                                 */
+                                /* XXX
+                                unsigned long version = inode->i_version;
+                                 */
+                                error = filldir
+                                        (dirent, de->name, de->name_len,
+                                         filp->f_pos, le32_to_cpu(de->inode),
+                                         d_type);
+                                if (error)
+                                        break;
 #if 0
-                               if (version != inode->i_version)
-                                       goto revalidate;
+                                if (version != inode->i_version)
+                                        goto revalidate;
 #endif
-                               stored ++;
-                       }
-                       filp->f_pos += le16_to_cpu(de->rec_len);
-               }
-               offset = 0;
-               UnlockPage(page);
-               page_cache_release(page);
-       }
-       UPDATE_ATIME(inode);
-       EXIT;
-       return 0;
+                                stored ++;
+                        }
+                        filp->f_pos += le16_to_cpu(de->rec_len);
+                }
+                offset = 0;
+                obd_unlock_page(page);
+                page_cache_release(page);
+        }
+        UPDATE_ATIME(inode);
+        EXIT;
+        return 0;
 }