Print this page
7653 tmpfs: calling unlink() on a directory which isn't empty should fail

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/tmpfs/tmp_dir.c
          +++ new/usr/src/uts/common/fs/tmpfs/tmp_dir.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
       24 + *
       25 + * Copyright 2016 RackTop Systems.
  24   26   */
  25   27  
  26      -#pragma ident   "%Z%%M% %I%     %E% SMI"
  27      -
  28   28  #include <sys/types.h>
  29   29  #include <sys/param.h>
  30   30  #include <sys/sysmacros.h>
  31   31  #include <sys/systm.h>
  32   32  #include <sys/time.h>
  33   33  #include <sys/vfs.h>
  34   34  #include <sys/vnode.h>
  35   35  #include <sys/errno.h>
  36   36  #include <sys/cmn_err.h>
  37   37  #include <sys/cred.h>
↓ open down ↓ 442 lines elided ↑ open up ↑
 480  480          }
 481  481  
 482  482          /*
 483  483           * If the tmpnode in the tdirent changed, we were probably
 484  484           * the victim of a concurrent rename operation.  The original
 485  485           * is gone, so return that status (same as UFS).
 486  486           */
 487  487          if (tp != tnp)
 488  488                  return (ENOENT);
 489  489  
      490 +        /*
      491 +         * If we are unlinking a directory which isn't empty (it has
      492 +         * more than the minumum '.' and '..' entries) return EEXIST.
      493 +         */
      494 +        if (tp->tn_type == VDIR && tp->tn_dirents > 2)
      495 +                return (EEXIST);
      496 +
 490  497          tmpfs_hash_out(tpdp);
 491  498  
 492  499          /*
 493  500           * Take tpdp out of the directory list.
 494  501           */
 495  502          ASSERT(tpdp->td_next != tpdp);
 496  503          ASSERT(tpdp->td_prev != tpdp);
 497  504          if (tpdp->td_prev) {
 498  505                  tpdp->td_prev->td_next = tpdp->td_next;
 499  506          }
↓ open down ↓ 20 lines elided ↑ open up ↑
 520  527          dir->tn_size -= (sizeof (struct tdirent) + namelen);
 521  528          dir->tn_dirents--;
 522  529  
 523  530          gethrestime(&now);
 524  531          dir->tn_mtime = now;
 525  532          dir->tn_ctime = now;
 526  533          tp->tn_ctime = now;
 527  534  
 528  535          ASSERT(tp->tn_nlink > 0);
 529  536          DECR_COUNT(&tp->tn_nlink, &tp->tn_tlock);
 530      -        if (op == DR_RMDIR && tp->tn_type == VDIR) {
      537 +        if (tp->tn_type == VDIR) {
 531  538                  tdirtrunc(tp);
 532  539                  ASSERT(tp->tn_nlink == 0);
 533  540          }
 534  541          return (0);
 535  542  }
 536  543  
 537  544  /*
 538  545   * tdirinit is used internally to initialize a directory (dir)
 539  546   * with '.' and '..' entries without checking permissions and locking
 540  547   */
↓ open down ↓ 555 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX