Author: mmacy
Date: Wed Feb 20 20:55:02 2019
New Revision: 344385
URL: https://svnweb.freebsd.org/changeset/base/344385

Log:
  PFS: Bump NAMELEN and don't require clients to be sleepable
  
  - debugfs consumers expect to be able to export names more than 48 characters
  
  - debugfs consumers expect to be able to hold locks across calls and are able
    to handle allocation failures
  
  Reviewed by:  hps@
  MFC after:    1 week
  Sponsored by: iX Systems
  Differential Revision:        https://reviews.freebsd.org/D19256

Modified:
  head/sys/fs/pseudofs/pseudofs.c
  head/sys/fs/pseudofs/pseudofs.h

Modified: head/sys/fs/pseudofs/pseudofs.c
==============================================================================
--- head/sys/fs/pseudofs/pseudofs.c     Wed Feb 20 20:48:10 2019        
(r344384)
+++ head/sys/fs/pseudofs/pseudofs.c     Wed Feb 20 20:55:02 2019        
(r344385)
@@ -68,15 +68,20 @@ SYSCTL_INT(_vfs_pfs, OID_AUTO, trace, CTLFLAG_RW, &pfs
  * Allocate and initialize a node
  */
 static struct pfs_node *
-pfs_alloc_node(struct pfs_info *pi, const char *name, pfs_type_t type)
+pfs_alloc_node_flags(struct pfs_info *pi, const char *name, pfs_type_t type, 
int flags)
 {
        struct pfs_node *pn;
+       int malloc_flags;
 
        KASSERT(strlen(name) < PFS_NAMELEN,
            ("%s(): node name is too long", __func__));
-
-       pn = malloc(sizeof *pn,
-           M_PFSNODES, M_WAITOK|M_ZERO);
+       if (flags & PFS_NOWAIT)
+               malloc_flags = M_NOWAIT | M_ZERO;
+       else
+               malloc_flags = M_WAITOK | M_ZERO;
+       pn = malloc(sizeof *pn, M_PFSNODES, malloc_flags);
+       if (pn == NULL)
+               return (NULL);
        mtx_init(&pn->pn_mutex, "pfs_node", NULL, MTX_DEF | MTX_DUPOK);
        strlcpy(pn->pn_name, name, sizeof pn->pn_name);
        pn->pn_type = type;
@@ -84,6 +89,12 @@ pfs_alloc_node(struct pfs_info *pi, const char *name, 
        return (pn);
 }
 
+static struct pfs_node *
+pfs_alloc_node(struct pfs_info *pi, const char *name, pfs_type_t type)
+{
+       return (pfs_alloc_node_flags(pi, name, type, 0));
+}
+
 /*
  * Add a node to a directory
  */
@@ -160,15 +171,29 @@ pfs_detach_node(struct pfs_node *pn)
 /*
  * Add . and .. to a directory
  */
+static int
+pfs_fixup_dir_flags(struct pfs_node *parent, int flags)
+{
+       struct pfs_node *dot, *dotdot;
+
+       dot = pfs_alloc_node_flags(parent->pn_info, ".", pfstype_this, flags);
+       if (dot == NULL)
+               return (ENOMEM);
+       dotdot = pfs_alloc_node_flags(parent->pn_info, "..", pfstype_parent, 
flags);
+       if (dotdot == NULL) {
+               pfs_destroy(dot);
+               return (ENOMEM);
+       }
+       pfs_add_node(parent, dot);
+       pfs_add_node(parent, dotdot);
+       return (0);
+}
+
 static void
 pfs_fixup_dir(struct pfs_node *parent)
 {
-       struct pfs_node *pn;
 
-       pn = pfs_alloc_node(parent->pn_info, ".", pfstype_this);
-       pfs_add_node(parent, pn);
-       pn = pfs_alloc_node(parent->pn_info, "..", pfstype_parent);
-       pfs_add_node(parent, pn);
+       pfs_fixup_dir_flags(parent, 0);
 }
 
 /*
@@ -180,16 +205,22 @@ pfs_create_dir(struct pfs_node *parent, const char *na
               int flags)
 {
        struct pfs_node *pn;
+       int rc;
 
-       pn = pfs_alloc_node(parent->pn_info, name,
-           (flags & PFS_PROCDEP) ? pfstype_procdir : pfstype_dir);
+       pn = pfs_alloc_node_flags(parent->pn_info, name,
+                        (flags & PFS_PROCDEP) ? pfstype_procdir : pfstype_dir, 
flags);
+       if (pn == NULL)
+               return (NULL);
        pn->pn_attr = attr;
        pn->pn_vis = vis;
        pn->pn_destroy = destroy;
        pn->pn_flags = flags;
        pfs_add_node(parent, pn);
-       pfs_fixup_dir(pn);
-
+       rc = pfs_fixup_dir_flags(pn, flags);
+       if (rc) {
+               pfs_destroy(pn);
+               return (NULL);
+       }
        return (pn);
 }
 
@@ -203,7 +234,9 @@ pfs_create_file(struct pfs_node *parent, const char *n
 {
        struct pfs_node *pn;
 
-       pn = pfs_alloc_node(parent->pn_info, name, pfstype_file);
+       pn = pfs_alloc_node_flags(parent->pn_info, name, pfstype_file, flags);
+       if (pn == NULL)
+               return (NULL);
        pn->pn_fill = fill;
        pn->pn_attr = attr;
        pn->pn_vis = vis;
@@ -224,7 +257,9 @@ pfs_create_link(struct pfs_node *parent, const char *n
 {
        struct pfs_node *pn;
 
-       pn = pfs_alloc_node(parent->pn_info, name, pfstype_symlink);
+       pn = pfs_alloc_node_flags(parent->pn_info, name, pfstype_symlink, 
flags);
+       if (pn == NULL)
+               return (NULL);
        pn->pn_fill = fill;
        pn->pn_attr = attr;
        pn->pn_vis = vis;

Modified: head/sys/fs/pseudofs/pseudofs.h
==============================================================================
--- head/sys/fs/pseudofs/pseudofs.h     Wed Feb 20 20:48:10 2019        
(r344384)
+++ head/sys/fs/pseudofs/pseudofs.h     Wed Feb 20 20:55:02 2019        
(r344385)
@@ -52,7 +52,7 @@ struct vnode;
 /*
  * Limits and constants
  */
-#define PFS_NAMELEN            48
+#define PFS_NAMELEN            128
 #define PFS_FSNAMELEN          16      /* equal to MFSNAMELEN */
 #define PFS_DELEN              (offsetof(struct dirent, d_name) + PFS_NAMELEN)
 
@@ -77,6 +77,7 @@ typedef enum {
 #define        PFS_RAWWR       0x0008  /* raw writer */
 #define PFS_RAW                (PFS_RAWRD|PFS_RAWWR)
 #define PFS_PROCDEP    0x0010  /* process-dependent */
+#define PFS_NOWAIT     0x0020 /* allow malloc to fail */
 
 /*
  * Data structures
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to