Linux Headquarters
[ Register ]
[ About us ] [ Home Page ]

Advertisement
[ Kernel ] [ Documentation ] [ Links ] [ Books ]

Advertisement

Kernel v2.6.25-rc7 /fs/dcache.c

Filename:/fs/dcache.c
Lines Added:48
Lines Deleted:60
Also changed in: (Previous) 2.6.25-rc6  2.6.25-rc5  2.6.25-rc4  2.6.25-rc3  2.6.25-rc2  2.6.25-rc1-git4 
(Following) 2.6.25-rc8  2.6.25-rc9  2.6.25  2.6.25-git5  2.6.25-git6  2.6.25-git7 

Location
[  2.6.25-rc7
  [  fs
     o  dcache.c

Patch

diff --git a/fs/dcache.c b/fs/dcache.c
index d9ca1e5..4345577 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -89,12 +89,20 @@ static void d_free(struct dentry *dentry)
    if (dentry->d_op && dentry->d_op->d_release)
       dentry->d_op->d_release(dentry);
    /* if dentry was never inserted into hash, immediate free is OK */
-   if (dentry->d_hash.pprev == NULL)
+   if (hlist_unhashed(&dentry->d_hash))
       __d_free(dentry);
    else
       call_rcu(&dentry->d_u.d_rcu, d_callback);
 }
 
+static void dentry_lru_remove(struct dentry *dentry)
+{
+   if (!list_empty(&dentry->d_lru)) {
+      list_del_init(&dentry->d_lru);
+      dentry_stat.nr_unused--;
+   }
+}
+
 /*
  * Release the dentry's inode, using the filesystem
  * d_iput() operation if defined.
@@ -211,13 +219,7 @@ repeat:
 unhash_it:
    __d_drop(dentry);
 kill_it:
-   /* If dentry was on d_lru list
-    * delete it from there
-    */
-   if (!list_empty(&dentry->d_lru)) {
-      list_del(&dentry->d_lru);
-      dentry_stat.nr_unused--;
-   }
+   dentry_lru_remove(dentry);
    dentry = d_kill(dentry);
    if (dentry)
       goto repeat;
@@ -285,10 +287,7 @@ int d_invalidate(struct dentry * dentry)
 static inline struct dentry * __dget_locked(struct dentry *dentry)
 {
    atomic_inc(&dentry->d_count);
-   if (!list_empty(&dentry->d_lru)) {
-      dentry_stat.nr_unused--;
-      list_del_init(&dentry->d_lru);
-   }
+   dentry_lru_remove(dentry);
    return dentry;
 }
 
@@ -404,10 +403,7 @@ static void prune_one_dentry(struct dentry * dentry)
 
       if (dentry->d_op && dentry->d_op->d_delete)
          dentry->d_op->d_delete(dentry);
-      if (!list_empty(&dentry->d_lru)) {
-         list_del(&dentry->d_lru);
-         dentry_stat.nr_unused--;
-      }
+      dentry_lru_remove(dentry);
       __d_drop(dentry);
       dentry = d_kill(dentry);
       spin_lock(&dcache_lock);
@@ -596,10 +592,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
 
    /* detach this root from the system */
    spin_lock(&dcache_lock);
-   if (!list_empty(&dentry->d_lru)) {
-      dentry_stat.nr_unused--;
-      list_del_init(&dentry->d_lru);
-   }
+   dentry_lru_remove(dentry);
    __d_drop(dentry);
    spin_unlock(&dcache_lock);
 
@@ -613,11 +606,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
          spin_lock(&dcache_lock);
          list_for_each_entry(loop, &dentry->d_subdirs,
                    d_u.d_child) {
-            if (!list_empty(&loop->d_lru)) {
-               dentry_stat.nr_unused--;
-               list_del_init(&loop->d_lru);
-            }
-
+            dentry_lru_remove(loop);
             __d_drop(loop);
             cond_resched_lock(&dcache_lock);
          }
@@ -799,10 +788,7 @@ resume:
       struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child);
       next = tmp->next;
 
-      if (!list_empty(&dentry->d_lru)) {
-         dentry_stat.nr_unused--;
-         list_del_init(&dentry->d_lru);
-      }
+      dentry_lru_remove(dentry);
       /* 
        * move only zero ref count dentries to the end 
        * of the unused list for prune_dcache
@@ -1408,9 +1394,6 @@ void d_delete(struct dentry * dentry)
    if (atomic_read(&dentry->d_count) == 1) {
       dentry_iput(dentry);
       fsnotify_nameremove(dentry, isdir);
-
-      /* remove this and other inotify debug checks after 2.6.18 */
-      dentry->d_flags &= ~DCACHE_INOTIFY_PARENT_WATCHED;
       return;
    }
 
