]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - fs/hostfs/hostfs_kern.c
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / fs / hostfs / hostfs_kern.c
index 2c0f148a49e65e9cb01016249a76dfd7985aeb25..2638c834ed281db783f6a7cd5ef24e2edb2047e4 100644 (file)
@@ -32,7 +32,7 @@ static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode)
 
 #define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_path.dentry->d_inode)
 
-static int hostfs_d_delete(struct dentry *dentry)
+static int hostfs_d_delete(const struct dentry *dentry)
 {
        return 1;
 }
@@ -92,12 +92,10 @@ __uml_setup("hostfs=", hostfs_args,
 
 static char *__dentry_name(struct dentry *dentry, char *name)
 {
-       char *p = __dentry_path(dentry, name, PATH_MAX);
+       char *p = dentry_path_raw(dentry, name, PATH_MAX);
        char *root;
        size_t len;
 
-       spin_unlock(&dcache_lock);
-
        root = dentry->d_sb->s_fs_info;
        len = strlen(root);
        if (IS_ERR(p)) {
@@ -123,25 +121,23 @@ static char *dentry_name(struct dentry *dentry)
        if (!name)
                return NULL;
 
-       spin_lock(&dcache_lock);
        return __dentry_name(dentry, name); /* will unlock */
 }
 
 static char *inode_name(struct inode *ino)
 {
        struct dentry *dentry;
-       char *name = __getname();
-       if (!name)
-               return NULL;
+       char *name;
 
-       spin_lock(&dcache_lock);
-       if (list_empty(&ino->i_dentry)) {
-               spin_unlock(&dcache_lock);
-               __putname(name);
+       dentry = d_find_alias(ino);
+       if (!dentry)
                return NULL;
-       }
-       dentry = list_first_entry(&ino->i_dentry, struct dentry, d_alias);
-       return __dentry_name(dentry, name); /* will unlock */
+
+       name = dentry_name(dentry);
+
+       dput(dentry);
+
+       return name;
 }
 
 static char *follow_link(char *link)
@@ -251,11 +247,18 @@ static void hostfs_evict_inode(struct inode *inode)
        }
 }
 
-static void hostfs_destroy_inode(struct inode *inode)
+static void hostfs_i_callback(struct rcu_head *head)
 {
+       struct inode *inode = container_of(head, struct inode, i_rcu);
+       INIT_LIST_HEAD(&inode->i_dentry);
        kfree(HOSTFS_I(inode));
 }
 
+static void hostfs_destroy_inode(struct inode *inode)
+{
+       call_rcu(&inode->i_rcu, hostfs_i_callback);
+}
+
 static int hostfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
 {
        const char *root_path = vfs->mnt_sb->s_fs_info;
@@ -609,7 +612,6 @@ struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry,
                goto out_put;
 
        d_add(dentry, inode);
-       dentry->d_op = &hostfs_dentry_ops;
        return NULL;
 
  out_put:
@@ -746,11 +748,14 @@ int hostfs_rename(struct inode *from_ino, struct dentry *from,
        return err;
 }
 
-int hostfs_permission(struct inode *ino, int desired)
+int hostfs_permission(struct inode *ino, int desired, unsigned int flags)
 {
        char *name;
        int r = 0, w = 0, x = 0, err;
 
+       if (flags & IPERM_FLAG_RCU)
+               return -ECHILD;
+
        if (desired & MAY_READ) r = 1;
        if (desired & MAY_WRITE) w = 1;
        if (desired & MAY_EXEC) x = 1;
@@ -765,7 +770,7 @@ int hostfs_permission(struct inode *ino, int desired)
                err = access_file(name, r, w, x);
        __putname(name);
        if (!err)
-               err = generic_permission(ino, desired, NULL);
+               err = generic_permission(ino, desired, flags, NULL);
        return err;
 }
 
@@ -916,6 +921,7 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
        sb->s_blocksize_bits = 10;
        sb->s_magic = HOSTFS_SUPER_MAGIC;
        sb->s_op = &hostfs_sbops;
+       sb->s_d_op = &hostfs_dentry_ops;
        sb->s_maxbytes = MAX_LFS_FILESIZE;
 
        /* NULL is printed as <NULL> by sprintf: avoid that. */