Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/ufs/ext2fs bump link limit to 65000 for files, and add s...



details:   https://anonhg.NetBSD.org/src/rev/fadd7c1b3e46
branches:  trunk
changeset: 817282:fadd7c1b3e46
user:      jdolecek <jdolecek%NetBSD.org@localhost>
date:      Mon Aug 15 18:38:10 2016 +0000

description:
bump link limit to 65000 for files, and add support for EXT2F_ROCOMPAT_DIR_NLINK to make link count unlimited for directories

diffstat:

 sys/ufs/ext2fs/ext2fs.h        |  12 +++++++++-
 sys/ufs/ext2fs/ext2fs_rename.c |  12 +++++-----
 sys/ufs/ext2fs/ext2fs_vnops.c  |  44 ++++++++++++++++++++++++++++-------------
 3 files changed, 46 insertions(+), 22 deletions(-)

diffs (197 lines):

diff -r 6f5d01aae88d -r fadd7c1b3e46 sys/ufs/ext2fs/ext2fs.h
--- a/sys/ufs/ext2fs/ext2fs.h   Mon Aug 15 18:29:34 2016 +0000
+++ b/sys/ufs/ext2fs/ext2fs.h   Mon Aug 15 18:38:10 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ext2fs.h,v 1.45 2016/08/14 11:42:50 jdolecek Exp $     */
+/*     $NetBSD: ext2fs.h,v 1.46 2016/08/15 18:38:10 jdolecek Exp $     */
 
 /*
  * Copyright (c) 1982, 1986, 1993
@@ -128,6 +128,13 @@
 #define MINFREE                5
 
 /*
+ * This is maximum amount of links allowed for files. For directories,
+ * going over this means setting DIR_NLINK feature.
+ */
+#define EXT2FS_LINK_MAX                65000
+#define EXT2FS_LINK_INF                1               /* link count unknown */
+
+/*
  * Super block for an ext2fs file system.
  */
 struct ext2fs {
@@ -358,7 +365,8 @@
 #define EXT2F_ROCOMPAT_SUPP            (EXT2F_ROCOMPAT_SPARSESUPER \
                                         | EXT2F_ROCOMPAT_LARGEFILE \
                                         | EXT2F_ROCOMPAT_HUGE_FILE \
-                                        | EXT2F_ROCOMPAT_EXTRA_ISIZE)
+                                        | EXT2F_ROCOMPAT_EXTRA_ISIZE \
+                                        | EXT2F_ROCOMPAT_DIR_NLINK)
 #define EXT2F_INCOMPAT_SUPP            (EXT2F_INCOMPAT_FTYPE \
                                         | EXT2F_INCOMPAT_EXTENTS)
 
diff -r 6f5d01aae88d -r fadd7c1b3e46 sys/ufs/ext2fs/ext2fs_rename.c
--- a/sys/ufs/ext2fs/ext2fs_rename.c    Mon Aug 15 18:29:34 2016 +0000
+++ b/sys/ufs/ext2fs/ext2fs_rename.c    Mon Aug 15 18:38:10 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ext2fs_rename.c,v 1.10 2016/08/13 07:40:10 christos Exp $      */
+/*     $NetBSD: ext2fs_rename.c,v 1.11 2016/08/15 18:38:10 jdolecek Exp $      */
 
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ext2fs_rename.c,v 1.10 2016/08/13 07:40:10 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ext2fs_rename.c,v 1.11 2016/08/15 18:38:10 jdolecek Exp $");
 
 #include <sys/param.h>
 #include <sys/buf.h>
@@ -307,7 +307,7 @@
         * We shall need to temporarily bump the link count, so make
         * sure there is room to do so.
         */
-       if ((nlink_t)VTOI(fvp)->i_e2fs_nlink >= LINK_MAX)
+       if ((nlink_t)VTOI(fvp)->i_e2fs_nlink >= EXT2FS_LINK_MAX)
                return EMLINK;
 
        directory_p = (fvp->v_type == VDIR);
@@ -330,7 +330,7 @@
         *    may be wrong, but correctable.
         */
 
-       KASSERT((nlink_t)VTOI(fvp)->i_e2fs_nlink < LINK_MAX);
+       KASSERT((nlink_t)VTOI(fvp)->i_e2fs_nlink < EXT2FS_LINK_MAX);
        VTOI(fvp)->i_e2fs_nlink++;
        VTOI(fvp)->i_flag |= IN_CHANGE;
        error = ext2fs_update(fvp, NULL, NULL, UPDATE_WAIT);
