Hi Andrew,

Today's linux-next merge of the akpm tree got a conflict in fs/dcache.c
between commit db14fc3abcd5 ("vfs: add d_walk()") from Linus' tree and
commit "dcache: convert to use new lru list infrastructure" from the akpm
tree.

I fixed it up (hopefully - see below) and can carry the fix as necessary
(no action is required).

-- 
Cheers,
Stephen Rothwell                    [email protected]

diff --cc fs/dcache.c
index fc05994,e4df9de..0000000
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@@ -1313,46 -1197,94 +1297,47 @@@ out
   * drop the lock and return early due to latency
   * constraints.
   */
 -static int select_parent(struct dentry *parent, struct list_head *dispose)
 -{
 -      struct dentry *this_parent;
 -      struct list_head *next;
 -      unsigned seq;
 -      int found = 0;
 -      int locked = 0;
  
 -      seq = read_seqbegin(&rename_lock);
 -again:
 -      this_parent = parent;
 -      spin_lock(&this_parent->d_lock);
 -repeat:
 -      next = this_parent->d_subdirs.next;
 -resume:
 -      while (next != &this_parent->d_subdirs) {
 -              struct list_head *tmp = next;
 -              struct dentry *dentry = list_entry(tmp, struct dentry, 
d_u.d_child);
 -              next = tmp->next;
 -
 -              spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
 +struct select_data {
 +      struct dentry *start;
 +      struct list_head dispose;
 +      int found;
 +};
  
 -              /*
 -               * move only zero ref count dentries to the dispose list.
 -               *
 -               * Those which are presently on the shrink list, being processed
 -               * by shrink_dentry_list(), shouldn't be moved.  Otherwise the
 -               * loop in shrink_dcache_parent() might not make any progress
 -               * and loop forever.
 -               */
 -              if (dentry->d_lockref.count) {
 -                      dentry_lru_del(dentry);
 -              } else if (!(dentry->d_flags & DCACHE_SHRINK_LIST)) {
 -                      dentry_lru_del(dentry);
 -                      list_add_tail(&dentry->d_lru, dispose);
 -                      dentry->d_flags |= DCACHE_SHRINK_LIST;
 -                      found++;
 -              }
 -              /*
 -               * We can return to the caller if we have found some (this
 -               * ensures forward progress). We'll be coming back to find
 -               * the rest.
 -               */
 -              if (found && need_resched()) {
 -                      spin_unlock(&dentry->d_lock);
 -                      goto out;
 -              }
 +static enum d_walk_ret select_collect(void *_data, struct dentry *dentry)
 +{
 +      struct select_data *data = _data;
 +      enum d_walk_ret ret = D_WALK_CONTINUE;
  
 -              /*
 -               * Descend a level if the d_subdirs list is non-empty.
 -               */
 -              if (!list_empty(&dentry->d_subdirs)) {
 -                      spin_unlock(&this_parent->d_lock);
 -                      spin_release(&dentry->d_lock.dep_map, 1, _RET_IP_);
 -                      this_parent = dentry;
 -                      spin_acquire(&this_parent->d_lock.dep_map, 0, 1, 
_RET_IP_);
 -                      goto repeat;
 -              }
 +      if (data->start == dentry)
 +              goto out;
  
 -              spin_unlock(&dentry->d_lock);
 -      }
        /*
 -       * All done at this level ... ascend and resume the search.
 +       * move only zero ref count dentries to the dispose list.
 +       *
 +       * Those which are presently on the shrink list, being processed
 +       * by shrink_dentry_list(), shouldn't be moved.  Otherwise the
 +       * loop in shrink_dcache_parent() might not make any progress
 +       * and loop forever.
         */
 -      if (this_parent != parent) {
 -              struct dentry *child = this_parent;
 -              this_parent = try_to_ascend(this_parent, locked, seq);
 -              if (!this_parent)
 -                      goto rename_retry;
 -              next = child->d_u.d_child.next;
 -              goto resume;
 +      if (dentry->d_lockref.count) {
 +              dentry_lru_del(dentry);
 +      } else if (!(dentry->d_flags & DCACHE_SHRINK_LIST)) {
-               dentry_lru_move_list(dentry, &data->dispose);
++              dentry_lru_del(dentry);
++              list_add_tail(&dentry->d_lru, &data->dispose);
 +              dentry->d_flags |= DCACHE_SHRINK_LIST;
 +              data->found++;
 +              ret = D_WALK_NORETRY;
        }
 +      /*
 +       * We can return to the caller if we have found some (this
 +       * ensures forward progress). We'll be coming back to find
 +       * the rest.
 +       */
 +      if (data->found && need_resched())
 +              ret = D_WALK_QUIT;
  out:
 -      spin_unlock(&this_parent->d_lock);
 -      if (!locked && read_seqretry(&rename_lock, seq))
 -              goto rename_retry;
 -      if (locked)
 -              write_sequnlock(&rename_lock);
 -      return found;
 -
 -rename_retry:
 -      if (found)
 -              return found;
 -      if (locked)
 -              goto again;
 -      locked = 1;
 -      write_seqlock(&rename_lock);
 -      goto again;
 +      return ret;
  }
  
  /**

Attachment: pgpIp85dSPV6k.pgp
Description: PGP signature

Reply via email to