@@ -1779,9 +1762,8 @@ shouldnt_be_hashed:
  *
  * "buflen" should be positive. Caller holds the dcache_lock.
  */
-static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
-         struct dentry *root, struct vfsmount *rootmnt,
-         char *buffer, int buflen)
+static char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
+             struct path *root, char *buffer, int buflen)
 {
    char * end = buffer+buflen;
    char * retval;
@@ -1806,7 +1788,7 @@ static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
    for (;;) {
       struct dentry * parent;
 
-      if (dentry == root && vfsmnt == rootmnt)
+      if (dentry == root->dentry && vfsmnt == root->mnt)
          break;
       if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
          /* Global root? */
@@ -1847,13 +1829,23 @@ Elong:
    return ERR_PTR(-ENAMETOOLONG);
 }
 
-/* write full pathname into buffer and return start of pathname */
-char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
-            char *buf, int buflen)
+/**
+ * d_path - return the path of a dentry
+ * @path: path to report
+ * @buf: buffer to return value in
+ * @buflen: buffer length
+ *
+ * Convert a dentry into an ASCII path name. If the entry has been deleted
+ * the string " (deleted)" is appended. Note that this is ambiguous.
+ *
+ * Returns the buffer or an error code if the path was too long.
+ *
+ * "buflen" should be positive. Caller holds the dcache_lock.
+ */
+char *d_path(struct path *path, char *buf, int buflen)
 {
    char *res;
-   struct vfsmount *rootmnt;
-   struct dentry *root;
+   struct path root;
 
    /*
     * We have various synthetic filesystems that never get mounted.  On
@@ -1862,18 +1854,17 @@ char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
     * user wants to identify the object in /proc/pid/fd/.  The little hack
     * below allows us to generate a name for these objects on demand:
     */
-   if (dentry->d_op && dentry->d_op->d_dname)
-      return dentry->d_op->d_dname(dentry, buf, buflen);
+   if (path->dentry->d_op && path->dentry->d_op->d_dname)
+      return path->dentry->d_op->d_dname(path->dentry, buf, buflen);
 
    read_lock(¤t->fs->lock);
-   rootmnt = mntget(current->fs->rootmnt);
-   root = dget(current->fs->root);
+   root = current->fs->root;
+   path_get(¤t->fs->root);
    read_unlock(¤t->fs->lock);
    spin_lock(&dcache_lock);
-   res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
+   res = __d_path(path->dentry, path->mnt, &root, buf, buflen);
    spin_unlock(&dcache_lock);
-   dput(root);
-   mntput(rootmnt);
+   path_put(&root);
    return res;
 }
 
@@ -1919,28 +1910,27 @@ char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen,
 asmlinkage long sys_getcwd(char __user *buf, unsigned long size)
 {
    int error;
-   struct vfsmount *pwdmnt, *rootmnt;
-   struct dentry *pwd, *root;
+   struct path pwd, root;
    char *page = (char *) __get_free_page(GFP_USER);
 
    if (!page)
       return -ENOMEM;
 
    read_lock(¤t->fs->lock);
-   pwdmnt = mntget(current->fs->pwdmnt);
-   pwd = dget(current->fs->pwd);
-   rootmnt = mntget(current->fs->rootmnt);
-   root = dget(current->fs->root);
+   pwd = current->fs->pwd;
+   path_get(¤t->fs->pwd);
+   root = current->fs->root;
+   path_get(¤t->fs->root);
    read_unlock(¤t->fs->lock);
 
    error = -ENOENT;
    /* Has the current directory has been unlinked? */
    spin_lock(&dcache_lock);
-   if (pwd->d_parent == pwd || !d_unhashed(pwd)) {
+   if (pwd.dentry->d_parent == pwd.dentry || !d_unhashed(pwd.dentry)) {
       unsigned long len;
       char * cwd;
 
-      cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE);
+      cwd = __d_path(pwd.dentry, pwd.mnt, &root, page, PAGE_SIZE);
       spin_unlock(&dcache_lock);
 
       error = PTR_ERR(cwd);
@@ -1958,10 +1948,8 @@ asmlinkage long sys_getcwd(char __user *buf, unsigned long size)
       spin_unlock(&dcache_lock);
 
 out:
-   dput(pwd);
-   mntput(pwdmnt);
-   dput(root);
-   mntput(rootmnt);
+   path_put(&pwd);
+   path_put(&root);
    free_page((unsigned long) page);
    return error;
 }


Comments: webmaster (at) linuxhq.com.
Advertising: banners (at) linuxhq.com.
Compilation ©1998-2008 Linux Headquarters, Inc.