]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - fs/namei.c
[PATCH] Consolidate the asm-ppc*/fcntl.h files into asm-powerpc
[karo-tx-linux.git] / fs / namei.c
index 32accb6a672f8dfb1e797e3e7cbbe5ec09871e5c..6ec1f0fefc5b017aa321738f7d3581370a91fad3 100644 (file)
@@ -501,6 +501,7 @@ struct path {
 static inline int __do_follow_link(struct path *path, struct nameidata *nd)
 {
        int error;
+       void *cookie;
        struct dentry *dentry = path->dentry;
 
        touch_atime(path->mnt, dentry);
@@ -508,13 +509,15 @@ static inline int __do_follow_link(struct path *path, struct nameidata *nd)
 
        if (path->mnt == nd->mnt)
                mntget(path->mnt);
-       error = dentry->d_inode->i_op->follow_link(dentry, nd);
-       if (!error) {
+       cookie = dentry->d_inode->i_op->follow_link(dentry, nd);
+       error = PTR_ERR(cookie);
+       if (!IS_ERR(cookie)) {
                char *s = nd_get_link(nd);
+               error = 0;
                if (s)
                        error = __vfs_follow_link(nd, s);
                if (dentry->d_inode->i_op->put_link)
-                       dentry->d_inode->i_op->put_link(dentry, nd);
+                       dentry->d_inode->i_op->put_link(dentry, nd, cookie);
        }
        dput(dentry);
        mntput(path->mnt);
@@ -1802,7 +1805,6 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
        up(&dentry->d_inode->i_sem);
        if (!error) {
                d_delete(dentry);
-               fsnotify_rmdir(dentry, dentry->d_inode, dir);
        }
        dput(dentry);
 
@@ -1874,9 +1876,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry)
 
        /* We don't d_delete() NFS sillyrenamed files--they still exist. */
        if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) {
-               struct inode *inode = dentry->d_inode;
                d_delete(dentry);
-               fsnotify_unlink(dentry, inode, dir);
        }
 
        return error;
@@ -2219,7 +2219,8 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
        if (!error) {
                const char *new_name = old_dentry->d_name.name;
-               fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir, new_dentry->d_inode);
+               fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir,
+                             new_dentry->d_inode, old_dentry->d_inode);
        }
        fsnotify_oldname_free(old_name);
 
@@ -2346,15 +2347,17 @@ out:
 int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen)
 {
        struct nameidata nd;
-       int res;
+       void *cookie;
+
        nd.depth = 0;
-       res = dentry->d_inode->i_op->follow_link(dentry, &nd);
-       if (!res) {
-               res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd));
+       cookie = dentry->d_inode->i_op->follow_link(dentry, &nd);
+       if (!IS_ERR(cookie)) {
+               int res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd));
                if (dentry->d_inode->i_op->put_link)
-                       dentry->d_inode->i_op->put_link(dentry, &nd);
+                       dentry->d_inode->i_op->put_link(dentry, &nd, cookie);
+               cookie = ERR_PTR(res);
        }
-       return res;
+       return PTR_ERR(cookie);
 }
 
 int vfs_follow_link(struct nameidata *nd, const char *link)
@@ -2397,23 +2400,20 @@ int page_readlink(struct dentry *dentry, char __user *buffer, int buflen)
        return res;
 }
 
-int page_follow_link_light(struct dentry *dentry, struct nameidata *nd)
+void *page_follow_link_light(struct dentry *dentry, struct nameidata *nd)
 {
-       struct page *page;
+       struct page *page = NULL;
        nd_set_link(nd, page_getlink(dentry, &page));
-       return 0;
+       return page;
 }
 
-void page_put_link(struct dentry *dentry, struct nameidata *nd)
+void page_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
 {
-       if (!IS_ERR(nd_get_link(nd))) {
-               struct page *page;
-               page = find_get_page(dentry->d_inode->i_mapping, 0);
-               if (!page)
-                       BUG();
+       struct page *page = cookie;
+
+       if (page) {
                kunmap(page);
                page_cache_release(page);
-               page_cache_release(page);
        }
 }