Merge mulgrave-w:git/scsi-misc-2.6
[pandora-kernel.git] / fs / ocfs2 / dir.c
index 856e20a..04e0191 100644 (file)
@@ -74,16 +74,17 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
 int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir)
 {
        int error = 0;
-       unsigned long offset, blk;
-       int i, num, stored;
+       unsigned long offset, blk, last_ra_blk = 0;
+       int i, stored;
        struct buffer_head * bh, * tmp;
        struct ocfs2_dir_entry * de;
        int err;
        struct inode *inode = filp->f_dentry->d_inode;
        struct super_block * sb = inode->i_sb;
-       int have_disk_lock = 0;
+       unsigned int ra_sectors = 16;
 
-       mlog_entry("dirino=%"MLFu64"\n", OCFS2_I(inode)->ip_blkno);
+       mlog_entry("dirino=%llu\n",
+                  (unsigned long long)OCFS2_I(inode)->ip_blkno);
 
        stored = 0;
        bh = NULL;
@@ -94,9 +95,8 @@ int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir)
                        mlog_errno(error);
                /* we haven't got any yet, so propagate the error. */
                stored = error;
-               goto bail;
+               goto bail_nolock;
        }
-       have_disk_lock = 1;
 
        offset = filp->f_pos & (sb->s_blocksize - 1);
 
