linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Recurring Oops in link_path_walk()
@ 2015-11-20 17:07 Christophe Leroy
  2015-11-20 17:56 ` Al Viro
  0 siblings, 1 reply; 5+ messages in thread
From: Christophe Leroy @ 2015-11-20 17:07 UTC (permalink / raw)
  To: Al Viro
  Cc: linux-kernel, LinuxPPC-dev, linux-fsdevel, BOUET Serge, BARABAN Luc

Al,

We've been running Kernel 3.18 for several monthes on our embedded 
boards, and we have a recurring Oops in link_path_walk()
It doesn't happen very often (approximatly once every month on one board 
among a set of 50 boards, never the same board).

Here below is the last oops I got, with kernel 3.18.22. It crashes at 
address 0xc00b75ac. Here below is the full desassembly of 
link_path_walk() so that you can see exactly the offending line.

The address it fails at is always the same (link_path_walk+0x414) but 
the oopsing data address is each time different. I added all Oops I got 
below after the disassembly (on different sub-versions of 3.18).

Do you have any idea of what this can be ? Is there any recent change 
made since 3.18 that could fix it and could be backported into 3.18 ?

Thanks,
Christophe

[10250.855670] Unable to handle kernel paging request for data at 
address 0x00003879
[10250.867593] Faulting instruction address: 0xc00b75ac
[10250.883695] Oops: Kernel access of bad area, sig: 11 [#1]
[10250.888766] PREEMPT CMPC885
[10250.891564] CPU: 0 PID: 2416 Comm: SUO_ Not tainted 3.18.22 #53
[10250.899123] task: c628e680 ti: c66c8000 task.ti: c66c8000
[10250.904451] NIP: c00b75ac LR: c00b7574 CTR: c00fcdc8
[10250.909364] REGS: c66c9d10 TRAP: 0300   Not tainted  (3.18.22)
[10250.916825] MSR: 00009032 <EE,ME,IR,DR,RI>  CR: 22002482 XER: 00000000
[10250.923374] DAR: 00003879 DSISR: c0000000
[10250.923374] GPR00: c00b7574 c66c9dc0 c628e680 c1088330 c50883b8 
c50883f2 90f9ced3 00000031
[10250.923374] GPR08: 00000000 00003869 c5085560 31c52da7 22002482 
101ccd18 101c0000 1017da60
[10250.923374] GPR16: 1024b884 101758d4 1017d9a8 1014e64c 1051553c 
00000000 00000000 c66c8000
[10250.923374] GPR24: 00100000 c66c9ea0 00300000 00000004 fffff000 
c651b02f 00000000 c66c9e88
[10250.955351] NIP [c00b75ac] link_path_walk+0x414/0x86c
[10250.960326] LR [c00b7574] link_path_walk+0x3dc/0x86c
[10250.965191] Call Trace:
[10250.967640] [c66c9dc0] [c00b7574] link_path_walk+0x3dc/0x86c (unreliable)
[10250.974363] [c66c9e20] [c00b9e30] path_openat+0x90/0x678
[10250.979605] [c66c9e80] [c00ba448] do_filp_open+0x30/0x8c
[10250.984857] [c66c9f00] [c00abc08] do_sys_open+0x14c/0x238
[10250.990196] [c66c9f40] [c000b294] ret_from_syscall+0x0/0x38
[10250.995654] Instruction dump:
[10250.998585] 7f834800 419e000c 48014f81 80610018 8081001c 81410020 
907f0000 909f0004
[10251.006243] 915f0020 3bc00000 8061000c 81230028 <81290010> 81290014 
2f890000 419e0014



c00b7198 <link_path_walk>:
  *
  * Returns 0 and nd will have valid dentry and mnt on success.
  * Returns error and drops reference to input namei data on failure.
  */
static int link_path_walk(const char *name, struct nameidata *nd)
{
c00b7198:    7c 08 02 a6     mflr    r0
c00b719c:    94 21 ff a0     stwu    r1,-96(r1)
c00b71a0:    be a1 00 34     stmw    r21,52(r1)
c00b71a4:    90 01 00 64     stw     r0,100(r1)
c00b71a8:    7c 7d 1b 78     mr      r29,r3
     struct path next;
     int err;

     while (*name=='/')
c00b71ac:    89 23 00 00     lbz     r9,0(r3)
  *
  * Returns 0 and nd will have valid dentry and mnt on success.
  * Returns error and drops reference to input namei data on failure.
  */
static int link_path_walk(const char *name, struct nameidata *nd)
{
c00b71b0:    7c 9f 23 78     mr      r31,r4
     struct path next;
     int err;

     while (*name=='/')
c00b71b4:    2b 89 00 2f     cmplwi  cr7,r9,47
c00b71b8:    40 9e 00 10     bne     cr7,c00b71c8 <link_path_walk+0x30>
c00b71bc:    8d 3d 00 01     lbzu    r9,1(r29)
c00b71c0:    2b 89 00 2f     cmplwi  cr7,r9,47
c00b71c4:    41 9e ff f8     beq     cr7,c00b71bc <link_path_walk+0x24>
         name++;
     if (!*name)
c00b71c8:    2f 89 00 00     cmpwi   cr7,r9,0
c00b71cc:    41 9e 02 48     beq     cr7,c00b7414 <link_path_walk+0x27c>
  * so we keep a cache of "no, this doesn't need follow_link"
  * for the common case.
  */
static inline int should_follow_link(struct dentry *dentry, int follow)
{
     return unlikely(d_is_symlink(dentry)) ? follow : 0;
c00b71d0:    3f 40 00 30     lis     r26,48

     error = security_inode_follow_link(link->dentry, nd);
     if (error)
         goto out_put_nd_path;

     nd->last_type = LAST_BIND;
c00b71d4:    3b 60 00 04     li      r27,4
     *p = dentry->d_inode->i_op->follow_link(dentry, nd);
     error = PTR_ERR(*p);
     if (IS_ERR(*p))
c00b71d8:    3b 80 f0 00     li      r28,-4096
     return status;
}

static __always_inline void set_root(struct nameidata *nd)
{
     get_fs_root(current->fs, &nd->root);
c00b71dc:    3b 3f 00 18     addi    r25,r31,24
c00b71e0:    54 37 00 24     rlwinm  r23,r1,0,0,18
         if (err) {
             err = nested_symlink(&next, nd);
             if (err)
                 return err;
         }
         if (!d_can_lookup(nd->path.dentry)) {
c00b71e4:    3f 00 00 10     lis     r24,16
     return 0;
}

static inline int may_lookup(struct nameidata *nd)
{
     if (nd->flags & LOOKUP_RCU) {
c00b71e8:    81 3f 00 24     lwz     r9,36(r31)
c00b71ec:    71 24 00 40     andi.   r4,r9,64
c00b71f0:    40 82 01 a0     bne     c00b7390 <link_path_walk+0x1f8>
         if (err != -ECHILD)
             return err;
         if (unlazy_walk(nd, NULL))
             return -ECHILD;
     }
     return inode_permission(nd->inode, MAY_EXEC);
c00b71f4:    80 7f 00 20     lwz     r3,32(r31)
c00b71f8:    38 80 00 01     li      r4,1
c00b71fc:    4b ff f2 15     bl      c00b6410 <inode_permission>
c00b7200:    7c 7e 1b 78     mr      r30,r3
     for(;;) {
         u64 hash_len;
         int type;

         err = may_lookup(nd);
          if (err)
c00b7204:    2f 9e 00 00     cmpwi   cr7,r30,0
c00b7208:    40 9e 01 1c     bne     cr7,c00b7324 <link_path_walk+0x18c>
static inline u64 hash_name(const char *name)
{
     unsigned long hash = init_name_hash();
     unsigned long len = 0, c;

     c = (unsigned char)*name;
c00b720c:    88 bd 00 00     lbz     r5,0(r29)
  * one character.
  */
static inline u64 hash_name(const char *name)
{
     unsigned long hash = init_name_hash();
     unsigned long len = 0, c;
c00b7210:    39 40 00 00     li      r10,0

     c = (unsigned char)*name;
c00b7214:    7c a9 2b 78     mr      r9,r5
  * We know there's a real path component here of at least
  * one character.
  */
static inline u64 hash_name(const char *name)
{
     unsigned long hash = init_name_hash();
c00b7218:    39 00 00 00     li      r8,0
c00b721c:    48 00 00 08     b       c00b7224 <link_path_walk+0x8c>
     c = (unsigned char)*name;
     do {
         len++;
         hash = partial_name_hash(c, hash);
         c = (unsigned char)name[len];
     } while (c && c != '/');
c00b7220:    41 9a 00 2c     beq     cr6,c00b724c <link_path_walk+0xb4>
     unsigned long hash = init_name_hash();
     unsigned long len = 0, c;

     c = (unsigned char)*name;
     do {
         len++;
c00b7224:    39 4a 00 01     addi    r10,r10,1

/* partial hash update function. Assume roughly 4 bits per character */
static inline unsigned long
partial_name_hash(unsigned long c, unsigned long prevhash)
{
     return (prevhash + (c << 4) + (c >> 4)) * 11;
c00b7228:    55 26 e1 3e     rlwinm  r6,r9,28,4,31
c00b722c:    55 27 20 36     rlwinm  r7,r9,4,0,27
         hash = partial_name_hash(c, hash);
         c = (unsigned char)name[len];
c00b7230:    7d 3d 50 ae     lbzx    r9,r29,r10
c00b7234:    7c e6 3a 14     add     r7,r6,r7
     } while (c && c != '/');
c00b7238:    2f 89 00 00     cmpwi   cr7,r9,0
c00b723c:    7d 07 42 14     add     r8,r7,r8
c00b7240:    2b 09 00 2f     cmplwi  cr6,r9,47
c00b7244:    1d 08 00 0b     mulli   r8,r8,11
c00b7248:    40 9e ff d8     bne     cr7,c00b7220 <link_path_walk+0x88>
             break;

         hash_len = hash_name(name);

         type = LAST_NORM;
         if (name[0] == '.') switch (hashlen_len(hash_len)) {
c00b724c:    2b 85 00 2e     cmplwi  cr7,r5,46
     do {
         len++;
         hash = partial_name_hash(c, hash);
         c = (unsigned char)name[len];
     } while (c && c != '/');
     return hashlen_create(end_name_hash(hash), len);
c00b7250:    7d 47 53 78     mr      r7,r10
c00b7254:    7d 06 43 78     mr      r6,r8
             break;

         hash_len = hash_name(name);

         type = LAST_NORM;
         if (name[0] == '.') switch (hashlen_len(hash_len)) {
c00b7258:    41 9e 01 70     beq     cr7,c00b73c8 <link_path_walk+0x230>
             case 1:
                 type = LAST_DOT;
         }
         if (likely(type == LAST_NORM)) {
             struct dentry *parent = nd->path.dentry;
             nd->flags &= ~LOOKUP_JUMPED;
c00b725c:    80 bf 00 24     lwz     r5,36(r31)
                 break;
             case 1:
                 type = LAST_DOT;
         }
         if (likely(type == LAST_NORM)) {
             struct dentry *parent = nd->path.dentry;
c00b7260:    81 3f 00 04     lwz     r9,4(r31)
             nd->flags &= ~LOOKUP_JUMPED;
c00b7264:    54 a5 05 24     rlwinm  r5,r5,0,20,18
c00b7268:    90 bf 00 24     stw     r5,36(r31)
             if (unlikely(parent->d_flags & DCACHE_OP_HASH)) {
c00b726c:    80 a9 00 00     lwz     r5,0(r9)
c00b7270:    70 a4 00 01     andi.   r4,r5,1
c00b7274:    40 82 02 30     bne     c00b74a4 <link_path_walk+0x30c>
c00b7278:    7d 45 53 78     mr      r5,r10
c00b727c:    39 20 00 00     li      r9,0
                 hash_len = this.hash_len;
                 name = this.name;
             }
         }

         nd->last.hash_len = hash_len;
c00b7280:    90 ff 00 08     stw     r7,8(r31)
c00b7284:    90 df 00 0c     stw     r6,12(r31)
         nd->last.name = name;
c00b7288:    93 bf 00 10     stw     r29,16(r31)
         nd->last_type = type;
c00b728c:    91 3f 00 30     stw     r9,48(r31)

         name += hashlen_len(hash_len);
         if (!*name)
c00b7290:    7d 5d 28 ee     lbzux   r10,r29,r5
c00b7294:    2f 8a 00 00     cmpwi   cr7,r10,0
c00b7298:    41 9e 01 7c     beq     cr7,c00b7414 <link_path_walk+0x27c>
          * If it wasn't NUL, we know it was '/'. Skip that
          * slash, and continue until no more slashes.
          */
         do {
             name++;
         } while (unlikely(*name == '/'));
c00b729c:    8d 5d 00 01     lbzu    r10,1(r29)
c00b72a0:    2b 8a 00 2f     cmplwi  cr7,r10,47
c00b72a4:    41 be ff f8     beq     cr7,c00b729c <link_path_walk+0x104>
         if (!*name)
c00b72a8:    2f 8a 00 00     cmpwi   cr7,r10,0
c00b72ac:    41 9e 01 68     beq     cr7,c00b7414 <link_path_walk+0x27c>
     /*
      * "." and ".." are special - ".." especially so because it has
      * to be able to know about the current root directory and
      * parent relationships.
      */
     if (unlikely(nd->last_type != LAST_NORM))
c00b72b0:    2f 89 00 00     cmpwi   cr7,r9,0
c00b72b4:    40 9e 01 bc     bne     cr7,c00b7470 <link_path_walk+0x2d8>
         return handle_dots(nd, nd->last_type);
     err = lookup_fast(nd, path, &inode);
c00b72b8:    7f e3 fb 78     mr      r3,r31
c00b72bc:    38 81 00 18     addi    r4,r1,24
c00b72c0:    38 a1 00 08     addi    r5,r1,8
c00b72c4:    4b ff f9 69     bl      c00b6c2c <lookup_fast>
     if (unlikely(err)) {
c00b72c8:    7c 7e 1b 79     mr.     r30,r3
c00b72cc:    40 82 06 f8     bne     c00b79c4 <link_path_walk+0x82c>
c00b72d0:    81 41 00 08     lwz     r10,8(r1)
             goto out_err;

         inode = path->dentry->d_inode;
     }
     err = -ENOENT;
     if (!inode || d_is_negative(path->dentry))
c00b72d4:    2f 8a 00 00     cmpwi   cr7,r10,0
c00b72d8:    41 9e 00 6c     beq     cr7,c00b7344 <link_path_walk+0x1ac>
c00b72dc:    80 81 00 1c     lwz     r4,28(r1)
     spin_unlock(&dentry->d_lock);
}

static inline unsigned __d_entry_type(const struct dentry *dentry)
{
     return dentry->d_flags & DCACHE_ENTRY_TYPE;
c00b72e0:    81 24 00 00     lwz     r9,0(r4)
c00b72e4:    75 28 00 70     andis.  r8,r9,112
c00b72e8:    41 82 00 5c     beq     c00b7344 <link_path_walk+0x1ac>
  * so we keep a cache of "no, this doesn't need follow_link"
  * for the common case.
  */
static inline int should_follow_link(struct dentry *dentry, int follow)
{
     return unlikely(d_is_symlink(dentry)) ? follow : 0;
c00b72ec:    7f 88 d0 00     cmpw    cr7,r8,r26
c00b72f0:    41 9e 02 04     beq     cr7,c00b74f4 <link_path_walk+0x35c>
}

static inline void path_to_nameidata(const struct path *path,
                     struct nameidata *nd)
{
     if (!(nd->flags & LOOKUP_RCU)) {
c00b72f4:    81 3f 00 24     lwz     r9,36(r31)
c00b72f8:    71 28 00 40     andi.   r8,r9,64
c00b72fc:    41 82 01 38     beq     c00b7434 <link_path_walk+0x29c>
c00b7300:    81 21 00 18     lwz     r9,24(r1)
         dput(nd->path.dentry);
         if (nd->path.mnt != path->mnt)
             mntput(nd->path.mnt);
     }
     nd->path.mnt = path->mnt;
c00b7304:    91 3f 00 00     stw     r9,0(r31)
     nd->path.dentry = path->dentry;
c00b7308:    90 9f 00 04     stw     r4,4(r31)
         }
         BUG_ON(inode != path->dentry->d_inode);
         return 1;
     }
     path_to_nameidata(path, nd);
     nd->inode = inode;
c00b730c:    91 5f 00 20     stw     r10,32(r31)
c00b7310:    81 24 00 00     lwz     r9,0(r4)
c00b7314:    55 29 02 56     rlwinm  r9,r9,0,9,11
         if (err) {
             err = nested_symlink(&next, nd);
             if (err)
                 return err;
         }
         if (!d_can_lookup(nd->path.dentry)) {
c00b7318:    7f 89 c0 00     cmpw    cr7,r9,r24
c00b731c:    41 9e fe cc     beq     cr7,c00b71e8 <link_path_walk+0x50>
             err = -ENOTDIR;
c00b7320:    3b c0 ff ec     li      r30,-20
             break;
         }
     }
     terminate_walk(nd);
c00b7324:    7f e3 fb 78     mr      r3,r31
c00b7328:    4b ff eb b9     bl      c00b5ee0 <terminate_walk>
     return err;
c00b732c:    7f c3 f3 78     mr      r3,r30
}
c00b7330:    80 01 00 64     lwz     r0,100(r1)
c00b7334:    ba a1 00 34     lmw     r21,52(r1)
c00b7338:    7c 08 03 a6     mtlr    r0
c00b733c:    38 21 00 60     addi    r1,r1,96
c00b7340:    4e 80 00 20     blr
}

static inline void path_to_nameidata(const struct path *path,
                     struct nameidata *nd)
{
     if (!(nd->flags & LOOKUP_RCU)) {
c00b7344:    81 3f 00 24     lwz     r9,36(r31)
c00b7348:    71 28 00 40     andi.   r8,r9,64
c00b734c:    41 82 00 24     beq     c00b7370 <link_path_walk+0x1d8>
c00b7350:    80 61 00 18     lwz     r3,24(r1)
         dput(nd->path.dentry);
         if (nd->path.mnt != path->mnt)
             mntput(nd->path.mnt);
     }
     nd->path.mnt = path->mnt;
     nd->path.dentry = path->dentry;
c00b7354:    81 21 00 1c     lwz     r9,28(r1)
     if (!(nd->flags & LOOKUP_RCU)) {
         dput(nd->path.dentry);
         if (nd->path.mnt != path->mnt)
             mntput(nd->path.mnt);
     }
     nd->path.mnt = path->mnt;
c00b7358:    90 7f 00 00     stw     r3,0(r31)
     nd->path.dentry = path->dentry;
c00b735c:    91 3f 00 04     stw     r9,4(r31)
         if (!d_can_lookup(nd->path.dentry)) {
             err = -ENOTDIR;
             break;
         }
     }
     terminate_walk(nd);
c00b7360:    7f e3 fb 78     mr      r3,r31
         if (err < 0)
             goto out_err;

         inode = path->dentry->d_inode;
     }
     err = -ENOENT;
c00b7364:    3b c0 ff fe     li      r30,-2
         if (!d_can_lookup(nd->path.dentry)) {
             err = -ENOTDIR;
             break;
         }
     }
     terminate_walk(nd);
c00b7368:    4b ff eb 79     bl      c00b5ee0 <terminate_walk>
c00b736c:    4b ff ff c0     b       c00b732c <link_path_walk+0x194>

static inline void path_to_nameidata(const struct path *path,
                     struct nameidata *nd)
{
     if (!(nd->flags & LOOKUP_RCU)) {
         dput(nd->path.dentry);
c00b7370:    80 7f 00 04     lwz     r3,4(r31)
c00b7374:    48 00 b5 89     bl      c00c28fc <dput>
         if (nd->path.mnt != path->mnt)
c00b7378:    80 7f 00 00     lwz     r3,0(r31)
c00b737c:    81 21 00 18     lwz     r9,24(r1)
c00b7380:    7f 83 48 40     cmplw   cr7,r3,r9
c00b7384:    41 be ff d0     beq     cr7,c00b7354 <link_path_walk+0x1bc>
             mntput(nd->path.mnt);
c00b7388:    48 01 51 7d     bl      c00cc504 <mntput>
c00b738c:    4b ff ff c4     b       c00b7350 <link_path_walk+0x1b8>
}

static inline int may_lookup(struct nameidata *nd)
{
     if (nd->flags & LOOKUP_RCU) {
         int err = inode_permission(nd->inode, MAY_EXEC|MAY_NOT_BLOCK);
c00b7390:    80 7f 00 20     lwz     r3,32(r31)
c00b7394:    38 80 00 81     li      r4,129
c00b7398:    4b ff f0 79     bl      c00b6410 <inode_permission>
         if (err != -ECHILD)
c00b739c:    2f 83 ff f6     cmpwi   cr7,r3,-10
}

static inline int may_lookup(struct nameidata *nd)
{
     if (nd->flags & LOOKUP_RCU) {
         int err = inode_permission(nd->inode, MAY_EXEC|MAY_NOT_BLOCK);
c00b73a0:    7c 7e 1b 78     mr      r30,r3
         if (err != -ECHILD)
c00b73a4:    40 9e fe 60     bne     cr7,c00b7204 <link_path_walk+0x6c>
             return err;
         if (unlazy_walk(nd, NULL))
c00b73a8:    7f e3 fb 78     mr      r3,r31
c00b73ac:    38 80 00 00     li      r4,0
c00b73b0:    4b ff f6 c5     bl      c00b6a74 <unlazy_walk>
c00b73b4:    2f 83 00 00     cmpwi   cr7,r3,0
c00b73b8:    41 be fe 3c     beq     cr7,c00b71f4 <link_path_walk+0x5c>
         if (!d_can_lookup(nd->path.dentry)) {
             err = -ENOTDIR;
             break;
         }
     }
     terminate_walk(nd);
c00b73bc:    7f e3 fb 78     mr      r3,r31
c00b73c0:    4b ff eb 21     bl      c00b5ee0 <terminate_walk>
c00b73c4:    4b ff ff 68     b       c00b732c <link_path_walk+0x194>
             break;

         hash_len = hash_name(name);

         type = LAST_NORM;
         if (name[0] == '.') switch (hashlen_len(hash_len)) {
c00b73c8:    2f 8a 00 01     cmpwi   cr7,r10,1
c00b73cc:    7d 45 53 78     mr      r5,r10
c00b73d0:    41 9e 00 5c     beq     cr7,c00b742c <link_path_walk+0x294>
c00b73d4:    2f 8a 00 02     cmpwi   cr7,r10,2
c00b73d8:    40 be fe 84     bne     cr7,c00b725c <link_path_walk+0xc4>
             case 2:
                 if (name[1] == '.') {
c00b73dc:    89 3d 00 01     lbz     r9,1(r29)
c00b73e0:    2f 89 00 2e     cmpwi   cr7,r9,46
c00b73e4:    40 9e fe 78     bne     cr7,c00b725c <link_path_walk+0xc4>
                     type = LAST_DOTDOT;
                     nd->flags |= LOOKUP_JUMPED;
c00b73e8:    81 5f 00 24     lwz     r10,36(r31)

         type = LAST_NORM;
         if (name[0] == '.') switch (hashlen_len(hash_len)) {
             case 2:
                 if (name[1] == '.') {
                     type = LAST_DOTDOT;
c00b73ec:    39 20 00 03     li      r9,3
                     nd->flags |= LOOKUP_JUMPED;
c00b73f0:    61 4a 10 00     ori     r10,r10,4096
c00b73f4:    91 5f 00 24     stw     r10,36(r31)
                 hash_len = this.hash_len;
                 name = this.name;
             }
         }

         nd->last.hash_len = hash_len;
c00b73f8:    90 ff 00 08     stw     r7,8(r31)
c00b73fc:    90 df 00 0c     stw     r6,12(r31)
         nd->last.name = name;
c00b7400:    93 bf 00 10     stw     r29,16(r31)
         nd->last_type = type;
c00b7404:    91 3f 00 30     stw     r9,48(r31)

         name += hashlen_len(hash_len);
         if (!*name)
c00b7408:    7d 5d 28 ee     lbzux   r10,r29,r5
c00b740c:    2f 8a 00 00     cmpwi   cr7,r10,0
c00b7410:    40 9e fe 8c     bne     cr7,c00b729c <link_path_walk+0x104>
             break;
         }
     }
     terminate_walk(nd);
     return err;
}
c00b7414:    80 01 00 64     lwz     r0,100(r1)
c00b7418:    ba a1 00 34     lmw     r21,52(r1)
c00b741c:    7c 08 03 a6     mtlr    r0
     int err;

     while (*name=='/')
         name++;
     if (!*name)
         return 0;
c00b7420:    38 60 00 00     li      r3,0
             break;
         }
     }
     terminate_walk(nd);
     return err;
}
c00b7424:    38 21 00 60     addi    r1,r1,96
c00b7428:    4e 80 00 20     blr
                     type = LAST_DOTDOT;
                     nd->flags |= LOOKUP_JUMPED;
                 }
                 break;
             case 1:
                 type = LAST_DOT;
c00b742c:    39 20 00 02     li      r9,2
c00b7430:    4b ff fe 50     b       c00b7280 <link_path_walk+0xe8>

static inline void path_to_nameidata(const struct path *path,
                     struct nameidata *nd)
{
     if (!(nd->flags & LOOKUP_RCU)) {
         dput(nd->path.dentry);
c00b7434:    80 7f 00 04     lwz     r3,4(r31)
c00b7438:    48 00 b4 c5     bl      c00c28fc <dput>
         if (nd->path.mnt != path->mnt)
c00b743c:    80 7f 00 00     lwz     r3,0(r31)
c00b7440:    81 21 00 18     lwz     r9,24(r1)
c00b7444:    7f 83 48 00     cmpw    cr7,r3,r9
c00b7448:    41 9e 00 18     beq     cr7,c00b7460 <link_path_walk+0x2c8>
             mntput(nd->path.mnt);
c00b744c:    48 01 50 b9     bl      c00cc504 <mntput>
c00b7450:    81 21 00 18     lwz     r9,24(r1)
c00b7454:    80 81 00 1c     lwz     r4,28(r1)
c00b7458:    81 41 00 08     lwz     r10,8(r1)
c00b745c:    4b ff fe a8     b       c00b7304 <link_path_walk+0x16c>
c00b7460:    80 81 00 1c     lwz     r4,28(r1)
c00b7464:    81 41 00 08     lwz     r10,8(r1)
static inline void path_to_nameidata(const struct path *path,
                     struct nameidata *nd)
{
     if (!(nd->flags & LOOKUP_RCU)) {
         dput(nd->path.dentry);
         if (nd->path.mnt != path->mnt)
c00b7468:    7c 69 1b 78     mr      r9,r3
c00b746c:    4b ff fe 98     b       c00b7304 <link_path_walk+0x16c>
     return inode_permission(nd->inode, MAY_EXEC);
}

static inline int handle_dots(struct nameidata *nd, int type)
{
     if (type == LAST_DOTDOT) {
c00b7470:    2f 89 00 03     cmpwi   cr7,r9,3
c00b7474:    41 9e 00 0c     beq     cr7,c00b7480 <link_path_walk+0x2e8>
c00b7478:    80 9f 00 04     lwz     r4,4(r31)
c00b747c:    4b ff fe 94     b       c00b7310 <link_path_walk+0x178>
         if (nd->flags & LOOKUP_RCU) {
c00b7480:    81 3f 00 24     lwz     r9,36(r31)
             if (follow_dotdot_rcu(nd))
c00b7484:    7f e3 fb 78     mr      r3,r31
}

static inline int handle_dots(struct nameidata *nd, int type)
{
     if (type == LAST_DOTDOT) {
         if (nd->flags & LOOKUP_RCU) {
c00b7488:    71 24 00 40     andi.   r4,r9,64
c00b748c:    41 82 00 5c     beq     c00b74e8 <link_path_walk+0x350>
             if (follow_dotdot_rcu(nd))
c00b7490:    4b ff e3 b1     bl      c00b5840 <follow_dotdot_rcu>
c00b7494:    2f 83 00 00     cmpwi   cr7,r3,0
c00b7498:    41 be ff e0     beq     cr7,c00b7478 <link_path_walk+0x2e0>
                 return -ECHILD;
c00b749c:    38 60 ff f6     li      r3,-10
c00b74a0:    4b ff fe 90     b       c00b7330 <link_path_walk+0x198>
         }
         if (likely(type == LAST_NORM)) {
             struct dentry *parent = nd->path.dentry;
             nd->flags &= ~LOOKUP_JUMPED;
             if (unlikely(parent->d_flags & DCACHE_OP_HASH)) {
                 struct qstr this = { { .hash_len = hash_len }, .name = 
name };
c00b74a4:    91 41 00 08     stw     r10,8(r1)
c00b74a8:    91 01 00 0c     stw     r8,12(r1)
c00b74ac:    93 a1 00 10     stw     r29,16(r1)
                 err = parent->d_op->d_hash(parent, &this);
c00b74b0:    7d 23 4b 78     mr      r3,r9
c00b74b4:    81 29 00 58     lwz     r9,88(r9)
c00b74b8:    38 81 00 08     addi    r4,r1,8
c00b74bc:    81 29 00 08     lwz     r9,8(r9)
c00b74c0:    7d 29 03 a6     mtctr   r9
c00b74c4:    4e 80 04 21     bctrl
                 if (err < 0)
c00b74c8:    7c 7e 1b 79     mr.     r30,r3
c00b74cc:    41 a0 fe 58     blt     c00b7324 <link_path_walk+0x18c>
                     break;
                 hash_len = this.hash_len;
c00b74d0:    80 e1 00 08     lwz     r7,8(r1)
c00b74d4:    80 c1 00 0c     lwz     r6,12(r1)
                 name = this.name;
c00b74d8:    83 a1 00 10     lwz     r29,16(r1)
c00b74dc:    7c e5 3b 78     mr      r5,r7
c00b74e0:    39 20 00 00     li      r9,0
c00b74e4:    4b ff fd 9c     b       c00b7280 <link_path_walk+0xe8>
     if (type == LAST_DOTDOT) {
         if (nd->flags & LOOKUP_RCU) {
             if (follow_dotdot_rcu(nd))
                 return -ECHILD;
         } else
             follow_dotdot(nd);
c00b74e8:    4b ff fb 99     bl      c00b7080 <follow_dotdot>
c00b74ec:    80 9f 00 04     lwz     r4,4(r31)
c00b74f0:    4b ff fe 20     b       c00b7310 <link_path_walk+0x178>
     err = -ENOENT;
     if (!inode || d_is_negative(path->dentry))
         goto out_path_put;

     if (should_follow_link(path->dentry, follow)) {
         if (nd->flags & LOOKUP_RCU) {
c00b74f4:    81 3f 00 24     lwz     r9,36(r31)
c00b74f8:    71 28 00 40     andi.   r8,r9,64
c00b74fc:    40 82 03 10     bne     c00b780c <link_path_walk+0x674>
                      unlazy_walk(nd, path->dentry))) {
                 err = -ECHILD;
                 goto out_err;
             }
         }
         BUG_ON(inode != path->dentry->d_inode);
c00b7500:    81 24 00 28     lwz     r9,40(r4)
c00b7504:    7d 49 4a 78     xor     r9,r10,r9
c00b7508:    7d 29 00 34     cntlzw  r9,r9
c00b750c:    55 29 d9 7e     rlwinm  r9,r9,27,5,31
c00b7510:    69 29 00 01     xori    r9,r9,1
c00b7514:    0f 09 00 00     twnei   r9,0
  */
static inline int nested_symlink(struct path *path, struct nameidata *nd)
{
     int res;

     if (unlikely(current->link_count >= MAX_NESTED_LINKS)) {
c00b7518:    81 22 02 88     lwz     r9,648(r2)
c00b751c:    2f 89 00 07     cmpwi   cr7,r9,7
c00b7520:    41 9d 04 88     bgt     cr7,c00b79a8 <link_path_walk+0x810>
         path_put_conditional(path, nd);
         path_put(&nd->path);
         return -ELOOP;
     }
     BUG_ON(nd->depth >= MAX_NESTED_LINKS);
c00b7524:    81 5f 00 34     lwz     r10,52(r31)
c00b7528:    21 2a 00 07     subfic  r9,r10,7
c00b752c:    7d 29 49 10     subfe   r9,r9,r9
c00b7530:    7d 29 00 d0     neg     r9,r9
c00b7534:    0f 09 00 00     twnei   r9,0

     nd->depth++;
c00b7538:    39 4a 00 01     addi    r10,r10,1
c00b753c:    91 5f 00 34     stw     r10,52(r31)
c00b7540:    3a c0 00 00     li      r22,0
     current->link_count++;
c00b7544:    81 42 02 88     lwz     r10,648(r2)
c00b7548:    39 4a 00 01     addi    r10,r10,1
c00b754c:    91 42 02 88     stw     r10,648(r2)
c00b7550:    48 00 00 8c     b       c00b75dc <link_path_walk+0x444>
  * so we keep a cache of "no, this doesn't need follow_link"
  * for the common case.
  */
static inline int should_follow_link(struct dentry *dentry, int follow)
{
     return unlikely(d_is_symlink(dentry)) ? follow : 0;
c00b7554:    7f 88 d0 00     cmpw    cr7,r8,r26
c00b7558:    41 9e 03 d8     beq     cr7,c00b7930 <link_path_walk+0x798>
}

static inline void path_to_nameidata(const struct path *path,
                     struct nameidata *nd)
{
     if (!(nd->flags & LOOKUP_RCU)) {
c00b755c:    81 3f 00 24     lwz     r9,36(r31)
c00b7560:    80 61 00 18     lwz     r3,24(r1)
c00b7564:    71 28 00 40     andi.   r8,r9,64
c00b7568:    40 82 00 2c     bne     c00b7594 <link_path_walk+0x3fc>
         dput(nd->path.dentry);
c00b756c:    80 7f 00 04     lwz     r3,4(r31)
c00b7570:    48 00 b3 8d     bl      c00c28fc <dput>
         if (nd->path.mnt != path->mnt)
c00b7574:    80 7f 00 00     lwz     r3,0(r31)
c00b7578:    81 21 00 18     lwz     r9,24(r1)
c00b757c:    7f 83 48 00     cmpw    cr7,r3,r9
c00b7580:    41 9e 00 0c     beq     cr7,c00b758c <link_path_walk+0x3f4>
             mntput(nd->path.mnt);
c00b7584:    48 01 4f 81     bl      c00cc504 <mntput>
c00b7588:    80 61 00 18     lwz     r3,24(r1)
c00b758c:    80 81 00 1c     lwz     r4,28(r1)
c00b7590:    81 41 00 20     lwz     r10,32(r1)
     }
     nd->path.mnt = path->mnt;
c00b7594:    90 7f 00 00     stw     r3,0(r31)
     nd->path.dentry = path->dentry;
c00b7598:    90 9f 00 04     stw     r4,4(r31)
         }
         BUG_ON(inode != path->dentry->d_inode);
         return 1;
     }
     path_to_nameidata(path, nd);
     nd->inode = inode;
c00b759c:    91 5f 00 20     stw     r10,32(r31)
     return 0;
c00b75a0:    3b c0 00 00     li      r30,0
     nd->flags |= LOOKUP_JUMPED;
}

static inline void put_link(struct nameidata *nd, struct path *link, 
void *cookie)
{
     struct inode *inode = link->dentry->d_inode;
c00b75a4:    80 61 00 0c     lwz     r3,12(r1)
     if (inode->i_op->put_link)
c00b75a8:    81 23 00 28     lwz     r9,40(r3)
==> c00b75ac:    81 29 00 10     lwz     r9,16(r9)
c00b75b0:    81 29 00 14     lwz     r9,20(r9)
c00b75b4:    2f 89 00 00     cmpwi   cr7,r9,0
c00b75b8:    41 9e 00 14     beq     cr7,c00b75cc <link_path_walk+0x434>
         inode->i_op->put_link(link->dentry, nd, cookie);
c00b75bc:    7f e4 fb 78     mr      r4,r31
c00b75c0:    7e a5 ab 78     mr      r5,r21
c00b75c4:    7d 29 03 a6     mtctr   r9
c00b75c8:    4e 80 04 21     bctrl
     path_put(link);
c00b75cc:    38 61 00 08     addi    r3,r1,8
c00b75d0:    4b ff f9 3d     bl      c00b6f0c <path_put>
         res = follow_link(&link, nd, &cookie);
         if (res)
             break;
         res = walk_component(nd, path, LOOKUP_FOLLOW);
         put_link(nd, &link, cookie);
     } while (res > 0);
c00b75d4:    2f 9e 00 01     cmpwi   cr7,r30,1
c00b75d8:    40 9e 01 bc     bne     cr7,c00b7794 <link_path_walk+0x5fc>

     nd->depth++;
     current->link_count++;

     do {
         struct path link = *path;
c00b75dc:    81 21 00 1c     lwz     r9,28(r1)
{
     struct dentry *dentry = link->dentry;
     int error;
     char *s;

     BUG_ON(nd->flags & LOOKUP_RCU);
c00b75e0:    81 5f 00 24     lwz     r10,36(r31)

     nd->depth++;
     current->link_count++;

     do {
         struct path link = *path;
c00b75e4:    81 01 00 18     lwz     r8,24(r1)
c00b75e8:    7d 3e 4b 78     mr      r30,r9
c00b75ec:    91 01 00 08     stw     r8,8(r1)
c00b75f0:    91 21 00 0c     stw     r9,12(r1)
}

static __always_inline int
follow_link(struct path *link, struct nameidata *nd, void **p)
{
     struct dentry *dentry = link->dentry;
c00b75f4:    7d 35 4b 78     mr      r21,r9
     int error;
     char *s;

     BUG_ON(nd->flags & LOOKUP_RCU);
c00b75f8:    55 4a 06 72     rlwinm  r10,r10,0,25,25
c00b75fc:    0f 0a 00 00     twnei   r10,0

     if (link->mnt == nd->path.mnt)
c00b7600:    80 61 00 08     lwz     r3,8(r1)
c00b7604:    81 5f 00 00     lwz     r10,0(r31)
c00b7608:    7f 83 50 00     cmpw    cr7,r3,r10
c00b760c:    41 9e 01 80     beq     cr7,c00b778c <link_path_walk+0x5f4>
         mntget(link->mnt);

     error = -ELOOP;
     if (unlikely(current->total_link_count >= 40))
c00b7610:    81 22 02 8c     lwz     r9,652(r2)
c00b7614:    2f 89 00 27     cmpwi   cr7,r9,39
c00b7618:    41 9d 02 e0     bgt     cr7,c00b78f8 <link_path_walk+0x760>
         goto out_put_nd_path;

     cond_resched();
c00b761c:    48 2e b4 99     bl      c03a2ab4 <_cond_resched>
     current->total_link_count++;
c00b7620:    81 42 02 8c     lwz     r10,652(r2)

     touch_atime(link);
c00b7624:    38 61 00 08     addi    r3,r1,8
     error = -ELOOP;
     if (unlikely(current->total_link_count >= 40))
         goto out_put_nd_path;

     cond_resched();
     current->total_link_count++;
c00b7628:    39 4a 00 01     addi    r10,r10,1
c00b762c:    91 42 02 8c     stw     r10,652(r2)

     touch_atime(link);
c00b7630:    48 01 03 f9     bl      c00c7a28 <touch_atime>
c00b7634:    81 3f 00 34     lwz     r9,52(r31)
     error = security_inode_follow_link(link->dentry, nd);
     if (error)
         goto out_put_nd_path;

     nd->last_type = LAST_BIND;
     *p = dentry->d_inode->i_op->follow_link(dentry, nd);
c00b7638:    7e a3 ab 78     mr      r3,r21
c00b763c:    39 29 00 0c     addi    r9,r9,12
c00b7640:    55 29 10 3a     rlwinm  r9,r9,2,0,29
c00b7644:    7d 3f 4a 14     add     r9,r31,r9
c00b7648:    92 c9 00 08     stw     r22,8(r9)

     error = security_inode_follow_link(link->dentry, nd);
     if (error)
         goto out_put_nd_path;

     nd->last_type = LAST_BIND;
c00b764c:    93 7f 00 30     stw     r27,48(r31)
     *p = dentry->d_inode->i_op->follow_link(dentry, nd);
c00b7650:    7f e4 fb 78     mr      r4,r31
c00b7654:    81 3e 00 28     lwz     r9,40(r30)
c00b7658:    81 29 00 10     lwz     r9,16(r9)
c00b765c:    81 29 00 04     lwz     r9,4(r9)
c00b7660:    7d 29 03 a6     mtctr   r9
c00b7664:    4e 80 04 21     bctrl
     error = PTR_ERR(*p);
     if (IS_ERR(*p))
c00b7668:    7f 83 e0 40     cmplw   cr7,r3,r28
     error = security_inode_follow_link(link->dentry, nd);
     if (error)
         goto out_put_nd_path;

     nd->last_type = LAST_BIND;
     *p = dentry->d_inode->i_op->follow_link(dentry, nd);
c00b766c:    7c 75 1b 78     mr      r21,r3
     error = PTR_ERR(*p);
     if (IS_ERR(*p))
c00b7670:    41 9d 02 a0     bgt     cr7,c00b7910 <link_path_walk+0x778>
}

static inline char *nd_get_link(struct nameidata *nd)
{
     return nd->saved_names[nd->depth];
c00b7674:    81 3f 00 34     lwz     r9,52(r31)
c00b7678:    39 29 00 0c     addi    r9,r9,12
c00b767c:    55 29 10 3a     rlwinm  r9,r9,2,0,29
c00b7680:    7d 3f 4a 14     add     r9,r31,r9
c00b7684:    83 c9 00 08     lwz     r30,8(r9)
         goto out_put_nd_path;

     error = 0;
     s = nd_get_link(nd);
     if (s) {
c00b7688:    2f 9e 00 00     cmpwi   cr7,r30,0
c00b768c:    41 9e 00 38     beq     cr7,c00b76c4 <link_path_walk+0x52c>
         if (unlikely(IS_ERR(s))) {
c00b7690:    7f 9e e0 40     cmplw   cr7,r30,r28
c00b7694:    41 9d 01 b8     bgt     cr7,c00b784c <link_path_walk+0x6b4>
             path_put(&nd->path);
             put_link(nd, link, *p);
             return PTR_ERR(s);
         }
         if (*s == '/') {
c00b7698:    89 3e 00 00     lbz     r9,0(r30)
c00b769c:    2f 89 00 2f     cmpwi   cr7,r9,47
c00b76a0:    41 9e 00 b0     beq     cr7,c00b7750 <link_path_walk+0x5b8>
             path_put(&nd->path);
             nd->path = nd->root;
             path_get(&nd->root);
             nd->flags |= LOOKUP_JUMPED;
         }
         nd->inode = nd->path.dentry->d_inode;
c00b76a4:    81 3f 00 04     lwz     r9,4(r31)
         error = link_path_walk(s, nd);
c00b76a8:    7f c3 f3 78     mr      r3,r30
             path_put(&nd->path);
             nd->path = nd->root;
             path_get(&nd->root);
             nd->flags |= LOOKUP_JUMPED;
         }
         nd->inode = nd->path.dentry->d_inode;
c00b76ac:    81 29 00 28     lwz     r9,40(r9)
         error = link_path_walk(s, nd);
c00b76b0:    7f e4 fb 78     mr      r4,r31
             path_put(&nd->path);
             nd->path = nd->root;
             path_get(&nd->root);
             nd->flags |= LOOKUP_JUMPED;
         }
         nd->inode = nd->path.dentry->d_inode;
c00b76b4:    91 3f 00 20     stw     r9,32(r31)
         error = link_path_walk(s, nd);
c00b76b8:    4b ff fa e1     bl      c00b7198 <link_path_walk>
         if (unlikely(error))
c00b76bc:    7c 7e 1b 79     mr.     r30,r3
c00b76c0:    40 82 01 94     bne     c00b7854 <link_path_walk+0x6bc>
     /*
      * "." and ".." are special - ".." especially so because it has
      * to be able to know about the current root directory and
      * parent relationships.
      */
     if (unlikely(nd->last_type != LAST_NORM))
c00b76c4:    81 3f 00 30     lwz     r9,48(r31)
c00b76c8:    2f 89 00 00     cmpwi   cr7,r9,0
c00b76cc:    40 9e 01 d4     bne     cr7,c00b78a0 <link_path_walk+0x708>
         return handle_dots(nd, nd->last_type);
     err = lookup_fast(nd, path, &inode);
c00b76d0:    7f e3 fb 78     mr      r3,r31
c00b76d4:    38 81 00 18     addi    r4,r1,24
c00b76d8:    38 a1 00 20     addi    r5,r1,32
c00b76dc:    4b ff f5 51     bl      c00b6c2c <lookup_fast>
     if (unlikely(err)) {
c00b76e0:    7c 7e 1b 79     mr.     r30,r3
c00b76e4:    40 82 01 ec     bne     c00b78d0 <link_path_walk+0x738>
c00b76e8:    81 41 00 20     lwz     r10,32(r1)
             goto out_err;

         inode = path->dentry->d_inode;
     }
     err = -ENOENT;
     if (!inode || d_is_negative(path->dentry))
c00b76ec:    2f 8a 00 00     cmpwi   cr7,r10,0
c00b76f0:    41 9e 00 14     beq     cr7,c00b7704 <link_path_walk+0x56c>
c00b76f4:    80 81 00 1c     lwz     r4,28(r1)
c00b76f8:    81 24 00 00     lwz     r9,0(r4)
c00b76fc:    75 28 00 70     andis.  r8,r9,112
c00b7700:    40 a2 fe 54     bne     c00b7554 <link_path_walk+0x3bc>
}

static inline void path_to_nameidata(const struct path *path,
                     struct nameidata *nd)
{
     if (!(nd->flags & LOOKUP_RCU)) {
c00b7704:    81 3f 00 24     lwz     r9,36(r31)
c00b7708:    71 24 00 40     andi.   r4,r9,64
c00b770c:    41 82 00 24     beq     c00b7730 <link_path_walk+0x598>
c00b7710:    80 61 00 18     lwz     r3,24(r1)
         dput(nd->path.dentry);
         if (nd->path.mnt != path->mnt)
             mntput(nd->path.mnt);
     }
     nd->path.mnt = path->mnt;
     nd->path.dentry = path->dentry;
c00b7714:    81 21 00 1c     lwz     r9,28(r1)
     if (!(nd->flags & LOOKUP_RCU)) {
         dput(nd->path.dentry);
         if (nd->path.mnt != path->mnt)
             mntput(nd->path.mnt);
     }
     nd->path.mnt = path->mnt;
c00b7718:    90 7f 00 00     stw     r3,0(r31)
     nd->path.dentry = path->dentry;
c00b771c:    91 3f 00 04     stw     r9,4(r31)
         if (err < 0)
             goto out_err;

         inode = path->dentry->d_inode;
     }
     err = -ENOENT;
c00b7720:    3b c0 ff fe     li      r30,-2
     return 0;

out_path_put:
     path_to_nameidata(path, nd);
out_err:
     terminate_walk(nd);
c00b7724:    7f e3 fb 78     mr      r3,r31
c00b7728:    4b ff e7 b9     bl      c00b5ee0 <terminate_walk>
c00b772c:    4b ff fe 78     b       c00b75a4 <link_path_walk+0x40c>

static inline void path_to_nameidata(const struct path *path,
                     struct nameidata *nd)
{
     if (!(nd->flags & LOOKUP_RCU)) {
         dput(nd->path.dentry);
c00b7730:    80 7f 00 04     lwz     r3,4(r31)
c00b7734:    48 00 b1 c9     bl      c00c28fc <dput>
         if (nd->path.mnt != path->mnt)
c00b7738:    80 7f 00 00     lwz     r3,0(r31)
c00b773c:    81 21 00 18     lwz     r9,24(r1)
c00b7740:    7f 83 48 40     cmplw   cr7,r3,r9
c00b7744:    41 be ff d0     beq     cr7,c00b7714 <link_path_walk+0x57c>
             mntput(nd->path.mnt);
c00b7748:    48 01 4d bd     bl      c00cc504 <mntput>
c00b774c:    4b ff ff c4     b       c00b7710 <link_path_walk+0x578>
             path_put(&nd->path);
             put_link(nd, link, *p);
             return PTR_ERR(s);
         }
         if (*s == '/') {
             if (!nd->root.mnt)
c00b7750:    81 3f 00 18     lwz     r9,24(r31)
c00b7754:    2f 89 00 00     cmpwi   cr7,r9,0
c00b7758:    41 9e 00 64     beq     cr7,c00b77bc <link_path_walk+0x624>
                 set_root(nd);
             path_put(&nd->path);
c00b775c:    7f e3 fb 78     mr      r3,r31
c00b7760:    4b ff f7 ad     bl      c00b6f0c <path_put>
             nd->path = nd->root;
c00b7764:    81 5f 00 18     lwz     r10,24(r31)
c00b7768:    81 7f 00 1c     lwz     r11,28(r31)
c00b776c:    91 5f 00 00     stw     r10,0(r31)
c00b7770:    91 7f 00 04     stw     r11,4(r31)
             path_get(&nd->root);
c00b7774:    7f 23 cb 78     mr      r3,r25
c00b7778:    4b ff ee 21     bl      c00b6598 <path_get>
             nd->flags |= LOOKUP_JUMPED;
c00b777c:    81 3f 00 24     lwz     r9,36(r31)
c00b7780:    61 29 10 00     ori     r9,r9,4096
c00b7784:    91 3f 00 24     stw     r9,36(r31)
c00b7788:    4b ff ff 1c     b       c00b76a4 <link_path_walk+0x50c>
     char *s;

     BUG_ON(nd->flags & LOOKUP_RCU);

     if (link->mnt == nd->path.mnt)
         mntget(link->mnt);
c00b778c:    48 01 4f 9d     bl      c00cc728 <mntget>
c00b7790:    4b ff fe 80     b       c00b7610 <link_path_walk+0x478>
             break;
         res = walk_component(nd, path, LOOKUP_FOLLOW);
         put_link(nd, &link, cookie);
     } while (res > 0);

     current->link_count--;
c00b7794:    81 42 02 88     lwz     r10,648(r2)
         if (err < 0)
             return err;

         if (err) {
             err = nested_symlink(&next, nd);
             if (err)
c00b7798:    2f 9e 00 00     cmpwi   cr7,r30,0
             break;
         res = walk_component(nd, path, LOOKUP_FOLLOW);
         put_link(nd, &link, cookie);
     } while (res > 0);

     current->link_count--;
c00b779c:    39 4a ff ff     addi    r10,r10,-1
c00b77a0:    91 42 02 88     stw     r10,648(r2)
     nd->depth--;
c00b77a4:    81 3f 00 34     lwz     r9,52(r31)
c00b77a8:    39 29 ff ff     addi    r9,r9,-1
c00b77ac:    91 3f 00 34     stw     r9,52(r31)
         if (err < 0)
             return err;

         if (err) {
             err = nested_symlink(&next, nd);
             if (err)
c00b77b0:    40 be fb 7c     bne     cr7,c00b732c <link_path_walk+0x194>
c00b77b4:    80 9f 00 04     lwz     r4,4(r31)
c00b77b8:    4b ff fb 58     b       c00b7310 <link_path_walk+0x178>
  * The various preempt_count add/sub methods
  */

static __always_inline void __preempt_count_add(int val)
{
     *preempt_count_ptr() += val;
c00b77bc:    81 37 00 0c     lwz     r9,12(r23)
     return status;
}

static __always_inline void set_root(struct nameidata *nd)
{
     get_fs_root(current->fs, &nd->root);
c00b77c0:    81 42 03 f0     lwz     r10,1008(r2)
c00b77c4:    39 29 00 01     addi    r9,r9,1
c00b77c8:    91 37 00 0c     stw     r9,12(r23)
extern int unshare_fs_struct(void);

static inline void get_fs_root(struct fs_struct *fs, struct path *root)
{
     spin_lock(&fs->lock);
     *root = fs->root;
c00b77cc:    81 6a 00 14     lwz     r11,20(r10)
c00b77d0:    81 4a 00 10     lwz     r10,16(r10)
c00b77d4:    91 7f 00 1c     stw     r11,28(r31)
c00b77d8:    91 5f 00 18     stw     r10,24(r31)
     path_get(root);
c00b77dc:    7f 23 cb 78     mr      r3,r25
c00b77e0:    4b ff ed b9     bl      c00b6598 <path_get>
     /*
      * Because of load-store architectures cannot do per-cpu atomic
      * operations; we cannot use PREEMPT_NEED_RESCHED because it might get
      * lost.
      */
     return !--*preempt_count_ptr() && tif_need_resched();
c00b77e4:    81 37 00 0c     lwz     r9,12(r23)
c00b77e8:    39 29 ff ff     addi    r9,r9,-1
c00b77ec:    2f 89 00 00     cmpwi   cr7,r9,0
c00b77f0:    91 37 00 0c     stw     r9,12(r23)
c00b77f4:    40 be ff 68     bne     cr7,c00b775c <link_path_walk+0x5c4>
c00b77f8:    81 37 00 4c     lwz     r9,76(r23)
c00b77fc:    71 24 00 04     andi.   r4,r9,4
c00b7800:    41 a2 ff 5c     beq     c00b775c <link_path_walk+0x5c4>
c00b7804:    48 2e ac b5     bl      c03a24b8 <preempt_schedule>
c00b7808:    4b ff ff 54     b       c00b775c <link_path_walk+0x5c4>
     if (!inode || d_is_negative(path->dentry))
         goto out_path_put;

     if (should_follow_link(path->dentry, follow)) {
         if (nd->flags & LOOKUP_RCU) {
             if (unlikely(nd->path.mnt != path->mnt ||
c00b780c:    81 5f 00 00     lwz     r10,0(r31)
c00b7810:    81 21 00 18     lwz     r9,24(r1)
c00b7814:    7f 8a 48 00     cmpw    cr7,r10,r9
c00b7818:    40 9e 01 d4     bne     cr7,c00b79ec <link_path_walk+0x854>
c00b781c:    7f e3 fb 78     mr      r3,r31
c00b7820:    4b ff f2 55     bl      c00b6a74 <unlazy_walk>
c00b7824:    2f 83 00 00     cmpwi   cr7,r3,0
c00b7828:    40 9e 01 c4     bne     cr7,c00b79ec <link_path_walk+0x854>
                      unlazy_walk(nd, path->dentry))) {
                 err = -ECHILD;
                 goto out_err;
             }
         }
         BUG_ON(inode != path->dentry->d_inode);
c00b782c:    81 21 00 1c     lwz     r9,28(r1)
c00b7830:    81 49 00 28     lwz     r10,40(r9)
c00b7834:    81 21 00 08     lwz     r9,8(r1)
c00b7838:    7d 49 4a 78     xor     r9,r10,r9
c00b783c:    7d 29 00 34     cntlzw  r9,r9
c00b7840:    55 29 d9 7e     rlwinm  r9,r9,27,5,31
c00b7844:    69 29 00 01     xori    r9,r9,1
c00b7848:    4b ff fc cc     b       c00b7514 <link_path_walk+0x37c>

     error = 0;
     s = nd_get_link(nd);
     if (s) {
         if (unlikely(IS_ERR(s))) {
             path_put(&nd->path);
c00b784c:    7f e3 fb 78     mr      r3,r31
c00b7850:    4b ff f6 bd     bl      c00b6f0c <path_put>
     nd->flags |= LOOKUP_JUMPED;
}

static inline void put_link(struct nameidata *nd, struct path *link, 
void *cookie)
{
     struct inode *inode = link->dentry->d_inode;
c00b7854:    80 61 00 0c     lwz     r3,12(r1)
     if (inode->i_op->put_link)
c00b7858:    81 23 00 28     lwz     r9,40(r3)
c00b785c:    81 29 00 10     lwz     r9,16(r9)
c00b7860:    81 29 00 14     lwz     r9,20(r9)
c00b7864:    2f 89 00 00     cmpwi   cr7,r9,0
c00b7868:    41 9e 00 14     beq     cr7,c00b787c <link_path_walk+0x6e4>
         inode->i_op->put_link(link->dentry, nd, cookie);
c00b786c:    7f e4 fb 78     mr      r4,r31
c00b7870:    7e a5 ab 78     mr      r5,r21
c00b7874:    7d 29 03 a6     mtctr   r9
c00b7878:    4e 80 04 21     bctrl
     path_put(link);
c00b787c:    38 61 00 08     addi    r3,r1,8
c00b7880:    4b ff f6 8d     bl      c00b6f0c <path_put>
             break;
         res = walk_component(nd, path, LOOKUP_FOLLOW);
         put_link(nd, &link, cookie);
     } while (res > 0);

     current->link_count--;
c00b7884:    81 42 02 88     lwz     r10,648(r2)
c00b7888:    39 4a ff ff     addi    r10,r10,-1
c00b788c:    91 42 02 88     stw     r10,648(r2)
     nd->depth--;
c00b7890:    81 3f 00 34     lwz     r9,52(r31)
c00b7894:    39 29 ff ff     addi    r9,r9,-1
c00b7898:    91 3f 00 34     stw     r9,52(r31)
c00b789c:    4b ff fa 90     b       c00b732c <link_path_walk+0x194>
     return inode_permission(nd->inode, MAY_EXEC);
}

static inline int handle_dots(struct nameidata *nd, int type)
{
     if (type == LAST_DOTDOT) {
c00b78a0:    2f 89 00 03     cmpwi   cr7,r9,3
c00b78a4:    40 9e 01 50     bne     cr7,c00b79f4 <link_path_walk+0x85c>
         if (nd->flags & LOOKUP_RCU) {
c00b78a8:    81 3f 00 24     lwz     r9,36(r31)
             if (follow_dotdot_rcu(nd))
c00b78ac:    7f e3 fb 78     mr      r3,r31
}

static inline int handle_dots(struct nameidata *nd, int type)
{
     if (type == LAST_DOTDOT) {
         if (nd->flags & LOOKUP_RCU) {
c00b78b0:    71 24 00 40     andi.   r4,r9,64
c00b78b4:    41 82 00 e8     beq     c00b799c <link_path_walk+0x804>
             if (follow_dotdot_rcu(nd))
c00b78b8:    4b ff df 89     bl      c00b5840 <follow_dotdot_rcu>
                 return -ECHILD;
c00b78bc:    30 63 ff ff     addic   r3,r3,-1
c00b78c0:    7c 63 19 10     subfe   r3,r3,r3
c00b78c4:    70 7e 00 0a     andi.   r30,r3,10
c00b78c8:    3b de ff f6     addi    r30,r30,-10
c00b78cc:    4b ff fc d8     b       c00b75a4 <link_path_walk+0x40c>
      */
     if (unlikely(nd->last_type != LAST_NORM))
         return handle_dots(nd, nd->last_type);
     err = lookup_fast(nd, path, &inode);
     if (unlikely(err)) {
         if (err < 0)
c00b78d0:    41 a0 fe 54     blt     c00b7724 <link_path_walk+0x58c>
             goto out_err;

         err = lookup_slow(nd, path);
c00b78d4:    7f e3 fb 78     mr      r3,r31
c00b78d8:    38 81 00 18     addi    r4,r1,24
c00b78dc:    4b ff e5 21     bl      c00b5dfc <lookup_slow>
         if (err < 0)
c00b78e0:    7c 7e 1b 79     mr.     r30,r3
c00b78e4:    41 a0 fe 40     blt     c00b7724 <link_path_walk+0x58c>
             goto out_err;

         inode = path->dentry->d_inode;
c00b78e8:    81 21 00 1c     lwz     r9,28(r1)
c00b78ec:    81 49 00 28     lwz     r10,40(r9)
c00b78f0:    91 41 00 20     stw     r10,32(r1)
c00b78f4:    4b ff fd f8     b       c00b76ec <link_path_walk+0x554>

     return error;

out_put_nd_path:
     *p = NULL;
     path_put(&nd->path);
c00b78f8:    7f e3 fb 78     mr      r3,r31
c00b78fc:    4b ff f6 11     bl      c00b6f0c <path_put>
     path_put(link);
c00b7900:    38 61 00 08     addi    r3,r1,8
c00b7904:    4b ff f6 09     bl      c00b6f0c <path_put>
     BUG_ON(nd->flags & LOOKUP_RCU);

     if (link->mnt == nd->path.mnt)
         mntget(link->mnt);

     error = -ELOOP;
c00b7908:    3b c0 ff d8     li      r30,-40
c00b790c:    4b ff ff 78     b       c00b7884 <link_path_walk+0x6ec>

     return error;

out_put_nd_path:
     *p = NULL;
     path_put(&nd->path);
c00b7910:    7f e3 fb 78     mr      r3,r31
c00b7914:    4b ff f5 f9     bl      c00b6f0c <path_put>
     path_put(link);
c00b7918:    38 61 00 08     addi    r3,r1,8
c00b791c:    4b ff f5 f1     bl      c00b6f0c <path_put>
     do {
         struct path link = *path;
         void *cookie;

         res = follow_link(&link, nd, &cookie);
         if (res)
c00b7920:    2f 95 00 00     cmpwi   cr7,r21,0
}

static inline long __must_check PTR_ERR(__force const void *ptr)
{
     return (long) ptr;
c00b7924:    7e be ab 78     mr      r30,r21
c00b7928:    40 9e ff 5c     bne     cr7,c00b7884 <link_path_walk+0x6ec>
c00b792c:    4b ff fd 98     b       c00b76c4 <link_path_walk+0x52c>
     err = -ENOENT;
     if (!inode || d_is_negative(path->dentry))
         goto out_path_put;

     if (should_follow_link(path->dentry, follow)) {
         if (nd->flags & LOOKUP_RCU) {
c00b7930:    81 3f 00 24     lwz     r9,36(r31)
c00b7934:    71 28 00 40     andi.   r8,r9,64
c00b7938:    40 82 00 24     bne     c00b795c <link_path_walk+0x7c4>
                      unlazy_walk(nd, path->dentry))) {
                 err = -ECHILD;
                 goto out_err;
             }
         }
         BUG_ON(inode != path->dentry->d_inode);
c00b793c:    81 24 00 28     lwz     r9,40(r4)
c00b7940:    7d 49 4a 78     xor     r9,r10,r9
c00b7944:    7d 29 00 34     cntlzw  r9,r9
c00b7948:    55 29 d9 7e     rlwinm  r9,r9,27,5,31
c00b794c:    69 29 00 01     xori    r9,r9,1
c00b7950:    0f 09 00 00     twnei   r9,0
         return 1;
c00b7954:    3b c0 00 01     li      r30,1
c00b7958:    4b ff fc 4c     b       c00b75a4 <link_path_walk+0x40c>
     if (!inode || d_is_negative(path->dentry))
         goto out_path_put;

     if (should_follow_link(path->dentry, follow)) {
         if (nd->flags & LOOKUP_RCU) {
             if (unlikely(nd->path.mnt != path->mnt ||
c00b795c:    81 5f 00 00     lwz     r10,0(r31)
c00b7960:    81 21 00 18     lwz     r9,24(r1)
c00b7964:    7f 8a 48 00     cmpw    cr7,r10,r9
c00b7968:    40 9e 00 94     bne     cr7,c00b79fc <link_path_walk+0x864>
c00b796c:    7f e3 fb 78     mr      r3,r31
c00b7970:    4b ff f1 05     bl      c00b6a74 <unlazy_walk>
c00b7974:    2f 83 00 00     cmpwi   cr7,r3,0
c00b7978:    40 9e 00 84     bne     cr7,c00b79fc <link_path_walk+0x864>
                      unlazy_walk(nd, path->dentry))) {
                 err = -ECHILD;
                 goto out_err;
             }
         }
         BUG_ON(inode != path->dentry->d_inode);
c00b797c:    81 21 00 1c     lwz     r9,28(r1)
c00b7980:    81 49 00 28     lwz     r10,40(r9)
c00b7984:    81 21 00 20     lwz     r9,32(r1)
c00b7988:    7d 49 4a 78     xor     r9,r10,r9
c00b798c:    7d 29 00 34     cntlzw  r9,r9
c00b7990:    55 29 d9 7e     rlwinm  r9,r9,27,5,31
c00b7994:    69 29 00 01     xori    r9,r9,1
c00b7998:    4b ff ff b8     b       c00b7950 <link_path_walk+0x7b8>
     if (type == LAST_DOTDOT) {
         if (nd->flags & LOOKUP_RCU) {
             if (follow_dotdot_rcu(nd))
                 return -ECHILD;
         } else
             follow_dotdot(nd);
c00b799c:    4b ff f6 e5     bl      c00b7080 <follow_dotdot>
     }
     return 0;
c00b79a0:    3b c0 00 00     li      r30,0
c00b79a4:    4b ff fc 00     b       c00b75a4 <link_path_walk+0x40c>
static inline int nested_symlink(struct path *path, struct nameidata *nd)
{
     int res;

     if (unlikely(current->link_count >= MAX_NESTED_LINKS)) {
         path_put_conditional(path, nd);
c00b79a8:    7f e4 fb 78     mr      r4,r31
c00b79ac:    38 61 00 18     addi    r3,r1,24
c00b79b0:    4b ff e3 f5     bl      c00b5da4 <path_put_conditional.isra.50>
         path_put(&nd->path);
c00b79b4:    7f e3 fb 78     mr      r3,r31
c00b79b8:    4b ff f5 55     bl      c00b6f0c <path_put>
         return -ELOOP;
c00b79bc:    38 60 ff d8     li      r3,-40
c00b79c0:    4b ff f9 70     b       c00b7330 <link_path_walk+0x198>
      */
     if (unlikely(nd->last_type != LAST_NORM))
         return handle_dots(nd, nd->last_type);
     err = lookup_fast(nd, path, &inode);
     if (unlikely(err)) {
         if (err < 0)
c00b79c4:    41 a0 f9 60     blt     c00b7324 <link_path_walk+0x18c>
             goto out_err;

         err = lookup_slow(nd, path);
c00b79c8:    7f e3 fb 78     mr      r3,r31
c00b79cc:    38 81 00 18     addi    r4,r1,24
c00b79d0:    4b ff e4 2d     bl      c00b5dfc <lookup_slow>
         if (err < 0)
c00b79d4:    7c 7e 1b 79     mr.     r30,r3
c00b79d8:    41 a0 f9 4c     blt     c00b7324 <link_path_walk+0x18c>
             goto out_err;

         inode = path->dentry->d_inode;
c00b79dc:    81 21 00 1c     lwz     r9,28(r1)
c00b79e0:    81 49 00 28     lwz     r10,40(r9)
c00b79e4:    91 41 00 08     stw     r10,8(r1)
c00b79e8:    4b ff f8 ec     b       c00b72d4 <link_path_walk+0x13c>

     if (should_follow_link(path->dentry, follow)) {
         if (nd->flags & LOOKUP_RCU) {
             if (unlikely(nd->path.mnt != path->mnt ||
                      unlazy_walk(nd, path->dentry))) {
                 err = -ECHILD;
c00b79ec:    3b c0 ff f6     li      r30,-10
c00b79f0:    4b ff f9 34     b       c00b7324 <link_path_walk+0x18c>
             if (follow_dotdot_rcu(nd))
                 return -ECHILD;
         } else
             follow_dotdot(nd);
     }
     return 0;
c00b79f4:    3b c0 00 00     li      r30,0
c00b79f8:    4b ff fb ac     b       c00b75a4 <link_path_walk+0x40c>

     if (should_follow_link(path->dentry, follow)) {
         if (nd->flags & LOOKUP_RCU) {
             if (unlikely(nd->path.mnt != path->mnt ||
                      unlazy_walk(nd, path->dentry))) {
                 err = -ECHILD;
c00b79fc:    3b c0 ff f6     li      r30,-10
c00b7a00:    4b ff fd 24     b       c00b7724 <link_path_walk+0x58c>


[59685.968909] Unable to handle kernel paging request for data at 
address 0x4f5f5079
[59685.981479] Faulting instruction address: 0xc00b74ec
[59685.990902] Oops: Kernel access of bad area, sig: 11 [#1]
[59685.996037] PREEMPT CMPC885
[59685.998833] CPU: 0 PID: 1019 Comm: SUO_ Not tainted 3.18.20 #49
[59686.006392] task: c66789a0 ti: c6456000 task.ti: c6456000
[59686.011719] NIP: c00b74ec LR: c00b74b4 CTR: c00fcc94
[59686.016631] REGS: c6457d10 TRAP: 0300   Not tainted  (3.18.20)
[59686.024098] MSR: 00009032 <EE,ME,IR,DR,RI>  CR: 22002482 XER: 00000000
[59686.030644] DAR: 4f5f5079 DSISR: c0000000
[59686.030644] GPR00: c00b74b4 c6457dc0 c66789a0 c105b410 c505b498 
c505b4d2 90f9ced3 00000031
[59686.030644] GPR08: 00000000 4f5f5069 c50605a0 227406f5 22002482 
101baac0 101b0000 1017b6d8
[59686.030644] GPR16: 1023961c 1017354c 1017b620 1014c608 10503284 
00000000 00000000 c6456000
[59686.030644] GPR24: 00100000 c6457ea0 00300000 00000004 fffff000 
c63fb02f 00000000 c6457e88
[59686.062616] NIP [c00b74ec] link_path_walk+0x414/0x86c
[59686.067595] LR [c00b74b4] link_path_walk+0x3dc/0x86c
[59686.072462] Call Trace:
[59686.074910] [c6457dc0] [c00b74b4] link_path_walk+0x3dc/0x86c (unreliable)
[59686.081627] [c6457e20] [c00b9d70] path_openat+0x90/0x678
[59686.086873] [c6457e80] [c00ba388] do_filp_open+0x30/0x8c
[59686.092128] [c6457f00] [c00abb48] do_sys_open+0x14c/0x238
[59686.097466] [c6457f40] [c000b294] ret_from_syscall+0x0/0x38
[59686.102923] Instruction dump:
[59686.105853] 7f834800 419e000c 48014f75 80610018 8081001c 81410020 
907f0000 909f0004
[59686.113513] 915f0020 3bc00000 8061000c 81230028 <81290010> 81290014 
2f890000 419e0014

[214067.708785] Unable to handle kernel paging request for data at 
address 0x93a10024
[214067.716082] Faulting instruction address: 0xc00b7350
[214067.721082] Oops: Kernel access of bad area, sig: 11 [#1]
[214067.726477] PREEMPT CMPC885
[214067.729360] CPU: 0 PID: 1021 Comm: SUO_ Not tainted 3.18.14 #43
[214067.737006] task: c6600e70 ti: c653e000 task.ti: c653e000
[214067.742420] NIP: c00b7350 LR: c00b7318 CTR: c00fcb04
[214067.747418] REGS: c653fd10 TRAP: 0300   Not tainted  (3.18.14)
[214067.754969] MSR: 00009032 <EE,ME,IR,DR,RI>  CR: 22002482 XER: 00000000
[214067.761608] DAR: 93a10024 DSISR: c0000000
[214067.761608] GPR00: c00b7318 c653fdc0 c6600e70 c105ac18 c505aca0 
c505acda 90f9ced3 00000031
[214067.761608] GPR08: 00000000 93a10014 c5060360 39d5d053 22002482 
101cae54 1017c030 105103ec
[214067.761608] GPR16: 101c0c38 00000003 10510120 1017c248 10239598 
00000000 00000000 c653e000
[214067.761608] GPR24: 00100000 c653fea0 00300000 00000004 fffff000 
c65f302f 00000000 c653fe88
[214067.793667] NIP [c00b7350] link_path_walk+0x414/0x86c
[214067.798730] LR [c00b7318] link_path_walk+0x3dc/0x86c
[214067.803681] Call Trace:
[214067.806219] [c653fdc0] [c00b7318] link_path_walk+0x3dc/0x86c 
(unreliable)
[214067.813017] [c653fe20] [c00b9bd4] path_openat+0x90/0x678
[214067.818352] [c653fe80] [c00ba1ec] do_filp_open+0x30/0x8c
[214067.823694] [c653ff00] [c00ab9ac] do_sys_open+0x14c/0x238
[214067.829120] [c653ff40] [c000b27c] ret_from_syscall+0x0/0x38
[214067.834658] Instruction dump:
[214067.837675] 7f834800 419e000c 48014fb5 80610018 8081001c 81410020 
907f0000 909f0004
[214067.845418] 915f0020 3bc00000 8061000c 81230028 <81290010> 81290014 
2f890000 419e0014
[214067.853353] ---[ end trace 78a545fb58576151 ]---

[205816.678044] Unable to handle kernel paging request for data at 
address 0x20202030
[205816.688395] Faulting instruction address: 0xc00b74ec
[205816.693912] Oops: Kernel access of bad area, sig: 11 [#1]
[205816.699098] PREEMPT CMPC885
[205816.701980] CPU: 0 PID: 1009 Comm: GVC_ Not tainted 3.18.20 #49
[205816.709627] task: c6655810 ti: c66b0000 task.ti: c66b0000
[205816.715038] NIP: c00b74ec LR: c00b74b4 CTR: c00fcc94
[205816.720037] REGS: c66b1d10 TRAP: 0300 Not tainted (3.18.20)
[205816.727589] MSR: 00009032 <EE,ME,IR,DR,RI> CR: 22002482 XER: 00000000
[205816.734221] DAR: 20202030 DSISR: c0000000
[205816.734221] GPR00: c00b74b4 c66b1dc0 c6655810 c105b388 c505b410 
c505b44b 3ac16eed 00000032
[205816.734221] GPR08: 00000000 20202020 c5061680 0e505267 22002482 
101baac0 00000000 1015a584
[205816.734221] GPR16: 1015a4ec 1015a56c 101b0508 101b08a4 10159f88 
00000000 00000000 c66b0000
[205816.734221] GPR24: 00100000 c66b1ea0 00300000 00000004 fffff000 
c6479030 00000000 c66b1e88
[205816.766277] NIP [c00b74ec] link_path_walk+0x414/0x86c
[205816.771343] LR [c00b74b4] link_path_walk+0x3dc/0x86c
[205816.776299] Call Trace:
[205816.778832] [c66b1dc0] [c00b74b4] link_path_walk+0x3dc/0x86c 
(unreliable)
[205816.785636] [c66b1e20] [c00b9d70] path_openat+0x90/0x678
[205816.790967] [c66b1e80] [c00ba388] do_filp_open+0x30/0x8c
[205816.796304] [c66b1f00] [c00abb48] do_sys_open+0x14c/0x238
[205816.801733] [c66b1f40] [c000b294] ret_from_syscall+0x0/0x38
[205816.807275] Instruction dump:
[205816.810292] 7f834800 419e000c 48014f75 80610018 8081001c 81410020 
907f0000 909f0004
[205816.818038] 915f0020 3bc00000 8061000c 81230028 <81290010> 81290014 
2f890000 419e0014

[219713.431174] Unable to handle kernel paging request for data at 
address 0x6e3d227e
[219713.438912] Faulting instruction address: 0xc00b7350
[219713.445717] Oops: Kernel access of bad area, sig: 11 [#1]
[219713.450862] PREEMPT CMPC885
[219713.453744] CPU: 0 PID: 1016 Comm: SUO_ Not tainted 3.18.14 #43
[219713.461390] task: c66b0e70 ti: c66ec000 task.ti: c66ec000
[219713.466803] NIP: c00b7350 LR: c00b7318 CTR: c00fcb04
[219713.471801] REGS: c66edd10 TRAP: 0300   Not tainted  (3.18.14)
[219713.479352] MSR: 00009032 <EE,ME,IR,DR,RI>  CR: 22002482 XER: 00000000
[219713.485989] DAR: 6e3d227e DSISR: c0000000
[219713.485989] GPR00: c00b7318 c66eddc0 c66b0e70 c105ab08 c505ab90 
c505abca 90f9ced3 00000031
[219713.485989] GPR08: 00000000 6e3d226e c5060360 0d2c06ce 22002482 
101cae54 1017c030 105103ec
[219713.485989] GPR16: 101c0c38 00000003 10510120 1017c248 10239598 
00000000 00000000 c66ec000
[219713.485989] GPR24: 00100000 c66edea0 00300000 00000004 fffff000 
c63f802f 00000000 c66ede88
[219713.518053] NIP [c00b7350] link_path_walk+0x414/0x86c
[219713.523116] LR [c00b7318] link_path_walk+0x3dc/0x86c
[219713.528067] Call Trace:
[219713.530601] [c66eddc0] [c00b7318] link_path_walk+0x3dc/0x86c 
(unreliable)
[219713.537401] [c66ede20] [c00b9bd4] path_openat+0x90/0x678
[219713.542735] [c66ede80] [c00ba1ec] do_filp_open+0x30/0x8c
[219713.548078] [c66edf00] [c00ab9ac] do_sys_open+0x14c/0x238
[219713.553503] [c66edf40] [c000b27c] ret_from_syscall+0x0/0x38
[219713.559041] Instruction dump:
[219713.562058] 7f834800 419e000c 48014fb5 80610018 8081001c 81410020 
907f0000 909f0004
[219713.569801] 915f0020 3bc00000 8061000c 81230028 <81290010> 81290014 
2f890000 419e0014



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Recurring Oops in link_path_walk()
  2015-11-20 17:07 Recurring Oops in link_path_walk() Christophe Leroy
@ 2015-11-20 17:56 ` Al Viro
  2015-11-20 18:58   ` Scott Wood
  0 siblings, 1 reply; 5+ messages in thread
From: Al Viro @ 2015-11-20 17:56 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: linux-kernel, LinuxPPC-dev, linux-fsdevel, BOUET Serge, BARABAN Luc

On Fri, Nov 20, 2015 at 06:07:59PM +0100, Christophe Leroy wrote:
> Al,
> 
> We've been running Kernel 3.18 for several monthes on our embedded
> boards, and we have a recurring Oops in link_path_walk()
> It doesn't happen very often (approximatly once every month on one
> board among a set of 50 boards, never the same board).
> 
> Here below is the last oops I got, with kernel 3.18.22. It crashes
> at address 0xc00b75ac. Here below is the full desassembly of
> link_path_walk() so that you can see exactly the offending line.
> 
> The address it fails at is always the same (link_path_walk+0x414)
> but the oopsing data address is each time different. I added all
> Oops I got below after the disassembly (on different sub-versions of
> 3.18).

Looks like garbage in dentry->d_inode, assuming that reconstruction of
the mapping of line numbers to addresses is correct...  Not sure it is,
though; what's more, just how does LR manage to point to the insn right
after the call of dput(), of all things?

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Recurring Oops in link_path_walk()
  2015-11-20 17:56 ` Al Viro
