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> 149ccf47b2SDave Marchevsky #include <linux/moduleparam.h> 15e5e5558eSMiklos Szeredi #include <linux/sched.h> 16e5e5558eSMiklos Szeredi #include <linux/namei.h> 1707e77dcaSMiklos Szeredi #include <linux/slab.h> 18703c7362SSeth Forshee #include <linux/xattr.h> 19261aaba7SMiklos Szeredi #include <linux/iversion.h> 2060bcc88aSSeth Forshee #include <linux/posix_acl.h> 213e2b6fdbSVivek Goyal #include <linux/security.h> 223e2b6fdbSVivek Goyal #include <linux/types.h> 233e2b6fdbSVivek Goyal #include <linux/kernel.h> 24e5e5558eSMiklos Szeredi 259ccf47b2SDave Marchevsky static bool __read_mostly allow_sys_admin_access; 269ccf47b2SDave Marchevsky module_param(allow_sys_admin_access, bool, 0644); 279ccf47b2SDave Marchevsky MODULE_PARM_DESC(allow_sys_admin_access, 289ccf47b2SDave Marchevsky "Allow users with CAP_SYS_ADMIN in initial userns to bypass allow_other access check"); 299ccf47b2SDave Marchevsky 304582a4abSFeng Shuo static void fuse_advise_use_readdirplus(struct inode *dir) 314582a4abSFeng Shuo { 324582a4abSFeng Shuo struct fuse_inode *fi = get_fuse_inode(dir); 334582a4abSFeng Shuo 344582a4abSFeng Shuo set_bit(FUSE_I_ADVISE_RDPLUS, &fi->state); 354582a4abSFeng Shuo } 364582a4abSFeng Shuo 3730c6a23dSKhazhismel Kumykov #if BITS_PER_LONG >= 64 3830c6a23dSKhazhismel Kumykov static inline void __fuse_dentry_settime(struct dentry *entry, u64 time) 3930c6a23dSKhazhismel Kumykov { 4030c6a23dSKhazhismel Kumykov entry->d_fsdata = (void *) time; 4130c6a23dSKhazhismel Kumykov } 4230c6a23dSKhazhismel Kumykov 4330c6a23dSKhazhismel Kumykov static inline u64 fuse_dentry_time(const struct dentry *entry) 4430c6a23dSKhazhismel Kumykov { 4530c6a23dSKhazhismel Kumykov return (u64)entry->d_fsdata; 4630c6a23dSKhazhismel Kumykov } 4730c6a23dSKhazhismel Kumykov 4830c6a23dSKhazhismel Kumykov #else 49f75fdf22SMiklos Szeredi union fuse_dentry { 50f75fdf22SMiklos Szeredi u64 time; 51f75fdf22SMiklos Szeredi struct rcu_head rcu; 52f75fdf22SMiklos Szeredi }; 53f75fdf22SMiklos Szeredi 5430c6a23dSKhazhismel Kumykov static inline void __fuse_dentry_settime(struct dentry *dentry, u64 time) 5530c6a23dSKhazhismel Kumykov { 5630c6a23dSKhazhismel Kumykov ((union fuse_dentry *) dentry->d_fsdata)->time = time; 5730c6a23dSKhazhismel Kumykov } 5830c6a23dSKhazhismel Kumykov 5930c6a23dSKhazhismel Kumykov static inline u64 fuse_dentry_time(const struct dentry *entry) 6030c6a23dSKhazhismel Kumykov { 6130c6a23dSKhazhismel Kumykov return ((union fuse_dentry *) entry->d_fsdata)->time; 6230c6a23dSKhazhismel Kumykov } 6330c6a23dSKhazhismel Kumykov #endif 6430c6a23dSKhazhismel Kumykov 658fab0106SMiklos Szeredi static void fuse_dentry_settime(struct dentry *dentry, u64 time) 660a0898cfSMiklos Szeredi { 678fab0106SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn_super(dentry->d_sb); 688fab0106SMiklos Szeredi bool delete = !time && fc->delete_stale; 698fab0106SMiklos Szeredi /* 708fab0106SMiklos Szeredi * Mess with DCACHE_OP_DELETE because dput() will be faster without it. 718fab0106SMiklos Szeredi * Don't care about races, either way it's just an optimization 728fab0106SMiklos Szeredi */ 738fab0106SMiklos Szeredi if ((!delete && (dentry->d_flags & DCACHE_OP_DELETE)) || 748fab0106SMiklos Szeredi (delete && !(dentry->d_flags & DCACHE_OP_DELETE))) { 758fab0106SMiklos Szeredi spin_lock(&dentry->d_lock); 768fab0106SMiklos Szeredi if (!delete) 778fab0106SMiklos Szeredi dentry->d_flags &= ~DCACHE_OP_DELETE; 788fab0106SMiklos Szeredi else 798fab0106SMiklos Szeredi dentry->d_flags |= DCACHE_OP_DELETE; 808fab0106SMiklos Szeredi spin_unlock(&dentry->d_lock); 810a0898cfSMiklos Szeredi } 820a0898cfSMiklos Szeredi 8330c6a23dSKhazhismel Kumykov __fuse_dentry_settime(dentry, time); 840a0898cfSMiklos Szeredi } 850a0898cfSMiklos Szeredi 866f9f1180SMiklos Szeredi /* 876f9f1180SMiklos Szeredi * FUSE caches dentries and attributes with separate timeout. The 886f9f1180SMiklos Szeredi * time in jiffies until the dentry/attributes are valid is stored in 89f75fdf22SMiklos Szeredi * dentry->d_fsdata and fuse_inode->i_time respectively. 906f9f1180SMiklos Szeredi */ 916f9f1180SMiklos Szeredi 926f9f1180SMiklos Szeredi /* 936f9f1180SMiklos Szeredi * Calculate the time in jiffies until a dentry/attributes are valid 946f9f1180SMiklos Szeredi */ 95bcb6f6d2SMiklos Szeredi static u64 time_to_jiffies(u64 sec, u32 nsec) 96e5e5558eSMiklos Szeredi { 97685d16ddSMiklos Szeredi if (sec || nsec) { 98bcb6f6d2SMiklos Szeredi struct timespec64 ts = { 99bcb6f6d2SMiklos Szeredi sec, 10021067527SDavid Sheets min_t(u32, nsec, NSEC_PER_SEC - 1) 101bcb6f6d2SMiklos Szeredi }; 102bcb6f6d2SMiklos Szeredi 103bcb6f6d2SMiklos Szeredi return get_jiffies_64() + timespec64_to_jiffies(&ts); 104685d16ddSMiklos Szeredi } else 1050a0898cfSMiklos Szeredi return 0; 106e5e5558eSMiklos Szeredi } 107e5e5558eSMiklos Szeredi 1086f9f1180SMiklos Szeredi /* 1096f9f1180SMiklos Szeredi * Set dentry and possibly attribute timeouts from the lookup/mk* 1106f9f1180SMiklos Szeredi * replies 1116f9f1180SMiklos Szeredi */ 112d123d8e1SMiklos Szeredi void fuse_change_entry_timeout(struct dentry *entry, struct fuse_entry_out *o) 1130aa7c699SMiklos Szeredi { 1140a0898cfSMiklos Szeredi fuse_dentry_settime(entry, 1150a0898cfSMiklos Szeredi time_to_jiffies(o->entry_valid, o->entry_valid_nsec)); 1161fb69e78SMiklos Szeredi } 1171fb69e78SMiklos Szeredi 1181fb69e78SMiklos Szeredi static u64 attr_timeout(struct fuse_attr_out *o) 1191fb69e78SMiklos Szeredi { 1201fb69e78SMiklos Szeredi return time_to_jiffies(o->attr_valid, o->attr_valid_nsec); 1211fb69e78SMiklos Szeredi } 1221fb69e78SMiklos Szeredi 123d123d8e1SMiklos Szeredi u64 entry_attr_timeout(struct fuse_entry_out *o) 1241fb69e78SMiklos Szeredi { 1251fb69e78SMiklos Szeredi return time_to_jiffies(o->attr_valid, o->attr_valid_nsec); 1268cbdf1e6SMiklos Szeredi } 1278cbdf1e6SMiklos Szeredi 128fa5eee57SMiklos Szeredi void fuse_invalidate_attr_mask(struct inode *inode, u32 mask) 1292f1e8196SMiklos Szeredi { 1302f1e8196SMiklos Szeredi set_mask_bits(&get_fuse_inode(inode)->inval_mask, 0, mask); 1312f1e8196SMiklos Szeredi } 1322f1e8196SMiklos Szeredi 1336f9f1180SMiklos Szeredi /* 1346f9f1180SMiklos Szeredi * Mark the attributes as stale, so that at the next call to 1356f9f1180SMiklos Szeredi * ->getattr() they will be fetched from userspace 1366f9f1180SMiklos Szeredi */ 1378cbdf1e6SMiklos Szeredi void fuse_invalidate_attr(struct inode *inode) 1388cbdf1e6SMiklos Szeredi { 1392f1e8196SMiklos Szeredi fuse_invalidate_attr_mask(inode, STATX_BASIC_STATS); 1408cbdf1e6SMiklos Szeredi } 1418cbdf1e6SMiklos Szeredi 142261aaba7SMiklos Szeredi static void fuse_dir_changed(struct inode *dir) 143261aaba7SMiklos Szeredi { 144261aaba7SMiklos Szeredi fuse_invalidate_attr(dir); 145261aaba7SMiklos Szeredi inode_maybe_inc_iversion(dir, false); 146261aaba7SMiklos Szeredi } 147261aaba7SMiklos Szeredi 148451418fcSAndrew Gallagher /** 149451418fcSAndrew Gallagher * Mark the attributes as stale due to an atime change. Avoid the invalidate if 150451418fcSAndrew Gallagher * atime is not used. 151451418fcSAndrew Gallagher */ 152451418fcSAndrew Gallagher void fuse_invalidate_atime(struct inode *inode) 153451418fcSAndrew Gallagher { 154451418fcSAndrew Gallagher if (!IS_RDONLY(inode)) 1552f1e8196SMiklos Szeredi fuse_invalidate_attr_mask(inode, STATX_ATIME); 156451418fcSAndrew Gallagher } 157451418fcSAndrew Gallagher 1586f9f1180SMiklos Szeredi /* 1596f9f1180SMiklos Szeredi * Just mark the entry as stale, so that a next attempt to look it up 1606f9f1180SMiklos Szeredi * will result in a new lookup call to userspace 1616f9f1180SMiklos Szeredi * 1626f9f1180SMiklos Szeredi * This is called when a dentry is about to become negative and the 1636f9f1180SMiklos Szeredi * timeout is unknown (unlink, rmdir, rename and in some cases 1646f9f1180SMiklos Szeredi * lookup) 1656f9f1180SMiklos Szeredi */ 166dbd561d2SMiklos Szeredi void fuse_invalidate_entry_cache(struct dentry *entry) 1678cbdf1e6SMiklos Szeredi { 1680a0898cfSMiklos Szeredi fuse_dentry_settime(entry, 0); 1698cbdf1e6SMiklos Szeredi } 1708cbdf1e6SMiklos Szeredi 1716f9f1180SMiklos Szeredi /* 1726f9f1180SMiklos Szeredi * Same as fuse_invalidate_entry_cache(), but also try to remove the 1736f9f1180SMiklos Szeredi * dentry from the hash 1746f9f1180SMiklos Szeredi */ 1758cbdf1e6SMiklos Szeredi static void fuse_invalidate_entry(struct dentry *entry) 1768cbdf1e6SMiklos Szeredi { 1778cbdf1e6SMiklos Szeredi d_invalidate(entry); 1788cbdf1e6SMiklos Szeredi fuse_invalidate_entry_cache(entry); 1790aa7c699SMiklos Szeredi } 1800aa7c699SMiklos Szeredi 1817078187aSMiklos Szeredi static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_args *args, 18213983d06SAl Viro u64 nodeid, const struct qstr *name, 183e5e5558eSMiklos Szeredi struct fuse_entry_out *outarg) 184e5e5558eSMiklos Szeredi { 1850e9663eeSMiklos Szeredi memset(outarg, 0, sizeof(struct fuse_entry_out)); 186d5b48543SMiklos Szeredi args->opcode = FUSE_LOOKUP; 187d5b48543SMiklos Szeredi args->nodeid = nodeid; 188d5b48543SMiklos Szeredi args->in_numargs = 1; 189d5b48543SMiklos Szeredi args->in_args[0].size = name->len + 1; 190d5b48543SMiklos Szeredi args->in_args[0].value = name->name; 191d5b48543SMiklos Szeredi args->out_numargs = 1; 192d5b48543SMiklos Szeredi args->out_args[0].size = sizeof(struct fuse_entry_out); 193d5b48543SMiklos Szeredi args->out_args[0].value = outarg; 194e5e5558eSMiklos Szeredi } 195e5e5558eSMiklos Szeredi 1966f9f1180SMiklos Szeredi /* 1976f9f1180SMiklos Szeredi * Check whether the dentry is still valid 1986f9f1180SMiklos Szeredi * 1996f9f1180SMiklos Szeredi * If the entry validity timeout has expired and the dentry is 2006f9f1180SMiklos Szeredi * positive, try to redo the lookup. If the lookup results in a 2016f9f1180SMiklos Szeredi * different inode, then let the VFS invalidate the dentry and redo 2026f9f1180SMiklos Szeredi * the lookup once more. If the lookup results in the same inode, 2036f9f1180SMiklos Szeredi * then refresh the attributes, timeouts and mark the dentry valid. 2046f9f1180SMiklos Szeredi */ 2050b728e19SAl Viro static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags) 206e5e5558eSMiklos Szeredi { 20734286d66SNick Piggin struct inode *inode; 20828420dadSMiklos Szeredi struct dentry *parent; 209fcee216bSMax Reitz struct fuse_mount *fm; 2106314efeeSMiklos Szeredi struct fuse_inode *fi; 211e2a6b952SMiklos Szeredi int ret; 2128cbdf1e6SMiklos Szeredi 2132b0143b5SDavid Howells inode = d_inode_rcu(entry); 2145d069dbeSMiklos Szeredi if (inode && fuse_is_bad(inode)) 215e2a6b952SMiklos Szeredi goto invalid; 216154210ccSAnand Avati else if (time_before64(fuse_dentry_time(entry), get_jiffies_64()) || 217*ccc031e2SJiachen Zhang (flags & (LOOKUP_EXCL | LOOKUP_REVAL | LOOKUP_RENAME_TARGET))) { 218e5e5558eSMiklos Szeredi struct fuse_entry_out outarg; 2197078187aSMiklos Szeredi FUSE_ARGS(args); 22007e77dcaSMiklos Szeredi struct fuse_forget_link *forget; 2211fb69e78SMiklos Szeredi u64 attr_version; 2228cbdf1e6SMiklos Szeredi 22350322fe7SMiklos Szeredi /* For negative dentries, always do a fresh lookup */ 2248cbdf1e6SMiklos Szeredi if (!inode) 225e2a6b952SMiklos Szeredi goto invalid; 2268cbdf1e6SMiklos Szeredi 227e2a6b952SMiklos Szeredi ret = -ECHILD; 2280b728e19SAl Viro if (flags & LOOKUP_RCU) 229e2a6b952SMiklos Szeredi goto out; 230e7c0a167SMiklos Szeredi 231fcee216bSMax Reitz fm = get_fuse_mount(inode); 232e5e5558eSMiklos Szeredi 23307e77dcaSMiklos Szeredi forget = fuse_alloc_forget(); 234e2a6b952SMiklos Szeredi ret = -ENOMEM; 2357078187aSMiklos Szeredi if (!forget) 236e2a6b952SMiklos Szeredi goto out; 2372d51013eSMiklos Szeredi 238fcee216bSMax Reitz attr_version = fuse_get_attr_version(fm->fc); 2391fb69e78SMiklos Szeredi 240e956edd0SMiklos Szeredi parent = dget_parent(entry); 241fcee216bSMax Reitz fuse_lookup_init(fm->fc, &args, get_node_id(d_inode(parent)), 242c180eebeSMiklos Szeredi &entry->d_name, &outarg); 243fcee216bSMax Reitz ret = fuse_simple_request(fm, &args); 244e956edd0SMiklos Szeredi dput(parent); 24550322fe7SMiklos Szeredi /* Zero nodeid is same as -ENOENT */ 2467078187aSMiklos Szeredi if (!ret && !outarg.nodeid) 2477078187aSMiklos Szeredi ret = -ENOENT; 2487078187aSMiklos Szeredi if (!ret) { 2496314efeeSMiklos Szeredi fi = get_fuse_inode(inode); 250bf109c64SMax Reitz if (outarg.nodeid != get_node_id(inode) || 251bf109c64SMax Reitz (bool) IS_AUTOMOUNT(inode) != (bool) (outarg.attr.flags & FUSE_ATTR_SUBMOUNT)) { 252fcee216bSMax Reitz fuse_queue_forget(fm->fc, forget, 253fcee216bSMax Reitz outarg.nodeid, 1); 254e2a6b952SMiklos Szeredi goto invalid; 2559e6268dbSMiklos Szeredi } 256c9d8f5f0SKirill Tkhai spin_lock(&fi->lock); 2579e6268dbSMiklos Szeredi fi->nlookup++; 258c9d8f5f0SKirill Tkhai spin_unlock(&fi->lock); 2599e6268dbSMiklos Szeredi } 26007e77dcaSMiklos Szeredi kfree(forget); 2617078187aSMiklos Szeredi if (ret == -ENOMEM) 2627078187aSMiklos Szeredi goto out; 263eb59bd17SMiklos Szeredi if (ret || fuse_invalid_attr(&outarg.attr) || 26415db1683SAmir Goldstein fuse_stale_inode(inode, outarg.generation, &outarg.attr)) 265e2a6b952SMiklos Szeredi goto invalid; 266e5e5558eSMiklos Szeredi 26760bcc88aSSeth Forshee forget_all_cached_acls(inode); 2681fb69e78SMiklos Szeredi fuse_change_attributes(inode, &outarg.attr, 2691fb69e78SMiklos Szeredi entry_attr_timeout(&outarg), 2701fb69e78SMiklos Szeredi attr_version); 2711fb69e78SMiklos Szeredi fuse_change_entry_timeout(entry, &outarg); 27228420dadSMiklos Szeredi } else if (inode) { 2736314efeeSMiklos Szeredi fi = get_fuse_inode(inode); 2746314efeeSMiklos Szeredi if (flags & LOOKUP_RCU) { 2756314efeeSMiklos Szeredi if (test_bit(FUSE_I_INIT_RDPLUS, &fi->state)) 2766314efeeSMiklos Szeredi return -ECHILD; 2776314efeeSMiklos Szeredi } else if (test_and_clear_bit(FUSE_I_INIT_RDPLUS, &fi->state)) { 27828420dadSMiklos Szeredi parent = dget_parent(entry); 2792b0143b5SDavid Howells fuse_advise_use_readdirplus(d_inode(parent)); 28028420dadSMiklos Szeredi dput(parent); 281e5e5558eSMiklos Szeredi } 28228420dadSMiklos Szeredi } 283e2a6b952SMiklos Szeredi ret = 1; 284e2a6b952SMiklos Szeredi out: 285e2a6b952SMiklos Szeredi return ret; 286e2a6b952SMiklos Szeredi 287e2a6b952SMiklos Szeredi invalid: 288e2a6b952SMiklos Szeredi ret = 0; 289e2a6b952SMiklos Szeredi goto out; 290e5e5558eSMiklos Szeredi } 291e5e5558eSMiklos Szeredi 29230c6a23dSKhazhismel Kumykov #if BITS_PER_LONG < 64 293f75fdf22SMiklos Szeredi static int fuse_dentry_init(struct dentry *dentry) 294f75fdf22SMiklos Szeredi { 295dc69e98cSKhazhismel Kumykov dentry->d_fsdata = kzalloc(sizeof(union fuse_dentry), 296dc69e98cSKhazhismel Kumykov GFP_KERNEL_ACCOUNT | __GFP_RECLAIMABLE); 297f75fdf22SMiklos Szeredi 298f75fdf22SMiklos Szeredi return dentry->d_fsdata ? 0 : -ENOMEM; 299f75fdf22SMiklos Szeredi } 300f75fdf22SMiklos Szeredi static void fuse_dentry_release(struct dentry *dentry) 301f75fdf22SMiklos Szeredi { 302f75fdf22SMiklos Szeredi union fuse_dentry *fd = dentry->d_fsdata; 303f75fdf22SMiklos Szeredi 304f75fdf22SMiklos Szeredi kfree_rcu(fd, rcu); 305f75fdf22SMiklos Szeredi } 30630c6a23dSKhazhismel Kumykov #endif 307f75fdf22SMiklos Szeredi 3088fab0106SMiklos Szeredi static int fuse_dentry_delete(const struct dentry *dentry) 3098fab0106SMiklos Szeredi { 3108fab0106SMiklos Szeredi return time_before64(fuse_dentry_time(dentry), get_jiffies_64()); 3118fab0106SMiklos Szeredi } 3128fab0106SMiklos Szeredi 313bf109c64SMax Reitz /* 314bf109c64SMax Reitz * Create a fuse_mount object with a new superblock (with path->dentry 315bf109c64SMax Reitz * as the root), and return that mount so it can be auto-mounted on 316bf109c64SMax Reitz * @path. 317bf109c64SMax Reitz */ 318bf109c64SMax Reitz static struct vfsmount *fuse_dentry_automount(struct path *path) 319bf109c64SMax Reitz { 320bf109c64SMax Reitz struct fs_context *fsc; 321bf109c64SMax Reitz struct vfsmount *mnt; 322bf109c64SMax Reitz struct fuse_inode *mp_fi = get_fuse_inode(d_inode(path->dentry)); 323bf109c64SMax Reitz 324bf109c64SMax Reitz fsc = fs_context_for_submount(path->mnt->mnt_sb->s_type, path->dentry); 32529e0e4dfSGreg Kurz if (IS_ERR(fsc)) 32629e0e4dfSGreg Kurz return ERR_CAST(fsc); 327bf109c64SMax Reitz 328266eb3f2SGreg Kurz /* Pass the FUSE inode of the mount for fuse_get_tree_submount() */ 329266eb3f2SGreg Kurz fsc->fs_private = mp_fi; 330266eb3f2SGreg Kurz 331bf109c64SMax Reitz /* Create the submount */ 33229e0e4dfSGreg Kurz mnt = fc_mount(fsc); 33329e0e4dfSGreg Kurz if (!IS_ERR(mnt)) 334bf109c64SMax Reitz mntget(mnt); 33529e0e4dfSGreg Kurz 336bf109c64SMax Reitz put_fs_context(fsc); 337bf109c64SMax Reitz return mnt; 338bf109c64SMax Reitz } 339bf109c64SMax Reitz 3404269590aSAl Viro const struct dentry_operations fuse_dentry_operations = { 341e5e5558eSMiklos Szeredi .d_revalidate = fuse_dentry_revalidate, 3428fab0106SMiklos Szeredi .d_delete = fuse_dentry_delete, 34330c6a23dSKhazhismel Kumykov #if BITS_PER_LONG < 64 344f75fdf22SMiklos Szeredi .d_init = fuse_dentry_init, 345f75fdf22SMiklos Szeredi .d_release = fuse_dentry_release, 34630c6a23dSKhazhismel Kumykov #endif 347bf109c64SMax Reitz .d_automount = fuse_dentry_automount, 348e5e5558eSMiklos Szeredi }; 349e5e5558eSMiklos Szeredi 3500ce267ffSMiklos Szeredi const struct dentry_operations fuse_root_dentry_operations = { 35130c6a23dSKhazhismel Kumykov #if BITS_PER_LONG < 64 3520ce267ffSMiklos Szeredi .d_init = fuse_dentry_init, 3530ce267ffSMiklos Szeredi .d_release = fuse_dentry_release, 35430c6a23dSKhazhismel Kumykov #endif 3550ce267ffSMiklos Szeredi }; 3560ce267ffSMiklos Szeredi 357a5bfffacSTimo Savola int fuse_valid_type(int m) 35839ee059aSMiklos Szeredi { 35939ee059aSMiklos Szeredi return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) || 36039ee059aSMiklos Szeredi S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m); 36139ee059aSMiklos Szeredi } 36239ee059aSMiklos Szeredi 363eb59bd17SMiklos Szeredi bool fuse_invalid_attr(struct fuse_attr *attr) 364eb59bd17SMiklos Szeredi { 365eb59bd17SMiklos Szeredi return !fuse_valid_type(attr->mode) || 366eb59bd17SMiklos Szeredi attr->size > LLONG_MAX; 367eb59bd17SMiklos Szeredi } 368eb59bd17SMiklos Szeredi 36913983d06SAl Viro int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name, 370c180eebeSMiklos Szeredi struct fuse_entry_out *outarg, struct inode **inode) 371c180eebeSMiklos Szeredi { 372fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount_super(sb); 3737078187aSMiklos Szeredi FUSE_ARGS(args); 37407e77dcaSMiklos Szeredi struct fuse_forget_link *forget; 375c180eebeSMiklos Szeredi u64 attr_version; 376c180eebeSMiklos Szeredi int err; 377c180eebeSMiklos Szeredi 378c180eebeSMiklos Szeredi *inode = NULL; 379c180eebeSMiklos Szeredi err = -ENAMETOOLONG; 380c180eebeSMiklos Szeredi if (name->len > FUSE_NAME_MAX) 381c180eebeSMiklos Szeredi goto out; 382c180eebeSMiklos Szeredi 383c180eebeSMiklos Szeredi 38407e77dcaSMiklos Szeredi forget = fuse_alloc_forget(); 38507e77dcaSMiklos Szeredi err = -ENOMEM; 3867078187aSMiklos Szeredi if (!forget) 387c180eebeSMiklos Szeredi goto out; 388c180eebeSMiklos Szeredi 389fcee216bSMax Reitz attr_version = fuse_get_attr_version(fm->fc); 390c180eebeSMiklos Szeredi 391fcee216bSMax Reitz fuse_lookup_init(fm->fc, &args, nodeid, name, outarg); 392fcee216bSMax Reitz err = fuse_simple_request(fm, &args); 393c180eebeSMiklos Szeredi /* Zero nodeid is same as -ENOENT, but with valid timeout */ 394c180eebeSMiklos Szeredi if (err || !outarg->nodeid) 395c180eebeSMiklos Szeredi goto out_put_forget; 396c180eebeSMiklos Szeredi 397c180eebeSMiklos Szeredi err = -EIO; 398c180eebeSMiklos Szeredi if (!outarg->nodeid) 399c180eebeSMiklos Szeredi goto out_put_forget; 400eb59bd17SMiklos Szeredi if (fuse_invalid_attr(&outarg->attr)) 401c180eebeSMiklos Szeredi goto out_put_forget; 402c180eebeSMiklos Szeredi 403c180eebeSMiklos Szeredi *inode = fuse_iget(sb, outarg->nodeid, outarg->generation, 404c180eebeSMiklos Szeredi &outarg->attr, entry_attr_timeout(outarg), 405c180eebeSMiklos Szeredi attr_version); 406c180eebeSMiklos Szeredi err = -ENOMEM; 407c180eebeSMiklos Szeredi if (!*inode) { 408fcee216bSMax Reitz fuse_queue_forget(fm->fc, forget, outarg->nodeid, 1); 409c180eebeSMiklos Szeredi goto out; 410c180eebeSMiklos Szeredi } 411c180eebeSMiklos Szeredi err = 0; 412c180eebeSMiklos Szeredi 413c180eebeSMiklos Szeredi out_put_forget: 41407e77dcaSMiklos Szeredi kfree(forget); 415c180eebeSMiklos Szeredi out: 416c180eebeSMiklos Szeredi return err; 417c180eebeSMiklos Szeredi } 418c180eebeSMiklos Szeredi 4190aa7c699SMiklos Szeredi static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, 42000cd8dd3SAl Viro unsigned int flags) 421e5e5558eSMiklos Szeredi { 422e5e5558eSMiklos Szeredi int err; 423e5e5558eSMiklos Szeredi struct fuse_entry_out outarg; 424c180eebeSMiklos Szeredi struct inode *inode; 4250de6256dSMiklos Szeredi struct dentry *newent; 426c180eebeSMiklos Szeredi bool outarg_valid = true; 42763576c13SMiklos Szeredi bool locked; 428e5e5558eSMiklos Szeredi 4295d069dbeSMiklos Szeredi if (fuse_is_bad(dir)) 4305d069dbeSMiklos Szeredi return ERR_PTR(-EIO); 4315d069dbeSMiklos Szeredi 43263576c13SMiklos Szeredi locked = fuse_lock_inode(dir); 433c180eebeSMiklos Szeredi err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name, 434c180eebeSMiklos Szeredi &outarg, &inode); 43563576c13SMiklos Szeredi fuse_unlock_inode(dir, locked); 436c180eebeSMiklos Szeredi if (err == -ENOENT) { 437c180eebeSMiklos Szeredi outarg_valid = false; 438c180eebeSMiklos Szeredi err = 0; 4392d51013eSMiklos Szeredi } 440c180eebeSMiklos Szeredi if (err) 441c180eebeSMiklos Szeredi goto out_err; 4422d51013eSMiklos Szeredi 443ee4e5271SMiklos Szeredi err = -EIO; 444c180eebeSMiklos Szeredi if (inode && get_node_id(inode) == FUSE_ROOT_ID) 445c180eebeSMiklos Szeredi goto out_iput; 446e5e5558eSMiklos Szeredi 44741d28bcaSAl Viro newent = d_splice_alias(inode, entry); 448c180eebeSMiklos Szeredi err = PTR_ERR(newent); 449c180eebeSMiklos Szeredi if (IS_ERR(newent)) 4505835f339SMiklos Szeredi goto out_err; 451d2a85164SMiklos Szeredi 4520de6256dSMiklos Szeredi entry = newent ? newent : entry; 453c180eebeSMiklos Szeredi if (outarg_valid) 4541fb69e78SMiklos Szeredi fuse_change_entry_timeout(entry, &outarg); 4558cbdf1e6SMiklos Szeredi else 4568cbdf1e6SMiklos Szeredi fuse_invalidate_entry_cache(entry); 457c180eebeSMiklos Szeredi 4586c26f717SMiklos Szeredi if (inode) 4594582a4abSFeng Shuo fuse_advise_use_readdirplus(dir); 4600de6256dSMiklos Szeredi return newent; 461c180eebeSMiklos Szeredi 462c180eebeSMiklos Szeredi out_iput: 463c180eebeSMiklos Szeredi iput(inode); 464c180eebeSMiklos Szeredi out_err: 465c180eebeSMiklos Szeredi return ERR_PTR(err); 466e5e5558eSMiklos Szeredi } 467e5e5558eSMiklos Szeredi 4683e2b6fdbSVivek Goyal static int get_security_context(struct dentry *entry, umode_t mode, 4693e2b6fdbSVivek Goyal void **security_ctx, u32 *security_ctxlen) 4703e2b6fdbSVivek Goyal { 4713e2b6fdbSVivek Goyal struct fuse_secctx *fctx; 4723e2b6fdbSVivek Goyal struct fuse_secctx_header *header; 4733e2b6fdbSVivek Goyal void *ctx = NULL, *ptr; 4743e2b6fdbSVivek Goyal u32 ctxlen, total_len = sizeof(*header); 4753e2b6fdbSVivek Goyal int err, nr_ctx = 0; 4763e2b6fdbSVivek Goyal const char *name; 4773e2b6fdbSVivek Goyal size_t namelen; 4783e2b6fdbSVivek Goyal 4793e2b6fdbSVivek Goyal err = security_dentry_init_security(entry, mode, &entry->d_name, 4803e2b6fdbSVivek Goyal &name, &ctx, &ctxlen); 4813e2b6fdbSVivek Goyal if (err) { 4823e2b6fdbSVivek Goyal if (err != -EOPNOTSUPP) 4833e2b6fdbSVivek Goyal goto out_err; 4843e2b6fdbSVivek Goyal /* No LSM is supporting this security hook. Ignore error */ 4853e2b6fdbSVivek Goyal ctxlen = 0; 4863e2b6fdbSVivek Goyal ctx = NULL; 4873e2b6fdbSVivek Goyal } 4883e2b6fdbSVivek Goyal 4893e2b6fdbSVivek Goyal if (ctxlen) { 4903e2b6fdbSVivek Goyal nr_ctx = 1; 4913e2b6fdbSVivek Goyal namelen = strlen(name) + 1; 4923e2b6fdbSVivek Goyal err = -EIO; 4933e2b6fdbSVivek Goyal if (WARN_ON(namelen > XATTR_NAME_MAX + 1 || ctxlen > S32_MAX)) 4943e2b6fdbSVivek Goyal goto out_err; 4953e2b6fdbSVivek Goyal total_len += FUSE_REC_ALIGN(sizeof(*fctx) + namelen + ctxlen); 4963e2b6fdbSVivek Goyal } 4973e2b6fdbSVivek Goyal 4983e2b6fdbSVivek Goyal err = -ENOMEM; 4993e2b6fdbSVivek Goyal header = ptr = kzalloc(total_len, GFP_KERNEL); 5003e2b6fdbSVivek Goyal if (!ptr) 5013e2b6fdbSVivek Goyal goto out_err; 5023e2b6fdbSVivek Goyal 5033e2b6fdbSVivek Goyal header->nr_secctx = nr_ctx; 5043e2b6fdbSVivek Goyal header->size = total_len; 5053e2b6fdbSVivek Goyal ptr += sizeof(*header); 5063e2b6fdbSVivek Goyal if (nr_ctx) { 5073e2b6fdbSVivek Goyal fctx = ptr; 5083e2b6fdbSVivek Goyal fctx->size = ctxlen; 5093e2b6fdbSVivek Goyal ptr += sizeof(*fctx); 5103e2b6fdbSVivek Goyal 5113e2b6fdbSVivek Goyal strcpy(ptr, name); 5123e2b6fdbSVivek Goyal ptr += namelen; 5133e2b6fdbSVivek Goyal 5143e2b6fdbSVivek Goyal memcpy(ptr, ctx, ctxlen); 5153e2b6fdbSVivek Goyal } 5163e2b6fdbSVivek Goyal *security_ctxlen = total_len; 5173e2b6fdbSVivek Goyal *security_ctx = header; 5183e2b6fdbSVivek Goyal err = 0; 5193e2b6fdbSVivek Goyal out_err: 5203e2b6fdbSVivek Goyal kfree(ctx); 5213e2b6fdbSVivek Goyal return err; 5223e2b6fdbSVivek Goyal } 5233e2b6fdbSVivek Goyal 5246f9f1180SMiklos Szeredi /* 5256f9f1180SMiklos Szeredi * Atomic create+open operation 5266f9f1180SMiklos Szeredi * 5276f9f1180SMiklos Szeredi * If the filesystem doesn't support this, then fall back to separate 5286f9f1180SMiklos Szeredi * 'mknod' + 'open' requests. 5296f9f1180SMiklos Szeredi */ 530d9585277SAl Viro static int fuse_create_open(struct inode *dir, struct dentry *entry, 53154d601cbSMiklos Szeredi struct file *file, unsigned int flags, 5327d375390SMiklos Szeredi umode_t mode, u32 opcode) 533fd72faacSMiklos Szeredi { 534fd72faacSMiklos Szeredi int err; 535fd72faacSMiklos Szeredi struct inode *inode; 536fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(dir); 5377078187aSMiklos Szeredi FUSE_ARGS(args); 53807e77dcaSMiklos Szeredi struct fuse_forget_link *forget; 539e0a43ddcSMiklos Szeredi struct fuse_create_in inarg; 540fd72faacSMiklos Szeredi struct fuse_open_out outopen; 541fd72faacSMiklos Szeredi struct fuse_entry_out outentry; 542ebf84d0cSKirill Tkhai struct fuse_inode *fi; 543fd72faacSMiklos Szeredi struct fuse_file *ff; 5443e2b6fdbSVivek Goyal void *security_ctx = NULL; 5453e2b6fdbSVivek Goyal u32 security_ctxlen; 5462fdbb8ddSMiklos Szeredi bool trunc = flags & O_TRUNC; 547fd72faacSMiklos Szeredi 548af109bcaSMiklos Szeredi /* Userspace expects S_IFREG in create mode */ 549af109bcaSMiklos Szeredi BUG_ON((mode & S_IFMT) != S_IFREG); 550af109bcaSMiklos Szeredi 55107e77dcaSMiklos Szeredi forget = fuse_alloc_forget(); 552c8ccbe03SMiklos Szeredi err = -ENOMEM; 55307e77dcaSMiklos Szeredi if (!forget) 554c8ccbe03SMiklos Szeredi goto out_err; 55551eb01e7SMiklos Szeredi 556ce1d5a49SMiklos Szeredi err = -ENOMEM; 557fcee216bSMax Reitz ff = fuse_file_alloc(fm); 558fd72faacSMiklos Szeredi if (!ff) 5597078187aSMiklos Szeredi goto out_put_forget_req; 560fd72faacSMiklos Szeredi 561fcee216bSMax Reitz if (!fm->fc->dont_mask) 562e0a43ddcSMiklos Szeredi mode &= ~current_umask(); 563e0a43ddcSMiklos Szeredi 564fd72faacSMiklos Szeredi flags &= ~O_NOCTTY; 565fd72faacSMiklos Szeredi memset(&inarg, 0, sizeof(inarg)); 5660e9663eeSMiklos Szeredi memset(&outentry, 0, sizeof(outentry)); 567fd72faacSMiklos Szeredi inarg.flags = flags; 568fd72faacSMiklos Szeredi inarg.mode = mode; 569e0a43ddcSMiklos Szeredi inarg.umask = current_umask(); 570643a666aSVivek Goyal 5712fdbb8ddSMiklos Szeredi if (fm->fc->handle_killpriv_v2 && trunc && 572643a666aSVivek Goyal !(flags & O_EXCL) && !capable(CAP_FSETID)) { 573643a666aSVivek Goyal inarg.open_flags |= FUSE_OPEN_KILL_SUIDGID; 574643a666aSVivek Goyal } 575643a666aSVivek Goyal 5767d375390SMiklos Szeredi args.opcode = opcode; 577d5b48543SMiklos Szeredi args.nodeid = get_node_id(dir); 578d5b48543SMiklos Szeredi args.in_numargs = 2; 579d5b48543SMiklos Szeredi args.in_args[0].size = sizeof(inarg); 580d5b48543SMiklos Szeredi args.in_args[0].value = &inarg; 581d5b48543SMiklos Szeredi args.in_args[1].size = entry->d_name.len + 1; 582d5b48543SMiklos Szeredi args.in_args[1].value = entry->d_name.name; 583d5b48543SMiklos Szeredi args.out_numargs = 2; 584d5b48543SMiklos Szeredi args.out_args[0].size = sizeof(outentry); 585d5b48543SMiklos Szeredi args.out_args[0].value = &outentry; 586d5b48543SMiklos Szeredi args.out_args[1].size = sizeof(outopen); 587d5b48543SMiklos Szeredi args.out_args[1].value = &outopen; 5883e2b6fdbSVivek Goyal 5893e2b6fdbSVivek Goyal if (fm->fc->init_security) { 5903e2b6fdbSVivek Goyal err = get_security_context(entry, mode, &security_ctx, 5913e2b6fdbSVivek Goyal &security_ctxlen); 5923e2b6fdbSVivek Goyal if (err) 5933e2b6fdbSVivek Goyal goto out_put_forget_req; 5943e2b6fdbSVivek Goyal 5953e2b6fdbSVivek Goyal args.in_numargs = 3; 5963e2b6fdbSVivek Goyal args.in_args[2].size = security_ctxlen; 5973e2b6fdbSVivek Goyal args.in_args[2].value = security_ctx; 5983e2b6fdbSVivek Goyal } 5993e2b6fdbSVivek Goyal 600fcee216bSMax Reitz err = fuse_simple_request(fm, &args); 6013e2b6fdbSVivek Goyal kfree(security_ctx); 602c8ccbe03SMiklos Szeredi if (err) 603fd72faacSMiklos Szeredi goto out_free_ff; 604fd72faacSMiklos Szeredi 605fd72faacSMiklos Szeredi err = -EIO; 606eb59bd17SMiklos Szeredi if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid) || 607eb59bd17SMiklos Szeredi fuse_invalid_attr(&outentry.attr)) 608fd72faacSMiklos Szeredi goto out_free_ff; 609fd72faacSMiklos Szeredi 610c7b7143cSMiklos Szeredi ff->fh = outopen.fh; 611c7b7143cSMiklos Szeredi ff->nodeid = outentry.nodeid; 612c7b7143cSMiklos Szeredi ff->open_flags = outopen.open_flags; 613fd72faacSMiklos Szeredi inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation, 6141fb69e78SMiklos Szeredi &outentry.attr, entry_attr_timeout(&outentry), 0); 615fd72faacSMiklos Szeredi if (!inode) { 616fd72faacSMiklos Szeredi flags &= ~(O_CREAT | O_EXCL | O_TRUNC); 617ebf84d0cSKirill Tkhai fuse_sync_release(NULL, ff, flags); 618fcee216bSMax Reitz fuse_queue_forget(fm->fc, forget, outentry.nodeid, 1); 619c8ccbe03SMiklos Szeredi err = -ENOMEM; 620c8ccbe03SMiklos Szeredi goto out_err; 621fd72faacSMiklos Szeredi } 62207e77dcaSMiklos Szeredi kfree(forget); 623fd72faacSMiklos Szeredi d_instantiate(entry, inode); 6241fb69e78SMiklos Szeredi fuse_change_entry_timeout(entry, &outentry); 625261aaba7SMiklos Szeredi fuse_dir_changed(dir); 626be12af3eSAl Viro err = finish_open(file, entry, generic_file_open); 62730d90494SAl Viro if (err) { 628ebf84d0cSKirill Tkhai fi = get_fuse_inode(inode); 629ebf84d0cSKirill Tkhai fuse_sync_release(fi, ff, flags); 630c8ccbe03SMiklos Szeredi } else { 631267d8444SMiklos Szeredi file->private_data = ff; 632c7b7143cSMiklos Szeredi fuse_finish_open(inode, file); 6332fdbb8ddSMiklos Szeredi if (fm->fc->atomic_o_trunc && trunc) 6342fdbb8ddSMiklos Szeredi truncate_pagecache(inode, 0); 6352fdbb8ddSMiklos Szeredi else if (!(ff->open_flags & FOPEN_KEEP_CACHE)) 6362fdbb8ddSMiklos Szeredi invalidate_inode_pages2(inode->i_mapping); 637c8ccbe03SMiklos Szeredi } 638d9585277SAl Viro return err; 639fd72faacSMiklos Szeredi 640fd72faacSMiklos Szeredi out_free_ff: 641fd72faacSMiklos Szeredi fuse_file_free(ff); 64251eb01e7SMiklos Szeredi out_put_forget_req: 64307e77dcaSMiklos Szeredi kfree(forget); 644c8ccbe03SMiklos Szeredi out_err: 645d9585277SAl Viro return err; 646c8ccbe03SMiklos Szeredi } 647c8ccbe03SMiklos Szeredi 648549c7297SChristian Brauner static int fuse_mknod(struct user_namespace *, struct inode *, struct dentry *, 649549c7297SChristian Brauner umode_t, dev_t); 650d9585277SAl Viro static int fuse_atomic_open(struct inode *dir, struct dentry *entry, 65130d90494SAl Viro struct file *file, unsigned flags, 65244907d79SAl Viro umode_t mode) 653c8ccbe03SMiklos Szeredi { 654c8ccbe03SMiklos Szeredi int err; 655c8ccbe03SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(dir); 656c8ccbe03SMiklos Szeredi struct dentry *res = NULL; 657c8ccbe03SMiklos Szeredi 6585d069dbeSMiklos Szeredi if (fuse_is_bad(dir)) 6595d069dbeSMiklos Szeredi return -EIO; 6605d069dbeSMiklos Szeredi 66100699ad8SAl Viro if (d_in_lookup(entry)) { 66200cd8dd3SAl Viro res = fuse_lookup(dir, entry, 0); 663c8ccbe03SMiklos Szeredi if (IS_ERR(res)) 664d9585277SAl Viro return PTR_ERR(res); 665c8ccbe03SMiklos Szeredi 666c8ccbe03SMiklos Szeredi if (res) 667c8ccbe03SMiklos Szeredi entry = res; 668c8ccbe03SMiklos Szeredi } 669c8ccbe03SMiklos Szeredi 6702b0143b5SDavid Howells if (!(flags & O_CREAT) || d_really_is_positive(entry)) 671c8ccbe03SMiklos Szeredi goto no_open; 672c8ccbe03SMiklos Szeredi 673c8ccbe03SMiklos Szeredi /* Only creates */ 67473a09dd9SAl Viro file->f_mode |= FMODE_CREATED; 675c8ccbe03SMiklos Szeredi 676c8ccbe03SMiklos Szeredi if (fc->no_create) 677c8ccbe03SMiklos Szeredi goto mknod; 678c8ccbe03SMiklos Szeredi 6797d375390SMiklos Szeredi err = fuse_create_open(dir, entry, file, flags, mode, FUSE_CREATE); 680d9585277SAl Viro if (err == -ENOSYS) { 681c8ccbe03SMiklos Szeredi fc->no_create = 1; 682c8ccbe03SMiklos Szeredi goto mknod; 683c8ccbe03SMiklos Szeredi } 684c8ccbe03SMiklos Szeredi out_dput: 685c8ccbe03SMiklos Szeredi dput(res); 686d9585277SAl Viro return err; 687c8ccbe03SMiklos Szeredi 688c8ccbe03SMiklos Szeredi mknod: 689549c7297SChristian Brauner err = fuse_mknod(&init_user_ns, dir, entry, mode, 0); 690d9585277SAl Viro if (err) 691c8ccbe03SMiklos Szeredi goto out_dput; 692c8ccbe03SMiklos Szeredi no_open: 693e45198a6SAl Viro return finish_no_open(file, res); 694fd72faacSMiklos Szeredi } 695fd72faacSMiklos Szeredi 6966f9f1180SMiklos Szeredi /* 6976f9f1180SMiklos Szeredi * Code shared between mknod, mkdir, symlink and link 6986f9f1180SMiklos Szeredi */ 699fcee216bSMax Reitz static int create_new_entry(struct fuse_mount *fm, struct fuse_args *args, 7009e6268dbSMiklos Szeredi struct inode *dir, struct dentry *entry, 701541af6a0SAl Viro umode_t mode) 7029e6268dbSMiklos Szeredi { 7039e6268dbSMiklos Szeredi struct fuse_entry_out outarg; 7049e6268dbSMiklos Szeredi struct inode *inode; 705c971e6a0SAl Viro struct dentry *d; 7069e6268dbSMiklos Szeredi int err; 70707e77dcaSMiklos Szeredi struct fuse_forget_link *forget; 7083e2b6fdbSVivek Goyal void *security_ctx = NULL; 7093e2b6fdbSVivek Goyal u32 security_ctxlen; 7102d51013eSMiklos Szeredi 7115d069dbeSMiklos Szeredi if (fuse_is_bad(dir)) 7125d069dbeSMiklos Szeredi return -EIO; 7135d069dbeSMiklos Szeredi 71407e77dcaSMiklos Szeredi forget = fuse_alloc_forget(); 7157078187aSMiklos Szeredi if (!forget) 71607e77dcaSMiklos Szeredi return -ENOMEM; 7179e6268dbSMiklos Szeredi 7180e9663eeSMiklos Szeredi memset(&outarg, 0, sizeof(outarg)); 719d5b48543SMiklos Szeredi args->nodeid = get_node_id(dir); 720d5b48543SMiklos Szeredi args->out_numargs = 1; 721d5b48543SMiklos Szeredi args->out_args[0].size = sizeof(outarg); 722d5b48543SMiklos Szeredi args->out_args[0].value = &outarg; 7233e2b6fdbSVivek Goyal 7243e2b6fdbSVivek Goyal if (fm->fc->init_security && args->opcode != FUSE_LINK) { 7253e2b6fdbSVivek Goyal err = get_security_context(entry, mode, &security_ctx, 7263e2b6fdbSVivek Goyal &security_ctxlen); 7273e2b6fdbSVivek Goyal if (err) 7283e2b6fdbSVivek Goyal goto out_put_forget_req; 7293e2b6fdbSVivek Goyal 7303e2b6fdbSVivek Goyal BUG_ON(args->in_numargs != 2); 7313e2b6fdbSVivek Goyal 7323e2b6fdbSVivek Goyal args->in_numargs = 3; 7333e2b6fdbSVivek Goyal args->in_args[2].size = security_ctxlen; 7343e2b6fdbSVivek Goyal args->in_args[2].value = security_ctx; 7353e2b6fdbSVivek Goyal } 7363e2b6fdbSVivek Goyal 737fcee216bSMax Reitz err = fuse_simple_request(fm, args); 7383e2b6fdbSVivek Goyal kfree(security_ctx); 7392d51013eSMiklos Szeredi if (err) 7402d51013eSMiklos Szeredi goto out_put_forget_req; 7412d51013eSMiklos Szeredi 74239ee059aSMiklos Szeredi err = -EIO; 743eb59bd17SMiklos Szeredi if (invalid_nodeid(outarg.nodeid) || fuse_invalid_attr(&outarg.attr)) 7442d51013eSMiklos Szeredi goto out_put_forget_req; 74539ee059aSMiklos Szeredi 74639ee059aSMiklos Szeredi if ((outarg.attr.mode ^ mode) & S_IFMT) 7472d51013eSMiklos Szeredi goto out_put_forget_req; 74839ee059aSMiklos Szeredi 7499e6268dbSMiklos Szeredi inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, 7501fb69e78SMiklos Szeredi &outarg.attr, entry_attr_timeout(&outarg), 0); 7519e6268dbSMiklos Szeredi if (!inode) { 752fcee216bSMax Reitz fuse_queue_forget(fm->fc, forget, outarg.nodeid, 1); 7539e6268dbSMiklos Szeredi return -ENOMEM; 7549e6268dbSMiklos Szeredi } 75507e77dcaSMiklos Szeredi kfree(forget); 7569e6268dbSMiklos Szeredi 757c971e6a0SAl Viro d_drop(entry); 758c971e6a0SAl Viro d = d_splice_alias(inode, entry); 759c971e6a0SAl Viro if (IS_ERR(d)) 760c971e6a0SAl Viro return PTR_ERR(d); 761d2a85164SMiklos Szeredi 762c971e6a0SAl Viro if (d) { 763c971e6a0SAl Viro fuse_change_entry_timeout(d, &outarg); 764c971e6a0SAl Viro dput(d); 765c971e6a0SAl Viro } else { 7661fb69e78SMiklos Szeredi fuse_change_entry_timeout(entry, &outarg); 767c971e6a0SAl Viro } 768261aaba7SMiklos Szeredi fuse_dir_changed(dir); 7699e6268dbSMiklos Szeredi return 0; 77039ee059aSMiklos Szeredi 7712d51013eSMiklos Szeredi out_put_forget_req: 77207e77dcaSMiklos Szeredi kfree(forget); 77339ee059aSMiklos Szeredi return err; 7749e6268dbSMiklos Szeredi } 7759e6268dbSMiklos Szeredi 776549c7297SChristian Brauner static int fuse_mknod(struct user_namespace *mnt_userns, struct inode *dir, 777549c7297SChristian Brauner struct dentry *entry, umode_t mode, dev_t rdev) 7789e6268dbSMiklos Szeredi { 7799e6268dbSMiklos Szeredi struct fuse_mknod_in inarg; 780fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(dir); 7817078187aSMiklos Szeredi FUSE_ARGS(args); 7829e6268dbSMiklos Szeredi 783fcee216bSMax Reitz if (!fm->fc->dont_mask) 784e0a43ddcSMiklos Szeredi mode &= ~current_umask(); 785e0a43ddcSMiklos Szeredi 7869e6268dbSMiklos Szeredi memset(&inarg, 0, sizeof(inarg)); 7879e6268dbSMiklos Szeredi inarg.mode = mode; 7889e6268dbSMiklos Szeredi inarg.rdev = new_encode_dev(rdev); 789e0a43ddcSMiklos Szeredi inarg.umask = current_umask(); 790d5b48543SMiklos Szeredi args.opcode = FUSE_MKNOD; 791d5b48543SMiklos Szeredi args.in_numargs = 2; 792d5b48543SMiklos Szeredi args.in_args[0].size = sizeof(inarg); 793d5b48543SMiklos Szeredi args.in_args[0].value = &inarg; 794d5b48543SMiklos Szeredi args.in_args[1].size = entry->d_name.len + 1; 795d5b48543SMiklos Szeredi args.in_args[1].value = entry->d_name.name; 796fcee216bSMax Reitz return create_new_entry(fm, &args, dir, entry, mode); 7979e6268dbSMiklos Szeredi } 7989e6268dbSMiklos Szeredi 799549c7297SChristian Brauner static int fuse_create(struct user_namespace *mnt_userns, struct inode *dir, 800549c7297SChristian Brauner struct dentry *entry, umode_t mode, bool excl) 8019e6268dbSMiklos Szeredi { 802549c7297SChristian Brauner return fuse_mknod(&init_user_ns, dir, entry, mode, 0); 8039e6268dbSMiklos Szeredi } 8049e6268dbSMiklos Szeredi 8057d375390SMiklos Szeredi static int fuse_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, 8067d375390SMiklos Szeredi struct file *file, umode_t mode) 8077d375390SMiklos Szeredi { 8087d375390SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(dir); 8097d375390SMiklos Szeredi int err; 8107d375390SMiklos Szeredi 8117d375390SMiklos Szeredi if (fc->no_tmpfile) 8127d375390SMiklos Szeredi return -EOPNOTSUPP; 8137d375390SMiklos Szeredi 8147d375390SMiklos Szeredi err = fuse_create_open(dir, file->f_path.dentry, file, file->f_flags, mode, FUSE_TMPFILE); 8157d375390SMiklos Szeredi if (err == -ENOSYS) { 8167d375390SMiklos Szeredi fc->no_tmpfile = 1; 8177d375390SMiklos Szeredi err = -EOPNOTSUPP; 8187d375390SMiklos Szeredi } 8197d375390SMiklos Szeredi return err; 8207d375390SMiklos Szeredi } 8217d375390SMiklos Szeredi 822549c7297SChristian Brauner static int fuse_mkdir(struct user_namespace *mnt_userns, struct inode *dir, 823549c7297SChristian Brauner struct dentry *entry, umode_t mode) 8249e6268dbSMiklos Szeredi { 8259e6268dbSMiklos Szeredi struct fuse_mkdir_in inarg; 826fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(dir); 8277078187aSMiklos Szeredi FUSE_ARGS(args); 8289e6268dbSMiklos Szeredi 829fcee216bSMax Reitz if (!fm->fc->dont_mask) 830e0a43ddcSMiklos Szeredi mode &= ~current_umask(); 831e0a43ddcSMiklos Szeredi 8329e6268dbSMiklos Szeredi memset(&inarg, 0, sizeof(inarg)); 8339e6268dbSMiklos Szeredi inarg.mode = mode; 834e0a43ddcSMiklos Szeredi inarg.umask = current_umask(); 835d5b48543SMiklos Szeredi args.opcode = FUSE_MKDIR; 836d5b48543SMiklos Szeredi args.in_numargs = 2; 837d5b48543SMiklos Szeredi args.in_args[0].size = sizeof(inarg); 838d5b48543SMiklos Szeredi args.in_args[0].value = &inarg; 839d5b48543SMiklos Szeredi args.in_args[1].size = entry->d_name.len + 1; 840d5b48543SMiklos Szeredi args.in_args[1].value = entry->d_name.name; 841fcee216bSMax Reitz return create_new_entry(fm, &args, dir, entry, S_IFDIR); 8429e6268dbSMiklos Szeredi } 8439e6268dbSMiklos Szeredi 844549c7297SChristian Brauner static int fuse_symlink(struct user_namespace *mnt_userns, struct inode *dir, 845549c7297SChristian Brauner struct dentry *entry, const char *link) 8469e6268dbSMiklos Szeredi { 847fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(dir); 8489e6268dbSMiklos Szeredi unsigned len = strlen(link) + 1; 8497078187aSMiklos Szeredi FUSE_ARGS(args); 8509e6268dbSMiklos Szeredi 851d5b48543SMiklos Szeredi args.opcode = FUSE_SYMLINK; 852d5b48543SMiklos Szeredi args.in_numargs = 2; 853d5b48543SMiklos Szeredi args.in_args[0].size = entry->d_name.len + 1; 854d5b48543SMiklos Szeredi args.in_args[0].value = entry->d_name.name; 855d5b48543SMiklos Szeredi args.in_args[1].size = len; 856d5b48543SMiklos Szeredi args.in_args[1].value = link; 857fcee216bSMax Reitz return create_new_entry(fm, &args, dir, entry, S_IFLNK); 8589e6268dbSMiklos Szeredi } 8599e6268dbSMiklos Szeredi 8605c791fe1SMiklos Szeredi void fuse_flush_time_update(struct inode *inode) 8615c791fe1SMiklos Szeredi { 8625c791fe1SMiklos Szeredi int err = sync_inode_metadata(inode, 1); 8635c791fe1SMiklos Szeredi 8645c791fe1SMiklos Szeredi mapping_set_error(inode->i_mapping, err); 8655c791fe1SMiklos Szeredi } 8665c791fe1SMiklos Szeredi 86797f044f6SMiklos Szeredi static void fuse_update_ctime_in_cache(struct inode *inode) 86831f3267bSMaxim Patlasov { 86931f3267bSMaxim Patlasov if (!IS_NOCMTIME(inode)) { 870c2050a45SDeepa Dinamani inode->i_ctime = current_time(inode); 87131f3267bSMaxim Patlasov mark_inode_dirty_sync(inode); 8725c791fe1SMiklos Szeredi fuse_flush_time_update(inode); 87331f3267bSMaxim Patlasov } 87431f3267bSMaxim Patlasov } 87531f3267bSMaxim Patlasov 87697f044f6SMiklos Szeredi void fuse_update_ctime(struct inode *inode) 87797f044f6SMiklos Szeredi { 878fa5eee57SMiklos Szeredi fuse_invalidate_attr_mask(inode, STATX_CTIME); 87997f044f6SMiklos Szeredi fuse_update_ctime_in_cache(inode); 88097f044f6SMiklos Szeredi } 88197f044f6SMiklos Szeredi 882cefd1b83SMiklos Szeredi static void fuse_entry_unlinked(struct dentry *entry) 883cefd1b83SMiklos Szeredi { 884cefd1b83SMiklos Szeredi struct inode *inode = d_inode(entry); 885cefd1b83SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(inode); 886cefd1b83SMiklos Szeredi struct fuse_inode *fi = get_fuse_inode(inode); 887cefd1b83SMiklos Szeredi 888cefd1b83SMiklos Szeredi spin_lock(&fi->lock); 889cefd1b83SMiklos Szeredi fi->attr_version = atomic64_inc_return(&fc->attr_version); 890cefd1b83SMiklos Szeredi /* 891cefd1b83SMiklos Szeredi * If i_nlink == 0 then unlink doesn't make sense, yet this can 892cefd1b83SMiklos Szeredi * happen if userspace filesystem is careless. It would be 893cefd1b83SMiklos Szeredi * difficult to enforce correct nlink usage so just ignore this 894cefd1b83SMiklos Szeredi * condition here 895cefd1b83SMiklos Szeredi */ 896cefd1b83SMiklos Szeredi if (S_ISDIR(inode->i_mode)) 897cefd1b83SMiklos Szeredi clear_nlink(inode); 898cefd1b83SMiklos Szeredi else if (inode->i_nlink > 0) 899cefd1b83SMiklos Szeredi drop_nlink(inode); 900cefd1b83SMiklos Szeredi spin_unlock(&fi->lock); 901cefd1b83SMiklos Szeredi fuse_invalidate_entry_cache(entry); 902cefd1b83SMiklos Szeredi fuse_update_ctime(inode); 903cefd1b83SMiklos Szeredi } 904cefd1b83SMiklos Szeredi 9059e6268dbSMiklos Szeredi static int fuse_unlink(struct inode *dir, struct dentry *entry) 9069e6268dbSMiklos Szeredi { 9079e6268dbSMiklos Szeredi int err; 908fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(dir); 9097078187aSMiklos Szeredi FUSE_ARGS(args); 9109e6268dbSMiklos Szeredi 9115d069dbeSMiklos Szeredi if (fuse_is_bad(dir)) 9125d069dbeSMiklos Szeredi return -EIO; 9135d069dbeSMiklos Szeredi 914d5b48543SMiklos Szeredi args.opcode = FUSE_UNLINK; 915d5b48543SMiklos Szeredi args.nodeid = get_node_id(dir); 916d5b48543SMiklos Szeredi args.in_numargs = 1; 917d5b48543SMiklos Szeredi args.in_args[0].size = entry->d_name.len + 1; 918d5b48543SMiklos Szeredi args.in_args[0].value = entry->d_name.name; 919fcee216bSMax Reitz err = fuse_simple_request(fm, &args); 9209e6268dbSMiklos Szeredi if (!err) { 921261aaba7SMiklos Szeredi fuse_dir_changed(dir); 922cefd1b83SMiklos Szeredi fuse_entry_unlinked(entry); 9239e6268dbSMiklos Szeredi } else if (err == -EINTR) 9249e6268dbSMiklos Szeredi fuse_invalidate_entry(entry); 9259e6268dbSMiklos Szeredi return err; 9269e6268dbSMiklos Szeredi } 9279e6268dbSMiklos Szeredi 9289e6268dbSMiklos Szeredi static int fuse_rmdir(struct inode *dir, struct dentry *entry) 9299e6268dbSMiklos Szeredi { 9309e6268dbSMiklos Szeredi int err; 931fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(dir); 9327078187aSMiklos Szeredi FUSE_ARGS(args); 9339e6268dbSMiklos Szeredi 9345d069dbeSMiklos Szeredi if (fuse_is_bad(dir)) 9355d069dbeSMiklos Szeredi return -EIO; 9365d069dbeSMiklos Szeredi 937d5b48543SMiklos Szeredi args.opcode = FUSE_RMDIR; 938d5b48543SMiklos Szeredi args.nodeid = get_node_id(dir); 939d5b48543SMiklos Szeredi args.in_numargs = 1; 940d5b48543SMiklos Szeredi args.in_args[0].size = entry->d_name.len + 1; 941d5b48543SMiklos Szeredi args.in_args[0].value = entry->d_name.name; 942fcee216bSMax Reitz err = fuse_simple_request(fm, &args); 9439e6268dbSMiklos Szeredi if (!err) { 944261aaba7SMiklos Szeredi fuse_dir_changed(dir); 945cefd1b83SMiklos Szeredi fuse_entry_unlinked(entry); 9469e6268dbSMiklos Szeredi } else if (err == -EINTR) 9479e6268dbSMiklos Szeredi fuse_invalidate_entry(entry); 9489e6268dbSMiklos Szeredi return err; 9499e6268dbSMiklos Szeredi } 9509e6268dbSMiklos Szeredi 9511560c974SMiklos Szeredi static int fuse_rename_common(struct inode *olddir, struct dentry *oldent, 9521560c974SMiklos Szeredi struct inode *newdir, struct dentry *newent, 9531560c974SMiklos Szeredi unsigned int flags, int opcode, size_t argsize) 9549e6268dbSMiklos Szeredi { 9559e6268dbSMiklos Szeredi int err; 9561560c974SMiklos Szeredi struct fuse_rename2_in inarg; 957fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(olddir); 9587078187aSMiklos Szeredi FUSE_ARGS(args); 9599e6268dbSMiklos Szeredi 9601560c974SMiklos Szeredi memset(&inarg, 0, argsize); 9619e6268dbSMiklos Szeredi inarg.newdir = get_node_id(newdir); 9621560c974SMiklos Szeredi inarg.flags = flags; 963d5b48543SMiklos Szeredi args.opcode = opcode; 964d5b48543SMiklos Szeredi args.nodeid = get_node_id(olddir); 965d5b48543SMiklos Szeredi args.in_numargs = 3; 966d5b48543SMiklos Szeredi args.in_args[0].size = argsize; 967d5b48543SMiklos Szeredi args.in_args[0].value = &inarg; 968d5b48543SMiklos Szeredi args.in_args[1].size = oldent->d_name.len + 1; 969d5b48543SMiklos Szeredi args.in_args[1].value = oldent->d_name.name; 970d5b48543SMiklos Szeredi args.in_args[2].size = newent->d_name.len + 1; 971d5b48543SMiklos Szeredi args.in_args[2].value = newent->d_name.name; 972fcee216bSMax Reitz err = fuse_simple_request(fm, &args); 9739e6268dbSMiklos Szeredi if (!err) { 97408b63307SMiklos Szeredi /* ctime changes */ 9752b0143b5SDavid Howells fuse_update_ctime(d_inode(oldent)); 97608b63307SMiklos Szeredi 977371e8fd0SMiklos Szeredi if (flags & RENAME_EXCHANGE) 9782b0143b5SDavid Howells fuse_update_ctime(d_inode(newent)); 9791560c974SMiklos Szeredi 980261aaba7SMiklos Szeredi fuse_dir_changed(olddir); 9819e6268dbSMiklos Szeredi if (olddir != newdir) 982261aaba7SMiklos Szeredi fuse_dir_changed(newdir); 9838cbdf1e6SMiklos Szeredi 9848cbdf1e6SMiklos Szeredi /* newent will end up negative */ 985cefd1b83SMiklos Szeredi if (!(flags & RENAME_EXCHANGE) && d_really_is_positive(newent)) 986cefd1b83SMiklos Szeredi fuse_entry_unlinked(newent); 9879e6268dbSMiklos Szeredi } else if (err == -EINTR) { 9889e6268dbSMiklos Szeredi /* If request was interrupted, DEITY only knows if the 9899e6268dbSMiklos Szeredi rename actually took place. If the invalidation 9909e6268dbSMiklos Szeredi fails (e.g. some process has CWD under the renamed 9919e6268dbSMiklos Szeredi directory), then there can be inconsistency between 9929e6268dbSMiklos Szeredi the dcache and the real filesystem. Tough luck. */ 9939e6268dbSMiklos Szeredi fuse_invalidate_entry(oldent); 9942b0143b5SDavid Howells if (d_really_is_positive(newent)) 9959e6268dbSMiklos Szeredi fuse_invalidate_entry(newent); 9969e6268dbSMiklos Szeredi } 9979e6268dbSMiklos Szeredi 9989e6268dbSMiklos Szeredi return err; 9999e6268dbSMiklos Szeredi } 10009e6268dbSMiklos Szeredi 1001549c7297SChristian Brauner static int fuse_rename2(struct user_namespace *mnt_userns, struct inode *olddir, 1002549c7297SChristian Brauner struct dentry *oldent, struct inode *newdir, 1003549c7297SChristian Brauner struct dentry *newent, unsigned int flags) 10041560c974SMiklos Szeredi { 10051560c974SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(olddir); 10061560c974SMiklos Szeredi int err; 10071560c974SMiklos Szeredi 10085d069dbeSMiklos Szeredi if (fuse_is_bad(olddir)) 10095d069dbeSMiklos Szeredi return -EIO; 10105d069dbeSMiklos Szeredi 1011519525faSVivek Goyal if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT)) 10121560c974SMiklos Szeredi return -EINVAL; 10131560c974SMiklos Szeredi 10144237ba43SMiklos Szeredi if (flags) { 10151560c974SMiklos Szeredi if (fc->no_rename2 || fc->minor < 23) 10161560c974SMiklos Szeredi return -EINVAL; 10171560c974SMiklos Szeredi 10181560c974SMiklos Szeredi err = fuse_rename_common(olddir, oldent, newdir, newent, flags, 10194237ba43SMiklos Szeredi FUSE_RENAME2, 10204237ba43SMiklos Szeredi sizeof(struct fuse_rename2_in)); 10211560c974SMiklos Szeredi if (err == -ENOSYS) { 10221560c974SMiklos Szeredi fc->no_rename2 = 1; 10231560c974SMiklos Szeredi err = -EINVAL; 10241560c974SMiklos Szeredi } 10254237ba43SMiklos Szeredi } else { 10264237ba43SMiklos Szeredi err = fuse_rename_common(olddir, oldent, newdir, newent, 0, 10274237ba43SMiklos Szeredi FUSE_RENAME, 10284237ba43SMiklos Szeredi sizeof(struct fuse_rename_in)); 10294237ba43SMiklos Szeredi } 10301560c974SMiklos Szeredi 10314237ba43SMiklos Szeredi return err; 10324237ba43SMiklos Szeredi } 10334237ba43SMiklos Szeredi 10349e6268dbSMiklos Szeredi static int fuse_link(struct dentry *entry, struct inode *newdir, 10359e6268dbSMiklos Szeredi struct dentry *newent) 10369e6268dbSMiklos Szeredi { 10379e6268dbSMiklos Szeredi int err; 10389e6268dbSMiklos Szeredi struct fuse_link_in inarg; 10392b0143b5SDavid Howells struct inode *inode = d_inode(entry); 1040fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(inode); 10417078187aSMiklos Szeredi FUSE_ARGS(args); 10429e6268dbSMiklos Szeredi 10439e6268dbSMiklos Szeredi memset(&inarg, 0, sizeof(inarg)); 10449e6268dbSMiklos Szeredi inarg.oldnodeid = get_node_id(inode); 1045d5b48543SMiklos Szeredi args.opcode = FUSE_LINK; 1046d5b48543SMiklos Szeredi args.in_numargs = 2; 1047d5b48543SMiklos Szeredi args.in_args[0].size = sizeof(inarg); 1048d5b48543SMiklos Szeredi args.in_args[0].value = &inarg; 1049d5b48543SMiklos Szeredi args.in_args[1].size = newent->d_name.len + 1; 1050d5b48543SMiklos Szeredi args.in_args[1].value = newent->d_name.name; 1051fcee216bSMax Reitz err = create_new_entry(fm, &args, newdir, newent, inode->i_mode); 105297f044f6SMiklos Szeredi if (!err) 105397f044f6SMiklos Szeredi fuse_update_ctime_in_cache(inode); 105497f044f6SMiklos Szeredi else if (err == -EINTR) 1055ac45d613SMiklos Szeredi fuse_invalidate_attr(inode); 105697f044f6SMiklos Szeredi 10579e6268dbSMiklos Szeredi return err; 10589e6268dbSMiklos Szeredi } 10599e6268dbSMiklos Szeredi 10601fb69e78SMiklos Szeredi static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr, 10611fb69e78SMiklos Szeredi struct kstat *stat) 10621fb69e78SMiklos Szeredi { 1063203627bbSMiklos Szeredi unsigned int blkbits; 10648373200bSPavel Emelyanov struct fuse_conn *fc = get_fuse_conn(inode); 10658373200bSPavel Emelyanov 10661fb69e78SMiklos Szeredi stat->dev = inode->i_sb->s_dev; 10671fb69e78SMiklos Szeredi stat->ino = attr->ino; 10681fb69e78SMiklos Szeredi stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777); 10691fb69e78SMiklos Szeredi stat->nlink = attr->nlink; 10708cb08329SEric W. Biederman stat->uid = make_kuid(fc->user_ns, attr->uid); 10718cb08329SEric W. Biederman stat->gid = make_kgid(fc->user_ns, attr->gid); 10721fb69e78SMiklos Szeredi stat->rdev = inode->i_rdev; 10731fb69e78SMiklos Szeredi stat->atime.tv_sec = attr->atime; 10741fb69e78SMiklos Szeredi stat->atime.tv_nsec = attr->atimensec; 10751fb69e78SMiklos Szeredi stat->mtime.tv_sec = attr->mtime; 10761fb69e78SMiklos Szeredi stat->mtime.tv_nsec = attr->mtimensec; 10771fb69e78SMiklos Szeredi stat->ctime.tv_sec = attr->ctime; 10781fb69e78SMiklos Szeredi stat->ctime.tv_nsec = attr->ctimensec; 10791fb69e78SMiklos Szeredi stat->size = attr->size; 10801fb69e78SMiklos Szeredi stat->blocks = attr->blocks; 1081203627bbSMiklos Szeredi 1082203627bbSMiklos Szeredi if (attr->blksize != 0) 1083203627bbSMiklos Szeredi blkbits = ilog2(attr->blksize); 1084203627bbSMiklos Szeredi else 1085203627bbSMiklos Szeredi blkbits = inode->i_sb->s_blocksize_bits; 1086203627bbSMiklos Szeredi 1087203627bbSMiklos Szeredi stat->blksize = 1 << blkbits; 10881fb69e78SMiklos Szeredi } 10891fb69e78SMiklos Szeredi 1090c79e322fSMiklos Szeredi static int fuse_do_getattr(struct inode *inode, struct kstat *stat, 1091c79e322fSMiklos Szeredi struct file *file) 1092e5e5558eSMiklos Szeredi { 1093e5e5558eSMiklos Szeredi int err; 1094c79e322fSMiklos Szeredi struct fuse_getattr_in inarg; 1095c79e322fSMiklos Szeredi struct fuse_attr_out outarg; 1096fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(inode); 10977078187aSMiklos Szeredi FUSE_ARGS(args); 10981fb69e78SMiklos Szeredi u64 attr_version; 10991fb69e78SMiklos Szeredi 1100fcee216bSMax Reitz attr_version = fuse_get_attr_version(fm->fc); 11011fb69e78SMiklos Szeredi 1102c79e322fSMiklos Szeredi memset(&inarg, 0, sizeof(inarg)); 11030e9663eeSMiklos Szeredi memset(&outarg, 0, sizeof(outarg)); 1104c79e322fSMiklos Szeredi /* Directories have separate file-handle space */ 1105c79e322fSMiklos Szeredi if (file && S_ISREG(inode->i_mode)) { 1106c79e322fSMiklos Szeredi struct fuse_file *ff = file->private_data; 1107c79e322fSMiklos Szeredi 1108c79e322fSMiklos Szeredi inarg.getattr_flags |= FUSE_GETATTR_FH; 1109c79e322fSMiklos Szeredi inarg.fh = ff->fh; 1110c79e322fSMiklos Szeredi } 1111d5b48543SMiklos Szeredi args.opcode = FUSE_GETATTR; 1112d5b48543SMiklos Szeredi args.nodeid = get_node_id(inode); 1113d5b48543SMiklos Szeredi args.in_numargs = 1; 1114d5b48543SMiklos Szeredi args.in_args[0].size = sizeof(inarg); 1115d5b48543SMiklos Szeredi args.in_args[0].value = &inarg; 1116d5b48543SMiklos Szeredi args.out_numargs = 1; 1117d5b48543SMiklos Szeredi args.out_args[0].size = sizeof(outarg); 1118d5b48543SMiklos Szeredi args.out_args[0].value = &outarg; 1119fcee216bSMax Reitz err = fuse_simple_request(fm, &args); 1120e5e5558eSMiklos Szeredi if (!err) { 1121eb59bd17SMiklos Szeredi if (fuse_invalid_attr(&outarg.attr) || 11226e3e2c43SAl Viro inode_wrong_type(inode, outarg.attr.mode)) { 11235d069dbeSMiklos Szeredi fuse_make_bad(inode); 1124e5e5558eSMiklos Szeredi err = -EIO; 1125e5e5558eSMiklos Szeredi } else { 1126c79e322fSMiklos Szeredi fuse_change_attributes(inode, &outarg.attr, 1127c79e322fSMiklos Szeredi attr_timeout(&outarg), 11281fb69e78SMiklos Szeredi attr_version); 11291fb69e78SMiklos Szeredi if (stat) 1130c79e322fSMiklos Szeredi fuse_fillattr(inode, &outarg.attr, stat); 1131e5e5558eSMiklos Szeredi } 1132e5e5558eSMiklos Szeredi } 1133e5e5558eSMiklos Szeredi return err; 1134e5e5558eSMiklos Szeredi } 1135e5e5558eSMiklos Szeredi 11365b97eeacSMiklos Szeredi static int fuse_update_get_attr(struct inode *inode, struct file *file, 11372f1e8196SMiklos Szeredi struct kstat *stat, u32 request_mask, 11382f1e8196SMiklos Szeredi unsigned int flags) 1139bcb4be80SMiklos Szeredi { 1140bcb4be80SMiklos Szeredi struct fuse_inode *fi = get_fuse_inode(inode); 11415b97eeacSMiklos Szeredi int err = 0; 1142bf5c1898SMiklos Szeredi bool sync; 1143ec855375SMiklos Szeredi u32 inval_mask = READ_ONCE(fi->inval_mask); 1144ec855375SMiklos Szeredi u32 cache_mask = fuse_get_cache_mask(inode); 1145bcb4be80SMiklos Szeredi 1146bf5c1898SMiklos Szeredi if (flags & AT_STATX_FORCE_SYNC) 1147bf5c1898SMiklos Szeredi sync = true; 1148bf5c1898SMiklos Szeredi else if (flags & AT_STATX_DONT_SYNC) 1149bf5c1898SMiklos Szeredi sync = false; 1150ec855375SMiklos Szeredi else if (request_mask & inval_mask & ~cache_mask) 11512f1e8196SMiklos Szeredi sync = true; 1152bf5c1898SMiklos Szeredi else 1153bf5c1898SMiklos Szeredi sync = time_before64(fi->i_time, get_jiffies_64()); 1154bf5c1898SMiklos Szeredi 1155bf5c1898SMiklos Szeredi if (sync) { 115660bcc88aSSeth Forshee forget_all_cached_acls(inode); 1157bcb4be80SMiklos Szeredi err = fuse_do_getattr(inode, stat, file); 11585b97eeacSMiklos Szeredi } else if (stat) { 11590d56a451SChristian Brauner generic_fillattr(&init_user_ns, inode, stat); 1160bcb4be80SMiklos Szeredi stat->mode = fi->orig_i_mode; 116145c72cd7SPavel Shilovsky stat->ino = fi->orig_ino; 1162bcb4be80SMiklos Szeredi } 1163bcb4be80SMiklos Szeredi 1164bcb4be80SMiklos Szeredi return err; 1165bcb4be80SMiklos Szeredi } 1166bcb4be80SMiklos Szeredi 1167c6c745b8SMiklos Szeredi int fuse_update_attributes(struct inode *inode, struct file *file, u32 mask) 11685b97eeacSMiklos Szeredi { 1169c6c745b8SMiklos Szeredi return fuse_update_get_attr(inode, file, NULL, mask, 0); 11705b97eeacSMiklos Szeredi } 11715b97eeacSMiklos Szeredi 1172fcee216bSMax Reitz int fuse_reverse_inval_entry(struct fuse_conn *fc, u64 parent_nodeid, 11734f8d3702SMiklos Szeredi u64 child_nodeid, struct qstr *name, u32 flags) 11743b463ae0SJohn Muir { 11753b463ae0SJohn Muir int err = -ENOTDIR; 11763b463ae0SJohn Muir struct inode *parent; 11773b463ae0SJohn Muir struct dentry *dir; 11783b463ae0SJohn Muir struct dentry *entry; 11793b463ae0SJohn Muir 1180fcee216bSMax Reitz parent = fuse_ilookup(fc, parent_nodeid, NULL); 11813b463ae0SJohn Muir if (!parent) 11823b463ae0SJohn Muir return -ENOENT; 11833b463ae0SJohn Muir 1184bda9a719SMiklos Szeredi inode_lock_nested(parent, I_MUTEX_PARENT); 11853b463ae0SJohn Muir if (!S_ISDIR(parent->i_mode)) 11863b463ae0SJohn Muir goto unlock; 11873b463ae0SJohn Muir 11883b463ae0SJohn Muir err = -ENOENT; 11893b463ae0SJohn Muir dir = d_find_alias(parent); 11903b463ae0SJohn Muir if (!dir) 11913b463ae0SJohn Muir goto unlock; 11923b463ae0SJohn Muir 11938387ff25SLinus Torvalds name->hash = full_name_hash(dir, name->name, name->len); 11943b463ae0SJohn Muir entry = d_lookup(dir, name); 11953b463ae0SJohn Muir dput(dir); 11963b463ae0SJohn Muir if (!entry) 11973b463ae0SJohn Muir goto unlock; 11983b463ae0SJohn Muir 1199261aaba7SMiklos Szeredi fuse_dir_changed(parent); 12004f8d3702SMiklos Szeredi if (!(flags & FUSE_EXPIRE_ONLY)) 12014f8d3702SMiklos Szeredi d_invalidate(entry); 12024f8d3702SMiklos Szeredi fuse_invalidate_entry_cache(entry); 1203451d0f59SJohn Muir 12042b0143b5SDavid Howells if (child_nodeid != 0 && d_really_is_positive(entry)) { 12055955102cSAl Viro inode_lock(d_inode(entry)); 12062b0143b5SDavid Howells if (get_node_id(d_inode(entry)) != child_nodeid) { 1207451d0f59SJohn Muir err = -ENOENT; 1208451d0f59SJohn Muir goto badentry; 1209451d0f59SJohn Muir } 1210451d0f59SJohn Muir if (d_mountpoint(entry)) { 1211451d0f59SJohn Muir err = -EBUSY; 1212451d0f59SJohn Muir goto badentry; 1213451d0f59SJohn Muir } 1214e36cb0b8SDavid Howells if (d_is_dir(entry)) { 1215451d0f59SJohn Muir shrink_dcache_parent(entry); 1216451d0f59SJohn Muir if (!simple_empty(entry)) { 1217451d0f59SJohn Muir err = -ENOTEMPTY; 1218451d0f59SJohn Muir goto badentry; 1219451d0f59SJohn Muir } 12202b0143b5SDavid Howells d_inode(entry)->i_flags |= S_DEAD; 1221451d0f59SJohn Muir } 1222451d0f59SJohn Muir dont_mount(entry); 12232b0143b5SDavid Howells clear_nlink(d_inode(entry)); 12243b463ae0SJohn Muir err = 0; 1225451d0f59SJohn Muir badentry: 12265955102cSAl Viro inode_unlock(d_inode(entry)); 1227451d0f59SJohn Muir if (!err) 1228451d0f59SJohn Muir d_delete(entry); 1229451d0f59SJohn Muir } else { 1230451d0f59SJohn Muir err = 0; 1231451d0f59SJohn Muir } 1232451d0f59SJohn Muir dput(entry); 12333b463ae0SJohn Muir 12343b463ae0SJohn Muir unlock: 12355955102cSAl Viro inode_unlock(parent); 12363b463ae0SJohn Muir iput(parent); 12373b463ae0SJohn Muir return err; 12383b463ae0SJohn Muir } 12393b463ae0SJohn Muir 124087729a55SMiklos Szeredi /* 124187729a55SMiklos Szeredi * Calling into a user-controlled filesystem gives the filesystem 1242c2132c1bSAnatol Pomozov * daemon ptrace-like capabilities over the current process. This 124387729a55SMiklos Szeredi * means, that the filesystem daemon is able to record the exact 124487729a55SMiklos Szeredi * filesystem operations performed, and can also control the behavior 124587729a55SMiklos Szeredi * of the requester process in otherwise impossible ways. For example 124687729a55SMiklos Szeredi * it can delay the operation for arbitrary length of time allowing 124787729a55SMiklos Szeredi * DoS against the requester. 124887729a55SMiklos Szeredi * 124987729a55SMiklos Szeredi * For this reason only those processes can call into the filesystem, 125087729a55SMiklos Szeredi * for which the owner of the mount has ptrace privilege. This 125187729a55SMiklos Szeredi * excludes processes started by other users, suid or sgid processes. 125287729a55SMiklos Szeredi */ 1253c2132c1bSAnatol Pomozov int fuse_allow_current_process(struct fuse_conn *fc) 125487729a55SMiklos Szeredi { 1255c69e8d9cSDavid Howells const struct cred *cred; 1256c69e8d9cSDavid Howells 12579ccf47b2SDave Marchevsky if (allow_sys_admin_access && capable(CAP_SYS_ADMIN)) 12589ccf47b2SDave Marchevsky return 1; 12599ccf47b2SDave Marchevsky 126029433a29SMiklos Szeredi if (fc->allow_other) 126173f03c2bSSeth Forshee return current_in_userns(fc->user_ns); 126287729a55SMiklos Szeredi 1263c2132c1bSAnatol Pomozov cred = current_cred(); 1264499dcf20SEric W. Biederman if (uid_eq(cred->euid, fc->user_id) && 1265499dcf20SEric W. Biederman uid_eq(cred->suid, fc->user_id) && 1266499dcf20SEric W. Biederman uid_eq(cred->uid, fc->user_id) && 1267499dcf20SEric W. Biederman gid_eq(cred->egid, fc->group_id) && 1268499dcf20SEric W. Biederman gid_eq(cred->sgid, fc->group_id) && 1269499dcf20SEric W. Biederman gid_eq(cred->gid, fc->group_id)) 1270c2132c1bSAnatol Pomozov return 1; 127187729a55SMiklos Szeredi 1272c2132c1bSAnatol Pomozov return 0; 127387729a55SMiklos Szeredi } 127487729a55SMiklos Szeredi 127531d40d74SMiklos Szeredi static int fuse_access(struct inode *inode, int mask) 127631d40d74SMiklos Szeredi { 1277fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(inode); 12787078187aSMiklos Szeredi FUSE_ARGS(args); 127931d40d74SMiklos Szeredi struct fuse_access_in inarg; 128031d40d74SMiklos Szeredi int err; 128131d40d74SMiklos Szeredi 1282698fa1d1SMiklos Szeredi BUG_ON(mask & MAY_NOT_BLOCK); 1283698fa1d1SMiklos Szeredi 1284fcee216bSMax Reitz if (fm->fc->no_access) 128531d40d74SMiklos Szeredi return 0; 128631d40d74SMiklos Szeredi 128731d40d74SMiklos Szeredi memset(&inarg, 0, sizeof(inarg)); 1288e6305c43SAl Viro inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC); 1289d5b48543SMiklos Szeredi args.opcode = FUSE_ACCESS; 1290d5b48543SMiklos Szeredi args.nodeid = get_node_id(inode); 1291d5b48543SMiklos Szeredi args.in_numargs = 1; 1292d5b48543SMiklos Szeredi args.in_args[0].size = sizeof(inarg); 1293d5b48543SMiklos Szeredi args.in_args[0].value = &inarg; 1294fcee216bSMax Reitz err = fuse_simple_request(fm, &args); 129531d40d74SMiklos Szeredi if (err == -ENOSYS) { 1296fcee216bSMax Reitz fm->fc->no_access = 1; 129731d40d74SMiklos Szeredi err = 0; 129831d40d74SMiklos Szeredi } 129931d40d74SMiklos Szeredi return err; 130031d40d74SMiklos Szeredi } 130131d40d74SMiklos Szeredi 130210556cb2SAl Viro static int fuse_perm_getattr(struct inode *inode, int mask) 130319690ddbSMiklos Szeredi { 130410556cb2SAl Viro if (mask & MAY_NOT_BLOCK) 130519690ddbSMiklos Szeredi return -ECHILD; 130619690ddbSMiklos Szeredi 130760bcc88aSSeth Forshee forget_all_cached_acls(inode); 130819690ddbSMiklos Szeredi return fuse_do_getattr(inode, NULL, NULL); 130919690ddbSMiklos Szeredi } 131019690ddbSMiklos Szeredi 13116f9f1180SMiklos Szeredi /* 13126f9f1180SMiklos Szeredi * Check permission. The two basic access models of FUSE are: 13136f9f1180SMiklos Szeredi * 13146f9f1180SMiklos Szeredi * 1) Local access checking ('default_permissions' mount option) based 13156f9f1180SMiklos Szeredi * on file mode. This is the plain old disk filesystem permission 13166f9f1180SMiklos Szeredi * modell. 13176f9f1180SMiklos Szeredi * 13186f9f1180SMiklos Szeredi * 2) "Remote" access checking, where server is responsible for 13196f9f1180SMiklos Szeredi * checking permission in each inode operation. An exception to this 13206f9f1180SMiklos Szeredi * is if ->permission() was invoked from sys_access() in which case an 13216f9f1180SMiklos Szeredi * access request is sent. Execute permission is still checked 13226f9f1180SMiklos Szeredi * locally based on file mode. 13236f9f1180SMiklos Szeredi */ 1324549c7297SChristian Brauner static int fuse_permission(struct user_namespace *mnt_userns, 1325549c7297SChristian Brauner struct inode *inode, int mask) 1326e5e5558eSMiklos Szeredi { 1327e5e5558eSMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(inode); 1328244f6385SMiklos Szeredi bool refreshed = false; 1329244f6385SMiklos Szeredi int err = 0; 1330e5e5558eSMiklos Szeredi 13315d069dbeSMiklos Szeredi if (fuse_is_bad(inode)) 13325d069dbeSMiklos Szeredi return -EIO; 13335d069dbeSMiklos Szeredi 1334c2132c1bSAnatol Pomozov if (!fuse_allow_current_process(fc)) 1335e5e5558eSMiklos Szeredi return -EACCES; 1336244f6385SMiklos Szeredi 1337244f6385SMiklos Szeredi /* 1338e8e96157SMiklos Szeredi * If attributes are needed, refresh them before proceeding 1339244f6385SMiklos Szeredi */ 134029433a29SMiklos Szeredi if (fc->default_permissions || 1341e8e96157SMiklos Szeredi ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) { 134219690ddbSMiklos Szeredi struct fuse_inode *fi = get_fuse_inode(inode); 1343d233c7ddSMiklos Szeredi u32 perm_mask = STATX_MODE | STATX_UID | STATX_GID; 134419690ddbSMiklos Szeredi 1345d233c7ddSMiklos Szeredi if (perm_mask & READ_ONCE(fi->inval_mask) || 1346d233c7ddSMiklos Szeredi time_before64(fi->i_time, get_jiffies_64())) { 134719690ddbSMiklos Szeredi refreshed = true; 134819690ddbSMiklos Szeredi 134910556cb2SAl Viro err = fuse_perm_getattr(inode, mask); 1350244f6385SMiklos Szeredi if (err) 1351244f6385SMiklos Szeredi return err; 13521fb69e78SMiklos Szeredi } 135319690ddbSMiklos Szeredi } 1354244f6385SMiklos Szeredi 135529433a29SMiklos Szeredi if (fc->default_permissions) { 135647291baaSChristian Brauner err = generic_permission(&init_user_ns, inode, mask); 13571e9a4ed9SMiklos Szeredi 13581e9a4ed9SMiklos Szeredi /* If permission is denied, try to refresh file 13591e9a4ed9SMiklos Szeredi attributes. This is also needed, because the root 13601e9a4ed9SMiklos Szeredi node will at first have no permissions */ 1361244f6385SMiklos Szeredi if (err == -EACCES && !refreshed) { 136210556cb2SAl Viro err = fuse_perm_getattr(inode, mask); 13631e9a4ed9SMiklos Szeredi if (!err) 136447291baaSChristian Brauner err = generic_permission(&init_user_ns, 136547291baaSChristian Brauner inode, mask); 13661e9a4ed9SMiklos Szeredi } 13671e9a4ed9SMiklos Szeredi 13686f9f1180SMiklos Szeredi /* Note: the opposite of the above test does not 13696f9f1180SMiklos Szeredi exist. So if permissions are revoked this won't be 13706f9f1180SMiklos Szeredi noticed immediately, only after the attribute 13716f9f1180SMiklos Szeredi timeout has expired */ 13729cfcac81SEric Paris } else if (mask & (MAY_ACCESS | MAY_CHDIR)) { 1373e8e96157SMiklos Szeredi err = fuse_access(inode, mask); 1374e8e96157SMiklos Szeredi } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { 1375e8e96157SMiklos Szeredi if (!(inode->i_mode & S_IXUGO)) { 1376e8e96157SMiklos Szeredi if (refreshed) 1377e5e5558eSMiklos Szeredi return -EACCES; 137831d40d74SMiklos Szeredi 137910556cb2SAl Viro err = fuse_perm_getattr(inode, mask); 1380e8e96157SMiklos Szeredi if (!err && !(inode->i_mode & S_IXUGO)) 1381e8e96157SMiklos Szeredi return -EACCES; 1382e8e96157SMiklos Szeredi } 1383e5e5558eSMiklos Szeredi } 1384244f6385SMiklos Szeredi return err; 1385e5e5558eSMiklos Szeredi } 1386e5e5558eSMiklos Szeredi 13875571f1e6SDan Schatzberg static int fuse_readlink_page(struct inode *inode, struct page *page) 1388e5e5558eSMiklos Szeredi { 1389fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(inode); 13904c29afecSMiklos Szeredi struct fuse_page_desc desc = { .length = PAGE_SIZE - 1 }; 13914c29afecSMiklos Szeredi struct fuse_args_pages ap = { 13924c29afecSMiklos Szeredi .num_pages = 1, 13934c29afecSMiklos Szeredi .pages = &page, 13944c29afecSMiklos Szeredi .descs = &desc, 13954c29afecSMiklos Szeredi }; 13964c29afecSMiklos Szeredi char *link; 13974c29afecSMiklos Szeredi ssize_t res; 1398e5e5558eSMiklos Szeredi 13994c29afecSMiklos Szeredi ap.args.opcode = FUSE_READLINK; 14004c29afecSMiklos Szeredi ap.args.nodeid = get_node_id(inode); 14014c29afecSMiklos Szeredi ap.args.out_pages = true; 14024c29afecSMiklos Szeredi ap.args.out_argvar = true; 14034c29afecSMiklos Szeredi ap.args.page_zeroing = true; 14044c29afecSMiklos Szeredi ap.args.out_numargs = 1; 14054c29afecSMiklos Szeredi ap.args.out_args[0].size = desc.length; 1406fcee216bSMax Reitz res = fuse_simple_request(fm, &ap.args); 14076b255391SAl Viro 1408451418fcSAndrew Gallagher fuse_invalidate_atime(inode); 14095571f1e6SDan Schatzberg 14104c29afecSMiklos Szeredi if (res < 0) 14114c29afecSMiklos Szeredi return res; 14124c29afecSMiklos Szeredi 14134c29afecSMiklos Szeredi if (WARN_ON(res >= PAGE_SIZE)) 14144c29afecSMiklos Szeredi return -EIO; 14154c29afecSMiklos Szeredi 14164c29afecSMiklos Szeredi link = page_address(page); 14174c29afecSMiklos Szeredi link[res] = '\0'; 14184c29afecSMiklos Szeredi 14194c29afecSMiklos Szeredi return 0; 14205571f1e6SDan Schatzberg } 14215571f1e6SDan Schatzberg 14225571f1e6SDan Schatzberg static const char *fuse_get_link(struct dentry *dentry, struct inode *inode, 14235571f1e6SDan Schatzberg struct delayed_call *callback) 14245571f1e6SDan Schatzberg { 14255571f1e6SDan Schatzberg struct fuse_conn *fc = get_fuse_conn(inode); 14265571f1e6SDan Schatzberg struct page *page; 14275571f1e6SDan Schatzberg int err; 14285571f1e6SDan Schatzberg 14295571f1e6SDan Schatzberg err = -EIO; 14305d069dbeSMiklos Szeredi if (fuse_is_bad(inode)) 14315571f1e6SDan Schatzberg goto out_err; 14325571f1e6SDan Schatzberg 14335571f1e6SDan Schatzberg if (fc->cache_symlinks) 14345571f1e6SDan Schatzberg return page_get_link(dentry, inode, callback); 14355571f1e6SDan Schatzberg 14365571f1e6SDan Schatzberg err = -ECHILD; 14375571f1e6SDan Schatzberg if (!dentry) 14385571f1e6SDan Schatzberg goto out_err; 14395571f1e6SDan Schatzberg 14405571f1e6SDan Schatzberg page = alloc_page(GFP_KERNEL); 14415571f1e6SDan Schatzberg err = -ENOMEM; 14425571f1e6SDan Schatzberg if (!page) 14435571f1e6SDan Schatzberg goto out_err; 14445571f1e6SDan Schatzberg 14455571f1e6SDan Schatzberg err = fuse_readlink_page(inode, page); 14465571f1e6SDan Schatzberg if (err) { 14475571f1e6SDan Schatzberg __free_page(page); 14485571f1e6SDan Schatzberg goto out_err; 14495571f1e6SDan Schatzberg } 14505571f1e6SDan Schatzberg 14515571f1e6SDan Schatzberg set_delayed_call(callback, page_put_link, page); 14525571f1e6SDan Schatzberg 14535571f1e6SDan Schatzberg return page_address(page); 14545571f1e6SDan Schatzberg 14555571f1e6SDan Schatzberg out_err: 14565571f1e6SDan Schatzberg return ERR_PTR(err); 1457e5e5558eSMiklos Szeredi } 1458e5e5558eSMiklos Szeredi 1459e5e5558eSMiklos Szeredi static int fuse_dir_open(struct inode *inode, struct file *file) 1460e5e5558eSMiklos Szeredi { 146191fe96b4SMiklos Szeredi return fuse_open_common(inode, file, true); 1462e5e5558eSMiklos Szeredi } 1463e5e5558eSMiklos Szeredi 1464e5e5558eSMiklos Szeredi static int fuse_dir_release(struct inode *inode, struct file *file) 1465e5e5558eSMiklos Szeredi { 14662e64ff15SChad Austin fuse_release_common(file, true); 14678b0797a4SMiklos Szeredi 14688b0797a4SMiklos Szeredi return 0; 1469e5e5558eSMiklos Szeredi } 1470e5e5558eSMiklos Szeredi 147102c24a82SJosef Bacik static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end, 147202c24a82SJosef Bacik int datasync) 147382547981SMiklos Szeredi { 1474a9c2d1e8SMiklos Szeredi struct inode *inode = file->f_mapping->host; 1475a9c2d1e8SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(inode); 1476a9c2d1e8SMiklos Szeredi int err; 1477a9c2d1e8SMiklos Szeredi 14785d069dbeSMiklos Szeredi if (fuse_is_bad(inode)) 1479a9c2d1e8SMiklos Szeredi return -EIO; 1480a9c2d1e8SMiklos Szeredi 1481a9c2d1e8SMiklos Szeredi if (fc->no_fsyncdir) 1482a9c2d1e8SMiklos Szeredi return 0; 1483a9c2d1e8SMiklos Szeredi 1484a9c2d1e8SMiklos Szeredi inode_lock(inode); 1485a9c2d1e8SMiklos Szeredi err = fuse_fsync_common(file, start, end, datasync, FUSE_FSYNCDIR); 1486a9c2d1e8SMiklos Szeredi if (err == -ENOSYS) { 1487a9c2d1e8SMiklos Szeredi fc->no_fsyncdir = 1; 1488a9c2d1e8SMiklos Szeredi err = 0; 1489a9c2d1e8SMiklos Szeredi } 1490a9c2d1e8SMiklos Szeredi inode_unlock(inode); 1491a9c2d1e8SMiklos Szeredi 1492a9c2d1e8SMiklos Szeredi return err; 149382547981SMiklos Szeredi } 149482547981SMiklos Szeredi 1495b18da0c5SMiklos Szeredi static long fuse_dir_ioctl(struct file *file, unsigned int cmd, 1496b18da0c5SMiklos Szeredi unsigned long arg) 1497b18da0c5SMiklos Szeredi { 1498b18da0c5SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host); 1499b18da0c5SMiklos Szeredi 1500b18da0c5SMiklos Szeredi /* FUSE_IOCTL_DIR only supported for API version >= 7.18 */ 1501b18da0c5SMiklos Szeredi if (fc->minor < 18) 1502b18da0c5SMiklos Szeredi return -ENOTTY; 1503b18da0c5SMiklos Szeredi 1504b18da0c5SMiklos Szeredi return fuse_ioctl_common(file, cmd, arg, FUSE_IOCTL_DIR); 1505b18da0c5SMiklos Szeredi } 1506b18da0c5SMiklos Szeredi 1507b18da0c5SMiklos Szeredi static long fuse_dir_compat_ioctl(struct file *file, unsigned int cmd, 1508b18da0c5SMiklos Szeredi unsigned long arg) 1509b18da0c5SMiklos Szeredi { 1510b18da0c5SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host); 1511b18da0c5SMiklos Szeredi 1512b18da0c5SMiklos Szeredi if (fc->minor < 18) 1513b18da0c5SMiklos Szeredi return -ENOTTY; 1514b18da0c5SMiklos Szeredi 1515b18da0c5SMiklos Szeredi return fuse_ioctl_common(file, cmd, arg, 1516b18da0c5SMiklos Szeredi FUSE_IOCTL_COMPAT | FUSE_IOCTL_DIR); 1517b18da0c5SMiklos Szeredi } 1518b18da0c5SMiklos Szeredi 1519b0aa7606SMaxim Patlasov static bool update_mtime(unsigned ivalid, bool trust_local_mtime) 152017637cbaSMiklos Szeredi { 152117637cbaSMiklos Szeredi /* Always update if mtime is explicitly set */ 152217637cbaSMiklos Szeredi if (ivalid & ATTR_MTIME_SET) 152317637cbaSMiklos Szeredi return true; 152417637cbaSMiklos Szeredi 1525b0aa7606SMaxim Patlasov /* Or if kernel i_mtime is the official one */ 1526b0aa7606SMaxim Patlasov if (trust_local_mtime) 1527b0aa7606SMaxim Patlasov return true; 1528b0aa7606SMaxim Patlasov 152917637cbaSMiklos Szeredi /* If it's an open(O_TRUNC) or an ftruncate(), don't update */ 153017637cbaSMiklos Szeredi if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE))) 153117637cbaSMiklos Szeredi return false; 153217637cbaSMiklos Szeredi 153317637cbaSMiklos Szeredi /* In all other cases update */ 153417637cbaSMiklos Szeredi return true; 153517637cbaSMiklos Szeredi } 153617637cbaSMiklos Szeredi 15378cb08329SEric W. Biederman static void iattr_to_fattr(struct fuse_conn *fc, struct iattr *iattr, 15388cb08329SEric W. Biederman struct fuse_setattr_in *arg, bool trust_local_cmtime) 15399e6268dbSMiklos Szeredi { 15409e6268dbSMiklos Szeredi unsigned ivalid = iattr->ia_valid; 15419e6268dbSMiklos Szeredi 15429e6268dbSMiklos Szeredi if (ivalid & ATTR_MODE) 1543befc649cSMiklos Szeredi arg->valid |= FATTR_MODE, arg->mode = iattr->ia_mode; 15449e6268dbSMiklos Szeredi if (ivalid & ATTR_UID) 15458cb08329SEric W. Biederman arg->valid |= FATTR_UID, arg->uid = from_kuid(fc->user_ns, iattr->ia_uid); 15469e6268dbSMiklos Szeredi if (ivalid & ATTR_GID) 15478cb08329SEric W. Biederman arg->valid |= FATTR_GID, arg->gid = from_kgid(fc->user_ns, iattr->ia_gid); 15489e6268dbSMiklos Szeredi if (ivalid & ATTR_SIZE) 1549befc649cSMiklos Szeredi arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size; 155017637cbaSMiklos Szeredi if (ivalid & ATTR_ATIME) { 155117637cbaSMiklos Szeredi arg->valid |= FATTR_ATIME; 1552befc649cSMiklos Szeredi arg->atime = iattr->ia_atime.tv_sec; 155317637cbaSMiklos Szeredi arg->atimensec = iattr->ia_atime.tv_nsec; 155417637cbaSMiklos Szeredi if (!(ivalid & ATTR_ATIME_SET)) 155517637cbaSMiklos Szeredi arg->valid |= FATTR_ATIME_NOW; 155617637cbaSMiklos Szeredi } 15573ad22c62SMaxim Patlasov if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, trust_local_cmtime)) { 155817637cbaSMiklos Szeredi arg->valid |= FATTR_MTIME; 1559befc649cSMiklos Szeredi arg->mtime = iattr->ia_mtime.tv_sec; 156017637cbaSMiklos Szeredi arg->mtimensec = iattr->ia_mtime.tv_nsec; 15613ad22c62SMaxim Patlasov if (!(ivalid & ATTR_MTIME_SET) && !trust_local_cmtime) 156217637cbaSMiklos Szeredi arg->valid |= FATTR_MTIME_NOW; 15639e6268dbSMiklos Szeredi } 15643ad22c62SMaxim Patlasov if ((ivalid & ATTR_CTIME) && trust_local_cmtime) { 15653ad22c62SMaxim Patlasov arg->valid |= FATTR_CTIME; 15663ad22c62SMaxim Patlasov arg->ctime = iattr->ia_ctime.tv_sec; 15673ad22c62SMaxim Patlasov arg->ctimensec = iattr->ia_ctime.tv_nsec; 15683ad22c62SMaxim Patlasov } 15699e6268dbSMiklos Szeredi } 15709e6268dbSMiklos Szeredi 15716f9f1180SMiklos Szeredi /* 15723be5a52bSMiklos Szeredi * Prevent concurrent writepages on inode 15733be5a52bSMiklos Szeredi * 15743be5a52bSMiklos Szeredi * This is done by adding a negative bias to the inode write counter 15753be5a52bSMiklos Szeredi * and waiting for all pending writes to finish. 15763be5a52bSMiklos Szeredi */ 15773be5a52bSMiklos Szeredi void fuse_set_nowrite(struct inode *inode) 15783be5a52bSMiklos Szeredi { 15793be5a52bSMiklos Szeredi struct fuse_inode *fi = get_fuse_inode(inode); 15803be5a52bSMiklos Szeredi 15815955102cSAl Viro BUG_ON(!inode_is_locked(inode)); 15823be5a52bSMiklos Szeredi 1583f15ecfefSKirill Tkhai spin_lock(&fi->lock); 15843be5a52bSMiklos Szeredi BUG_ON(fi->writectr < 0); 15853be5a52bSMiklos Szeredi fi->writectr += FUSE_NOWRITE; 1586f15ecfefSKirill Tkhai spin_unlock(&fi->lock); 15873be5a52bSMiklos Szeredi wait_event(fi->page_waitq, fi->writectr == FUSE_NOWRITE); 15883be5a52bSMiklos Szeredi } 15893be5a52bSMiklos Szeredi 15903be5a52bSMiklos Szeredi /* 15913be5a52bSMiklos Szeredi * Allow writepages on inode 15923be5a52bSMiklos Szeredi * 15933be5a52bSMiklos Szeredi * Remove the bias from the writecounter and send any queued 15943be5a52bSMiklos Szeredi * writepages. 15953be5a52bSMiklos Szeredi */ 15963be5a52bSMiklos Szeredi static void __fuse_release_nowrite(struct inode *inode) 15973be5a52bSMiklos Szeredi { 15983be5a52bSMiklos Szeredi struct fuse_inode *fi = get_fuse_inode(inode); 15993be5a52bSMiklos Szeredi 16003be5a52bSMiklos Szeredi BUG_ON(fi->writectr != FUSE_NOWRITE); 16013be5a52bSMiklos Szeredi fi->writectr = 0; 16023be5a52bSMiklos Szeredi fuse_flush_writepages(inode); 16033be5a52bSMiklos Szeredi } 16043be5a52bSMiklos Szeredi 16053be5a52bSMiklos Szeredi void fuse_release_nowrite(struct inode *inode) 16063be5a52bSMiklos Szeredi { 1607f15ecfefSKirill Tkhai struct fuse_inode *fi = get_fuse_inode(inode); 16083be5a52bSMiklos Szeredi 1609f15ecfefSKirill Tkhai spin_lock(&fi->lock); 16103be5a52bSMiklos Szeredi __fuse_release_nowrite(inode); 1611f15ecfefSKirill Tkhai spin_unlock(&fi->lock); 16123be5a52bSMiklos Szeredi } 16133be5a52bSMiklos Szeredi 16147078187aSMiklos Szeredi static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_args *args, 1615b0aa7606SMaxim Patlasov struct inode *inode, 1616b0aa7606SMaxim Patlasov struct fuse_setattr_in *inarg_p, 1617b0aa7606SMaxim Patlasov struct fuse_attr_out *outarg_p) 1618b0aa7606SMaxim Patlasov { 1619d5b48543SMiklos Szeredi args->opcode = FUSE_SETATTR; 1620d5b48543SMiklos Szeredi args->nodeid = get_node_id(inode); 1621d5b48543SMiklos Szeredi args->in_numargs = 1; 1622d5b48543SMiklos Szeredi args->in_args[0].size = sizeof(*inarg_p); 1623d5b48543SMiklos Szeredi args->in_args[0].value = inarg_p; 1624d5b48543SMiklos Szeredi args->out_numargs = 1; 1625d5b48543SMiklos Szeredi args->out_args[0].size = sizeof(*outarg_p); 1626d5b48543SMiklos Szeredi args->out_args[0].value = outarg_p; 1627b0aa7606SMaxim Patlasov } 1628b0aa7606SMaxim Patlasov 1629b0aa7606SMaxim Patlasov /* 1630b0aa7606SMaxim Patlasov * Flush inode->i_mtime to the server 1631b0aa7606SMaxim Patlasov */ 1632ab9e13f7SMaxim Patlasov int fuse_flush_times(struct inode *inode, struct fuse_file *ff) 1633b0aa7606SMaxim Patlasov { 1634fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(inode); 16357078187aSMiklos Szeredi FUSE_ARGS(args); 1636b0aa7606SMaxim Patlasov struct fuse_setattr_in inarg; 1637b0aa7606SMaxim Patlasov struct fuse_attr_out outarg; 1638b0aa7606SMaxim Patlasov 1639b0aa7606SMaxim Patlasov memset(&inarg, 0, sizeof(inarg)); 1640b0aa7606SMaxim Patlasov memset(&outarg, 0, sizeof(outarg)); 1641b0aa7606SMaxim Patlasov 1642ab9e13f7SMaxim Patlasov inarg.valid = FATTR_MTIME; 1643b0aa7606SMaxim Patlasov inarg.mtime = inode->i_mtime.tv_sec; 1644b0aa7606SMaxim Patlasov inarg.mtimensec = inode->i_mtime.tv_nsec; 1645fcee216bSMax Reitz if (fm->fc->minor >= 23) { 1646ab9e13f7SMaxim Patlasov inarg.valid |= FATTR_CTIME; 1647ab9e13f7SMaxim Patlasov inarg.ctime = inode->i_ctime.tv_sec; 1648ab9e13f7SMaxim Patlasov inarg.ctimensec = inode->i_ctime.tv_nsec; 1649ab9e13f7SMaxim Patlasov } 16501e18bda8SMiklos Szeredi if (ff) { 16511e18bda8SMiklos Szeredi inarg.valid |= FATTR_FH; 16521e18bda8SMiklos Szeredi inarg.fh = ff->fh; 16531e18bda8SMiklos Szeredi } 1654fcee216bSMax Reitz fuse_setattr_fill(fm->fc, &args, inode, &inarg, &outarg); 1655b0aa7606SMaxim Patlasov 1656fcee216bSMax Reitz return fuse_simple_request(fm, &args); 1657b0aa7606SMaxim Patlasov } 1658b0aa7606SMaxim Patlasov 16593be5a52bSMiklos Szeredi /* 16606f9f1180SMiklos Szeredi * Set attributes, and at the same time refresh them. 16616f9f1180SMiklos Szeredi * 16626f9f1180SMiklos Szeredi * Truncation is slightly complicated, because the 'truncate' request 16636f9f1180SMiklos Szeredi * may fail, in which case we don't want to touch the mapping. 16649ffbb916SMiklos Szeredi * vmtruncate() doesn't allow for this case, so do the rlimit checking 16659ffbb916SMiklos Szeredi * and the actual truncation by hand. 16666f9f1180SMiklos Szeredi */ 166762490330SJan Kara int fuse_do_setattr(struct dentry *dentry, struct iattr *attr, 166849d4914fSMiklos Szeredi struct file *file) 16699e6268dbSMiklos Szeredi { 167062490330SJan Kara struct inode *inode = d_inode(dentry); 1671fcee216bSMax Reitz struct fuse_mount *fm = get_fuse_mount(inode); 1672fcee216bSMax Reitz struct fuse_conn *fc = fm->fc; 167306a7c3c2SMaxim Patlasov struct fuse_inode *fi = get_fuse_inode(inode); 16748bcbbe9cSJan Kara struct address_space *mapping = inode->i_mapping; 16757078187aSMiklos Szeredi FUSE_ARGS(args); 16769e6268dbSMiklos Szeredi struct fuse_setattr_in inarg; 16779e6268dbSMiklos Szeredi struct fuse_attr_out outarg; 16783be5a52bSMiklos Szeredi bool is_truncate = false; 1679c15016b7SMiklos Szeredi bool is_wb = fc->writeback_cache && S_ISREG(inode->i_mode); 16803be5a52bSMiklos Szeredi loff_t oldsize; 16819e6268dbSMiklos Szeredi int err; 1682c15016b7SMiklos Szeredi bool trust_local_cmtime = is_wb; 16836ae330caSVivek Goyal bool fault_blocked = false; 16849e6268dbSMiklos Szeredi 168529433a29SMiklos Szeredi if (!fc->default_permissions) 1686db78b877SChristoph Hellwig attr->ia_valid |= ATTR_FORCE; 1687db78b877SChristoph Hellwig 16882f221d6fSChristian Brauner err = setattr_prepare(&init_user_ns, dentry, attr); 16891e9a4ed9SMiklos Szeredi if (err) 16901e9a4ed9SMiklos Szeredi return err; 16911e9a4ed9SMiklos Szeredi 16926ae330caSVivek Goyal if (attr->ia_valid & ATTR_SIZE) { 16936ae330caSVivek Goyal if (WARN_ON(!S_ISREG(inode->i_mode))) 16946ae330caSVivek Goyal return -EIO; 16956ae330caSVivek Goyal is_truncate = true; 16966ae330caSVivek Goyal } 16976ae330caSVivek Goyal 16986ae330caSVivek Goyal if (FUSE_IS_DAX(inode) && is_truncate) { 16998bcbbe9cSJan Kara filemap_invalidate_lock(mapping); 17006ae330caSVivek Goyal fault_blocked = true; 17016ae330caSVivek Goyal err = fuse_dax_break_layouts(inode, 0, 0); 17026ae330caSVivek Goyal if (err) { 17038bcbbe9cSJan Kara filemap_invalidate_unlock(mapping); 17046ae330caSVivek Goyal return err; 17056ae330caSVivek Goyal } 17066ae330caSVivek Goyal } 17076ae330caSVivek Goyal 17088d56adddSMiklos Szeredi if (attr->ia_valid & ATTR_OPEN) { 1709df0e91d4SMiklos Szeredi /* This is coming from open(..., ... | O_TRUNC); */ 1710df0e91d4SMiklos Szeredi WARN_ON(!(attr->ia_valid & ATTR_SIZE)); 1711df0e91d4SMiklos Szeredi WARN_ON(attr->ia_size != 0); 1712df0e91d4SMiklos Szeredi if (fc->atomic_o_trunc) { 1713df0e91d4SMiklos Szeredi /* 1714df0e91d4SMiklos Szeredi * No need to send request to userspace, since actual 1715df0e91d4SMiklos Szeredi * truncation has already been done by OPEN. But still 1716df0e91d4SMiklos Szeredi * need to truncate page cache. 1717df0e91d4SMiklos Szeredi */ 1718df0e91d4SMiklos Szeredi i_size_write(inode, 0); 1719df0e91d4SMiklos Szeredi truncate_pagecache(inode, 0); 17206ae330caSVivek Goyal goto out; 1721df0e91d4SMiklos Szeredi } 17228d56adddSMiklos Szeredi file = NULL; 17238d56adddSMiklos Szeredi } 17246ff958edSMiklos Szeredi 1725b24e7598SMiklos Szeredi /* Flush dirty data/metadata before non-truncate SETATTR */ 1726c15016b7SMiklos Szeredi if (is_wb && 1727b24e7598SMiklos Szeredi attr->ia_valid & 1728b24e7598SMiklos Szeredi (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_MTIME_SET | 1729b24e7598SMiklos Szeredi ATTR_TIMES_SET)) { 1730b24e7598SMiklos Szeredi err = write_inode_now(inode, true); 1731b24e7598SMiklos Szeredi if (err) 1732b24e7598SMiklos Szeredi return err; 1733b24e7598SMiklos Szeredi 1734b24e7598SMiklos Szeredi fuse_set_nowrite(inode); 1735b24e7598SMiklos Szeredi fuse_release_nowrite(inode); 1736b24e7598SMiklos Szeredi } 1737b24e7598SMiklos Szeredi 173806a7c3c2SMaxim Patlasov if (is_truncate) { 17393be5a52bSMiklos Szeredi fuse_set_nowrite(inode); 174006a7c3c2SMaxim Patlasov set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); 17413ad22c62SMaxim Patlasov if (trust_local_cmtime && attr->ia_size != inode->i_size) 17423ad22c62SMaxim Patlasov attr->ia_valid |= ATTR_MTIME | ATTR_CTIME; 174306a7c3c2SMaxim Patlasov } 17443be5a52bSMiklos Szeredi 17459e6268dbSMiklos Szeredi memset(&inarg, 0, sizeof(inarg)); 17460e9663eeSMiklos Szeredi memset(&outarg, 0, sizeof(outarg)); 17478cb08329SEric W. Biederman iattr_to_fattr(fc, attr, &inarg, trust_local_cmtime); 174849d4914fSMiklos Szeredi if (file) { 174949d4914fSMiklos Szeredi struct fuse_file *ff = file->private_data; 175049d4914fSMiklos Szeredi inarg.valid |= FATTR_FH; 175149d4914fSMiklos Szeredi inarg.fh = ff->fh; 175249d4914fSMiklos Szeredi } 175331792161SVivek Goyal 175431792161SVivek Goyal /* Kill suid/sgid for non-directory chown unconditionally */ 175531792161SVivek Goyal if (fc->handle_killpriv_v2 && !S_ISDIR(inode->i_mode) && 175631792161SVivek Goyal attr->ia_valid & (ATTR_UID | ATTR_GID)) 175731792161SVivek Goyal inarg.valid |= FATTR_KILL_SUIDGID; 175831792161SVivek Goyal 1759f3332114SMiklos Szeredi if (attr->ia_valid & ATTR_SIZE) { 1760f3332114SMiklos Szeredi /* For mandatory locking in truncate */ 1761f3332114SMiklos Szeredi inarg.valid |= FATTR_LOCKOWNER; 1762f3332114SMiklos Szeredi inarg.lock_owner = fuse_lock_owner_id(fc, current->files); 176331792161SVivek Goyal 176431792161SVivek Goyal /* Kill suid/sgid for truncate only if no CAP_FSETID */ 176531792161SVivek Goyal if (fc->handle_killpriv_v2 && !capable(CAP_FSETID)) 176631792161SVivek Goyal inarg.valid |= FATTR_KILL_SUIDGID; 1767f3332114SMiklos Szeredi } 17687078187aSMiklos Szeredi fuse_setattr_fill(fc, &args, inode, &inarg, &outarg); 1769fcee216bSMax Reitz err = fuse_simple_request(fm, &args); 1770e00d2c2dSMiklos Szeredi if (err) { 1771e00d2c2dSMiklos Szeredi if (err == -EINTR) 1772e00d2c2dSMiklos Szeredi fuse_invalidate_attr(inode); 17733be5a52bSMiklos Szeredi goto error; 1774e00d2c2dSMiklos Szeredi } 1775e00d2c2dSMiklos Szeredi 1776eb59bd17SMiklos Szeredi if (fuse_invalid_attr(&outarg.attr) || 17776e3e2c43SAl Viro inode_wrong_type(inode, outarg.attr.mode)) { 17785d069dbeSMiklos Szeredi fuse_make_bad(inode); 17793be5a52bSMiklos Szeredi err = -EIO; 17803be5a52bSMiklos Szeredi goto error; 17819e6268dbSMiklos Szeredi } 17829e6268dbSMiklos Szeredi 1783f15ecfefSKirill Tkhai spin_lock(&fi->lock); 1784b0aa7606SMaxim Patlasov /* the kernel maintains i_mtime locally */ 17853ad22c62SMaxim Patlasov if (trust_local_cmtime) { 17863ad22c62SMaxim Patlasov if (attr->ia_valid & ATTR_MTIME) 1787b0aa7606SMaxim Patlasov inode->i_mtime = attr->ia_mtime; 17883ad22c62SMaxim Patlasov if (attr->ia_valid & ATTR_CTIME) 17893ad22c62SMaxim Patlasov inode->i_ctime = attr->ia_ctime; 17901e18bda8SMiklos Szeredi /* FIXME: clear I_DIRTY_SYNC? */ 1791b0aa7606SMaxim Patlasov } 1792b0aa7606SMaxim Patlasov 17933be5a52bSMiklos Szeredi fuse_change_attributes_common(inode, &outarg.attr, 17944b52f059SMiklos Szeredi attr_timeout(&outarg), 17954b52f059SMiklos Szeredi fuse_get_cache_mask(inode)); 17963be5a52bSMiklos Szeredi oldsize = inode->i_size; 17978373200bSPavel Emelyanov /* see the comment in fuse_change_attributes() */ 1798c15016b7SMiklos Szeredi if (!is_wb || is_truncate) 17993be5a52bSMiklos Szeredi i_size_write(inode, outarg.attr.size); 18003be5a52bSMiklos Szeredi 18013be5a52bSMiklos Szeredi if (is_truncate) { 1802f15ecfefSKirill Tkhai /* NOTE: this may release/reacquire fi->lock */ 18033be5a52bSMiklos Szeredi __fuse_release_nowrite(inode); 18043be5a52bSMiklos Szeredi } 1805f15ecfefSKirill Tkhai spin_unlock(&fi->lock); 18063be5a52bSMiklos Szeredi 18073be5a52bSMiklos Szeredi /* 18083be5a52bSMiklos Szeredi * Only call invalidate_inode_pages2() after removing 18092bf06b8eSMatthew Wilcox (Oracle) * FUSE_NOWRITE, otherwise fuse_launder_folio() would deadlock. 18103be5a52bSMiklos Szeredi */ 18118373200bSPavel Emelyanov if ((is_truncate || !is_wb) && 18128373200bSPavel Emelyanov S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) { 18137caef267SKirill A. Shutemov truncate_pagecache(inode, outarg.attr.size); 18148bcbbe9cSJan Kara invalidate_inode_pages2(mapping); 18153be5a52bSMiklos Szeredi } 18163be5a52bSMiklos Szeredi 181706a7c3c2SMaxim Patlasov clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); 18186ae330caSVivek Goyal out: 18196ae330caSVivek Goyal if (fault_blocked) 18208bcbbe9cSJan Kara filemap_invalidate_unlock(mapping); 18216ae330caSVivek Goyal 1822e00d2c2dSMiklos Szeredi return 0; 18233be5a52bSMiklos Szeredi 18243be5a52bSMiklos Szeredi error: 18253be5a52bSMiklos Szeredi if (is_truncate) 18263be5a52bSMiklos Szeredi fuse_release_nowrite(inode); 18273be5a52bSMiklos Szeredi 182806a7c3c2SMaxim Patlasov clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); 18296ae330caSVivek Goyal 18306ae330caSVivek Goyal if (fault_blocked) 18318bcbbe9cSJan Kara filemap_invalidate_unlock(mapping); 18323be5a52bSMiklos Szeredi return err; 18339e6268dbSMiklos Szeredi } 18349e6268dbSMiklos Szeredi 1835549c7297SChristian Brauner static int fuse_setattr(struct user_namespace *mnt_userns, struct dentry *entry, 1836549c7297SChristian Brauner struct iattr *attr) 183749d4914fSMiklos Szeredi { 18382b0143b5SDavid Howells struct inode *inode = d_inode(entry); 18395e940c1dSMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(inode); 1840a09f99edSMiklos Szeredi struct file *file = (attr->ia_valid & ATTR_FILE) ? attr->ia_file : NULL; 18415e2b8828SMiklos Szeredi int ret; 1842efb9fa9eSMaxim Patlasov 18435d069dbeSMiklos Szeredi if (fuse_is_bad(inode)) 18445d069dbeSMiklos Szeredi return -EIO; 18455d069dbeSMiklos Szeredi 1846efb9fa9eSMaxim Patlasov if (!fuse_allow_current_process(get_fuse_conn(inode))) 1847efb9fa9eSMaxim Patlasov return -EACCES; 1848efb9fa9eSMaxim Patlasov 1849a09f99edSMiklos Szeredi if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) { 1850a09f99edSMiklos Szeredi attr->ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID | 1851a09f99edSMiklos Szeredi ATTR_MODE); 18525e940c1dSMiklos Szeredi 1853a09f99edSMiklos Szeredi /* 18545e940c1dSMiklos Szeredi * The only sane way to reliably kill suid/sgid is to do it in 18555e940c1dSMiklos Szeredi * the userspace filesystem 18565e940c1dSMiklos Szeredi * 18575e940c1dSMiklos Szeredi * This should be done on write(), truncate() and chown(). 18585e940c1dSMiklos Szeredi */ 18598981bdfdSVivek Goyal if (!fc->handle_killpriv && !fc->handle_killpriv_v2) { 18605e940c1dSMiklos Szeredi /* 18615e940c1dSMiklos Szeredi * ia_mode calculation may have used stale i_mode. 18625e940c1dSMiklos Szeredi * Refresh and recalculate. 1863a09f99edSMiklos Szeredi */ 1864a09f99edSMiklos Szeredi ret = fuse_do_getattr(inode, NULL, file); 1865a09f99edSMiklos Szeredi if (ret) 1866a09f99edSMiklos Szeredi return ret; 1867a09f99edSMiklos Szeredi 1868a09f99edSMiklos Szeredi attr->ia_mode = inode->i_mode; 1869c01638f5SMiklos Szeredi if (inode->i_mode & S_ISUID) { 1870a09f99edSMiklos Szeredi attr->ia_valid |= ATTR_MODE; 1871a09f99edSMiklos Szeredi attr->ia_mode &= ~S_ISUID; 1872a09f99edSMiklos Szeredi } 1873c01638f5SMiklos Szeredi if ((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { 1874a09f99edSMiklos Szeredi attr->ia_valid |= ATTR_MODE; 1875a09f99edSMiklos Szeredi attr->ia_mode &= ~S_ISGID; 1876a09f99edSMiklos Szeredi } 1877a09f99edSMiklos Szeredi } 18785e940c1dSMiklos Szeredi } 1879a09f99edSMiklos Szeredi if (!attr->ia_valid) 1880a09f99edSMiklos Szeredi return 0; 1881a09f99edSMiklos Szeredi 1882abb5a14fSLinus Torvalds ret = fuse_do_setattr(entry, attr, file); 18835e2b8828SMiklos Szeredi if (!ret) { 188460bcc88aSSeth Forshee /* 188560bcc88aSSeth Forshee * If filesystem supports acls it may have updated acl xattrs in 188660bcc88aSSeth Forshee * the filesystem, so forget cached acls for the inode. 188760bcc88aSSeth Forshee */ 188860bcc88aSSeth Forshee if (fc->posix_acl) 188960bcc88aSSeth Forshee forget_all_cached_acls(inode); 189060bcc88aSSeth Forshee 18915e2b8828SMiklos Szeredi /* Directory mode changed, may need to revalidate access */ 18925e2b8828SMiklos Szeredi if (d_is_dir(entry) && (attr->ia_valid & ATTR_MODE)) 18935e2b8828SMiklos Szeredi fuse_invalidate_entry_cache(entry); 18945e2b8828SMiklos Szeredi } 18955e2b8828SMiklos Szeredi return ret; 189649d4914fSMiklos Szeredi } 189749d4914fSMiklos Szeredi 1898549c7297SChristian Brauner static int fuse_getattr(struct user_namespace *mnt_userns, 1899549c7297SChristian Brauner const struct path *path, struct kstat *stat, 1900a528d35eSDavid Howells u32 request_mask, unsigned int flags) 1901e5e5558eSMiklos Szeredi { 1902a528d35eSDavid Howells struct inode *inode = d_inode(path->dentry); 1903244f6385SMiklos Szeredi struct fuse_conn *fc = get_fuse_conn(inode); 1904244f6385SMiklos Szeredi 19055d069dbeSMiklos Szeredi if (fuse_is_bad(inode)) 19065d069dbeSMiklos Szeredi return -EIO; 19075d069dbeSMiklos Szeredi 19085157da2cSMiklos Szeredi if (!fuse_allow_current_process(fc)) { 19095157da2cSMiklos Szeredi if (!request_mask) { 19105157da2cSMiklos Szeredi /* 19115157da2cSMiklos Szeredi * If user explicitly requested *nothing* then don't 19125157da2cSMiklos Szeredi * error out, but return st_dev only. 19135157da2cSMiklos Szeredi */ 19145157da2cSMiklos Szeredi stat->result_mask = 0; 19155157da2cSMiklos Szeredi stat->dev = inode->i_sb->s_dev; 19165157da2cSMiklos Szeredi return 0; 19175157da2cSMiklos Szeredi } 1918244f6385SMiklos Szeredi return -EACCES; 19195157da2cSMiklos Szeredi } 1920244f6385SMiklos Szeredi 19212f1e8196SMiklos Szeredi return fuse_update_get_attr(inode, NULL, stat, request_mask, flags); 1922e5e5558eSMiklos Szeredi } 1923e5e5558eSMiklos Szeredi 1924754661f1SArjan van de Ven static const struct inode_operations fuse_dir_inode_operations = { 1925e5e5558eSMiklos Szeredi .lookup = fuse_lookup, 19269e6268dbSMiklos Szeredi .mkdir = fuse_mkdir, 19279e6268dbSMiklos Szeredi .symlink = fuse_symlink, 19289e6268dbSMiklos Szeredi .unlink = fuse_unlink, 19299e6268dbSMiklos Szeredi .rmdir = fuse_rmdir, 19302773bf00SMiklos Szeredi .rename = fuse_rename2, 19319e6268dbSMiklos Szeredi .link = fuse_link, 19329e6268dbSMiklos Szeredi .setattr = fuse_setattr, 19339e6268dbSMiklos Szeredi .create = fuse_create, 1934c8ccbe03SMiklos Szeredi .atomic_open = fuse_atomic_open, 19357d375390SMiklos Szeredi .tmpfile = fuse_tmpfile, 19369e6268dbSMiklos Szeredi .mknod = fuse_mknod, 1937e5e5558eSMiklos Szeredi .permission = fuse_permission, 1938e5e5558eSMiklos Szeredi .getattr = fuse_getattr, 193992a8780eSMiklos Szeredi .listxattr = fuse_listxattr, 194060bcc88aSSeth Forshee .get_acl = fuse_get_acl, 194160bcc88aSSeth Forshee .set_acl = fuse_set_acl, 194272227eacSMiklos Szeredi .fileattr_get = fuse_fileattr_get, 194372227eacSMiklos Szeredi .fileattr_set = fuse_fileattr_set, 1944e5e5558eSMiklos Szeredi }; 1945e5e5558eSMiklos Szeredi 19464b6f5d20SArjan van de Ven static const struct file_operations fuse_dir_operations = { 1947b6aeadedSMiklos Szeredi .llseek = generic_file_llseek, 1948e5e5558eSMiklos Szeredi .read = generic_read_dir, 1949d9b3dbdcSAl Viro .iterate_shared = fuse_readdir, 1950e5e5558eSMiklos Szeredi .open = fuse_dir_open, 1951e5e5558eSMiklos Szeredi .release = fuse_dir_release, 195282547981SMiklos Szeredi .fsync = fuse_dir_fsync, 1953b18da0c5SMiklos Szeredi .unlocked_ioctl = fuse_dir_ioctl, 1954b18da0c5SMiklos Szeredi .compat_ioctl = fuse_dir_compat_ioctl, 1955e5e5558eSMiklos Szeredi }; 1956e5e5558eSMiklos Szeredi 1957754661f1SArjan van de Ven static const struct inode_operations fuse_common_inode_operations = { 19589e6268dbSMiklos Szeredi .setattr = fuse_setattr, 1959e5e5558eSMiklos Szeredi .permission = fuse_permission, 1960e5e5558eSMiklos Szeredi .getattr = fuse_getattr, 196192a8780eSMiklos Szeredi .listxattr = fuse_listxattr, 196260bcc88aSSeth Forshee .get_acl = fuse_get_acl, 196360bcc88aSSeth Forshee .set_acl = fuse_set_acl, 196472227eacSMiklos Szeredi .fileattr_get = fuse_fileattr_get, 196572227eacSMiklos Szeredi .fileattr_set = fuse_fileattr_set, 1966e5e5558eSMiklos Szeredi }; 1967e5e5558eSMiklos Szeredi 1968754661f1SArjan van de Ven static const struct inode_operations fuse_symlink_inode_operations = { 19699e6268dbSMiklos Szeredi .setattr = fuse_setattr, 19706b255391SAl Viro .get_link = fuse_get_link, 1971e5e5558eSMiklos Szeredi .getattr = fuse_getattr, 197292a8780eSMiklos Szeredi .listxattr = fuse_listxattr, 1973e5e5558eSMiklos Szeredi }; 1974e5e5558eSMiklos Szeredi 1975e5e5558eSMiklos Szeredi void fuse_init_common(struct inode *inode) 1976e5e5558eSMiklos Szeredi { 1977e5e5558eSMiklos Szeredi inode->i_op = &fuse_common_inode_operations; 1978e5e5558eSMiklos Szeredi } 1979e5e5558eSMiklos Szeredi 1980e5e5558eSMiklos Szeredi void fuse_init_dir(struct inode *inode) 1981e5e5558eSMiklos Szeredi { 1982ab2257e9SMiklos Szeredi struct fuse_inode *fi = get_fuse_inode(inode); 1983ab2257e9SMiklos Szeredi 1984e5e5558eSMiklos Szeredi inode->i_op = &fuse_dir_inode_operations; 1985e5e5558eSMiklos Szeredi inode->i_fop = &fuse_dir_operations; 1986ab2257e9SMiklos Szeredi 1987ab2257e9SMiklos Szeredi spin_lock_init(&fi->rdc.lock); 1988ab2257e9SMiklos Szeredi fi->rdc.cached = false; 1989ab2257e9SMiklos Szeredi fi->rdc.size = 0; 1990ab2257e9SMiklos Szeredi fi->rdc.pos = 0; 1991ab2257e9SMiklos Szeredi fi->rdc.version = 0; 1992e5e5558eSMiklos Szeredi } 1993e5e5558eSMiklos Szeredi 19945efd00e4SMatthew Wilcox (Oracle) static int fuse_symlink_read_folio(struct file *null, struct folio *folio) 19955571f1e6SDan Schatzberg { 19965efd00e4SMatthew Wilcox (Oracle) int err = fuse_readlink_page(folio->mapping->host, &folio->page); 19975571f1e6SDan Schatzberg 19985571f1e6SDan Schatzberg if (!err) 19995efd00e4SMatthew Wilcox (Oracle) folio_mark_uptodate(folio); 20005571f1e6SDan Schatzberg 20015efd00e4SMatthew Wilcox (Oracle) folio_unlock(folio); 20025571f1e6SDan Schatzberg 20035571f1e6SDan Schatzberg return err; 20045571f1e6SDan Schatzberg } 20055571f1e6SDan Schatzberg 20065571f1e6SDan Schatzberg static const struct address_space_operations fuse_symlink_aops = { 20075efd00e4SMatthew Wilcox (Oracle) .read_folio = fuse_symlink_read_folio, 20085571f1e6SDan Schatzberg }; 20095571f1e6SDan Schatzberg 2010e5e5558eSMiklos Szeredi void fuse_init_symlink(struct inode *inode) 2011e5e5558eSMiklos Szeredi { 2012e5e5558eSMiklos Szeredi inode->i_op = &fuse_symlink_inode_operations; 20135571f1e6SDan Schatzberg inode->i_data.a_ops = &fuse_symlink_aops; 20145571f1e6SDan Schatzberg inode_nohighmem(inode); 2015e5e5558eSMiklos Szeredi } 2016