@@ -104,24 +104,29 @@ int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir)
                blk = (filp->f_pos) >> sb->s_blocksize_bits;
                bh = ocfs2_bread(inode, blk, &err, 0);
                if (!bh) {
-                       mlog(ML_ERROR, "directory #%"MLFu64" contains a hole "
-                                      "at offset %lld\n",
-                            OCFS2_I(inode)->ip_blkno,
+                       mlog(ML_ERROR,
+                            "directory #%llu contains a hole at offset %lld\n",
+                            (unsigned long long)OCFS2_I(inode)->ip_blkno,
                             filp->f_pos);
                        filp->f_pos += sb->s_blocksize - offset;
                        continue;
                }
 
-               /*
-                * Do the readahead (8k)
-                */
-               if (!offset) {
-                       for (i = 16 >> (sb->s_blocksize_bits - 9), num = 0;
+               /* The idea here is to begin with 8k read-ahead and to stay
+                * 4k ahead of our current position.
+                *
+                * TODO: Use the pagecache for this. We just need to
+                * make sure it's cluster-safe... */
+               if (!last_ra_blk
+                   || (((last_ra_blk - blk) << 9) <= (ra_sectors / 2))) {
+                       for (i = ra_sectors >> (sb->s_blocksize_bits - 9);
                             i > 0; i--) {
                                tmp = ocfs2_bread(inode, ++blk, &err, 1);
                                if (tmp)
                                        brelse(tmp);
                        }
+                       last_ra_blk = blk;
+                       ra_sectors = 8;
                }
 
 revalidate:
@@ -193,16 +198,16 @@ revalidate:
 
        stored = 0;
 bail:
-       if (have_disk_lock)
-               ocfs2_meta_unlock(inode, 0);
+       ocfs2_meta_unlock(inode, 0);
 
+bail_nolock:
        mlog_exit(stored);
 
        return stored;
 }
 
 /*
- * NOTE: this should always be called with parent dir i_sem taken.
+ * NOTE: this should always be called with parent dir i_mutex taken.
  */
 int ocfs2_find_files_on_disk(const char *name,
                             int namelen,
@@ -212,11 +217,9 @@ int ocfs2_find_files_on_disk(const char *name,
                             struct ocfs2_dir_entry **dirent)
 {
        int status = -ENOENT;
-       struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 
-       mlog_entry("(osb=%p, parent=%"MLFu64", name='%.*s', blkno=%p, "
-                  "inode=%p)\n",
-                  osb, OCFS2_I(inode)->ip_blkno, namelen, name, blkno, inode);
+       mlog_entry("(name=%.*s, blkno=%p, inode=%p, dirent_bh=%p, dirent=%p)\n",
+                  namelen, name, blkno, inode, dirent_bh, dirent);
 
        *dirent_bh = ocfs2_find_entry(name, namelen, inode, dirent);
        if (!*dirent_bh || !*dirent) {
@@ -245,7 +248,7 @@ leave:
  * Return 0 if the name does not exist
  * Return -EEXIST if the directory contains the name
  *
- * Callers should have i_sem + a cluster lock on dir
+ * Callers should have i_mutex + a cluster lock on dir
  */
 int ocfs2_check_dir_for_entry(struct inode *dir,
                              const char *name,
@@ -255,8 +258,8 @@ int ocfs2_check_dir_for_entry(struct inode *dir,
        struct buffer_head *dirent_bh = NULL;
        struct ocfs2_dir_entry *dirent = NULL;
 
-       mlog_entry("dir %"MLFu64", name '%.*s'\n", OCFS2_I(dir)->ip_blkno,
-                  namelen, name);
+       mlog_entry("dir %llu, name '%.*s'\n",
+                  (unsigned long long)OCFS2_I(dir)->ip_blkno, namelen, name);
 
        ret = -EEXIST;
        dirent_bh = ocfs2_find_entry(name, namelen, dir, &dirent);
@@ -287,9 +290,8 @@ int ocfs2_empty_dir(struct inode *inode)
        if ((i_size_read(inode) <
             (OCFS2_DIR_REC_LEN(1) + OCFS2_DIR_REC_LEN(2))) ||
            !(bh = ocfs2_bread(inode, 0, &err, 0))) {
-               mlog(ML_ERROR, "bad directory (dir #%"MLFu64") - "
-                              "no data block\n",
-                    OCFS2_I(inode)->ip_blkno);
+               mlog(ML_ERROR, "bad directory (dir #%llu) - no data block\n",
+                    (unsigned long long)OCFS2_I(inode)->ip_blkno);
                return 1;
        }
 
@@ -300,9 +302,8 @@ int ocfs2_empty_dir(struct inode *inode)
                        !le64_to_cpu(de1->inode) ||
                        strcmp(".", de->name) ||
                        strcmp("..", de1->name)) {
-               mlog(ML_ERROR, "bad directory (dir #%"MLFu64") - "
-                              "no `.' or `..'\n",
-                    OCFS2_I(inode)->ip_blkno);
+               mlog(ML_ERROR, "bad directory (dir #%llu) - no `.' or `..'\n",
+                    (unsigned long long)OCFS2_I(inode)->ip_blkno);
                brelse(bh);
                return 1;
        }
@@ -314,9 +315,8 @@ int ocfs2_empty_dir(struct inode *inode)
                        bh = ocfs2_bread(inode,
                                         offset >> sb->s_blocksize_bits, &err, 0);
                        if (!bh) {
-                               mlog(ML_ERROR, "directory #%"MLFu64" contains "
-                                              "a hole at offset %lu\n",
-                                    OCFS2_I(inode)->ip_blkno, offset);
+                               mlog(ML_ERROR, "dir %llu has a hole at %lu\n",
+                                    (unsigned long long)OCFS2_I(inode)->ip_blkno, offset);
                                offset += sb->s_blocksize;
                                continue;
                        }
@@ -406,8 +406,8 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
        mlog_entry_void();
 
        dir_i_size = i_size_read(dir);
-       mlog(0, "extending dir %"MLFu64" (i_size = %lld)\n",
-            OCFS2_I(dir)->ip_blkno, dir_i_size);
+       mlog(0, "extending dir %llu (i_size = %lld)\n",
+            (unsigned long long)OCFS2_I(dir)->ip_blkno, dir_i_size);
 
        handle = ocfs2_alloc_handle(osb);
        if (handle == NULL) {
@@ -531,8 +531,8 @@ int ocfs2_prepare_dir_for_insert(struct ocfs2_super *osb,
 
        mlog_entry_void();
 
-       mlog(0, "getting ready to insert namelen %d into dir %"MLFu64"\n",
-            namelen, OCFS2_I(dir)->ip_blkno);
+       mlog(0, "getting ready to insert namelen %d into dir %llu\n",
+            namelen, (unsigned long long)OCFS2_I(dir)->ip_blkno);
 
        BUG_ON(!S_ISDIR(dir->i_mode));
        fe = (struct ocfs2_dinode *) parent_fe_bh->b_data;