]> git.openfabrics.org - ~shefty/rdma-dev.git/blobdiff - fs/ceph/dir.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph...
[~shefty/rdma-dev.git] / fs / ceph / dir.c
index 852ff8600ac9875a5acf896247fb92485d6a8848..382abc9a6a5409ffc052556f58bcb612c5680c5f 100644 (file)
@@ -270,7 +270,7 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir)
                off = 1;
        }
        if (filp->f_pos == 1) {
-               ino_t ino = filp->f_dentry->d_parent->d_inode->i_ino;
+               ino_t ino = parent_ino(filp->f_dentry);
                dout("readdir off 1 -> '..'\n");
                if (filldir(dirent, "..", 2, ceph_make_fpos(0, 1),
                            ceph_translate_ino(inode->i_sb, ino),
@@ -464,14 +464,19 @@ static loff_t ceph_dir_llseek(struct file *file, loff_t offset, int origin)
        loff_t retval;
 
        mutex_lock(&inode->i_mutex);
+       retval = -EINVAL;
        switch (origin) {
        case SEEK_END:
                offset += inode->i_size + 2;   /* FIXME */
                break;
        case SEEK_CUR:
                offset += file->f_pos;
+       case SEEK_SET:
+               break;
+       default:
+               goto out;
        }
-       retval = -EINVAL;
+
        if (offset >= 0 && offset <= inode->i_sb->s_maxbytes) {
                if (offset != file->f_pos) {
                        file->f_pos = offset;
@@ -495,6 +500,7 @@ static loff_t ceph_dir_llseek(struct file *file, loff_t offset, int origin)
                if (offset > old_offset)
                        fi->dir_release_count--;
        }
+out:
        mutex_unlock(&inode->i_mutex);
        return retval;
 }
@@ -592,7 +598,6 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,
        /* open (but not create!) intent? */
        if (nd &&
            (nd->flags & LOOKUP_OPEN) &&
-           (nd->flags & LOOKUP_CONTINUE) == 0 && /* only open last component */
            !(nd->intent.open.flags & O_CREAT)) {
                int mode = nd->intent.open.create_mode & ~current->fs->umask;
                return ceph_lookup_open(dir, dentry, nd, mode, 1);
@@ -1144,7 +1149,8 @@ static ssize_t ceph_read_dir(struct file *file, char __user *buf, size_t size,
  * an fsync() on a dir will wait for any uncommitted directory
  * operations to commit.
  */
-static int ceph_dir_fsync(struct file *file, int datasync)
+static int ceph_dir_fsync(struct file *file, loff_t start, loff_t end,
+                         int datasync)
 {
        struct inode *inode = file->f_path.dentry->d_inode;
        struct ceph_inode_info *ci = ceph_inode(inode);
@@ -1154,6 +1160,11 @@ static int ceph_dir_fsync(struct file *file, int datasync)
        int ret = 0;
 
        dout("dir_fsync %p\n", inode);
+       ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
+       if (ret)
+               return ret;
+       mutex_lock(&inode->i_mutex);
+
        spin_lock(&ci->i_unsafe_lock);
        if (list_empty(head))
                goto out;
@@ -1187,6 +1198,8 @@ static int ceph_dir_fsync(struct file *file, int datasync)
        } while (req->r_tid < last_tid);
 out:
        spin_unlock(&ci->i_unsafe_lock);
+       mutex_unlock(&inode->i_mutex);
+
        return ret;
 }