@ 2015-11-20 18:58   ` Scott Wood
  2015-11-20 21:17     ` Al Viro
  0 siblings, 1 reply; 5+ messages in thread
From: Scott Wood @ 2015-11-20 18:58 UTC (permalink / raw)
  To: Al Viro, Christophe Leroy
  Cc: linux-kernel, LinuxPPC-dev, linux-fsdevel, BOUET Serge, BARABAN Luc

On Fri, 2015-11-20 at 17:56 +0000, Al Viro wrote:
> On Fri, Nov 20, 2015 at 06:07:59PM +0100, Christophe Leroy wrote:
> > Al,
> > 
> > We've been running Kernel 3.18 for several monthes on our embedded
> > boards, and we have a recurring Oops in link_path_walk()
> > It doesn't happen very often (approximatly once every month on one
> > board among a set of 50 boards, never the same board).
> > 
> > Here below is the last oops I got, with kernel 3.18.22. It crashes
> > at address 0xc00b75ac. Here below is the full desassembly of
> > link_path_walk() so that you can see exactly the offending line.
> > 
> > The address it fails at is always the same (link_path_walk+0x414)
> > but the oopsing data address is each time different. I added all
> > Oops I got below after the disassembly (on different sub-versions of
> > 3.18).
> 
> Looks like garbage in dentry->d_inode, assuming that reconstruction of
> the mapping of line numbers to addresses is correct...  Not sure it is,
> though; what's more, just how does LR manage to point to the insn right
> after the call of dput(), of all things?

