Blame view
fs/fuse/inode.c
35.8 KB
d8a5ba454 [PATCH] FUSE - core |
1 2 |
/* FUSE: Filesystem in Userspace |
1729a16c2 fuse: style fixes |
3 |
Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> |
d8a5ba454 [PATCH] FUSE - core |
4 5 6 7 8 9 10 11 12 13 |
This program can be distributed under the terms of the GNU GPL. See the file COPYING. */ #include "fuse_i.h" #include <linux/pagemap.h> #include <linux/slab.h> #include <linux/file.h> |
d8a5ba454 [PATCH] FUSE - core |
14 15 16 |
#include <linux/seq_file.h> #include <linux/init.h> #include <linux/module.h> |
487ea5af6 fuse: limit user-... |
17 |
#include <linux/moduleparam.h> |
c30da2e98 fuse: convert to ... |
18 19 |
#include <linux/fs_context.h> #include <linux/fs_parser.h> |
d8a5ba454 [PATCH] FUSE - core |
20 |
#include <linux/statfs.h> |
9c8ef5614 [PATCH] fuse: scr... |
21 |
#include <linux/random.h> |
e8edc6e03 Detach sched.h fr... |
22 |
#include <linux/sched.h> |
dbd561d23 fuse: add export ... |
23 |
#include <linux/exportfs.h> |
60bcc88ad fuse: Add posix A... |
24 |
#include <linux/posix_acl.h> |
0b6e9ea04 fuse: Add support... |
25 |
#include <linux/pid_namespace.h> |
d8a5ba454 [PATCH] FUSE - core |
26 27 28 29 |
MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>"); MODULE_DESCRIPTION("Filesystem in Userspace"); MODULE_LICENSE("GPL"); |
e18b890bb [PATCH] slab: rem... |
30 |
static struct kmem_cache *fuse_inode_cachep; |
bafa96541 [PATCH] fuse: add... |
31 32 |
struct list_head fuse_conn_list; DEFINE_MUTEX(fuse_mutex); |
d8a5ba454 [PATCH] FUSE - core |
33 |
|
e4dca7b7a treewide: Fix fun... |
34 |
static int set_global_limit(const char *val, const struct kernel_param *kp); |
487ea5af6 fuse: limit user-... |
35 |
|
79a9d9943 fuse: add fusectl... |
36 |
unsigned max_user_bgreq; |
487ea5af6 fuse: limit user-... |
37 38 39 40 41 42 |
module_param_call(max_user_bgreq, set_global_limit, param_get_uint, &max_user_bgreq, 0644); __MODULE_PARM_TYPE(max_user_bgreq, "uint"); MODULE_PARM_DESC(max_user_bgreq, "Global limit for the maximum number of backgrounded requests an " "unprivileged user can set"); |
79a9d9943 fuse: add fusectl... |
43 |
unsigned max_user_congthresh; |
487ea5af6 fuse: limit user-... |
44 45 46 47 48 49 |
module_param_call(max_user_congthresh, set_global_limit, param_get_uint, &max_user_congthresh, 0644); __MODULE_PARM_TYPE(max_user_congthresh, "uint"); MODULE_PARM_DESC(max_user_congthresh, "Global limit for the maximum congestion threshold an " "unprivileged user can set"); |
d8a5ba454 [PATCH] FUSE - core |
50 |
#define FUSE_SUPER_MAGIC 0x65735546 |
d1875dbaa mount options: fi... |
51 |
#define FUSE_DEFAULT_BLKSIZE 512 |
7a6d3c8b3 fuse: make the nu... |
52 53 54 55 56 |
/** Maximum number of outstanding background requests */ #define FUSE_DEFAULT_MAX_BACKGROUND 12 /** Congestion starts at 75% of maximum */ #define FUSE_DEFAULT_CONGESTION_THRESHOLD (FUSE_DEFAULT_MAX_BACKGROUND * 3 / 4) |
c30da2e98 fuse: convert to ... |
57 58 59 |
#ifdef CONFIG_BLOCK static struct file_system_type fuseblk_fs_type; #endif |
a2daff680 fuse: fix non-ANS... |
60 |
struct fuse_forget_link *fuse_alloc_forget(void) |
07e77dca8 fuse: separate qu... |
61 |
{ |
dc69e98c2 fuse: kmemcg acco... |
62 |
return kzalloc(sizeof(struct fuse_forget_link), GFP_KERNEL_ACCOUNT); |
07e77dca8 fuse: separate qu... |
63 |
} |
d8a5ba454 [PATCH] FUSE - core |
64 65 |
static struct inode *fuse_alloc_inode(struct super_block *sb) { |
d8a5ba454 [PATCH] FUSE - core |
66 |
struct fuse_inode *fi; |
9031a69cf fuse: clean up fu... |
67 68 |
fi = kmem_cache_alloc(fuse_inode_cachep, GFP_KERNEL); if (!fi) |
d8a5ba454 [PATCH] FUSE - core |
69 |
return NULL; |
0a0898cf4 [PATCH] fuse: use... |
70 |
fi->i_time = 0; |
2f1e81965 fuse: allow fine ... |
71 |
fi->inval_mask = 0; |
d8a5ba454 [PATCH] FUSE - core |
72 |
fi->nodeid = 0; |
9e6268db4 [PATCH] FUSE - re... |
73 |
fi->nlookup = 0; |
fbee36b92 fuse: fix uniniti... |
74 |
fi->attr_version = 0; |
45c72cd73 fuse: fix stat ca... |
75 |
fi->orig_ino = 0; |
4582a4ab2 FUSE: Adapt readd... |
76 |
fi->state = 0; |
5c672ab3f fuse: serialize d... |
77 |
mutex_init(&fi->mutex); |
f15ecfef0 fuse: Introduce f... |
78 |
spin_lock_init(&fi->lock); |
07e77dca8 fuse: separate qu... |
79 80 |
fi->forget = fuse_alloc_forget(); if (!fi->forget) { |
9031a69cf fuse: clean up fu... |
81 |
kmem_cache_free(fuse_inode_cachep, fi); |
e5e5558e9 [PATCH] FUSE - re... |
82 83 |
return NULL; } |
d8a5ba454 [PATCH] FUSE - core |
84 |
|
9031a69cf fuse: clean up fu... |
85 |
return &fi->inode; |
d8a5ba454 [PATCH] FUSE - core |
86 |
} |
9baf28bbf fuse: switch to -... |
87 |
static void fuse_free_inode(struct inode *inode) |
d8a5ba454 [PATCH] FUSE - core |
88 |
{ |
e5e5558e9 [PATCH] FUSE - re... |
89 |
struct fuse_inode *fi = get_fuse_inode(inode); |
9baf28bbf fuse: switch to -... |
90 |
|
5c672ab3f fuse: serialize d... |
91 |
mutex_destroy(&fi->mutex); |
07e77dca8 fuse: separate qu... |
92 |
kfree(fi->forget); |
9baf28bbf fuse: switch to -... |
93 |
kmem_cache_free(fuse_inode_cachep, fi); |
d8a5ba454 [PATCH] FUSE - core |
94 |
} |
b57922d97 convert remaining... |
95 |
static void fuse_evict_inode(struct inode *inode) |
d8a5ba454 [PATCH] FUSE - core |
96 |
{ |
9baf28bbf fuse: switch to -... |
97 |
struct fuse_inode *fi = get_fuse_inode(inode); |
91b0abe36 mm + fs: store sh... |
98 |
truncate_inode_pages_final(&inode->i_data); |
dbd5768f8 vfs: Rename end_w... |
99 |
clear_inode(inode); |
1751e8a6c Rename superblock... |
100 |
if (inode->i_sb->s_flags & SB_ACTIVE) { |
1e9a4ed93 [PATCH] FUSE - mo... |
101 |
struct fuse_conn *fc = get_fuse_conn(inode); |
07e77dca8 fuse: separate qu... |
102 103 |
fuse_queue_forget(fc, fi->forget, fi->nodeid, fi->nlookup); fi->forget = NULL; |
e5e5558e9 [PATCH] FUSE - re... |
104 |
} |
9baf28bbf fuse: switch to -... |
105 106 107 108 |
if (S_ISREG(inode->i_mode) && !is_bad_inode(inode)) { WARN_ON(!list_empty(&fi->write_files)); WARN_ON(!list_empty(&fi->queued_writes)); } |
d8a5ba454 [PATCH] FUSE - core |
109 |
} |
0189a2d36 fuse: use ->recon... |
110 |
static int fuse_reconfigure(struct fs_context *fc) |
714212593 [PATCH] fuse: add... |
111 |
{ |
0189a2d36 fuse: use ->recon... |
112 |
struct super_block *sb = fc->root->d_sb; |
02b9984d6 fs: push sync_fil... |
113 |
sync_filesystem(sb); |
0189a2d36 fuse: use ->recon... |
114 |
if (fc->sb_flags & SB_MANDLOCK) |
714212593 [PATCH] fuse: add... |
115 116 117 118 |
return -EINVAL; return 0; } |
45c72cd73 fuse: fix stat ca... |
119 120 121 122 123 124 125 126 127 128 129 |
/* * ino_t is 32-bits on 32-bit arch. We have to squash the 64-bit value down * so that it will fit. */ static ino_t fuse_squash_ino(u64 ino64) { ino_t ino = (ino_t) ino64; if (sizeof(ino_t) < sizeof(u64)) ino ^= ino64 >> (sizeof(u64) - sizeof(ino_t)) * 8; return ino; } |
3be5a52b3 fuse: support wri... |
130 131 |
void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, u64 attr_valid) |
d8a5ba454 [PATCH] FUSE - core |
132 |
{ |
9ffbb9162 [PATCH] fuse: fix... |
133 |
struct fuse_conn *fc = get_fuse_conn(inode); |
ebc14c4db fuse: fix permiss... |
134 |
struct fuse_inode *fi = get_fuse_inode(inode); |
d8a5ba454 [PATCH] FUSE - core |
135 |
|
f15ecfef0 fuse: Introduce f... |
136 |
lockdep_assert_held(&fi->lock); |
4510d86fb fuse: Convert fc-... |
137 |
fi->attr_version = atomic64_inc_return(&fc->attr_version); |
1fb69e781 fuse: fix race be... |
138 |
fi->i_time = attr_valid; |
2f1e81965 fuse: allow fine ... |
139 |
WRITE_ONCE(fi->inval_mask, 0); |
1fb69e781 fuse: fix race be... |
140 |
|
45c72cd73 fuse: fix stat ca... |
141 |
inode->i_ino = fuse_squash_ino(attr->ino); |
ebc14c4db fuse: fix permiss... |
142 |
inode->i_mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777); |
bfe868486 filesystems: add ... |
143 |
set_nlink(inode, attr->nlink); |
8cb08329b fuse: Support fus... |
144 145 |
inode->i_uid = make_kuid(fc->user_ns, attr->uid); inode->i_gid = make_kgid(fc->user_ns, attr->gid); |
d8a5ba454 [PATCH] FUSE - core |
146 147 148 |
inode->i_blocks = attr->blocks; inode->i_atime.tv_sec = attr->atime; inode->i_atime.tv_nsec = attr->atimensec; |
b0aa76065 fuse: Trust kerne... |
149 150 151 152 |
/* mtime from server may be stale due to local buffered write */ if (!fc->writeback_cache || !S_ISREG(inode->i_mode)) { inode->i_mtime.tv_sec = attr->mtime; inode->i_mtime.tv_nsec = attr->mtimensec; |
31f3267b4 fuse: trust kerne... |
153 154 |
inode->i_ctime.tv_sec = attr->ctime; inode->i_ctime.tv_nsec = attr->ctimensec; |
b0aa76065 fuse: Trust kerne... |
155 |
} |
e00d2c2d4 fuse: truncate on... |
156 |
|
0e9663ee4 fuse: add blksize... |
157 158 159 160 |
if (attr->blksize != 0) inode->i_blkbits = ilog2(attr->blksize); else inode->i_blkbits = inode->i_sb->s_blocksize_bits; |
ebc14c4db fuse: fix permiss... |
161 162 163 164 165 166 |
/* * Don't set the sticky bit in i_mode, unless we want the VFS * to check permissions. This prevents failures due to the * check in may_delete(). */ fi->orig_i_mode = inode->i_mode; |
29433a299 fuse: get rid of ... |
167 |
if (!fc->default_permissions) |
ebc14c4db fuse: fix permiss... |
168 |
inode->i_mode &= ~S_ISVTX; |
45c72cd73 fuse: fix stat ca... |
169 170 |
fi->orig_ino = attr->ino; |
3be5a52b3 fuse: support wri... |
171 172 173 174 175 176 177 |
} void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, u64 attr_valid, u64 attr_version) { struct fuse_conn *fc = get_fuse_conn(inode); struct fuse_inode *fi = get_fuse_inode(inode); |
8373200b1 fuse: Trust kerne... |
178 |
bool is_wb = fc->writeback_cache; |
3be5a52b3 fuse: support wri... |
179 |
loff_t oldsize; |
a64ba10f6 fuse: convert las... |
180 |
struct timespec64 old_mtime; |
3be5a52b3 fuse: support wri... |
181 |
|
f15ecfef0 fuse: Introduce f... |
182 |
spin_lock(&fi->lock); |
06a7c3c27 fuse: hotfix trun... |
183 184 |
if ((attr_version != 0 && fi->attr_version > attr_version) || test_bit(FUSE_I_SIZE_UNSTABLE, &fi->state)) { |
f15ecfef0 fuse: Introduce f... |
185 |
spin_unlock(&fi->lock); |
3be5a52b3 fuse: support wri... |
186 187 |
return; } |
a64ba10f6 fuse: convert las... |
188 |
old_mtime = inode->i_mtime; |
3be5a52b3 fuse: support wri... |
189 |
fuse_change_attributes_common(inode, attr, attr_valid); |
ebc14c4db fuse: fix permiss... |
190 |
|
e00d2c2d4 fuse: truncate on... |
191 |
oldsize = inode->i_size; |
8373200b1 fuse: Trust kerne... |
192 193 194 195 196 197 198 |
/* * In case of writeback_cache enabled, the cached writes beyond EOF * extend local i_size without keeping userspace server in sync. So, * attr->size coming from server can be stale. We cannot trust it. */ if (!is_wb || !S_ISREG(inode->i_mode)) i_size_write(inode, attr->size); |
f15ecfef0 fuse: Introduce f... |
199 |
spin_unlock(&fi->lock); |
e00d2c2d4 fuse: truncate on... |
200 |
|
8373200b1 fuse: Trust kerne... |
201 |
if (!is_wb && S_ISREG(inode->i_mode)) { |
eed2179ef fuse: invalidate ... |
202 203 204 |
bool inval = false; if (oldsize != attr->size) { |
7caef2676 truncate: drop 'o... |
205 |
truncate_pagecache(inode, attr->size); |
ad2ba64dd fuse: allow files... |
206 207 |
if (!fc->explicit_inval_data) inval = true; |
eed2179ef fuse: invalidate ... |
208 |
} else if (fc->auto_inval_data) { |
a64ba10f6 fuse: convert las... |
209 |
struct timespec64 new_mtime = { |
eed2179ef fuse: invalidate ... |
210 211 212 213 214 215 216 217 |
.tv_sec = attr->mtime, .tv_nsec = attr->mtimensec, }; /* * Auto inval mode also checks and invalidates if mtime * has changed. */ |
a64ba10f6 fuse: convert las... |
218 |
if (!timespec64_equal(&old_mtime, &new_mtime)) |
eed2179ef fuse: invalidate ... |
219 220 221 222 223 |
inval = true; } if (inval) invalidate_inode_pages2(inode->i_mapping); |
e00d2c2d4 fuse: truncate on... |
224 |
} |
d8a5ba454 [PATCH] FUSE - core |
225 226 227 228 229 |
} static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr) { inode->i_mode = attr->mode & S_IFMT; |
9ffbb9162 [PATCH] fuse: fix... |
230 |
inode->i_size = attr->size; |
b0aa76065 fuse: Trust kerne... |
231 232 |
inode->i_mtime.tv_sec = attr->mtime; inode->i_mtime.tv_nsec = attr->mtimensec; |
31f3267b4 fuse: trust kerne... |
233 234 |
inode->i_ctime.tv_sec = attr->ctime; inode->i_ctime.tv_nsec = attr->ctimensec; |
e5e5558e9 [PATCH] FUSE - re... |
235 236 |
if (S_ISREG(inode->i_mode)) { fuse_init_common(inode); |
b6aeadeda [PATCH] FUSE - fi... |
237 |
fuse_init_file_inode(inode); |
e5e5558e9 [PATCH] FUSE - re... |
238 239 240 241 242 243 244 245 246 |
} else if (S_ISDIR(inode->i_mode)) fuse_init_dir(inode); else if (S_ISLNK(inode->i_mode)) fuse_init_symlink(inode); else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { fuse_init_common(inode); init_special_inode(inode, inode->i_mode, new_decode_dev(attr->rdev)); |
39ee059af [PATCH] fuse: che... |
247 248 |
} else BUG(); |
d8a5ba454 [PATCH] FUSE - core |
249 |
} |
3b463ae0c fuse: invalidatio... |
250 |
int fuse_inode_eq(struct inode *inode, void *_nodeidp) |
d8a5ba454 [PATCH] FUSE - core |
251 |
{ |
b48badf01 fuse: fix node ID... |
252 |
u64 nodeid = *(u64 *) _nodeidp; |
d8a5ba454 [PATCH] FUSE - core |
253 254 255 256 257 258 259 260 |
if (get_node_id(inode) == nodeid) return 1; else return 0; } static int fuse_inode_set(struct inode *inode, void *_nodeidp) { |
b48badf01 fuse: fix node ID... |
261 |
u64 nodeid = *(u64 *) _nodeidp; |
d8a5ba454 [PATCH] FUSE - core |
262 263 264 |
get_fuse_inode(inode)->nodeid = nodeid; return 0; } |
b48badf01 fuse: fix node ID... |
265 |
struct inode *fuse_iget(struct super_block *sb, u64 nodeid, |
1fb69e781 fuse: fix race be... |
266 267 |
int generation, struct fuse_attr *attr, u64 attr_valid, u64 attr_version) |
d8a5ba454 [PATCH] FUSE - core |
268 269 |
{ struct inode *inode; |
9e6268db4 [PATCH] FUSE - re... |
270 |
struct fuse_inode *fi; |
d8a5ba454 [PATCH] FUSE - core |
271 |
struct fuse_conn *fc = get_fuse_conn_super(sb); |
d8a5ba454 [PATCH] FUSE - core |
272 273 274 275 276 277 278 |
retry: inode = iget5_locked(sb, nodeid, fuse_inode_eq, fuse_inode_set, &nodeid); if (!inode) return NULL; if ((inode->i_state & I_NEW)) { |
b0aa76065 fuse: Trust kerne... |
279 |
inode->i_flags |= S_NOATIME; |
d31433c8b fuse: do not use ... |
280 |
if (!fc->writeback_cache || !S_ISREG(attr->mode)) |
b0aa76065 fuse: Trust kerne... |
281 |
inode->i_flags |= S_NOCMTIME; |
d8a5ba454 [PATCH] FUSE - core |
282 |
inode->i_generation = generation; |
d8a5ba454 [PATCH] FUSE - core |
283 284 285 |
fuse_init_inode(inode, attr); unlock_new_inode(inode); } else if ((inode->i_mode ^ attr->mode) & S_IFMT) { |
d8a5ba454 [PATCH] FUSE - core |
286 287 288 |
/* Inode has changed type, any I/O on the old should fail */ make_bad_inode(inode); iput(inode); |
d8a5ba454 [PATCH] FUSE - core |
289 290 |
goto retry; } |
9e6268db4 [PATCH] FUSE - re... |
291 |
fi = get_fuse_inode(inode); |
c9d8f5f06 fuse: Protect fi-... |
292 |
spin_lock(&fi->lock); |
1729a16c2 fuse: style fixes |
293 |
fi->nlookup++; |
c9d8f5f06 fuse: Protect fi-... |
294 |
spin_unlock(&fi->lock); |
1fb69e781 fuse: fix race be... |
295 |
fuse_change_attributes(inode, attr, attr_valid, attr_version); |
d8a5ba454 [PATCH] FUSE - core |
296 297 |
return inode; } |
3b463ae0c fuse: invalidatio... |
298 299 300 |
int fuse_reverse_inval_inode(struct super_block *sb, u64 nodeid, loff_t offset, loff_t len) { |
5ddd9ced9 fuse: update attr... |
301 302 |
struct fuse_conn *fc = get_fuse_conn_super(sb); struct fuse_inode *fi; |
3b463ae0c fuse: invalidatio... |
303 304 305 306 307 308 309 |
struct inode *inode; pgoff_t pg_start; pgoff_t pg_end; inode = ilookup5(sb, nodeid, fuse_inode_eq, &nodeid); if (!inode) return -ENOENT; |
5ddd9ced9 fuse: update attr... |
310 311 312 313 |
fi = get_fuse_inode(inode); spin_lock(&fi->lock); fi->attr_version = atomic64_inc_return(&fc->attr_version); spin_unlock(&fi->lock); |
3b463ae0c fuse: invalidatio... |
314 |
fuse_invalidate_attr(inode); |
60bcc88ad fuse: Add posix A... |
315 |
forget_all_cached_acls(inode); |
3b463ae0c fuse: invalidatio... |
316 |
if (offset >= 0) { |
09cbfeaf1 mm, fs: get rid o... |
317 |
pg_start = offset >> PAGE_SHIFT; |
3b463ae0c fuse: invalidatio... |
318 319 320 |
if (len <= 0) pg_end = -1; else |
09cbfeaf1 mm, fs: get rid o... |
321 |
pg_end = (offset + len - 1) >> PAGE_SHIFT; |
3b463ae0c fuse: invalidatio... |
322 323 324 325 326 327 |
invalidate_inode_pages2_range(inode->i_mapping, pg_start, pg_end); } iput(inode); return 0; } |
63576c13b fuse: fix initial... |
328 |
bool fuse_lock_inode(struct inode *inode) |
5c672ab3f fuse: serialize d... |
329 |
{ |
63576c13b fuse: fix initial... |
330 331 332 |
bool locked = false; if (!get_fuse_conn(inode)->parallel_dirops) { |
5c672ab3f fuse: serialize d... |
333 |
mutex_lock(&get_fuse_inode(inode)->mutex); |
63576c13b fuse: fix initial... |
334 335 336 337 |
locked = true; } return locked; |
5c672ab3f fuse: serialize d... |
338 |
} |
63576c13b fuse: fix initial... |
339 |
void fuse_unlock_inode(struct inode *inode, bool locked) |
5c672ab3f fuse: serialize d... |
340 |
{ |
63576c13b fuse: fix initial... |
341 |
if (locked) |
5c672ab3f fuse: serialize d... |
342 343 |
mutex_unlock(&get_fuse_inode(inode)->mutex); } |
42faad996 [PATCH] restore s... |
344 |
static void fuse_umount_begin(struct super_block *sb) |
69a53bf26 [PATCH] fuse: add... |
345 |
{ |
15c8e72e8 fuse: allow skipp... |
346 347 348 349 |
struct fuse_conn *fc = get_fuse_conn_super(sb); if (!fc->no_force_umount) fuse_abort_conn(fc); |
69a53bf26 [PATCH] fuse: add... |
350 |
} |
0ec7ca41f [PATCH] fuse: add... |
351 352 |
static void fuse_send_destroy(struct fuse_conn *fc) { |
1ccd1ea24 fuse: convert des... |
353 354 355 356 357 358 359 |
if (fc->conn_init) { FUSE_ARGS(args); args.opcode = FUSE_DESTROY; args.force = true; args.nocreds = true; fuse_simple_request(fc, &args); |
0ec7ca41f [PATCH] fuse: add... |
360 361 |
} } |
a325f9b92 fuse: update fuse... |
362 363 364 |
static void fuse_put_super(struct super_block *sb) { struct fuse_conn *fc = get_fuse_conn_super(sb); |
bbd997979 cuse: fix fuse_co... |
365 366 367 368 |
mutex_lock(&fuse_mutex); list_del(&fc->entry); fuse_ctl_remove_conn(fc); mutex_unlock(&fuse_mutex); |
bbd997979 cuse: fix fuse_co... |
369 |
|
bafa96541 [PATCH] fuse: add... |
370 |
fuse_conn_put(fc); |
d8a5ba454 [PATCH] FUSE - core |
371 |
} |
e5e5558e9 [PATCH] FUSE - re... |
372 373 374 375 |
static void convert_fuse_statfs(struct kstatfs *stbuf, struct fuse_kstatfs *attr) { stbuf->f_type = FUSE_SUPER_MAGIC; stbuf->f_bsize = attr->bsize; |
de5f12025 [PATCH] fuse: add... |
376 |
stbuf->f_frsize = attr->frsize; |
e5e5558e9 [PATCH] FUSE - re... |
377 378 379 380 381 382 383 384 |
stbuf->f_blocks = attr->blocks; stbuf->f_bfree = attr->bfree; stbuf->f_bavail = attr->bavail; stbuf->f_files = attr->files; stbuf->f_ffree = attr->ffree; stbuf->f_namelen = attr->namelen; /* fsid is left zero */ } |
726c33422 [PATCH] VFS: Perm... |
385 |
static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf) |
e5e5558e9 [PATCH] FUSE - re... |
386 |
{ |
726c33422 [PATCH] VFS: Perm... |
387 |
struct super_block *sb = dentry->d_sb; |
e5e5558e9 [PATCH] FUSE - re... |
388 |
struct fuse_conn *fc = get_fuse_conn_super(sb); |
7078187a7 fuse: introduce f... |
389 |
FUSE_ARGS(args); |
e5e5558e9 [PATCH] FUSE - re... |
390 391 |
struct fuse_statfs_out outarg; int err; |
c2132c1bc Do not use RCU fo... |
392 |
if (!fuse_allow_current_process(fc)) { |
e57ac6837 fuse: fix allowin... |
393 394 395 |
buf->f_type = FUSE_SUPER_MAGIC; return 0; } |
de5f12025 [PATCH] fuse: add... |
396 |
memset(&outarg, 0, sizeof(outarg)); |
d5b485435 fuse: flatten 'st... |
397 398 399 400 401 402 |
args.in_numargs = 0; args.opcode = FUSE_STATFS; args.nodeid = get_node_id(d_inode(dentry)); args.out_numargs = 1; args.out_args[0].size = sizeof(outarg); args.out_args[0].value = &outarg; |
7078187a7 fuse: introduce f... |
403 |
err = fuse_simple_request(fc, &args); |
e5e5558e9 [PATCH] FUSE - re... |
404 405 |
if (!err) convert_fuse_statfs(buf, &outarg.st); |
e5e5558e9 [PATCH] FUSE - re... |
406 407 |
return err; } |
d8a5ba454 [PATCH] FUSE - core |
408 |
enum { |
c30da2e98 fuse: convert to ... |
409 410 |
OPT_SOURCE, OPT_SUBTYPE, |
d8a5ba454 [PATCH] FUSE - core |
411 412 413 |
OPT_FD, OPT_ROOTMODE, OPT_USER_ID, |
87729a551 [PATCH] FUSE: tig... |
414 |
OPT_GROUP_ID, |
d8a5ba454 [PATCH] FUSE - core |
415 416 |
OPT_DEFAULT_PERMISSIONS, OPT_ALLOW_OTHER, |
db50b96c0 [PATCH] FUSE - re... |
417 |
OPT_MAX_READ, |
d80916140 [PATCH] fuse: add... |
418 |
OPT_BLKSIZE, |
d8a5ba454 [PATCH] FUSE - core |
419 420 |
OPT_ERR }; |
d7167b149 fs_parse: fold fs... |
421 |
static const struct fs_parameter_spec fuse_fs_parameters[] = { |
c30da2e98 fuse: convert to ... |
422 423 424 425 426 427 428 429 430 |
fsparam_string ("source", OPT_SOURCE), fsparam_u32 ("fd", OPT_FD), fsparam_u32oct ("rootmode", OPT_ROOTMODE), fsparam_u32 ("user_id", OPT_USER_ID), fsparam_u32 ("group_id", OPT_GROUP_ID), fsparam_flag ("default_permissions", OPT_DEFAULT_PERMISSIONS), fsparam_flag ("allow_other", OPT_ALLOW_OTHER), fsparam_u32 ("max_read", OPT_MAX_READ), fsparam_u32 ("blksize", OPT_BLKSIZE), |
c7eb68696 vfs: subtype hand... |
431 |
fsparam_string ("subtype", OPT_SUBTYPE), |
c30da2e98 fuse: convert to ... |
432 433 |
{} }; |
c30da2e98 fuse: convert to ... |
434 |
static int fuse_parse_param(struct fs_context *fc, struct fs_parameter *param) |
233a01fa9 fuse: handle larg... |
435 |
{ |
c30da2e98 fuse: convert to ... |
436 437 438 |
struct fs_parse_result result; struct fuse_fs_context *ctx = fc->fs_private; int opt; |
b330966f7 fuse: reject opti... |
439 440 441 442 443 444 445 446 447 448 |
if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) { /* * Ignore options coming from mount(MS_REMOUNT) for backward * compatibility. */ if (fc->oldapi) return 0; return invalfc(fc, "No changes allowed in reconfigure"); } |
e8b20a474 fuse: ignore 'dat... |
449 |
|
d7167b149 fs_parse: fold fs... |
450 |
opt = fs_parse(fc, fuse_fs_parameters, param, &result); |
c30da2e98 fuse: convert to ... |
451 452 453 454 455 456 |
if (opt < 0) return opt; switch (opt) { case OPT_SOURCE: if (fc->source) |
2e28c49ea fuse: switch to u... |
457 |
return invalfc(fc, "Multiple sources specified"); |
c30da2e98 fuse: convert to ... |
458 459 460 461 462 463 |
fc->source = param->string; param->string = NULL; break; case OPT_SUBTYPE: if (ctx->subtype) |
2e28c49ea fuse: switch to u... |
464 |
return invalfc(fc, "Multiple subtypes specified"); |
c30da2e98 fuse: convert to ... |
465 466 467 468 469 470 |
ctx->subtype = param->string; param->string = NULL; return 0; case OPT_FD: ctx->fd = result.uint_32; |
cabdb4fa2 fuse: use true,fa... |
471 |
ctx->fd_present = true; |
c30da2e98 fuse: convert to ... |
472 473 474 475 |
break; case OPT_ROOTMODE: if (!fuse_valid_type(result.uint_32)) |
2e28c49ea fuse: switch to u... |
476 |
return invalfc(fc, "Invalid rootmode"); |
c30da2e98 fuse: convert to ... |
477 |
ctx->rootmode = result.uint_32; |
cabdb4fa2 fuse: use true,fa... |
478 |
ctx->rootmode_present = true; |
c30da2e98 fuse: convert to ... |
479 480 481 482 483 |
break; case OPT_USER_ID: ctx->user_id = make_kuid(fc->user_ns, result.uint_32); if (!uid_valid(ctx->user_id)) |
2e28c49ea fuse: switch to u... |
484 |
return invalfc(fc, "Invalid user_id"); |
cabdb4fa2 fuse: use true,fa... |
485 |
ctx->user_id_present = true; |
c30da2e98 fuse: convert to ... |
486 487 488 489 490 |
break; case OPT_GROUP_ID: ctx->group_id = make_kgid(fc->user_ns, result.uint_32); if (!gid_valid(ctx->group_id)) |
2e28c49ea fuse: switch to u... |
491 |
return invalfc(fc, "Invalid group_id"); |
cabdb4fa2 fuse: use true,fa... |
492 |
ctx->group_id_present = true; |
c30da2e98 fuse: convert to ... |
493 494 495 |
break; case OPT_DEFAULT_PERMISSIONS: |
cabdb4fa2 fuse: use true,fa... |
496 |
ctx->default_permissions = true; |
c30da2e98 fuse: convert to ... |
497 498 499 |
break; case OPT_ALLOW_OTHER: |
cabdb4fa2 fuse: use true,fa... |
500 |
ctx->allow_other = true; |
c30da2e98 fuse: convert to ... |
501 502 503 504 505 506 507 508 |
break; case OPT_MAX_READ: ctx->max_read = result.uint_32; break; case OPT_BLKSIZE: if (!ctx->is_bdev) |
2e28c49ea fuse: switch to u... |
509 |
return invalfc(fc, "blksize only supported for fuseblk"); |
c30da2e98 fuse: convert to ... |
510 511 512 513 514 |
ctx->blksize = result.uint_32; break; default: return -EINVAL; |
233a01fa9 fuse: handle larg... |
515 |
} |
c30da2e98 fuse: convert to ... |
516 517 |
return 0; |
233a01fa9 fuse: handle larg... |
518 |
} |
c30da2e98 fuse: convert to ... |
519 |
static void fuse_free_fc(struct fs_context *fc) |
d8a5ba454 [PATCH] FUSE - core |
520 |
{ |
c30da2e98 fuse: convert to ... |
521 |
struct fuse_fs_context *ctx = fc->fs_private; |
5a5336827 [PATCH] fuse: str... |
522 |
|
c30da2e98 fuse: convert to ... |
523 524 525 526 |
if (ctx) { kfree(ctx->subtype); kfree(ctx); } |
d8a5ba454 [PATCH] FUSE - core |
527 |
} |
34c80b1d9 vfs: switch ->sho... |
528 |
static int fuse_show_options(struct seq_file *m, struct dentry *root) |
d8a5ba454 [PATCH] FUSE - core |
529 |
{ |
34c80b1d9 vfs: switch ->sho... |
530 531 |
struct super_block *sb = root->d_sb; struct fuse_conn *fc = get_fuse_conn_super(sb); |
d8a5ba454 [PATCH] FUSE - core |
532 |
|
3f22c7467 virtio-fs: don't ... |
533 534 |
if (fc->no_mount_options) return 0; |
8cb08329b fuse: Support fus... |
535 536 |
seq_printf(m, ",user_id=%u", from_kuid_munged(fc->user_ns, fc->user_id)); seq_printf(m, ",group_id=%u", from_kgid_munged(fc->user_ns, fc->group_id)); |
29433a299 fuse: get rid of ... |
537 |
if (fc->default_permissions) |
1e9a4ed93 [PATCH] FUSE - mo... |
538 |
seq_puts(m, ",default_permissions"); |
29433a299 fuse: get rid of ... |
539 |
if (fc->allow_other) |
1e9a4ed93 [PATCH] FUSE - mo... |
540 |
seq_puts(m, ",allow_other"); |
db50b96c0 [PATCH] FUSE - re... |
541 542 |
if (fc->max_read != ~0) seq_printf(m, ",max_read=%u", fc->max_read); |
34c80b1d9 vfs: switch ->sho... |
543 544 |
if (sb->s_bdev && sb->s_blocksize != FUSE_DEFAULT_BLKSIZE) seq_printf(m, ",blksize=%lu", sb->s_blocksize); |
d8a5ba454 [PATCH] FUSE - core |
545 546 |
return 0; } |
ae3aad77f fuse: add fuse_iq... |
547 548 549 |
static void fuse_iqueue_init(struct fuse_iqueue *fiq, const struct fuse_iqueue_ops *ops, void *priv) |
f88996a93 fuse: separate ou... |
550 551 |
{ memset(fiq, 0, sizeof(struct fuse_iqueue)); |
76e43c8cc fuse: fix deadloc... |
552 |
spin_lock_init(&fiq->lock); |
f88996a93 fuse: separate ou... |
553 554 555 556 |
init_waitqueue_head(&fiq->waitq); INIT_LIST_HEAD(&fiq->pending); INIT_LIST_HEAD(&fiq->interrupts); fiq->forget_list_tail = &fiq->forget_list_head; |
e16714d87 fuse: duplicate -... |
557 |
fiq->connected = 1; |
ae3aad77f fuse: add fuse_iq... |
558 559 |
fiq->ops = ops; fiq->priv = priv; |
f88996a93 fuse: separate ou... |
560 |
} |
3a2b5b9cd fuse: separate ou... |
561 562 |
static void fuse_pqueue_init(struct fuse_pqueue *fpq) { |
be2ff42c5 fuse: Use hash ta... |
563 |
unsigned int i; |
45a91cb1a fuse: pqueue locking |
564 |
spin_lock_init(&fpq->lock); |
be2ff42c5 fuse: Use hash ta... |
565 566 |
for (i = 0; i < FUSE_PQ_HASH_SIZE; i++) INIT_LIST_HEAD(&fpq->processing[i]); |
3a2b5b9cd fuse: separate ou... |
567 |
INIT_LIST_HEAD(&fpq->io); |
e96edd94d fuse: duplicate -... |
568 |
fpq->connected = 1; |
3a2b5b9cd fuse: separate ou... |
569 |
} |
ae3aad77f fuse: add fuse_iq... |
570 571 |
void fuse_conn_init(struct fuse_conn *fc, struct user_namespace *user_ns, const struct fuse_iqueue_ops *fiq_ops, void *fiq_priv) |
d8a5ba454 [PATCH] FUSE - core |
572 |
{ |
0d179aa59 fuse: separate ou... |
573 574 |
memset(fc, 0, sizeof(*fc)); spin_lock_init(&fc->lock); |
ae2dffa39 fuse: introduce f... |
575 |
spin_lock_init(&fc->bg_lock); |
3b463ae0c fuse: invalidatio... |
576 |
init_rwsem(&fc->killsb); |
095fc40ac fuse: convert fus... |
577 |
refcount_set(&fc->count, 1); |
c3696046b fuse: separate pq... |
578 |
atomic_set(&fc->dev_count, 1); |
0d179aa59 fuse: separate ou... |
579 |
init_waitqueue_head(&fc->blocked_waitq); |
ae3aad77f fuse: add fuse_iq... |
580 |
fuse_iqueue_init(&fc->iq, fiq_ops, fiq_priv); |
0d179aa59 fuse: separate ou... |
581 582 |
INIT_LIST_HEAD(&fc->bg_queue); INIT_LIST_HEAD(&fc->entry); |
cc080e9e9 fuse: introduce p... |
583 |
INIT_LIST_HEAD(&fc->devices); |
0d179aa59 fuse: separate ou... |
584 |
atomic_set(&fc->num_waiting, 0); |
7a6d3c8b3 fuse: make the nu... |
585 586 |
fc->max_background = FUSE_DEFAULT_MAX_BACKGROUND; fc->congestion_threshold = FUSE_DEFAULT_CONGESTION_THRESHOLD; |
75126f550 fuse: use atomic6... |
587 |
atomic64_set(&fc->khctr, 0); |
0d179aa59 fuse: separate ou... |
588 |
fc->polled_files = RB_ROOT; |
0aada8847 fuse: skip blocki... |
589 |
fc->blocked = 0; |
796523fb2 fuse: add flag fc... |
590 |
fc->initialized = 0; |
e16714d87 fuse: duplicate -... |
591 |
fc->connected = 1; |
4510d86fb fuse: Convert fc-... |
592 |
atomic64_set(&fc->attr_version, 1); |
0d179aa59 fuse: separate ou... |
593 |
get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key)); |
0b6e9ea04 fuse: Add support... |
594 |
fc->pid_ns = get_pid_ns(task_active_pid_ns(current)); |
8cb08329b fuse: Support fus... |
595 |
fc->user_ns = get_user_ns(user_ns); |
8a3177db5 cuse: fix ioctl |
596 |
fc->max_pages = FUSE_DEFAULT_MAX_PAGES_PER_REQ; |
d8a5ba454 [PATCH] FUSE - core |
597 |
} |
0d179aa59 fuse: separate ou... |
598 |
EXPORT_SYMBOL_GPL(fuse_conn_init); |
d8a5ba454 [PATCH] FUSE - core |
599 |
|
bafa96541 [PATCH] fuse: add... |
600 601 |
void fuse_conn_put(struct fuse_conn *fc) { |
095fc40ac fuse: convert fus... |
602 |
if (refcount_dec_and_test(&fc->count)) { |
a62a8ef9d virtio-fs: add vi... |
603 604 605 606 |
struct fuse_iqueue *fiq = &fc->iq; if (fiq->ops->release) fiq->ops->release(fiq); |
0b6e9ea04 fuse: Add support... |
607 |
put_pid_ns(fc->pid_ns); |
8cb08329b fuse: Support fus... |
608 |
put_user_ns(fc->user_ns); |
43901aabd fuse: add fuse_co... |
609 |
fc->release(fc); |
d2a85164a [PATCH] fuse: fix... |
610 |
} |
bafa96541 [PATCH] fuse: add... |
611 |
} |
08cbf542b fuse: export symb... |
612 |
EXPORT_SYMBOL_GPL(fuse_conn_put); |
bafa96541 [PATCH] fuse: add... |
613 614 615 |
struct fuse_conn *fuse_conn_get(struct fuse_conn *fc) { |
095fc40ac fuse: convert fus... |
616 |
refcount_inc(&fc->count); |
bafa96541 [PATCH] fuse: add... |
617 618 |
return fc; } |
08cbf542b fuse: export symb... |
619 |
EXPORT_SYMBOL_GPL(fuse_conn_get); |
bafa96541 [PATCH] fuse: add... |
620 |
|
b93f858ab fuse: add fuse_ p... |
621 |
static struct inode *fuse_get_root_inode(struct super_block *sb, unsigned mode) |
d8a5ba454 [PATCH] FUSE - core |
622 623 624 625 626 627 |
{ struct fuse_attr attr; memset(&attr, 0, sizeof(attr)); attr.mode = mode; attr.ino = FUSE_ROOT_ID; |
074406fa6 fuse: set i_nlink... |
628 |
attr.nlink = 1; |
1fb69e781 fuse: fix race be... |
629 |
return fuse_iget(sb, 1, 0, &attr, 0, 0); |
d8a5ba454 [PATCH] FUSE - core |
630 |
} |
1729a16c2 fuse: style fixes |
631 |
struct fuse_inode_handle { |
dbd561d23 fuse: add export ... |
632 633 634 635 636 637 638 |
u64 nodeid; u32 generation; }; static struct dentry *fuse_get_dentry(struct super_block *sb, struct fuse_inode_handle *handle) { |
33670fa29 fuse: nfs export ... |
639 |
struct fuse_conn *fc = get_fuse_conn_super(sb); |
dbd561d23 fuse: add export ... |
640 641 642 643 644 645 646 647 |
struct inode *inode; struct dentry *entry; int err = -ESTALE; if (handle->nodeid == 0) goto out_err; inode = ilookup5(sb, handle->nodeid, fuse_inode_eq, &handle->nodeid); |
33670fa29 fuse: nfs export ... |
648 649 |
if (!inode) { struct fuse_entry_out outarg; |
13983d062 qstr: constify in... |
650 |
const struct qstr name = QSTR_INIT(".", 1); |
33670fa29 fuse: nfs export ... |
651 652 653 |
if (!fc->export_support) goto out_err; |
33670fa29 fuse: nfs export ... |
654 655 656 657 658 659 660 661 662 663 664 665 |
err = fuse_lookup_name(sb, handle->nodeid, &name, &outarg, &inode); if (err && err != -ENOENT) goto out_err; if (err || !inode) { err = -ESTALE; goto out_err; } err = -EIO; if (get_node_id(inode) != handle->nodeid) goto out_iput; } |
dbd561d23 fuse: add export ... |
666 667 668 |
err = -ESTALE; if (inode->i_generation != handle->generation) goto out_iput; |
440037287 [PATCH] switch al... |
669 |
entry = d_obtain_alias(inode); |
c35eebe99 switch fuse |
670 |
if (!IS_ERR(entry) && get_node_id(inode) != FUSE_ROOT_ID) |
dbd561d23 fuse: add export ... |
671 |
fuse_invalidate_entry_cache(entry); |
dbd561d23 fuse: add export ... |
672 673 674 675 676 677 678 679 |
return entry; out_iput: iput(inode); out_err: return ERR_PTR(err); } |
b0b0382bb ->encode_fh() API... |
680 681 |
static int fuse_encode_fh(struct inode *inode, u32 *fh, int *max_len, struct inode *parent) |
dbd561d23 fuse: add export ... |
682 |
{ |
b0b0382bb ->encode_fh() API... |
683 |
int len = parent ? 6 : 3; |
dbd561d23 fuse: add export ... |
684 685 |
u64 nodeid; u32 generation; |
5fe0c2378 exportfs: Return ... |
686 687 |
if (*max_len < len) { *max_len = len; |
94e07a759 fs: encode_fh: re... |
688 |
return FILEID_INVALID; |
5fe0c2378 exportfs: Return ... |
689 |
} |
dbd561d23 fuse: add export ... |
690 691 692 693 694 695 696 |
nodeid = get_fuse_inode(inode)->nodeid; generation = inode->i_generation; fh[0] = (u32)(nodeid >> 32); fh[1] = (u32)(nodeid & 0xffffffff); fh[2] = generation; |
b0b0382bb ->encode_fh() API... |
697 |
if (parent) { |
dbd561d23 fuse: add export ... |
698 699 |
nodeid = get_fuse_inode(parent)->nodeid; generation = parent->i_generation; |
dbd561d23 fuse: add export ... |
700 701 702 703 704 705 706 |
fh[3] = (u32)(nodeid >> 32); fh[4] = (u32)(nodeid & 0xffffffff); fh[5] = generation; } *max_len = len; |
b0b0382bb ->encode_fh() API... |
707 |
return parent ? 0x82 : 0x81; |
dbd561d23 fuse: add export ... |
708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 |
} static struct dentry *fuse_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len, int fh_type) { struct fuse_inode_handle handle; if ((fh_type != 0x81 && fh_type != 0x82) || fh_len < 3) return NULL; handle.nodeid = (u64) fid->raw[0] << 32; handle.nodeid |= (u64) fid->raw[1]; handle.generation = fid->raw[2]; return fuse_get_dentry(sb, &handle); } static struct dentry *fuse_fh_to_parent(struct super_block *sb, struct fid *fid, int fh_len, int fh_type) { struct fuse_inode_handle parent; if (fh_type != 0x82 || fh_len < 6) return NULL; parent.nodeid = (u64) fid->raw[3] << 32; parent.nodeid |= (u64) fid->raw[4]; parent.generation = fid->raw[5]; return fuse_get_dentry(sb, &parent); } |
33670fa29 fuse: nfs export ... |
737 738 |
static struct dentry *fuse_get_parent(struct dentry *child) { |
2b0143b5c VFS: normal files... |
739 |
struct inode *child_inode = d_inode(child); |
33670fa29 fuse: nfs export ... |
740 741 742 743 |
struct fuse_conn *fc = get_fuse_conn(child_inode); struct inode *inode; struct dentry *parent; struct fuse_entry_out outarg; |
13983d062 qstr: constify in... |
744 |
const struct qstr name = QSTR_INIT("..", 2); |
33670fa29 fuse: nfs export ... |
745 746 747 748 |
int err; if (!fc->export_support) return ERR_PTR(-ESTALE); |
33670fa29 fuse: nfs export ... |
749 750 |
err = fuse_lookup_name(child_inode->i_sb, get_node_id(child_inode), &name, &outarg, &inode); |
440037287 [PATCH] switch al... |
751 752 753 |
if (err) { if (err == -ENOENT) return ERR_PTR(-ESTALE); |
33670fa29 fuse: nfs export ... |
754 |
return ERR_PTR(err); |
33670fa29 fuse: nfs export ... |
755 |
} |
440037287 [PATCH] switch al... |
756 757 |
parent = d_obtain_alias(inode); |
c35eebe99 switch fuse |
758 |
if (!IS_ERR(parent) && get_node_id(inode) != FUSE_ROOT_ID) |
33670fa29 fuse: nfs export ... |
759 |
fuse_invalidate_entry_cache(parent); |
33670fa29 fuse: nfs export ... |
760 761 762 |
return parent; } |
dbd561d23 fuse: add export ... |
763 764 765 766 767 |
static const struct export_operations fuse_export_operations = { .fh_to_dentry = fuse_fh_to_dentry, .fh_to_parent = fuse_fh_to_parent, .encode_fh = fuse_encode_fh, |
33670fa29 fuse: nfs export ... |
768 |
.get_parent = fuse_get_parent, |
dbd561d23 fuse: add export ... |
769 |
}; |
ee9b6d61a [PATCH] Mark stru... |
770 |
static const struct super_operations fuse_super_operations = { |
d8a5ba454 [PATCH] FUSE - core |
771 |
.alloc_inode = fuse_alloc_inode, |
9baf28bbf fuse: switch to -... |
772 |
.free_inode = fuse_free_inode, |
b57922d97 convert remaining... |
773 |
.evict_inode = fuse_evict_inode, |
1e18bda86 fuse: add .write_... |
774 |
.write_inode = fuse_write_inode, |
ead5f0b5f fuse: delete inod... |
775 |
.drop_inode = generic_delete_inode, |
d8a5ba454 [PATCH] FUSE - core |
776 |
.put_super = fuse_put_super, |
69a53bf26 [PATCH] fuse: add... |
777 |
.umount_begin = fuse_umount_begin, |
e5e5558e9 [PATCH] FUSE - re... |
778 |
.statfs = fuse_statfs, |
d8a5ba454 [PATCH] FUSE - core |
779 780 |
.show_options = fuse_show_options, }; |
487ea5af6 fuse: limit user-... |
781 782 |
static void sanitize_global_limit(unsigned *limit) { |
f22f812d5 fuse: fix request... |
783 784 785 786 |
/* * The default maximum number of async requests is calculated to consume * 1/2^13 of the total memory, assuming 392 bytes per request. */ |
487ea5af6 fuse: limit user-... |
787 |
if (*limit == 0) |
f22f812d5 fuse: fix request... |
788 |
*limit = ((totalram_pages() << PAGE_SHIFT) >> 13) / 392; |
487ea5af6 fuse: limit user-... |
789 790 791 792 |
if (*limit >= 1 << 16) *limit = (1 << 16) - 1; } |
e4dca7b7a treewide: Fix fun... |
793 |
static int set_global_limit(const char *val, const struct kernel_param *kp) |
487ea5af6 fuse: limit user-... |
794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 |
{ int rv; rv = param_set_uint(val, kp); if (rv) return rv; sanitize_global_limit((unsigned *)kp->arg); return 0; } static void process_init_limits(struct fuse_conn *fc, struct fuse_init_out *arg) { int cap_sys_admin = capable(CAP_SYS_ADMIN); if (arg->minor < 13) return; sanitize_global_limit(&max_user_bgreq); sanitize_global_limit(&max_user_congthresh); |
ae2dffa39 fuse: introduce f... |
815 |
spin_lock(&fc->bg_lock); |
487ea5af6 fuse: limit user-... |
816 817 818 819 820 821 822 823 824 825 826 827 828 |
if (arg->max_background) { fc->max_background = arg->max_background; if (!cap_sys_admin && fc->max_background > max_user_bgreq) fc->max_background = max_user_bgreq; } if (arg->congestion_threshold) { fc->congestion_threshold = arg->congestion_threshold; if (!cap_sys_admin && fc->congestion_threshold > max_user_congthresh) fc->congestion_threshold = max_user_congthresh; } |
ae2dffa39 fuse: introduce f... |
829 |
spin_unlock(&fc->bg_lock); |
487ea5af6 fuse: limit user-... |
830 |
} |
615047eff fuse: convert ini... |
831 832 833 834 835 836 837 838 |
struct fuse_init_args { struct fuse_args args; struct fuse_init_in in; struct fuse_init_out out; }; static void process_init_reply(struct fuse_conn *fc, struct fuse_args *args, int error) |
9b9a04693 [PATCH] fuse: mov... |
839 |
{ |
615047eff fuse: convert ini... |
840 841 |
struct fuse_init_args *ia = container_of(args, typeof(*ia), args); struct fuse_init_out *arg = &ia->out; |
9b9a04693 [PATCH] fuse: mov... |
842 |
|
615047eff fuse: convert ini... |
843 |
if (error || arg->major != FUSE_KERNEL_VERSION) |
9b9a04693 [PATCH] fuse: mov... |
844 845 |
fc->conn_error = 1; else { |
9cd684551 [PATCH] fuse: fix... |
846 |
unsigned long ra_pages; |
487ea5af6 fuse: limit user-... |
847 |
process_init_limits(fc, arg); |
9cd684551 [PATCH] fuse: fix... |
848 |
if (arg->minor >= 6) { |
09cbfeaf1 mm, fs: get rid o... |
849 |
ra_pages = arg->max_readahead / PAGE_SIZE; |
9cd684551 [PATCH] fuse: fix... |
850 851 |
if (arg->flags & FUSE_ASYNC_READ) fc->async_read = 1; |
714212593 [PATCH] fuse: add... |
852 853 |
if (!(arg->flags & FUSE_POSIX_LOCKS)) fc->no_lock = 1; |
37fb3a30b fuse: fix flock |
854 855 856 |
if (arg->minor >= 17) { if (!(arg->flags & FUSE_FLOCK_LOCKS)) fc->no_flock = 1; |
24114504c fuse: fix flock b... |
857 858 859 |
} else { if (!(arg->flags & FUSE_POSIX_LOCKS)) fc->no_flock = 1; |
37fb3a30b fuse: fix flock |
860 |
} |
6ff958edb fuse: add atomic ... |
861 862 |
if (arg->flags & FUSE_ATOMIC_O_TRUNC) fc->atomic_o_trunc = 1; |
33670fa29 fuse: nfs export ... |
863 864 865 866 867 |
if (arg->minor >= 9) { /* LOOKUP has dependency on proto version */ if (arg->flags & FUSE_EXPORT_SUPPORT) fc->export_support = 1; } |
78bb6cb9a fuse: add flag to... |
868 869 |
if (arg->flags & FUSE_BIG_WRITES) fc->big_writes = 1; |
e0a43ddcc fuse: allow umask... |
870 871 |
if (arg->flags & FUSE_DONT_MASK) fc->dont_mask = 1; |
72d0d248c fuse: add FUSE_AU... |
872 873 |
if (arg->flags & FUSE_AUTO_INVAL_DATA) fc->auto_inval_data = 1; |
ad2ba64dd fuse: allow files... |
874 875 |
else if (arg->flags & FUSE_EXPLICIT_INVAL_DATA) fc->explicit_inval_data = 1; |
28420dad2 fuse: fix readdir... |
876 |
if (arg->flags & FUSE_DO_READDIRPLUS) { |
0b05b1838 fuse: implement N... |
877 |
fc->do_readdirplus = 1; |
28420dad2 fuse: fix readdir... |
878 879 880 |
if (arg->flags & FUSE_READDIRPLUS_AUTO) fc->readdirplus_auto = 1; } |
60b9df7a5 fuse: add flag to... |
881 882 |
if (arg->flags & FUSE_ASYNC_DIO) fc->async_dio = 1; |
4d99ff8f1 fuse: Turn writeb... |
883 884 |
if (arg->flags & FUSE_WRITEBACK_CACHE) fc->writeback_cache = 1; |
5c672ab3f fuse: serialize d... |
885 886 |
if (arg->flags & FUSE_PARALLEL_DIROPS) fc->parallel_dirops = 1; |
5e940c1dd fuse: handle kill... |
887 888 |
if (arg->flags & FUSE_HANDLE_KILLPRIV) fc->handle_killpriv = 1; |
e27c9d387 fuse: fuse: add t... |
889 890 |
if (arg->time_gran && arg->time_gran <= 1000000000) fc->sb->s_time_gran = arg->time_gran; |
60bcc88ad fuse: Add posix A... |
891 |
if ((arg->flags & FUSE_POSIX_ACL)) { |
29433a299 fuse: get rid of ... |
892 |
fc->default_permissions = 1; |
60bcc88ad fuse: Add posix A... |
893 894 895 |
fc->posix_acl = 1; fc->sb->s_xattr = fuse_acl_xattr_handlers; } |
5571f1e65 fuse: enable cach... |
896 897 |
if (arg->flags & FUSE_CACHE_SYMLINKS) fc->cache_symlinks = 1; |
3b7008b22 fuse: return -ECO... |
898 899 |
if (arg->flags & FUSE_ABORT_ERROR) fc->abort_err = 1; |
5da784cce fuse: add max_pag... |
900 901 902 903 904 |
if (arg->flags & FUSE_MAX_PAGES) { fc->max_pages = min_t(unsigned int, FUSE_MAX_MAX_PAGES, max_t(unsigned int, arg->max_pages, 1)); } |
714212593 [PATCH] fuse: add... |
905 |
} else { |
09cbfeaf1 mm, fs: get rid o... |
906 |
ra_pages = fc->max_read / PAGE_SIZE; |
714212593 [PATCH] fuse: add... |
907 |
fc->no_lock = 1; |
37fb3a30b fuse: fix flock |
908 |
fc->no_flock = 1; |
714212593 [PATCH] fuse: add... |
909 |
} |
9cd684551 [PATCH] fuse: fix... |
910 |
|
5f7f7543f fuse: Convert to ... |
911 912 |
fc->sb->s_bdi->ra_pages = min(fc->sb->s_bdi->ra_pages, ra_pages); |
9b9a04693 [PATCH] fuse: mov... |
913 914 |
fc->minor = arg->minor; fc->max_write = arg->minor < 5 ? 4096 : arg->max_write; |
f948d5643 fuse: fix thinko ... |
915 |
fc->max_write = max_t(unsigned, 4096, fc->max_write); |
0ec7ca41f [PATCH] fuse: add... |
916 |
fc->conn_init = 1; |
9b9a04693 [PATCH] fuse: mov... |
917 |
} |
615047eff fuse: convert ini... |
918 |
kfree(ia); |
9759bd518 fuse: add memory ... |
919 |
fuse_set_initialized(fc); |
08a53cdce [PATCH] fuse: acc... |
920 |
wake_up_all(&fc->blocked_waitq); |
9b9a04693 [PATCH] fuse: mov... |
921 |
} |
95a84cdb1 fuse: export fuse... |
922 |
void fuse_send_init(struct fuse_conn *fc) |
9b9a04693 [PATCH] fuse: mov... |
923 |
{ |
615047eff fuse: convert ini... |
924 |
struct fuse_init_args *ia; |
095da6cbb [PATCH] fuse: fix... |
925 |
|
615047eff fuse: convert ini... |
926 927 928 929 930 931 932 |
ia = kzalloc(sizeof(*ia), GFP_KERNEL | __GFP_NOFAIL); ia->in.major = FUSE_KERNEL_VERSION; ia->in.minor = FUSE_KERNEL_MINOR_VERSION; ia->in.max_readahead = fc->sb->s_bdi->ra_pages * PAGE_SIZE; ia->in.flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC | |
37fb3a30b fuse: fix flock |
933 |
FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK | |
69fe05c90 fuse: add missing... |
934 |
FUSE_SPLICE_WRITE | FUSE_SPLICE_MOVE | FUSE_SPLICE_READ | |
9446385f0 fuse: fix wrong a... |
935 |
FUSE_FLOCK_LOCKS | FUSE_HAS_IOCTL_DIR | FUSE_AUTO_INVAL_DATA | |
4d99ff8f1 fuse: Turn writeb... |
936 |
FUSE_DO_READDIRPLUS | FUSE_READDIRPLUS_AUTO | FUSE_ASYNC_DIO | |
5c672ab3f fuse: serialize d... |
937 |
FUSE_WRITEBACK_CACHE | FUSE_NO_OPEN_SUPPORT | |
3b7008b22 fuse: return -ECO... |
938 |
FUSE_PARALLEL_DIROPS | FUSE_HANDLE_KILLPRIV | FUSE_POSIX_ACL | |
d9a9ea94f fuse: support cli... |
939 |
FUSE_ABORT_ERROR | FUSE_MAX_PAGES | FUSE_CACHE_SYMLINKS | |
ad2ba64dd fuse: allow files... |
940 |
FUSE_NO_OPENDIR_SUPPORT | FUSE_EXPLICIT_INVAL_DATA; |
615047eff fuse: convert ini... |
941 942 943 944 945 |
ia->args.opcode = FUSE_INIT; ia->args.in_numargs = 1; ia->args.in_args[0].size = sizeof(ia->in); ia->args.in_args[0].value = &ia->in; ia->args.out_numargs = 1; |
3ad2f3fbb tree-wide: Assort... |
946 |
/* Variable length argument used for backward compatibility |
9b9a04693 [PATCH] fuse: mov... |
947 948 |
with interface version < 7.5. Rest of init_out is zeroed by do_get_request(), so a short reply is not a problem */ |
cabdb4fa2 fuse: use true,fa... |
949 |
ia->args.out_argvar = true; |
615047eff fuse: convert ini... |
950 951 952 953 954 955 956 957 |
ia->args.out_args[0].size = sizeof(ia->out); ia->args.out_args[0].value = &ia->out; ia->args.force = true; ia->args.nocreds = true; ia->args.end = process_init_reply; if (fuse_simple_background(fc, &ia->args, GFP_KERNEL) != 0) process_init_reply(fc, &ia->args, -ENOTCONN); |
9b9a04693 [PATCH] fuse: mov... |
958 |
} |
95a84cdb1 fuse: export fuse... |
959 |
EXPORT_SYMBOL_GPL(fuse_send_init); |
9b9a04693 [PATCH] fuse: mov... |
960 |
|
783863d64 fuse: dissociate ... |
961 |
void fuse_free_conn(struct fuse_conn *fc) |
43901aabd fuse: add fuse_co... |
962 |
{ |
cc080e9e9 fuse: introduce p... |
963 |
WARN_ON(!list_empty(&fc->devices)); |
dd3e2c55a fuse: rcu-delay f... |
964 |
kfree_rcu(fc, rcu); |
43901aabd fuse: add fuse_co... |
965 |
} |
783863d64 fuse: dissociate ... |
966 |
EXPORT_SYMBOL_GPL(fuse_free_conn); |
43901aabd fuse: add fuse_co... |
967 |
|
a325f9b92 fuse: update fuse... |
968 969 970 |
static int fuse_bdi_init(struct fuse_conn *fc, struct super_block *sb) { int err; |
5f7f7543f fuse: Convert to ... |
971 |
char *suffix = ""; |
a325f9b92 fuse: update fuse... |
972 |
|
69c8ebf83 fuseblk: Fix warn... |
973 |
if (sb->s_bdev) { |
5f7f7543f fuse: Convert to ... |
974 |
suffix = "-fuseblk"; |
69c8ebf83 fuseblk: Fix warn... |
975 976 977 978 979 980 981 |
/* * sb->s_bdi points to blkdev's bdi however we want to redirect * it to our private bdi... */ bdi_put(sb->s_bdi); sb->s_bdi = &noop_backing_dev_info; } |
5f7f7543f fuse: Convert to ... |
982 983 |
err = super_setup_bdi_name(sb, "%u:%u%s", MAJOR(fc->dev), MINOR(fc->dev), suffix); |
a325f9b92 fuse: update fuse... |
984 985 |
if (err) return err; |
b5420237e mm: refactor read... |
986 |
sb->s_bdi->ra_pages = VM_READAHEAD_PAGES; |
5f7f7543f fuse: Convert to ... |
987 988 |
/* fuse does it's own writeback accounting */ sb->s_bdi->capabilities = BDI_CAP_NO_ACCT_WB | BDI_CAP_STRICTLIMIT; |
a325f9b92 fuse: update fuse... |
989 |
|
a325f9b92 fuse: update fuse... |
990 991 992 993 994 995 996 997 998 999 1000 1001 |
/* * For a single fuse filesystem use max 1% of dirty + * writeback threshold. * * This gives about 1M of write buffer for memory maps on a * machine with 1G and 10% dirty_ratio, which should be more * than enough. * * Privileged users can raise it by writing to * * /sys/class/bdi/<bdi>/max_ratio */ |
5f7f7543f fuse: Convert to ... |
1002 |
bdi_set_max_ratio(sb->s_bdi, 1); |
a325f9b92 fuse: update fuse... |
1003 1004 1005 |
return 0; } |
0cd1eb9a4 fuse: separate fu... |
1006 |
struct fuse_dev *fuse_dev_alloc(void) |
cc080e9e9 fuse: introduce p... |
1007 1008 |
{ struct fuse_dev *fud; |
be2ff42c5 fuse: Use hash ta... |
1009 |
struct list_head *pq; |
cc080e9e9 fuse: introduce p... |
1010 1011 |
fud = kzalloc(sizeof(struct fuse_dev), GFP_KERNEL); |
be2ff42c5 fuse: Use hash ta... |
1012 1013 |
if (!fud) return NULL; |
cc080e9e9 fuse: introduce p... |
1014 |
|
be2ff42c5 fuse: Use hash ta... |
1015 1016 1017 1018 |
pq = kcalloc(FUSE_PQ_HASH_SIZE, sizeof(struct list_head), GFP_KERNEL); if (!pq) { kfree(fud); return NULL; |
cc080e9e9 fuse: introduce p... |
1019 |
} |
be2ff42c5 fuse: Use hash ta... |
1020 |
fud->pq.processing = pq; |
be2ff42c5 fuse: Use hash ta... |
1021 |
fuse_pqueue_init(&fud->pq); |
0cd1eb9a4 fuse: separate fu... |
1022 1023 1024 1025 1026 1027 1028 |
return fud; } EXPORT_SYMBOL_GPL(fuse_dev_alloc); void fuse_dev_install(struct fuse_dev *fud, struct fuse_conn *fc) { fud->fc = fuse_conn_get(fc); |
be2ff42c5 fuse: Use hash ta... |
1029 1030 1031 |
spin_lock(&fc->lock); list_add_tail(&fud->entry, &fc->devices); spin_unlock(&fc->lock); |
0cd1eb9a4 fuse: separate fu... |
1032 1033 |
} EXPORT_SYMBOL_GPL(fuse_dev_install); |
be2ff42c5 fuse: Use hash ta... |
1034 |
|
0cd1eb9a4 fuse: separate fu... |
1035 1036 1037 1038 1039 1040 1041 1042 1043 |
struct fuse_dev *fuse_dev_alloc_install(struct fuse_conn *fc) { struct fuse_dev *fud; fud = fuse_dev_alloc(); if (!fud) return NULL; fuse_dev_install(fud, fc); |
cc080e9e9 fuse: introduce p... |
1044 1045 |
return fud; } |
0cd1eb9a4 fuse: separate fu... |
1046 |
EXPORT_SYMBOL_GPL(fuse_dev_alloc_install); |
cc080e9e9 fuse: introduce p... |
1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 |
void fuse_dev_free(struct fuse_dev *fud) { struct fuse_conn *fc = fud->fc; if (fc) { spin_lock(&fc->lock); list_del(&fud->entry); spin_unlock(&fc->lock); fuse_conn_put(fc); } |
d72f70da6 fuse: Fix memory ... |
1059 |
kfree(fud->pq.processing); |
cc080e9e9 fuse: introduce p... |
1060 1061 1062 |
kfree(fud); } EXPORT_SYMBOL_GPL(fuse_dev_free); |
0cc2656cd fuse: extract fus... |
1063 |
int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx) |
d8a5ba454 [PATCH] FUSE - core |
1064 |
{ |
7fd3abfa8 virtiofs: do not ... |
1065 |
struct fuse_dev *fud = NULL; |
0cc2656cd fuse: extract fus... |
1066 |
struct fuse_conn *fc = get_fuse_conn_super(sb); |
d8a5ba454 [PATCH] FUSE - core |
1067 |
struct inode *root; |
f543f253f [PATCH] fuse: mak... |
1068 |
struct dentry *root_dentry; |
d8a5ba454 [PATCH] FUSE - core |
1069 |
int err; |
c2b8f0069 fuse: fuse_fill_s... |
1070 |
err = -EINVAL; |
1751e8a6c Rename superblock... |
1071 |
if (sb->s_flags & SB_MANDLOCK) |
c2b8f0069 fuse: fuse_fill_s... |
1072 |
goto err; |
714212593 [PATCH] fuse: add... |
1073 |
|
1751e8a6c Rename superblock... |
1074 |
sb->s_flags &= ~(SB_NOSEC | SB_I_VERSION); |
9e1f1de02 more conservative... |
1075 |
|
0cc2656cd fuse: extract fus... |
1076 |
if (ctx->is_bdev) { |
875d95ec9 [PATCH] fuse: fix... |
1077 |
#ifdef CONFIG_BLOCK |
c2b8f0069 fuse: fuse_fill_s... |
1078 |
err = -EINVAL; |
c30da2e98 fuse: convert to ... |
1079 |
if (!sb_set_blocksize(sb, ctx->blksize)) |
c2b8f0069 fuse: fuse_fill_s... |
1080 |
goto err; |
875d95ec9 [PATCH] fuse: fix... |
1081 |
#endif |
d80916140 [PATCH] fuse: add... |
1082 |
} else { |
09cbfeaf1 mm, fs: get rid o... |
1083 1084 |
sb->s_blocksize = PAGE_SIZE; sb->s_blocksize_bits = PAGE_SHIFT; |
d80916140 [PATCH] fuse: add... |
1085 |
} |
c30da2e98 fuse: convert to ... |
1086 1087 1088 |
sb->s_subtype = ctx->subtype; ctx->subtype = NULL; |
d8a5ba454 [PATCH] FUSE - core |
1089 1090 |
sb->s_magic = FUSE_SUPER_MAGIC; sb->s_op = &fuse_super_operations; |
703c73629 fuse: Use generic... |
1091 |
sb->s_xattr = fuse_xattr_handlers; |
d8a5ba454 [PATCH] FUSE - core |
1092 |
sb->s_maxbytes = MAX_LFS_FILESIZE; |
0a2da9b2e fuse: allow nanos... |
1093 |
sb->s_time_gran = 1; |
dbd561d23 fuse: add export ... |
1094 |
sb->s_export_op = &fuse_export_operations; |
0834136ae fuse: define the ... |
1095 1096 1097 |
sb->s_iflags |= SB_I_IMA_UNVERIFIABLE_SIGNATURE; if (sb->s_user_ns != &init_user_ns) sb->s_iflags |= SB_I_UNTRUSTED_MOUNTER; |
d8a5ba454 [PATCH] FUSE - core |
1098 |
|
e45b2546e fuse: Ensure posi... |
1099 1100 1101 1102 1103 1104 |
/* * If we are not in the initial user namespace posix * acls must be translated. */ if (sb->s_user_ns != &init_user_ns) sb->s_xattr = fuse_no_acl_xattr_handlers; |
7fd3abfa8 virtiofs: do not ... |
1105 1106 1107 1108 1109 1110 |
if (ctx->fudptr) { err = -ENOMEM; fud = fuse_dev_alloc_install(fc); if (!fud) goto err; } |
cc080e9e9 fuse: introduce p... |
1111 |
|
a325f9b92 fuse: update fuse... |
1112 |
fc->dev = sb->s_dev; |
3b463ae0c fuse: invalidatio... |
1113 |
fc->sb = sb; |
a325f9b92 fuse: update fuse... |
1114 1115 |
err = fuse_bdi_init(fc, sb); if (err) |
cc080e9e9 fuse: introduce p... |
1116 |
goto err_dev_free; |
0d179aa59 fuse: separate ou... |
1117 |
|
e0a43ddcc fuse: allow umask... |
1118 |
/* Handle umasking inside the fuse code */ |
1751e8a6c Rename superblock... |
1119 |
if (sb->s_flags & SB_POSIXACL) |
e0a43ddcc fuse: allow umask... |
1120 |
fc->dont_mask = 1; |
1751e8a6c Rename superblock... |
1121 |
sb->s_flags |= SB_POSIXACL; |
e0a43ddcc fuse: allow umask... |
1122 |
|
c30da2e98 fuse: convert to ... |
1123 1124 1125 1126 1127 |
fc->default_permissions = ctx->default_permissions; fc->allow_other = ctx->allow_other; fc->user_id = ctx->user_id; fc->group_id = ctx->group_id; fc->max_read = max_t(unsigned, 4096, ctx->max_read); |
783863d64 fuse: dissociate ... |
1128 |
fc->destroy = ctx->destroy; |
15c8e72e8 fuse: allow skipp... |
1129 1130 |
fc->no_control = ctx->no_control; fc->no_force_umount = ctx->no_force_umount; |
3f22c7467 virtio-fs: don't ... |
1131 |
fc->no_mount_options = ctx->no_mount_options; |
f543f253f [PATCH] fuse: mak... |
1132 |
|
d8a5ba454 [PATCH] FUSE - core |
1133 |
err = -ENOMEM; |
c30da2e98 fuse: convert to ... |
1134 |
root = fuse_get_root_inode(sb, ctx->rootmode); |
0ce267ff9 fuse: fix root de... |
1135 |
sb->s_d_op = &fuse_root_dentry_operations; |
48fde701a switch open-coded... |
1136 1137 |
root_dentry = d_make_root(root); if (!root_dentry) |
cc080e9e9 fuse: introduce p... |
1138 |
goto err_dev_free; |
0ce267ff9 fuse: fix root de... |
1139 |
/* Root dentry doesn't have .d_revalidate */ |
c35eebe99 switch fuse |
1140 |
sb->s_d_op = &fuse_dentry_operations; |
f543f253f [PATCH] fuse: mak... |
1141 |
|
bafa96541 [PATCH] fuse: add... |
1142 |
mutex_lock(&fuse_mutex); |
8aa09a50b [fuse] fix race b... |
1143 |
err = -EINVAL; |
7fd3abfa8 virtiofs: do not ... |
1144 |
if (ctx->fudptr && *ctx->fudptr) |
bafa96541 [PATCH] fuse: add... |
1145 |
goto err_unlock; |
8aa09a50b [fuse] fix race b... |
1146 |
|
bafa96541 [PATCH] fuse: add... |
1147 1148 1149 1150 1151 |
err = fuse_ctl_add_conn(fc); if (err) goto err_unlock; list_add_tail(&fc->entry, &fuse_conn_list); |
f543f253f [PATCH] fuse: mak... |
1152 |
sb->s_root = root_dentry; |
7fd3abfa8 virtiofs: do not ... |
1153 1154 |
if (ctx->fudptr) *ctx->fudptr = fud; |
bafa96541 [PATCH] fuse: add... |
1155 |
mutex_unlock(&fuse_mutex); |
0cc2656cd fuse: extract fus... |
1156 1157 1158 1159 1160 1161 |
return 0; err_unlock: mutex_unlock(&fuse_mutex); dput(root_dentry); err_dev_free: |
7fd3abfa8 virtiofs: do not ... |
1162 1163 |
if (fud) fuse_dev_free(fud); |
0cc2656cd fuse: extract fus... |
1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 |
err: return err; } EXPORT_SYMBOL_GPL(fuse_fill_super_common); static int fuse_fill_super(struct super_block *sb, struct fs_context *fsc) { struct fuse_fs_context *ctx = fsc->fs_private; struct file *file; int err; struct fuse_conn *fc; err = -EINVAL; file = fget(ctx->fd); if (!file) goto err; /* * Require mount to happen from the same user namespace which * opened /dev/fuse to prevent potential attacks. */ if ((file->f_op != &fuse_dev_operations) || (file->f_cred->user_ns != sb->s_user_ns)) goto err_fput; ctx->fudptr = &file->private_data; fc = kmalloc(sizeof(*fc), GFP_KERNEL); err = -ENOMEM; if (!fc) goto err_fput; |
ae3aad77f fuse: add fuse_iq... |
1194 |
fuse_conn_init(fc, sb->s_user_ns, &fuse_dev_fiq_ops, NULL); |
0cc2656cd fuse: extract fus... |
1195 1196 1197 1198 1199 1200 |
fc->release = fuse_free_conn; sb->s_fs_info = fc; err = fuse_fill_super_common(sb, ctx); if (err) goto err_put_conn; |
0720b3159 [PATCH] fuse: sim... |
1201 1202 1203 1204 1205 1206 |
/* * atomic_dec_and_test() in fput() provides the necessary * memory barrier for file->private_data to be visible on all * CPUs after this */ fput(file); |
0cc2656cd fuse: extract fus... |
1207 |
fuse_send_init(get_fuse_conn_super(sb)); |
d8a5ba454 [PATCH] FUSE - core |
1208 |
return 0; |
c2b8f0069 fuse: fuse_fill_s... |
1209 |
err_put_conn: |
bafa96541 [PATCH] fuse: add... |
1210 |
fuse_conn_put(fc); |
543b8f866 fuse: don't keep ... |
1211 |
sb->s_fs_info = NULL; |
c2b8f0069 fuse: fuse_fill_s... |
1212 1213 1214 |
err_fput: fput(file); err: |
d8a5ba454 [PATCH] FUSE - core |
1215 1216 |
return err; } |
c30da2e98 fuse: convert to ... |
1217 |
static int fuse_get_tree(struct fs_context *fc) |
d8a5ba454 [PATCH] FUSE - core |
1218 |
{ |
c30da2e98 fuse: convert to ... |
1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 |
struct fuse_fs_context *ctx = fc->fs_private; if (!ctx->fd_present || !ctx->rootmode_present || !ctx->user_id_present || !ctx->group_id_present) return -EINVAL; #ifdef CONFIG_BLOCK if (ctx->is_bdev) return get_tree_bdev(fc, fuse_fill_super); #endif return get_tree_nodev(fc, fuse_fill_super); } static const struct fs_context_operations fuse_context_ops = { .free = fuse_free_fc, .parse_param = fuse_parse_param, |
0189a2d36 fuse: use ->recon... |
1236 |
.reconfigure = fuse_reconfigure, |
c30da2e98 fuse: convert to ... |
1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 |
.get_tree = fuse_get_tree, }; /* * Set up the filesystem mount context. */ static int fuse_init_fs_context(struct fs_context *fc) { struct fuse_fs_context *ctx; ctx = kzalloc(sizeof(struct fuse_fs_context), GFP_KERNEL); if (!ctx) return -ENOMEM; ctx->max_read = ~0; ctx->blksize = FUSE_DEFAULT_BLKSIZE; #ifdef CONFIG_BLOCK |
783863d64 fuse: dissociate ... |
1255 |
if (fc->fs_type == &fuseblk_fs_type) { |
c30da2e98 fuse: convert to ... |
1256 |
ctx->is_bdev = true; |
783863d64 fuse: dissociate ... |
1257 1258 |
ctx->destroy = true; } |
c30da2e98 fuse: convert to ... |
1259 1260 1261 1262 1263 |
#endif fc->fs_private = ctx; fc->ops = &fuse_context_ops; return 0; |
d8a5ba454 [PATCH] FUSE - core |
1264 |
} |
e8f3bd773 fuse: Fix oops at... |
1265 |
static void fuse_sb_destroy(struct super_block *sb) |
3b463ae0c fuse: invalidatio... |
1266 1267 1268 1269 |
{ struct fuse_conn *fc = get_fuse_conn_super(sb); if (fc) { |
1ccd1ea24 fuse: convert des... |
1270 1271 |
if (fc->destroy) fuse_send_destroy(fc); |
e8f3bd773 fuse: Fix oops at... |
1272 |
|
eb98e3bdf fuse: clean up ab... |
1273 |
fuse_abort_conn(fc); |
e8f3bd773 fuse: Fix oops at... |
1274 |
fuse_wait_aborted(fc); |
3b463ae0c fuse: invalidatio... |
1275 1276 1277 1278 |
down_write(&fc->killsb); fc->sb = NULL; up_write(&fc->killsb); } |
e8f3bd773 fuse: Fix oops at... |
1279 |
} |
3b463ae0c fuse: invalidatio... |
1280 |
|
783863d64 fuse: dissociate ... |
1281 |
void fuse_kill_sb_anon(struct super_block *sb) |
e8f3bd773 fuse: Fix oops at... |
1282 1283 |
{ fuse_sb_destroy(sb); |
3b463ae0c fuse: invalidatio... |
1284 1285 |
kill_anon_super(sb); } |
783863d64 fuse: dissociate ... |
1286 |
EXPORT_SYMBOL_GPL(fuse_kill_sb_anon); |
3b463ae0c fuse: invalidatio... |
1287 |
|
875d95ec9 [PATCH] fuse: fix... |
1288 1289 1290 |
static struct file_system_type fuse_fs_type = { .owner = THIS_MODULE, .name = "fuse", |
4ad769f3c fuse: Allow fully... |
1291 |
.fs_flags = FS_HAS_SUBTYPE | FS_USERNS_MOUNT, |
c30da2e98 fuse: convert to ... |
1292 |
.init_fs_context = fuse_init_fs_context, |
d7167b149 fs_parse: fold fs... |
1293 |
.parameters = fuse_fs_parameters, |
3b463ae0c fuse: invalidatio... |
1294 |
.kill_sb = fuse_kill_sb_anon, |
875d95ec9 [PATCH] fuse: fix... |
1295 |
}; |
7f78e0351 fs: Limit sys_mou... |
1296 |
MODULE_ALIAS_FS("fuse"); |
875d95ec9 [PATCH] fuse: fix... |
1297 1298 |
#ifdef CONFIG_BLOCK |
3b463ae0c fuse: invalidatio... |
1299 1300 |
static void fuse_kill_sb_blk(struct super_block *sb) { |
e8f3bd773 fuse: Fix oops at... |
1301 |
fuse_sb_destroy(sb); |
3b463ae0c fuse: invalidatio... |
1302 1303 |
kill_block_super(sb); } |
d6392f873 [PATCH] fuse: add... |
1304 1305 1306 |
static struct file_system_type fuseblk_fs_type = { .owner = THIS_MODULE, .name = "fuseblk", |
c30da2e98 fuse: convert to ... |
1307 |
.init_fs_context = fuse_init_fs_context, |
d7167b149 fs_parse: fold fs... |
1308 |
.parameters = fuse_fs_parameters, |
3b463ae0c fuse: invalidatio... |
1309 |
.kill_sb = fuse_kill_sb_blk, |
edad01e2a fuse: ->fs_flags ... |
1310 |
.fs_flags = FS_REQUIRES_DEV | FS_HAS_SUBTYPE, |
d6392f873 [PATCH] fuse: add... |
1311 |
}; |
7f78e0351 fs: Limit sys_mou... |
1312 |
MODULE_ALIAS_FS("fuseblk"); |
d6392f873 [PATCH] fuse: add... |
1313 |
|
875d95ec9 [PATCH] fuse: fix... |
1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 |
static inline int register_fuseblk(void) { return register_filesystem(&fuseblk_fs_type); } static inline void unregister_fuseblk(void) { unregister_filesystem(&fuseblk_fs_type); } #else static inline int register_fuseblk(void) { return 0; } static inline void unregister_fuseblk(void) { } #endif |
51cc50685 SL*B: drop kmem c... |
1333 |
static void fuse_inode_init_once(void *foo) |
d8a5ba454 [PATCH] FUSE - core |
1334 |
{ |
1729a16c2 fuse: style fixes |
1335 |
struct inode *inode = foo; |
d8a5ba454 [PATCH] FUSE - core |
1336 |
|
a35afb830 Remove SLAB_CTOR_... |
1337 |
inode_init_once(inode); |
d8a5ba454 [PATCH] FUSE - core |
1338 1339 1340 1341 1342 |
} static int __init fuse_fs_init(void) { int err; |
d6392f873 [PATCH] fuse: add... |
1343 |
fuse_inode_cachep = kmem_cache_create("fuse_inode", |
df206988e fs: fuse: account... |
1344 1345 1346 |
sizeof(struct fuse_inode), 0, SLAB_HWCACHE_ALIGN|SLAB_ACCOUNT|SLAB_RECLAIM_ACCOUNT, fuse_inode_init_once); |
d6392f873 [PATCH] fuse: add... |
1347 1348 |
err = -ENOMEM; if (!fuse_inode_cachep) |
988f03256 fuse: register_fi... |
1349 1350 1351 1352 1353 1354 1355 1356 1357 |
goto out; err = register_fuseblk(); if (err) goto out2; err = register_filesystem(&fuse_fs_type); if (err) goto out3; |
d6392f873 [PATCH] fuse: add... |
1358 1359 |
return 0; |
d8a5ba454 [PATCH] FUSE - core |
1360 |
|
988f03256 fuse: register_fi... |
1361 |
out3: |
875d95ec9 [PATCH] fuse: fix... |
1362 |
unregister_fuseblk(); |
988f03256 fuse: register_fi... |
1363 1364 |
out2: kmem_cache_destroy(fuse_inode_cachep); |
d6392f873 [PATCH] fuse: add... |
1365 |
out: |
d8a5ba454 [PATCH] FUSE - core |
1366 1367 1368 1369 1370 1371 |
return err; } static void fuse_fs_cleanup(void) { unregister_filesystem(&fuse_fs_type); |
875d95ec9 [PATCH] fuse: fix... |
1372 |
unregister_fuseblk(); |
8c0a85377 fs: push rcu_barr... |
1373 1374 1375 1376 1377 1378 |
/* * Make sure all delayed rcu free inodes are flushed before we * destroy cache. */ rcu_barrier(); |
d8a5ba454 [PATCH] FUSE - core |
1379 1380 |
kmem_cache_destroy(fuse_inode_cachep); } |
5c89e17e9 kobject: convert ... |
1381 |
static struct kobject *fuse_kobj; |
5c89e17e9 kobject: convert ... |
1382 |
|
f543f253f [PATCH] fuse: mak... |
1383 1384 1385 |
static int fuse_sysfs_init(void) { int err; |
00d266662 kobject: convert ... |
1386 |
fuse_kobj = kobject_create_and_add("fuse", fs_kobj); |
5c89e17e9 kobject: convert ... |
1387 1388 |
if (!fuse_kobj) { err = -ENOMEM; |
f543f253f [PATCH] fuse: mak... |
1389 |
goto out_err; |
5c89e17e9 kobject: convert ... |
1390 |
} |
f543f253f [PATCH] fuse: mak... |
1391 |
|
f9bb48825 sysfs: Create mou... |
1392 1393 |
err = sysfs_create_mount_point(fuse_kobj, "connections"); if (err) |
f543f253f [PATCH] fuse: mak... |
1394 1395 1396 1397 1398 |
goto out_fuse_unregister; return 0; out_fuse_unregister: |
197b12d67 Kobject: convert ... |
1399 |
kobject_put(fuse_kobj); |
f543f253f [PATCH] fuse: mak... |
1400 1401 1402 1403 1404 1405 |
out_err: return err; } static void fuse_sysfs_cleanup(void) { |
f9bb48825 sysfs: Create mou... |
1406 |
sysfs_remove_mount_point(fuse_kobj, "connections"); |
197b12d67 Kobject: convert ... |
1407 |
kobject_put(fuse_kobj); |
f543f253f [PATCH] fuse: mak... |
1408 |
} |
d8a5ba454 [PATCH] FUSE - core |
1409 1410 1411 |
static int __init fuse_init(void) { int res; |
f2294482f fuse: convert pri... |
1412 1413 1414 |
pr_info("init (API version %i.%i) ", FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION); |
d8a5ba454 [PATCH] FUSE - core |
1415 |
|
bafa96541 [PATCH] fuse: add... |
1416 |
INIT_LIST_HEAD(&fuse_conn_list); |
d8a5ba454 [PATCH] FUSE - core |
1417 1418 1419 |
res = fuse_fs_init(); if (res) goto err; |
334f485df [PATCH] FUSE - de... |
1420 1421 1422 |
res = fuse_dev_init(); if (res) goto err_fs_cleanup; |
f543f253f [PATCH] fuse: mak... |
1423 1424 1425 |
res = fuse_sysfs_init(); if (res) goto err_dev_cleanup; |
bafa96541 [PATCH] fuse: add... |
1426 1427 1428 |
res = fuse_ctl_init(); if (res) goto err_sysfs_cleanup; |
487ea5af6 fuse: limit user-... |
1429 1430 |
sanitize_global_limit(&max_user_bgreq); sanitize_global_limit(&max_user_congthresh); |
d8a5ba454 [PATCH] FUSE - core |
1431 |
return 0; |
bafa96541 [PATCH] fuse: add... |
1432 1433 |
err_sysfs_cleanup: fuse_sysfs_cleanup(); |
f543f253f [PATCH] fuse: mak... |
1434 1435 |
err_dev_cleanup: fuse_dev_cleanup(); |
334f485df [PATCH] FUSE - de... |
1436 1437 |
err_fs_cleanup: fuse_fs_cleanup(); |
d8a5ba454 [PATCH] FUSE - core |
1438 1439 1440 1441 1442 1443 |
err: return res; } static void __exit fuse_exit(void) { |
f2294482f fuse: convert pri... |
1444 1445 |
pr_debug("exit "); |
d8a5ba454 [PATCH] FUSE - core |
1446 |
|
bafa96541 [PATCH] fuse: add... |
1447 |
fuse_ctl_cleanup(); |
f543f253f [PATCH] fuse: mak... |
1448 |
fuse_sysfs_cleanup(); |
d8a5ba454 [PATCH] FUSE - core |
1449 |
fuse_fs_cleanup(); |
334f485df [PATCH] FUSE - de... |
1450 |
fuse_dev_cleanup(); |
d8a5ba454 [PATCH] FUSE - core |
1451 1452 1453 1454 |
} module_init(fuse_init); module_exit(fuse_exit); |