Fri Jan 27 10:47:54 2017 UTC ()
Run vflush() when going from read/write to read only.


(hannken)
diff -r1.52 -r1.53 src/sys/fs/tmpfs/tmpfs.h
diff -r1.68 -r1.69 src/sys/fs/tmpfs/tmpfs_vfsops.c

cvs diff -r1.52 -r1.53 src/sys/fs/tmpfs/tmpfs.h (expand / switch to unified diff)

--- src/sys/fs/tmpfs/tmpfs.h 2015/07/06 10:07:12 1.52
+++ src/sys/fs/tmpfs/tmpfs.h 2017/01/27 10:47:54 1.53
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: tmpfs.h,v 1.52 2015/07/06 10:07:12 hannken Exp $ */ 1/* $NetBSD: tmpfs.h,v 1.53 2017/01/27 10:47:54 hannken Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc. 4 * Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Julio M. Merino Vidal, developed as part of Google's Summer of Code 8 * by Julio M. Merino Vidal, developed as part of Google's Summer of Code
9 * 2005 program. 9 * 2005 program.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -207,26 +207,29 @@ CTASSERT(TMPFS_MAXNAMLEN < UINT16_MAX); @@ -207,26 +207,29 @@ CTASSERT(TMPFS_MAXNAMLEN < UINT16_MAX);
207 * Ored into tmpfs_node_t::tn_holdcount. 207 * Ored into tmpfs_node_t::tn_holdcount.
208 */ 208 */
209#define TMPFS_NODE_RECLAIMED (1U << 30) 209#define TMPFS_NODE_RECLAIMED (1U << 30)
210 210
211/* 211/*
212 * Internal representation of a tmpfs mount point. 212 * Internal representation of a tmpfs mount point.
213 */ 213 */
214typedef struct tmpfs_mount { 214typedef struct tmpfs_mount {
215 /* Limit and number of bytes in use by the file system. */ 215 /* Limit and number of bytes in use by the file system. */
216 uint64_t tm_mem_limit; 216 uint64_t tm_mem_limit;
217 uint64_t tm_bytes_used; 217 uint64_t tm_bytes_used;
218 kmutex_t tm_acc_lock; 218 kmutex_t tm_acc_lock;
219 219
 220 /* Read-only indicator. */
 221 bool tm_rdonly;
 222
220 /* Pointer to the root inode. */ 223 /* Pointer to the root inode. */
221 tmpfs_node_t * tm_root; 224 tmpfs_node_t * tm_root;
222 225
223 /* Maximum number of possible nodes for this file system. */ 226 /* Maximum number of possible nodes for this file system. */
224 unsigned int tm_nodes_max; 227 unsigned int tm_nodes_max;
225 228
226 /* Number of nodes currently allocated. */ 229 /* Number of nodes currently allocated. */
227 unsigned int tm_nodes_cnt; 230 unsigned int tm_nodes_cnt;
228 231
229 /* List of inodes and the lock protecting it. */ 232 /* List of inodes and the lock protecting it. */
230 kmutex_t tm_lock; 233 kmutex_t tm_lock;
231 struct tmpfs_node_list tm_nodes; 234 struct tmpfs_node_list tm_nodes;
232} tmpfs_mount_t; 235} tmpfs_mount_t;

cvs diff -r1.68 -r1.69 src/sys/fs/tmpfs/tmpfs_vfsops.c (expand / switch to unified diff)