When "bl dput" is executed, LR gets set to the instruction after the bl. 
 After dput returns, LR still has that value.  Presumably the call to mntput
was skipped via the beq.  Nothing else modifies LR between the dput return and
the faulting address.

-Scott



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Recurring Oops in link_path_walk()
  2015-11-20 18:58   ` Scott Wood
@ 2015-11-20 21:17     ` Al Viro
  2015-11-21 10:37       ` christophe leroy
  0 siblings, 1 reply; 5+ messages in thread
From: Al Viro @ 2015-11-20 21:17 UTC (permalink / raw)
  To: Scott Wood
  Cc: Christophe Leroy, linux-kernel, LinuxPPC-dev, linux-fsdevel,
	BOUET Serge, BARABAN Luc

On Fri, Nov 20, 2015 at 12:58:40PM -0600, Scott Wood wrote:

> > Looks like garbage in dentry->d_inode, assuming that reconstruction of
> > the mapping of line numbers to addresses is correct...  Not sure it is,
> > though; what's more, just how does LR manage to point to the insn right
> > after the call of dput(), of all things?
> 
> When "bl dput" is executed, LR gets set to the instruction after the bl. 
>  After dput returns, LR still has that value.  Presumably the call to mntput
> was skipped via the beq.  Nothing else modifies LR between the dput return and
> the faulting address.

OK, AFAICS it's this:
604)        do {
605)                struct path link = *path;
606)                void *cookie;
607) 
608)                res = follow_link(&link, nd, &cookie);
609)                if (res)
610)                        break;
611)                res = walk_component(nd, path, LOOKUP_FOLLOW);
612)                put_link(nd, &link, cookie);
and we are seeing assorted garbage as link.dentry->d_inode at put_link()
call.  What's really interesting, follow_link() has return 0, which means
that it must have passed through
849)        *p = dentry->d_inode->i_op->follow_link(dentry, nd);
with
825)        struct dentry *dentry = link->dentry;
upstream of that and link as seen by follow_link() is &link as seen by
caller (nested_symlink()); IOW, at that point link.dentry->d_inode used to
be a valid pointer.

Do you have something resembling a reproducer or a chance to get a crash
dump at that point?

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Recurring Oops in link_path_walk()
  2015-11-20 21:17     ` Al Viro