@@ -352,11 +352,11 @@
                 * parent we don't fool with the link count.
                 */
                if (directory_p && reparent_p) {
-                       if ((nlink_t)VTOI(tdvp)->i_e2fs_nlink >= LINK_MAX) {
+                       if ((nlink_t)VTOI(tdvp)->i_e2fs_nlink >= EXT2FS_LINK_MAX) {
                                error = EMLINK;
                                goto whymustithurtsomuch;
                        }
-                       KASSERT((nlink_t)VTOI(tdvp)->i_e2fs_nlink < LINK_MAX);
+                       KASSERT((nlink_t)VTOI(tdvp)->i_e2fs_nlink < EXT2FS_LINK_MAX);
                        VTOI(tdvp)->i_e2fs_nlink++;
                        VTOI(tdvp)->i_flag |= IN_CHANGE;
                        error = ext2fs_update(tdvp, NULL, NULL, UPDATE_WAIT);
diff -r 6f5d01aae88d -r fadd7c1b3e46 sys/ufs/ext2fs/ext2fs_vnops.c
--- a/sys/ufs/ext2fs/ext2fs_vnops.c     Mon Aug 15 18:29:34 2016 +0000
+++ b/sys/ufs/ext2fs/ext2fs_vnops.c     Mon Aug 15 18:38:10 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ext2fs_vnops.c,v 1.124 2016/08/15 18:29:34 jdolecek Exp $      */
+/*     $NetBSD: ext2fs_vnops.c,v 1.125 2016/08/15 18:38:10 jdolecek Exp $      */
 
 /*
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -65,7 +65,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.124 2016/08/15 18:29:34 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.125 2016/08/15 18:38:10 jdolecek Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -626,7 +626,7 @@
                goto out2;
        }
        ip = VTOI(vp);
-       if ((nlink_t)ip->i_e2fs_nlink >= LINK_MAX) {
+       if ((nlink_t)ip->i_e2fs_nlink >= EXT2FS_LINK_MAX) {
                VOP_ABORTOP(dvp, cnp);
                error = EMLINK;
                goto out1;
@@ -677,11 +677,6 @@
        ulr = &VTOI(dvp)->i_crap;
        UFS_CHECK_CRAPCOUNTER(VTOI(dvp));
 
-       if ((nlink_t)dp->i_e2fs_nlink >= LINK_MAX) {
-               error = EMLINK;
-               goto out;
-       }
-
        /*
         * Acquire the inode, but don't sync/direnter it just yet
         */
@@ -700,7 +695,24 @@
         * be done before reference is created
         * so reparation is possible if we crash.
         */
-       dp->i_e2fs_nlink++;
+       if (dp->i_e2fs_nlink != EXT2FS_LINK_INF)
+               dp->i_e2fs_nlink++;
+
+       /*
+        * If we hit the link limit, for directories just set the nlink
+        * to special value 1, which means the link count is bigger
+        * than EXT2FS_LINK_MAX.
+        */
+       if ((nlink_t)dp->i_e2fs_nlink >= EXT2FS_LINK_MAX) {
+               dp->i_e2fs_nlink = EXT2FS_LINK_INF;
+
+               /* set the feature flag DIR_NLINK if not set already */
+               if (!EXT2F_HAS_ROCOMPAT_FEATURE(dp->i_e2fs, EXT2F_ROCOMPAT_DIR_NLINK)) {
+                       dp->i_e2fs->e2fs.e2fs_features_rocompat |= EXT2F_ROCOMPAT_DIR_NLINK;
+                       dp->i_e2fs->e2fs_fmod = 1;
+               }
+       }
+
        dp->i_flag |= IN_CHANGE;
        if ((error = ext2fs_update(dvp, NULL, NULL, UPDATE_DIROP)) != 0)
                goto bad;
@@ -725,7 +737,8 @@
            sizeof (dirtemplate), (off_t)0, IO_NODELOCKED|IO_SYNC,
            cnp->cn_cred, (size_t *)0, NULL);
        if (error) {
-               dp->i_e2fs_nlink--;
+               if (dp->i_e2fs_nlink != EXT2FS_LINK_INF)
+                       dp->i_e2fs_nlink--;
                dp->i_flag |= IN_CHANGE;
                goto bad;
        }
@@ -734,7 +747,8 @@
        else {
                error = ext2fs_setsize(ip, VTOI(dvp)->i_e2fs->e2fs_bsize);
                if (error) {
-                       dp->i_e2fs_nlink--;
+                       if (dp->i_e2fs_nlink != EXT2FS_LINK_INF)
+                               dp->i_e2fs_nlink--;
                        dp->i_flag |= IN_CHANGE;
                        goto bad;
                }
@@ -745,7 +759,8 @@
        /* Directory set up, now install its entry in the parent directory. */
        error = ext2fs_direnter(ip, dvp, ulr, cnp);
        if (error != 0) {
-               dp->i_e2fs_nlink--;
+               if (dp->i_e2fs_nlink != EXT2FS_LINK_INF)
+                       dp->i_e2fs_nlink--;
                dp->i_flag |= IN_CHANGE;
        }
 bad:
@@ -807,7 +822,7 @@
         *  non-empty.)
         */
        error = 0;
-       if (ip->i_e2fs_nlink != 2 ||
+       if ((ip->i_e2fs_nlink != 2 && ip->i_e2fs_nlink != EXT2FS_LINK_INF) ||
            !ext2fs_dirempty(ip, dp->i_number, cnp->cn_cred)) {
                error = ENOTEMPTY;
                goto out;
@@ -825,7 +840,8 @@
        error = ext2fs_dirremove(dvp, ulr, cnp);
        if (error != 0)
                goto out;
-       dp->i_e2fs_nlink--;
+       if (dp->i_e2fs_nlink != EXT2FS_LINK_INF)
+               dp->i_e2fs_nlink--;
        dp->i_flag |= IN_CHANGE;
        VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK);
        cache_purge(dvp);



Home | Main Index | Thread Index | Old Index