Changes to enable fastlinks. Compile with option FASTLINKS to activate.
authorJordan K. Hubbard <jkh@FreeBSD.org>
Thu, 22 Jul 1993 16:58:16 +0000 (16:58 +0000)
committerJordan K. Hubbard <jkh@FreeBSD.org>
Thu, 22 Jul 1993 16:58:16 +0000 (16:58 +0000)
sys/ufs/dinode.h
sys/ufs/inode.h
sys/ufs/ufs_inode.c
sys/ufs/ufs_vnops.c

index 599c6a4..73ddd48 100644 (file)
@@ -41,6 +41,8 @@
 #define        NDADDR  12              /* direct addresses in inode */
 #define        NIADDR  3               /* indirect addresses in inode */
 
 #define        NDADDR  12              /* direct addresses in inode */
 #define        NIADDR  3               /* indirect addresses in inode */
 
+#define        MAXFASTLINK     (((NDADDR+NIADDR) * sizeof(daddr_t)) - 1)
+
 struct dinode {
        u_short di_mode;        /*  0: mode and type of file */
        short   di_nlink;       /*  2: number of links to file */
 struct dinode {
        u_short di_mode;        /*  0: mode and type of file */
        short   di_nlink;       /*  2: number of links to file */
@@ -53,14 +55,24 @@ struct dinode {
        long    di_mtspare;
        time_t  di_ctime;       /* 32: last time inode changed */
        long    di_ctspare;
        long    di_mtspare;
        time_t  di_ctime;       /* 32: last time inode changed */
        long    di_ctspare;
-       daddr_t di_db[NDADDR];  /* 40: disk block addresses */
-       daddr_t di_ib[NIADDR];  /* 88: indirect blocks */
+       union {
+               struct {
+                       daddr_t di_udb[NDADDR]; /* 40: disk block addresses */
+                       daddr_t di_uib[NIADDR]; /* 88: indirect blocks */
+               } di_addr;
+               char di_usymlink[MAXFASTLINK+1];
+       } di_un;
        long    di_flags;       /* 100: status, currently unused */
        long    di_blocks;      /* 104: blocks actually held */
        long    di_gen;         /* 108: generation number */
        long    di_flags;       /* 100: status, currently unused */
        long    di_blocks;      /* 104: blocks actually held */
        long    di_gen;         /* 108: generation number */
-       long    di_spare[4];    /* 112: reserved, currently unused */
+#define        DI_SPARE_SZ     4               /* 112: spare for 4 longs */
+       u_long  di_spare[DI_SPARE_SZ];  /* reserved (unused) */
 };
 
 };
 
+#define        di_db           di_un.di_addr.di_udb
+#define di_ib          di_un.di_addr.di_uib
+#define        di_symlink      di_un.di_usymlink
+
 #if BYTE_ORDER == LITTLE_ENDIAN || defined(tahoe) /* ugh! -- must be fixed */
 #define        di_size         di_qsize.val[0]
 #else /* BYTE_ORDER == BIG_ENDIAN */
 #if BYTE_ORDER == LITTLE_ENDIAN || defined(tahoe) /* ugh! -- must be fixed */
 #define        di_size         di_qsize.val[0]
 #else /* BYTE_ORDER == BIG_ENDIAN */
@@ -84,3 +96,8 @@ struct dinode {
 #define        IREAD           0400            /* read permission */
 #define        IWRITE          0200            /* write permission */
 #define        IEXEC           0100            /* execute permission */
 #define        IREAD           0400            /* read permission */
 #define        IWRITE          0200            /* write permission */
 #define        IEXEC           0100            /* execute permission */
+
+#define        DFASTLINK(di) \
+       ((((di).di_mode & IFMT) == IFLNK) && \
+        ((di).di_size <= MAXFASTLINK) && \
+        ((di).di_size == (di).di_spare[0]))
index b945ae4..7f86627 100644 (file)
@@ -67,6 +67,8 @@ struct inode {
        struct  dinode i_din;   /* the on-disk dinode */
 };
 
        struct  dinode i_din;   /* the on-disk dinode */
 };
 
+#define        FASTLINK(ip)    (DFASTLINK((ip)->i_din))
+#define        i_symlink       i_din.di_symlink
 #define        i_mode          i_din.di_mode
 #define        i_nlink         i_din.di_nlink
 #define        i_uid           i_din.di_uid
 #define        i_mode          i_din.di_mode
 #define        i_nlink         i_din.di_nlink
 #define        i_uid           i_din.di_uid
@@ -87,6 +89,7 @@ struct inode {
 #define i_gen          i_din.di_gen
 #define        i_forw          i_chain[0]
 #define        i_back          i_chain[1]
 #define i_gen          i_din.di_gen
 #define        i_forw          i_chain[0]
 #define        i_back          i_chain[1]
+#define        i_di_spare      i_din.di_spare
 
 /* flags */
 #define        ILOCKED         0x0001          /* inode is locked */
 
 /* flags */
 #define        ILOCKED         0x0001          /* inode is locked */
index 34eaa76..543d88f 100644 (file)
@@ -140,6 +140,8 @@ loop:
        for (i = 0; i < MAXQUOTAS; i++)
                ip->i_dquot[i] = NODQUOT;
 #endif
        for (i = 0; i < MAXQUOTAS; i++)
                ip->i_dquot[i] = NODQUOT;
 #endif
+       for (i=0; i < DI_SPARE_SZ; i++)
+               ip->i_di_spare[i] = (unsigned long)0L;
        /*
         * Put it onto its hash chain and lock it so that other requests for
         * this inode will block if they arrive while we are sleeping waiting
        /*
         * Put it onto its hash chain and lock it so that other requests for
         * this inode will block if they arrive while we are sleeping waiting
@@ -406,6 +408,13 @@ itrunc(oip, length, flags)
        struct inode tip;
 
        vnode_pager_setsize(ITOV(oip), length);
        struct inode tip;
 
        vnode_pager_setsize(ITOV(oip), length);
+       if (FASTLINK(oip)) {
+               if (length != 0)
+                       panic("itrunc fastlink to non-zero");
+               bzero(oip->i_symlink, MAXFASTLINK);
+               oip->i_size = 0;
+               oip->i_din.di_spare[0] = 0;
+       }
        if (oip->i_size <= length) {
                oip->i_flag |= ICHG|IUPD;
                error = iupdat(oip, &time, &time, 1);
        if (oip->i_size <= length) {
                oip->i_flag |= ICHG|IUPD;
                error = iupdat(oip, &time, &time, 1);
index b7ff76c..922fd6a 100644 (file)
@@ -1281,12 +1281,22 @@ ufs_symlink(ndp, vap, target, p)
        struct proc *p;
 {
        struct inode *ip;
        struct proc *p;
 {
        struct inode *ip;
+       int len = strlen(target);
        int error;
 
        error = maknode(IFLNK | vap->va_mode, ndp, &ip);
        if (error)
                return (error);
        int error;
 
        error = maknode(IFLNK | vap->va_mode, ndp, &ip);
        if (error)
                return (error);
-       error = vn_rdwr(UIO_WRITE, ITOV(ip), target, strlen(target), (off_t)0,
+#ifdef FASTLINKS
+       if (len <= MAXFASTLINK) {
+               ip->i_din.di_spare[0] = len;
+               ip->i_size = len;
+               bcopy(target, ip->i_symlink, len);
+               ip->i_flag |= ICHG;
+               error = iupdat(ip, &time, &time, 1);
+       } else
+#endif
+       error = vn_rdwr(UIO_WRITE, ITOV(ip), target, len, (off_t)0,
                UIO_SYSSPACE, IO_NODELOCKED, ndp->ni_cred, (int *)0,
                (struct proc *)0);
        iput(ip);
                UIO_SYSSPACE, IO_NODELOCKED, ndp->ni_cred, (int *)0,
                (struct proc *)0);
        iput(ip);
@@ -1328,8 +1338,11 @@ ufs_readlink(vp, uiop, cred)
        struct uio *uiop;
        struct ucred *cred;
 {
        struct uio *uiop;
        struct ucred *cred;
 {
-
-       return (ufs_read(vp, uiop, 0, cred));
+       struct inode *ip = VTOI(vp);
+       if (FASTLINK(ip))
+               return (uiomove(ip->i_symlink, ip->i_size, uiop));
+       else
+               return (ufs_read(vp, uiop, 0, cred));
 }
 
 /*
 }
 
 /*