Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[O_TMPFILE] it's still short a few helpers, but infrastructure should be OK now...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro 60545d0d f9652e10

+164 -5
+1
arch/alpha/include/uapi/asm/fcntl.h
··· 32 32 #define O_SYNC (__O_SYNC|O_DSYNC) 33 33 34 34 #define O_PATH 040000000 35 + #define O_TMPFILE 0100000000 35 36 36 37 #define F_GETLK 7 37 38 #define F_SETLK 8
+1
arch/parisc/include/uapi/asm/fcntl.h
··· 20 20 #define O_INVISIBLE 004000000 /* invisible I/O, for DMAPI/XDSM */ 21 21 22 22 #define O_PATH 020000000 23 + #define O_TMPFILE 040000000 23 24 24 25 #define F_GETLK64 8 25 26 #define F_SETLK64 9
+1
arch/sparc/include/uapi/asm/fcntl.h
··· 35 35 #define O_SYNC (__O_SYNC|O_DSYNC) 36 36 37 37 #define O_PATH 0x1000000 38 + #define O_TMPFILE 0x2000000 38 39 39 40 #define F_GETOWN 5 /* for sockets. */ 40 41 #define F_SETOWN 6 /* for sockets. */
+16
fs/dcache.c
··· 2968 2968 goto again; 2969 2969 } 2970 2970 2971 + void d_tmpfile(struct dentry *dentry, struct inode *inode) 2972 + { 2973 + inode_dec_link_count(inode); 2974 + BUG_ON(dentry->d_name.name != dentry->d_iname || 2975 + !hlist_unhashed(&dentry->d_alias) || 2976 + !d_unlinked(dentry)); 2977 + spin_lock(&dentry->d_parent->d_lock); 2978 + spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); 2979 + dentry->d_name.len = sprintf(dentry->d_iname, "#%llu", 2980 + (unsigned long long)inode->i_ino); 2981 + spin_unlock(&dentry->d_lock); 2982 + spin_unlock(&dentry->d_parent->d_lock); 2983 + d_instantiate(dentry, inode); 2984 + } 2985 + EXPORT_SYMBOL(d_tmpfile); 2986 + 2971 2987 /** 2972 2988 * find_inode_number - check for dentry with name 2973 2989 * @dir: directory to check
+24
fs/ext2/namei.c
··· 119 119 return ext2_add_nondir(dentry, inode); 120 120 } 121 121 122 + static int ext2_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) 123 + { 124 + struct inode *inode = ext2_new_inode(dir, mode, NULL); 125 + if (IS_ERR(inode)) 126 + return PTR_ERR(inode); 127 + 128 + inode->i_op = &ext2_file_inode_operations; 129 + if (ext2_use_xip(inode->i_sb)) { 130 + inode->i_mapping->a_ops = &ext2_aops_xip; 131 + inode->i_fop = &ext2_xip_file_operations; 132 + } else if (test_opt(inode->i_sb, NOBH)) { 133 + inode->i_mapping->a_ops = &ext2_nobh_aops; 134 + inode->i_fop = &ext2_file_operations; 135 + } else { 136 + inode->i_mapping->a_ops = &ext2_aops; 137 + inode->i_fop = &ext2_file_operations; 138 + } 139 + mark_inode_dirty(inode); 140 + d_tmpfile(dentry, inode); 141 + unlock_new_inode(inode); 142 + return 0; 143 + } 144 + 122 145 static int ext2_mknod (struct inode * dir, struct dentry *dentry, umode_t mode, dev_t rdev) 123 146 { 124 147 struct inode * inode; ··· 421 398 #endif 422 399 .setattr = ext2_setattr, 423 400 .get_acl = ext2_get_acl, 401 + .tmpfile = ext2_tmpfile, 424 402 }; 425 403 426 404 const struct inode_operations ext2_special_inode_operations = {
+13
fs/minix/namei.c
··· 54 54 return error; 55 55 } 56 56 57 + static int minix_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) 58 + { 59 + int error; 60 + struct inode *inode = minix_new_inode(dir, mode, &error); 61 + if (inode) { 62 + minix_set_inode(inode, 0); 63 + mark_inode_dirty(inode); 64 + d_tmpfile(dentry, inode); 65 + } 66 + return error; 67 + } 68 + 57 69 static int minix_create(struct inode *dir, struct dentry *dentry, umode_t mode, 58 70 bool excl) 59 71 { ··· 266 254 .mknod = minix_mknod, 267 255 .rename = minix_rename, 268 256 .getattr = minix_getattr, 257 + .tmpfile = minix_tmpfile, 269 258 };
+60
fs/namei.c
··· 2902 2902 goto retry_lookup; 2903 2903 } 2904 2904 2905 + static int do_tmpfile(int dfd, struct filename *pathname, 2906 + struct nameidata *nd, int flags, 2907 + const struct open_flags *op, 2908 + struct file *file, int *opened) 2909 + { 2910 + static const struct qstr name = QSTR_INIT("/", 1); 2911 + struct dentry *dentry, *child; 2912 + struct inode *dir; 2913 + int error = path_lookupat(dfd, pathname->name, 2914 + flags | LOOKUP_DIRECTORY, nd); 2915 + if (unlikely(error)) 2916 + return error; 2917 + error = mnt_want_write(nd->path.mnt); 2918 + if (unlikely(error)) 2919 + goto out; 2920 + /* we want directory to be writable */ 2921 + error = inode_permission(nd->inode, MAY_WRITE | MAY_EXEC); 2922 + if (error) 2923 + goto out2; 2924 + dentry = nd->path.dentry; 2925 + dir = dentry->d_inode; 2926 + if (!dir->i_op->tmpfile) { 2927 + error = -EOPNOTSUPP; 2928 + goto out2; 2929 + } 2930 + child = d_alloc(dentry, &name); 2931 + if (unlikely(!child)) { 2932 + error = -ENOMEM; 2933 + goto out2; 2934 + } 2935 + nd->flags &= ~LOOKUP_DIRECTORY; 2936 + nd->flags |= op->intent; 2937 + dput(nd->path.dentry); 2938 + nd->path.dentry = child; 2939 + error = dir->i_op->tmpfile(dir, nd->path.dentry, op->mode); 2940 + if (error) 2941 + goto out2; 2942 + audit_inode(pathname, nd->path.dentry, 0); 2943 + error = may_open(&nd->path, op->acc_mode, op->open_flag); 2944 + if (error) 2945 + goto out2; 2946 + file->f_path.mnt = nd->path.mnt; 2947 + error = finish_open(file, nd->path.dentry, NULL, opened); 2948 + if (error) 2949 + goto out2; 2950 + error = open_check_o_direct(file); 2951 + if (error) 2952 + fput(file); 2953 + out2: 2954 + mnt_drop_write(nd->path.mnt); 2955 + out: 2956 + path_put(&nd->path); 2957 + return error; 2958 + } 2959 + 2905 2960 static struct file *path_openat(int dfd, struct filename *pathname, 2906 2961 struct nameidata *nd, const struct open_flags *op, int flags) 2907 2962 { ··· 2971 2916 return file; 2972 2917 2973 2918 file->f_flags = op->open_flag; 2919 + 2920 + if (unlikely(file->f_flags & O_TMPFILE)) { 2921 + error = do_tmpfile(dfd, pathname, nd, flags, op, file, &opened); 2922 + goto out; 2923 + } 2974 2924 2975 2925 error = path_init(dfd, pathname->name, flags | LOOKUP_PARENT, nd, &base); 2976 2926 if (unlikely(error))
+9 -5
fs/open.c
··· 840 840 if (flags & __O_SYNC) 841 841 flags |= O_DSYNC; 842 842 843 - /* 844 - * If we have O_PATH in the open flag. Then we 845 - * cannot have anything other than the below set of flags 846 - */ 847 - if (flags & O_PATH) { 843 + if (flags & O_TMPFILE) { 844 + if (!(flags & O_CREAT)) 845 + return -EINVAL; 846 + acc_mode = MAY_OPEN | ACC_MODE(flags); 847 + } else if (flags & O_PATH) { 848 + /* 849 + * If we have O_PATH in the open flag. Then we 850 + * cannot have anything other than the below set of flags 851 + */ 848 852 flags &= O_DIRECTORY | O_NOFOLLOW | O_PATH; 849 853 acc_mode = 0; 850 854 } else {
+2
include/linux/dcache.h
··· 246 246 /* <clickety>-<click> the ramfs-type tree */ 247 247 extern void d_genocide(struct dentry *); 248 248 249 + extern void d_tmpfile(struct dentry *, struct inode *); 250 + 249 251 extern struct dentry *d_find_alias(struct inode *); 250 252 extern void d_prune_aliases(struct inode *); 251 253
+1
include/linux/fs.h
··· 1580 1580 int (*atomic_open)(struct inode *, struct dentry *, 1581 1581 struct file *, unsigned open_flag, 1582 1582 umode_t create_mode, int *opened); 1583 + int (*tmpfile) (struct inode *, struct dentry *, umode_t); 1583 1584 } ____cacheline_aligned; 1584 1585 1585 1586 ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
+4
include/uapi/asm-generic/fcntl.h
··· 84 84 #define O_PATH 010000000 85 85 #endif 86 86 87 + #ifndef O_TMPFILE 88 + #define O_TMPFILE 020000000 89 + #endif 90 + 87 91 #ifndef O_NDELAY 88 92 #define O_NDELAY O_NONBLOCK 89 93 #endif
+32
mm/shmem.c
··· 1965 1965 return error; 1966 1966 } 1967 1967 1968 + static int 1969 + shmem_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) 1970 + { 1971 + struct inode *inode; 1972 + int error = -ENOSPC; 1973 + 1974 + inode = shmem_get_inode(dir->i_sb, dir, mode, 0, VM_NORESERVE); 1975 + if (inode) { 1976 + error = security_inode_init_security(inode, dir, 1977 + NULL, 1978 + shmem_initxattrs, NULL); 1979 + if (error) { 1980 + if (error != -EOPNOTSUPP) { 1981 + iput(inode); 1982 + return error; 1983 + } 1984 + } 1985 + #ifdef CONFIG_TMPFS_POSIX_ACL 1986 + error = generic_acl_init(inode, dir); 1987 + if (error) { 1988 + iput(inode); 1989 + return error; 1990 + } 1991 + #else 1992 + error = 0; 1993 + #endif 1994 + d_tmpfile(dentry, inode); 1995 + } 1996 + return error; 1997 + } 1998 + 1968 1999 static int shmem_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) 1969 2000 { 1970 2001 int error; ··· 2754 2723 .rmdir = shmem_rmdir, 2755 2724 .mknod = shmem_mknod, 2756 2725 .rename = shmem_rename, 2726 + .tmpfile = shmem_tmpfile, 2757 2727 #endif 2758 2728 #ifdef CONFIG_TMPFS_XATTR 2759 2729 .setxattr = shmem_setxattr,