| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * linux/fs/9p/vfs_inode.c |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 5 | 6 | * |
|---|
| 6 | 7 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> |
|---|
| 7 | 8 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 10 | | - * it under the terms of the GNU General Public License version 2 |
|---|
| 11 | | - * as published by the Free Software Foundation. |
|---|
| 12 | | - * |
|---|
| 13 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 14 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 15 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 16 | | - * GNU General Public License for more details. |
|---|
| 17 | | - * |
|---|
| 18 | | - * You should have received a copy of the GNU General Public License |
|---|
| 19 | | - * along with this program; if not, write to: |
|---|
| 20 | | - * Free Software Foundation |
|---|
| 21 | | - * 51 Franklin Street, Fifth Floor |
|---|
| 22 | | - * Boston, MA 02111-1301 USA |
|---|
| 23 | | - * |
|---|
| 24 | 9 | */ |
|---|
| 25 | 10 | |
|---|
| 26 | 11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
|---|
| .. | .. |
|---|
| 158 | 143 | default: |
|---|
| 159 | 144 | p9_debug(P9_DEBUG_ERROR, "Unknown special type %c %s\n", |
|---|
| 160 | 145 | type, stat->extension); |
|---|
| 161 | | - }; |
|---|
| 146 | + } |
|---|
| 162 | 147 | *rdev = MKDEV(major, minor); |
|---|
| 163 | 148 | } else |
|---|
| 164 | 149 | res |= S_IFREG; |
|---|
| .. | .. |
|---|
| 238 | 223 | struct inode *v9fs_alloc_inode(struct super_block *sb) |
|---|
| 239 | 224 | { |
|---|
| 240 | 225 | struct v9fs_inode *v9inode; |
|---|
| 241 | | - v9inode = (struct v9fs_inode *)kmem_cache_alloc(v9fs_inode_cache, |
|---|
| 242 | | - GFP_KERNEL); |
|---|
| 226 | + v9inode = kmem_cache_alloc(v9fs_inode_cache, GFP_KERNEL); |
|---|
| 243 | 227 | if (!v9inode) |
|---|
| 244 | 228 | return NULL; |
|---|
| 245 | 229 | #ifdef CONFIG_9P_FSCACHE |
|---|
| .. | .. |
|---|
| 253 | 237 | } |
|---|
| 254 | 238 | |
|---|
| 255 | 239 | /** |
|---|
| 256 | | - * v9fs_destroy_inode - destroy an inode |
|---|
| 240 | + * v9fs_free_inode - destroy an inode |
|---|
| 257 | 241 | * |
|---|
| 258 | 242 | */ |
|---|
| 259 | 243 | |
|---|
| 260 | | -static void v9fs_i_callback(struct rcu_head *head) |
|---|
| 244 | +void v9fs_free_inode(struct inode *inode) |
|---|
| 261 | 245 | { |
|---|
| 262 | | - struct inode *inode = container_of(head, struct inode, i_rcu); |
|---|
| 263 | 246 | kmem_cache_free(v9fs_inode_cache, V9FS_I(inode)); |
|---|
| 264 | | -} |
|---|
| 265 | | - |
|---|
| 266 | | -void v9fs_destroy_inode(struct inode *inode) |
|---|
| 267 | | -{ |
|---|
| 268 | | - call_rcu(&inode->i_rcu, v9fs_i_callback); |
|---|
| 269 | 247 | } |
|---|
| 270 | 248 | |
|---|
| 271 | 249 | int v9fs_init_inode(struct v9fs_session_info *v9ses, |
|---|
| .. | .. |
|---|
| 389 | 367 | return inode; |
|---|
| 390 | 368 | } |
|---|
| 391 | 369 | |
|---|
| 392 | | -/* |
|---|
| 393 | | -static struct v9fs_fid* |
|---|
| 394 | | -v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry) |
|---|
| 395 | | -{ |
|---|
| 396 | | - int err; |
|---|
| 397 | | - int nfid; |
|---|
| 398 | | - struct v9fs_fid *ret; |
|---|
| 399 | | - struct v9fs_fcall *fcall; |
|---|
| 400 | | - |
|---|
| 401 | | - nfid = v9fs_get_idpool(&v9ses->fidpool); |
|---|
| 402 | | - if (nfid < 0) { |
|---|
| 403 | | - eprintk(KERN_WARNING, "no free fids available\n"); |
|---|
| 404 | | - return ERR_PTR(-ENOSPC); |
|---|
| 405 | | - } |
|---|
| 406 | | - |
|---|
| 407 | | - err = v9fs_t_walk(v9ses, fid, nfid, (char *) dentry->d_name.name, |
|---|
| 408 | | - &fcall); |
|---|
| 409 | | - |
|---|
| 410 | | - if (err < 0) { |
|---|
| 411 | | - if (fcall && fcall->id == RWALK) |
|---|
| 412 | | - goto clunk_fid; |
|---|
| 413 | | - |
|---|
| 414 | | - PRINT_FCALL_ERROR("walk error", fcall); |
|---|
| 415 | | - v9fs_put_idpool(nfid, &v9ses->fidpool); |
|---|
| 416 | | - goto error; |
|---|
| 417 | | - } |
|---|
| 418 | | - |
|---|
| 419 | | - kfree(fcall); |
|---|
| 420 | | - fcall = NULL; |
|---|
| 421 | | - ret = v9fs_fid_create(v9ses, nfid); |
|---|
| 422 | | - if (!ret) { |
|---|
| 423 | | - err = -ENOMEM; |
|---|
| 424 | | - goto clunk_fid; |
|---|
| 425 | | - } |
|---|
| 426 | | - |
|---|
| 427 | | - err = v9fs_fid_insert(ret, dentry); |
|---|
| 428 | | - if (err < 0) { |
|---|
| 429 | | - v9fs_fid_destroy(ret); |
|---|
| 430 | | - goto clunk_fid; |
|---|
| 431 | | - } |
|---|
| 432 | | - |
|---|
| 433 | | - return ret; |
|---|
| 434 | | - |
|---|
| 435 | | -clunk_fid: |
|---|
| 436 | | - v9fs_t_clunk(v9ses, nfid); |
|---|
| 437 | | - |
|---|
| 438 | | -error: |
|---|
| 439 | | - kfree(fcall); |
|---|
| 440 | | - return ERR_PTR(err); |
|---|
| 441 | | -} |
|---|
| 442 | | -*/ |
|---|
| 443 | | - |
|---|
| 444 | | - |
|---|
| 445 | 370 | /** |
|---|
| 446 | 371 | * v9fs_clear_inode - release an inode |
|---|
| 447 | 372 | * @inode: inode to release |
|---|
| .. | .. |
|---|
| 473 | 398 | |
|---|
| 474 | 399 | umode = p9mode2unixmode(v9ses, st, &rdev); |
|---|
| 475 | 400 | /* don't match inode of different type */ |
|---|
| 476 | | - if ((inode->i_mode & S_IFMT) != (umode & S_IFMT)) |
|---|
| 401 | + if (inode_wrong_type(inode, umode)) |
|---|
| 477 | 402 | return 0; |
|---|
| 478 | 403 | |
|---|
| 479 | 404 | /* compare qid details */ |
|---|
| .. | .. |
|---|
| 1111 | 1036 | { |
|---|
| 1112 | 1037 | int retval; |
|---|
| 1113 | 1038 | struct v9fs_session_info *v9ses; |
|---|
| 1114 | | - struct p9_fid *fid; |
|---|
| 1039 | + struct p9_fid *fid = NULL; |
|---|
| 1115 | 1040 | struct p9_wstat wstat; |
|---|
| 1116 | 1041 | |
|---|
| 1117 | 1042 | p9_debug(P9_DEBUG_VFS, "\n"); |
|---|
| .. | .. |
|---|
| 1121 | 1046 | |
|---|
| 1122 | 1047 | retval = -EPERM; |
|---|
| 1123 | 1048 | v9ses = v9fs_dentry2v9ses(dentry); |
|---|
| 1124 | | - fid = v9fs_fid_lookup(dentry); |
|---|
| 1049 | + if (iattr->ia_valid & ATTR_FILE) { |
|---|
| 1050 | + fid = iattr->ia_file->private_data; |
|---|
| 1051 | + WARN_ON(!fid); |
|---|
| 1052 | + } |
|---|
| 1053 | + if (!fid) |
|---|
| 1054 | + fid = v9fs_fid_lookup(dentry); |
|---|
| 1125 | 1055 | if(IS_ERR(fid)) |
|---|
| 1126 | 1056 | return PTR_ERR(fid); |
|---|
| 1127 | 1057 | |
|---|
| .. | .. |
|---|
| 1430 | 1360 | * Don't update inode if the file type is different |
|---|
| 1431 | 1361 | */ |
|---|
| 1432 | 1362 | umode = p9mode2unixmode(v9ses, st, &rdev); |
|---|
| 1433 | | - if ((inode->i_mode & S_IFMT) != (umode & S_IFMT)) |
|---|
| 1363 | + if (inode_wrong_type(inode, umode)) |
|---|
| 1434 | 1364 | goto out; |
|---|
| 1435 | 1365 | |
|---|
| 1436 | 1366 | /* |
|---|