--- src/sys/fs/tmpfs/tmpfs_vfsops.c 2016/08/26 21:44:24 1.68
+++ src/sys/fs/tmpfs/tmpfs_vfsops.c 2017/01/27 10:47:54 1.69
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: tmpfs_vfsops.c,v 1.68 2016/08/26 21:44:24 dholland Exp $ */ 1/* $NetBSD: tmpfs_vfsops.c,v 1.69 2017/01/27 10:47:54 hannken Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc. 4 * Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Julio M. Merino Vidal, developed as part of Google's Summer of Code 8 * by Julio M. Merino Vidal, developed as part of Google's Summer of Code
9 * 2005 program. 9 * 2005 program.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -32,27 +32,27 @@ @@ -32,27 +32,27 @@
32 32
33/* 33/*
34 * Efficient memory file system. 34 * Efficient memory file system.
35 * 35 *
36 * tmpfs is a file system that uses NetBSD's virtual memory sub-system 36 * tmpfs is a file system that uses NetBSD's virtual memory sub-system
37 * (the well-known UVM) to store file data and metadata in an efficient 37 * (the well-known UVM) to store file data and metadata in an efficient
38 * way. This means that it does not follow the structure of an on-disk 38 * way. This means that it does not follow the structure of an on-disk
39 * file system because it simply does not need to. Instead, it uses 39 * file system because it simply does not need to. Instead, it uses
40 * memory-specific data structures and algorithms to automatically 40 * memory-specific data structures and algorithms to automatically
41 * allocate and release resources. 41 * allocate and release resources.
42 */ 42 */
43 43
44#include <sys/cdefs.h> 44#include <sys/cdefs.h>
45__KERNEL_RCSID(0, "$NetBSD: tmpfs_vfsops.c,v 1.68 2016/08/26 21:44:24 dholland Exp $"); 45__KERNEL_RCSID(0, "$NetBSD: tmpfs_vfsops.c,v 1.69 2017/01/27 10:47:54 hannken Exp $");
46 46
47#include <sys/param.h> 47#include <sys/param.h>
48#include <sys/atomic.h> 48#include <sys/atomic.h>
49#include <sys/types.h> 49#include <sys/types.h>
50#include <sys/kmem.h> 50#include <sys/kmem.h>
51#include <sys/mount.h> 51#include <sys/mount.h>
52#include <sys/stat.h> 52#include <sys/stat.h>
53#include <sys/systm.h> 53#include <sys/systm.h>
54#include <sys/vnode.h> 54#include <sys/vnode.h>
55#include <sys/kauth.h> 55#include <sys/kauth.h>
56#include <sys/module.h> 56#include <sys/module.h>
57 57
58#include <miscfs/genfs/genfs.h> 58#include <miscfs/genfs/genfs.h>
@@ -82,27 +82,27 @@ tmpfs_done(void) @@ -82,27 +82,27 @@ tmpfs_done(void)
82 pool_destroy(&tmpfs_node_pool); 82 pool_destroy(&tmpfs_node_pool);
83} 83}
84 84
85int 85int
86tmpfs_mount(struct mount *mp, const char *path, void *data, size_t *data_len) 86tmpfs_mount(struct mount *mp, const char *path, void *data, size_t *data_len)
87{ 87{
88 struct tmpfs_args *args = data; 88 struct tmpfs_args *args = data;
89 tmpfs_mount_t *tmp; 89 tmpfs_mount_t *tmp;
90 tmpfs_node_t *root; 90 tmpfs_node_t *root;
91 struct vattr va; 91 struct vattr va;
92 struct vnode *vp; 92 struct vnode *vp;
93 uint64_t memlimit; 93 uint64_t memlimit;
94 ino_t nodes; 94 ino_t nodes;
95 int error; 95 int error, flags;
96 bool set_memlimit; 96 bool set_memlimit;
97 bool set_nodes; 97 bool set_nodes;
98 98
99 if (args == NULL) 99 if (args == NULL)
100 return EINVAL; 100 return EINVAL;
101 101
102 /* Validate the version. */ 102 /* Validate the version. */
103 if (*data_len < sizeof(*args) || 103 if (*data_len < sizeof(*args) ||
104 args->ta_version != TMPFS_ARGS_VERSION) 104 args->ta_version != TMPFS_ARGS_VERSION)
105 return EINVAL; 105 return EINVAL;
106 106
107 /* Handle retrieval of mount point arguments. */ 107 /* Handle retrieval of mount point arguments. */
108 if (mp->mnt_flag & MNT_GETARGS) { 108 if (mp->mnt_flag & MNT_GETARGS) {
@@ -150,44 +150,60 @@ tmpfs_mount(struct mount *mp, const char @@ -150,44 +150,60 @@ tmpfs_mount(struct mount *mp, const char
150 nodes = 3 + (memlimit / 1024); 150 nodes = 3 + (memlimit / 1024);
151 set_nodes = false; 151 set_nodes = false;
152 } else { 152 } else {
153 nodes = args->ta_nodes_max; 153 nodes = args->ta_nodes_max;
154 set_nodes = true; 154 set_nodes = true;
155 } 155 }
156 nodes = MIN(nodes, INT_MAX); 156 nodes = MIN(nodes, INT_MAX);
157 KASSERT(nodes >= 3); 157 KASSERT(nodes >= 3);
158 158
159 if (mp->mnt_flag & MNT_UPDATE) { 159 if (mp->mnt_flag & MNT_UPDATE) {
160 tmp = VFS_TO_TMPFS(mp); 160 tmp = VFS_TO_TMPFS(mp);
161 if (set_nodes && nodes < tmp->tm_nodes_cnt) 161 if (set_nodes && nodes < tmp->tm_nodes_cnt)
162 return EBUSY; 162 return EBUSY;
 163 if (!tmp->tm_rdonly && (mp->mnt_flag & MNT_RDONLY)) {
 164 /* Changing from read/write to read-only. */
 165 flags = WRITECLOSE;
 166 if ((mp->mnt_flag & MNT_FORCE))
 167 flags |= FORCECLOSE;
 168 error = vflush(mp, NULL, flags);
 169 if (error)
 170 return error;
 171 tmp->tm_rdonly = true;
 172 }
 173 if (tmp->tm_rdonly && (mp->mnt_flag & IMNT_WANTRDWR)) {
 174 /* Changing from read-only to read/write. */
 175 tmp->tm_rdonly = false;
 176 }
163 if (set_memlimit) { 177 if (set_memlimit) {
164 if ((error = tmpfs_mntmem_set(tmp, memlimit)) != 0) 178 if ((error = tmpfs_mntmem_set(tmp, memlimit)) != 0)
165 return error; 179 return error;
166 } 180 }
167 if (set_nodes) 181 if (set_nodes)
168 tmp->tm_nodes_max = nodes; 182 tmp->tm_nodes_max = nodes;
169 root = tmp->tm_root; 183 root = tmp->tm_root;
170 root->tn_uid = args->ta_root_uid; 184 root->tn_uid = args->ta_root_uid;
171 root->tn_gid = args->ta_root_gid; 185 root->tn_gid = args->ta_root_gid;
172 root->tn_mode = args->ta_root_mode; 186 root->tn_mode = args->ta_root_mode;
173 return 0; 187 return 0;
174 } 188 }
175 189
176 /* Allocate the tmpfs mount structure and fill it. */ 190 /* Allocate the tmpfs mount structure and fill it. */
177 tmp = kmem_zalloc(sizeof(tmpfs_mount_t), KM_SLEEP); 191 tmp = kmem_zalloc(sizeof(tmpfs_mount_t), KM_SLEEP);
178 if (tmp == NULL) 192 if (tmp == NULL)
179 return ENOMEM; 193 return ENOMEM;
180 194
 195 if ((mp->mnt_flag & MNT_RDONLY))
 196 tmp->tm_rdonly = true;
181 tmp->tm_nodes_max = nodes; 197 tmp->tm_nodes_max = nodes;
182 tmp->tm_nodes_cnt = 0; 198 tmp->tm_nodes_cnt = 0;
183 LIST_INIT(&tmp->tm_nodes); 199 LIST_INIT(&tmp->tm_nodes);
184 200
185 mutex_init(&tmp->tm_lock, MUTEX_DEFAULT, IPL_NONE); 201 mutex_init(&tmp->tm_lock, MUTEX_DEFAULT, IPL_NONE);
186 tmpfs_mntmem_init(tmp, memlimit); 202 tmpfs_mntmem_init(tmp, memlimit);
187 mp->mnt_data = tmp; 203 mp->mnt_data = tmp;
188 204
189 /* Allocate the root node. */ 205 /* Allocate the root node. */
190 vattr_null(&va); 206 vattr_null(&va);
191 va.va_type = VDIR; 207 va.va_type = VDIR;
192 va.va_mode = args->ta_root_mode & ALLPERMS; 208 va.va_mode = args->ta_root_mode & ALLPERMS;
193 va.va_uid = args->ta_root_uid; 209 va.va_uid = args->ta_root_uid;