@ 2015-11-21 10:37       ` christophe leroy
  0 siblings, 0 replies; 5+ messages in thread
From: christophe leroy @ 2015-11-21 10:37 UTC (permalink / raw)
  To: Al Viro
  Cc: Scott Wood, linux-kernel, LinuxPPC-dev, linux-fsdevel,
	BOUET Serge, BARABAN Luc



Le 20/11/2015 22:17, Al Viro a écrit :
> On Fri, Nov 20, 2015 at 12:58:40PM -0600, Scott Wood wrote:
>
>>> Looks like garbage in dentry->d_inode, assuming that reconstruction of
>>> the mapping of line numbers to addresses is correct...  Not sure it is,
>>> though; what's more, just how does LR manage to point to the insn right
>>> after the call of dput(), of all things?
>> When "bl dput" is executed, LR gets set to the instruction after the bl.
>>   After dput returns, LR still has that value.  Presumably the call to mntput
>> was skipped via the beq.  Nothing else modifies LR between the dput return and
>> the faulting address.
> OK, AFAICS it's this:
> 604)        do {
> 605)                struct path link = *path;
> 606)                void *cookie;
> 607)
> 608)                res = follow_link(&link, nd, &cookie);
> 609)                if (res)
> 610)                        break;
> 611)                res = walk_component(nd, path, LOOKUP_FOLLOW);
> 612)                put_link(nd, &link, cookie);
> and we are seeing assorted garbage as link.dentry->d_inode at put_link()
> call.  What's really interesting, follow_link() has return 0, which means
> that it must have passed through
> 849)        *p = dentry->d_inode->i_op->follow_link(dentry, nd);
> with
> 825)        struct dentry *dentry = link->dentry;
> upstream of that and link as seen by follow_link() is &link as seen by
> caller (nested_symlink()); IOW, at that point link.dentry->d_inode used to
> be a valid pointer.
>
> Do you have something resembling a reproducer or a chance to get a crash
> dump at that point?
>

Unfortunately no, I got no way to reproduce it, it happens very seldom.
Not sure what kind of crash dump I could get when it happens.

Maybe I can try to add delais/scheduling between follow_link() and 
put_link() to see if it happens more often ?


Also got a few other Oops at different functions but even more seldom 
than this one, not sure it has any link with that one, but I put them 
below just in case. Maybe they are worth being investigated as well, in 
that case I could also provide function disassembly for them:



[46796.501487] Unable to handle kernel paging request for data at 
address 0x000002dd
[46796.514365] Faulting instruction address: 0xc00c5978
[46796.524217] Oops: Kernel access of bad area, sig: 11 [#1]
[46796.529351] PREEMPT CMPC885
[46796.532144] CPU: 0 PID: 1107 Comm: snmpd Not tainted 3.18.14 #43
[46796.539790] task: c682d340 ti: c6728000 task.ti: c6728000
[46796.545119] NIP: c00c5978 LR: c00c5974 CTR: c00efeb4
[46796.550033] REGS: c6729e00 TRAP: 0300   Not tainted (3.18.14)
[46796.557497] MSR: 00009032 <EE,ME,IR,DR,RI>  CR: 24042424 XER: 20000000
[46796.564043] DAR: 000002dd DSISR: c0000000
[46796.564043] GPR00: c00c5974 c6729eb0 c682d340 00000000 c5a02734 
00000003 00000000 00851d4a
[46796.564043] GPR08: 000005ae 000002b9 00009032 000001e4 24042424 
1001c8cc 7fc835f8 100ad378
[46796.564043] GPR16: 00000000 7fc835f0 7fc835e8 7fc835e0 7fc835d8 
7fc835d0 7fc835c8 7fc835c0
[46796.564043] GPR24: 0fe59f14 000002ac c6a44b48 c6056110 c5e03168 
c5a026e0 c6728000 c1a026e0
[46796.596017] NIP [c00c5978] destroy_inode+0x38/0x84
[46796.600736] LR [c00c5974] destroy_inode+0x34/0x84
[46796.605344] Call Trace:
[46796.607793] [c6729eb0] [c00c5974] destroy_inode+0x34/0x84 (unreliable)
[46796.614271] [c6729ec0] [c00c1d90] __dentry_kill+0x2a8/0x304
[46796.619763] [c6729ee0] [c00c27c8] dput+0xd0/0x1d8
[46796.624416] [c6729f00] [c00adf54] __fput+0x134/0x1fc
[46796.629319] [c6729f20] [c002de28] task_work_run+0xac/0xf4
[46796.634655] [c6729f40] [c000bba4] do_user_signal+0x74/0xc4
[46796.640023] Instruction dump:
[46796.642955] 39430078 93e1000c 90010014 7c7f1b78 81230078 7d295278 
7d290034 5529d97e
[46796.650612] 69290001 0f090000 4bffff45 813f0014 <81290024> 81290004 
2f890000 419e0020

Here it is inode->i_sb which seems wrong.

c00c5940 <destroy_inode>:
     struct inode *inode = container_of(head, struct inode, i_rcu);
     kmem_cache_free(inode_cachep, inode);
}

static void destroy_inode(struct inode *inode)
{
c00c5940:    7c 08 02 a6     mflr    r0
c00c5944:    94 21 ff f0     stwu    r1,-16(r1)
     BUG_ON(!list_empty(&inode->i_lru));
c00c5948:    39 43 00 78     addi    r10,r3,120
     struct inode *inode = container_of(head, struct inode, i_rcu);
     kmem_cache_free(inode_cachep, inode);
}

static void destroy_inode(struct inode *inode)
{
c00c594c:    93 e1 00 0c     stw     r31,12(r1)
c00c5950:    90 01 00 14     stw     r0,20(r1)
c00c5954:    7c 7f 1b 78     mr      r31,r3
     BUG_ON(!list_empty(&inode->i_lru));
c00c5958:    81 23 00 78     lwz     r9,120(r3)
c00c595c:    7d 29 52 78     xor     r9,r9,r10
c00c5960:    7d 29 00 34     cntlzw  r9,r9
c00c5964:    55 29 d9 7e     rlwinm  r9,r9,27,5,31
c00c5968:    69 29 00 01     xori    r9,r9,1
c00c596c:    0f 09 00 00     twnei   r9,0
     __destroy_inode(inode);
c00c5970:    4b ff ff 45     bl      c00c58b4 <__destroy_inode>
     if (inode->i_sb->s_op->destroy_inode)
c00c5974:    81 3f 00 14     lwz     r9,20(r31)
==> c00c5978:    81 29 00 24     lwz     r9,36(r9)
c00c597c:    81 29 00 04     lwz     r9,4(r9)
c00c5980:    2f 89 00 00     cmpwi   cr7,r9,0
c00c5984:    41 9e 00 20     beq     cr7,c00c59a4 <destroy_inode+0x64>
         inode->i_sb->s_op->destroy_inode(inode);
     else
         call_rcu(&inode->i_rcu, i_callback);
}
c00c5988:    80 01 00 14     lwz     r0,20(r1)


[32878.259271] Unable to handle kernel paging request for data at 
address 0xf030f0f4
[32878.266488] Faulting instruction address: 0xc00b65ec
[32878.271404] Oops: Kernel access of bad area, sig: 11 [#1]
[32878.276712] PREEMPT CMPC885
[32878.279510] CPU: 0 PID: 1391 Comm: snmpd Not tainted 3.18.14 #43
[32878.287157] task: c6812b50 ti: c6c2a000 task.ti: c6c2a000
[32878.292482] NIP: c00b65ec LR: c00b65c8 CTR: 00000000
[32878.297395] REGS: c6c2bd40 TRAP: 0300   Not tainted  (3.18.14)
[32878.304860] MSR: 00009032 <EE,ME,IR,DR,RI>  CR: 22042422 XER: 00000000
[32878.311408] DAR: f030f0f4 DSISR: c0000000
[32878.311408] GPR00: c00b9bb8 c6c2bdf0 c6812b50 ffffff9c c6478010 
00000051 f0e1f0f0 f030f0f0
[32878.311408] GPR08: f0f8f0f0 c2c05380 f030f0f0 00000220 42042422 
1001c8cc 7fffffff 0ffedab0
[32878.311408] GPR16: 3f800000 1001c314 559b51dc 7fca8508 1001bcb0 
00000000 7fca84f8 1001be28
[32878.311408] GPR24: 0fe8c008 1001be28 00000041 c6478000 c6c2bf08 
ffffff9c c6c2be88 c6c2be88
[32878.343378] NIP [c00b65ec] path_init+0x25c/0x488
[32878.347929] LR [c00b65c8] path_init+0x238/0x488
[32878.352365] Call Trace:
[32878.354798] [c6c2bdf0] [c0531500] 0xc0531500 (unreliable)
[32878.360158] [c6c2be20] [c00b9bb8] path_openat+0x74/0x678
[32878.365402] [c6c2be80] [c00ba1ec] do_filp_open+0x30/0x8c
[32878.370657] [c6c2bf00] [c00ab9ac] do_sys_open+0x14c/0x238
[32878.375997] [c6c2bf40] [c000b27c] ret_from_syscall+0x0/0x38
[32878.381449] Instruction dump:
[32878.384379] 70a70040 41820114 4bf90a81 812203f0 81090004 710a0001 
40820240 81490014
[32878.392039] 80c90010 915f001c 90df0018 7d475378 <814a0004> 71460001 
40820210 80e90004

[122726.996005] Unable to handle kernel paging request for data at 
address 0xf0f0f0f4
[122727.003271] Faulting instruction address: 0xc00b65ec
[122727.008271] Oops: Kernel access of bad area, sig: 11 [#1]
[122727.013667] PREEMPT CMPC885
[122727.016550] CPU: 0 PID: 567 Comm: snmpd Not tainted 3.18.14 #43
[122727.024196] task: c63bb9c0 ti: c647e000 task.ti: c647e000
[122727.029608] NIP: c00b65ec LR: c00b65c8 CTR: 00000000
[122727.034607] REGS: c647fd40 TRAP: 0300   Not tainted  (3.18.14)
[122727.042159] MSR: 00009032 <EE,ME,IR,DR,RI>  CR: 24222422 XER: 00000000
[122727.048793] DAR: f0f0f0f4 DSISR: c0000000
[122727.048793] GPR00: c00b9bb8 c647fdf0 c63bb9c0 ffffff9c c6432010 
00000051 f0f0f0f0 f0f0f0f0
[122727.048793] GPR08: f0f0f0f0 c2501040 f0f0f0f0 000000da 44222422 
1001c8cc 00000000 0000000a
[122727.048793] GPR16: 10151c70 7f84fab1 7f84fbe8 7f84ff40 7f84faa8 
00000000 10127b90 7f84fbf0
[122727.048793] GPR24: 0ff681f8 1014a590 00000041 c6432000 c647ff08 
ffffff9c c647fe88 c647fe88
[122727.080850] NIP [c00b65ec] path_init+0x25c/0x488
[122727.085486] LR [c00b65c8] path_init+0x238/0x488
[122727.090008] Call Trace:
[122727.092528] [c647fdf0] [c0531500] 0xc0531500 (unreliable)
[122727.097974] [c647fe20] [c00b9bb8] path_openat+0x74/0x678
[122727.103304] [c647fe80] [c00ba1ec] do_filp_open+0x30/0x8c
[122727.108642] [c647ff00] [c00ab9ac] do_sys_open+0x14c/0x238
[122727.114070] [c647ff40] [c000b27c] ret_from_syscall+0x0/0x38
[122727.119609] Instruction dump:
[122727.122625] 70a70040 41820114 4bf90a81 812203f0 81090004 710a0001 
40820240 81490014
[122727.130370] 80c90010 915f001c 90df0018 7d475378 <814a0004> 71460001 
40820210 80e90004


---
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast.
https://www.avast.com/antivirus


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2015-11-21 10:37 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-20 17:07 Recurring Oops in link_path_walk() Christophe Leroy
2015-11-20 17:56 ` Al Viro
2015-11-20 18:58   ` Scott Wood
2015-11-20 21:17     ` Al Viro
2015-11-21 10:37       ` christophe leroy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).