From owner-svn-src-all@FreeBSD.ORG Sat Apr 7 15:27:35 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 11E2F106564A; Sat, 7 Apr 2012 15:27:35 +0000 (UTC) (envelope-from gleb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id E743F8FC12; Sat, 7 Apr 2012 15:27:34 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q37FRYCD067803; Sat, 7 Apr 2012 15:27:34 GMT (envelope-from gleb@svn.freebsd.org) Received: (from gleb@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q37FRYJ9067798; Sat, 7 Apr 2012 15:27:34 GMT (envelope-from gleb@svn.freebsd.org) Message-Id: <201204071527.q37FRYJ9067798@svn.freebsd.org> From: Gleb Kurtsou Date: Sat, 7 Apr 2012 15:27:34 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r233999 - in head/sys: fs/tmpfs kern sys X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 07 Apr 2012 15:27:35 -0000 Author: gleb Date: Sat Apr 7 15:27:34 2012 New Revision: 233999 URL: http://svn.freebsd.org/changeset/base/233999 Log: Add vfs_getopt_size. Support human readable file system options in tmpfs. Increase maximum tmpfs file system size to 4GB*PAGE_SIZE on 32 bit archs. Discussed with: delphij MFC after: 2 weeks Modified: head/sys/fs/tmpfs/tmpfs_vfsops.c head/sys/kern/vfs_mount.c head/sys/sys/mount.h Modified: head/sys/fs/tmpfs/tmpfs_vfsops.c ============================================================================== --- head/sys/fs/tmpfs/tmpfs_vfsops.c Sat Apr 7 15:23:51 2012 (r233998) +++ head/sys/fs/tmpfs/tmpfs_vfsops.c Sat Apr 7 15:27:34 2012 (r233999) @@ -132,12 +132,10 @@ tmpfs_mount(struct mount *mp) { struct tmpfs_mount *tmp; struct tmpfs_node *root; - size_t pages; - uint32_t nodes; int error; /* Size counters. */ - u_int nodes_max; - u_quad_t size_max, maxfilesize; + u_quad_t pages; + off_t nodes_max, size_max, maxfilesize; /* Root node attributes. */ uid_t root_uid; @@ -173,12 +171,11 @@ tmpfs_mount(struct mount *mp) if (mp->mnt_cred->cr_ruid != 0 || vfs_scanopt(mp->mnt_optnew, "mode", "%ho", &root_mode) != 1) root_mode = va.va_mode; - if (vfs_scanopt(mp->mnt_optnew, "inodes", "%u", &nodes_max) != 1) + if (vfs_getopt_size(mp->mnt_optnew, "inodes", &nodes_max) != 0) nodes_max = 0; - if (vfs_scanopt(mp->mnt_optnew, "size", "%qu", &size_max) != 1) + if (vfs_getopt_size(mp->mnt_optnew, "size", &size_max) != 0) size_max = 0; - if (vfs_scanopt(mp->mnt_optnew, "maxfilesize", "%qu", - &maxfilesize) != 1) + if (vfs_getopt_size(mp->mnt_optnew, "maxfilesize", &maxfilesize) != 0) maxfilesize = 0; /* Do not allow mounts if we do not have enough memory to preserve @@ -190,7 +187,8 @@ tmpfs_mount(struct mount *mp) * allowed to use, based on the maximum size the user passed in * the mount structure. A value of zero is treated as if the * maximum available space was requested. */ - if (size_max < PAGE_SIZE || size_max > SIZE_MAX - PAGE_SIZE) + if (size_max < PAGE_SIZE || size_max > OFF_MAX - PAGE_SIZE || + (SIZE_MAX < OFF_MAX && size_max / PAGE_SIZE >= SIZE_MAX)) pages = SIZE_MAX; else pages = howmany(size_max, PAGE_SIZE); @@ -198,21 +196,20 @@ tmpfs_mount(struct mount *mp) if (nodes_max <= 3) { if (pages > UINT32_MAX - 3) - nodes = UINT32_MAX; + nodes_max = UINT32_MAX; else - nodes = pages + 3; - } else - nodes = nodes_max; - MPASS(nodes >= 3); + nodes_max = pages + 3; + } + MPASS(nodes_max >= 3); /* Allocate the tmpfs mount structure and fill it. */ tmp = (struct tmpfs_mount *)malloc(sizeof(struct tmpfs_mount), M_TMPFSMNT, M_WAITOK | M_ZERO); mtx_init(&tmp->allnode_lock, "tmpfs allnode lock", NULL, MTX_DEF); - tmp->tm_nodes_max = nodes; + tmp->tm_nodes_max = nodes_max; tmp->tm_nodes_inuse = 0; - tmp->tm_maxfilesize = maxfilesize > 0 ? maxfilesize : UINT64_MAX; + tmp->tm_maxfilesize = maxfilesize > 0 ? maxfilesize : OFF_MAX; LIST_INIT(&tmp->tm_nodes_used); tmp->tm_pages_max = pages; Modified: head/sys/kern/vfs_mount.c ============================================================================== --- head/sys/kern/vfs_mount.c Sat Apr 7 15:23:51 2012 (r233998) +++ head/sys/kern/vfs_mount.c Sat Apr 7 15:27:34 2012 (r233999) @@ -1520,6 +1520,48 @@ vfs_getopt_pos(struct vfsoptlist *opts, return (-1); } +int +vfs_getopt_size(struct vfsoptlist *opts, const char *name, off_t *value) +{ + char *opt_value, *vtp; + quad_t iv; + int error, opt_len; + + error = vfs_getopt(opts, name, (void **)&opt_value, &opt_len); + if (error != 0) + return (error); + if (opt_len == 0 || opt_value == NULL) + return (EINVAL); + if (opt_value[0] == '\0' || opt_value[opt_len - 1] != '\0') + return (EINVAL); + iv = strtoq(opt_value, &vtp, 0); + if (vtp == opt_value || (vtp[0] != '\0' && vtp[1] != '\0')) + return (EINVAL); + if (iv < 0) + return (EINVAL); + switch (vtp[0]) { + case 't': + case 'T': + iv *= 1024; + case 'g': + case 'G': + iv *= 1024; + case 'm': + case 'M': + iv *= 1024; + case 'k': + case 'K': + iv *= 1024; + case '\0': + break; + default: + return (EINVAL); + } + *value = iv; + + return (0); +} + char * vfs_getopts(struct vfsoptlist *opts, const char *name, int *error) { Modified: head/sys/sys/mount.h ============================================================================== --- head/sys/sys/mount.h Sat Apr 7 15:23:51 2012 (r233998) +++ head/sys/sys/mount.h Sat Apr 7 15:27:34 2012 (r233999) @@ -718,6 +718,8 @@ int vfs_flagopt(struct vfsoptlist *opts, uint64_t val); int vfs_getopt(struct vfsoptlist *, const char *, void **, int *); int vfs_getopt_pos(struct vfsoptlist *opts, const char *name); +int vfs_getopt_size(struct vfsoptlist *opts, const char *name, + off_t *value); char *vfs_getopts(struct vfsoptlist *, const char *, int *error); int vfs_copyopt(struct vfsoptlist *, const char *, void *, int); int vfs_filteropt(struct vfsoptlist *, const char **legal);