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> 13bf109c64SMax Reitz #include <linux/fs_context.h> 14e5e5558eSMiklos Szeredi #include <linux/sched.h> 15e5e5558eSMiklos Szeredi #include <linux/namei.h> 1607e77dcaSMiklos Szeredi #include <linux/slab.h> 17703c7362SSeth Forshee #include <linux/xattr.h> 18261aaba7SMiklos Szeredi #include <linux/iversion.h> 1960bcc88aSSeth Forshee #include <linux/posix_acl.h> 203e2b6fdbSVivek Goyal #include <linux/security.h> 213e2b6fdbSVivek Goyal #include <linux/types.h> 223e2b6fdbSVivek Goyal #include <linux/kernel.h> 23e5e5558eSMiklos Szeredi 244582a4abSFeng Shuo static void fuse_advise_use_readdirplus(struct inode *dir) 254582a4abSFeng Shuo { 264582a4abSFeng Shuo struct fuse_inode *fi = get_fuse_inode(dir); 274582a4abSFeng Shuo 284582a4abSFeng Shuo set_bit(FUSE_I_ADVISE_RDPLUS, &fi->state); 294582a4abSFeng Shuo } 304582a4abSFeng Shuo 3130c6a23dSKhazhismel Kumykov #if BITS_PER_LONG >= 64 3230c6a23dSKhazhismel Kumykov static inline void __fuse_dentry_settime(struct dentry *entry, u64 time) 3330c6a23dSKhazhismel Kumykov { 3430c6a23dSKhazhismel Kumykov entry->d_fsdata = (void *) time; 3530c6a23dSKhazhismel Kumykov } 3630c6a23dSKhazhismel Kumykov 3730c6a23dSKhazhismel Kumykov static inline u64 fuse_dentry_time(const struct dentry *entry) 3830c6a23dSKhazhismel Kumykov { 3930c6a23dSKhazhismel Kumykov return (u64)entry->d_fsdata; 4030c6a23dSKhazhismel Kumykov } 4130c6a23dSKhazhismel Kumykov 4230c6a23dSKhazhismel Kumykov #else 43f75fdf22SMiklos Szeredi union fuse_dentry { 44f75fdf22SMiklos Szeredi u64 time; 45f75fdf22SMiklos Szeredi struct rcu_head rcu; 46f75fdf22SMiklos Szeredi }; 47f75fdf22SMiklos Szeredi 4830c6a23dSKhazhismel Kumykov static inline void __fuse_dentry_settime(struct dentry *dentry, u64 time) 4930c6a23dSKhazhismel Kumykov { 5030c6a23dSKhazhismel Kumykov ((union fuse_dentry *) dentry->d_fsdata)->time = time; 5130c6a23dSKhazhismel Kumykov } 5230c6a23dSKhazhismel Kumykov 5330c6a23dSKhazhismel Kumykov static inline u64 fuse_dentry_time(const struct dentry *entry) 5430c6a23dSKhazhismel Kumykov { 5530c6a23dSKhazhismel Kumykov return ((union fuse_dentry *) entry->d_fsdata)->time; 5630c6a23dSKhazhismel Kumykov } 5730c6a23dSKhazhismel Kumykov #endif 5830c6a23dSKhazhismel Kumykov 598fab0106SMiklos Szeredi static void fuse_dentry_settime(struct dentry *dentry, u64 time) 600a0898cfSMiklos Szeredi { 618fab0106SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn_super(dentry->d_sb); 628fab0106SMiklos Szeredi bool delete = !time && fc->delete_stale; 638fab0106SMiklos Szeredi /* 648fab0106SMiklos Szeredi * Mess with DCACHE_OP_DELETE because dput() will be faster without it. 658fab0106SMiklos Szeredi * Don't care about races, either way it's just an optimization 668fab0106SMiklos Szeredi */ 678fab0106SMiklos Szeredi if ((!delete && (dentry->d_flags & DCACHE_OP_DELETE)) || 688fab0106SMiklos Szeredi (delete && !(dentry->d_flags & DCACHE_OP_DELETE))) { 698fab0106SMiklos Szeredi spin_lock(&dentry->d_lock); 708fab0106SMiklos Szeredi if (!delete) 718fab0106SMiklos Szeredi dentry->d_flags &= ~DCACHE_OP_DELETE; 728fab0106SMiklos Szeredi else 738fab0106SMiklos Szeredi dentry->d_flags |= DCACHE_OP_DELETE; 748fab0106SMiklos Szeredi spin_unlock(&dentry->d_lock); 750a0898cfSMiklos Szeredi } 760a0898cfSMiklos Szeredi 7730c6a23dSKhazhismel Kumykov __fuse_dentry_settime(dentry, time); 780a0898cfSMiklos Szeredi } 790a0898cfSMiklos Szeredi 806f9f1180SMiklos Szeredi /* 816f9f1180SMiklos Szeredi * FUSE caches dentries and attributes with separate timeout. The 826f9f1180SMiklos Szeredi * time in jiffies until the dentry/attributes are valid is stored in 83f75fdf22SMiklos Szeredi * dentry->d_fsdata and fuse_inode->i_time respectively. 846f9f1180SMiklos Szeredi */ 856f9f1180SMiklos Szeredi 866f9f1180SMiklos Szeredi /* 876f9f1180SMiklos Szeredi * Calculate the time in jiffies until a dentry/attributes are valid 886f9f1180SMiklos Szeredi */ 89bcb6f6d2SMiklos Szeredi static u64 time_to_jiffies(u64 sec, u32 nsec) 90e5e5558eSMiklos Szeredi { 91685d16ddSMiklos Szeredi if (sec || nsec) { 92bcb6f6d2SMiklos Szeredi struct timespec64 ts = { 93bcb6f6d2SMiklos Szeredi sec, 9421067527SDavid Sheets min_t(u32, nsec, NSEC_PER_SEC - 1) 95bcb6f6d2SMiklos Szeredi }; 96bcb6f6d2SMiklos Szeredi 97bcb6f6d2SMiklos Szeredi return get_jiffies_64() + timespec64_to_jiffies(&ts); 98685d16ddSMiklos Szeredi } else 990a0898cfSMiklos Szeredi return 0; 100e5e5558eSMiklos Szeredi } 101e5e5558eSMiklos Szeredi 1026f9f1180SMiklos Szeredi /* 1036f9f1180SMiklos Szeredi * Set dentry and possibly attribute timeouts from the lookup/mk* 1046f9f1180SMiklos Szeredi * replies 1056f9f1180SMiklos Szeredi */ 106d123d8e1SMiklos Szeredi void fuse_change_entry_timeout(struct dentry *entry, struct fuse_entry_out *o) 1070aa7c699SMiklos Szeredi { 1080a0898cfSMiklos Szeredi fuse_dentry_settime(entry, 1090a0898cfSMiklos Szeredi time_to_jiffies(o->entry_valid, o->entry_valid_nsec)); 1101fb69e78SMiklos Szeredi } 1111fb69e78SMiklos Szeredi 1121fb69e78SMiklos Szeredi static u64 attr_timeout(struct fuse_attr_out *o) 1131fb69e78SMiklos Szeredi { 1141fb69e78SMiklos Szeredi return time_to_jiffies(o->attr_valid, o->attr_valid_nsec); 1151fb69e78SMiklos Szeredi } 1161fb69e78SMiklos Szeredi 117d123d8e1SMiklos Szeredi u64 entry_attr_timeout(struct fuse_entry_out *o) 1181fb69e78SMiklos Szeredi { 1191fb69e78SMiklos Szeredi return time_to_jiffies(o->attr_valid, o->attr_valid_nsec); 1208cbdf1e6SMiklos Szeredi } 1218cbdf1e6SMiklos Szeredi 122fa5eee57SMiklos Szeredi void fuse_invalidate_attr_mask(struct inode *inode, u32 mask) 1232f1e8196SMiklos Szeredi { 1242f1e8196SMiklos Szeredi set_mask_bits(&get_fuse_inode(inode)->inval_mask, 0, mask); 1252f1e8196SMiklos Szeredi } 1262f1e8196SMiklos Szeredi 1276f9f1180SMiklos Szeredi /* 1286f9f1180SMiklos Szeredi * Mark the attributes as stale, so that at the next call to 1296f9f1180SMiklos Szeredi * ->getattr() they will be fetched from userspace 1306f9f1180SMiklos Szeredi */ 1318cbdf1e6SMiklos Szeredi void fuse_invalidate_attr(struct inode *inode) 1328cbdf1e6SMiklos Szeredi { 1332f1e8196SMiklos Szeredi fuse_invalidate_attr_mask(inode, STATX_BASIC_STATS); 1348cbdf1e6SMiklos Szeredi } 1358cbdf1e6SMiklos Szeredi 136261aaba7SMiklos Szeredi static void fuse_dir_changed(struct inode *dir) 137261aaba7SMiklos Szeredi { 138261aaba7SMiklos Szeredi fuse_invalidate_attr(dir); 139261aaba7SMiklos Szeredi inode_maybe_inc_iversion(dir, false); 140261aaba7SMiklos Szeredi } 141261aaba7SMiklos Szeredi 142451418fcSAndrew Gallagher /** 143451418fcSAndrew Gallagher * Mark the attributes as stale due to an atime change. Avoid the invalidate if 144451418fcSAndrew Gallagher * atime is not used. 145451418fcSAndrew Gallagher */ 146451418fcSAndrew Gallagher void fuse_invalidate_atime(struct inode *inode) 147451418fcSAndrew Gallagher { 148451418fcSAndrew Gallagher if (!IS_RDONLY(inode)) 1492f1e8196SMiklos Szeredi fuse_invalidate_attr_mask(inode, STATX_ATIME); 150451418fcSAndrew Gallagher } 151451418fcSAndrew Gallagher 1526f9f1180SMiklos Szeredi /* 1536f9f1180SMiklos Szeredi * Just mark the entry as stale, so that a next attempt to look it up 1546f9f1180SMiklos Szeredi * will result in a new lookup call to userspace 1556f9f1180SMiklos Szeredi * 1566f9f1180SMiklos Szeredi * This is called when a dentry is about to become negative and the 1576f9f1180SMiklos Szeredi * timeout is unknown (unlink, rmdir, rename and in some cases 1586f9f1180SMiklos Szeredi * lookup) 1596f9f1180SMiklos Szeredi */ 160dbd561d2SMiklos Szeredi void fuse_invalidate_entry_cache(struct dentry *entry) 1618cbdf1e6SMiklos Szeredi { 1620a0898cfSMiklos Szeredi fuse_dentry_settime(entry, 0); 1638cbdf1e6SMiklos Szeredi } 1648cbdf1e6SMiklos Szeredi 1656f9f1180SMiklos Szeredi /* 1666f9f1180SMiklos Szeredi * Same as fuse_invalidate_entry_cache(), but also try to remove the 1676f9f1180SMiklos Szeredi * dentry from the hash 1686f9f1180SMiklos Szeredi */ 1698cbdf1e6SMiklos Szeredi static void fuse_invalidate_entry(struct dentry *entry) 1708cbdf1e6SMiklos Szeredi { 1718cbdf1e6SMiklos Szeredi d_invalidate(entry); 1728cbdf1e6SMiklos Szeredi fuse_invalidate_entry_cache(entry); 1730aa7c699SMiklos Szeredi } 1740aa7c699SMiklos Szeredi 1757078187aSMiklos Szeredi static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_args *args, 17613983d06SAl Viro u64 nodeid, const struct qstr *name, 177e5e5558eSMiklos Szeredi struct fuse_entry_out *outarg) 178e5e5558eSMiklos Szeredi { 1790e9663eeSMiklos Szeredi memset(outarg, 0, sizeof(struct fuse_entry_out)); 180d5b48543SMiklos Szeredi args->opcode = FUSE_LOOKUP; 181d5b48543SMiklos Szeredi args->nodeid = nodeid; 182d5b48543SMiklos Szeredi args->in_numargs = 1; 183d5b48543SMiklos Szeredi args->in_args[0].size = name->len + 1; 184d5b48543SMiklos Szeredi args->in_args[0].value = name->name; 185d5b48543SMiklos Szeredi args->out_numargs = 1; 186d5b48543SMiklos Szeredi args->out_args[0].size = sizeof(struct fuse_entry_out); 187d5b48543SMiklos Szeredi args->out_args[0].value = outarg; 188e5e5558eSMiklos Szeredi } 189e5e5558eSMiklos Szeredi 1906f9f1180SMiklos Szeredi /* 1916f9f1180SMiklos Szeredi * Check whether the dentry is still valid 1926f9f1180SMiklos Szeredi * 1936f9f1180SMiklos Szeredi * If the entry validity timeout has expired and the dentry is 1946f9f1180SMiklos Szeredi * positive, try to redo the lookup. If the lookup results in a 1956f9f1180SMiklos Szeredi * different inode, then let the VFS invalidate the dentry and redo 1966f9f1180SMiklos Szeredi * the lookup once more. If the lookup results in the same inode, 1976f9f1180SMiklos Szeredi * then refresh the attributes, timeouts and mark the dentry valid. 1986f9f1180SMiklos Szeredi */ 1990b728e19SAl Viro static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags) 200e5e5558eSMiklos Szeredi { 20134286d66SNick Piggin struct inode *inode; 20228420dadSMiklos Szeredi struct dentry *parent; 203fcee216bSMax Reitz struct fuse_mount *fm; 2046314efeeSMiklos Szeredi struct fuse_inode *fi; 205e2a6b952SMiklos Szeredi int ret; 2068cbdf1e6SMiklos Szeredi 2072b0143b5SDavid Howells inode = d_inode_rcu(entry); 2085d069dbeSMiklos Szeredi if (inode && fuse_is_bad(inode)) 209e2a6b952SMiklos Szeredi goto invalid; 210154210ccSAnand Avati else if (time_before64(fuse_dentry_time(entry), get_jiffies_64()) || 211df8629afSMiklos Szeredi (flags & (LOOKUP_EXCL | LOOKUP_REVAL))) { 212e5e5558eSMiklos Szeredi struct fuse_entry_out outarg; 2137078187aSMiklos Szeredi FUSE_ARGS(args); 21407e77dcaSMiklos Szeredi struct fuse_forget_link *forget; 2151fb69e78SMiklos Szeredi u64 attr_version; 2168cbdf1e6SMiklos Szeredi 21750322fe7SMiklos Szeredi /* For negative dentries, always do a fresh lookup */ 2188cbdf1e6SMiklos Szeredi if (!inode) 219e2a6b952SMiklos Szeredi goto invalid; 2208cbdf1e6SMiklos Szeredi 221e2a6b952SMiklos Szeredi ret = -ECHILD; 2220b728e19SAl Viro if (flags & LOOKUP_RCU) 223e2a6b952SMiklos Szeredi goto out; 224e7c0a167SMiklos Szeredi 225fcee216bSMax Reitz fm = get_fuse_mount(inode); 226e5e5558eSMiklos Szeredi 22707e77dcaSMiklos Szeredi forget = fuse_alloc_forget(); 228e2a6b952SMiklos Szeredi ret = -ENOMEM; 2297078187aSMiklos Szeredi if (!forget) 230e2a6b952SMiklos Szeredi goto out; 2312d51013eSMiklos Szeredi 232fcee216bSMax Reitz attr_version = fuse_get_attr_version(fm->fc); 2331fb69e78SMiklos Szeredi 234e956edd0SMiklos Szeredi parent = dget_parent(entry); 235fcee216bSMax Reitz fuse_lookup_init(fm->fc, &args, get_node_id(d_inode(parent)), 236c180eebeSMiklos Szeredi &entry->d_name, &outarg); 237fcee216bSMax Reitz ret = fuse_simple_request(fm, &args); 238e956edd0SMiklos Szeredi dput(parent); 23950322fe7SMiklos Szeredi /* Zero nodeid is same as -ENOENT */ 2407078187aSMiklos Szeredi if (!ret && !outarg.nodeid) 2417078187aSMiklos Szeredi ret = -ENOENT; 2427078187aSMiklos Szeredi if (!ret) { 2436314efeeSMiklos Szeredi fi = get_fuse_inode(inode); 244bf109c64SMax Reitz if (outarg.nodeid != get_node_id(inode) || 245bf109c64SMax Reitz (bool) IS_AUTOMOUNT(inode) != (bool) (outarg.attr.flags & FUSE_ATTR_SUBMOUNT)) { 246fcee216bSMax Reitz fuse_queue_forget(fm->fc, forget, 247fcee216bSMax Reitz outarg.nodeid, 1); 248e2a6b952SMiklos Szeredi goto invalid; 2499e6268dbSMiklos Szeredi } 250c9d8f5f0SKirill Tkhai spin_lock(&fi->lock); 2519e6268dbSMiklos Szeredi fi->nlookup++; 252c9d8f5f0SKirill Tkhai spin_unlock(&fi->lock); 2539e6268dbSMiklos Szeredi } 25407e77dcaSMiklos Szeredi kfree(forget); 2557078187aSMiklos Szeredi if (ret == -ENOMEM) 2567078187aSMiklos Szeredi goto out; 257eb59bd17SMiklos Szeredi if (ret || fuse_invalid_attr(&outarg.attr) || 25815db1683SAmir Goldstein fuse_stale_inode(inode, outarg.generation, &outarg.attr)) 259e2a6b952SMiklos Szeredi goto invalid; 260e5e5558eSMiklos Szeredi 26160bcc88aSSeth Forshee forget_all_cached_acls(inode); 2621fb69e78SMiklos Szeredi fuse_change_attributes(inode, &outarg.attr, 2631fb69e78SMiklos Szeredi entry_attr_timeout(&outarg), 2641fb69e78SMiklos Szeredi attr_version); 2651fb69e78SMiklos Szeredi fuse_change_entry_timeout(entry, &outarg); 26628420dadSMiklos Szeredi } else if (inode) { 2676314efeeSMiklos Szeredi fi = get_fuse_inode(inode); 2686314efeeSMiklos Szeredi if (flags & LOOKUP_RCU) { 2696314efeeSMiklos Szeredi if (test_bit(FUSE_I_INIT_RDPLUS, &fi->state)) 2706314efeeSMiklos Szeredi return -ECHILD; 2716314efeeSMiklos Szeredi } else if (test_and_clear_bit(FUSE_I_INIT_RDPLUS, &fi->state)) { 27228420dadSMiklos Szeredi parent = dget_parent(entry); 2732b0143b5SDavid Howells fuse_advise_use_readdirplus(d_inode(parent)); 27428420dadSMiklos Szeredi dput(parent); 275e5e5558eSMiklos Szeredi } 27628420dadSMiklos Szeredi } 277e2a6b952SMiklos Szeredi ret = 1; 278e2a6b952SMiklos Szeredi out: 279e2a6b952SMiklos Szeredi return ret; 280e2a6b952SMiklos Szeredi 281e2a6b952SMiklos Szeredi invalid: 282e2a6b952SMiklos Szeredi ret = 0; 283e2a6b952SMiklos Szeredi goto out; 284e5e5558eSMiklos Szeredi } 285e5e5558eSMiklos Szeredi 28630c6a23dSKhazhismel Kumykov #if BITS_PER_LONG < 64 287f75fdf22SMiklos Szeredi static int fuse_dentry_init(struct dentry *dentry) 288f75fdf22SMiklos Szeredi { 289dc69e98cSKhazhismel Kumykov dentry->d_fsdata = kzalloc(sizeof(union fuse_dentry), 290dc69e98cSKhazhismel Kumykov GFP_KERNEL_ACCOUNT | __GFP_RECLAIMABLE); 291f75fdf22SMiklos Szeredi 292f75fdf22SMiklos Szeredi return dentry->d_fsdata ? 0 : -ENOMEM; 293f75fdf22SMiklos Szeredi } 294f75fdf22SMiklos Szeredi static void fuse_dentry_release(struct dentry *dentry) 295f75fdf22SMiklos Szeredi { 296f75fdf22SMiklos Szeredi union fuse_dentry *fd = dentry->d_fsdata; 297f75fdf22SMiklos Szeredi 298f75fdf22SMiklos Szeredi kfree_rcu(fd, rcu); 299f75fdf22SMiklos Szeredi } 30030c6a23dSKhazhismel Kumykov #endif 301f75fdf22SMiklos Szeredi 3028fab0106SMiklos Szeredi static int fuse_dentry_delete(const struct dentry *dentry) 3038fab0106SMiklos Szeredi { 3048fab0106SMiklos Szeredi return time_before64(fuse_dentry_time(dentry), get_jiffies_64()); 3058fab0106SMiklos Szeredi } 3068fab0106SMiklos Szeredi 307bf109c64SMax Reitz /* 308bf109c64SMax Reitz * Create a fuse_mount object with a new superblock (with path->dentry 309bf109c64SMax Reitz * as the root), and return that mount so it can be auto-mounted on 310bf109c64SMax Reitz * @path. 311bf109c64SMax Reitz */ 312bf109c64SMax Reitz static struct vfsmount *fuse_dentry_automount(struct path *path) 313bf109c64SMax Reitz { 314bf109c64SMax Reitz struct fs_context *fsc; 315bf109c64SMax Reitz struct vfsmount *mnt; 316bf109c64SMax Reitz struct fuse_inode *mp_fi = get_fuse_inode(d_inode(path->dentry)); 317bf109c64SMax Reitz 318bf109c64SMax Reitz fsc = fs_context_for_submount(path->mnt->mnt_sb->s_type, path->dentry); 31929e0e4dfSGreg Kurz if (IS_ERR(fsc)) 32029e0e4dfSGreg Kurz return ERR_CAST(fsc); 321bf109c64SMax Reitz 322266eb3f2SGreg Kurz /* Pass the FUSE inode of the mount for fuse_get_tree_submount() */ 323266eb3f2SGreg Kurz fsc->fs_private = mp_fi; 324266eb3f2SGreg Kurz 325bf109c64SMax Reitz /* Create the submount */ 32629e0e4dfSGreg Kurz mnt = fc_mount(fsc); 32729e0e4dfSGreg Kurz if (!IS_ERR(mnt)) 328bf109c64SMax Reitz mntget(mnt); 32929e0e4dfSGreg Kurz 330bf109c64SMax Reitz put_fs_context(fsc); 331bf109c64SMax Reitz return mnt; 332bf109c64SMax Reitz } 333bf109c64SMax Reitz 3344269590aSAl Viro const struct dentry_operations fuse_dentry_operations = { 335e5e5558eSMiklos Szeredi .d_revalidate = fuse_dentry_revalidate, 3368fab0106SMiklos Szeredi .d_delete = fuse_dentry_delete, 33730c6a23dSKhazhismel Kumykov #if BITS_PER_LONG < 64 338f75fdf22SMiklos Szeredi .d_init = fuse_dentry_init, 339f75fdf22SMiklos Szeredi .d_release = fuse_dentry_release, 34030c6a23dSKhazhismel Kumykov #endif 341bf109c64SMax Reitz .d_automount = fuse_dentry_automount, 342e5e5558eSMiklos Szeredi }; 343e5e5558eSMiklos Szeredi 3440ce267ffSMiklos Szeredi const struct dentry_operations fuse_root_dentry_operations = { 34530c6a23dSKhazhismel Kumykov #if BITS_PER_LONG < 64 3460ce267ffSMiklos Szeredi .d_init = fuse_dentry_init, 3470ce267ffSMiklos Szeredi .d_release = fuse_dentry_release, 34830c6a23dSKhazhismel Kumykov #endif 3490ce267ffSMiklos Szeredi }; 3500ce267ffSMiklos Szeredi 351a5bfffacSTimo Savola int fuse_valid_type(int m) 35239ee059aSMiklos Szeredi { 35339ee059aSMiklos Szeredi return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) || 35439ee059aSMiklos Szeredi S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m); 35539ee059aSMiklos Szeredi } 35639ee059aSMiklos Szeredi 357eb59bd17SMiklos Szeredi bool fuse_invalid_attr(struct fuse_attr *attr) 358eb59bd17SMiklos Szeredi { 359eb59bd17SMiklos Szeredi return !fuse_valid_type(attr->mode) || 360eb59bd17SMiklos Szeredi attr->size > LLONG_MAX; 361eb59bd17SMiklos Szeredi } 362eb59bd17SMiklos Szeredi 36313983d06SAl Viro int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name, 364c180eebeSMiklos Szeredi struct fuse_entry_out *outarg, struct inode **inode) 365c180eebeSMiklos Szeredi { 366fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount_super(sb); 3677078187aSMiklos Szeredi FUSE_ARGS(args); 36807e77dcaSMiklos Szeredi struct fuse_forget_link *forget; 369c180eebeSMiklos Szeredi u64 attr_version; 370c180eebeSMiklos Szeredi int err; 371c180eebeSMiklos Szeredi 372c180eebeSMiklos Szeredi *inode = NULL; 373c180eebeSMiklos Szeredi err = -ENAMETOOLONG; 374c180eebeSMiklos Szeredi if (name->len > FUSE_NAME_MAX) 375c180eebeSMiklos Szeredi goto out; 376c180eebeSMiklos Szeredi 377c180eebeSMiklos Szeredi 37807e77dcaSMiklos Szeredi forget = fuse_alloc_forget(); 37907e77dcaSMiklos Szeredi err = -ENOMEM; 3807078187aSMiklos Szeredi if (!forget) 381c180eebeSMiklos Szeredi goto out; 382c180eebeSMiklos Szeredi 383fcee216bSMax Reitz attr_version = fuse_get_attr_version(fm->fc); 384c180eebeSMiklos Szeredi 385fcee216bSMax Reitz fuse_lookup_init(fm->fc, &args, nodeid, name, outarg); 386fcee216bSMax Reitz err = fuse_simple_request(fm, &args); 387c180eebeSMiklos Szeredi /* Zero nodeid is same as -ENOENT, but with valid timeout */ 388c180eebeSMiklos Szeredi if (err || !outarg->nodeid) 389c180eebeSMiklos Szeredi goto out_put_forget; 390c180eebeSMiklos Szeredi 391c180eebeSMiklos Szeredi err = -EIO; 392c180eebeSMiklos Szeredi if (!outarg->nodeid) 393c180eebeSMiklos Szeredi goto out_put_forget; 394eb59bd17SMiklos Szeredi if (fuse_invalid_attr(&outarg->attr)) 395c180eebeSMiklos Szeredi goto out_put_forget; 396c180eebeSMiklos Szeredi 397c180eebeSMiklos Szeredi *inode = fuse_iget(sb, outarg->nodeid, outarg->generation, 398c180eebeSMiklos Szeredi &outarg->attr, entry_attr_timeout(outarg), 399c180eebeSMiklos Szeredi attr_version); 400c180eebeSMiklos Szeredi err = -ENOMEM; 401c180eebeSMiklos Szeredi if (!*inode) { 402fcee216bSMax Reitz fuse_queue_forget(fm->fc, forget, outarg->nodeid, 1); 403c180eebeSMiklos Szeredi goto out; 404c180eebeSMiklos Szeredi } 405c180eebeSMiklos Szeredi err = 0; 406c180eebeSMiklos Szeredi 407c180eebeSMiklos Szeredi out_put_forget: 40807e77dcaSMiklos Szeredi kfree(forget); 409c180eebeSMiklos Szeredi out: 410c180eebeSMiklos Szeredi return err; 411c180eebeSMiklos Szeredi } 412c180eebeSMiklos Szeredi 4130aa7c699SMiklos Szeredi static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, 41400cd8dd3SAl Viro unsigned int flags) 415e5e5558eSMiklos Szeredi { 416e5e5558eSMiklos Szeredi int err; 417e5e5558eSMiklos Szeredi struct fuse_entry_out outarg; 418c180eebeSMiklos Szeredi struct inode *inode; 4190de6256dSMiklos Szeredi struct dentry *newent; 420c180eebeSMiklos Szeredi bool outarg_valid = true; 42163576c13SMiklos Szeredi bool locked; 422e5e5558eSMiklos Szeredi 4235d069dbeSMiklos Szeredi if (fuse_is_bad(dir)) 4245d069dbeSMiklos Szeredi return ERR_PTR(-EIO); 4255d069dbeSMiklos Szeredi 42663576c13SMiklos Szeredi locked = fuse_lock_inode(dir); 427c180eebeSMiklos Szeredi err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name, 428c180eebeSMiklos Szeredi &outarg, &inode); 42963576c13SMiklos Szeredi fuse_unlock_inode(dir, locked); 430c180eebeSMiklos Szeredi if (err == -ENOENT) { 431c180eebeSMiklos Szeredi outarg_valid = false; 432c180eebeSMiklos Szeredi err = 0; 4332d51013eSMiklos Szeredi } 434c180eebeSMiklos Szeredi if (err) 435c180eebeSMiklos Szeredi goto out_err; 4362d51013eSMiklos Szeredi 437ee4e5271SMiklos Szeredi err = -EIO; 438c180eebeSMiklos Szeredi if (inode && get_node_id(inode) == FUSE_ROOT_ID) 439c180eebeSMiklos Szeredi goto out_iput; 440e5e5558eSMiklos Szeredi 44141d28bcaSAl Viro newent = d_splice_alias(inode, entry); 442c180eebeSMiklos Szeredi err = PTR_ERR(newent); 443c180eebeSMiklos Szeredi if (IS_ERR(newent)) 4445835f339SMiklos Szeredi goto out_err; 445d2a85164SMiklos Szeredi 4460de6256dSMiklos Szeredi entry = newent ? newent : entry; 447c180eebeSMiklos Szeredi if (outarg_valid) 4481fb69e78SMiklos Szeredi fuse_change_entry_timeout(entry, &outarg); 4498cbdf1e6SMiklos Szeredi else 4508cbdf1e6SMiklos Szeredi fuse_invalidate_entry_cache(entry); 451c180eebeSMiklos Szeredi 4526c26f717SMiklos Szeredi if (inode) 4534582a4abSFeng Shuo fuse_advise_use_readdirplus(dir); 4540de6256dSMiklos Szeredi return newent; 455c180eebeSMiklos Szeredi 456c180eebeSMiklos Szeredi out_iput: 457c180eebeSMiklos Szeredi iput(inode); 458c180eebeSMiklos Szeredi out_err: 459c180eebeSMiklos Szeredi return ERR_PTR(err); 460e5e5558eSMiklos Szeredi } 461e5e5558eSMiklos Szeredi 4623e2b6fdbSVivek Goyal static int get_security_context(struct dentry *entry, umode_t mode, 4633e2b6fdbSVivek Goyal void **security_ctx, u32 *security_ctxlen) 4643e2b6fdbSVivek Goyal { 4653e2b6fdbSVivek Goyal struct fuse_secctx *fctx; 4663e2b6fdbSVivek Goyal struct fuse_secctx_header *header; 4673e2b6fdbSVivek Goyal void *ctx = NULL, *ptr; 4683e2b6fdbSVivek Goyal u32 ctxlen, total_len = sizeof(*header); 4693e2b6fdbSVivek Goyal int err, nr_ctx = 0; 4703e2b6fdbSVivek Goyal const char *name; 4713e2b6fdbSVivek Goyal size_t namelen; 4723e2b6fdbSVivek Goyal 4733e2b6fdbSVivek Goyal err = security_dentry_init_security(entry, mode, &entry->d_name, 4743e2b6fdbSVivek Goyal &name, &ctx, &ctxlen); 4753e2b6fdbSVivek Goyal if (err) { 4763e2b6fdbSVivek Goyal if (err != -EOPNOTSUPP) 4773e2b6fdbSVivek Goyal goto out_err; 4783e2b6fdbSVivek Goyal /* No LSM is supporting this security hook. Ignore error */ 4793e2b6fdbSVivek Goyal ctxlen = 0; 4803e2b6fdbSVivek Goyal ctx = NULL; 4813e2b6fdbSVivek Goyal } 4823e2b6fdbSVivek Goyal 4833e2b6fdbSVivek Goyal if (ctxlen) { 4843e2b6fdbSVivek Goyal nr_ctx = 1; 4853e2b6fdbSVivek Goyal namelen = strlen(name) + 1; 4863e2b6fdbSVivek Goyal err = -EIO; 4873e2b6fdbSVivek Goyal if (WARN_ON(namelen > XATTR_NAME_MAX + 1 || ctxlen > S32_MAX)) 4883e2b6fdbSVivek Goyal goto out_err; 4893e2b6fdbSVivek Goyal total_len += FUSE_REC_ALIGN(sizeof(*fctx) + namelen + ctxlen); 4903e2b6fdbSVivek Goyal } 4913e2b6fdbSVivek Goyal 4923e2b6fdbSVivek Goyal err = -ENOMEM; 4933e2b6fdbSVivek Goyal header = ptr = kzalloc(total_len, GFP_KERNEL); 4943e2b6fdbSVivek Goyal if (!ptr) 4953e2b6fdbSVivek Goyal goto out_err; 4963e2b6fdbSVivek Goyal 4973e2b6fdbSVivek Goyal header->nr_secctx = nr_ctx; 4983e2b6fdbSVivek Goyal header->size = total_len; 4993e2b6fdbSVivek Goyal ptr += sizeof(*header); 5003e2b6fdbSVivek Goyal if (nr_ctx) { 5013e2b6fdbSVivek Goyal fctx = ptr; 5023e2b6fdbSVivek Goyal fctx->size = ctxlen; 5033e2b6fdbSVivek Goyal ptr += sizeof(*fctx); 5043e2b6fdbSVivek Goyal 5053e2b6fdbSVivek Goyal strcpy(ptr, name); 5063e2b6fdbSVivek Goyal ptr += namelen; 5073e2b6fdbSVivek Goyal 5083e2b6fdbSVivek Goyal memcpy(ptr, ctx, ctxlen); 5093e2b6fdbSVivek Goyal } 5103e2b6fdbSVivek Goyal *security_ctxlen = total_len; 5113e2b6fdbSVivek Goyal *security_ctx = header; 5123e2b6fdbSVivek Goyal err = 0; 5133e2b6fdbSVivek Goyal out_err: 5143e2b6fdbSVivek Goyal kfree(ctx); 5153e2b6fdbSVivek Goyal return err; 5163e2b6fdbSVivek Goyal } 5173e2b6fdbSVivek Goyal 5186f9f1180SMiklos Szeredi /* 5196f9f1180SMiklos Szeredi * Atomic create+open operation 5206f9f1180SMiklos Szeredi * 5216f9f1180SMiklos Szeredi * If the filesystem doesn't support this, then fall back to separate 5226f9f1180SMiklos Szeredi * 'mknod' + 'open' requests. 5236f9f1180SMiklos Szeredi */ 524d9585277SAl Viro static int fuse_create_open(struct inode *dir, struct dentry *entry, 52554d601cbSMiklos Szeredi struct file *file, unsigned int flags, 526b452a458SAl Viro umode_t mode) 527fd72faacSMiklos Szeredi { 528fd72faacSMiklos Szeredi int err; 529fd72faacSMiklos Szeredi struct inode *inode; 530fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(dir); 5317078187aSMiklos Szeredi FUSE_ARGS(args); 53207e77dcaSMiklos Szeredi struct fuse_forget_link *forget; 533e0a43ddcSMiklos Szeredi struct fuse_create_in inarg; 534fd72faacSMiklos Szeredi struct fuse_open_out outopen; 535fd72faacSMiklos Szeredi struct fuse_entry_out outentry; 536ebf84d0cSKirill Tkhai struct fuse_inode *fi; 537fd72faacSMiklos Szeredi struct fuse_file *ff; 5383e2b6fdbSVivek Goyal void *security_ctx = NULL; 5393e2b6fdbSVivek Goyal u32 security_ctxlen; 540fd72faacSMiklos Szeredi 541af109bcaSMiklos Szeredi /* Userspace expects S_IFREG in create mode */ 542af109bcaSMiklos Szeredi BUG_ON((mode & S_IFMT) != S_IFREG); 543af109bcaSMiklos Szeredi 54407e77dcaSMiklos Szeredi forget = fuse_alloc_forget(); 545c8ccbe03SMiklos Szeredi err = -ENOMEM; 54607e77dcaSMiklos Szeredi if (!forget) 547c8ccbe03SMiklos Szeredi goto out_err; 54851eb01e7SMiklos Szeredi 549ce1d5a49SMiklos Szeredi err = -ENOMEM; 550fcee216bSMax Reitz ff = fuse_file_alloc(fm); 551fd72faacSMiklos Szeredi if (!ff) 5527078187aSMiklos Szeredi goto out_put_forget_req; 553fd72faacSMiklos Szeredi 554fcee216bSMax Reitz if (!fm->fc->dont_mask) 555e0a43ddcSMiklos Szeredi mode &= ~current_umask(); 556e0a43ddcSMiklos Szeredi 557fd72faacSMiklos Szeredi flags &= ~O_NOCTTY; 558fd72faacSMiklos Szeredi memset(&inarg, 0, sizeof(inarg)); 5590e9663eeSMiklos Szeredi memset(&outentry, 0, sizeof(outentry)); 560fd72faacSMiklos Szeredi inarg.flags = flags; 561fd72faacSMiklos Szeredi inarg.mode = mode; 562e0a43ddcSMiklos Szeredi inarg.umask = current_umask(); 563643a666aSVivek Goyal 564643a666aSVivek Goyal if (fm->fc->handle_killpriv_v2 && (flags & O_TRUNC) && 565643a666aSVivek Goyal !(flags & O_EXCL) && !capable(CAP_FSETID)) { 566643a666aSVivek Goyal inarg.open_flags |= FUSE_OPEN_KILL_SUIDGID; 567643a666aSVivek Goyal } 568643a666aSVivek Goyal 569d5b48543SMiklos Szeredi args.opcode = FUSE_CREATE; 570d5b48543SMiklos Szeredi args.nodeid = get_node_id(dir); 571d5b48543SMiklos Szeredi args.in_numargs = 2; 572d5b48543SMiklos Szeredi args.in_args[0].size = sizeof(inarg); 573d5b48543SMiklos Szeredi args.in_args[0].value = &inarg; 574d5b48543SMiklos Szeredi args.in_args[1].size = entry->d_name.len + 1; 575d5b48543SMiklos Szeredi args.in_args[1].value = entry->d_name.name; 576d5b48543SMiklos Szeredi args.out_numargs = 2; 577d5b48543SMiklos Szeredi args.out_args[0].size = sizeof(outentry); 578d5b48543SMiklos Szeredi args.out_args[0].value = &outentry; 579d5b48543SMiklos Szeredi args.out_args[1].size = sizeof(outopen); 580d5b48543SMiklos Szeredi args.out_args[1].value = &outopen; 5813e2b6fdbSVivek Goyal 5823e2b6fdbSVivek Goyal if (fm->fc->init_security) { 5833e2b6fdbSVivek Goyal err = get_security_context(entry, mode, &security_ctx, 5843e2b6fdbSVivek Goyal &security_ctxlen); 5853e2b6fdbSVivek Goyal if (err) 5863e2b6fdbSVivek Goyal goto out_put_forget_req; 5873e2b6fdbSVivek Goyal 5883e2b6fdbSVivek Goyal args.in_numargs = 3; 5893e2b6fdbSVivek Goyal args.in_args[2].size = security_ctxlen; 5903e2b6fdbSVivek Goyal args.in_args[2].value = security_ctx; 5913e2b6fdbSVivek Goyal } 5923e2b6fdbSVivek Goyal 593fcee216bSMax Reitz err = fuse_simple_request(fm, &args); 5943e2b6fdbSVivek Goyal kfree(security_ctx); 595c8ccbe03SMiklos Szeredi if (err) 596fd72faacSMiklos Szeredi goto out_free_ff; 597fd72faacSMiklos Szeredi 598fd72faacSMiklos Szeredi err = -EIO; 599eb59bd17SMiklos Szeredi if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid) || 600eb59bd17SMiklos Szeredi fuse_invalid_attr(&outentry.attr)) 601fd72faacSMiklos Szeredi goto out_free_ff; 602fd72faacSMiklos Szeredi 603c7b7143cSMiklos Szeredi ff->fh = outopen.fh; 604c7b7143cSMiklos Szeredi ff->nodeid = outentry.nodeid; 605c7b7143cSMiklos Szeredi ff->open_flags = outopen.open_flags; 606fd72faacSMiklos Szeredi inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation, 6071fb69e78SMiklos Szeredi &outentry.attr, entry_attr_timeout(&outentry), 0); 608fd72faacSMiklos Szeredi if (!inode) { 609fd72faacSMiklos Szeredi flags &= ~(O_CREAT | O_EXCL | O_TRUNC); 610ebf84d0cSKirill Tkhai fuse_sync_release(NULL, ff, flags); 611fcee216bSMax Reitz fuse_queue_forget(fm->fc, forget, outentry.nodeid, 1); 612c8ccbe03SMiklos Szeredi err = -ENOMEM; 613c8ccbe03SMiklos Szeredi goto out_err; 614fd72faacSMiklos Szeredi } 61507e77dcaSMiklos Szeredi kfree(forget); 616fd72faacSMiklos Szeredi d_instantiate(entry, inode); 6171fb69e78SMiklos Szeredi fuse_change_entry_timeout(entry, &outentry); 618261aaba7SMiklos Szeredi fuse_dir_changed(dir); 619be12af3eSAl Viro err = finish_open(file, entry, generic_file_open); 62030d90494SAl Viro if (err) { 621ebf84d0cSKirill Tkhai fi = get_fuse_inode(inode); 622ebf84d0cSKirill Tkhai fuse_sync_release(fi, ff, flags); 623c8ccbe03SMiklos Szeredi } else { 624267d8444SMiklos Szeredi file->private_data = ff; 625c7b7143cSMiklos Szeredi fuse_finish_open(inode, file); 626c8ccbe03SMiklos Szeredi } 627d9585277SAl Viro return err; 628fd72faacSMiklos Szeredi 629fd72faacSMiklos Szeredi out_free_ff: 630fd72faacSMiklos Szeredi fuse_file_free(ff); 63151eb01e7SMiklos Szeredi out_put_forget_req: 63207e77dcaSMiklos Szeredi kfree(forget); 633c8ccbe03SMiklos Szeredi out_err: 634d9585277SAl Viro return err; 635c8ccbe03SMiklos Szeredi } 636c8ccbe03SMiklos Szeredi 637549c7297SChristian Brauner static int fuse_mknod(struct user_namespace *, struct inode *, struct dentry *, 638549c7297SChristian Brauner umode_t, dev_t); 639d9585277SAl Viro static int fuse_atomic_open(struct inode *dir, struct dentry *entry, 64030d90494SAl Viro struct file *file, unsigned flags, 64144907d79SAl Viro umode_t mode) 642c8ccbe03SMiklos Szeredi { 643c8ccbe03SMiklos Szeredi int err; 644c8ccbe03SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(dir); 645c8ccbe03SMiklos Szeredi struct dentry *res = NULL; 646c8ccbe03SMiklos Szeredi 6475d069dbeSMiklos Szeredi if (fuse_is_bad(dir)) 6485d069dbeSMiklos Szeredi return -EIO; 6495d069dbeSMiklos Szeredi 65000699ad8SAl Viro if (d_in_lookup(entry)) { 65100cd8dd3SAl Viro res = fuse_lookup(dir, entry, 0); 652c8ccbe03SMiklos Szeredi if (IS_ERR(res)) 653d9585277SAl Viro return PTR_ERR(res); 654c8ccbe03SMiklos Szeredi 655c8ccbe03SMiklos Szeredi if (res) 656c8ccbe03SMiklos Szeredi entry = res; 657c8ccbe03SMiklos Szeredi } 658c8ccbe03SMiklos Szeredi 6592b0143b5SDavid Howells if (!(flags & O_CREAT) || d_really_is_positive(entry)) 660c8ccbe03SMiklos Szeredi goto no_open; 661c8ccbe03SMiklos Szeredi 662c8ccbe03SMiklos Szeredi /* Only creates */ 66373a09dd9SAl Viro file->f_mode |= FMODE_CREATED; 664c8ccbe03SMiklos Szeredi 665c8ccbe03SMiklos Szeredi if (fc->no_create) 666c8ccbe03SMiklos Szeredi goto mknod; 667c8ccbe03SMiklos Szeredi 668b452a458SAl Viro err = fuse_create_open(dir, entry, file, flags, mode); 669d9585277SAl Viro if (err == -ENOSYS) { 670c8ccbe03SMiklos Szeredi fc->no_create = 1; 671c8ccbe03SMiklos Szeredi goto mknod; 672c8ccbe03SMiklos Szeredi } 673c8ccbe03SMiklos Szeredi out_dput: 674c8ccbe03SMiklos Szeredi dput(res); 675d9585277SAl Viro return err; 676c8ccbe03SMiklos Szeredi 677c8ccbe03SMiklos Szeredi mknod: 678549c7297SChristian Brauner err = fuse_mknod(&init_user_ns, dir, entry, mode, 0); 679d9585277SAl Viro if (err) 680c8ccbe03SMiklos Szeredi goto out_dput; 681c8ccbe03SMiklos Szeredi no_open: 682e45198a6SAl Viro return finish_no_open(file, res); 683fd72faacSMiklos Szeredi } 684fd72faacSMiklos Szeredi 6856f9f1180SMiklos Szeredi /* 6866f9f1180SMiklos Szeredi * Code shared between mknod, mkdir, symlink and link 6876f9f1180SMiklos Szeredi */ 688fcee216bSMax Reitz static int create_new_entry(struct fuse_mount *fm, struct fuse_args *args, 6899e6268dbSMiklos Szeredi struct inode *dir, struct dentry *entry, 690541af6a0SAl Viro umode_t mode) 6919e6268dbSMiklos Szeredi { 6929e6268dbSMiklos Szeredi struct fuse_entry_out outarg; 6939e6268dbSMiklos Szeredi struct inode *inode; 694c971e6a0SAl Viro struct dentry *d; 6959e6268dbSMiklos Szeredi int err; 69607e77dcaSMiklos Szeredi struct fuse_forget_link *forget; 6973e2b6fdbSVivek Goyal void *security_ctx = NULL; 6983e2b6fdbSVivek Goyal u32 security_ctxlen; 6992d51013eSMiklos Szeredi 7005d069dbeSMiklos Szeredi if (fuse_is_bad(dir)) 7015d069dbeSMiklos Szeredi return -EIO; 7025d069dbeSMiklos Szeredi 70307e77dcaSMiklos Szeredi forget = fuse_alloc_forget(); 7047078187aSMiklos Szeredi if (!forget) 70507e77dcaSMiklos Szeredi return -ENOMEM; 7069e6268dbSMiklos Szeredi 7070e9663eeSMiklos Szeredi memset(&outarg, 0, sizeof(outarg)); 708d5b48543SMiklos Szeredi args->nodeid = get_node_id(dir); 709d5b48543SMiklos Szeredi args->out_numargs = 1; 710d5b48543SMiklos Szeredi args->out_args[0].size = sizeof(outarg); 711d5b48543SMiklos Szeredi args->out_args[0].value = &outarg; 7123e2b6fdbSVivek Goyal 7133e2b6fdbSVivek Goyal if (fm->fc->init_security && args->opcode != FUSE_LINK) { 7143e2b6fdbSVivek Goyal err = get_security_context(entry, mode, &security_ctx, 7153e2b6fdbSVivek Goyal &security_ctxlen); 7163e2b6fdbSVivek Goyal if (err) 7173e2b6fdbSVivek Goyal goto out_put_forget_req; 7183e2b6fdbSVivek Goyal 7193e2b6fdbSVivek Goyal BUG_ON(args->in_numargs != 2); 7203e2b6fdbSVivek Goyal 7213e2b6fdbSVivek Goyal args->in_numargs = 3; 7223e2b6fdbSVivek Goyal args->in_args[2].size = security_ctxlen; 7233e2b6fdbSVivek Goyal args->in_args[2].value = security_ctx; 7243e2b6fdbSVivek Goyal } 7253e2b6fdbSVivek Goyal 726fcee216bSMax Reitz err = fuse_simple_request(fm, args); 7273e2b6fdbSVivek Goyal kfree(security_ctx); 7282d51013eSMiklos Szeredi if (err) 7292d51013eSMiklos Szeredi goto out_put_forget_req; 7302d51013eSMiklos Szeredi 73139ee059aSMiklos Szeredi err = -EIO; 732eb59bd17SMiklos Szeredi if (invalid_nodeid(outarg.nodeid) || fuse_invalid_attr(&outarg.attr)) 7332d51013eSMiklos Szeredi goto out_put_forget_req; 73439ee059aSMiklos Szeredi 73539ee059aSMiklos Szeredi if ((outarg.attr.mode ^ mode) & S_IFMT) 7362d51013eSMiklos Szeredi goto out_put_forget_req; 73739ee059aSMiklos Szeredi 7389e6268dbSMiklos Szeredi inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, 7391fb69e78SMiklos Szeredi &outarg.attr, entry_attr_timeout(&outarg), 0); 7409e6268dbSMiklos Szeredi if (!inode) { 741fcee216bSMax Reitz fuse_queue_forget(fm->fc, forget, outarg.nodeid, 1); 7429e6268dbSMiklos Szeredi return -ENOMEM; 7439e6268dbSMiklos Szeredi } 74407e77dcaSMiklos Szeredi kfree(forget); 7459e6268dbSMiklos Szeredi 746c971e6a0SAl Viro d_drop(entry); 747c971e6a0SAl Viro d = d_splice_alias(inode, entry); 748c971e6a0SAl Viro if (IS_ERR(d)) 749c971e6a0SAl Viro return PTR_ERR(d); 750d2a85164SMiklos Szeredi 751c971e6a0SAl Viro if (d) { 752c971e6a0SAl Viro fuse_change_entry_timeout(d, &outarg); 753c971e6a0SAl Viro dput(d); 754c971e6a0SAl Viro } else { 7551fb69e78SMiklos Szeredi fuse_change_entry_timeout(entry, &outarg); 756c971e6a0SAl Viro } 757261aaba7SMiklos Szeredi fuse_dir_changed(dir); 7589e6268dbSMiklos Szeredi return 0; 75939ee059aSMiklos Szeredi 7602d51013eSMiklos Szeredi out_put_forget_req: 76107e77dcaSMiklos Szeredi kfree(forget); 76239ee059aSMiklos Szeredi return err; 7639e6268dbSMiklos Szeredi } 7649e6268dbSMiklos Szeredi 765549c7297SChristian Brauner static int fuse_mknod(struct user_namespace *mnt_userns, struct inode *dir, 766549c7297SChristian Brauner struct dentry *entry, umode_t mode, dev_t rdev) 7679e6268dbSMiklos Szeredi { 7689e6268dbSMiklos Szeredi struct fuse_mknod_in inarg; 769fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(dir); 7707078187aSMiklos Szeredi FUSE_ARGS(args); 7719e6268dbSMiklos Szeredi 772fcee216bSMax Reitz if (!fm->fc->dont_mask) 773e0a43ddcSMiklos Szeredi mode &= ~current_umask(); 774e0a43ddcSMiklos Szeredi 7759e6268dbSMiklos Szeredi memset(&inarg, 0, sizeof(inarg)); 7769e6268dbSMiklos Szeredi inarg.mode = mode; 7779e6268dbSMiklos Szeredi inarg.rdev = new_encode_dev(rdev); 778e0a43ddcSMiklos Szeredi inarg.umask = current_umask(); 779d5b48543SMiklos Szeredi args.opcode = FUSE_MKNOD; 780d5b48543SMiklos Szeredi args.in_numargs = 2; 781d5b48543SMiklos Szeredi args.in_args[0].size = sizeof(inarg); 782d5b48543SMiklos Szeredi args.in_args[0].value = &inarg; 783d5b48543SMiklos Szeredi args.in_args[1].size = entry->d_name.len + 1; 784d5b48543SMiklos Szeredi args.in_args[1].value = entry->d_name.name; 785fcee216bSMax Reitz return create_new_entry(fm, &args, dir, entry, mode); 7869e6268dbSMiklos Szeredi } 7879e6268dbSMiklos Szeredi 788549c7297SChristian Brauner static int fuse_create(struct user_namespace *mnt_userns, struct inode *dir, 789549c7297SChristian Brauner struct dentry *entry, umode_t mode, bool excl) 7909e6268dbSMiklos Szeredi { 791549c7297SChristian Brauner return fuse_mknod(&init_user_ns, dir, entry, mode, 0); 7929e6268dbSMiklos Szeredi } 7939e6268dbSMiklos Szeredi 794549c7297SChristian Brauner static int fuse_mkdir(struct user_namespace *mnt_userns, struct inode *dir, 795549c7297SChristian Brauner struct dentry *entry, umode_t mode) 7969e6268dbSMiklos Szeredi { 7979e6268dbSMiklos Szeredi struct fuse_mkdir_in inarg; 798fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(dir); 7997078187aSMiklos Szeredi FUSE_ARGS(args); 8009e6268dbSMiklos Szeredi 801fcee216bSMax Reitz if (!fm->fc->dont_mask) 802e0a43ddcSMiklos Szeredi mode &= ~current_umask(); 803e0a43ddcSMiklos Szeredi 8049e6268dbSMiklos Szeredi memset(&inarg, 0, sizeof(inarg)); 8059e6268dbSMiklos Szeredi inarg.mode = mode; 806e0a43ddcSMiklos Szeredi inarg.umask = current_umask(); 807d5b48543SMiklos Szeredi args.opcode = FUSE_MKDIR; 808d5b48543SMiklos Szeredi args.in_numargs = 2; 809d5b48543SMiklos Szeredi args.in_args[0].size = sizeof(inarg); 810d5b48543SMiklos Szeredi args.in_args[0].value = &inarg; 811d5b48543SMiklos Szeredi args.in_args[1].size = entry->d_name.len + 1; 812d5b48543SMiklos Szeredi args.in_args[1].value = entry->d_name.name; 813fcee216bSMax Reitz return create_new_entry(fm, &args, dir, entry, S_IFDIR); 8149e6268dbSMiklos Szeredi } 8159e6268dbSMiklos Szeredi 816549c7297SChristian Brauner static int fuse_symlink(struct user_namespace *mnt_userns, struct inode *dir, 817549c7297SChristian Brauner struct dentry *entry, const char *link) 8189e6268dbSMiklos Szeredi { 819fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(dir); 8209e6268dbSMiklos Szeredi unsigned len = strlen(link) + 1; 8217078187aSMiklos Szeredi FUSE_ARGS(args); 8229e6268dbSMiklos Szeredi 823d5b48543SMiklos Szeredi args.opcode = FUSE_SYMLINK; 824d5b48543SMiklos Szeredi args.in_numargs = 2; 825d5b48543SMiklos Szeredi args.in_args[0].size = entry->d_name.len + 1; 826d5b48543SMiklos Szeredi args.in_args[0].value = entry->d_name.name; 827d5b48543SMiklos Szeredi args.in_args[1].size = len; 828d5b48543SMiklos Szeredi args.in_args[1].value = link; 829fcee216bSMax Reitz return create_new_entry(fm, &args, dir, entry, S_IFLNK); 8309e6268dbSMiklos Szeredi } 8319e6268dbSMiklos Szeredi 8325c791fe1SMiklos Szeredi void fuse_flush_time_update(struct inode *inode) 8335c791fe1SMiklos Szeredi { 8345c791fe1SMiklos Szeredi int err = sync_inode_metadata(inode, 1); 8355c791fe1SMiklos Szeredi 8365c791fe1SMiklos Szeredi mapping_set_error(inode->i_mapping, err); 8375c791fe1SMiklos Szeredi } 8385c791fe1SMiklos Szeredi 83997f044f6SMiklos Szeredi static void fuse_update_ctime_in_cache(struct inode *inode) 84031f3267bSMaxim Patlasov { 84131f3267bSMaxim Patlasov if (!IS_NOCMTIME(inode)) { 842c2050a45SDeepa Dinamani inode->i_ctime = current_time(inode); 84331f3267bSMaxim Patlasov mark_inode_dirty_sync(inode); 8445c791fe1SMiklos Szeredi fuse_flush_time_update(inode); 84531f3267bSMaxim Patlasov } 84631f3267bSMaxim Patlasov } 84731f3267bSMaxim Patlasov 84897f044f6SMiklos Szeredi void fuse_update_ctime(struct inode *inode) 84997f044f6SMiklos Szeredi { 850fa5eee57SMiklos Szeredi fuse_invalidate_attr_mask(inode, STATX_CTIME); 85197f044f6SMiklos Szeredi fuse_update_ctime_in_cache(inode); 85297f044f6SMiklos Szeredi } 85397f044f6SMiklos Szeredi 854cefd1b83SMiklos Szeredi static void fuse_entry_unlinked(struct dentry *entry) 855cefd1b83SMiklos Szeredi { 856cefd1b83SMiklos Szeredi struct inode *inode = d_inode(entry); 857cefd1b83SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(inode); 858cefd1b83SMiklos Szeredi struct fuse_inode *fi = get_fuse_inode(inode); 859cefd1b83SMiklos Szeredi 860cefd1b83SMiklos Szeredi spin_lock(&fi->lock); 861cefd1b83SMiklos Szeredi fi->attr_version = atomic64_inc_return(&fc->attr_version); 862cefd1b83SMiklos Szeredi /* 863cefd1b83SMiklos Szeredi * If i_nlink == 0 then unlink doesn't make sense, yet this can 864cefd1b83SMiklos Szeredi * happen if userspace filesystem is careless. It would be 865cefd1b83SMiklos Szeredi * difficult to enforce correct nlink usage so just ignore this 866cefd1b83SMiklos Szeredi * condition here 867cefd1b83SMiklos Szeredi */ 868cefd1b83SMiklos Szeredi if (S_ISDIR(inode->i_mode)) 869cefd1b83SMiklos Szeredi clear_nlink(inode); 870cefd1b83SMiklos Szeredi else if (inode->i_nlink > 0) 871cefd1b83SMiklos Szeredi drop_nlink(inode); 872cefd1b83SMiklos Szeredi spin_unlock(&fi->lock); 873cefd1b83SMiklos Szeredi fuse_invalidate_entry_cache(entry); 874cefd1b83SMiklos Szeredi fuse_update_ctime(inode); 875cefd1b83SMiklos Szeredi } 876cefd1b83SMiklos Szeredi 8779e6268dbSMiklos Szeredi static int fuse_unlink(struct inode *dir, struct dentry *entry) 8789e6268dbSMiklos Szeredi { 8799e6268dbSMiklos Szeredi int err; 880fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(dir); 8817078187aSMiklos Szeredi FUSE_ARGS(args); 8829e6268dbSMiklos Szeredi 8835d069dbeSMiklos Szeredi if (fuse_is_bad(dir)) 8845d069dbeSMiklos Szeredi return -EIO; 8855d069dbeSMiklos Szeredi 886d5b48543SMiklos Szeredi args.opcode = FUSE_UNLINK; 887d5b48543SMiklos Szeredi args.nodeid = get_node_id(dir); 888d5b48543SMiklos Szeredi args.in_numargs = 1; 889d5b48543SMiklos Szeredi args.in_args[0].size = entry->d_name.len + 1; 890d5b48543SMiklos Szeredi args.in_args[0].value = entry->d_name.name; 891fcee216bSMax Reitz err = fuse_simple_request(fm, &args); 8929e6268dbSMiklos Szeredi if (!err) { 893261aaba7SMiklos Szeredi fuse_dir_changed(dir); 894cefd1b83SMiklos Szeredi fuse_entry_unlinked(entry); 8959e6268dbSMiklos Szeredi } else if (err == -EINTR) 8969e6268dbSMiklos Szeredi fuse_invalidate_entry(entry); 8979e6268dbSMiklos Szeredi return err; 8989e6268dbSMiklos Szeredi } 8999e6268dbSMiklos Szeredi 9009e6268dbSMiklos Szeredi static int fuse_rmdir(struct inode *dir, struct dentry *entry) 9019e6268dbSMiklos Szeredi { 9029e6268dbSMiklos Szeredi int err; 903fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(dir); 9047078187aSMiklos Szeredi FUSE_ARGS(args); 9059e6268dbSMiklos Szeredi 9065d069dbeSMiklos Szeredi if (fuse_is_bad(dir)) 9075d069dbeSMiklos Szeredi return -EIO; 9085d069dbeSMiklos Szeredi 909d5b48543SMiklos Szeredi args.opcode = FUSE_RMDIR; 910d5b48543SMiklos Szeredi args.nodeid = get_node_id(dir); 911d5b48543SMiklos Szeredi args.in_numargs = 1; 912d5b48543SMiklos Szeredi args.in_args[0].size = entry->d_name.len + 1; 913d5b48543SMiklos Szeredi args.in_args[0].value = entry->d_name.name; 914fcee216bSMax Reitz err = fuse_simple_request(fm, &args); 9159e6268dbSMiklos Szeredi if (!err) { 916261aaba7SMiklos Szeredi fuse_dir_changed(dir); 917cefd1b83SMiklos Szeredi fuse_entry_unlinked(entry); 9189e6268dbSMiklos Szeredi } else if (err == -EINTR) 9199e6268dbSMiklos Szeredi fuse_invalidate_entry(entry); 9209e6268dbSMiklos Szeredi return err; 9219e6268dbSMiklos Szeredi } 9229e6268dbSMiklos Szeredi 9231560c974SMiklos Szeredi static int fuse_rename_common(struct inode *olddir, struct dentry *oldent, 9241560c974SMiklos Szeredi struct inode *newdir, struct dentry *newent, 9251560c974SMiklos Szeredi unsigned int flags, int opcode, size_t argsize) 9269e6268dbSMiklos Szeredi { 9279e6268dbSMiklos Szeredi int err; 9281560c974SMiklos Szeredi struct fuse_rename2_in inarg; 929fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(olddir); 9307078187aSMiklos Szeredi FUSE_ARGS(args); 9319e6268dbSMiklos Szeredi 9321560c974SMiklos Szeredi memset(&inarg, 0, argsize); 9339e6268dbSMiklos Szeredi inarg.newdir = get_node_id(newdir); 9341560c974SMiklos Szeredi inarg.flags = flags; 935d5b48543SMiklos Szeredi args.opcode = opcode; 936d5b48543SMiklos Szeredi args.nodeid = get_node_id(olddir); 937d5b48543SMiklos Szeredi args.in_numargs = 3; 938d5b48543SMiklos Szeredi args.in_args[0].size = argsize; 939d5b48543SMiklos Szeredi args.in_args[0].value = &inarg; 940d5b48543SMiklos Szeredi args.in_args[1].size = oldent->d_name.len + 1; 941d5b48543SMiklos Szeredi args.in_args[1].value = oldent->d_name.name; 942d5b48543SMiklos Szeredi args.in_args[2].size = newent->d_name.len + 1; 943d5b48543SMiklos Szeredi args.in_args[2].value = newent->d_name.name; 944fcee216bSMax Reitz err = fuse_simple_request(fm, &args); 9459e6268dbSMiklos Szeredi if (!err) { 94608b63307SMiklos Szeredi /* ctime changes */ 9472b0143b5SDavid Howells fuse_update_ctime(d_inode(oldent)); 94808b63307SMiklos Szeredi 949371e8fd0SMiklos Szeredi if (flags & RENAME_EXCHANGE) 9502b0143b5SDavid Howells fuse_update_ctime(d_inode(newent)); 9511560c974SMiklos Szeredi 952261aaba7SMiklos Szeredi fuse_dir_changed(olddir); 9539e6268dbSMiklos Szeredi if (olddir != newdir) 954261aaba7SMiklos Szeredi fuse_dir_changed(newdir); 9558cbdf1e6SMiklos Szeredi 9568cbdf1e6SMiklos Szeredi /* newent will end up negative */ 957cefd1b83SMiklos Szeredi if (!(flags & RENAME_EXCHANGE) && d_really_is_positive(newent)) 958cefd1b83SMiklos Szeredi fuse_entry_unlinked(newent); 9599e6268dbSMiklos Szeredi } else if (err == -EINTR) { 9609e6268dbSMiklos Szeredi /* If request was interrupted, DEITY only knows if the 9619e6268dbSMiklos Szeredi rename actually took place. If the invalidation 9629e6268dbSMiklos Szeredi fails (e.g. some process has CWD under the renamed 9639e6268dbSMiklos Szeredi directory), then there can be inconsistency between 9649e6268dbSMiklos Szeredi the dcache and the real filesystem. Tough luck. */ 9659e6268dbSMiklos Szeredi fuse_invalidate_entry(oldent); 9662b0143b5SDavid Howells if (d_really_is_positive(newent)) 9679e6268dbSMiklos Szeredi fuse_invalidate_entry(newent); 9689e6268dbSMiklos Szeredi } 9699e6268dbSMiklos Szeredi 9709e6268dbSMiklos Szeredi return err; 9719e6268dbSMiklos Szeredi } 9729e6268dbSMiklos Szeredi 973549c7297SChristian Brauner static int fuse_rename2(struct user_namespace *mnt_userns, struct inode *olddir, 974549c7297SChristian Brauner struct dentry *oldent, struct inode *newdir, 975549c7297SChristian Brauner struct dentry *newent, unsigned int flags) 9761560c974SMiklos Szeredi { 9771560c974SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(olddir); 9781560c974SMiklos Szeredi int err; 9791560c974SMiklos Szeredi 9805d069dbeSMiklos Szeredi if (fuse_is_bad(olddir)) 9815d069dbeSMiklos Szeredi return -EIO; 9825d069dbeSMiklos Szeredi 983519525faSVivek Goyal if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT)) 9841560c974SMiklos Szeredi return -EINVAL; 9851560c974SMiklos Szeredi 9864237ba43SMiklos Szeredi if (flags) { 9871560c974SMiklos Szeredi if (fc->no_rename2 || fc->minor < 23) 9881560c974SMiklos Szeredi return -EINVAL; 9891560c974SMiklos Szeredi 9901560c974SMiklos Szeredi err = fuse_rename_common(olddir, oldent, newdir, newent, flags, 9914237ba43SMiklos Szeredi FUSE_RENAME2, 9924237ba43SMiklos Szeredi sizeof(struct fuse_rename2_in)); 9931560c974SMiklos Szeredi if (err == -ENOSYS) { 9941560c974SMiklos Szeredi fc->no_rename2 = 1; 9951560c974SMiklos Szeredi err = -EINVAL; 9961560c974SMiklos Szeredi } 9974237ba43SMiklos Szeredi } else { 9984237ba43SMiklos Szeredi err = fuse_rename_common(olddir, oldent, newdir, newent, 0, 9994237ba43SMiklos Szeredi FUSE_RENAME, 10004237ba43SMiklos Szeredi sizeof(struct fuse_rename_in)); 10014237ba43SMiklos Szeredi } 10021560c974SMiklos Szeredi 10034237ba43SMiklos Szeredi return err; 10044237ba43SMiklos Szeredi } 10054237ba43SMiklos Szeredi 10069e6268dbSMiklos Szeredi static int fuse_link(struct dentry *entry, struct inode *newdir, 10079e6268dbSMiklos Szeredi struct dentry *newent) 10089e6268dbSMiklos Szeredi { 10099e6268dbSMiklos Szeredi int err; 10109e6268dbSMiklos Szeredi struct fuse_link_in inarg; 10112b0143b5SDavid Howells struct inode *inode = d_inode(entry); 1012fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(inode); 10137078187aSMiklos Szeredi FUSE_ARGS(args); 10149e6268dbSMiklos Szeredi 10159e6268dbSMiklos Szeredi memset(&inarg, 0, sizeof(inarg)); 10169e6268dbSMiklos Szeredi inarg.oldnodeid = get_node_id(inode); 1017d5b48543SMiklos Szeredi args.opcode = FUSE_LINK; 1018d5b48543SMiklos Szeredi args.in_numargs = 2; 1019d5b48543SMiklos Szeredi args.in_args[0].size = sizeof(inarg); 1020d5b48543SMiklos Szeredi args.in_args[0].value = &inarg; 1021d5b48543SMiklos Szeredi args.in_args[1].size = newent->d_name.len + 1; 1022d5b48543SMiklos Szeredi args.in_args[1].value = newent->d_name.name; 1023fcee216bSMax Reitz err = create_new_entry(fm, &args, newdir, newent, inode->i_mode); 102497f044f6SMiklos Szeredi if (!err) 102597f044f6SMiklos Szeredi fuse_update_ctime_in_cache(inode); 102697f044f6SMiklos Szeredi else if (err == -EINTR) 1027ac45d613SMiklos Szeredi fuse_invalidate_attr(inode); 102897f044f6SMiklos Szeredi 10299e6268dbSMiklos Szeredi return err; 10309e6268dbSMiklos Szeredi } 10319e6268dbSMiklos Szeredi 10321fb69e78SMiklos Szeredi static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr, 10331fb69e78SMiklos Szeredi struct kstat *stat) 10341fb69e78SMiklos Szeredi { 1035203627bbSMiklos Szeredi unsigned int blkbits; 10368373200bSPavel Emelyanov struct fuse_conn *fc = get_fuse_conn(inode); 10378373200bSPavel Emelyanov 10381fb69e78SMiklos Szeredi stat->dev = inode->i_sb->s_dev; 10391fb69e78SMiklos Szeredi stat->ino = attr->ino; 10401fb69e78SMiklos Szeredi stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777); 10411fb69e78SMiklos Szeredi stat->nlink = attr->nlink; 10428cb08329SEric W. Biederman stat->uid = make_kuid(fc->user_ns, attr->uid); 10438cb08329SEric W. Biederman stat->gid = make_kgid(fc->user_ns, attr->gid); 10441fb69e78SMiklos Szeredi stat->rdev = inode->i_rdev; 10451fb69e78SMiklos Szeredi stat->atime.tv_sec = attr->atime; 10461fb69e78SMiklos Szeredi stat->atime.tv_nsec = attr->atimensec; 10471fb69e78SMiklos Szeredi stat->mtime.tv_sec = attr->mtime; 10481fb69e78SMiklos Szeredi stat->mtime.tv_nsec = attr->mtimensec; 10491fb69e78SMiklos Szeredi stat->ctime.tv_sec = attr->ctime; 10501fb69e78SMiklos Szeredi stat->ctime.tv_nsec = attr->ctimensec; 10511fb69e78SMiklos Szeredi stat->size = attr->size; 10521fb69e78SMiklos Szeredi stat->blocks = attr->blocks; 1053203627bbSMiklos Szeredi 1054203627bbSMiklos Szeredi if (attr->blksize != 0) 1055203627bbSMiklos Szeredi blkbits = ilog2(attr->blksize); 1056203627bbSMiklos Szeredi else 1057203627bbSMiklos Szeredi blkbits = inode->i_sb->s_blocksize_bits; 1058203627bbSMiklos Szeredi 1059203627bbSMiklos Szeredi stat->blksize = 1 << blkbits; 10601fb69e78SMiklos Szeredi } 10611fb69e78SMiklos Szeredi 1062c79e322fSMiklos Szeredi static int fuse_do_getattr(struct inode *inode, struct kstat *stat, 1063c79e322fSMiklos Szeredi struct file *file) 1064e5e5558eSMiklos Szeredi { 1065e5e5558eSMiklos Szeredi int err; 1066c79e322fSMiklos Szeredi struct fuse_getattr_in inarg; 1067c79e322fSMiklos Szeredi struct fuse_attr_out outarg; 1068fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(inode); 10697078187aSMiklos Szeredi FUSE_ARGS(args); 10701fb69e78SMiklos Szeredi u64 attr_version; 10711fb69e78SMiklos Szeredi 1072fcee216bSMax Reitz attr_version = fuse_get_attr_version(fm->fc); 10731fb69e78SMiklos Szeredi 1074c79e322fSMiklos Szeredi memset(&inarg, 0, sizeof(inarg)); 10750e9663eeSMiklos Szeredi memset(&outarg, 0, sizeof(outarg)); 1076c79e322fSMiklos Szeredi /* Directories have separate file-handle space */ 1077c79e322fSMiklos Szeredi if (file && S_ISREG(inode->i_mode)) { 1078c79e322fSMiklos Szeredi struct fuse_file *ff = file->private_data; 1079c79e322fSMiklos Szeredi 1080c79e322fSMiklos Szeredi inarg.getattr_flags |= FUSE_GETATTR_FH; 1081c79e322fSMiklos Szeredi inarg.fh = ff->fh; 1082c79e322fSMiklos Szeredi } 1083d5b48543SMiklos Szeredi args.opcode = FUSE_GETATTR; 1084d5b48543SMiklos Szeredi args.nodeid = get_node_id(inode); 1085d5b48543SMiklos Szeredi args.in_numargs = 1; 1086d5b48543SMiklos Szeredi args.in_args[0].size = sizeof(inarg); 1087d5b48543SMiklos Szeredi args.in_args[0].value = &inarg; 1088d5b48543SMiklos Szeredi args.out_numargs = 1; 1089d5b48543SMiklos Szeredi args.out_args[0].size = sizeof(outarg); 1090d5b48543SMiklos Szeredi args.out_args[0].value = &outarg; 1091fcee216bSMax Reitz err = fuse_simple_request(fm, &args); 1092e5e5558eSMiklos Szeredi if (!err) { 1093eb59bd17SMiklos Szeredi if (fuse_invalid_attr(&outarg.attr) || 10946e3e2c43SAl Viro inode_wrong_type(inode, outarg.attr.mode)) { 10955d069dbeSMiklos Szeredi fuse_make_bad(inode); 1096e5e5558eSMiklos Szeredi err = -EIO; 1097e5e5558eSMiklos Szeredi } else { 1098c79e322fSMiklos Szeredi fuse_change_attributes(inode, &outarg.attr, 1099c79e322fSMiklos Szeredi attr_timeout(&outarg), 11001fb69e78SMiklos Szeredi attr_version); 11011fb69e78SMiklos Szeredi if (stat) 1102c79e322fSMiklos Szeredi fuse_fillattr(inode, &outarg.attr, stat); 1103e5e5558eSMiklos Szeredi } 1104e5e5558eSMiklos Szeredi } 1105e5e5558eSMiklos Szeredi return err; 1106e5e5558eSMiklos Szeredi } 1107e5e5558eSMiklos Szeredi 11085b97eeacSMiklos Szeredi static int fuse_update_get_attr(struct inode *inode, struct file *file, 11092f1e8196SMiklos Szeredi struct kstat *stat, u32 request_mask, 11102f1e8196SMiklos Szeredi unsigned int flags) 1111bcb4be80SMiklos Szeredi { 1112bcb4be80SMiklos Szeredi struct fuse_inode *fi = get_fuse_inode(inode); 11135b97eeacSMiklos Szeredi int err = 0; 1114bf5c1898SMiklos Szeredi bool sync; 1115ec855375SMiklos Szeredi u32 inval_mask = READ_ONCE(fi->inval_mask); 1116ec855375SMiklos Szeredi u32 cache_mask = fuse_get_cache_mask(inode); 1117bcb4be80SMiklos Szeredi 1118bf5c1898SMiklos Szeredi if (flags & AT_STATX_FORCE_SYNC) 1119bf5c1898SMiklos Szeredi sync = true; 1120bf5c1898SMiklos Szeredi else if (flags & AT_STATX_DONT_SYNC) 1121bf5c1898SMiklos Szeredi sync = false; 1122ec855375SMiklos Szeredi else if (request_mask & inval_mask & ~cache_mask) 11232f1e8196SMiklos Szeredi sync = true; 1124bf5c1898SMiklos Szeredi else 1125bf5c1898SMiklos Szeredi sync = time_before64(fi->i_time, get_jiffies_64()); 1126bf5c1898SMiklos Szeredi 1127bf5c1898SMiklos Szeredi if (sync) { 112860bcc88aSSeth Forshee forget_all_cached_acls(inode); 1129bcb4be80SMiklos Szeredi err = fuse_do_getattr(inode, stat, file); 11305b97eeacSMiklos Szeredi } else if (stat) { 11310d56a451SChristian Brauner generic_fillattr(&init_user_ns, inode, stat); 1132bcb4be80SMiklos Szeredi stat->mode = fi->orig_i_mode; 113345c72cd7SPavel Shilovsky stat->ino = fi->orig_ino; 1134bcb4be80SMiklos Szeredi } 1135bcb4be80SMiklos Szeredi 1136bcb4be80SMiklos Szeredi return err; 1137bcb4be80SMiklos Szeredi } 1138bcb4be80SMiklos Szeredi 1139c6c745b8SMiklos Szeredi int fuse_update_attributes(struct inode *inode, struct file *file, u32 mask) 11405b97eeacSMiklos Szeredi { 1141c6c745b8SMiklos Szeredi return fuse_update_get_attr(inode, file, NULL, mask, 0); 11425b97eeacSMiklos Szeredi } 11435b97eeacSMiklos Szeredi 1144fcee216bSMax Reitz int fuse_reverse_inval_entry(struct fuse_conn *fc, u64 parent_nodeid, 1145451d0f59SJohn Muir u64 child_nodeid, struct qstr *name) 11463b463ae0SJohn Muir { 11473b463ae0SJohn Muir int err = -ENOTDIR; 11483b463ae0SJohn Muir struct inode *parent; 11493b463ae0SJohn Muir struct dentry *dir; 11503b463ae0SJohn Muir struct dentry *entry; 11513b463ae0SJohn Muir 1152fcee216bSMax Reitz parent = fuse_ilookup(fc, parent_nodeid, NULL); 11533b463ae0SJohn Muir if (!parent) 11543b463ae0SJohn Muir return -ENOENT; 11553b463ae0SJohn Muir 1156bda9a719SMiklos Szeredi inode_lock_nested(parent, I_MUTEX_PARENT); 11573b463ae0SJohn Muir if (!S_ISDIR(parent->i_mode)) 11583b463ae0SJohn Muir goto unlock; 11593b463ae0SJohn Muir 11603b463ae0SJohn Muir err = -ENOENT; 11613b463ae0SJohn Muir dir = d_find_alias(parent); 11623b463ae0SJohn Muir if (!dir) 11633b463ae0SJohn Muir goto unlock; 11643b463ae0SJohn Muir 11658387ff25SLinus Torvalds name->hash = full_name_hash(dir, name->name, name->len); 11663b463ae0SJohn Muir entry = d_lookup(dir, name); 11673b463ae0SJohn Muir dput(dir); 11683b463ae0SJohn Muir if (!entry) 11693b463ae0SJohn Muir goto unlock; 11703b463ae0SJohn Muir 1171261aaba7SMiklos Szeredi fuse_dir_changed(parent); 11723b463ae0SJohn Muir fuse_invalidate_entry(entry); 1173451d0f59SJohn Muir 11742b0143b5SDavid Howells if (child_nodeid != 0 && d_really_is_positive(entry)) { 11755955102cSAl Viro inode_lock(d_inode(entry)); 11762b0143b5SDavid Howells if (get_node_id(d_inode(entry)) != child_nodeid) { 1177451d0f59SJohn Muir err = -ENOENT; 1178451d0f59SJohn Muir goto badentry; 1179451d0f59SJohn Muir } 1180451d0f59SJohn Muir if (d_mountpoint(entry)) { 1181451d0f59SJohn Muir err = -EBUSY; 1182451d0f59SJohn Muir goto badentry; 1183451d0f59SJohn Muir } 1184e36cb0b8SDavid Howells if (d_is_dir(entry)) { 1185451d0f59SJohn Muir shrink_dcache_parent(entry); 1186451d0f59SJohn Muir if (!simple_empty(entry)) { 1187451d0f59SJohn Muir err = -ENOTEMPTY; 1188451d0f59SJohn Muir goto badentry; 1189451d0f59SJohn Muir } 11902b0143b5SDavid Howells d_inode(entry)->i_flags |= S_DEAD; 1191451d0f59SJohn Muir } 1192451d0f59SJohn Muir dont_mount(entry); 11932b0143b5SDavid Howells clear_nlink(d_inode(entry)); 11943b463ae0SJohn Muir err = 0; 1195451d0f59SJohn Muir badentry: 11965955102cSAl Viro inode_unlock(d_inode(entry)); 1197451d0f59SJohn Muir if (!err) 1198451d0f59SJohn Muir d_delete(entry); 1199451d0f59SJohn Muir } else { 1200451d0f59SJohn Muir err = 0; 1201451d0f59SJohn Muir } 1202451d0f59SJohn Muir dput(entry); 12033b463ae0SJohn Muir 12043b463ae0SJohn Muir unlock: 12055955102cSAl Viro inode_unlock(parent); 12063b463ae0SJohn Muir iput(parent); 12073b463ae0SJohn Muir return err; 12083b463ae0SJohn Muir } 12093b463ae0SJohn Muir 121087729a55SMiklos Szeredi /* 121187729a55SMiklos Szeredi * Calling into a user-controlled filesystem gives the filesystem 1212c2132c1bSAnatol Pomozov * daemon ptrace-like capabilities over the current process. This 121387729a55SMiklos Szeredi * means, that the filesystem daemon is able to record the exact 121487729a55SMiklos Szeredi * filesystem operations performed, and can also control the behavior 121587729a55SMiklos Szeredi * of the requester process in otherwise impossible ways. For example 121687729a55SMiklos Szeredi * it can delay the operation for arbitrary length of time allowing 121787729a55SMiklos Szeredi * DoS against the requester. 121887729a55SMiklos Szeredi * 121987729a55SMiklos Szeredi * For this reason only those processes can call into the filesystem, 122087729a55SMiklos Szeredi * for which the owner of the mount has ptrace privilege. This 122187729a55SMiklos Szeredi * excludes processes started by other users, suid or sgid processes. 122287729a55SMiklos Szeredi */ 1223c2132c1bSAnatol Pomozov int fuse_allow_current_process(struct fuse_conn *fc) 122487729a55SMiklos Szeredi { 1225c69e8d9cSDavid Howells const struct cred *cred; 1226c69e8d9cSDavid Howells 122729433a29SMiklos Szeredi if (fc->allow_other) 122873f03c2bSSeth Forshee return current_in_userns(fc->user_ns); 122987729a55SMiklos Szeredi 1230c2132c1bSAnatol Pomozov cred = current_cred(); 1231499dcf20SEric W. Biederman if (uid_eq(cred->euid, fc->user_id) && 1232499dcf20SEric W. Biederman uid_eq(cred->suid, fc->user_id) && 1233499dcf20SEric W. Biederman uid_eq(cred->uid, fc->user_id) && 1234499dcf20SEric W. Biederman gid_eq(cred->egid, fc->group_id) && 1235499dcf20SEric W. Biederman gid_eq(cred->sgid, fc->group_id) && 1236499dcf20SEric W. Biederman gid_eq(cred->gid, fc->group_id)) 1237c2132c1bSAnatol Pomozov return 1; 123887729a55SMiklos Szeredi 1239c2132c1bSAnatol Pomozov return 0; 124087729a55SMiklos Szeredi } 124187729a55SMiklos Szeredi 124231d40d74SMiklos Szeredi static int fuse_access(struct inode *inode, int mask) 124331d40d74SMiklos Szeredi { 1244fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(inode); 12457078187aSMiklos Szeredi FUSE_ARGS(args); 124631d40d74SMiklos Szeredi struct fuse_access_in inarg; 124731d40d74SMiklos Szeredi int err; 124831d40d74SMiklos Szeredi 1249698fa1d1SMiklos Szeredi BUG_ON(mask & MAY_NOT_BLOCK); 1250698fa1d1SMiklos Szeredi 1251fcee216bSMax Reitz if (fm->fc->no_access) 125231d40d74SMiklos Szeredi return 0; 125331d40d74SMiklos Szeredi 125431d40d74SMiklos Szeredi memset(&inarg, 0, sizeof(inarg)); 1255e6305c43SAl Viro inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC); 1256d5b48543SMiklos Szeredi args.opcode = FUSE_ACCESS; 1257d5b48543SMiklos Szeredi args.nodeid = get_node_id(inode); 1258d5b48543SMiklos Szeredi args.in_numargs = 1; 1259d5b48543SMiklos Szeredi args.in_args[0].size = sizeof(inarg); 1260d5b48543SMiklos Szeredi args.in_args[0].value = &inarg; 1261fcee216bSMax Reitz err = fuse_simple_request(fm, &args); 126231d40d74SMiklos Szeredi if (err == -ENOSYS) { 1263fcee216bSMax Reitz fm->fc->no_access = 1; 126431d40d74SMiklos Szeredi err = 0; 126531d40d74SMiklos Szeredi } 126631d40d74SMiklos Szeredi return err; 126731d40d74SMiklos Szeredi } 126831d40d74SMiklos Szeredi 126910556cb2SAl Viro static int fuse_perm_getattr(struct inode *inode, int mask) 127019690ddbSMiklos Szeredi { 127110556cb2SAl Viro if (mask & MAY_NOT_BLOCK) 127219690ddbSMiklos Szeredi return -ECHILD; 127319690ddbSMiklos Szeredi 127460bcc88aSSeth Forshee forget_all_cached_acls(inode); 127519690ddbSMiklos Szeredi return fuse_do_getattr(inode, NULL, NULL); 127619690ddbSMiklos Szeredi } 127719690ddbSMiklos Szeredi 12786f9f1180SMiklos Szeredi /* 12796f9f1180SMiklos Szeredi * Check permission. The two basic access models of FUSE are: 12806f9f1180SMiklos Szeredi * 12816f9f1180SMiklos Szeredi * 1) Local access checking ('default_permissions' mount option) based 12826f9f1180SMiklos Szeredi * on file mode. This is the plain old disk filesystem permission 12836f9f1180SMiklos Szeredi * modell. 12846f9f1180SMiklos Szeredi * 12856f9f1180SMiklos Szeredi * 2) "Remote" access checking, where server is responsible for 12866f9f1180SMiklos Szeredi * checking permission in each inode operation. An exception to this 12876f9f1180SMiklos Szeredi * is if ->permission() was invoked from sys_access() in which case an 12886f9f1180SMiklos Szeredi * access request is sent. Execute permission is still checked 12896f9f1180SMiklos Szeredi * locally based on file mode. 12906f9f1180SMiklos Szeredi */ 1291549c7297SChristian Brauner static int fuse_permission(struct user_namespace *mnt_userns, 1292549c7297SChristian Brauner struct inode *inode, int mask) 1293e5e5558eSMiklos Szeredi { 1294e5e5558eSMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(inode); 1295244f6385SMiklos Szeredi bool refreshed = false; 1296244f6385SMiklos Szeredi int err = 0; 1297e5e5558eSMiklos Szeredi 12985d069dbeSMiklos Szeredi if (fuse_is_bad(inode)) 12995d069dbeSMiklos Szeredi return -EIO; 13005d069dbeSMiklos Szeredi 1301c2132c1bSAnatol Pomozov if (!fuse_allow_current_process(fc)) 1302e5e5558eSMiklos Szeredi return -EACCES; 1303244f6385SMiklos Szeredi 1304244f6385SMiklos Szeredi /* 1305e8e96157SMiklos Szeredi * If attributes are needed, refresh them before proceeding 1306244f6385SMiklos Szeredi */ 130729433a29SMiklos Szeredi if (fc->default_permissions || 1308e8e96157SMiklos Szeredi ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) { 130919690ddbSMiklos Szeredi struct fuse_inode *fi = get_fuse_inode(inode); 1310d233c7ddSMiklos Szeredi u32 perm_mask = STATX_MODE | STATX_UID | STATX_GID; 131119690ddbSMiklos Szeredi 1312d233c7ddSMiklos Szeredi if (perm_mask & READ_ONCE(fi->inval_mask) || 1313d233c7ddSMiklos Szeredi time_before64(fi->i_time, get_jiffies_64())) { 131419690ddbSMiklos Szeredi refreshed = true; 131519690ddbSMiklos Szeredi 131610556cb2SAl Viro err = fuse_perm_getattr(inode, mask); 1317244f6385SMiklos Szeredi if (err) 1318244f6385SMiklos Szeredi return err; 13191fb69e78SMiklos Szeredi } 132019690ddbSMiklos Szeredi } 1321244f6385SMiklos Szeredi 132229433a29SMiklos Szeredi if (fc->default_permissions) { 132347291baaSChristian Brauner err = generic_permission(&init_user_ns, inode, mask); 13241e9a4ed9SMiklos Szeredi 13251e9a4ed9SMiklos Szeredi /* If permission is denied, try to refresh file 13261e9a4ed9SMiklos Szeredi attributes. This is also needed, because the root 13271e9a4ed9SMiklos Szeredi node will at first have no permissions */ 1328244f6385SMiklos Szeredi if (err == -EACCES && !refreshed) { 132910556cb2SAl Viro err = fuse_perm_getattr(inode, mask); 13301e9a4ed9SMiklos Szeredi if (!err) 133147291baaSChristian Brauner err = generic_permission(&init_user_ns, 133247291baaSChristian Brauner inode, mask); 13331e9a4ed9SMiklos Szeredi } 13341e9a4ed9SMiklos Szeredi 13356f9f1180SMiklos Szeredi /* Note: the opposite of the above test does not 13366f9f1180SMiklos Szeredi exist. So if permissions are revoked this won't be 13376f9f1180SMiklos Szeredi noticed immediately, only after the attribute 13386f9f1180SMiklos Szeredi timeout has expired */ 13399cfcac81SEric Paris } else if (mask & (MAY_ACCESS | MAY_CHDIR)) { 1340e8e96157SMiklos Szeredi err = fuse_access(inode, mask); 1341e8e96157SMiklos Szeredi } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { 1342e8e96157SMiklos Szeredi if (!(inode->i_mode & S_IXUGO)) { 1343e8e96157SMiklos Szeredi if (refreshed) 1344e5e5558eSMiklos Szeredi return -EACCES; 134531d40d74SMiklos Szeredi 134610556cb2SAl Viro err = fuse_perm_getattr(inode, mask); 1347e8e96157SMiklos Szeredi if (!err && !(inode->i_mode & S_IXUGO)) 1348e8e96157SMiklos Szeredi return -EACCES; 1349e8e96157SMiklos Szeredi } 1350e5e5558eSMiklos Szeredi } 1351244f6385SMiklos Szeredi return err; 1352e5e5558eSMiklos Szeredi } 1353e5e5558eSMiklos Szeredi 13545571f1e6SDan Schatzberg static int fuse_readlink_page(struct inode *inode, struct page *page) 1355e5e5558eSMiklos Szeredi { 1356fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(inode); 13574c29afecSMiklos Szeredi struct fuse_page_desc desc = { .length = PAGE_SIZE - 1 }; 13584c29afecSMiklos Szeredi struct fuse_args_pages ap = { 13594c29afecSMiklos Szeredi .num_pages = 1, 13604c29afecSMiklos Szeredi .pages = &page, 13614c29afecSMiklos Szeredi .descs = &desc, 13624c29afecSMiklos Szeredi }; 13634c29afecSMiklos Szeredi char *link; 13644c29afecSMiklos Szeredi ssize_t res; 1365e5e5558eSMiklos Szeredi 13664c29afecSMiklos Szeredi ap.args.opcode = FUSE_READLINK; 13674c29afecSMiklos Szeredi ap.args.nodeid = get_node_id(inode); 13684c29afecSMiklos Szeredi ap.args.out_pages = true; 13694c29afecSMiklos Szeredi ap.args.out_argvar = true; 13704c29afecSMiklos Szeredi ap.args.page_zeroing = true; 13714c29afecSMiklos Szeredi ap.args.out_numargs = 1; 13724c29afecSMiklos Szeredi ap.args.out_args[0].size = desc.length; 1373fcee216bSMax Reitz res = fuse_simple_request(fm, &ap.args); 13746b255391SAl Viro 1375451418fcSAndrew Gallagher fuse_invalidate_atime(inode); 13765571f1e6SDan Schatzberg 13774c29afecSMiklos Szeredi if (res < 0) 13784c29afecSMiklos Szeredi return res; 13794c29afecSMiklos Szeredi 13804c29afecSMiklos Szeredi if (WARN_ON(res >= PAGE_SIZE)) 13814c29afecSMiklos Szeredi return -EIO; 13824c29afecSMiklos Szeredi 13834c29afecSMiklos Szeredi link = page_address(page); 13844c29afecSMiklos Szeredi link[res] = '\0'; 13854c29afecSMiklos Szeredi 13864c29afecSMiklos Szeredi return 0; 13875571f1e6SDan Schatzberg } 13885571f1e6SDan Schatzberg 13895571f1e6SDan Schatzberg static const char *fuse_get_link(struct dentry *dentry, struct inode *inode, 13905571f1e6SDan Schatzberg struct delayed_call *callback) 13915571f1e6SDan Schatzberg { 13925571f1e6SDan Schatzberg struct fuse_conn *fc = get_fuse_conn(inode); 13935571f1e6SDan Schatzberg struct page *page; 13945571f1e6SDan Schatzberg int err; 13955571f1e6SDan Schatzberg 13965571f1e6SDan Schatzberg err = -EIO; 13975d069dbeSMiklos Szeredi if (fuse_is_bad(inode)) 13985571f1e6SDan Schatzberg goto out_err; 13995571f1e6SDan Schatzberg 14005571f1e6SDan Schatzberg if (fc->cache_symlinks) 14015571f1e6SDan Schatzberg return page_get_link(dentry, inode, callback); 14025571f1e6SDan Schatzberg 14035571f1e6SDan Schatzberg err = -ECHILD; 14045571f1e6SDan Schatzberg if (!dentry) 14055571f1e6SDan Schatzberg goto out_err; 14065571f1e6SDan Schatzberg 14075571f1e6SDan Schatzberg page = alloc_page(GFP_KERNEL); 14085571f1e6SDan Schatzberg err = -ENOMEM; 14095571f1e6SDan Schatzberg if (!page) 14105571f1e6SDan Schatzberg goto out_err; 14115571f1e6SDan Schatzberg 14125571f1e6SDan Schatzberg err = fuse_readlink_page(inode, page); 14135571f1e6SDan Schatzberg if (err) { 14145571f1e6SDan Schatzberg __free_page(page); 14155571f1e6SDan Schatzberg goto out_err; 14165571f1e6SDan Schatzberg } 14175571f1e6SDan Schatzberg 14185571f1e6SDan Schatzberg set_delayed_call(callback, page_put_link, page); 14195571f1e6SDan Schatzberg 14205571f1e6SDan Schatzberg return page_address(page); 14215571f1e6SDan Schatzberg 14225571f1e6SDan Schatzberg out_err: 14235571f1e6SDan Schatzberg return ERR_PTR(err); 1424e5e5558eSMiklos Szeredi } 1425e5e5558eSMiklos Szeredi 1426e5e5558eSMiklos Szeredi static int fuse_dir_open(struct inode *inode, struct file *file) 1427e5e5558eSMiklos Szeredi { 142891fe96b4SMiklos Szeredi return fuse_open_common(inode, file, true); 1429e5e5558eSMiklos Szeredi } 1430e5e5558eSMiklos Szeredi 1431e5e5558eSMiklos Szeredi static int fuse_dir_release(struct inode *inode, struct file *file) 1432e5e5558eSMiklos Szeredi { 14332e64ff15SChad Austin fuse_release_common(file, true); 14348b0797a4SMiklos Szeredi 14358b0797a4SMiklos Szeredi return 0; 1436e5e5558eSMiklos Szeredi } 1437e5e5558eSMiklos Szeredi 143802c24a82SJosef Bacik static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end, 143902c24a82SJosef Bacik int datasync) 144082547981SMiklos Szeredi { 1441a9c2d1e8SMiklos Szeredi struct inode *inode = file->f_mapping->host; 1442a9c2d1e8SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(inode); 1443a9c2d1e8SMiklos Szeredi int err; 1444a9c2d1e8SMiklos Szeredi 14455d069dbeSMiklos Szeredi if (fuse_is_bad(inode)) 1446a9c2d1e8SMiklos Szeredi return -EIO; 1447a9c2d1e8SMiklos Szeredi 1448a9c2d1e8SMiklos Szeredi if (fc->no_fsyncdir) 1449a9c2d1e8SMiklos Szeredi return 0; 1450a9c2d1e8SMiklos Szeredi 1451a9c2d1e8SMiklos Szeredi inode_lock(inode); 1452a9c2d1e8SMiklos Szeredi err = fuse_fsync_common(file, start, end, datasync, FUSE_FSYNCDIR); 1453a9c2d1e8SMiklos Szeredi if (err == -ENOSYS) { 1454a9c2d1e8SMiklos Szeredi fc->no_fsyncdir = 1; 1455a9c2d1e8SMiklos Szeredi err = 0; 1456a9c2d1e8SMiklos Szeredi } 1457a9c2d1e8SMiklos Szeredi inode_unlock(inode); 1458a9c2d1e8SMiklos Szeredi 1459a9c2d1e8SMiklos Szeredi return err; 146082547981SMiklos Szeredi } 146182547981SMiklos Szeredi 1462b18da0c5SMiklos Szeredi static long fuse_dir_ioctl(struct file *file, unsigned int cmd, 1463b18da0c5SMiklos Szeredi unsigned long arg) 1464b18da0c5SMiklos Szeredi { 1465b18da0c5SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host); 1466b18da0c5SMiklos Szeredi 1467b18da0c5SMiklos Szeredi /* FUSE_IOCTL_DIR only supported for API version >= 7.18 */ 1468b18da0c5SMiklos Szeredi if (fc->minor < 18) 1469b18da0c5SMiklos Szeredi return -ENOTTY; 1470b18da0c5SMiklos Szeredi 1471b18da0c5SMiklos Szeredi return fuse_ioctl_common(file, cmd, arg, FUSE_IOCTL_DIR); 1472b18da0c5SMiklos Szeredi } 1473b18da0c5SMiklos Szeredi 1474b18da0c5SMiklos Szeredi static long fuse_dir_compat_ioctl(struct file *file, unsigned int cmd, 1475b18da0c5SMiklos Szeredi unsigned long arg) 1476b18da0c5SMiklos Szeredi { 1477b18da0c5SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host); 1478b18da0c5SMiklos Szeredi 1479b18da0c5SMiklos Szeredi if (fc->minor < 18) 1480b18da0c5SMiklos Szeredi return -ENOTTY; 1481b18da0c5SMiklos Szeredi 1482b18da0c5SMiklos Szeredi return fuse_ioctl_common(file, cmd, arg, 1483b18da0c5SMiklos Szeredi FUSE_IOCTL_COMPAT | FUSE_IOCTL_DIR); 1484b18da0c5SMiklos Szeredi } 1485b18da0c5SMiklos Szeredi 1486b0aa7606SMaxim Patlasov static bool update_mtime(unsigned ivalid, bool trust_local_mtime) 148717637cbaSMiklos Szeredi { 148817637cbaSMiklos Szeredi /* Always update if mtime is explicitly set */ 148917637cbaSMiklos Szeredi if (ivalid & ATTR_MTIME_SET) 149017637cbaSMiklos Szeredi return true; 149117637cbaSMiklos Szeredi 1492b0aa7606SMaxim Patlasov /* Or if kernel i_mtime is the official one */ 1493b0aa7606SMaxim Patlasov if (trust_local_mtime) 1494b0aa7606SMaxim Patlasov return true; 1495b0aa7606SMaxim Patlasov 149617637cbaSMiklos Szeredi /* If it's an open(O_TRUNC) or an ftruncate(), don't update */ 149717637cbaSMiklos Szeredi if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE))) 149817637cbaSMiklos Szeredi return false; 149917637cbaSMiklos Szeredi 150017637cbaSMiklos Szeredi /* In all other cases update */ 150117637cbaSMiklos Szeredi return true; 150217637cbaSMiklos Szeredi } 150317637cbaSMiklos Szeredi 15048cb08329SEric W. Biederman static void iattr_to_fattr(struct fuse_conn *fc, struct iattr *iattr, 15058cb08329SEric W. Biederman struct fuse_setattr_in *arg, bool trust_local_cmtime) 15069e6268dbSMiklos Szeredi { 15079e6268dbSMiklos Szeredi unsigned ivalid = iattr->ia_valid; 15089e6268dbSMiklos Szeredi 15099e6268dbSMiklos Szeredi if (ivalid & ATTR_MODE) 1510befc649cSMiklos Szeredi arg->valid |= FATTR_MODE, arg->mode = iattr->ia_mode; 15119e6268dbSMiklos Szeredi if (ivalid & ATTR_UID) 15128cb08329SEric W. Biederman arg->valid |= FATTR_UID, arg->uid = from_kuid(fc->user_ns, iattr->ia_uid); 15139e6268dbSMiklos Szeredi if (ivalid & ATTR_GID) 15148cb08329SEric W. Biederman arg->valid |= FATTR_GID, arg->gid = from_kgid(fc->user_ns, iattr->ia_gid); 15159e6268dbSMiklos Szeredi if (ivalid & ATTR_SIZE) 1516befc649cSMiklos Szeredi arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size; 151717637cbaSMiklos Szeredi if (ivalid & ATTR_ATIME) { 151817637cbaSMiklos Szeredi arg->valid |= FATTR_ATIME; 1519befc649cSMiklos Szeredi arg->atime = iattr->ia_atime.tv_sec; 152017637cbaSMiklos Szeredi arg->atimensec = iattr->ia_atime.tv_nsec; 152117637cbaSMiklos Szeredi if (!(ivalid & ATTR_ATIME_SET)) 152217637cbaSMiklos Szeredi arg->valid |= FATTR_ATIME_NOW; 152317637cbaSMiklos Szeredi } 15243ad22c62SMaxim Patlasov if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, trust_local_cmtime)) { 152517637cbaSMiklos Szeredi arg->valid |= FATTR_MTIME; 1526befc649cSMiklos Szeredi arg->mtime = iattr->ia_mtime.tv_sec; 152717637cbaSMiklos Szeredi arg->mtimensec = iattr->ia_mtime.tv_nsec; 15283ad22c62SMaxim Patlasov if (!(ivalid & ATTR_MTIME_SET) && !trust_local_cmtime) 152917637cbaSMiklos Szeredi arg->valid |= FATTR_MTIME_NOW; 15309e6268dbSMiklos Szeredi } 15313ad22c62SMaxim Patlasov if ((ivalid & ATTR_CTIME) && trust_local_cmtime) { 15323ad22c62SMaxim Patlasov arg->valid |= FATTR_CTIME; 15333ad22c62SMaxim Patlasov arg->ctime = iattr->ia_ctime.tv_sec; 15343ad22c62SMaxim Patlasov arg->ctimensec = iattr->ia_ctime.tv_nsec; 15353ad22c62SMaxim Patlasov } 15369e6268dbSMiklos Szeredi } 15379e6268dbSMiklos Szeredi 15386f9f1180SMiklos Szeredi /* 15393be5a52bSMiklos Szeredi * Prevent concurrent writepages on inode 15403be5a52bSMiklos Szeredi * 15413be5a52bSMiklos Szeredi * This is done by adding a negative bias to the inode write counter 15423be5a52bSMiklos Szeredi * and waiting for all pending writes to finish. 15433be5a52bSMiklos Szeredi */ 15443be5a52bSMiklos Szeredi void fuse_set_nowrite(struct inode *inode) 15453be5a52bSMiklos Szeredi { 15463be5a52bSMiklos Szeredi struct fuse_inode *fi = get_fuse_inode(inode); 15473be5a52bSMiklos Szeredi 15485955102cSAl Viro BUG_ON(!inode_is_locked(inode)); 15493be5a52bSMiklos Szeredi 1550f15ecfefSKirill Tkhai spin_lock(&fi->lock); 15513be5a52bSMiklos Szeredi BUG_ON(fi->writectr < 0); 15523be5a52bSMiklos Szeredi fi->writectr += FUSE_NOWRITE; 1553f15ecfefSKirill Tkhai spin_unlock(&fi->lock); 15543be5a52bSMiklos Szeredi wait_event(fi->page_waitq, fi->writectr == FUSE_NOWRITE); 15553be5a52bSMiklos Szeredi } 15563be5a52bSMiklos Szeredi 15573be5a52bSMiklos Szeredi /* 15583be5a52bSMiklos Szeredi * Allow writepages on inode 15593be5a52bSMiklos Szeredi * 15603be5a52bSMiklos Szeredi * Remove the bias from the writecounter and send any queued 15613be5a52bSMiklos Szeredi * writepages. 15623be5a52bSMiklos Szeredi */ 15633be5a52bSMiklos Szeredi static void __fuse_release_nowrite(struct inode *inode) 15643be5a52bSMiklos Szeredi { 15653be5a52bSMiklos Szeredi struct fuse_inode *fi = get_fuse_inode(inode); 15663be5a52bSMiklos Szeredi 15673be5a52bSMiklos Szeredi BUG_ON(fi->writectr != FUSE_NOWRITE); 15683be5a52bSMiklos Szeredi fi->writectr = 0; 15693be5a52bSMiklos Szeredi fuse_flush_writepages(inode); 15703be5a52bSMiklos Szeredi } 15713be5a52bSMiklos Szeredi 15723be5a52bSMiklos Szeredi void fuse_release_nowrite(struct inode *inode) 15733be5a52bSMiklos Szeredi { 1574f15ecfefSKirill Tkhai struct fuse_inode *fi = get_fuse_inode(inode); 15753be5a52bSMiklos Szeredi 1576f15ecfefSKirill Tkhai spin_lock(&fi->lock); 15773be5a52bSMiklos Szeredi __fuse_release_nowrite(inode); 1578f15ecfefSKirill Tkhai spin_unlock(&fi->lock); 15793be5a52bSMiklos Szeredi } 15803be5a52bSMiklos Szeredi 15817078187aSMiklos Szeredi static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_args *args, 1582b0aa7606SMaxim Patlasov struct inode *inode, 1583b0aa7606SMaxim Patlasov struct fuse_setattr_in *inarg_p, 1584b0aa7606SMaxim Patlasov struct fuse_attr_out *outarg_p) 1585b0aa7606SMaxim Patlasov { 1586d5b48543SMiklos Szeredi args->opcode = FUSE_SETATTR; 1587d5b48543SMiklos Szeredi args->nodeid = get_node_id(inode); 1588d5b48543SMiklos Szeredi args->in_numargs = 1; 1589d5b48543SMiklos Szeredi args->in_args[0].size = sizeof(*inarg_p); 1590d5b48543SMiklos Szeredi args->in_args[0].value = inarg_p; 1591d5b48543SMiklos Szeredi args->out_numargs = 1; 1592d5b48543SMiklos Szeredi args->out_args[0].size = sizeof(*outarg_p); 1593d5b48543SMiklos Szeredi args->out_args[0].value = outarg_p; 1594b0aa7606SMaxim Patlasov } 1595b0aa7606SMaxim Patlasov 1596b0aa7606SMaxim Patlasov /* 1597b0aa7606SMaxim Patlasov * Flush inode->i_mtime to the server 1598b0aa7606SMaxim Patlasov */ 1599ab9e13f7SMaxim Patlasov int fuse_flush_times(struct inode *inode, struct fuse_file *ff) 1600b0aa7606SMaxim Patlasov { 1601fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(inode); 16027078187aSMiklos Szeredi FUSE_ARGS(args); 1603b0aa7606SMaxim Patlasov struct fuse_setattr_in inarg; 1604b0aa7606SMaxim Patlasov struct fuse_attr_out outarg; 1605b0aa7606SMaxim Patlasov 1606b0aa7606SMaxim Patlasov memset(&inarg, 0, sizeof(inarg)); 1607b0aa7606SMaxim Patlasov memset(&outarg, 0, sizeof(outarg)); 1608b0aa7606SMaxim Patlasov 1609ab9e13f7SMaxim Patlasov inarg.valid = FATTR_MTIME; 1610b0aa7606SMaxim Patlasov inarg.mtime = inode->i_mtime.tv_sec; 1611b0aa7606SMaxim Patlasov inarg.mtimensec = inode->i_mtime.tv_nsec; 1612fcee216bSMax Reitz if (fm->fc->minor >= 23) { 1613ab9e13f7SMaxim Patlasov inarg.valid |= FATTR_CTIME; 1614ab9e13f7SMaxim Patlasov inarg.ctime = inode->i_ctime.tv_sec; 1615ab9e13f7SMaxim Patlasov inarg.ctimensec = inode->i_ctime.tv_nsec; 1616ab9e13f7SMaxim Patlasov } 16171e18bda8SMiklos Szeredi if (ff) { 16181e18bda8SMiklos Szeredi inarg.valid |= FATTR_FH; 16191e18bda8SMiklos Szeredi inarg.fh = ff->fh; 16201e18bda8SMiklos Szeredi } 1621fcee216bSMax Reitz fuse_setattr_fill(fm->fc, &args, inode, &inarg, &outarg); 1622b0aa7606SMaxim Patlasov 1623fcee216bSMax Reitz return fuse_simple_request(fm, &args); 1624b0aa7606SMaxim Patlasov } 1625b0aa7606SMaxim Patlasov 16263be5a52bSMiklos Szeredi /* 16276f9f1180SMiklos Szeredi * Set attributes, and at the same time refresh them. 16286f9f1180SMiklos Szeredi * 16296f9f1180SMiklos Szeredi * Truncation is slightly complicated, because the 'truncate' request 16306f9f1180SMiklos Szeredi * may fail, in which case we don't want to touch the mapping. 16319ffbb916SMiklos Szeredi * vmtruncate() doesn't allow for this case, so do the rlimit checking 16329ffbb916SMiklos Szeredi * and the actual truncation by hand. 16336f9f1180SMiklos Szeredi */ 163462490330SJan Kara int fuse_do_setattr(struct dentry *dentry, struct iattr *attr, 163549d4914fSMiklos Szeredi struct file *file) 16369e6268dbSMiklos Szeredi { 163762490330SJan Kara struct inode *inode = d_inode(dentry); 1638fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(inode); 1639fcee216bSMax Reitz struct fuse_conn *fc = fm->fc; 164006a7c3c2SMaxim Patlasov struct fuse_inode *fi = get_fuse_inode(inode); 16418bcbbe9cSJan Kara struct address_space *mapping = inode->i_mapping; 16427078187aSMiklos Szeredi FUSE_ARGS(args); 16439e6268dbSMiklos Szeredi struct fuse_setattr_in inarg; 16449e6268dbSMiklos Szeredi struct fuse_attr_out outarg; 16453be5a52bSMiklos Szeredi bool is_truncate = false; 1646c15016b7SMiklos Szeredi bool is_wb = fc->writeback_cache && S_ISREG(inode->i_mode); 16473be5a52bSMiklos Szeredi loff_t oldsize; 16489e6268dbSMiklos Szeredi int err; 1649c15016b7SMiklos Szeredi bool trust_local_cmtime = is_wb; 16506ae330caSVivek Goyal bool fault_blocked = false; 16519e6268dbSMiklos Szeredi 165229433a29SMiklos Szeredi if (!fc->default_permissions) 1653db78b877SChristoph Hellwig attr->ia_valid |= ATTR_FORCE; 1654db78b877SChristoph Hellwig 16552f221d6fSChristian Brauner err = setattr_prepare(&init_user_ns, dentry, attr); 16561e9a4ed9SMiklos Szeredi if (err) 16571e9a4ed9SMiklos Szeredi return err; 16581e9a4ed9SMiklos Szeredi 16596ae330caSVivek Goyal if (attr->ia_valid & ATTR_SIZE) { 16606ae330caSVivek Goyal if (WARN_ON(!S_ISREG(inode->i_mode))) 16616ae330caSVivek Goyal return -EIO; 16626ae330caSVivek Goyal is_truncate = true; 16636ae330caSVivek Goyal } 16646ae330caSVivek Goyal 16656ae330caSVivek Goyal if (FUSE_IS_DAX(inode) && is_truncate) { 16668bcbbe9cSJan Kara filemap_invalidate_lock(mapping); 16676ae330caSVivek Goyal fault_blocked = true; 16686ae330caSVivek Goyal err = fuse_dax_break_layouts(inode, 0, 0); 16696ae330caSVivek Goyal if (err) { 16708bcbbe9cSJan Kara filemap_invalidate_unlock(mapping); 16716ae330caSVivek Goyal return err; 16726ae330caSVivek Goyal } 16736ae330caSVivek Goyal } 16746ae330caSVivek Goyal 16758d56adddSMiklos Szeredi if (attr->ia_valid & ATTR_OPEN) { 1676df0e91d4SMiklos Szeredi /* This is coming from open(..., ... | O_TRUNC); */ 1677df0e91d4SMiklos Szeredi WARN_ON(!(attr->ia_valid & ATTR_SIZE)); 1678df0e91d4SMiklos Szeredi WARN_ON(attr->ia_size != 0); 1679df0e91d4SMiklos Szeredi if (fc->atomic_o_trunc) { 1680df0e91d4SMiklos Szeredi /* 1681df0e91d4SMiklos Szeredi * No need to send request to userspace, since actual 1682df0e91d4SMiklos Szeredi * truncation has already been done by OPEN. But still 1683df0e91d4SMiklos Szeredi * need to truncate page cache. 1684df0e91d4SMiklos Szeredi */ 1685df0e91d4SMiklos Szeredi i_size_write(inode, 0); 1686df0e91d4SMiklos Szeredi truncate_pagecache(inode, 0); 16876ae330caSVivek Goyal goto out; 1688df0e91d4SMiklos Szeredi } 16898d56adddSMiklos Szeredi file = NULL; 16908d56adddSMiklos Szeredi } 16916ff958edSMiklos Szeredi 1692b24e7598SMiklos Szeredi /* Flush dirty data/metadata before non-truncate SETATTR */ 1693c15016b7SMiklos Szeredi if (is_wb && 1694b24e7598SMiklos Szeredi attr->ia_valid & 1695b24e7598SMiklos Szeredi (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_MTIME_SET | 1696b24e7598SMiklos Szeredi ATTR_TIMES_SET)) { 1697b24e7598SMiklos Szeredi err = write_inode_now(inode, true); 1698b24e7598SMiklos Szeredi if (err) 1699b24e7598SMiklos Szeredi return err; 1700b24e7598SMiklos Szeredi 1701b24e7598SMiklos Szeredi fuse_set_nowrite(inode); 1702b24e7598SMiklos Szeredi fuse_release_nowrite(inode); 1703b24e7598SMiklos Szeredi } 1704b24e7598SMiklos Szeredi 170506a7c3c2SMaxim Patlasov if (is_truncate) { 17063be5a52bSMiklos Szeredi fuse_set_nowrite(inode); 170706a7c3c2SMaxim Patlasov set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); 17083ad22c62SMaxim Patlasov if (trust_local_cmtime && attr->ia_size != inode->i_size) 17093ad22c62SMaxim Patlasov attr->ia_valid |= ATTR_MTIME | ATTR_CTIME; 171006a7c3c2SMaxim Patlasov } 17113be5a52bSMiklos Szeredi 17129e6268dbSMiklos Szeredi memset(&inarg, 0, sizeof(inarg)); 17130e9663eeSMiklos Szeredi memset(&outarg, 0, sizeof(outarg)); 17148cb08329SEric W. Biederman iattr_to_fattr(fc, attr, &inarg, trust_local_cmtime); 171549d4914fSMiklos Szeredi if (file) { 171649d4914fSMiklos Szeredi struct fuse_file *ff = file->private_data; 171749d4914fSMiklos Szeredi inarg.valid |= FATTR_FH; 171849d4914fSMiklos Szeredi inarg.fh = ff->fh; 171949d4914fSMiklos Szeredi } 172031792161SVivek Goyal 172131792161SVivek Goyal /* Kill suid/sgid for non-directory chown unconditionally */ 172231792161SVivek Goyal if (fc->handle_killpriv_v2 && !S_ISDIR(inode->i_mode) && 172331792161SVivek Goyal attr->ia_valid & (ATTR_UID | ATTR_GID)) 172431792161SVivek Goyal inarg.valid |= FATTR_KILL_SUIDGID; 172531792161SVivek Goyal 1726f3332114SMiklos Szeredi if (attr->ia_valid & ATTR_SIZE) { 1727f3332114SMiklos Szeredi /* For mandatory locking in truncate */ 1728f3332114SMiklos Szeredi inarg.valid |= FATTR_LOCKOWNER; 1729f3332114SMiklos Szeredi inarg.lock_owner = fuse_lock_owner_id(fc, current->files); 173031792161SVivek Goyal 173131792161SVivek Goyal /* Kill suid/sgid for truncate only if no CAP_FSETID */ 173231792161SVivek Goyal if (fc->handle_killpriv_v2 && !capable(CAP_FSETID)) 173331792161SVivek Goyal inarg.valid |= FATTR_KILL_SUIDGID; 1734f3332114SMiklos Szeredi } 17357078187aSMiklos Szeredi fuse_setattr_fill(fc, &args, inode, &inarg, &outarg); 1736fcee216bSMax Reitz err = fuse_simple_request(fm, &args); 1737e00d2c2dSMiklos Szeredi if (err) { 1738e00d2c2dSMiklos Szeredi if (err == -EINTR) 1739e00d2c2dSMiklos Szeredi fuse_invalidate_attr(inode); 17403be5a52bSMiklos Szeredi goto error; 1741e00d2c2dSMiklos Szeredi } 1742e00d2c2dSMiklos Szeredi 1743eb59bd17SMiklos Szeredi if (fuse_invalid_attr(&outarg.attr) || 17446e3e2c43SAl Viro inode_wrong_type(inode, outarg.attr.mode)) { 17455d069dbeSMiklos Szeredi fuse_make_bad(inode); 17463be5a52bSMiklos Szeredi err = -EIO; 17473be5a52bSMiklos Szeredi goto error; 17489e6268dbSMiklos Szeredi } 17499e6268dbSMiklos Szeredi 1750f15ecfefSKirill Tkhai spin_lock(&fi->lock); 1751b0aa7606SMaxim Patlasov /* the kernel maintains i_mtime locally */ 17523ad22c62SMaxim Patlasov if (trust_local_cmtime) { 17533ad22c62SMaxim Patlasov if (attr->ia_valid & ATTR_MTIME) 1754b0aa7606SMaxim Patlasov inode->i_mtime = attr->ia_mtime; 17553ad22c62SMaxim Patlasov if (attr->ia_valid & ATTR_CTIME) 17563ad22c62SMaxim Patlasov inode->i_ctime = attr->ia_ctime; 17571e18bda8SMiklos Szeredi /* FIXME: clear I_DIRTY_SYNC? */ 1758b0aa7606SMaxim Patlasov } 1759b0aa7606SMaxim Patlasov 17603be5a52bSMiklos Szeredi fuse_change_attributes_common(inode, &outarg.attr, 17614b52f059SMiklos Szeredi attr_timeout(&outarg), 17624b52f059SMiklos Szeredi fuse_get_cache_mask(inode)); 17633be5a52bSMiklos Szeredi oldsize = inode->i_size; 17648373200bSPavel Emelyanov /* see the comment in fuse_change_attributes() */ 1765c15016b7SMiklos Szeredi if (!is_wb || is_truncate) 17663be5a52bSMiklos Szeredi i_size_write(inode, outarg.attr.size); 17673be5a52bSMiklos Szeredi 17683be5a52bSMiklos Szeredi if (is_truncate) { 1769f15ecfefSKirill Tkhai /* NOTE: this may release/reacquire fi->lock */ 17703be5a52bSMiklos Szeredi __fuse_release_nowrite(inode); 17713be5a52bSMiklos Szeredi } 1772f15ecfefSKirill Tkhai spin_unlock(&fi->lock); 17733be5a52bSMiklos Szeredi 17743be5a52bSMiklos Szeredi /* 17753be5a52bSMiklos Szeredi * Only call invalidate_inode_pages2() after removing 17762bf06b8eSMatthew Wilcox (Oracle) * FUSE_NOWRITE, otherwise fuse_launder_folio() would deadlock. 17773be5a52bSMiklos Szeredi */ 17788373200bSPavel Emelyanov if ((is_truncate || !is_wb) && 17798373200bSPavel Emelyanov S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) { 17807caef267SKirill A. Shutemov truncate_pagecache(inode, outarg.attr.size); 17818bcbbe9cSJan Kara invalidate_inode_pages2(mapping); 17823be5a52bSMiklos Szeredi } 17833be5a52bSMiklos Szeredi 178406a7c3c2SMaxim Patlasov clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); 17856ae330caSVivek Goyal out: 17866ae330caSVivek Goyal if (fault_blocked) 17878bcbbe9cSJan Kara filemap_invalidate_unlock(mapping); 17886ae330caSVivek Goyal 1789e00d2c2dSMiklos Szeredi return 0; 17903be5a52bSMiklos Szeredi 17913be5a52bSMiklos Szeredi error: 17923be5a52bSMiklos Szeredi if (is_truncate) 17933be5a52bSMiklos Szeredi fuse_release_nowrite(inode); 17943be5a52bSMiklos Szeredi 179506a7c3c2SMaxim Patlasov clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); 17966ae330caSVivek Goyal 17976ae330caSVivek Goyal if (fault_blocked) 17988bcbbe9cSJan Kara filemap_invalidate_unlock(mapping); 17993be5a52bSMiklos Szeredi return err; 18009e6268dbSMiklos Szeredi } 18019e6268dbSMiklos Szeredi 1802549c7297SChristian Brauner static int fuse_setattr(struct user_namespace *mnt_userns, struct dentry *entry, 1803549c7297SChristian Brauner struct iattr *attr) 180449d4914fSMiklos Szeredi { 18052b0143b5SDavid Howells struct inode *inode = d_inode(entry); 18065e940c1dSMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(inode); 1807a09f99edSMiklos Szeredi struct file *file = (attr->ia_valid & ATTR_FILE) ? attr->ia_file : NULL; 18085e2b8828SMiklos Szeredi int ret; 1809efb9fa9eSMaxim Patlasov 18105d069dbeSMiklos Szeredi if (fuse_is_bad(inode)) 18115d069dbeSMiklos Szeredi return -EIO; 18125d069dbeSMiklos Szeredi 1813efb9fa9eSMaxim Patlasov if (!fuse_allow_current_process(get_fuse_conn(inode))) 1814efb9fa9eSMaxim Patlasov return -EACCES; 1815efb9fa9eSMaxim Patlasov 1816a09f99edSMiklos Szeredi if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) { 1817a09f99edSMiklos Szeredi attr->ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID | 1818a09f99edSMiklos Szeredi ATTR_MODE); 18195e940c1dSMiklos Szeredi 1820a09f99edSMiklos Szeredi /* 18215e940c1dSMiklos Szeredi * The only sane way to reliably kill suid/sgid is to do it in 18225e940c1dSMiklos Szeredi * the userspace filesystem 18235e940c1dSMiklos Szeredi * 18245e940c1dSMiklos Szeredi * This should be done on write(), truncate() and chown(). 18255e940c1dSMiklos Szeredi */ 18268981bdfdSVivek Goyal if (!fc->handle_killpriv && !fc->handle_killpriv_v2) { 18275e940c1dSMiklos Szeredi /* 18285e940c1dSMiklos Szeredi * ia_mode calculation may have used stale i_mode. 18295e940c1dSMiklos Szeredi * Refresh and recalculate. 1830a09f99edSMiklos Szeredi */ 1831a09f99edSMiklos Szeredi ret = fuse_do_getattr(inode, NULL, file); 1832a09f99edSMiklos Szeredi if (ret) 1833a09f99edSMiklos Szeredi return ret; 1834a09f99edSMiklos Szeredi 1835a09f99edSMiklos Szeredi attr->ia_mode = inode->i_mode; 1836c01638f5SMiklos Szeredi if (inode->i_mode & S_ISUID) { 1837a09f99edSMiklos Szeredi attr->ia_valid |= ATTR_MODE; 1838a09f99edSMiklos Szeredi attr->ia_mode &= ~S_ISUID; 1839a09f99edSMiklos Szeredi } 1840c01638f5SMiklos Szeredi if ((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { 1841a09f99edSMiklos Szeredi attr->ia_valid |= ATTR_MODE; 1842a09f99edSMiklos Szeredi attr->ia_mode &= ~S_ISGID; 1843a09f99edSMiklos Szeredi } 1844a09f99edSMiklos Szeredi } 18455e940c1dSMiklos Szeredi } 1846a09f99edSMiklos Szeredi if (!attr->ia_valid) 1847a09f99edSMiklos Szeredi return 0; 1848a09f99edSMiklos Szeredi 1849abb5a14fSLinus Torvalds ret = fuse_do_setattr(entry, attr, file); 18505e2b8828SMiklos Szeredi if (!ret) { 185160bcc88aSSeth Forshee /* 185260bcc88aSSeth Forshee * If filesystem supports acls it may have updated acl xattrs in 185360bcc88aSSeth Forshee * the filesystem, so forget cached acls for the inode. 185460bcc88aSSeth Forshee */ 185560bcc88aSSeth Forshee if (fc->posix_acl) 185660bcc88aSSeth Forshee forget_all_cached_acls(inode); 185760bcc88aSSeth Forshee 18585e2b8828SMiklos Szeredi /* Directory mode changed, may need to revalidate access */ 18595e2b8828SMiklos Szeredi if (d_is_dir(entry) && (attr->ia_valid & ATTR_MODE)) 18605e2b8828SMiklos Szeredi fuse_invalidate_entry_cache(entry); 18615e2b8828SMiklos Szeredi } 18625e2b8828SMiklos Szeredi return ret; 186349d4914fSMiklos Szeredi } 186449d4914fSMiklos Szeredi 1865549c7297SChristian Brauner static int fuse_getattr(struct user_namespace *mnt_userns, 1866549c7297SChristian Brauner const struct path *path, struct kstat *stat, 1867a528d35eSDavid Howells u32 request_mask, unsigned int flags) 1868e5e5558eSMiklos Szeredi { 1869a528d35eSDavid Howells struct inode *inode = d_inode(path->dentry); 1870244f6385SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(inode); 1871244f6385SMiklos Szeredi 18725d069dbeSMiklos Szeredi if (fuse_is_bad(inode)) 18735d069dbeSMiklos Szeredi return -EIO; 18745d069dbeSMiklos Szeredi 18755157da2cSMiklos Szeredi if (!fuse_allow_current_process(fc)) { 18765157da2cSMiklos Szeredi if (!request_mask) { 18775157da2cSMiklos Szeredi /* 18785157da2cSMiklos Szeredi * If user explicitly requested *nothing* then don't 18795157da2cSMiklos Szeredi * error out, but return st_dev only. 18805157da2cSMiklos Szeredi */ 18815157da2cSMiklos Szeredi stat->result_mask = 0; 18825157da2cSMiklos Szeredi stat->dev = inode->i_sb->s_dev; 18835157da2cSMiklos Szeredi return 0; 18845157da2cSMiklos Szeredi } 1885244f6385SMiklos Szeredi return -EACCES; 18865157da2cSMiklos Szeredi } 1887244f6385SMiklos Szeredi 18882f1e8196SMiklos Szeredi return fuse_update_get_attr(inode, NULL, stat, request_mask, flags); 1889e5e5558eSMiklos Szeredi } 1890e5e5558eSMiklos Szeredi 1891754661f1SArjan van de Ven static const struct inode_operations fuse_dir_inode_operations = { 1892e5e5558eSMiklos Szeredi .lookup = fuse_lookup, 18939e6268dbSMiklos Szeredi .mkdir = fuse_mkdir, 18949e6268dbSMiklos Szeredi .symlink = fuse_symlink, 18959e6268dbSMiklos Szeredi .unlink = fuse_unlink, 18969e6268dbSMiklos Szeredi .rmdir = fuse_rmdir, 18972773bf00SMiklos Szeredi .rename = fuse_rename2, 18989e6268dbSMiklos Szeredi .link = fuse_link, 18999e6268dbSMiklos Szeredi .setattr = fuse_setattr, 19009e6268dbSMiklos Szeredi .create = fuse_create, 1901c8ccbe03SMiklos Szeredi .atomic_open = fuse_atomic_open, 19029e6268dbSMiklos Szeredi .mknod = fuse_mknod, 1903e5e5558eSMiklos Szeredi .permission = fuse_permission, 1904e5e5558eSMiklos Szeredi .getattr = fuse_getattr, 190592a8780eSMiklos Szeredi .listxattr = fuse_listxattr, 190660bcc88aSSeth Forshee .get_acl = fuse_get_acl, 190760bcc88aSSeth Forshee .set_acl = fuse_set_acl, 190872227eacSMiklos Szeredi .fileattr_get = fuse_fileattr_get, 190972227eacSMiklos Szeredi .fileattr_set = fuse_fileattr_set, 1910e5e5558eSMiklos Szeredi }; 1911e5e5558eSMiklos Szeredi 19124b6f5d20SArjan van de Ven static const struct file_operations fuse_dir_operations = { 1913b6aeadedSMiklos Szeredi .llseek = generic_file_llseek, 1914e5e5558eSMiklos Szeredi .read = generic_read_dir, 1915d9b3dbdcSAl Viro .iterate_shared = fuse_readdir, 1916e5e5558eSMiklos Szeredi .open = fuse_dir_open, 1917e5e5558eSMiklos Szeredi .release = fuse_dir_release, 191882547981SMiklos Szeredi .fsync = fuse_dir_fsync, 1919b18da0c5SMiklos Szeredi .unlocked_ioctl = fuse_dir_ioctl, 1920b18da0c5SMiklos Szeredi .compat_ioctl = fuse_dir_compat_ioctl, 1921e5e5558eSMiklos Szeredi }; 1922e5e5558eSMiklos Szeredi 1923754661f1SArjan van de Ven static const struct inode_operations fuse_common_inode_operations = { 19249e6268dbSMiklos Szeredi .setattr = fuse_setattr, 1925e5e5558eSMiklos Szeredi .permission = fuse_permission, 1926e5e5558eSMiklos Szeredi .getattr = fuse_getattr, 192792a8780eSMiklos Szeredi .listxattr = fuse_listxattr, 192860bcc88aSSeth Forshee .get_acl = fuse_get_acl, 192960bcc88aSSeth Forshee .set_acl = fuse_set_acl, 193072227eacSMiklos Szeredi .fileattr_get = fuse_fileattr_get, 193172227eacSMiklos Szeredi .fileattr_set = fuse_fileattr_set, 1932e5e5558eSMiklos Szeredi }; 1933e5e5558eSMiklos Szeredi 1934754661f1SArjan van de Ven static const struct inode_operations fuse_symlink_inode_operations = { 19359e6268dbSMiklos Szeredi .setattr = fuse_setattr, 19366b255391SAl Viro .get_link = fuse_get_link, 1937e5e5558eSMiklos Szeredi .getattr = fuse_getattr, 193892a8780eSMiklos Szeredi .listxattr = fuse_listxattr, 1939e5e5558eSMiklos Szeredi }; 1940e5e5558eSMiklos Szeredi 1941e5e5558eSMiklos Szeredi void fuse_init_common(struct inode *inode) 1942e5e5558eSMiklos Szeredi { 1943e5e5558eSMiklos Szeredi inode->i_op = &fuse_common_inode_operations; 1944e5e5558eSMiklos Szeredi } 1945e5e5558eSMiklos Szeredi 1946e5e5558eSMiklos Szeredi void fuse_init_dir(struct inode *inode) 1947e5e5558eSMiklos Szeredi { 1948ab2257e9SMiklos Szeredi struct fuse_inode *fi = get_fuse_inode(inode); 1949ab2257e9SMiklos Szeredi 1950e5e5558eSMiklos Szeredi inode->i_op = &fuse_dir_inode_operations; 1951e5e5558eSMiklos Szeredi inode->i_fop = &fuse_dir_operations; 1952ab2257e9SMiklos Szeredi 1953ab2257e9SMiklos Szeredi spin_lock_init(&fi->rdc.lock); 1954ab2257e9SMiklos Szeredi fi->rdc.cached = false; 1955ab2257e9SMiklos Szeredi fi->rdc.size = 0; 1956ab2257e9SMiklos Szeredi fi->rdc.pos = 0; 1957ab2257e9SMiklos Szeredi fi->rdc.version = 0; 1958e5e5558eSMiklos Szeredi } 1959e5e5558eSMiklos Szeredi 1960*5efd00e4SMatthew Wilcox (Oracle) static int fuse_symlink_read_folio(struct file *null, struct folio *folio) 19615571f1e6SDan Schatzberg { 1962*5efd00e4SMatthew Wilcox (Oracle) int err = fuse_readlink_page(folio->mapping->host, &folio->page); 19635571f1e6SDan Schatzberg 19645571f1e6SDan Schatzberg if (!err) 1965*5efd00e4SMatthew Wilcox (Oracle) folio_mark_uptodate(folio); 19665571f1e6SDan Schatzberg 1967*5efd00e4SMatthew Wilcox (Oracle) folio_unlock(folio); 19685571f1e6SDan Schatzberg 19695571f1e6SDan Schatzberg return err; 19705571f1e6SDan Schatzberg } 19715571f1e6SDan Schatzberg 19725571f1e6SDan Schatzberg static const struct address_space_operations fuse_symlink_aops = { 1973*5efd00e4SMatthew Wilcox (Oracle) .read_folio = fuse_symlink_read_folio, 19745571f1e6SDan Schatzberg }; 19755571f1e6SDan Schatzberg 1976e5e5558eSMiklos Szeredi void fuse_init_symlink(struct inode *inode) 1977e5e5558eSMiklos Szeredi { 1978e5e5558eSMiklos Szeredi inode->i_op = &fuse_symlink_inode_operations; 19795571f1e6SDan Schatzberg inode->i_data.a_ops = &fuse_symlink_aops; 19805571f1e6SDan Schatzberg inode_nohighmem(inode); 1981e5e5558eSMiklos Szeredi } 1982