1e5e5558eSMiklos Szeredi /* 2e5e5558eSMiklos Szeredi FUSE: Filesystem in Userspace 31729a16cSMiklos Szeredi Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> 4e5e5558eSMiklos Szeredi 5e5e5558eSMiklos Szeredi This program can be distributed under the terms of the GNU GPL. 6e5e5558eSMiklos Szeredi See the file COPYING. 7e5e5558eSMiklos Szeredi */ 8e5e5558eSMiklos Szeredi 9e5e5558eSMiklos Szeredi #include "fuse_i.h" 10e5e5558eSMiklos Szeredi 11e5e5558eSMiklos Szeredi #include <linux/pagemap.h> 12e5e5558eSMiklos Szeredi #include <linux/file.h> 13e5e5558eSMiklos Szeredi #include <linux/sched.h> 14e5e5558eSMiklos Szeredi #include <linux/namei.h> 1507e77dcaSMiklos Szeredi #include <linux/slab.h> 16703c7362SSeth Forshee #include <linux/xattr.h> 17261aaba7SMiklos Szeredi #include <linux/iversion.h> 1860bcc88aSSeth Forshee #include <linux/posix_acl.h> 19e5e5558eSMiklos Szeredi 204582a4abSFeng Shuo static void fuse_advise_use_readdirplus(struct inode *dir) 214582a4abSFeng Shuo { 224582a4abSFeng Shuo struct fuse_inode *fi = get_fuse_inode(dir); 234582a4abSFeng Shuo 244582a4abSFeng Shuo set_bit(FUSE_I_ADVISE_RDPLUS, &fi->state); 254582a4abSFeng Shuo } 264582a4abSFeng Shuo 2730c6a23dSKhazhismel Kumykov #if BITS_PER_LONG >= 64 2830c6a23dSKhazhismel Kumykov static inline void __fuse_dentry_settime(struct dentry *entry, u64 time) 2930c6a23dSKhazhismel Kumykov { 3030c6a23dSKhazhismel Kumykov entry->d_fsdata = (void *) time; 3130c6a23dSKhazhismel Kumykov } 3230c6a23dSKhazhismel Kumykov 3330c6a23dSKhazhismel Kumykov static inline u64 fuse_dentry_time(const struct dentry *entry) 3430c6a23dSKhazhismel Kumykov { 3530c6a23dSKhazhismel Kumykov return (u64)entry->d_fsdata; 3630c6a23dSKhazhismel Kumykov } 3730c6a23dSKhazhismel Kumykov 3830c6a23dSKhazhismel Kumykov #else 39f75fdf22SMiklos Szeredi union fuse_dentry { 40f75fdf22SMiklos Szeredi u64 time; 41f75fdf22SMiklos Szeredi struct rcu_head rcu; 42f75fdf22SMiklos Szeredi }; 43f75fdf22SMiklos Szeredi 4430c6a23dSKhazhismel Kumykov static inline void __fuse_dentry_settime(struct dentry *dentry, u64 time) 4530c6a23dSKhazhismel Kumykov { 4630c6a23dSKhazhismel Kumykov ((union fuse_dentry *) dentry->d_fsdata)->time = time; 4730c6a23dSKhazhismel Kumykov } 4830c6a23dSKhazhismel Kumykov 4930c6a23dSKhazhismel Kumykov static inline u64 fuse_dentry_time(const struct dentry *entry) 5030c6a23dSKhazhismel Kumykov { 5130c6a23dSKhazhismel Kumykov return ((union fuse_dentry *) entry->d_fsdata)->time; 5230c6a23dSKhazhismel Kumykov } 5330c6a23dSKhazhismel Kumykov #endif 5430c6a23dSKhazhismel Kumykov 558fab0106SMiklos Szeredi static void fuse_dentry_settime(struct dentry *dentry, u64 time) 560a0898cfSMiklos Szeredi { 578fab0106SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn_super(dentry->d_sb); 588fab0106SMiklos Szeredi bool delete = !time && fc->delete_stale; 598fab0106SMiklos Szeredi /* 608fab0106SMiklos Szeredi * Mess with DCACHE_OP_DELETE because dput() will be faster without it. 618fab0106SMiklos Szeredi * Don't care about races, either way it's just an optimization 628fab0106SMiklos Szeredi */ 638fab0106SMiklos Szeredi if ((!delete && (dentry->d_flags & DCACHE_OP_DELETE)) || 648fab0106SMiklos Szeredi (delete && !(dentry->d_flags & DCACHE_OP_DELETE))) { 658fab0106SMiklos Szeredi spin_lock(&dentry->d_lock); 668fab0106SMiklos Szeredi if (!delete) 678fab0106SMiklos Szeredi dentry->d_flags &= ~DCACHE_OP_DELETE; 688fab0106SMiklos Szeredi else 698fab0106SMiklos Szeredi dentry->d_flags |= DCACHE_OP_DELETE; 708fab0106SMiklos Szeredi spin_unlock(&dentry->d_lock); 710a0898cfSMiklos Szeredi } 720a0898cfSMiklos Szeredi 7330c6a23dSKhazhismel Kumykov __fuse_dentry_settime(dentry, time); 740a0898cfSMiklos Szeredi } 750a0898cfSMiklos Szeredi 766f9f1180SMiklos Szeredi /* 776f9f1180SMiklos Szeredi * FUSE caches dentries and attributes with separate timeout. The 786f9f1180SMiklos Szeredi * time in jiffies until the dentry/attributes are valid is stored in 79f75fdf22SMiklos Szeredi * dentry->d_fsdata and fuse_inode->i_time respectively. 806f9f1180SMiklos Szeredi */ 816f9f1180SMiklos Szeredi 826f9f1180SMiklos Szeredi /* 836f9f1180SMiklos Szeredi * Calculate the time in jiffies until a dentry/attributes are valid 846f9f1180SMiklos Szeredi */ 85bcb6f6d2SMiklos Szeredi static u64 time_to_jiffies(u64 sec, u32 nsec) 86e5e5558eSMiklos Szeredi { 87685d16ddSMiklos Szeredi if (sec || nsec) { 88bcb6f6d2SMiklos Szeredi struct timespec64 ts = { 89bcb6f6d2SMiklos Szeredi sec, 9021067527SDavid Sheets min_t(u32, nsec, NSEC_PER_SEC - 1) 91bcb6f6d2SMiklos Szeredi }; 92bcb6f6d2SMiklos Szeredi 93bcb6f6d2SMiklos Szeredi return get_jiffies_64() + timespec64_to_jiffies(&ts); 94685d16ddSMiklos Szeredi } else 950a0898cfSMiklos Szeredi return 0; 96e5e5558eSMiklos Szeredi } 97e5e5558eSMiklos Szeredi 986f9f1180SMiklos Szeredi /* 996f9f1180SMiklos Szeredi * Set dentry and possibly attribute timeouts from the lookup/mk* 1006f9f1180SMiklos Szeredi * replies 1016f9f1180SMiklos Szeredi */ 102d123d8e1SMiklos Szeredi void fuse_change_entry_timeout(struct dentry *entry, struct fuse_entry_out *o) 1030aa7c699SMiklos Szeredi { 1040a0898cfSMiklos Szeredi fuse_dentry_settime(entry, 1050a0898cfSMiklos Szeredi time_to_jiffies(o->entry_valid, o->entry_valid_nsec)); 1061fb69e78SMiklos Szeredi } 1071fb69e78SMiklos Szeredi 1081fb69e78SMiklos Szeredi static u64 attr_timeout(struct fuse_attr_out *o) 1091fb69e78SMiklos Szeredi { 1101fb69e78SMiklos Szeredi return time_to_jiffies(o->attr_valid, o->attr_valid_nsec); 1111fb69e78SMiklos Szeredi } 1121fb69e78SMiklos Szeredi 113d123d8e1SMiklos Szeredi u64 entry_attr_timeout(struct fuse_entry_out *o) 1141fb69e78SMiklos Szeredi { 1151fb69e78SMiklos Szeredi return time_to_jiffies(o->attr_valid, o->attr_valid_nsec); 1168cbdf1e6SMiklos Szeredi } 1178cbdf1e6SMiklos Szeredi 1182f1e8196SMiklos Szeredi static void fuse_invalidate_attr_mask(struct inode *inode, u32 mask) 1192f1e8196SMiklos Szeredi { 1202f1e8196SMiklos Szeredi set_mask_bits(&get_fuse_inode(inode)->inval_mask, 0, mask); 1212f1e8196SMiklos Szeredi } 1222f1e8196SMiklos Szeredi 1236f9f1180SMiklos Szeredi /* 1246f9f1180SMiklos Szeredi * Mark the attributes as stale, so that at the next call to 1256f9f1180SMiklos Szeredi * ->getattr() they will be fetched from userspace 1266f9f1180SMiklos Szeredi */ 1278cbdf1e6SMiklos Szeredi void fuse_invalidate_attr(struct inode *inode) 1288cbdf1e6SMiklos Szeredi { 1292f1e8196SMiklos Szeredi fuse_invalidate_attr_mask(inode, STATX_BASIC_STATS); 1308cbdf1e6SMiklos Szeredi } 1318cbdf1e6SMiklos Szeredi 132261aaba7SMiklos Szeredi static void fuse_dir_changed(struct inode *dir) 133261aaba7SMiklos Szeredi { 134261aaba7SMiklos Szeredi fuse_invalidate_attr(dir); 135261aaba7SMiklos Szeredi inode_maybe_inc_iversion(dir, false); 136261aaba7SMiklos Szeredi } 137261aaba7SMiklos Szeredi 138451418fcSAndrew Gallagher /** 139451418fcSAndrew Gallagher * Mark the attributes as stale due to an atime change. Avoid the invalidate if 140451418fcSAndrew Gallagher * atime is not used. 141451418fcSAndrew Gallagher */ 142451418fcSAndrew Gallagher void fuse_invalidate_atime(struct inode *inode) 143451418fcSAndrew Gallagher { 144451418fcSAndrew Gallagher if (!IS_RDONLY(inode)) 1452f1e8196SMiklos Szeredi fuse_invalidate_attr_mask(inode, STATX_ATIME); 146451418fcSAndrew Gallagher } 147451418fcSAndrew Gallagher 1486f9f1180SMiklos Szeredi /* 1496f9f1180SMiklos Szeredi * Just mark the entry as stale, so that a next attempt to look it up 1506f9f1180SMiklos Szeredi * will result in a new lookup call to userspace 1516f9f1180SMiklos Szeredi * 1526f9f1180SMiklos Szeredi * This is called when a dentry is about to become negative and the 1536f9f1180SMiklos Szeredi * timeout is unknown (unlink, rmdir, rename and in some cases 1546f9f1180SMiklos Szeredi * lookup) 1556f9f1180SMiklos Szeredi */ 156dbd561d2SMiklos Szeredi void fuse_invalidate_entry_cache(struct dentry *entry) 1578cbdf1e6SMiklos Szeredi { 1580a0898cfSMiklos Szeredi fuse_dentry_settime(entry, 0); 1598cbdf1e6SMiklos Szeredi } 1608cbdf1e6SMiklos Szeredi 1616f9f1180SMiklos Szeredi /* 1626f9f1180SMiklos Szeredi * Same as fuse_invalidate_entry_cache(), but also try to remove the 1636f9f1180SMiklos Szeredi * dentry from the hash 1646f9f1180SMiklos Szeredi */ 1658cbdf1e6SMiklos Szeredi static void fuse_invalidate_entry(struct dentry *entry) 1668cbdf1e6SMiklos Szeredi { 1678cbdf1e6SMiklos Szeredi d_invalidate(entry); 1688cbdf1e6SMiklos Szeredi fuse_invalidate_entry_cache(entry); 1690aa7c699SMiklos Szeredi } 1700aa7c699SMiklos Szeredi 1717078187aSMiklos Szeredi static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_args *args, 17213983d06SAl Viro u64 nodeid, const struct qstr *name, 173e5e5558eSMiklos Szeredi struct fuse_entry_out *outarg) 174e5e5558eSMiklos Szeredi { 1750e9663eeSMiklos Szeredi memset(outarg, 0, sizeof(struct fuse_entry_out)); 176d5b48543SMiklos Szeredi args->opcode = FUSE_LOOKUP; 177d5b48543SMiklos Szeredi args->nodeid = nodeid; 178d5b48543SMiklos Szeredi args->in_numargs = 1; 179d5b48543SMiklos Szeredi args->in_args[0].size = name->len + 1; 180d5b48543SMiklos Szeredi args->in_args[0].value = name->name; 181d5b48543SMiklos Szeredi args->out_numargs = 1; 182d5b48543SMiklos Szeredi args->out_args[0].size = sizeof(struct fuse_entry_out); 183d5b48543SMiklos Szeredi args->out_args[0].value = outarg; 184e5e5558eSMiklos Szeredi } 185e5e5558eSMiklos Szeredi 1866f9f1180SMiklos Szeredi /* 1876f9f1180SMiklos Szeredi * Check whether the dentry is still valid 1886f9f1180SMiklos Szeredi * 1896f9f1180SMiklos Szeredi * If the entry validity timeout has expired and the dentry is 1906f9f1180SMiklos Szeredi * positive, try to redo the lookup. If the lookup results in a 1916f9f1180SMiklos Szeredi * different inode, then let the VFS invalidate the dentry and redo 1926f9f1180SMiklos Szeredi * the lookup once more. If the lookup results in the same inode, 1936f9f1180SMiklos Szeredi * then refresh the attributes, timeouts and mark the dentry valid. 1946f9f1180SMiklos Szeredi */ 1950b728e19SAl Viro static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags) 196e5e5558eSMiklos Szeredi { 19734286d66SNick Piggin struct inode *inode; 19828420dadSMiklos Szeredi struct dentry *parent; 19928420dadSMiklos Szeredi struct fuse_conn *fc; 2006314efeeSMiklos Szeredi struct fuse_inode *fi; 201e2a6b952SMiklos Szeredi int ret; 2028cbdf1e6SMiklos Szeredi 2032b0143b5SDavid Howells inode = d_inode_rcu(entry); 2048cbdf1e6SMiklos Szeredi if (inode && is_bad_inode(inode)) 205e2a6b952SMiklos Szeredi goto invalid; 206154210ccSAnand Avati else if (time_before64(fuse_dentry_time(entry), get_jiffies_64()) || 207154210ccSAnand Avati (flags & LOOKUP_REVAL)) { 208e5e5558eSMiklos Szeredi struct fuse_entry_out outarg; 2097078187aSMiklos Szeredi FUSE_ARGS(args); 21007e77dcaSMiklos Szeredi struct fuse_forget_link *forget; 2111fb69e78SMiklos Szeredi u64 attr_version; 2128cbdf1e6SMiklos Szeredi 21350322fe7SMiklos Szeredi /* For negative dentries, always do a fresh lookup */ 2148cbdf1e6SMiklos Szeredi if (!inode) 215e2a6b952SMiklos Szeredi goto invalid; 2168cbdf1e6SMiklos Szeredi 217e2a6b952SMiklos Szeredi ret = -ECHILD; 2180b728e19SAl Viro if (flags & LOOKUP_RCU) 219e2a6b952SMiklos Szeredi goto out; 220e7c0a167SMiklos Szeredi 2218cbdf1e6SMiklos Szeredi fc = get_fuse_conn(inode); 222e5e5558eSMiklos Szeredi 22307e77dcaSMiklos Szeredi forget = fuse_alloc_forget(); 224e2a6b952SMiklos Szeredi ret = -ENOMEM; 2257078187aSMiklos Szeredi if (!forget) 226e2a6b952SMiklos Szeredi goto out; 2272d51013eSMiklos Szeredi 2287dca9fd3SMiklos Szeredi attr_version = fuse_get_attr_version(fc); 2291fb69e78SMiklos Szeredi 230e956edd0SMiklos Szeredi parent = dget_parent(entry); 2312b0143b5SDavid Howells fuse_lookup_init(fc, &args, get_node_id(d_inode(parent)), 232c180eebeSMiklos Szeredi &entry->d_name, &outarg); 2337078187aSMiklos Szeredi ret = fuse_simple_request(fc, &args); 234e956edd0SMiklos Szeredi dput(parent); 23550322fe7SMiklos Szeredi /* Zero nodeid is same as -ENOENT */ 2367078187aSMiklos Szeredi if (!ret && !outarg.nodeid) 2377078187aSMiklos Szeredi ret = -ENOENT; 2387078187aSMiklos Szeredi if (!ret) { 2396314efeeSMiklos Szeredi fi = get_fuse_inode(inode); 2409e6268dbSMiklos Szeredi if (outarg.nodeid != get_node_id(inode)) { 24107e77dcaSMiklos Szeredi fuse_queue_forget(fc, forget, outarg.nodeid, 1); 242e2a6b952SMiklos Szeredi goto invalid; 2439e6268dbSMiklos Szeredi } 244c9d8f5f0SKirill Tkhai spin_lock(&fi->lock); 2459e6268dbSMiklos Szeredi fi->nlookup++; 246c9d8f5f0SKirill Tkhai spin_unlock(&fi->lock); 2479e6268dbSMiklos Szeredi } 24807e77dcaSMiklos Szeredi kfree(forget); 2497078187aSMiklos Szeredi if (ret == -ENOMEM) 2507078187aSMiklos Szeredi goto out; 2517078187aSMiklos Szeredi if (ret || (outarg.attr.mode ^ inode->i_mode) & S_IFMT) 252e2a6b952SMiklos Szeredi goto invalid; 253e5e5558eSMiklos Szeredi 25460bcc88aSSeth Forshee forget_all_cached_acls(inode); 2551fb69e78SMiklos Szeredi fuse_change_attributes(inode, &outarg.attr, 2561fb69e78SMiklos Szeredi entry_attr_timeout(&outarg), 2571fb69e78SMiklos Szeredi attr_version); 2581fb69e78SMiklos Szeredi fuse_change_entry_timeout(entry, &outarg); 25928420dadSMiklos Szeredi } else if (inode) { 2606314efeeSMiklos Szeredi fi = get_fuse_inode(inode); 2616314efeeSMiklos Szeredi if (flags & LOOKUP_RCU) { 2626314efeeSMiklos Szeredi if (test_bit(FUSE_I_INIT_RDPLUS, &fi->state)) 2636314efeeSMiklos Szeredi return -ECHILD; 2646314efeeSMiklos Szeredi } else if (test_and_clear_bit(FUSE_I_INIT_RDPLUS, &fi->state)) { 26528420dadSMiklos Szeredi parent = dget_parent(entry); 2662b0143b5SDavid Howells fuse_advise_use_readdirplus(d_inode(parent)); 26728420dadSMiklos Szeredi dput(parent); 268e5e5558eSMiklos Szeredi } 26928420dadSMiklos Szeredi } 270e2a6b952SMiklos Szeredi ret = 1; 271e2a6b952SMiklos Szeredi out: 272e2a6b952SMiklos Szeredi return ret; 273e2a6b952SMiklos Szeredi 274e2a6b952SMiklos Szeredi invalid: 275e2a6b952SMiklos Szeredi ret = 0; 276e2a6b952SMiklos Szeredi goto out; 277e5e5558eSMiklos Szeredi } 278e5e5558eSMiklos Szeredi 27930c6a23dSKhazhismel Kumykov #if BITS_PER_LONG < 64 280f75fdf22SMiklos Szeredi static int fuse_dentry_init(struct dentry *dentry) 281f75fdf22SMiklos Szeredi { 282dc69e98cSKhazhismel Kumykov dentry->d_fsdata = kzalloc(sizeof(union fuse_dentry), 283dc69e98cSKhazhismel Kumykov GFP_KERNEL_ACCOUNT | __GFP_RECLAIMABLE); 284f75fdf22SMiklos Szeredi 285f75fdf22SMiklos Szeredi return dentry->d_fsdata ? 0 : -ENOMEM; 286f75fdf22SMiklos Szeredi } 287f75fdf22SMiklos Szeredi static void fuse_dentry_release(struct dentry *dentry) 288f75fdf22SMiklos Szeredi { 289f75fdf22SMiklos Szeredi union fuse_dentry *fd = dentry->d_fsdata; 290f75fdf22SMiklos Szeredi 291f75fdf22SMiklos Szeredi kfree_rcu(fd, rcu); 292f75fdf22SMiklos Szeredi } 29330c6a23dSKhazhismel Kumykov #endif 294f75fdf22SMiklos Szeredi 2958fab0106SMiklos Szeredi static int fuse_dentry_delete(const struct dentry *dentry) 2968fab0106SMiklos Szeredi { 2978fab0106SMiklos Szeredi return time_before64(fuse_dentry_time(dentry), get_jiffies_64()); 2988fab0106SMiklos Szeredi } 2998fab0106SMiklos Szeredi 3004269590aSAl Viro const struct dentry_operations fuse_dentry_operations = { 301e5e5558eSMiklos Szeredi .d_revalidate = fuse_dentry_revalidate, 3028fab0106SMiklos Szeredi .d_delete = fuse_dentry_delete, 30330c6a23dSKhazhismel Kumykov #if BITS_PER_LONG < 64 304f75fdf22SMiklos Szeredi .d_init = fuse_dentry_init, 305f75fdf22SMiklos Szeredi .d_release = fuse_dentry_release, 30630c6a23dSKhazhismel Kumykov #endif 307e5e5558eSMiklos Szeredi }; 308e5e5558eSMiklos Szeredi 3090ce267ffSMiklos Szeredi const struct dentry_operations fuse_root_dentry_operations = { 31030c6a23dSKhazhismel Kumykov #if BITS_PER_LONG < 64 3110ce267ffSMiklos Szeredi .d_init = fuse_dentry_init, 3120ce267ffSMiklos Szeredi .d_release = fuse_dentry_release, 31330c6a23dSKhazhismel Kumykov #endif 3140ce267ffSMiklos Szeredi }; 3150ce267ffSMiklos Szeredi 316a5bfffacSTimo Savola int fuse_valid_type(int m) 31739ee059aSMiklos Szeredi { 31839ee059aSMiklos Szeredi return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) || 31939ee059aSMiklos Szeredi S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m); 32039ee059aSMiklos Szeredi } 32139ee059aSMiklos Szeredi 32213983d06SAl Viro int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name, 323c180eebeSMiklos Szeredi struct fuse_entry_out *outarg, struct inode **inode) 324c180eebeSMiklos Szeredi { 325c180eebeSMiklos Szeredi struct fuse_conn *fc = get_fuse_conn_super(sb); 3267078187aSMiklos Szeredi FUSE_ARGS(args); 32707e77dcaSMiklos Szeredi struct fuse_forget_link *forget; 328c180eebeSMiklos Szeredi u64 attr_version; 329c180eebeSMiklos Szeredi int err; 330c180eebeSMiklos Szeredi 331c180eebeSMiklos Szeredi *inode = NULL; 332c180eebeSMiklos Szeredi err = -ENAMETOOLONG; 333c180eebeSMiklos Szeredi if (name->len > FUSE_NAME_MAX) 334c180eebeSMiklos Szeredi goto out; 335c180eebeSMiklos Szeredi 336c180eebeSMiklos Szeredi 33707e77dcaSMiklos Szeredi forget = fuse_alloc_forget(); 33807e77dcaSMiklos Szeredi err = -ENOMEM; 3397078187aSMiklos Szeredi if (!forget) 340c180eebeSMiklos Szeredi goto out; 341c180eebeSMiklos Szeredi 342c180eebeSMiklos Szeredi attr_version = fuse_get_attr_version(fc); 343c180eebeSMiklos Szeredi 3447078187aSMiklos Szeredi fuse_lookup_init(fc, &args, nodeid, name, outarg); 3457078187aSMiklos Szeredi err = fuse_simple_request(fc, &args); 346c180eebeSMiklos Szeredi /* Zero nodeid is same as -ENOENT, but with valid timeout */ 347c180eebeSMiklos Szeredi if (err || !outarg->nodeid) 348c180eebeSMiklos Szeredi goto out_put_forget; 349c180eebeSMiklos Szeredi 350c180eebeSMiklos Szeredi err = -EIO; 351c180eebeSMiklos Szeredi if (!outarg->nodeid) 352c180eebeSMiklos Szeredi goto out_put_forget; 353c180eebeSMiklos Szeredi if (!fuse_valid_type(outarg->attr.mode)) 354c180eebeSMiklos Szeredi goto out_put_forget; 355c180eebeSMiklos Szeredi 356c180eebeSMiklos Szeredi *inode = fuse_iget(sb, outarg->nodeid, outarg->generation, 357c180eebeSMiklos Szeredi &outarg->attr, entry_attr_timeout(outarg), 358c180eebeSMiklos Szeredi attr_version); 359c180eebeSMiklos Szeredi err = -ENOMEM; 360c180eebeSMiklos Szeredi if (!*inode) { 36107e77dcaSMiklos Szeredi fuse_queue_forget(fc, forget, outarg->nodeid, 1); 362c180eebeSMiklos Szeredi goto out; 363c180eebeSMiklos Szeredi } 364c180eebeSMiklos Szeredi err = 0; 365c180eebeSMiklos Szeredi 366c180eebeSMiklos Szeredi out_put_forget: 36707e77dcaSMiklos Szeredi kfree(forget); 368c180eebeSMiklos Szeredi out: 369c180eebeSMiklos Szeredi return err; 370c180eebeSMiklos Szeredi } 371c180eebeSMiklos Szeredi 3720aa7c699SMiklos Szeredi static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, 37300cd8dd3SAl Viro unsigned int flags) 374e5e5558eSMiklos Szeredi { 375e5e5558eSMiklos Szeredi int err; 376e5e5558eSMiklos Szeredi struct fuse_entry_out outarg; 377c180eebeSMiklos Szeredi struct inode *inode; 3780de6256dSMiklos Szeredi struct dentry *newent; 379c180eebeSMiklos Szeredi bool outarg_valid = true; 38063576c13SMiklos Szeredi bool locked; 381e5e5558eSMiklos Szeredi 38263576c13SMiklos Szeredi locked = fuse_lock_inode(dir); 383c180eebeSMiklos Szeredi err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name, 384c180eebeSMiklos Szeredi &outarg, &inode); 38563576c13SMiklos Szeredi fuse_unlock_inode(dir, locked); 386c180eebeSMiklos Szeredi if (err == -ENOENT) { 387c180eebeSMiklos Szeredi outarg_valid = false; 388c180eebeSMiklos Szeredi err = 0; 3892d51013eSMiklos Szeredi } 390c180eebeSMiklos Szeredi if (err) 391c180eebeSMiklos Szeredi goto out_err; 3922d51013eSMiklos Szeredi 393ee4e5271SMiklos Szeredi err = -EIO; 394c180eebeSMiklos Szeredi if (inode && get_node_id(inode) == FUSE_ROOT_ID) 395c180eebeSMiklos Szeredi goto out_iput; 396e5e5558eSMiklos Szeredi 39741d28bcaSAl Viro newent = d_splice_alias(inode, entry); 398c180eebeSMiklos Szeredi err = PTR_ERR(newent); 399c180eebeSMiklos Szeredi if (IS_ERR(newent)) 4005835f339SMiklos Szeredi goto out_err; 401d2a85164SMiklos Szeredi 4020de6256dSMiklos Szeredi entry = newent ? newent : entry; 403c180eebeSMiklos Szeredi if (outarg_valid) 4041fb69e78SMiklos Szeredi fuse_change_entry_timeout(entry, &outarg); 4058cbdf1e6SMiklos Szeredi else 4068cbdf1e6SMiklos Szeredi fuse_invalidate_entry_cache(entry); 407c180eebeSMiklos Szeredi 4086c26f717SMiklos Szeredi if (inode) 4094582a4abSFeng Shuo fuse_advise_use_readdirplus(dir); 4100de6256dSMiklos Szeredi return newent; 411c180eebeSMiklos Szeredi 412c180eebeSMiklos Szeredi out_iput: 413c180eebeSMiklos Szeredi iput(inode); 414c180eebeSMiklos Szeredi out_err: 415c180eebeSMiklos Szeredi return ERR_PTR(err); 416e5e5558eSMiklos Szeredi } 417e5e5558eSMiklos Szeredi 4186f9f1180SMiklos Szeredi /* 4196f9f1180SMiklos Szeredi * Atomic create+open operation 4206f9f1180SMiklos Szeredi * 4216f9f1180SMiklos Szeredi * If the filesystem doesn't support this, then fall back to separate 4226f9f1180SMiklos Szeredi * 'mknod' + 'open' requests. 4236f9f1180SMiklos Szeredi */ 424d9585277SAl Viro static int fuse_create_open(struct inode *dir, struct dentry *entry, 42530d90494SAl Viro struct file *file, unsigned flags, 426b452a458SAl Viro umode_t mode) 427fd72faacSMiklos Szeredi { 428fd72faacSMiklos Szeredi int err; 429fd72faacSMiklos Szeredi struct inode *inode; 430fd72faacSMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(dir); 4317078187aSMiklos Szeredi FUSE_ARGS(args); 43207e77dcaSMiklos Szeredi struct fuse_forget_link *forget; 433e0a43ddcSMiklos Szeredi struct fuse_create_in inarg; 434fd72faacSMiklos Szeredi struct fuse_open_out outopen; 435fd72faacSMiklos Szeredi struct fuse_entry_out outentry; 436ebf84d0cSKirill Tkhai struct fuse_inode *fi; 437fd72faacSMiklos Szeredi struct fuse_file *ff; 438fd72faacSMiklos Szeredi 439af109bcaSMiklos Szeredi /* Userspace expects S_IFREG in create mode */ 440af109bcaSMiklos Szeredi BUG_ON((mode & S_IFMT) != S_IFREG); 441af109bcaSMiklos Szeredi 44207e77dcaSMiklos Szeredi forget = fuse_alloc_forget(); 443c8ccbe03SMiklos Szeredi err = -ENOMEM; 44407e77dcaSMiklos Szeredi if (!forget) 445c8ccbe03SMiklos Szeredi goto out_err; 44651eb01e7SMiklos Szeredi 447ce1d5a49SMiklos Szeredi err = -ENOMEM; 448acf99433STejun Heo ff = fuse_file_alloc(fc); 449fd72faacSMiklos Szeredi if (!ff) 4507078187aSMiklos Szeredi goto out_put_forget_req; 451fd72faacSMiklos Szeredi 452e0a43ddcSMiklos Szeredi if (!fc->dont_mask) 453e0a43ddcSMiklos Szeredi mode &= ~current_umask(); 454e0a43ddcSMiklos Szeredi 455fd72faacSMiklos Szeredi flags &= ~O_NOCTTY; 456fd72faacSMiklos Szeredi memset(&inarg, 0, sizeof(inarg)); 4570e9663eeSMiklos Szeredi memset(&outentry, 0, sizeof(outentry)); 458fd72faacSMiklos Szeredi inarg.flags = flags; 459fd72faacSMiklos Szeredi inarg.mode = mode; 460e0a43ddcSMiklos Szeredi inarg.umask = current_umask(); 461d5b48543SMiklos Szeredi args.opcode = FUSE_CREATE; 462d5b48543SMiklos Szeredi args.nodeid = get_node_id(dir); 463d5b48543SMiklos Szeredi args.in_numargs = 2; 464d5b48543SMiklos Szeredi args.in_args[0].size = sizeof(inarg); 465d5b48543SMiklos Szeredi args.in_args[0].value = &inarg; 466d5b48543SMiklos Szeredi args.in_args[1].size = entry->d_name.len + 1; 467d5b48543SMiklos Szeredi args.in_args[1].value = entry->d_name.name; 468d5b48543SMiklos Szeredi args.out_numargs = 2; 469d5b48543SMiklos Szeredi args.out_args[0].size = sizeof(outentry); 470d5b48543SMiklos Szeredi args.out_args[0].value = &outentry; 471d5b48543SMiklos Szeredi args.out_args[1].size = sizeof(outopen); 472d5b48543SMiklos Szeredi args.out_args[1].value = &outopen; 4737078187aSMiklos Szeredi err = fuse_simple_request(fc, &args); 474c8ccbe03SMiklos Szeredi if (err) 475fd72faacSMiklos Szeredi goto out_free_ff; 476fd72faacSMiklos Szeredi 477fd72faacSMiklos Szeredi err = -EIO; 4782827d0b2SMiklos Szeredi if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid)) 479fd72faacSMiklos Szeredi goto out_free_ff; 480fd72faacSMiklos Szeredi 481c7b7143cSMiklos Szeredi ff->fh = outopen.fh; 482c7b7143cSMiklos Szeredi ff->nodeid = outentry.nodeid; 483c7b7143cSMiklos Szeredi ff->open_flags = outopen.open_flags; 484fd72faacSMiklos Szeredi inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation, 4851fb69e78SMiklos Szeredi &outentry.attr, entry_attr_timeout(&outentry), 0); 486fd72faacSMiklos Szeredi if (!inode) { 487fd72faacSMiklos Szeredi flags &= ~(O_CREAT | O_EXCL | O_TRUNC); 488ebf84d0cSKirill Tkhai fuse_sync_release(NULL, ff, flags); 48907e77dcaSMiklos Szeredi fuse_queue_forget(fc, forget, outentry.nodeid, 1); 490c8ccbe03SMiklos Szeredi err = -ENOMEM; 491c8ccbe03SMiklos Szeredi goto out_err; 492fd72faacSMiklos Szeredi } 49307e77dcaSMiklos Szeredi kfree(forget); 494fd72faacSMiklos Szeredi d_instantiate(entry, inode); 4951fb69e78SMiklos Szeredi fuse_change_entry_timeout(entry, &outentry); 496261aaba7SMiklos Szeredi fuse_dir_changed(dir); 497be12af3eSAl Viro err = finish_open(file, entry, generic_file_open); 49830d90494SAl Viro if (err) { 499ebf84d0cSKirill Tkhai fi = get_fuse_inode(inode); 500ebf84d0cSKirill Tkhai fuse_sync_release(fi, ff, flags); 501c8ccbe03SMiklos Szeredi } else { 502267d8444SMiklos Szeredi file->private_data = ff; 503c7b7143cSMiklos Szeredi fuse_finish_open(inode, file); 504c8ccbe03SMiklos Szeredi } 505d9585277SAl Viro return err; 506fd72faacSMiklos Szeredi 507fd72faacSMiklos Szeredi out_free_ff: 508fd72faacSMiklos Szeredi fuse_file_free(ff); 50951eb01e7SMiklos Szeredi out_put_forget_req: 51007e77dcaSMiklos Szeredi kfree(forget); 511c8ccbe03SMiklos Szeredi out_err: 512d9585277SAl Viro return err; 513c8ccbe03SMiklos Szeredi } 514c8ccbe03SMiklos Szeredi 515c8ccbe03SMiklos Szeredi static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t); 516d9585277SAl Viro static int fuse_atomic_open(struct inode *dir, struct dentry *entry, 51730d90494SAl Viro struct file *file, unsigned flags, 51844907d79SAl Viro umode_t mode) 519c8ccbe03SMiklos Szeredi { 520c8ccbe03SMiklos Szeredi int err; 521c8ccbe03SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(dir); 522c8ccbe03SMiklos Szeredi struct dentry *res = NULL; 523c8ccbe03SMiklos Szeredi 52400699ad8SAl Viro if (d_in_lookup(entry)) { 52500cd8dd3SAl Viro res = fuse_lookup(dir, entry, 0); 526c8ccbe03SMiklos Szeredi if (IS_ERR(res)) 527d9585277SAl Viro return PTR_ERR(res); 528c8ccbe03SMiklos Szeredi 529c8ccbe03SMiklos Szeredi if (res) 530c8ccbe03SMiklos Szeredi entry = res; 531c8ccbe03SMiklos Szeredi } 532c8ccbe03SMiklos Szeredi 5332b0143b5SDavid Howells if (!(flags & O_CREAT) || d_really_is_positive(entry)) 534c8ccbe03SMiklos Szeredi goto no_open; 535c8ccbe03SMiklos Szeredi 536c8ccbe03SMiklos Szeredi /* Only creates */ 53773a09dd9SAl Viro file->f_mode |= FMODE_CREATED; 538c8ccbe03SMiklos Szeredi 539c8ccbe03SMiklos Szeredi if (fc->no_create) 540c8ccbe03SMiklos Szeredi goto mknod; 541c8ccbe03SMiklos Szeredi 542b452a458SAl Viro err = fuse_create_open(dir, entry, file, flags, mode); 543d9585277SAl Viro if (err == -ENOSYS) { 544c8ccbe03SMiklos Szeredi fc->no_create = 1; 545c8ccbe03SMiklos Szeredi goto mknod; 546c8ccbe03SMiklos Szeredi } 547c8ccbe03SMiklos Szeredi out_dput: 548c8ccbe03SMiklos Szeredi dput(res); 549d9585277SAl Viro return err; 550c8ccbe03SMiklos Szeredi 551c8ccbe03SMiklos Szeredi mknod: 552c8ccbe03SMiklos Szeredi err = fuse_mknod(dir, entry, mode, 0); 553d9585277SAl Viro if (err) 554c8ccbe03SMiklos Szeredi goto out_dput; 555c8ccbe03SMiklos Szeredi no_open: 556e45198a6SAl Viro return finish_no_open(file, res); 557fd72faacSMiklos Szeredi } 558fd72faacSMiklos Szeredi 5596f9f1180SMiklos Szeredi /* 5606f9f1180SMiklos Szeredi * Code shared between mknod, mkdir, symlink and link 5616f9f1180SMiklos Szeredi */ 5627078187aSMiklos Szeredi static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args, 5639e6268dbSMiklos Szeredi struct inode *dir, struct dentry *entry, 564541af6a0SAl Viro umode_t mode) 5659e6268dbSMiklos Szeredi { 5669e6268dbSMiklos Szeredi struct fuse_entry_out outarg; 5679e6268dbSMiklos Szeredi struct inode *inode; 568c971e6a0SAl Viro struct dentry *d; 5699e6268dbSMiklos Szeredi int err; 57007e77dcaSMiklos Szeredi struct fuse_forget_link *forget; 5712d51013eSMiklos Szeredi 57207e77dcaSMiklos Szeredi forget = fuse_alloc_forget(); 5737078187aSMiklos Szeredi if (!forget) 57407e77dcaSMiklos Szeredi return -ENOMEM; 5759e6268dbSMiklos Szeredi 5760e9663eeSMiklos Szeredi memset(&outarg, 0, sizeof(outarg)); 577d5b48543SMiklos Szeredi args->nodeid = get_node_id(dir); 578d5b48543SMiklos Szeredi args->out_numargs = 1; 579d5b48543SMiklos Szeredi args->out_args[0].size = sizeof(outarg); 580d5b48543SMiklos Szeredi args->out_args[0].value = &outarg; 5817078187aSMiklos Szeredi err = fuse_simple_request(fc, args); 5822d51013eSMiklos Szeredi if (err) 5832d51013eSMiklos Szeredi goto out_put_forget_req; 5842d51013eSMiklos Szeredi 58539ee059aSMiklos Szeredi err = -EIO; 58639ee059aSMiklos Szeredi if (invalid_nodeid(outarg.nodeid)) 5872d51013eSMiklos Szeredi goto out_put_forget_req; 58839ee059aSMiklos Szeredi 58939ee059aSMiklos Szeredi if ((outarg.attr.mode ^ mode) & S_IFMT) 5902d51013eSMiklos Szeredi goto out_put_forget_req; 59139ee059aSMiklos Szeredi 5929e6268dbSMiklos Szeredi inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, 5931fb69e78SMiklos Szeredi &outarg.attr, entry_attr_timeout(&outarg), 0); 5949e6268dbSMiklos Szeredi if (!inode) { 59507e77dcaSMiklos Szeredi fuse_queue_forget(fc, forget, outarg.nodeid, 1); 5969e6268dbSMiklos Szeredi return -ENOMEM; 5979e6268dbSMiklos Szeredi } 59807e77dcaSMiklos Szeredi kfree(forget); 5999e6268dbSMiklos Szeredi 600c971e6a0SAl Viro d_drop(entry); 601c971e6a0SAl Viro d = d_splice_alias(inode, entry); 602c971e6a0SAl Viro if (IS_ERR(d)) 603c971e6a0SAl Viro return PTR_ERR(d); 604d2a85164SMiklos Szeredi 605c971e6a0SAl Viro if (d) { 606c971e6a0SAl Viro fuse_change_entry_timeout(d, &outarg); 607c971e6a0SAl Viro dput(d); 608c971e6a0SAl Viro } else { 6091fb69e78SMiklos Szeredi fuse_change_entry_timeout(entry, &outarg); 610c971e6a0SAl Viro } 611261aaba7SMiklos Szeredi fuse_dir_changed(dir); 6129e6268dbSMiklos Szeredi return 0; 61339ee059aSMiklos Szeredi 6142d51013eSMiklos Szeredi out_put_forget_req: 61507e77dcaSMiklos Szeredi kfree(forget); 61639ee059aSMiklos Szeredi return err; 6179e6268dbSMiklos Szeredi } 6189e6268dbSMiklos Szeredi 6191a67aafbSAl Viro static int fuse_mknod(struct inode *dir, struct dentry *entry, umode_t mode, 6209e6268dbSMiklos Szeredi dev_t rdev) 6219e6268dbSMiklos Szeredi { 6229e6268dbSMiklos Szeredi struct fuse_mknod_in inarg; 6239e6268dbSMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(dir); 6247078187aSMiklos Szeredi FUSE_ARGS(args); 6259e6268dbSMiklos Szeredi 626e0a43ddcSMiklos Szeredi if (!fc->dont_mask) 627e0a43ddcSMiklos Szeredi mode &= ~current_umask(); 628e0a43ddcSMiklos Szeredi 6299e6268dbSMiklos Szeredi memset(&inarg, 0, sizeof(inarg)); 6309e6268dbSMiklos Szeredi inarg.mode = mode; 6319e6268dbSMiklos Szeredi inarg.rdev = new_encode_dev(rdev); 632e0a43ddcSMiklos Szeredi inarg.umask = current_umask(); 633d5b48543SMiklos Szeredi args.opcode = FUSE_MKNOD; 634d5b48543SMiklos Szeredi args.in_numargs = 2; 635d5b48543SMiklos Szeredi args.in_args[0].size = sizeof(inarg); 636d5b48543SMiklos Szeredi args.in_args[0].value = &inarg; 637d5b48543SMiklos Szeredi args.in_args[1].size = entry->d_name.len + 1; 638d5b48543SMiklos Szeredi args.in_args[1].value = entry->d_name.name; 6397078187aSMiklos Szeredi return create_new_entry(fc, &args, dir, entry, mode); 6409e6268dbSMiklos Szeredi } 6419e6268dbSMiklos Szeredi 6424acdaf27SAl Viro static int fuse_create(struct inode *dir, struct dentry *entry, umode_t mode, 643ebfc3b49SAl Viro bool excl) 6449e6268dbSMiklos Szeredi { 6459e6268dbSMiklos Szeredi return fuse_mknod(dir, entry, mode, 0); 6469e6268dbSMiklos Szeredi } 6479e6268dbSMiklos Szeredi 64818bb1db3SAl Viro static int fuse_mkdir(struct inode *dir, struct dentry *entry, umode_t mode) 6499e6268dbSMiklos Szeredi { 6509e6268dbSMiklos Szeredi struct fuse_mkdir_in inarg; 6519e6268dbSMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(dir); 6527078187aSMiklos Szeredi FUSE_ARGS(args); 6539e6268dbSMiklos Szeredi 654e0a43ddcSMiklos Szeredi if (!fc->dont_mask) 655e0a43ddcSMiklos Szeredi mode &= ~current_umask(); 656e0a43ddcSMiklos Szeredi 6579e6268dbSMiklos Szeredi memset(&inarg, 0, sizeof(inarg)); 6589e6268dbSMiklos Szeredi inarg.mode = mode; 659e0a43ddcSMiklos Szeredi inarg.umask = current_umask(); 660d5b48543SMiklos Szeredi args.opcode = FUSE_MKDIR; 661d5b48543SMiklos Szeredi args.in_numargs = 2; 662d5b48543SMiklos Szeredi args.in_args[0].size = sizeof(inarg); 663d5b48543SMiklos Szeredi args.in_args[0].value = &inarg; 664d5b48543SMiklos Szeredi args.in_args[1].size = entry->d_name.len + 1; 665d5b48543SMiklos Szeredi args.in_args[1].value = entry->d_name.name; 6667078187aSMiklos Szeredi return create_new_entry(fc, &args, dir, entry, S_IFDIR); 6679e6268dbSMiklos Szeredi } 6689e6268dbSMiklos Szeredi 6699e6268dbSMiklos Szeredi static int fuse_symlink(struct inode *dir, struct dentry *entry, 6709e6268dbSMiklos Szeredi const char *link) 6719e6268dbSMiklos Szeredi { 6729e6268dbSMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(dir); 6739e6268dbSMiklos Szeredi unsigned len = strlen(link) + 1; 6747078187aSMiklos Szeredi FUSE_ARGS(args); 6759e6268dbSMiklos Szeredi 676d5b48543SMiklos Szeredi args.opcode = FUSE_SYMLINK; 677d5b48543SMiklos Szeredi args.in_numargs = 2; 678d5b48543SMiklos Szeredi args.in_args[0].size = entry->d_name.len + 1; 679d5b48543SMiklos Szeredi args.in_args[0].value = entry->d_name.name; 680d5b48543SMiklos Szeredi args.in_args[1].size = len; 681d5b48543SMiklos Szeredi args.in_args[1].value = link; 6827078187aSMiklos Szeredi return create_new_entry(fc, &args, dir, entry, S_IFLNK); 6839e6268dbSMiklos Szeredi } 6849e6268dbSMiklos Szeredi 685703c7362SSeth Forshee void fuse_update_ctime(struct inode *inode) 68631f3267bSMaxim Patlasov { 68731f3267bSMaxim Patlasov if (!IS_NOCMTIME(inode)) { 688c2050a45SDeepa Dinamani inode->i_ctime = current_time(inode); 68931f3267bSMaxim Patlasov mark_inode_dirty_sync(inode); 69031f3267bSMaxim Patlasov } 69131f3267bSMaxim Patlasov } 69231f3267bSMaxim Patlasov 6939e6268dbSMiklos Szeredi static int fuse_unlink(struct inode *dir, struct dentry *entry) 6949e6268dbSMiklos Szeredi { 6959e6268dbSMiklos Szeredi int err; 6969e6268dbSMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(dir); 6977078187aSMiklos Szeredi FUSE_ARGS(args); 6989e6268dbSMiklos Szeredi 699d5b48543SMiklos Szeredi args.opcode = FUSE_UNLINK; 700d5b48543SMiklos Szeredi args.nodeid = get_node_id(dir); 701d5b48543SMiklos Szeredi args.in_numargs = 1; 702d5b48543SMiklos Szeredi args.in_args[0].size = entry->d_name.len + 1; 703d5b48543SMiklos Szeredi args.in_args[0].value = entry->d_name.name; 7047078187aSMiklos Szeredi err = fuse_simple_request(fc, &args); 7059e6268dbSMiklos Szeredi if (!err) { 7062b0143b5SDavid Howells struct inode *inode = d_inode(entry); 707ac45d613SMiklos Szeredi struct fuse_inode *fi = get_fuse_inode(inode); 7089e6268dbSMiklos Szeredi 709f15ecfefSKirill Tkhai spin_lock(&fi->lock); 7104510d86fSKirill Tkhai fi->attr_version = atomic64_inc_return(&fc->attr_version); 711dfca7cebSMiklos Szeredi /* 712dfca7cebSMiklos Szeredi * If i_nlink == 0 then unlink doesn't make sense, yet this can 713dfca7cebSMiklos Szeredi * happen if userspace filesystem is careless. It would be 714dfca7cebSMiklos Szeredi * difficult to enforce correct nlink usage so just ignore this 715dfca7cebSMiklos Szeredi * condition here 716dfca7cebSMiklos Szeredi */ 717dfca7cebSMiklos Szeredi if (inode->i_nlink > 0) 718ac45d613SMiklos Szeredi drop_nlink(inode); 719f15ecfefSKirill Tkhai spin_unlock(&fi->lock); 7209e6268dbSMiklos Szeredi fuse_invalidate_attr(inode); 721261aaba7SMiklos Szeredi fuse_dir_changed(dir); 7228cbdf1e6SMiklos Szeredi fuse_invalidate_entry_cache(entry); 72331f3267bSMaxim Patlasov fuse_update_ctime(inode); 7249e6268dbSMiklos Szeredi } else if (err == -EINTR) 7259e6268dbSMiklos Szeredi fuse_invalidate_entry(entry); 7269e6268dbSMiklos Szeredi return err; 7279e6268dbSMiklos Szeredi } 7289e6268dbSMiklos Szeredi 7299e6268dbSMiklos Szeredi static int fuse_rmdir(struct inode *dir, struct dentry *entry) 7309e6268dbSMiklos Szeredi { 7319e6268dbSMiklos Szeredi int err; 7329e6268dbSMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(dir); 7337078187aSMiklos Szeredi FUSE_ARGS(args); 7349e6268dbSMiklos Szeredi 735d5b48543SMiklos Szeredi args.opcode = FUSE_RMDIR; 736d5b48543SMiklos Szeredi args.nodeid = get_node_id(dir); 737d5b48543SMiklos Szeredi args.in_numargs = 1; 738d5b48543SMiklos Szeredi args.in_args[0].size = entry->d_name.len + 1; 739d5b48543SMiklos Szeredi args.in_args[0].value = entry->d_name.name; 7407078187aSMiklos Szeredi err = fuse_simple_request(fc, &args); 7419e6268dbSMiklos Szeredi if (!err) { 7422b0143b5SDavid Howells clear_nlink(d_inode(entry)); 743261aaba7SMiklos Szeredi fuse_dir_changed(dir); 7448cbdf1e6SMiklos Szeredi fuse_invalidate_entry_cache(entry); 7459e6268dbSMiklos Szeredi } else if (err == -EINTR) 7469e6268dbSMiklos Szeredi fuse_invalidate_entry(entry); 7479e6268dbSMiklos Szeredi return err; 7489e6268dbSMiklos Szeredi } 7499e6268dbSMiklos Szeredi 7501560c974SMiklos Szeredi static int fuse_rename_common(struct inode *olddir, struct dentry *oldent, 7511560c974SMiklos Szeredi struct inode *newdir, struct dentry *newent, 7521560c974SMiklos Szeredi unsigned int flags, int opcode, size_t argsize) 7539e6268dbSMiklos Szeredi { 7549e6268dbSMiklos Szeredi int err; 7551560c974SMiklos Szeredi struct fuse_rename2_in inarg; 7569e6268dbSMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(olddir); 7577078187aSMiklos Szeredi FUSE_ARGS(args); 7589e6268dbSMiklos Szeredi 7591560c974SMiklos Szeredi memset(&inarg, 0, argsize); 7609e6268dbSMiklos Szeredi inarg.newdir = get_node_id(newdir); 7611560c974SMiklos Szeredi inarg.flags = flags; 762d5b48543SMiklos Szeredi args.opcode = opcode; 763d5b48543SMiklos Szeredi args.nodeid = get_node_id(olddir); 764d5b48543SMiklos Szeredi args.in_numargs = 3; 765d5b48543SMiklos Szeredi args.in_args[0].size = argsize; 766d5b48543SMiklos Szeredi args.in_args[0].value = &inarg; 767d5b48543SMiklos Szeredi args.in_args[1].size = oldent->d_name.len + 1; 768d5b48543SMiklos Szeredi args.in_args[1].value = oldent->d_name.name; 769d5b48543SMiklos Szeredi args.in_args[2].size = newent->d_name.len + 1; 770d5b48543SMiklos Szeredi args.in_args[2].value = newent->d_name.name; 7717078187aSMiklos Szeredi err = fuse_simple_request(fc, &args); 7729e6268dbSMiklos Szeredi if (!err) { 77308b63307SMiklos Szeredi /* ctime changes */ 7742b0143b5SDavid Howells fuse_invalidate_attr(d_inode(oldent)); 7752b0143b5SDavid Howells fuse_update_ctime(d_inode(oldent)); 77608b63307SMiklos Szeredi 7771560c974SMiklos Szeredi if (flags & RENAME_EXCHANGE) { 7782b0143b5SDavid Howells fuse_invalidate_attr(d_inode(newent)); 7792b0143b5SDavid Howells fuse_update_ctime(d_inode(newent)); 7801560c974SMiklos Szeredi } 7811560c974SMiklos Szeredi 782261aaba7SMiklos Szeredi fuse_dir_changed(olddir); 7839e6268dbSMiklos Szeredi if (olddir != newdir) 784261aaba7SMiklos Szeredi fuse_dir_changed(newdir); 7858cbdf1e6SMiklos Szeredi 7868cbdf1e6SMiklos Szeredi /* newent will end up negative */ 7872b0143b5SDavid Howells if (!(flags & RENAME_EXCHANGE) && d_really_is_positive(newent)) { 7882b0143b5SDavid Howells fuse_invalidate_attr(d_inode(newent)); 7898cbdf1e6SMiklos Szeredi fuse_invalidate_entry_cache(newent); 7902b0143b5SDavid Howells fuse_update_ctime(d_inode(newent)); 7915219f346SMiklos Szeredi } 7929e6268dbSMiklos Szeredi } else if (err == -EINTR) { 7939e6268dbSMiklos Szeredi /* If request was interrupted, DEITY only knows if the 7949e6268dbSMiklos Szeredi rename actually took place. If the invalidation 7959e6268dbSMiklos Szeredi fails (e.g. some process has CWD under the renamed 7969e6268dbSMiklos Szeredi directory), then there can be inconsistency between 7979e6268dbSMiklos Szeredi the dcache and the real filesystem. Tough luck. */ 7989e6268dbSMiklos Szeredi fuse_invalidate_entry(oldent); 7992b0143b5SDavid Howells if (d_really_is_positive(newent)) 8009e6268dbSMiklos Szeredi fuse_invalidate_entry(newent); 8019e6268dbSMiklos Szeredi } 8029e6268dbSMiklos Szeredi 8039e6268dbSMiklos Szeredi return err; 8049e6268dbSMiklos Szeredi } 8059e6268dbSMiklos Szeredi 8061560c974SMiklos Szeredi static int fuse_rename2(struct inode *olddir, struct dentry *oldent, 8071560c974SMiklos Szeredi struct inode *newdir, struct dentry *newent, 8081560c974SMiklos Szeredi unsigned int flags) 8091560c974SMiklos Szeredi { 8101560c974SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(olddir); 8111560c974SMiklos Szeredi int err; 8121560c974SMiklos Szeredi 8131560c974SMiklos Szeredi if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE)) 8141560c974SMiklos Szeredi return -EINVAL; 8151560c974SMiklos Szeredi 8164237ba43SMiklos Szeredi if (flags) { 8171560c974SMiklos Szeredi if (fc->no_rename2 || fc->minor < 23) 8181560c974SMiklos Szeredi return -EINVAL; 8191560c974SMiklos Szeredi 8201560c974SMiklos Szeredi err = fuse_rename_common(olddir, oldent, newdir, newent, flags, 8214237ba43SMiklos Szeredi FUSE_RENAME2, 8224237ba43SMiklos Szeredi sizeof(struct fuse_rename2_in)); 8231560c974SMiklos Szeredi if (err == -ENOSYS) { 8241560c974SMiklos Szeredi fc->no_rename2 = 1; 8251560c974SMiklos Szeredi err = -EINVAL; 8261560c974SMiklos Szeredi } 8274237ba43SMiklos Szeredi } else { 8284237ba43SMiklos Szeredi err = fuse_rename_common(olddir, oldent, newdir, newent, 0, 8294237ba43SMiklos Szeredi FUSE_RENAME, 8304237ba43SMiklos Szeredi sizeof(struct fuse_rename_in)); 8314237ba43SMiklos Szeredi } 8321560c974SMiklos Szeredi 8334237ba43SMiklos Szeredi return err; 8344237ba43SMiklos Szeredi } 8354237ba43SMiklos Szeredi 8369e6268dbSMiklos Szeredi static int fuse_link(struct dentry *entry, struct inode *newdir, 8379e6268dbSMiklos Szeredi struct dentry *newent) 8389e6268dbSMiklos Szeredi { 8399e6268dbSMiklos Szeredi int err; 8409e6268dbSMiklos Szeredi struct fuse_link_in inarg; 8412b0143b5SDavid Howells struct inode *inode = d_inode(entry); 8429e6268dbSMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(inode); 8437078187aSMiklos Szeredi FUSE_ARGS(args); 8449e6268dbSMiklos Szeredi 8459e6268dbSMiklos Szeredi memset(&inarg, 0, sizeof(inarg)); 8469e6268dbSMiklos Szeredi inarg.oldnodeid = get_node_id(inode); 847d5b48543SMiklos Szeredi args.opcode = FUSE_LINK; 848d5b48543SMiklos Szeredi args.in_numargs = 2; 849d5b48543SMiklos Szeredi args.in_args[0].size = sizeof(inarg); 850d5b48543SMiklos Szeredi args.in_args[0].value = &inarg; 851d5b48543SMiklos Szeredi args.in_args[1].size = newent->d_name.len + 1; 852d5b48543SMiklos Szeredi args.in_args[1].value = newent->d_name.name; 8537078187aSMiklos Szeredi err = create_new_entry(fc, &args, newdir, newent, inode->i_mode); 8549e6268dbSMiklos Szeredi /* Contrary to "normal" filesystems it can happen that link 8559e6268dbSMiklos Szeredi makes two "logical" inodes point to the same "physical" 8569e6268dbSMiklos Szeredi inode. We invalidate the attributes of the old one, so it 8579e6268dbSMiklos Szeredi will reflect changes in the backing inode (link count, 8589e6268dbSMiklos Szeredi etc.) 8599e6268dbSMiklos Szeredi */ 860ac45d613SMiklos Szeredi if (!err) { 861ac45d613SMiklos Szeredi struct fuse_inode *fi = get_fuse_inode(inode); 862ac45d613SMiklos Szeredi 863f15ecfefSKirill Tkhai spin_lock(&fi->lock); 8644510d86fSKirill Tkhai fi->attr_version = atomic64_inc_return(&fc->attr_version); 865ac45d613SMiklos Szeredi inc_nlink(inode); 866f15ecfefSKirill Tkhai spin_unlock(&fi->lock); 8679e6268dbSMiklos Szeredi fuse_invalidate_attr(inode); 86831f3267bSMaxim Patlasov fuse_update_ctime(inode); 869ac45d613SMiklos Szeredi } else if (err == -EINTR) { 870ac45d613SMiklos Szeredi fuse_invalidate_attr(inode); 871ac45d613SMiklos Szeredi } 8729e6268dbSMiklos Szeredi return err; 8739e6268dbSMiklos Szeredi } 8749e6268dbSMiklos Szeredi 8751fb69e78SMiklos Szeredi static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr, 8761fb69e78SMiklos Szeredi struct kstat *stat) 8771fb69e78SMiklos Szeredi { 878203627bbSMiklos Szeredi unsigned int blkbits; 8798373200bSPavel Emelyanov struct fuse_conn *fc = get_fuse_conn(inode); 8808373200bSPavel Emelyanov 8818373200bSPavel Emelyanov /* see the comment in fuse_change_attributes() */ 882b0aa7606SMaxim Patlasov if (fc->writeback_cache && S_ISREG(inode->i_mode)) { 8838373200bSPavel Emelyanov attr->size = i_size_read(inode); 884b0aa7606SMaxim Patlasov attr->mtime = inode->i_mtime.tv_sec; 885b0aa7606SMaxim Patlasov attr->mtimensec = inode->i_mtime.tv_nsec; 88631f3267bSMaxim Patlasov attr->ctime = inode->i_ctime.tv_sec; 88731f3267bSMaxim Patlasov attr->ctimensec = inode->i_ctime.tv_nsec; 888b0aa7606SMaxim Patlasov } 889203627bbSMiklos Szeredi 8901fb69e78SMiklos Szeredi stat->dev = inode->i_sb->s_dev; 8911fb69e78SMiklos Szeredi stat->ino = attr->ino; 8921fb69e78SMiklos Szeredi stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777); 8931fb69e78SMiklos Szeredi stat->nlink = attr->nlink; 8948cb08329SEric W. Biederman stat->uid = make_kuid(fc->user_ns, attr->uid); 8958cb08329SEric W. Biederman stat->gid = make_kgid(fc->user_ns, attr->gid); 8961fb69e78SMiklos Szeredi stat->rdev = inode->i_rdev; 8971fb69e78SMiklos Szeredi stat->atime.tv_sec = attr->atime; 8981fb69e78SMiklos Szeredi stat->atime.tv_nsec = attr->atimensec; 8991fb69e78SMiklos Szeredi stat->mtime.tv_sec = attr->mtime; 9001fb69e78SMiklos Szeredi stat->mtime.tv_nsec = attr->mtimensec; 9011fb69e78SMiklos Szeredi stat->ctime.tv_sec = attr->ctime; 9021fb69e78SMiklos Szeredi stat->ctime.tv_nsec = attr->ctimensec; 9031fb69e78SMiklos Szeredi stat->size = attr->size; 9041fb69e78SMiklos Szeredi stat->blocks = attr->blocks; 905203627bbSMiklos Szeredi 906203627bbSMiklos Szeredi if (attr->blksize != 0) 907203627bbSMiklos Szeredi blkbits = ilog2(attr->blksize); 908203627bbSMiklos Szeredi else 909203627bbSMiklos Szeredi blkbits = inode->i_sb->s_blocksize_bits; 910203627bbSMiklos Szeredi 911203627bbSMiklos Szeredi stat->blksize = 1 << blkbits; 9121fb69e78SMiklos Szeredi } 9131fb69e78SMiklos Szeredi 914c79e322fSMiklos Szeredi static int fuse_do_getattr(struct inode *inode, struct kstat *stat, 915c79e322fSMiklos Szeredi struct file *file) 916e5e5558eSMiklos Szeredi { 917e5e5558eSMiklos Szeredi int err; 918c79e322fSMiklos Szeredi struct fuse_getattr_in inarg; 919c79e322fSMiklos Szeredi struct fuse_attr_out outarg; 920e5e5558eSMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(inode); 9217078187aSMiklos Szeredi FUSE_ARGS(args); 9221fb69e78SMiklos Szeredi u64 attr_version; 9231fb69e78SMiklos Szeredi 9247dca9fd3SMiklos Szeredi attr_version = fuse_get_attr_version(fc); 9251fb69e78SMiklos Szeredi 926c79e322fSMiklos Szeredi memset(&inarg, 0, sizeof(inarg)); 9270e9663eeSMiklos Szeredi memset(&outarg, 0, sizeof(outarg)); 928c79e322fSMiklos Szeredi /* Directories have separate file-handle space */ 929c79e322fSMiklos Szeredi if (file && S_ISREG(inode->i_mode)) { 930c79e322fSMiklos Szeredi struct fuse_file *ff = file->private_data; 931c79e322fSMiklos Szeredi 932c79e322fSMiklos Szeredi inarg.getattr_flags |= FUSE_GETATTR_FH; 933c79e322fSMiklos Szeredi inarg.fh = ff->fh; 934c79e322fSMiklos Szeredi } 935d5b48543SMiklos Szeredi args.opcode = FUSE_GETATTR; 936d5b48543SMiklos Szeredi args.nodeid = get_node_id(inode); 937d5b48543SMiklos Szeredi args.in_numargs = 1; 938d5b48543SMiklos Szeredi args.in_args[0].size = sizeof(inarg); 939d5b48543SMiklos Szeredi args.in_args[0].value = &inarg; 940d5b48543SMiklos Szeredi args.out_numargs = 1; 941d5b48543SMiklos Szeredi args.out_args[0].size = sizeof(outarg); 942d5b48543SMiklos Szeredi args.out_args[0].value = &outarg; 9437078187aSMiklos Szeredi err = fuse_simple_request(fc, &args); 944e5e5558eSMiklos Szeredi if (!err) { 945c79e322fSMiklos Szeredi if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) { 946e5e5558eSMiklos Szeredi make_bad_inode(inode); 947e5e5558eSMiklos Szeredi err = -EIO; 948e5e5558eSMiklos Szeredi } else { 949c79e322fSMiklos Szeredi fuse_change_attributes(inode, &outarg.attr, 950c79e322fSMiklos Szeredi attr_timeout(&outarg), 9511fb69e78SMiklos Szeredi attr_version); 9521fb69e78SMiklos Szeredi if (stat) 953c79e322fSMiklos Szeredi fuse_fillattr(inode, &outarg.attr, stat); 954e5e5558eSMiklos Szeredi } 955e5e5558eSMiklos Szeredi } 956e5e5558eSMiklos Szeredi return err; 957e5e5558eSMiklos Szeredi } 958e5e5558eSMiklos Szeredi 9595b97eeacSMiklos Szeredi static int fuse_update_get_attr(struct inode *inode, struct file *file, 9602f1e8196SMiklos Szeredi struct kstat *stat, u32 request_mask, 9612f1e8196SMiklos Szeredi unsigned int flags) 962bcb4be80SMiklos Szeredi { 963bcb4be80SMiklos Szeredi struct fuse_inode *fi = get_fuse_inode(inode); 9645b97eeacSMiklos Szeredi int err = 0; 965bf5c1898SMiklos Szeredi bool sync; 966bcb4be80SMiklos Szeredi 967bf5c1898SMiklos Szeredi if (flags & AT_STATX_FORCE_SYNC) 968bf5c1898SMiklos Szeredi sync = true; 969bf5c1898SMiklos Szeredi else if (flags & AT_STATX_DONT_SYNC) 970bf5c1898SMiklos Szeredi sync = false; 9712f1e8196SMiklos Szeredi else if (request_mask & READ_ONCE(fi->inval_mask)) 9722f1e8196SMiklos Szeredi sync = true; 973bf5c1898SMiklos Szeredi else 974bf5c1898SMiklos Szeredi sync = time_before64(fi->i_time, get_jiffies_64()); 975bf5c1898SMiklos Szeredi 976bf5c1898SMiklos Szeredi if (sync) { 97760bcc88aSSeth Forshee forget_all_cached_acls(inode); 978bcb4be80SMiklos Szeredi err = fuse_do_getattr(inode, stat, file); 9795b97eeacSMiklos Szeredi } else if (stat) { 980bcb4be80SMiklos Szeredi generic_fillattr(inode, stat); 981bcb4be80SMiklos Szeredi stat->mode = fi->orig_i_mode; 98245c72cd7SPavel Shilovsky stat->ino = fi->orig_ino; 983bcb4be80SMiklos Szeredi } 984bcb4be80SMiklos Szeredi 985bcb4be80SMiklos Szeredi return err; 986bcb4be80SMiklos Szeredi } 987bcb4be80SMiklos Szeredi 9885b97eeacSMiklos Szeredi int fuse_update_attributes(struct inode *inode, struct file *file) 9895b97eeacSMiklos Szeredi { 990802dc049SMiklos Szeredi /* Do *not* need to get atime for internal purposes */ 991802dc049SMiklos Szeredi return fuse_update_get_attr(inode, file, NULL, 992802dc049SMiklos Szeredi STATX_BASIC_STATS & ~STATX_ATIME, 0); 9935b97eeacSMiklos Szeredi } 9945b97eeacSMiklos Szeredi 9953b463ae0SJohn Muir int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid, 996451d0f59SJohn Muir u64 child_nodeid, struct qstr *name) 9973b463ae0SJohn Muir { 9983b463ae0SJohn Muir int err = -ENOTDIR; 9993b463ae0SJohn Muir struct inode *parent; 10003b463ae0SJohn Muir struct dentry *dir; 10013b463ae0SJohn Muir struct dentry *entry; 10023b463ae0SJohn Muir 10033b463ae0SJohn Muir parent = ilookup5(sb, parent_nodeid, fuse_inode_eq, &parent_nodeid); 10043b463ae0SJohn Muir if (!parent) 10053b463ae0SJohn Muir return -ENOENT; 10063b463ae0SJohn Muir 10075955102cSAl Viro inode_lock(parent); 10083b463ae0SJohn Muir if (!S_ISDIR(parent->i_mode)) 10093b463ae0SJohn Muir goto unlock; 10103b463ae0SJohn Muir 10113b463ae0SJohn Muir err = -ENOENT; 10123b463ae0SJohn Muir dir = d_find_alias(parent); 10133b463ae0SJohn Muir if (!dir) 10143b463ae0SJohn Muir goto unlock; 10153b463ae0SJohn Muir 10168387ff25SLinus Torvalds name->hash = full_name_hash(dir, name->name, name->len); 10173b463ae0SJohn Muir entry = d_lookup(dir, name); 10183b463ae0SJohn Muir dput(dir); 10193b463ae0SJohn Muir if (!entry) 10203b463ae0SJohn Muir goto unlock; 10213b463ae0SJohn Muir 1022261aaba7SMiklos Szeredi fuse_dir_changed(parent); 10233b463ae0SJohn Muir fuse_invalidate_entry(entry); 1024451d0f59SJohn Muir 10252b0143b5SDavid Howells if (child_nodeid != 0 && d_really_is_positive(entry)) { 10265955102cSAl Viro inode_lock(d_inode(entry)); 10272b0143b5SDavid Howells if (get_node_id(d_inode(entry)) != child_nodeid) { 1028451d0f59SJohn Muir err = -ENOENT; 1029451d0f59SJohn Muir goto badentry; 1030451d0f59SJohn Muir } 1031451d0f59SJohn Muir if (d_mountpoint(entry)) { 1032451d0f59SJohn Muir err = -EBUSY; 1033451d0f59SJohn Muir goto badentry; 1034451d0f59SJohn Muir } 1035e36cb0b8SDavid Howells if (d_is_dir(entry)) { 1036451d0f59SJohn Muir shrink_dcache_parent(entry); 1037451d0f59SJohn Muir if (!simple_empty(entry)) { 1038451d0f59SJohn Muir err = -ENOTEMPTY; 1039451d0f59SJohn Muir goto badentry; 1040451d0f59SJohn Muir } 10412b0143b5SDavid Howells d_inode(entry)->i_flags |= S_DEAD; 1042451d0f59SJohn Muir } 1043451d0f59SJohn Muir dont_mount(entry); 10442b0143b5SDavid Howells clear_nlink(d_inode(entry)); 10453b463ae0SJohn Muir err = 0; 1046451d0f59SJohn Muir badentry: 10475955102cSAl Viro inode_unlock(d_inode(entry)); 1048451d0f59SJohn Muir if (!err) 1049451d0f59SJohn Muir d_delete(entry); 1050451d0f59SJohn Muir } else { 1051451d0f59SJohn Muir err = 0; 1052451d0f59SJohn Muir } 1053451d0f59SJohn Muir dput(entry); 10543b463ae0SJohn Muir 10553b463ae0SJohn Muir unlock: 10565955102cSAl Viro inode_unlock(parent); 10573b463ae0SJohn Muir iput(parent); 10583b463ae0SJohn Muir return err; 10593b463ae0SJohn Muir } 10603b463ae0SJohn Muir 106187729a55SMiklos Szeredi /* 106287729a55SMiklos Szeredi * Calling into a user-controlled filesystem gives the filesystem 1063c2132c1bSAnatol Pomozov * daemon ptrace-like capabilities over the current process. This 106487729a55SMiklos Szeredi * means, that the filesystem daemon is able to record the exact 106587729a55SMiklos Szeredi * filesystem operations performed, and can also control the behavior 106687729a55SMiklos Szeredi * of the requester process in otherwise impossible ways. For example 106787729a55SMiklos Szeredi * it can delay the operation for arbitrary length of time allowing 106887729a55SMiklos Szeredi * DoS against the requester. 106987729a55SMiklos Szeredi * 107087729a55SMiklos Szeredi * For this reason only those processes can call into the filesystem, 107187729a55SMiklos Szeredi * for which the owner of the mount has ptrace privilege. This 107287729a55SMiklos Szeredi * excludes processes started by other users, suid or sgid processes. 107387729a55SMiklos Szeredi */ 1074c2132c1bSAnatol Pomozov int fuse_allow_current_process(struct fuse_conn *fc) 107587729a55SMiklos Szeredi { 1076c69e8d9cSDavid Howells const struct cred *cred; 1077c69e8d9cSDavid Howells 107829433a29SMiklos Szeredi if (fc->allow_other) 107973f03c2bSSeth Forshee return current_in_userns(fc->user_ns); 108087729a55SMiklos Szeredi 1081c2132c1bSAnatol Pomozov cred = current_cred(); 1082499dcf20SEric W. Biederman if (uid_eq(cred->euid, fc->user_id) && 1083499dcf20SEric W. Biederman uid_eq(cred->suid, fc->user_id) && 1084499dcf20SEric W. Biederman uid_eq(cred->uid, fc->user_id) && 1085499dcf20SEric W. Biederman gid_eq(cred->egid, fc->group_id) && 1086499dcf20SEric W. Biederman gid_eq(cred->sgid, fc->group_id) && 1087499dcf20SEric W. Biederman gid_eq(cred->gid, fc->group_id)) 1088c2132c1bSAnatol Pomozov return 1; 108987729a55SMiklos Szeredi 1090c2132c1bSAnatol Pomozov return 0; 109187729a55SMiklos Szeredi } 109287729a55SMiklos Szeredi 109331d40d74SMiklos Szeredi static int fuse_access(struct inode *inode, int mask) 109431d40d74SMiklos Szeredi { 109531d40d74SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(inode); 10967078187aSMiklos Szeredi FUSE_ARGS(args); 109731d40d74SMiklos Szeredi struct fuse_access_in inarg; 109831d40d74SMiklos Szeredi int err; 109931d40d74SMiklos Szeredi 1100698fa1d1SMiklos Szeredi BUG_ON(mask & MAY_NOT_BLOCK); 1101698fa1d1SMiklos Szeredi 110231d40d74SMiklos Szeredi if (fc->no_access) 110331d40d74SMiklos Szeredi return 0; 110431d40d74SMiklos Szeredi 110531d40d74SMiklos Szeredi memset(&inarg, 0, sizeof(inarg)); 1106e6305c43SAl Viro inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC); 1107d5b48543SMiklos Szeredi args.opcode = FUSE_ACCESS; 1108d5b48543SMiklos Szeredi args.nodeid = get_node_id(inode); 1109d5b48543SMiklos Szeredi args.in_numargs = 1; 1110d5b48543SMiklos Szeredi args.in_args[0].size = sizeof(inarg); 1111d5b48543SMiklos Szeredi args.in_args[0].value = &inarg; 11127078187aSMiklos Szeredi err = fuse_simple_request(fc, &args); 111331d40d74SMiklos Szeredi if (err == -ENOSYS) { 111431d40d74SMiklos Szeredi fc->no_access = 1; 111531d40d74SMiklos Szeredi err = 0; 111631d40d74SMiklos Szeredi } 111731d40d74SMiklos Szeredi return err; 111831d40d74SMiklos Szeredi } 111931d40d74SMiklos Szeredi 112010556cb2SAl Viro static int fuse_perm_getattr(struct inode *inode, int mask) 112119690ddbSMiklos Szeredi { 112210556cb2SAl Viro if (mask & MAY_NOT_BLOCK) 112319690ddbSMiklos Szeredi return -ECHILD; 112419690ddbSMiklos Szeredi 112560bcc88aSSeth Forshee forget_all_cached_acls(inode); 112619690ddbSMiklos Szeredi return fuse_do_getattr(inode, NULL, NULL); 112719690ddbSMiklos Szeredi } 112819690ddbSMiklos Szeredi 11296f9f1180SMiklos Szeredi /* 11306f9f1180SMiklos Szeredi * Check permission. The two basic access models of FUSE are: 11316f9f1180SMiklos Szeredi * 11326f9f1180SMiklos Szeredi * 1) Local access checking ('default_permissions' mount option) based 11336f9f1180SMiklos Szeredi * on file mode. This is the plain old disk filesystem permission 11346f9f1180SMiklos Szeredi * modell. 11356f9f1180SMiklos Szeredi * 11366f9f1180SMiklos Szeredi * 2) "Remote" access checking, where server is responsible for 11376f9f1180SMiklos Szeredi * checking permission in each inode operation. An exception to this 11386f9f1180SMiklos Szeredi * is if ->permission() was invoked from sys_access() in which case an 11396f9f1180SMiklos Szeredi * access request is sent. Execute permission is still checked 11406f9f1180SMiklos Szeredi * locally based on file mode. 11416f9f1180SMiklos Szeredi */ 114210556cb2SAl Viro static int fuse_permission(struct inode *inode, int mask) 1143e5e5558eSMiklos Szeredi { 1144e5e5558eSMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(inode); 1145244f6385SMiklos Szeredi bool refreshed = false; 1146244f6385SMiklos Szeredi int err = 0; 1147e5e5558eSMiklos Szeredi 1148c2132c1bSAnatol Pomozov if (!fuse_allow_current_process(fc)) 1149e5e5558eSMiklos Szeredi return -EACCES; 1150244f6385SMiklos Szeredi 1151244f6385SMiklos Szeredi /* 1152e8e96157SMiklos Szeredi * If attributes are needed, refresh them before proceeding 1153244f6385SMiklos Szeredi */ 115429433a29SMiklos Szeredi if (fc->default_permissions || 1155e8e96157SMiklos Szeredi ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) { 115619690ddbSMiklos Szeredi struct fuse_inode *fi = get_fuse_inode(inode); 1157d233c7ddSMiklos Szeredi u32 perm_mask = STATX_MODE | STATX_UID | STATX_GID; 115819690ddbSMiklos Szeredi 1159d233c7ddSMiklos Szeredi if (perm_mask & READ_ONCE(fi->inval_mask) || 1160d233c7ddSMiklos Szeredi time_before64(fi->i_time, get_jiffies_64())) { 116119690ddbSMiklos Szeredi refreshed = true; 116219690ddbSMiklos Szeredi 116310556cb2SAl Viro err = fuse_perm_getattr(inode, mask); 1164244f6385SMiklos Szeredi if (err) 1165244f6385SMiklos Szeredi return err; 11661fb69e78SMiklos Szeredi } 116719690ddbSMiklos Szeredi } 1168244f6385SMiklos Szeredi 116929433a29SMiklos Szeredi if (fc->default_permissions) { 11702830ba7fSAl Viro err = generic_permission(inode, mask); 11711e9a4ed9SMiklos Szeredi 11721e9a4ed9SMiklos Szeredi /* If permission is denied, try to refresh file 11731e9a4ed9SMiklos Szeredi attributes. This is also needed, because the root 11741e9a4ed9SMiklos Szeredi node will at first have no permissions */ 1175244f6385SMiklos Szeredi if (err == -EACCES && !refreshed) { 117610556cb2SAl Viro err = fuse_perm_getattr(inode, mask); 11771e9a4ed9SMiklos Szeredi if (!err) 11782830ba7fSAl Viro err = generic_permission(inode, mask); 11791e9a4ed9SMiklos Szeredi } 11801e9a4ed9SMiklos Szeredi 11816f9f1180SMiklos Szeredi /* Note: the opposite of the above test does not 11826f9f1180SMiklos Szeredi exist. So if permissions are revoked this won't be 11836f9f1180SMiklos Szeredi noticed immediately, only after the attribute 11846f9f1180SMiklos Szeredi timeout has expired */ 11859cfcac81SEric Paris } else if (mask & (MAY_ACCESS | MAY_CHDIR)) { 1186e8e96157SMiklos Szeredi err = fuse_access(inode, mask); 1187e8e96157SMiklos Szeredi } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { 1188e8e96157SMiklos Szeredi if (!(inode->i_mode & S_IXUGO)) { 1189e8e96157SMiklos Szeredi if (refreshed) 1190e5e5558eSMiklos Szeredi return -EACCES; 119131d40d74SMiklos Szeredi 119210556cb2SAl Viro err = fuse_perm_getattr(inode, mask); 1193e8e96157SMiklos Szeredi if (!err && !(inode->i_mode & S_IXUGO)) 1194e8e96157SMiklos Szeredi return -EACCES; 1195e8e96157SMiklos Szeredi } 1196e5e5558eSMiklos Szeredi } 1197244f6385SMiklos Szeredi return err; 1198e5e5558eSMiklos Szeredi } 1199e5e5558eSMiklos Szeredi 12005571f1e6SDan Schatzberg static int fuse_readlink_page(struct inode *inode, struct page *page) 1201e5e5558eSMiklos Szeredi { 1202e5e5558eSMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(inode); 12034c29afecSMiklos Szeredi struct fuse_page_desc desc = { .length = PAGE_SIZE - 1 }; 12044c29afecSMiklos Szeredi struct fuse_args_pages ap = { 12054c29afecSMiklos Szeredi .num_pages = 1, 12064c29afecSMiklos Szeredi .pages = &page, 12074c29afecSMiklos Szeredi .descs = &desc, 12084c29afecSMiklos Szeredi }; 12094c29afecSMiklos Szeredi char *link; 12104c29afecSMiklos Szeredi ssize_t res; 1211e5e5558eSMiklos Szeredi 12124c29afecSMiklos Szeredi ap.args.opcode = FUSE_READLINK; 12134c29afecSMiklos Szeredi ap.args.nodeid = get_node_id(inode); 12144c29afecSMiklos Szeredi ap.args.out_pages = true; 12154c29afecSMiklos Szeredi ap.args.out_argvar = true; 12164c29afecSMiklos Szeredi ap.args.page_zeroing = true; 12174c29afecSMiklos Szeredi ap.args.out_numargs = 1; 12184c29afecSMiklos Szeredi ap.args.out_args[0].size = desc.length; 12194c29afecSMiklos Szeredi res = fuse_simple_request(fc, &ap.args); 12206b255391SAl Viro 1221451418fcSAndrew Gallagher fuse_invalidate_atime(inode); 12225571f1e6SDan Schatzberg 12234c29afecSMiklos Szeredi if (res < 0) 12244c29afecSMiklos Szeredi return res; 12254c29afecSMiklos Szeredi 12264c29afecSMiklos Szeredi if (WARN_ON(res >= PAGE_SIZE)) 12274c29afecSMiklos Szeredi return -EIO; 12284c29afecSMiklos Szeredi 12294c29afecSMiklos Szeredi link = page_address(page); 12304c29afecSMiklos Szeredi link[res] = '\0'; 12314c29afecSMiklos Szeredi 12324c29afecSMiklos Szeredi return 0; 12335571f1e6SDan Schatzberg } 12345571f1e6SDan Schatzberg 12355571f1e6SDan Schatzberg static const char *fuse_get_link(struct dentry *dentry, struct inode *inode, 12365571f1e6SDan Schatzberg struct delayed_call *callback) 12375571f1e6SDan Schatzberg { 12385571f1e6SDan Schatzberg struct fuse_conn *fc = get_fuse_conn(inode); 12395571f1e6SDan Schatzberg struct page *page; 12405571f1e6SDan Schatzberg int err; 12415571f1e6SDan Schatzberg 12425571f1e6SDan Schatzberg err = -EIO; 12435571f1e6SDan Schatzberg if (is_bad_inode(inode)) 12445571f1e6SDan Schatzberg goto out_err; 12455571f1e6SDan Schatzberg 12465571f1e6SDan Schatzberg if (fc->cache_symlinks) 12475571f1e6SDan Schatzberg return page_get_link(dentry, inode, callback); 12485571f1e6SDan Schatzberg 12495571f1e6SDan Schatzberg err = -ECHILD; 12505571f1e6SDan Schatzberg if (!dentry) 12515571f1e6SDan Schatzberg goto out_err; 12525571f1e6SDan Schatzberg 12535571f1e6SDan Schatzberg page = alloc_page(GFP_KERNEL); 12545571f1e6SDan Schatzberg err = -ENOMEM; 12555571f1e6SDan Schatzberg if (!page) 12565571f1e6SDan Schatzberg goto out_err; 12575571f1e6SDan Schatzberg 12585571f1e6SDan Schatzberg err = fuse_readlink_page(inode, page); 12595571f1e6SDan Schatzberg if (err) { 12605571f1e6SDan Schatzberg __free_page(page); 12615571f1e6SDan Schatzberg goto out_err; 12625571f1e6SDan Schatzberg } 12635571f1e6SDan Schatzberg 12645571f1e6SDan Schatzberg set_delayed_call(callback, page_put_link, page); 12655571f1e6SDan Schatzberg 12665571f1e6SDan Schatzberg return page_address(page); 12675571f1e6SDan Schatzberg 12685571f1e6SDan Schatzberg out_err: 12695571f1e6SDan Schatzberg return ERR_PTR(err); 1270e5e5558eSMiklos Szeredi } 1271e5e5558eSMiklos Szeredi 1272e5e5558eSMiklos Szeredi static int fuse_dir_open(struct inode *inode, struct file *file) 1273e5e5558eSMiklos Szeredi { 127491fe96b4SMiklos Szeredi return fuse_open_common(inode, file, true); 1275e5e5558eSMiklos Szeredi } 1276e5e5558eSMiklos Szeredi 1277e5e5558eSMiklos Szeredi static int fuse_dir_release(struct inode *inode, struct file *file) 1278e5e5558eSMiklos Szeredi { 12792e64ff15SChad Austin fuse_release_common(file, true); 12808b0797a4SMiklos Szeredi 12818b0797a4SMiklos Szeredi return 0; 1282e5e5558eSMiklos Szeredi } 1283e5e5558eSMiklos Szeredi 128402c24a82SJosef Bacik static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end, 128502c24a82SJosef Bacik int datasync) 128682547981SMiklos Szeredi { 1287a9c2d1e8SMiklos Szeredi struct inode *inode = file->f_mapping->host; 1288a9c2d1e8SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(inode); 1289a9c2d1e8SMiklos Szeredi int err; 1290a9c2d1e8SMiklos Szeredi 1291a9c2d1e8SMiklos Szeredi if (is_bad_inode(inode)) 1292a9c2d1e8SMiklos Szeredi return -EIO; 1293a9c2d1e8SMiklos Szeredi 1294a9c2d1e8SMiklos Szeredi if (fc->no_fsyncdir) 1295a9c2d1e8SMiklos Szeredi return 0; 1296a9c2d1e8SMiklos Szeredi 1297a9c2d1e8SMiklos Szeredi inode_lock(inode); 1298a9c2d1e8SMiklos Szeredi err = fuse_fsync_common(file, start, end, datasync, FUSE_FSYNCDIR); 1299a9c2d1e8SMiklos Szeredi if (err == -ENOSYS) { 1300a9c2d1e8SMiklos Szeredi fc->no_fsyncdir = 1; 1301a9c2d1e8SMiklos Szeredi err = 0; 1302a9c2d1e8SMiklos Szeredi } 1303a9c2d1e8SMiklos Szeredi inode_unlock(inode); 1304a9c2d1e8SMiklos Szeredi 1305a9c2d1e8SMiklos Szeredi return err; 130682547981SMiklos Szeredi } 130782547981SMiklos Szeredi 1308b18da0c5SMiklos Szeredi static long fuse_dir_ioctl(struct file *file, unsigned int cmd, 1309b18da0c5SMiklos Szeredi unsigned long arg) 1310b18da0c5SMiklos Szeredi { 1311b18da0c5SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host); 1312b18da0c5SMiklos Szeredi 1313b18da0c5SMiklos Szeredi /* FUSE_IOCTL_DIR only supported for API version >= 7.18 */ 1314b18da0c5SMiklos Szeredi if (fc->minor < 18) 1315b18da0c5SMiklos Szeredi return -ENOTTY; 1316b18da0c5SMiklos Szeredi 1317b18da0c5SMiklos Szeredi return fuse_ioctl_common(file, cmd, arg, FUSE_IOCTL_DIR); 1318b18da0c5SMiklos Szeredi } 1319b18da0c5SMiklos Szeredi 1320b18da0c5SMiklos Szeredi static long fuse_dir_compat_ioctl(struct file *file, unsigned int cmd, 1321b18da0c5SMiklos Szeredi unsigned long arg) 1322b18da0c5SMiklos Szeredi { 1323b18da0c5SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host); 1324b18da0c5SMiklos Szeredi 1325b18da0c5SMiklos Szeredi if (fc->minor < 18) 1326b18da0c5SMiklos Szeredi return -ENOTTY; 1327b18da0c5SMiklos Szeredi 1328b18da0c5SMiklos Szeredi return fuse_ioctl_common(file, cmd, arg, 1329b18da0c5SMiklos Szeredi FUSE_IOCTL_COMPAT | FUSE_IOCTL_DIR); 1330b18da0c5SMiklos Szeredi } 1331b18da0c5SMiklos Szeredi 1332b0aa7606SMaxim Patlasov static bool update_mtime(unsigned ivalid, bool trust_local_mtime) 133317637cbaSMiklos Szeredi { 133417637cbaSMiklos Szeredi /* Always update if mtime is explicitly set */ 133517637cbaSMiklos Szeredi if (ivalid & ATTR_MTIME_SET) 133617637cbaSMiklos Szeredi return true; 133717637cbaSMiklos Szeredi 1338b0aa7606SMaxim Patlasov /* Or if kernel i_mtime is the official one */ 1339b0aa7606SMaxim Patlasov if (trust_local_mtime) 1340b0aa7606SMaxim Patlasov return true; 1341b0aa7606SMaxim Patlasov 134217637cbaSMiklos Szeredi /* If it's an open(O_TRUNC) or an ftruncate(), don't update */ 134317637cbaSMiklos Szeredi if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE))) 134417637cbaSMiklos Szeredi return false; 134517637cbaSMiklos Szeredi 134617637cbaSMiklos Szeredi /* In all other cases update */ 134717637cbaSMiklos Szeredi return true; 134817637cbaSMiklos Szeredi } 134917637cbaSMiklos Szeredi 13508cb08329SEric W. Biederman static void iattr_to_fattr(struct fuse_conn *fc, struct iattr *iattr, 13518cb08329SEric W. Biederman struct fuse_setattr_in *arg, bool trust_local_cmtime) 13529e6268dbSMiklos Szeredi { 13539e6268dbSMiklos Szeredi unsigned ivalid = iattr->ia_valid; 13549e6268dbSMiklos Szeredi 13559e6268dbSMiklos Szeredi if (ivalid & ATTR_MODE) 1356befc649cSMiklos Szeredi arg->valid |= FATTR_MODE, arg->mode = iattr->ia_mode; 13579e6268dbSMiklos Szeredi if (ivalid & ATTR_UID) 13588cb08329SEric W. Biederman arg->valid |= FATTR_UID, arg->uid = from_kuid(fc->user_ns, iattr->ia_uid); 13599e6268dbSMiklos Szeredi if (ivalid & ATTR_GID) 13608cb08329SEric W. Biederman arg->valid |= FATTR_GID, arg->gid = from_kgid(fc->user_ns, iattr->ia_gid); 13619e6268dbSMiklos Szeredi if (ivalid & ATTR_SIZE) 1362befc649cSMiklos Szeredi arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size; 136317637cbaSMiklos Szeredi if (ivalid & ATTR_ATIME) { 136417637cbaSMiklos Szeredi arg->valid |= FATTR_ATIME; 1365befc649cSMiklos Szeredi arg->atime = iattr->ia_atime.tv_sec; 136617637cbaSMiklos Szeredi arg->atimensec = iattr->ia_atime.tv_nsec; 136717637cbaSMiklos Szeredi if (!(ivalid & ATTR_ATIME_SET)) 136817637cbaSMiklos Szeredi arg->valid |= FATTR_ATIME_NOW; 136917637cbaSMiklos Szeredi } 13703ad22c62SMaxim Patlasov if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, trust_local_cmtime)) { 137117637cbaSMiklos Szeredi arg->valid |= FATTR_MTIME; 1372befc649cSMiklos Szeredi arg->mtime = iattr->ia_mtime.tv_sec; 137317637cbaSMiklos Szeredi arg->mtimensec = iattr->ia_mtime.tv_nsec; 13743ad22c62SMaxim Patlasov if (!(ivalid & ATTR_MTIME_SET) && !trust_local_cmtime) 137517637cbaSMiklos Szeredi arg->valid |= FATTR_MTIME_NOW; 13769e6268dbSMiklos Szeredi } 13773ad22c62SMaxim Patlasov if ((ivalid & ATTR_CTIME) && trust_local_cmtime) { 13783ad22c62SMaxim Patlasov arg->valid |= FATTR_CTIME; 13793ad22c62SMaxim Patlasov arg->ctime = iattr->ia_ctime.tv_sec; 13803ad22c62SMaxim Patlasov arg->ctimensec = iattr->ia_ctime.tv_nsec; 13813ad22c62SMaxim Patlasov } 13829e6268dbSMiklos Szeredi } 13839e6268dbSMiklos Szeredi 13846f9f1180SMiklos Szeredi /* 13853be5a52bSMiklos Szeredi * Prevent concurrent writepages on inode 13863be5a52bSMiklos Szeredi * 13873be5a52bSMiklos Szeredi * This is done by adding a negative bias to the inode write counter 13883be5a52bSMiklos Szeredi * and waiting for all pending writes to finish. 13893be5a52bSMiklos Szeredi */ 13903be5a52bSMiklos Szeredi void fuse_set_nowrite(struct inode *inode) 13913be5a52bSMiklos Szeredi { 13923be5a52bSMiklos Szeredi struct fuse_inode *fi = get_fuse_inode(inode); 13933be5a52bSMiklos Szeredi 13945955102cSAl Viro BUG_ON(!inode_is_locked(inode)); 13953be5a52bSMiklos Szeredi 1396f15ecfefSKirill Tkhai spin_lock(&fi->lock); 13973be5a52bSMiklos Szeredi BUG_ON(fi->writectr < 0); 13983be5a52bSMiklos Szeredi fi->writectr += FUSE_NOWRITE; 1399f15ecfefSKirill Tkhai spin_unlock(&fi->lock); 14003be5a52bSMiklos Szeredi wait_event(fi->page_waitq, fi->writectr == FUSE_NOWRITE); 14013be5a52bSMiklos Szeredi } 14023be5a52bSMiklos Szeredi 14033be5a52bSMiklos Szeredi /* 14043be5a52bSMiklos Szeredi * Allow writepages on inode 14053be5a52bSMiklos Szeredi * 14063be5a52bSMiklos Szeredi * Remove the bias from the writecounter and send any queued 14073be5a52bSMiklos Szeredi * writepages. 14083be5a52bSMiklos Szeredi */ 14093be5a52bSMiklos Szeredi static void __fuse_release_nowrite(struct inode *inode) 14103be5a52bSMiklos Szeredi { 14113be5a52bSMiklos Szeredi struct fuse_inode *fi = get_fuse_inode(inode); 14123be5a52bSMiklos Szeredi 14133be5a52bSMiklos Szeredi BUG_ON(fi->writectr != FUSE_NOWRITE); 14143be5a52bSMiklos Szeredi fi->writectr = 0; 14153be5a52bSMiklos Szeredi fuse_flush_writepages(inode); 14163be5a52bSMiklos Szeredi } 14173be5a52bSMiklos Szeredi 14183be5a52bSMiklos Szeredi void fuse_release_nowrite(struct inode *inode) 14193be5a52bSMiklos Szeredi { 1420f15ecfefSKirill Tkhai struct fuse_inode *fi = get_fuse_inode(inode); 14213be5a52bSMiklos Szeredi 1422f15ecfefSKirill Tkhai spin_lock(&fi->lock); 14233be5a52bSMiklos Szeredi __fuse_release_nowrite(inode); 1424f15ecfefSKirill Tkhai spin_unlock(&fi->lock); 14253be5a52bSMiklos Szeredi } 14263be5a52bSMiklos Szeredi 14277078187aSMiklos Szeredi static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_args *args, 1428b0aa7606SMaxim Patlasov struct inode *inode, 1429b0aa7606SMaxim Patlasov struct fuse_setattr_in *inarg_p, 1430b0aa7606SMaxim Patlasov struct fuse_attr_out *outarg_p) 1431b0aa7606SMaxim Patlasov { 1432d5b48543SMiklos Szeredi args->opcode = FUSE_SETATTR; 1433d5b48543SMiklos Szeredi args->nodeid = get_node_id(inode); 1434d5b48543SMiklos Szeredi args->in_numargs = 1; 1435d5b48543SMiklos Szeredi args->in_args[0].size = sizeof(*inarg_p); 1436d5b48543SMiklos Szeredi args->in_args[0].value = inarg_p; 1437d5b48543SMiklos Szeredi args->out_numargs = 1; 1438d5b48543SMiklos Szeredi args->out_args[0].size = sizeof(*outarg_p); 1439d5b48543SMiklos Szeredi args->out_args[0].value = outarg_p; 1440b0aa7606SMaxim Patlasov } 1441b0aa7606SMaxim Patlasov 1442b0aa7606SMaxim Patlasov /* 1443b0aa7606SMaxim Patlasov * Flush inode->i_mtime to the server 1444b0aa7606SMaxim Patlasov */ 1445ab9e13f7SMaxim Patlasov int fuse_flush_times(struct inode *inode, struct fuse_file *ff) 1446b0aa7606SMaxim Patlasov { 1447b0aa7606SMaxim Patlasov struct fuse_conn *fc = get_fuse_conn(inode); 14487078187aSMiklos Szeredi FUSE_ARGS(args); 1449b0aa7606SMaxim Patlasov struct fuse_setattr_in inarg; 1450b0aa7606SMaxim Patlasov struct fuse_attr_out outarg; 1451b0aa7606SMaxim Patlasov 1452b0aa7606SMaxim Patlasov memset(&inarg, 0, sizeof(inarg)); 1453b0aa7606SMaxim Patlasov memset(&outarg, 0, sizeof(outarg)); 1454b0aa7606SMaxim Patlasov 1455ab9e13f7SMaxim Patlasov inarg.valid = FATTR_MTIME; 1456b0aa7606SMaxim Patlasov inarg.mtime = inode->i_mtime.tv_sec; 1457b0aa7606SMaxim Patlasov inarg.mtimensec = inode->i_mtime.tv_nsec; 1458ab9e13f7SMaxim Patlasov if (fc->minor >= 23) { 1459ab9e13f7SMaxim Patlasov inarg.valid |= FATTR_CTIME; 1460ab9e13f7SMaxim Patlasov inarg.ctime = inode->i_ctime.tv_sec; 1461ab9e13f7SMaxim Patlasov inarg.ctimensec = inode->i_ctime.tv_nsec; 1462ab9e13f7SMaxim Patlasov } 14631e18bda8SMiklos Szeredi if (ff) { 14641e18bda8SMiklos Szeredi inarg.valid |= FATTR_FH; 14651e18bda8SMiklos Szeredi inarg.fh = ff->fh; 14661e18bda8SMiklos Szeredi } 14677078187aSMiklos Szeredi fuse_setattr_fill(fc, &args, inode, &inarg, &outarg); 1468b0aa7606SMaxim Patlasov 14697078187aSMiklos Szeredi return fuse_simple_request(fc, &args); 1470b0aa7606SMaxim Patlasov } 1471b0aa7606SMaxim Patlasov 14723be5a52bSMiklos Szeredi /* 14736f9f1180SMiklos Szeredi * Set attributes, and at the same time refresh them. 14746f9f1180SMiklos Szeredi * 14756f9f1180SMiklos Szeredi * Truncation is slightly complicated, because the 'truncate' request 14766f9f1180SMiklos Szeredi * may fail, in which case we don't want to touch the mapping. 14779ffbb916SMiklos Szeredi * vmtruncate() doesn't allow for this case, so do the rlimit checking 14789ffbb916SMiklos Szeredi * and the actual truncation by hand. 14796f9f1180SMiklos Szeredi */ 148062490330SJan Kara int fuse_do_setattr(struct dentry *dentry, struct iattr *attr, 148149d4914fSMiklos Szeredi struct file *file) 14829e6268dbSMiklos Szeredi { 148362490330SJan Kara struct inode *inode = d_inode(dentry); 14849e6268dbSMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(inode); 148506a7c3c2SMaxim Patlasov struct fuse_inode *fi = get_fuse_inode(inode); 14867078187aSMiklos Szeredi FUSE_ARGS(args); 14879e6268dbSMiklos Szeredi struct fuse_setattr_in inarg; 14889e6268dbSMiklos Szeredi struct fuse_attr_out outarg; 14893be5a52bSMiklos Szeredi bool is_truncate = false; 14908373200bSPavel Emelyanov bool is_wb = fc->writeback_cache; 14913be5a52bSMiklos Szeredi loff_t oldsize; 14929e6268dbSMiklos Szeredi int err; 14933ad22c62SMaxim Patlasov bool trust_local_cmtime = is_wb && S_ISREG(inode->i_mode); 14949e6268dbSMiklos Szeredi 149529433a29SMiklos Szeredi if (!fc->default_permissions) 1496db78b877SChristoph Hellwig attr->ia_valid |= ATTR_FORCE; 1497db78b877SChristoph Hellwig 149831051c85SJan Kara err = setattr_prepare(dentry, attr); 14991e9a4ed9SMiklos Szeredi if (err) 15001e9a4ed9SMiklos Szeredi return err; 15011e9a4ed9SMiklos Szeredi 15028d56adddSMiklos Szeredi if (attr->ia_valid & ATTR_OPEN) { 1503df0e91d4SMiklos Szeredi /* This is coming from open(..., ... | O_TRUNC); */ 1504df0e91d4SMiklos Szeredi WARN_ON(!(attr->ia_valid & ATTR_SIZE)); 1505df0e91d4SMiklos Szeredi WARN_ON(attr->ia_size != 0); 1506df0e91d4SMiklos Szeredi if (fc->atomic_o_trunc) { 1507df0e91d4SMiklos Szeredi /* 1508df0e91d4SMiklos Szeredi * No need to send request to userspace, since actual 1509df0e91d4SMiklos Szeredi * truncation has already been done by OPEN. But still 1510df0e91d4SMiklos Szeredi * need to truncate page cache. 1511df0e91d4SMiklos Szeredi */ 1512df0e91d4SMiklos Szeredi i_size_write(inode, 0); 1513df0e91d4SMiklos Szeredi truncate_pagecache(inode, 0); 15146ff958edSMiklos Szeredi return 0; 1515df0e91d4SMiklos Szeredi } 15168d56adddSMiklos Szeredi file = NULL; 15178d56adddSMiklos Szeredi } 15186ff958edSMiklos Szeredi 1519ab2257e9SMiklos Szeredi if (attr->ia_valid & ATTR_SIZE) { 1520ab2257e9SMiklos Szeredi if (WARN_ON(!S_ISREG(inode->i_mode))) 1521ab2257e9SMiklos Szeredi return -EIO; 15223be5a52bSMiklos Szeredi is_truncate = true; 1523ab2257e9SMiklos Szeredi } 15249e6268dbSMiklos Szeredi 1525*b24e7598SMiklos Szeredi /* Flush dirty data/metadata before non-truncate SETATTR */ 1526*b24e7598SMiklos Szeredi if (is_wb && S_ISREG(inode->i_mode) && 1527*b24e7598SMiklos Szeredi attr->ia_valid & 1528*b24e7598SMiklos Szeredi (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_MTIME_SET | 1529*b24e7598SMiklos Szeredi ATTR_TIMES_SET)) { 1530*b24e7598SMiklos Szeredi err = write_inode_now(inode, true); 1531*b24e7598SMiklos Szeredi if (err) 1532*b24e7598SMiklos Szeredi return err; 1533*b24e7598SMiklos Szeredi 1534*b24e7598SMiklos Szeredi fuse_set_nowrite(inode); 1535*b24e7598SMiklos Szeredi fuse_release_nowrite(inode); 1536*b24e7598SMiklos Szeredi } 1537*b24e7598SMiklos Szeredi 153806a7c3c2SMaxim Patlasov if (is_truncate) { 15393be5a52bSMiklos Szeredi fuse_set_nowrite(inode); 154006a7c3c2SMaxim Patlasov set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); 15413ad22c62SMaxim Patlasov if (trust_local_cmtime && attr->ia_size != inode->i_size) 15423ad22c62SMaxim Patlasov attr->ia_valid |= ATTR_MTIME | ATTR_CTIME; 154306a7c3c2SMaxim Patlasov } 15443be5a52bSMiklos Szeredi 15459e6268dbSMiklos Szeredi memset(&inarg, 0, sizeof(inarg)); 15460e9663eeSMiklos Szeredi memset(&outarg, 0, sizeof(outarg)); 15478cb08329SEric W. Biederman iattr_to_fattr(fc, attr, &inarg, trust_local_cmtime); 154849d4914fSMiklos Szeredi if (file) { 154949d4914fSMiklos Szeredi struct fuse_file *ff = file->private_data; 155049d4914fSMiklos Szeredi inarg.valid |= FATTR_FH; 155149d4914fSMiklos Szeredi inarg.fh = ff->fh; 155249d4914fSMiklos Szeredi } 1553f3332114SMiklos Szeredi if (attr->ia_valid & ATTR_SIZE) { 1554f3332114SMiklos Szeredi /* For mandatory locking in truncate */ 1555f3332114SMiklos Szeredi inarg.valid |= FATTR_LOCKOWNER; 1556f3332114SMiklos Szeredi inarg.lock_owner = fuse_lock_owner_id(fc, current->files); 1557f3332114SMiklos Szeredi } 15587078187aSMiklos Szeredi fuse_setattr_fill(fc, &args, inode, &inarg, &outarg); 15597078187aSMiklos Szeredi err = fuse_simple_request(fc, &args); 1560e00d2c2dSMiklos Szeredi if (err) { 1561e00d2c2dSMiklos Szeredi if (err == -EINTR) 1562e00d2c2dSMiklos Szeredi fuse_invalidate_attr(inode); 15633be5a52bSMiklos Szeredi goto error; 1564e00d2c2dSMiklos Szeredi } 1565e00d2c2dSMiklos Szeredi 15669e6268dbSMiklos Szeredi if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) { 15679e6268dbSMiklos Szeredi make_bad_inode(inode); 15683be5a52bSMiklos Szeredi err = -EIO; 15693be5a52bSMiklos Szeredi goto error; 15709e6268dbSMiklos Szeredi } 15719e6268dbSMiklos Szeredi 1572f15ecfefSKirill Tkhai spin_lock(&fi->lock); 1573b0aa7606SMaxim Patlasov /* the kernel maintains i_mtime locally */ 15743ad22c62SMaxim Patlasov if (trust_local_cmtime) { 15753ad22c62SMaxim Patlasov if (attr->ia_valid & ATTR_MTIME) 1576b0aa7606SMaxim Patlasov inode->i_mtime = attr->ia_mtime; 15773ad22c62SMaxim Patlasov if (attr->ia_valid & ATTR_CTIME) 15783ad22c62SMaxim Patlasov inode->i_ctime = attr->ia_ctime; 15791e18bda8SMiklos Szeredi /* FIXME: clear I_DIRTY_SYNC? */ 1580b0aa7606SMaxim Patlasov } 1581b0aa7606SMaxim Patlasov 15823be5a52bSMiklos Szeredi fuse_change_attributes_common(inode, &outarg.attr, 15833be5a52bSMiklos Szeredi attr_timeout(&outarg)); 15843be5a52bSMiklos Szeredi oldsize = inode->i_size; 15858373200bSPavel Emelyanov /* see the comment in fuse_change_attributes() */ 15868373200bSPavel Emelyanov if (!is_wb || is_truncate || !S_ISREG(inode->i_mode)) 15873be5a52bSMiklos Szeredi i_size_write(inode, outarg.attr.size); 15883be5a52bSMiklos Szeredi 15893be5a52bSMiklos Szeredi if (is_truncate) { 1590f15ecfefSKirill Tkhai /* NOTE: this may release/reacquire fi->lock */ 15913be5a52bSMiklos Szeredi __fuse_release_nowrite(inode); 15923be5a52bSMiklos Szeredi } 1593f15ecfefSKirill Tkhai spin_unlock(&fi->lock); 15943be5a52bSMiklos Szeredi 15953be5a52bSMiklos Szeredi /* 15963be5a52bSMiklos Szeredi * Only call invalidate_inode_pages2() after removing 15973be5a52bSMiklos Szeredi * FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock. 15983be5a52bSMiklos Szeredi */ 15998373200bSPavel Emelyanov if ((is_truncate || !is_wb) && 16008373200bSPavel Emelyanov S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) { 16017caef267SKirill A. Shutemov truncate_pagecache(inode, outarg.attr.size); 16023be5a52bSMiklos Szeredi invalidate_inode_pages2(inode->i_mapping); 16033be5a52bSMiklos Szeredi } 16043be5a52bSMiklos Szeredi 160506a7c3c2SMaxim Patlasov clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); 1606e00d2c2dSMiklos Szeredi return 0; 16073be5a52bSMiklos Szeredi 16083be5a52bSMiklos Szeredi error: 16093be5a52bSMiklos Szeredi if (is_truncate) 16103be5a52bSMiklos Szeredi fuse_release_nowrite(inode); 16113be5a52bSMiklos Szeredi 161206a7c3c2SMaxim Patlasov clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); 16133be5a52bSMiklos Szeredi return err; 16149e6268dbSMiklos Szeredi } 16159e6268dbSMiklos Szeredi 161649d4914fSMiklos Szeredi static int fuse_setattr(struct dentry *entry, struct iattr *attr) 161749d4914fSMiklos Szeredi { 16182b0143b5SDavid Howells struct inode *inode = d_inode(entry); 16195e940c1dSMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(inode); 1620a09f99edSMiklos Szeredi struct file *file = (attr->ia_valid & ATTR_FILE) ? attr->ia_file : NULL; 16215e2b8828SMiklos Szeredi int ret; 1622efb9fa9eSMaxim Patlasov 1623efb9fa9eSMaxim Patlasov if (!fuse_allow_current_process(get_fuse_conn(inode))) 1624efb9fa9eSMaxim Patlasov return -EACCES; 1625efb9fa9eSMaxim Patlasov 1626a09f99edSMiklos Szeredi if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) { 1627a09f99edSMiklos Szeredi attr->ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID | 1628a09f99edSMiklos Szeredi ATTR_MODE); 16295e940c1dSMiklos Szeredi 1630a09f99edSMiklos Szeredi /* 16315e940c1dSMiklos Szeredi * The only sane way to reliably kill suid/sgid is to do it in 16325e940c1dSMiklos Szeredi * the userspace filesystem 16335e940c1dSMiklos Szeredi * 16345e940c1dSMiklos Szeredi * This should be done on write(), truncate() and chown(). 16355e940c1dSMiklos Szeredi */ 16365e940c1dSMiklos Szeredi if (!fc->handle_killpriv) { 16375e940c1dSMiklos Szeredi /* 16385e940c1dSMiklos Szeredi * ia_mode calculation may have used stale i_mode. 16395e940c1dSMiklos Szeredi * Refresh and recalculate. 1640a09f99edSMiklos Szeredi */ 1641a09f99edSMiklos Szeredi ret = fuse_do_getattr(inode, NULL, file); 1642a09f99edSMiklos Szeredi if (ret) 1643a09f99edSMiklos Szeredi return ret; 1644a09f99edSMiklos Szeredi 1645a09f99edSMiklos Szeredi attr->ia_mode = inode->i_mode; 1646c01638f5SMiklos Szeredi if (inode->i_mode & S_ISUID) { 1647a09f99edSMiklos Szeredi attr->ia_valid |= ATTR_MODE; 1648a09f99edSMiklos Szeredi attr->ia_mode &= ~S_ISUID; 1649a09f99edSMiklos Szeredi } 1650c01638f5SMiklos Szeredi if ((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { 1651a09f99edSMiklos Szeredi attr->ia_valid |= ATTR_MODE; 1652a09f99edSMiklos Szeredi attr->ia_mode &= ~S_ISGID; 1653a09f99edSMiklos Szeredi } 1654a09f99edSMiklos Szeredi } 16555e940c1dSMiklos Szeredi } 1656a09f99edSMiklos Szeredi if (!attr->ia_valid) 1657a09f99edSMiklos Szeredi return 0; 1658a09f99edSMiklos Szeredi 1659abb5a14fSLinus Torvalds ret = fuse_do_setattr(entry, attr, file); 16605e2b8828SMiklos Szeredi if (!ret) { 166160bcc88aSSeth Forshee /* 166260bcc88aSSeth Forshee * If filesystem supports acls it may have updated acl xattrs in 166360bcc88aSSeth Forshee * the filesystem, so forget cached acls for the inode. 166460bcc88aSSeth Forshee */ 166560bcc88aSSeth Forshee if (fc->posix_acl) 166660bcc88aSSeth Forshee forget_all_cached_acls(inode); 166760bcc88aSSeth Forshee 16685e2b8828SMiklos Szeredi /* Directory mode changed, may need to revalidate access */ 16695e2b8828SMiklos Szeredi if (d_is_dir(entry) && (attr->ia_valid & ATTR_MODE)) 16705e2b8828SMiklos Szeredi fuse_invalidate_entry_cache(entry); 16715e2b8828SMiklos Szeredi } 16725e2b8828SMiklos Szeredi return ret; 167349d4914fSMiklos Szeredi } 167449d4914fSMiklos Szeredi 1675a528d35eSDavid Howells static int fuse_getattr(const struct path *path, struct kstat *stat, 1676a528d35eSDavid Howells u32 request_mask, unsigned int flags) 1677e5e5558eSMiklos Szeredi { 1678a528d35eSDavid Howells struct inode *inode = d_inode(path->dentry); 1679244f6385SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(inode); 1680244f6385SMiklos Szeredi 1681c2132c1bSAnatol Pomozov if (!fuse_allow_current_process(fc)) 1682244f6385SMiklos Szeredi return -EACCES; 1683244f6385SMiklos Szeredi 16842f1e8196SMiklos Szeredi return fuse_update_get_attr(inode, NULL, stat, request_mask, flags); 1685e5e5558eSMiklos Szeredi } 1686e5e5558eSMiklos Szeredi 1687754661f1SArjan van de Ven static const struct inode_operations fuse_dir_inode_operations = { 1688e5e5558eSMiklos Szeredi .lookup = fuse_lookup, 16899e6268dbSMiklos Szeredi .mkdir = fuse_mkdir, 16909e6268dbSMiklos Szeredi .symlink = fuse_symlink, 16919e6268dbSMiklos Szeredi .unlink = fuse_unlink, 16929e6268dbSMiklos Szeredi .rmdir = fuse_rmdir, 16932773bf00SMiklos Szeredi .rename = fuse_rename2, 16949e6268dbSMiklos Szeredi .link = fuse_link, 16959e6268dbSMiklos Szeredi .setattr = fuse_setattr, 16969e6268dbSMiklos Szeredi .create = fuse_create, 1697c8ccbe03SMiklos Szeredi .atomic_open = fuse_atomic_open, 16989e6268dbSMiklos Szeredi .mknod = fuse_mknod, 1699e5e5558eSMiklos Szeredi .permission = fuse_permission, 1700e5e5558eSMiklos Szeredi .getattr = fuse_getattr, 170192a8780eSMiklos Szeredi .listxattr = fuse_listxattr, 170260bcc88aSSeth Forshee .get_acl = fuse_get_acl, 170360bcc88aSSeth Forshee .set_acl = fuse_set_acl, 1704e5e5558eSMiklos Szeredi }; 1705e5e5558eSMiklos Szeredi 17064b6f5d20SArjan van de Ven static const struct file_operations fuse_dir_operations = { 1707b6aeadedSMiklos Szeredi .llseek = generic_file_llseek, 1708e5e5558eSMiklos Szeredi .read = generic_read_dir, 1709d9b3dbdcSAl Viro .iterate_shared = fuse_readdir, 1710e5e5558eSMiklos Szeredi .open = fuse_dir_open, 1711e5e5558eSMiklos Szeredi .release = fuse_dir_release, 171282547981SMiklos Szeredi .fsync = fuse_dir_fsync, 1713b18da0c5SMiklos Szeredi .unlocked_ioctl = fuse_dir_ioctl, 1714b18da0c5SMiklos Szeredi .compat_ioctl = fuse_dir_compat_ioctl, 1715e5e5558eSMiklos Szeredi }; 1716e5e5558eSMiklos Szeredi 1717754661f1SArjan van de Ven static const struct inode_operations fuse_common_inode_operations = { 17189e6268dbSMiklos Szeredi .setattr = fuse_setattr, 1719e5e5558eSMiklos Szeredi .permission = fuse_permission, 1720e5e5558eSMiklos Szeredi .getattr = fuse_getattr, 172192a8780eSMiklos Szeredi .listxattr = fuse_listxattr, 172260bcc88aSSeth Forshee .get_acl = fuse_get_acl, 172360bcc88aSSeth Forshee .set_acl = fuse_set_acl, 1724e5e5558eSMiklos Szeredi }; 1725e5e5558eSMiklos Szeredi 1726754661f1SArjan van de Ven static const struct inode_operations fuse_symlink_inode_operations = { 17279e6268dbSMiklos Szeredi .setattr = fuse_setattr, 17286b255391SAl Viro .get_link = fuse_get_link, 1729e5e5558eSMiklos Szeredi .getattr = fuse_getattr, 173092a8780eSMiklos Szeredi .listxattr = fuse_listxattr, 1731e5e5558eSMiklos Szeredi }; 1732e5e5558eSMiklos Szeredi 1733e5e5558eSMiklos Szeredi void fuse_init_common(struct inode *inode) 1734e5e5558eSMiklos Szeredi { 1735e5e5558eSMiklos Szeredi inode->i_op = &fuse_common_inode_operations; 1736e5e5558eSMiklos Szeredi } 1737e5e5558eSMiklos Szeredi 1738e5e5558eSMiklos Szeredi void fuse_init_dir(struct inode *inode) 1739e5e5558eSMiklos Szeredi { 1740ab2257e9SMiklos Szeredi struct fuse_inode *fi = get_fuse_inode(inode); 1741ab2257e9SMiklos Szeredi 1742e5e5558eSMiklos Szeredi inode->i_op = &fuse_dir_inode_operations; 1743e5e5558eSMiklos Szeredi inode->i_fop = &fuse_dir_operations; 1744ab2257e9SMiklos Szeredi 1745ab2257e9SMiklos Szeredi spin_lock_init(&fi->rdc.lock); 1746ab2257e9SMiklos Szeredi fi->rdc.cached = false; 1747ab2257e9SMiklos Szeredi fi->rdc.size = 0; 1748ab2257e9SMiklos Szeredi fi->rdc.pos = 0; 1749ab2257e9SMiklos Szeredi fi->rdc.version = 0; 1750e5e5558eSMiklos Szeredi } 1751e5e5558eSMiklos Szeredi 17525571f1e6SDan Schatzberg static int fuse_symlink_readpage(struct file *null, struct page *page) 17535571f1e6SDan Schatzberg { 17545571f1e6SDan Schatzberg int err = fuse_readlink_page(page->mapping->host, page); 17555571f1e6SDan Schatzberg 17565571f1e6SDan Schatzberg if (!err) 17575571f1e6SDan Schatzberg SetPageUptodate(page); 17585571f1e6SDan Schatzberg 17595571f1e6SDan Schatzberg unlock_page(page); 17605571f1e6SDan Schatzberg 17615571f1e6SDan Schatzberg return err; 17625571f1e6SDan Schatzberg } 17635571f1e6SDan Schatzberg 17645571f1e6SDan Schatzberg static const struct address_space_operations fuse_symlink_aops = { 17655571f1e6SDan Schatzberg .readpage = fuse_symlink_readpage, 17665571f1e6SDan Schatzberg }; 17675571f1e6SDan Schatzberg 1768e5e5558eSMiklos Szeredi void fuse_init_symlink(struct inode *inode) 1769e5e5558eSMiklos Szeredi { 1770e5e5558eSMiklos Szeredi inode->i_op = &fuse_symlink_inode_operations; 17715571f1e6SDan Schatzberg inode->i_data.a_ops = &fuse_symlink_aops; 17725571f1e6SDan Schatzberg inode_nohighmem(inode); 1773e5e5558eSMiklos Szeredi } 1774