mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
Merge branch 'lineage-16.0' into followmsi-pie
Conflicts: arch/arm/configs/lineageos_flo_defconfig
This commit is contained in:
commit
69672b517e
355 changed files with 8971 additions and 5103 deletions
9
Documentation/ABI/removed/ip_queue
Normal file
9
Documentation/ABI/removed/ip_queue
Normal file
|
@ -0,0 +1,9 @@
|
|||
What: ip_queue
|
||||
Date: finally removed in kernel v3.5.0
|
||||
Contact: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Description:
|
||||
ip_queue has been replaced by nfnetlink_queue which provides
|
||||
more advanced queueing mechanism to user-space. The ip_queue
|
||||
module was already announced to become obsolete years ago.
|
||||
|
||||
Users:
|
|
@ -361,14 +361,6 @@ Why: Internal alias support has been present in module-init-tools for some
|
|||
|
||||
Who: Wey-Yi Guy <wey-yi.w.guy@intel.com>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: xt_NOTRACK
|
||||
Files: net/netfilter/xt_NOTRACK.c
|
||||
When: April 2011
|
||||
Why: Superseded by xt_CT
|
||||
Who: Netfilter developer team <netfilter-devel@vger.kernel.org>
|
||||
|
||||
----------------------------
|
||||
|
||||
What: IRQF_DISABLED
|
||||
|
@ -407,13 +399,6 @@ Who: Jean Delvare <khali@linux-fr.org>
|
|||
|
||||
----------------------------
|
||||
|
||||
What: xt_connlimit rev 0
|
||||
When: 2012
|
||||
Who: Jan Engelhardt <jengelh@medozas.de>
|
||||
Files: net/netfilter/xt_connlimit.c
|
||||
|
||||
----------------------------
|
||||
|
||||
What: ipt_addrtype match include file
|
||||
When: 2012
|
||||
Why: superseded by xt_addrtype
|
||||
|
|
|
@ -9,7 +9,7 @@ be able to use diff(1).
|
|||
|
||||
--------------------------- dentry_operations --------------------------
|
||||
prototypes:
|
||||
int (*d_revalidate)(struct dentry *, struct nameidata *);
|
||||
int (*d_revalidate)(struct dentry *, unsigned int);
|
||||
int (*d_hash)(const struct dentry *, const struct inode *,
|
||||
struct qstr *);
|
||||
int (*d_compare)(const struct dentry *, const struct inode *,
|
||||
|
@ -37,9 +37,8 @@ d_manage: no no yes (ref-walk) maybe
|
|||
|
||||
--------------------------- inode_operations ---------------------------
|
||||
prototypes:
|
||||
int (*create) (struct inode *,struct dentry *,umode_t, struct nameidata *);
|
||||
struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameid
|
||||
ata *);
|
||||
int (*create) (struct inode *,struct dentry *,umode_t, bool);
|
||||
struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int);
|
||||
int (*link) (struct dentry *,struct inode *,struct dentry *);
|
||||
int (*unlink) (struct inode *,struct dentry *);
|
||||
int (*symlink) (struct inode *,struct dentry *,const char *);
|
||||
|
@ -63,6 +62,10 @@ ata *);
|
|||
void (*truncate_range)(struct inode *, loff_t, loff_t);
|
||||
int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len);
|
||||
void (*update_time)(struct inode *, struct timespec *, int);
|
||||
int (*atomic_open)(struct inode *, struct dentry *,
|
||||
struct file *, unsigned open_flag,
|
||||
umode_t create_mode, int *opened);
|
||||
int (*tmpfile) (struct inode *, struct dentry *, umode_t);
|
||||
|
||||
locking rules:
|
||||
all may block
|
||||
|
@ -91,6 +94,8 @@ removexattr: yes
|
|||
truncate_range: yes
|
||||
fiemap: no
|
||||
update_time: no
|
||||
atomic_open: yes
|
||||
tmpfile: no
|
||||
|
||||
Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on
|
||||
victim.
|
||||
|
|
|
@ -435,3 +435,14 @@ release it yourself.
|
|||
d_alloc_root() is gone, along with a lot of bugs caused by code
|
||||
misusing it. Replacement: d_make_root(inode). The difference is,
|
||||
d_make_root() drops the reference to inode if dentry allocation fails.
|
||||
|
||||
--
|
||||
[mandatory]
|
||||
The witch is dead! Well, 2/3 of it, anyway. ->d_revalidate() and
|
||||
->lookup() do *not* take struct nameidata anymore; just the flags.
|
||||
--
|
||||
[mandatory]
|
||||
->create() doesn't take struct nameidata *; unlike the previous
|
||||
two, it gets "is it an O_EXCL or equivalent?" boolean argument. Note that
|
||||
local filesystems can ignore tha argument - they are guaranteed that the
|
||||
object doesn't exist. It's remote/distributed ones that might care...
|
||||
|
|
|
@ -341,8 +341,8 @@ This describes how the VFS can manipulate an inode in your
|
|||
filesystem. As of kernel 2.6.22, the following members are defined:
|
||||
|
||||
struct inode_operations {
|
||||
int (*create) (struct inode *,struct dentry *, umode_t, struct nameidata *);
|
||||
struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);
|
||||
int (*create) (struct inode *,struct dentry *, umode_t, bool);
|
||||
struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int);
|
||||
int (*link) (struct dentry *,struct inode *,struct dentry *);
|
||||
int (*unlink) (struct inode *,struct dentry *);
|
||||
int (*symlink) (struct inode *,struct dentry *,const char *);
|
||||
|
@ -365,6 +365,9 @@ struct inode_operations {
|
|||
int (*removexattr) (struct dentry *, const char *);
|
||||
void (*truncate_range)(struct inode *, loff_t, loff_t);
|
||||
void (*update_time)(struct inode *, struct timespec *, int);
|
||||
int (*atomic_open)(struct inode *, struct dentry *, struct file *,
|
||||
unsigned open_flag, umode_t create_mode, int *opened);
|
||||
int (*tmpfile) (struct inode *, struct dentry *, umode_t);
|
||||
};
|
||||
|
||||
Again, all methods are called without any locks being held, unless
|
||||
|
@ -480,6 +483,19 @@ otherwise noted.
|
|||
an inode. If this is not defined the VFS will update the inode itself
|
||||
and call mark_inode_dirty_sync.
|
||||
|
||||
atomic_open: called on the last component of an open. Using this optional
|
||||
method the filesystem can look up, possibly create and open the file in
|
||||
one atomic operation. If it cannot perform this (e.g. the file type
|
||||
turned out to be wrong) it may signal this by returning 1 instead of
|
||||
usual 0 or -ve . This method is only called if the last component is
|
||||
negative or needs lookup. Cached positive dentries are still handled by
|
||||
f_op->open(). If the file was created, the FILE_CREATED flag should be
|
||||
set in "opened". In case of O_EXCL the method must only succeed if the
|
||||
file didn't exist and hence FILE_CREATED shall always be set on success.
|
||||
|
||||
tmpfile: called in the end of O_TMPFILE open(). Optional, equivalent to
|
||||
atomically creating, opening and unlinking a file in given directory.
|
||||
|
||||
The Address Space Object
|
||||
========================
|
||||
|
||||
|
@ -888,7 +904,7 @@ the VFS uses a default. As of kernel 2.6.22, the following members are
|
|||
defined:
|
||||
|
||||
struct dentry_operations {
|
||||
int (*d_revalidate)(struct dentry *, struct nameidata *);
|
||||
int (*d_revalidate)(struct dentry *, unsigned int);
|
||||
int (*d_hash)(const struct dentry *, const struct inode *,
|
||||
struct qstr *);
|
||||
int (*d_compare)(const struct dentry *, const struct inode *,
|
||||
|
@ -907,11 +923,11 @@ struct dentry_operations {
|
|||
dcache. Most filesystems leave this as NULL, because all their
|
||||
dentries in the dcache are valid
|
||||
|
||||
d_revalidate may be called in rcu-walk mode (nd->flags & LOOKUP_RCU).
|
||||
d_revalidate may be called in rcu-walk mode (flags & LOOKUP_RCU).
|
||||
If in rcu-walk mode, the filesystem must revalidate the dentry without
|
||||
blocking or storing to the dentry, d_parent and d_inode should not be
|
||||
used without care (because they can go NULL), instead nd->inode should
|
||||
be used.
|
||||
used without care (because they can change and, in d_inode case, even
|
||||
become NULL under us).
|
||||
|
||||
If a situation is encountered that rcu-walk cannot handle, return
|
||||
-ECHILD and it will be called again in ref-walk mode.
|
||||
|
|
|
@ -981,6 +981,19 @@ disable_xfrm - BOOLEAN
|
|||
Disable IPSEC encryption on this interface, whatever the policy
|
||||
|
||||
|
||||
drop_unicast_in_l2_multicast - BOOLEAN
|
||||
Drop any unicast IP packets that are received in link-layer
|
||||
multicast (or broadcast) frames.
|
||||
This behavior (for multicast) is actually a SHOULD in RFC
|
||||
1122, but is disabled by default for compatibility reasons.
|
||||
Default: off (0)
|
||||
|
||||
drop_gratuitous_arp - BOOLEAN
|
||||
Drop all gratuitous ARP frames, for example if there's a known
|
||||
good ARP proxy on the network and such frames need not be used
|
||||
(or in the case of 802.11, must not be used to prevent attacks.)
|
||||
Default: off (0)
|
||||
|
||||
|
||||
tag - INTEGER
|
||||
Allows you to write a number, which can be used as required.
|
||||
|
@ -1299,6 +1312,19 @@ use_optimistic - BOOLEAN
|
|||
0: disabled (default)
|
||||
1: enabled
|
||||
|
||||
drop_unicast_in_l2_multicast - BOOLEAN
|
||||
Drop any unicast IPv6 packets that are received in link-layer
|
||||
multicast (or broadcast) frames.
|
||||
|
||||
By default this is turned off.
|
||||
|
||||
drop_unsolicited_na - BOOLEAN
|
||||
Drop all unsolicited neighbor advertisements, for example if there's
|
||||
a known good NA proxy on the network and such frames need not be used
|
||||
(or in the case of 802.11, must not be used to prevent attacks.)
|
||||
|
||||
By default this is turned off.
|
||||
|
||||
icmp/*:
|
||||
ratelimit - INTEGER
|
||||
Limit the maximal rates for sending ICMPv6 packets.
|
||||
|
|
|
@ -32,6 +32,8 @@ Currently, these files are in /proc/sys/fs:
|
|||
- nr_open
|
||||
- overflowuid
|
||||
- overflowgid
|
||||
- protected_hardlinks
|
||||
- protected_symlinks
|
||||
- pipe-user-pages-hard
|
||||
- pipe-user-pages-soft
|
||||
- suid_dumpable
|
||||
|
@ -180,6 +182,46 @@ applied.
|
|||
|
||||
==============================================================
|
||||
|
||||
protected_hardlinks:
|
||||
|
||||
A long-standing class of security issues is the hardlink-based
|
||||
time-of-check-time-of-use race, most commonly seen in world-writable
|
||||
directories like /tmp. The common method of exploitation of this flaw
|
||||
is to cross privilege boundaries when following a given hardlink (i.e. a
|
||||
root process follows a hardlink created by another user). Additionally,
|
||||
on systems without separated partitions, this stops unauthorized users
|
||||
from "pinning" vulnerable setuid/setgid files against being upgraded by
|
||||
the administrator, or linking to special files.
|
||||
|
||||
When set to "0", hardlink creation behavior is unrestricted.
|
||||
|
||||
When set to "1" hardlinks cannot be created by users if they do not
|
||||
already own the source file, or do not have read/write access to it.
|
||||
|
||||
This protection is based on the restrictions in Openwall and grsecurity.
|
||||
|
||||
==============================================================
|
||||
|
||||
protected_symlinks:
|
||||
|
||||
A long-standing class of security issues is the symlink-based
|
||||
time-of-check-time-of-use race, most commonly seen in world-writable
|
||||
directories like /tmp. The common method of exploitation of this flaw
|
||||
is to cross privilege boundaries when following a given symlink (i.e. a
|
||||
root process follows a symlink belonging to another user). For a likely
|
||||
incomplete list of hundreds of examples across the years, please see:
|
||||
http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=/tmp
|
||||
|
||||
When set to "0", symlink following behavior is unrestricted.
|
||||
|
||||
When set to "1" symlinks are permitted to be followed only when outside
|
||||
a sticky world-writable directory, or when the uid of the symlink and
|
||||
follower match, or when the directory owner matches the symlink's owner.
|
||||
|
||||
This protection is based on the restrictions in Openwall and grsecurity.
|
||||
|
||||
==============================================================
|
||||
|
||||
suid_dumpable:
|
||||
|
||||
This value can be used to query and set the core dump mode for setuid
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#define O_SYNC (__O_SYNC|O_DSYNC)
|
||||
|
||||
#define O_PATH 040000000
|
||||
#define __O_TMPFILE 0100000000
|
||||
|
||||
#define F_GETLK 7
|
||||
#define F_SETLK 8
|
||||
|
|
|
@ -289,7 +289,7 @@ osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags)
|
|||
{
|
||||
int retval;
|
||||
struct cdfs_args tmp;
|
||||
char *devname;
|
||||
struct filename *devname;
|
||||
|
||||
retval = -EFAULT;
|
||||
if (copy_from_user(&tmp, args, sizeof(tmp)))
|
||||
|
@ -298,7 +298,7 @@ osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags)
|
|||
retval = PTR_ERR(devname);
|
||||
if (IS_ERR(devname))
|
||||
goto out;
|
||||
retval = do_mount(devname, dirname, "ext2", flags, NULL);
|
||||
retval = do_mount(devname->name, dirname, "ext2", flags, NULL);
|
||||
putname(devname);
|
||||
out:
|
||||
return retval;
|
||||
|
@ -309,7 +309,7 @@ osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags)
|
|||
{
|
||||
int retval;
|
||||
struct cdfs_args tmp;
|
||||
char *devname;
|
||||
struct filename *devname;
|
||||
|
||||
retval = -EFAULT;
|
||||
if (copy_from_user(&tmp, args, sizeof(tmp)))
|
||||
|
@ -318,7 +318,7 @@ osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags)
|
|||
retval = PTR_ERR(devname);
|
||||
if (IS_ERR(devname))
|
||||
goto out;
|
||||
retval = do_mount(devname, dirname, "iso9660", flags, NULL);
|
||||
retval = do_mount(devname->name, dirname, "iso9660", flags, NULL);
|
||||
putname(devname);
|
||||
out:
|
||||
return retval;
|
||||
|
@ -339,7 +339,7 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, const char __user *, path,
|
|||
int, flag, void __user *, data)
|
||||
{
|
||||
int retval;
|
||||
char *name;
|
||||
struct filename *name;
|
||||
|
||||
name = getname(path);
|
||||
retval = PTR_ERR(name);
|
||||
|
@ -347,13 +347,13 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, const char __user *, path,
|
|||
goto out;
|
||||
switch (typenr) {
|
||||
case 1:
|
||||
retval = osf_ufs_mount(name, data, flag);
|
||||
retval = osf_ufs_mount(name->name, data, flag);
|
||||
break;
|
||||
case 6:
|
||||
retval = osf_cdfs_mount(name, data, flag);
|
||||
retval = osf_cdfs_mount(name->name, data, flag);
|
||||
break;
|
||||
case 9:
|
||||
retval = osf_procfs_mount(name, data, flag);
|
||||
retval = osf_procfs_mount(name->name, data, flag);
|
||||
break;
|
||||
default:
|
||||
retval = -EINVAL;
|
||||
|
|
|
@ -145,10 +145,13 @@ CONFIG_NF_CONNTRACK_PPTP=y
|
|||
CONFIG_NF_CONNTRACK_SANE=y
|
||||
CONFIG_NF_CONNTRACK_TFTP=y
|
||||
CONFIG_NF_CT_NETLINK=y
|
||||
CONFIG_NF_CT_NETLINK_HELPER=y
|
||||
CONFIG_NETFILTER_NETLINK_QUEUE_CT=y
|
||||
CONFIG_NETFILTER_TPROXY=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_HMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
|
||||
CONFIG_NETFILTER_XT_TARGET_LOG=y
|
||||
CONFIG_NETFILTER_XT_TARGET_MARK=y
|
||||
|
@ -157,6 +160,7 @@ CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
|
|||
CONFIG_NETFILTER_XT_TARGET_SECMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
|
||||
CONFIG_NETFILTER_XT_MATCH_COMMENT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNLABEL=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
|
||||
|
@ -187,7 +191,7 @@ CONFIG_IP_NF_MATCH_ECN=y
|
|||
CONFIG_IP_NF_MATCH_TTL=y
|
||||
CONFIG_IP_NF_FILTER=y
|
||||
CONFIG_IP_NF_TARGET_REJECT=y
|
||||
CONFIG_NF_NAT=y
|
||||
CONFIG_NF_NAT_IPV4=y
|
||||
CONFIG_IP_NF_TARGET_MASQUERADE=y
|
||||
CONFIG_IP_NF_TARGET_NETMAP=y
|
||||
CONFIG_IP_NF_TARGET_REDIRECT=y
|
||||
|
@ -198,6 +202,7 @@ CONFIG_IP_NF_ARPTABLES=y
|
|||
CONFIG_IP_NF_ARPFILTER=y
|
||||
CONFIG_IP_NF_ARP_MANGLE=y
|
||||
CONFIG_NF_CONNTRACK_IPV6=y
|
||||
CONFIG_NF_NAT_IPV6=y
|
||||
CONFIG_IP6_NF_IPTABLES=y
|
||||
CONFIG_IP6_NF_FILTER=y
|
||||
CONFIG_IP6_NF_TARGET_REJECT=y
|
||||
|
|
|
@ -156,9 +156,13 @@ CONFIG_NF_CONNTRACK_PPTP=y
|
|||
CONFIG_NF_CONNTRACK_SANE=y
|
||||
CONFIG_NF_CONNTRACK_TFTP=y
|
||||
CONFIG_NF_CT_NETLINK=y
|
||||
CONFIG_NF_CT_NETLINK_HELPER=y
|
||||
CONFIG_NETFILTER_NETLINK_QUEUE_CT=y
|
||||
CONFIG_NETFILTER_TPROXY=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_HMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
|
||||
CONFIG_NETFILTER_XT_TARGET_LOG=y
|
||||
CONFIG_NETFILTER_XT_TARGET_MARK=y
|
||||
|
@ -167,6 +171,7 @@ CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
|
|||
CONFIG_NETFILTER_XT_TARGET_SECMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
|
||||
CONFIG_NETFILTER_XT_MATCH_COMMENT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNLABEL=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
|
||||
|
@ -196,7 +201,7 @@ CONFIG_IP_NF_MATCH_RPFILTER=y
|
|||
CONFIG_IP_NF_MATCH_TTL=y
|
||||
CONFIG_IP_NF_FILTER=y
|
||||
CONFIG_IP_NF_TARGET_REJECT=y
|
||||
CONFIG_NF_NAT=y
|
||||
CONFIG_NF_NAT_IPV4=y
|
||||
CONFIG_IP_NF_TARGET_MASQUERADE=y
|
||||
CONFIG_IP_NF_TARGET_NETMAP=y
|
||||
CONFIG_IP_NF_TARGET_REDIRECT=y
|
||||
|
@ -207,6 +212,7 @@ CONFIG_IP_NF_ARPTABLES=y
|
|||
CONFIG_IP_NF_ARPFILTER=y
|
||||
CONFIG_IP_NF_ARP_MANGLE=y
|
||||
CONFIG_NF_CONNTRACK_IPV6=y
|
||||
CONFIG_NF_NAT_IPV6=y
|
||||
CONFIG_IP6_NF_IPTABLES=y
|
||||
CONFIG_IP6_NF_MATCH_RPFILTER=y
|
||||
CONFIG_IP6_NF_FILTER=y
|
||||
|
|
|
@ -67,13 +67,13 @@ asmlinkage int sys_execve(const char __user *filenamei,
|
|||
const char __user *const __user *envp, struct pt_regs *regs)
|
||||
{
|
||||
int error;
|
||||
char * filename;
|
||||
struct filename *filename;
|
||||
|
||||
filename = getname(filenamei);
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
error = do_execve(filename, argv, envp, regs);
|
||||
error = do_execve(filename->name, argv, envp, regs);
|
||||
putname(filename);
|
||||
out:
|
||||
return error;
|
||||
|
|
|
@ -388,14 +388,14 @@ asmlinkage int sys_execve(const char __user *ufilename,
|
|||
struct pt_regs *regs)
|
||||
{
|
||||
int error;
|
||||
char *filename;
|
||||
struct filename *filename;
|
||||
|
||||
filename = getname(ufilename);
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
|
||||
error = do_execve(filename, uargv, uenvp, regs);
|
||||
error = do_execve(filename->name, uargv, uenvp, regs);
|
||||
putname(filename);
|
||||
|
||||
out:
|
||||
|
|
|
@ -211,14 +211,14 @@ asmlinkage int sys_execve(const char __user *name,
|
|||
const char __user *const __user *envp)
|
||||
{
|
||||
int error;
|
||||
char *filename;
|
||||
struct filename *filename;
|
||||
struct pt_regs *regs = (struct pt_regs *)((&name) + 6);
|
||||
|
||||
filename = getname(name);
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
return error;
|
||||
error = do_execve(filename, argv, envp, regs);
|
||||
error = do_execve(filename->name, argv, envp, regs);
|
||||
putname(filename);
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -212,14 +212,14 @@ asmlinkage int sys_execve(const char *fname,
|
|||
struct pt_regs *regs)
|
||||
{
|
||||
int error;
|
||||
char *filename;
|
||||
struct filename *filename;
|
||||
|
||||
filename = getname(fname);
|
||||
error = PTR_ERR(filename);
|
||||
|
||||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
error = do_execve(filename, argv, envp, regs);
|
||||
error = do_execve(filename->name, argv, envp, regs);
|
||||
putname(filename);
|
||||
out:
|
||||
return error;
|
||||
|
|
|
@ -224,7 +224,7 @@ sys_execve(const char *fname,
|
|||
struct pt_regs *regs)
|
||||
{
|
||||
int error;
|
||||
char *filename;
|
||||
struct filename *filename;
|
||||
|
||||
filename = getname(fname);
|
||||
error = PTR_ERR(filename);
|
||||
|
@ -232,7 +232,7 @@ sys_execve(const char *fname,
|
|||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
|
||||
error = do_execve(filename, argv, envp, regs);
|
||||
error = do_execve(filename->name, argv, envp, regs);
|
||||
putname(filename);
|
||||
out:
|
||||
return error;
|
||||
|
|
|
@ -217,14 +217,14 @@ asmlinkage int sys_execve(const char *name,
|
|||
int dummy, ...)
|
||||
{
|
||||
int error;
|
||||
char * filename;
|
||||
struct filename *filename;
|
||||
struct pt_regs *regs = (struct pt_regs *) ((unsigned char *)&dummy-4);
|
||||
|
||||
filename = getname(name);
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
return error;
|
||||
error = do_execve(filename, argv, envp, regs);
|
||||
error = do_execve(filename->name, argv, envp, regs);
|
||||
putname(filename);
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ asmlinkage int sys_execve(char __user *ufilename,
|
|||
const char __user *const __user *envp)
|
||||
{
|
||||
struct pt_regs *pregs = current_thread_info()->regs;
|
||||
char *filename;
|
||||
struct filename *filename;
|
||||
int retval;
|
||||
|
||||
filename = getname(ufilename);
|
||||
|
@ -48,7 +48,7 @@ asmlinkage int sys_execve(char __user *ufilename,
|
|||
if (IS_ERR(filename))
|
||||
return retval;
|
||||
|
||||
retval = do_execve(filename, argv, envp, pregs);
|
||||
retval = do_execve(filename->name, argv, envp, pregs);
|
||||
putname(filename);
|
||||
|
||||
return retval;
|
||||
|
|
|
@ -636,14 +636,14 @@ sys_execve (const char __user *filename,
|
|||
const char __user *const __user *envp,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
char *fname;
|
||||
struct filename *fname;
|
||||
int error;
|
||||
|
||||
fname = getname(filename);
|
||||
error = PTR_ERR(fname);
|
||||
if (IS_ERR(fname))
|
||||
goto out;
|
||||
error = do_execve(fname, argv, envp, regs);
|
||||
error = do_execve(fname->name, argv, envp, regs);
|
||||
putname(fname);
|
||||
out:
|
||||
return error;
|
||||
|
|
|
@ -296,14 +296,14 @@ asmlinkage int sys_execve(const char __user *ufilename,
|
|||
unsigned long r6, struct pt_regs regs)
|
||||
{
|
||||
int error;
|
||||
char *filename;
|
||||
struct filename *filename;
|
||||
|
||||
filename = getname(ufilename);
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
|
||||
error = do_execve(filename, uargv, uenvp, ®s);
|
||||
error = do_execve(filename->name, uargv, uenvp, ®s);
|
||||
putname(filename);
|
||||
out:
|
||||
return error;
|
||||
|
|
|
@ -67,7 +67,6 @@ CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
|
||||
|
|
|
@ -67,7 +67,6 @@ CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
|
||||
|
|
|
@ -65,7 +65,6 @@ CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
|
||||
|
|
|
@ -65,7 +65,6 @@ CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
|
||||
|
|
|
@ -66,7 +66,6 @@ CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
|
||||
|
|
|
@ -61,7 +61,6 @@ CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
|
||||
|
|
|
@ -80,7 +80,6 @@ CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
|
||||
|
|
|
@ -64,7 +64,6 @@ CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
|
||||
|
|
|
@ -65,7 +65,6 @@ CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
|
||||
|
|
|
@ -61,7 +61,6 @@ CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
|
||||
|
|
|
@ -62,7 +62,6 @@ CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
|
||||
|
|
|
@ -62,7 +62,6 @@ CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
|
||||
|
|
|
@ -54,13 +54,13 @@ asmlinkage long microblaze_execve(const char __user *filenamei,
|
|||
struct pt_regs *regs)
|
||||
{
|
||||
int error;
|
||||
char *filename;
|
||||
struct filename *filename;
|
||||
|
||||
filename = getname(filenamei);
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
error = do_execve(filename, argv, envp, regs);
|
||||
error = do_execve(filename->name, argv, envp, regs);
|
||||
putname(filename);
|
||||
out:
|
||||
return error;
|
||||
|
|
|
@ -56,7 +56,6 @@ CONFIG_NF_CONNTRACK_MARK=y
|
|||
CONFIG_NF_CONNTRACK_FTP=m
|
||||
CONFIG_NF_CONNTRACK_IRC=m
|
||||
CONFIG_NF_CONNTRACK_TFTP=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_MATCH_LIMIT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_MAC=m
|
||||
|
|
|
@ -96,7 +96,6 @@ CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_SECMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
|
|
|
@ -87,7 +87,6 @@ CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TPROXY=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_SECMARK=m
|
||||
|
|
|
@ -60,7 +60,6 @@ CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_SECMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_MATCH_COMMENT=m
|
||||
|
|
|
@ -86,7 +86,6 @@ CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TPROXY=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_SECMARK=m
|
||||
|
|
|
@ -59,7 +59,6 @@ CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_SECMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_MATCH_COMMENT=m
|
||||
|
|
|
@ -108,7 +108,6 @@ CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TPROXY=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_SECMARK=m
|
||||
|
|
|
@ -109,7 +109,6 @@ CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TPROXY=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_SECMARK=m
|
||||
|
|
|
@ -68,7 +68,6 @@ CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_SECMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_MATCH_COMMENT=m
|
||||
|
|
|
@ -83,13 +83,13 @@ out:
|
|||
asmlinkage int sys32_execve(nabi_no_regargs struct pt_regs regs)
|
||||
{
|
||||
int error;
|
||||
char * filename;
|
||||
struct filename *filename;
|
||||
|
||||
filename = getname(compat_ptr(regs.regs[4]));
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
error = compat_do_execve(filename, compat_ptr(regs.regs[5]),
|
||||
error = compat_do_execve(filename->name, compat_ptr(regs.regs[5]),
|
||||
compat_ptr(regs.regs[6]), ®s);
|
||||
putname(filename);
|
||||
|
||||
|
|
|
@ -133,13 +133,13 @@ _sys_clone(nabi_no_regargs struct pt_regs regs)
|
|||
asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs)
|
||||
{
|
||||
int error;
|
||||
char * filename;
|
||||
struct filename *filename;
|
||||
|
||||
filename = getname((const char __user *) (long)regs.regs[4]);
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
error = do_execve(filename,
|
||||
error = do_execve(filename->name,
|
||||
(const char __user *const __user *) (long)regs.regs[5],
|
||||
(const char __user *const __user *) (long)regs.regs[6],
|
||||
®s);
|
||||
|
|
|
@ -271,7 +271,7 @@ asmlinkage long _sys_execve(const char __user *name,
|
|||
struct pt_regs *regs)
|
||||
{
|
||||
int error;
|
||||
char *filename;
|
||||
struct filename *filename;
|
||||
|
||||
filename = getname(name);
|
||||
error = PTR_ERR(filename);
|
||||
|
@ -279,7 +279,7 @@ asmlinkage long _sys_execve(const char __user *name,
|
|||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
|
||||
error = do_execve(filename, argv, envp, regs);
|
||||
error = do_execve(filename->name, argv, envp, regs);
|
||||
putname(filename);
|
||||
|
||||
out:
|
||||
|
|
|
@ -34,14 +34,14 @@
|
|||
int hpux_execve(struct pt_regs *regs)
|
||||
{
|
||||
int error;
|
||||
char *filename;
|
||||
struct filename *filename;
|
||||
|
||||
filename = getname((const char __user *) regs->gr[26]);
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
|
||||
error = do_execve(filename,
|
||||
error = do_execve(filename->name,
|
||||
(const char __user *const __user *) regs->gr[25],
|
||||
(const char __user *const __user *) regs->gr[24],
|
||||
regs);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#define O_INVISIBLE 004000000 /* invisible I/O, for DMAPI/XDSM */
|
||||
|
||||
#define O_PATH 020000000
|
||||
#define __O_TMPFILE 040000000
|
||||
|
||||
#define F_GETLK64 8
|
||||
#define F_SETLK64 9
|
||||
|
|
|
@ -342,13 +342,13 @@ unsigned long thread_saved_pc(struct task_struct *t)
|
|||
asmlinkage int sys_execve(struct pt_regs *regs)
|
||||
{
|
||||
int error;
|
||||
char *filename;
|
||||
struct filename *filename;
|
||||
|
||||
filename = getname((const char __user *) regs->gr[26]);
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
error = do_execve(filename,
|
||||
error = do_execve(filename->name,
|
||||
(const char __user *const __user *) regs->gr[25],
|
||||
(const char __user *const __user *) regs->gr[24],
|
||||
regs);
|
||||
|
|
|
@ -60,14 +60,14 @@
|
|||
asmlinkage int sys32_execve(struct pt_regs *regs)
|
||||
{
|
||||
int error;
|
||||
char *filename;
|
||||
struct filename *filename;
|
||||
|
||||
DBG(("sys32_execve(%p) r26 = 0x%lx\n", regs, regs->gr[26]));
|
||||
filename = getname((const char __user *) regs->gr[26]);
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
error = compat_do_execve(filename, compat_ptr(regs->gr[25]),
|
||||
error = compat_do_execve(filename->name, compat_ptr(regs->gr[25]),
|
||||
compat_ptr(regs->gr[24]), regs);
|
||||
putname(filename);
|
||||
out:
|
||||
|
|
|
@ -55,7 +55,6 @@ CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
|
||||
|
|
|
@ -91,7 +91,6 @@ CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TPROXY=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
|
|
|
@ -66,7 +66,6 @@ CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TPROXY=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
|
|
|
@ -167,7 +167,6 @@ CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TPROXY=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_SECMARK=m
|
||||
|
|
|
@ -70,7 +70,7 @@ static long do_spu_create(const char __user *pathname, unsigned int flags,
|
|||
ret = PTR_ERR(dentry);
|
||||
if (!IS_ERR(dentry)) {
|
||||
ret = spufs_create(&path, dentry, flags, mode, neighbor);
|
||||
path_put(&path);
|
||||
done_path_create(&path, dentry);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -92,14 +92,14 @@ asmlinkage long
|
|||
score_execve(struct pt_regs *regs)
|
||||
{
|
||||
int error;
|
||||
char *filename;
|
||||
struct filename *filename;
|
||||
|
||||
filename = getname((char __user*)regs->regs[4]);
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
return error;
|
||||
|
||||
error = do_execve(filename,
|
||||
error = do_execve(filename->name,
|
||||
(const char __user *const __user *)regs->regs[5],
|
||||
(const char __user *const __user *)regs->regs[6],
|
||||
regs);
|
||||
|
|
|
@ -302,14 +302,14 @@ asmlinkage int sys_execve(const char __user *ufilename,
|
|||
{
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
int error;
|
||||
char *filename;
|
||||
struct filename *filename;
|
||||
|
||||
filename = getname(ufilename);
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
|
||||
error = do_execve(filename, uargv, uenvp, regs);
|
||||
error = do_execve(filename->name, uargv, uenvp, regs);
|
||||
putname(filename);
|
||||
out:
|
||||
return error;
|
||||
|
|
|
@ -490,14 +490,14 @@ asmlinkage int sys_execve(const char *ufilename, char **uargv,
|
|||
struct pt_regs *pregs)
|
||||
{
|
||||
int error;
|
||||
char *filename;
|
||||
struct filename *filename;
|
||||
|
||||
filename = getname((char __user *)ufilename);
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
|
||||
error = do_execve(filename,
|
||||
error = do_execve(filename->name,
|
||||
(const char __user *const __user *)uargv,
|
||||
(const char __user *const __user *)uenvp,
|
||||
pregs);
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#define O_SYNC (__O_SYNC|O_DSYNC)
|
||||
|
||||
#define O_PATH 0x1000000
|
||||
#define __O_TMPFILE 0x2000000
|
||||
|
||||
#define F_GETOWN 5 /* for sockets. */
|
||||
#define F_SETOWN 6 /* for sockets. */
|
||||
|
|
|
@ -625,7 +625,7 @@ int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs)
|
|||
asmlinkage int sparc_execve(struct pt_regs *regs)
|
||||
{
|
||||
int error, base = 0;
|
||||
char *filename;
|
||||
struct filename *filename;
|
||||
|
||||
/* Check for indirect call. */
|
||||
if(regs->u_regs[UREG_G1] == 0)
|
||||
|
@ -635,7 +635,7 @@ asmlinkage int sparc_execve(struct pt_regs *regs)
|
|||
error = PTR_ERR(filename);
|
||||
if(IS_ERR(filename))
|
||||
goto out;
|
||||
error = do_execve(filename,
|
||||
error = do_execve(filename->name,
|
||||
(const char __user *const __user *)
|
||||
regs->u_regs[base + UREG_I1],
|
||||
(const char __user *const __user *)
|
||||
|
|
|
@ -722,7 +722,7 @@ EXPORT_SYMBOL(dump_fpu);
|
|||
asmlinkage int sparc_execve(struct pt_regs *regs)
|
||||
{
|
||||
int error, base = 0;
|
||||
char *filename;
|
||||
struct filename *filename;
|
||||
|
||||
/* User register window flush is done by entry.S */
|
||||
|
||||
|
@ -734,7 +734,7 @@ asmlinkage int sparc_execve(struct pt_regs *regs)
|
|||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
error = do_execve(filename,
|
||||
error = do_execve(filename->name,
|
||||
(const char __user *const __user *)
|
||||
regs->u_regs[base + UREG_I1],
|
||||
(const char __user *const __user *)
|
||||
|
|
|
@ -403,7 +403,7 @@ asmlinkage long compat_sys_rt_sigaction(int sig,
|
|||
asmlinkage long sparc32_execve(struct pt_regs *regs)
|
||||
{
|
||||
int error, base = 0;
|
||||
char *filename;
|
||||
struct filename *filename;
|
||||
|
||||
/* User register window flush is done by entry.S */
|
||||
|
||||
|
@ -416,7 +416,7 @@ asmlinkage long sparc32_execve(struct pt_regs *regs)
|
|||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
|
||||
error = compat_do_execve(filename,
|
||||
error = compat_do_execve(filename->name,
|
||||
compat_ptr(regs->u_regs[base + UREG_I1]),
|
||||
compat_ptr(regs->u_regs[base + UREG_I2]), regs);
|
||||
|
||||
|
|
|
@ -134,7 +134,6 @@ CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TEE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TPROXY=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
|
|
|
@ -132,7 +132,6 @@ CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
|
|||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TEE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TPROXY=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
|
|
|
@ -619,13 +619,13 @@ SYSCALL_DEFINE4(execve, const char __user *, path,
|
|||
struct pt_regs *, regs)
|
||||
{
|
||||
long error;
|
||||
char *filename;
|
||||
struct filename *filename;
|
||||
|
||||
filename = getname(path);
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
error = do_execve(filename, argv, envp, regs);
|
||||
error = do_execve(filename->name, argv, envp, regs);
|
||||
putname(filename);
|
||||
if (error == 0)
|
||||
single_step_execve();
|
||||
|
@ -640,13 +640,13 @@ long compat_sys_execve(const char __user *path,
|
|||
struct pt_regs *regs)
|
||||
{
|
||||
long error;
|
||||
char *filename;
|
||||
struct filename *filename;
|
||||
|
||||
filename = getname(path);
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
error = compat_do_execve(filename, argv, envp, regs);
|
||||
error = compat_do_execve(filename->name, argv, envp, regs);
|
||||
putname(filename);
|
||||
if (error == 0)
|
||||
single_step_execve();
|
||||
|
|
|
@ -51,13 +51,13 @@ asmlinkage long __sys_execve(const char __user *filename,
|
|||
struct pt_regs *regs)
|
||||
{
|
||||
int error;
|
||||
char *fn;
|
||||
struct filename *fn;
|
||||
|
||||
fn = getname(filename);
|
||||
error = PTR_ERR(fn);
|
||||
if (IS_ERR(fn))
|
||||
goto out;
|
||||
error = do_execve(fn, argv, envp, regs);
|
||||
error = do_execve(fn->name, argv, envp, regs);
|
||||
putname(fn);
|
||||
out:
|
||||
return error;
|
||||
|
|
|
@ -325,13 +325,13 @@ long xtensa_execve(const char __user *name,
|
|||
struct pt_regs *regs)
|
||||
{
|
||||
long error;
|
||||
char * filename;
|
||||
struct filename *filename;
|
||||
|
||||
filename = getname(name);
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
error = do_execve(filename, argv, envp, regs);
|
||||
error = do_execve(filename->name, argv, envp, regs);
|
||||
putname(filename);
|
||||
out:
|
||||
return error;
|
||||
|
|
|
@ -156,9 +156,7 @@ static int dev_mkdir(const char *name, umode_t mode)
|
|||
if (!err)
|
||||
/* mark as kernel-created inode */
|
||||
dentry->d_inode->i_private = &thread;
|
||||
dput(dentry);
|
||||
mutex_unlock(&path.dentry->d_inode->i_mutex);
|
||||
path_put(&path);
|
||||
done_path_create(&path, dentry);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -218,10 +216,7 @@ static int handle_create(const char *nodename, umode_t mode, struct device *dev)
|
|||
/* mark as kernel-created inode */
|
||||
dentry->d_inode->i_private = &thread;
|
||||
}
|
||||
dput(dentry);
|
||||
|
||||
mutex_unlock(&path.dentry->d_inode->i_mutex);
|
||||
path_put(&path);
|
||||
done_path_create(&path, dentry);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
@ -144,7 +144,7 @@ extern void v9fs_session_close(struct v9fs_session_info *v9ses);
|
|||
extern void v9fs_session_cancel(struct v9fs_session_info *v9ses);
|
||||
extern void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses);
|
||||
extern struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
|
||||
struct nameidata *nameidata);
|
||||
unsigned int flags);
|
||||
extern int v9fs_vfs_unlink(struct inode *i, struct dentry *d);
|
||||
extern int v9fs_vfs_rmdir(struct inode *i, struct dentry *d);
|
||||
extern int v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
|
|
|
@ -100,13 +100,13 @@ static void v9fs_dentry_release(struct dentry *dentry)
|
|||
}
|
||||
}
|
||||
|
||||
static int v9fs_lookup_revalidate(struct dentry *dentry, struct nameidata *nd)
|
||||
static int v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
|
||||
{
|
||||
struct p9_fid *fid;
|
||||
struct inode *inode;
|
||||
struct v9fs_inode *v9inode;
|
||||
|
||||
if (nd->flags & LOOKUP_RCU)
|
||||
if (flags & LOOKUP_RCU)
|
||||
return -ECHILD;
|
||||
|
||||
inode = dentry->d_inode;
|
||||
|
|
|
@ -711,88 +711,34 @@ error:
|
|||
}
|
||||
|
||||
/**
|
||||
* v9fs_vfs_create - VFS hook to create files
|
||||
* v9fs_vfs_create - VFS hook to create a regular file
|
||||
*
|
||||
* open(.., O_CREAT) is handled in v9fs_vfs_atomic_open(). This is only called
|
||||
* for mknod(2).
|
||||
*
|
||||
* @dir: directory inode that is being created
|
||||
* @dentry: dentry that is being deleted
|
||||
* @mode: create permissions
|
||||
* @nd: path information
|
||||
*
|
||||
*/
|
||||
|
||||
static int
|
||||
v9fs_vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
|
||||
struct nameidata *nd)
|
||||
bool excl)
|
||||
{
|
||||
int err;
|
||||
u32 perm;
|
||||
int flags;
|
||||
struct file *filp;
|
||||
struct v9fs_inode *v9inode;
|
||||
struct v9fs_session_info *v9ses;
|
||||
struct p9_fid *fid, *inode_fid;
|
||||
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
|
||||
u32 perm = unixmode2p9mode(v9ses, mode);
|
||||
struct p9_fid *fid;
|
||||
|
||||
err = 0;
|
||||
fid = NULL;
|
||||
v9ses = v9fs_inode2v9ses(dir);
|
||||
perm = unixmode2p9mode(v9ses, mode);
|
||||
if (nd)
|
||||
flags = nd->intent.open.flags;
|
||||
else
|
||||
flags = O_RDWR;
|
||||
|
||||
fid = v9fs_create(v9ses, dir, dentry, NULL, perm,
|
||||
v9fs_uflags2omode(flags,
|
||||
v9fs_proto_dotu(v9ses)));
|
||||
if (IS_ERR(fid)) {
|
||||
err = PTR_ERR(fid);
|
||||
fid = NULL;
|
||||
goto error;
|
||||
}
|
||||
/* P9_OEXCL? */
|
||||
fid = v9fs_create(v9ses, dir, dentry, NULL, perm, P9_ORDWR);
|
||||
if (IS_ERR(fid))
|
||||
return PTR_ERR(fid);
|
||||
|
||||
v9fs_invalidate_inode_attr(dir);
|
||||
/* if we are opening a file, assign the open fid to the file */
|
||||
if (nd) {
|
||||
v9inode = V9FS_I(dentry->d_inode);
|
||||
mutex_lock(&v9inode->v_mutex);
|
||||
if (v9ses->cache && !v9inode->writeback_fid &&
|
||||
((flags & O_ACCMODE) != O_RDONLY)) {
|
||||
/*
|
||||
* clone a fid and add it to writeback_fid
|
||||
* we do it during open time instead of
|
||||
* page dirty time via write_begin/page_mkwrite
|
||||
* because we want write after unlink usecase
|
||||
* to work.
|
||||
*/
|
||||
inode_fid = v9fs_writeback_fid(dentry);
|
||||
if (IS_ERR(inode_fid)) {
|
||||
err = PTR_ERR(inode_fid);
|
||||
mutex_unlock(&v9inode->v_mutex);
|
||||
goto error;
|
||||
}
|
||||
v9inode->writeback_fid = (void *) inode_fid;
|
||||
}
|
||||
mutex_unlock(&v9inode->v_mutex);
|
||||
filp = lookup_instantiate_filp(nd, dentry, generic_file_open);
|
||||
if (IS_ERR(filp)) {
|
||||
err = PTR_ERR(filp);
|
||||
goto error;
|
||||
}
|
||||
|
||||
filp->private_data = fid;
|
||||
#ifdef CONFIG_9P_FSCACHE
|
||||
if (v9ses->cache)
|
||||
v9fs_cache_inode_set_cookie(dentry->d_inode, filp);
|
||||
#endif
|
||||
} else
|
||||
p9_client_clunk(fid);
|
||||
p9_client_clunk(fid);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (fid)
|
||||
p9_client_clunk(fid);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -838,7 +784,7 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
|
|||
*/
|
||||
|
||||
struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
|
||||
struct nameidata *nameidata)
|
||||
unsigned int flags)
|
||||
{
|
||||
struct dentry *res;
|
||||
struct super_block *sb;
|
||||
|
@ -848,8 +794,8 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
|
|||
char *name;
|
||||
int result = 0;
|
||||
|
||||
p9_debug(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n",
|
||||
dir, dentry->d_name.name, dentry, nameidata);
|
||||
p9_debug(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p flags: %x\n",
|
||||
dir, dentry->d_name.name, dentry, flags);
|
||||
|
||||
if (dentry->d_name.len > NAME_MAX)
|
||||
return ERR_PTR(-ENAMETOOLONG);
|
||||
|
@ -909,6 +855,86 @@ error:
|
|||
return ERR_PTR(result);
|
||||
}
|
||||
|
||||
static int
|
||||
v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
|
||||
struct file *file, unsigned flags, umode_t mode,
|
||||
int *opened)
|
||||
{
|
||||
int err;
|
||||
u32 perm;
|
||||
struct v9fs_inode *v9inode;
|
||||
struct v9fs_session_info *v9ses;
|
||||
struct p9_fid *fid, *inode_fid;
|
||||
struct dentry *res = NULL;
|
||||
|
||||
if (d_unhashed(dentry)) {
|
||||
res = v9fs_vfs_lookup(dir, dentry, 0);
|
||||
if (IS_ERR(res))
|
||||
return PTR_ERR(res);
|
||||
|
||||
if (res)
|
||||
dentry = res;
|
||||
}
|
||||
|
||||
/* Only creates */
|
||||
if (!(flags & O_CREAT) || dentry->d_inode)
|
||||
return finish_no_open(file, res);
|
||||
|
||||
err = 0;
|
||||
fid = NULL;
|
||||
v9ses = v9fs_inode2v9ses(dir);
|
||||
perm = unixmode2p9mode(v9ses, mode);
|
||||
fid = v9fs_create(v9ses, dir, dentry, NULL, perm,
|
||||
v9fs_uflags2omode(flags,
|
||||
v9fs_proto_dotu(v9ses)));
|
||||
if (IS_ERR(fid)) {
|
||||
err = PTR_ERR(fid);
|
||||
fid = NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
v9fs_invalidate_inode_attr(dir);
|
||||
v9inode = V9FS_I(dentry->d_inode);
|
||||
mutex_lock(&v9inode->v_mutex);
|
||||
if (v9ses->cache && !v9inode->writeback_fid &&
|
||||
((flags & O_ACCMODE) != O_RDONLY)) {
|
||||
/*
|
||||
* clone a fid and add it to writeback_fid
|
||||
* we do it during open time instead of
|
||||
* page dirty time via write_begin/page_mkwrite
|
||||
* because we want write after unlink usecase
|
||||
* to work.
|
||||
*/
|
||||
inode_fid = v9fs_writeback_fid(dentry);
|
||||
if (IS_ERR(inode_fid)) {
|
||||
err = PTR_ERR(inode_fid);
|
||||
mutex_unlock(&v9inode->v_mutex);
|
||||
goto error;
|
||||
}
|
||||
v9inode->writeback_fid = (void *) inode_fid;
|
||||
}
|
||||
mutex_unlock(&v9inode->v_mutex);
|
||||
err = finish_open(file, dentry, generic_file_open, opened);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
file->private_data = fid;
|
||||
#ifdef CONFIG_9P_FSCACHE
|
||||
if (v9ses->cache)
|
||||
v9fs_cache_inode_set_cookie(dentry->d_inode, file);
|
||||
#endif
|
||||
|
||||
*opened |= FILE_CREATED;
|
||||
out:
|
||||
dput(res);
|
||||
return err;
|
||||
|
||||
error:
|
||||
if (fid)
|
||||
p9_client_clunk(fid);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_vfs_unlink - VFS unlink hook to delete an inode
|
||||
* @i: inode that is being unlinked
|
||||
|
@ -1487,6 +1513,7 @@ out:
|
|||
static const struct inode_operations v9fs_dir_inode_operations_dotu = {
|
||||
.create = v9fs_vfs_create,
|
||||
.lookup = v9fs_vfs_lookup,
|
||||
.atomic_open = v9fs_vfs_atomic_open,
|
||||
.symlink = v9fs_vfs_symlink,
|
||||
.link = v9fs_vfs_link,
|
||||
.unlink = v9fs_vfs_unlink,
|
||||
|
@ -1501,6 +1528,7 @@ static const struct inode_operations v9fs_dir_inode_operations_dotu = {
|
|||
static const struct inode_operations v9fs_dir_inode_operations = {
|
||||
.create = v9fs_vfs_create,
|
||||
.lookup = v9fs_vfs_lookup,
|
||||
.atomic_open = v9fs_vfs_atomic_open,
|
||||
.unlink = v9fs_vfs_unlink,
|
||||
.mkdir = v9fs_vfs_mkdir,
|
||||
.rmdir = v9fs_vfs_rmdir,
|
||||
|
|
|
@ -247,20 +247,25 @@ int v9fs_open_to_dotl_flags(int flags)
|
|||
* @dir: directory inode that is being created
|
||||
* @dentry: dentry that is being deleted
|
||||
* @mode: create permissions
|
||||
* @nd: path information
|
||||
*
|
||||
*/
|
||||
|
||||
static int
|
||||
v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
|
||||
struct nameidata *nd)
|
||||
bool excl)
|
||||
{
|
||||
return v9fs_vfs_mknod_dotl(dir, dentry, omode, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
|
||||
struct file *file, unsigned flags, umode_t omode,
|
||||
int *opened)
|
||||
{
|
||||
int err = 0;
|
||||
gid_t gid;
|
||||
int flags;
|
||||
umode_t mode;
|
||||
char *name = NULL;
|
||||
struct file *filp;
|
||||
struct p9_qid qid;
|
||||
struct inode *inode;
|
||||
struct p9_fid *fid = NULL;
|
||||
|
@ -268,18 +273,22 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
|
|||
struct p9_fid *dfid, *ofid, *inode_fid;
|
||||
struct v9fs_session_info *v9ses;
|
||||
struct posix_acl *pacl = NULL, *dacl = NULL;
|
||||
struct dentry *res = NULL;
|
||||
|
||||
if (d_unhashed(dentry)) {
|
||||
res = v9fs_vfs_lookup(dir, dentry, 0);
|
||||
if (IS_ERR(res))
|
||||
return PTR_ERR(res);
|
||||
|
||||
if (res)
|
||||
dentry = res;
|
||||
}
|
||||
|
||||
/* Only creates */
|
||||
if (!(flags & O_CREAT) || dentry->d_inode)
|
||||
return finish_no_open(file, res);
|
||||
|
||||
v9ses = v9fs_inode2v9ses(dir);
|
||||
if (nd)
|
||||
flags = nd->intent.open.flags;
|
||||
else {
|
||||
/*
|
||||
* create call without LOOKUP_OPEN is due
|
||||
* to mknod of regular files. So use mknod
|
||||
* operation.
|
||||
*/
|
||||
return v9fs_vfs_mknod_dotl(dir, dentry, omode, 0);
|
||||
}
|
||||
|
||||
name = (char *) dentry->d_name.name;
|
||||
p9_debug(P9_DEBUG_VFS, "name:%s flags:0x%x mode:0x%hx\n",
|
||||
|
@ -289,7 +298,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
|
|||
if (IS_ERR(dfid)) {
|
||||
err = PTR_ERR(dfid);
|
||||
p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
|
||||
return err;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* clone a fid to use for creation */
|
||||
|
@ -297,7 +306,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
|
|||
if (IS_ERR(ofid)) {
|
||||
err = PTR_ERR(ofid);
|
||||
p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
|
||||
return err;
|
||||
goto out;
|
||||
}
|
||||
|
||||
gid = v9fs_get_fsgid_for_create(dir);
|
||||
|
@ -362,17 +371,18 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
|
|||
}
|
||||
mutex_unlock(&v9inode->v_mutex);
|
||||
/* Since we are opening a file, assign the open fid to the file */
|
||||
filp = lookup_instantiate_filp(nd, dentry, generic_file_open);
|
||||
if (IS_ERR(filp)) {
|
||||
err = PTR_ERR(filp);
|
||||
err = finish_open(file, dentry, generic_file_open, opened);
|
||||
if (err)
|
||||
goto err_clunk_old_fid;
|
||||
}
|
||||
filp->private_data = ofid;
|
||||
file->private_data = ofid;
|
||||
#ifdef CONFIG_9P_FSCACHE
|
||||
if (v9ses->cache)
|
||||
v9fs_cache_inode_set_cookie(inode, filp);
|
||||
v9fs_cache_inode_set_cookie(inode, file);
|
||||
#endif
|
||||
return 0;
|
||||
*opened |= FILE_CREATED;
|
||||
out:
|
||||
dput(res);
|
||||
return err;
|
||||
|
||||
error:
|
||||
if (fid)
|
||||
|
@ -381,7 +391,7 @@ err_clunk_old_fid:
|
|||
if (ofid)
|
||||
p9_client_clunk(ofid);
|
||||
v9fs_set_create_acl(NULL, &dacl, &pacl);
|
||||
return err;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -999,6 +1009,7 @@ out:
|
|||
|
||||
const struct inode_operations v9fs_dir_inode_operations_dotl = {
|
||||
.create = v9fs_vfs_create_dotl,
|
||||
.atomic_open = v9fs_vfs_atomic_open_dotl,
|
||||
.lookup = v9fs_vfs_lookup,
|
||||
.link = v9fs_vfs_link_dotl,
|
||||
.symlink = v9fs_vfs_symlink_dotl,
|
||||
|
|
|
@ -266,7 +266,7 @@ const struct dentry_operations adfs_dentry_operations = {
|
|||
};
|
||||
|
||||
static struct dentry *
|
||||
adfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
|
||||
adfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
|
||||
{
|
||||
struct inode *inode = NULL;
|
||||
struct object_info obj;
|
||||
|
|
|
@ -154,9 +154,9 @@ extern void affs_free_bitmap(struct super_block *sb);
|
|||
/* namei.c */
|
||||
|
||||
extern int affs_hash_name(struct super_block *sb, const u8 *name, unsigned int len);
|
||||
extern struct dentry *affs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *);
|
||||
extern struct dentry *affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int);
|
||||
extern int affs_unlink(struct inode *dir, struct dentry *dentry);
|
||||
extern int affs_create(struct inode *dir, struct dentry *dentry, umode_t mode, struct nameidata *);
|
||||
extern int affs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool);
|
||||
extern int affs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
|
||||
extern int affs_rmdir(struct inode *dir, struct dentry *dentry);
|
||||
extern int affs_link(struct dentry *olddentry, struct inode *dir,
|
||||
|
|
|
@ -211,7 +211,7 @@ affs_find_entry(struct inode *dir, struct dentry *dentry)
|
|||
}
|
||||
|
||||
struct dentry *
|
||||
affs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
|
||||
affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
|
||||
{
|
||||
struct super_block *sb = dir->i_sb;
|
||||
struct buffer_head *bh;
|
||||
|
@ -255,7 +255,7 @@ affs_unlink(struct inode *dir, struct dentry *dentry)
|
|||
}
|
||||
|
||||
int
|
||||
affs_create(struct inode *dir, struct dentry *dentry, umode_t mode, struct nameidata *nd)
|
||||
affs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool excl)
|
||||
{
|
||||
struct super_block *sb = dir->i_sb;
|
||||
struct inode *inode;
|
||||
|
|
14
fs/afs/dir.c
14
fs/afs/dir.c
|
@ -20,16 +20,16 @@
|
|||
#include "internal.h"
|
||||
|
||||
static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
|
||||
struct nameidata *nd);
|
||||
unsigned int flags);
|
||||
static int afs_dir_open(struct inode *inode, struct file *file);
|
||||
static int afs_readdir(struct file *file, void *dirent, filldir_t filldir);
|
||||
static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd);
|
||||
static int afs_d_revalidate(struct dentry *dentry, unsigned int flags);
|
||||
static int afs_d_delete(const struct dentry *dentry);
|
||||
static void afs_d_release(struct dentry *dentry);
|
||||
static int afs_lookup_filldir(void *_cookie, const char *name, int nlen,
|
||||
loff_t fpos, u64 ino, unsigned dtype);
|
||||
static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
|
||||
struct nameidata *nd);
|
||||
bool excl);
|
||||
static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
|
||||
static int afs_rmdir(struct inode *dir, struct dentry *dentry);
|
||||
static int afs_unlink(struct inode *dir, struct dentry *dentry);
|
||||
|
@ -516,7 +516,7 @@ out:
|
|||
* look up an entry in a directory
|
||||
*/
|
||||
static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
|
||||
struct nameidata *nd)
|
||||
unsigned int flags)
|
||||
{
|
||||
struct afs_vnode *vnode;
|
||||
struct afs_fid fid;
|
||||
|
@ -598,7 +598,7 @@ success:
|
|||
* - NOTE! the hit can be a negative hit too, so we can't assume we have an
|
||||
* inode
|
||||
*/
|
||||
static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
|
||||
static int afs_d_revalidate(struct dentry *dentry, unsigned int flags)
|
||||
{
|
||||
struct afs_vnode *vnode, *dir;
|
||||
struct afs_fid uninitialized_var(fid);
|
||||
|
@ -607,7 +607,7 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
|
|||
void *dir_version;
|
||||
int ret;
|
||||
|
||||
if (nd->flags & LOOKUP_RCU)
|
||||
if (flags & LOOKUP_RCU)
|
||||
return -ECHILD;
|
||||
|
||||
vnode = AFS_FS_I(dentry->d_inode);
|
||||
|
@ -949,7 +949,7 @@ error:
|
|||
* create a regular file on an AFS filesystem
|
||||
*/
|
||||
static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
|
||||
struct nameidata *nd)
|
||||
bool excl)
|
||||
{
|
||||
struct afs_file_status status;
|
||||
struct afs_callback cb;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
static struct dentry *afs_mntpt_lookup(struct inode *dir,
|
||||
struct dentry *dentry,
|
||||
struct nameidata *nd);
|
||||
unsigned int flags);
|
||||
static int afs_mntpt_open(struct inode *inode, struct file *file);
|
||||
static void afs_mntpt_expiry_timed_out(struct work_struct *work);
|
||||
|
||||
|
@ -104,7 +104,7 @@ out:
|
|||
*/
|
||||
static struct dentry *afs_mntpt_lookup(struct inode *dir,
|
||||
struct dentry *dentry,
|
||||
struct nameidata *nd)
|
||||
unsigned int flags)
|
||||
{
|
||||
_enter("%p,%p{%p{%s},%s}",
|
||||
dir,
|
||||
|
|
|
@ -32,7 +32,7 @@ static long autofs4_root_ioctl(struct file *,unsigned int,unsigned long);
|
|||
static long autofs4_root_compat_ioctl(struct file *,unsigned int,unsigned long);
|
||||
#endif
|
||||
static int autofs4_dir_open(struct inode *inode, struct file *file);
|
||||
static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *);
|
||||
static struct dentry *autofs4_lookup(struct inode *,struct dentry *, unsigned int);
|
||||
static struct vfsmount *autofs4_d_automount(struct path *);
|
||||
static int autofs4_d_manage(struct dentry *, bool);
|
||||
static void autofs4_dentry_release(struct dentry *);
|
||||
|
@ -460,7 +460,7 @@ int autofs4_d_manage(struct dentry *dentry, bool rcu_walk)
|
|||
}
|
||||
|
||||
/* Lookups in the root directory */
|
||||
static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
|
||||
static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
|
||||
{
|
||||
struct autofs_sb_info *sbi;
|
||||
struct autofs_info *ino;
|
||||
|
|
|
@ -173,13 +173,13 @@ static const struct file_operations bad_file_ops =
|
|||
};
|
||||
|
||||
static int bad_inode_create (struct inode *dir, struct dentry *dentry,
|
||||
umode_t mode, struct nameidata *nd)
|
||||
umode_t mode, bool excl)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static struct dentry *bad_inode_lookup(struct inode *dir,
|
||||
struct dentry *dentry, struct nameidata *nd)
|
||||
struct dentry *dentry, unsigned int flags)
|
||||
{
|
||||
return ERR_PTR(-EIO);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ static int befs_readdir(struct file *, void *, filldir_t);
|
|||
static int befs_get_block(struct inode *, sector_t, struct buffer_head *, int);
|
||||
static int befs_readpage(struct file *file, struct page *page);
|
||||
static sector_t befs_bmap(struct address_space *mapping, sector_t block);
|
||||
static struct dentry *befs_lookup(struct inode *, struct dentry *, struct nameidata *);
|
||||
static struct dentry *befs_lookup(struct inode *, struct dentry *, unsigned int);
|
||||
static struct inode *befs_iget(struct super_block *, unsigned long);
|
||||
static struct inode *befs_alloc_inode(struct super_block *sb);
|
||||
static void befs_destroy_inode(struct inode *inode);
|
||||
|
@ -159,7 +159,7 @@ befs_get_block(struct inode *inode, sector_t block,
|
|||
}
|
||||
|
||||
static struct dentry *
|
||||
befs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
|
||||
befs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
|
||||
{
|
||||
struct inode *inode = NULL;
|
||||
struct super_block *sb = dir->i_sb;
|
||||
|
|
|
@ -85,7 +85,7 @@ const struct file_operations bfs_dir_operations = {
|
|||
extern void dump_imap(const char *, struct super_block *);
|
||||
|
||||
static int bfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
|
||||
struct nameidata *nd)
|
||||
bool excl)
|
||||
{
|
||||
int err;
|
||||
struct inode *inode;
|
||||
|
@ -133,7 +133,7 @@ static int bfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
|
|||
}
|
||||
|
||||
static struct dentry *bfs_lookup(struct inode *dir, struct dentry *dentry,
|
||||
struct nameidata *nd)
|
||||
unsigned int flags)
|
||||
{
|
||||
struct inode *inode = NULL;
|
||||
struct buffer_head *bh;
|
||||
|
|
|
@ -4187,7 +4187,7 @@ static void btrfs_dentry_release(struct dentry *dentry)
|
|||
}
|
||||
|
||||
static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
|
||||
struct nameidata *nd)
|
||||
unsigned int flags)
|
||||
{
|
||||
struct dentry *ret;
|
||||
|
||||
|
@ -4860,7 +4860,7 @@ out_unlock:
|
|||
}
|
||||
|
||||
static int btrfs_create(struct inode *dir, struct dentry *dentry,
|
||||
umode_t mode, struct nameidata *nd)
|
||||
umode_t mode, bool excl)
|
||||
{
|
||||
struct btrfs_trans_handle *trans;
|
||||
struct btrfs_root *root = BTRFS_I(dir)->root;
|
||||
|
|
|
@ -567,7 +567,7 @@ lookup_again:
|
|||
if (ret < 0)
|
||||
goto create_error;
|
||||
start = jiffies;
|
||||
ret = vfs_create(dir->d_inode, next, S_IFREG, NULL);
|
||||
ret = vfs_create(dir->d_inode, next, S_IFREG, true);
|
||||
cachefiles_hist(cachefiles_create_histogram, start);
|
||||
if (ret < 0)
|
||||
goto create_error;
|
||||
|
|
|
@ -576,7 +576,7 @@ static int is_root_ceph_dentry(struct inode *inode, struct dentry *dentry)
|
|||
* the MDS so that it gets our 'caps wanted' value in a single op.
|
||||
*/
|
||||
static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,
|
||||
struct nameidata *nd)
|
||||
unsigned int flags)
|
||||
{
|
||||
struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb);
|
||||
struct ceph_mds_client *mdsc = fsc->mdsc;
|
||||
|
@ -594,14 +594,6 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,
|
|||
if (err < 0)
|
||||
return ERR_PTR(err);
|
||||
|
||||
/* open (but not create!) intent? */
|
||||
if (nd &&
|
||||
(nd->flags & LOOKUP_OPEN) &&
|
||||
!(nd->intent.open.flags & O_CREAT)) {
|
||||
int mode = nd->intent.open.create_mode & ~current->fs->umask;
|
||||
return ceph_lookup_open(dir, dentry, nd, mode, 1);
|
||||
}
|
||||
|
||||
/* can we conclude ENOENT locally? */
|
||||
if (dentry->d_inode == NULL) {
|
||||
struct ceph_inode_info *ci = ceph_inode(dir);
|
||||
|
@ -642,13 +634,51 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,
|
|||
return dentry;
|
||||
}
|
||||
|
||||
int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
|
||||
struct file *file, unsigned flags, umode_t mode,
|
||||
int *opened)
|
||||
{
|
||||
int err;
|
||||
struct dentry *res = NULL;
|
||||
|
||||
if (!(flags & O_CREAT)) {
|
||||
if (dentry->d_name.len > NAME_MAX)
|
||||
return -ENAMETOOLONG;
|
||||
|
||||
err = ceph_init_dentry(dentry);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return ceph_lookup_open(dir, dentry, file, flags, mode, opened);
|
||||
}
|
||||
|
||||
if (d_unhashed(dentry)) {
|
||||
res = ceph_lookup(dir, dentry, 0);
|
||||
if (IS_ERR(res))
|
||||
return PTR_ERR(res);
|
||||
|
||||
if (res)
|
||||
dentry = res;
|
||||
}
|
||||
|
||||
/* We don't deal with positive dentries here */
|
||||
if (dentry->d_inode)
|
||||
return finish_no_open(file, res);
|
||||
|
||||
*opened |= FILE_CREATED;
|
||||
err = ceph_lookup_open(dir, dentry, file, flags, mode, opened);
|
||||
dput(res);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we do a create but get no trace back from the MDS, follow up with
|
||||
* a lookup (the VFS expects us to link up the provided dentry).
|
||||
*/
|
||||
int ceph_handle_notrace_create(struct inode *dir, struct dentry *dentry)
|
||||
{
|
||||
struct dentry *result = ceph_lookup(dir, dentry, NULL);
|
||||
struct dentry *result = ceph_lookup(dir, dentry, 0);
|
||||
|
||||
if (result && !IS_ERR(result)) {
|
||||
/*
|
||||
|
@ -700,25 +730,9 @@ static int ceph_mknod(struct inode *dir, struct dentry *dentry,
|
|||
}
|
||||
|
||||
static int ceph_create(struct inode *dir, struct dentry *dentry, umode_t mode,
|
||||
struct nameidata *nd)
|
||||
bool excl)
|
||||
{
|
||||
dout("create in dir %p dentry %p name '%.*s'\n",
|
||||
dir, dentry, dentry->d_name.len, dentry->d_name.name);
|
||||
|
||||
if (ceph_snap(dir) != CEPH_NOSNAP)
|
||||
return -EROFS;
|
||||
|
||||
if (nd) {
|
||||
BUG_ON((nd->flags & LOOKUP_OPEN) == 0);
|
||||
dentry = ceph_lookup_open(dir, dentry, nd, mode, 0);
|
||||
/* hrm, what should i do here if we get aliased? */
|
||||
if (IS_ERR(dentry))
|
||||
return PTR_ERR(dentry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* fall back to mknod */
|
||||
return ceph_mknod(dir, dentry, (mode & ~S_IFMT) | S_IFREG, 0);
|
||||
return ceph_mknod(dir, dentry, mode, 0);
|
||||
}
|
||||
|
||||
static int ceph_symlink(struct inode *dir, struct dentry *dentry,
|
||||
|
@ -1028,12 +1042,12 @@ static int dir_lease_is_valid(struct inode *dir, struct dentry *dentry)
|
|||
/*
|
||||
* Check if cached dentry can be trusted.
|
||||
*/
|
||||
static int ceph_d_revalidate(struct dentry *dentry, struct nameidata *nd)
|
||||
static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags)
|
||||
{
|
||||
int valid = 0;
|
||||
struct inode *dir;
|
||||
|
||||
if (nd && nd->flags & LOOKUP_RCU)
|
||||
if (flags & LOOKUP_RCU)
|
||||
return -ECHILD;
|
||||
|
||||
dout("d_revalidate %p '%.*s' inode %p offset %lld\n", dentry,
|
||||
|
@ -1080,7 +1094,7 @@ static void ceph_d_release(struct dentry *dentry)
|
|||
}
|
||||
|
||||
static int ceph_snapdir_d_revalidate(struct dentry *dentry,
|
||||
struct nameidata *nd)
|
||||
unsigned int flags)
|
||||
{
|
||||
/*
|
||||
* Eventually, we'll want to revalidate snapped metadata
|
||||
|
@ -1357,6 +1371,7 @@ const struct inode_operations ceph_dir_iops = {
|
|||
.rmdir = ceph_unlink,
|
||||
.rename = ceph_rename,
|
||||
.create = ceph_create,
|
||||
.atomic_open = ceph_atomic_open,
|
||||
};
|
||||
|
||||
const struct dentry_operations ceph_dentry_ops = {
|
||||
|
|
|
@ -214,22 +214,15 @@ out:
|
|||
* may_open() fails, the struct *file gets cleaned up (i.e.
|
||||
* ceph_release gets called). So fear not!
|
||||
*/
|
||||
/*
|
||||
* flags
|
||||
* path_lookup_open -> LOOKUP_OPEN
|
||||
* path_lookup_create -> LOOKUP_OPEN|LOOKUP_CREATE
|
||||
*/
|
||||
struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry,
|
||||
struct nameidata *nd, int mode,
|
||||
int locked_dir)
|
||||
int ceph_lookup_open(struct inode *dir, struct dentry *dentry,
|
||||
struct file *file, unsigned flags, umode_t mode,
|
||||
int *opened)
|
||||
{
|
||||
struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb);
|
||||
struct ceph_mds_client *mdsc = fsc->mdsc;
|
||||
struct file *file;
|
||||
struct ceph_mds_request *req;
|
||||
struct dentry *ret;
|
||||
int err;
|
||||
int flags = nd->intent.open.flags;
|
||||
|
||||
dout("ceph_lookup_open dentry %p '%.*s' flags %d mode 0%o\n",
|
||||
dentry, dentry->d_name.len, dentry->d_name.name, flags, mode);
|
||||
|
@ -237,7 +230,7 @@ struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry,
|
|||
/* do the open */
|
||||
req = prepare_open_request(dir->i_sb, flags, mode);
|
||||
if (IS_ERR(req))
|
||||
return ERR_CAST(req);
|
||||
return PTR_ERR(req);
|
||||
req->r_dentry = dget(dentry);
|
||||
req->r_num_caps = 2;
|
||||
if (flags & O_CREAT) {
|
||||
|
@ -255,14 +248,17 @@ struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry,
|
|||
err = ceph_handle_notrace_create(dir, dentry);
|
||||
if (err)
|
||||
goto out;
|
||||
file = lookup_instantiate_filp(nd, req->r_dentry, ceph_open);
|
||||
if (IS_ERR(file))
|
||||
err = PTR_ERR(file);
|
||||
err = finish_open(file, req->r_dentry, ceph_open, opened);
|
||||
out:
|
||||
ret = ceph_finish_lookup(req, dentry, err);
|
||||
ceph_mdsc_put_request(req);
|
||||
dout("ceph_lookup_open result=%p\n", ret);
|
||||
return ret;
|
||||
|
||||
if (IS_ERR(ret))
|
||||
return PTR_ERR(ret);
|
||||
|
||||
dput(ret);
|
||||
return err;
|
||||
}
|
||||
|
||||
int ceph_release(struct inode *inode, struct file *file)
|
||||
|
|
|
@ -806,9 +806,9 @@ extern int ceph_copy_from_page_vector(struct page **pages,
|
|||
loff_t off, size_t len);
|
||||
extern struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags);
|
||||
extern int ceph_open(struct inode *inode, struct file *file);
|
||||
extern struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry,
|
||||
struct nameidata *nd, int mode,
|
||||
int locked_dir);
|
||||
extern int ceph_lookup_open(struct inode *dir, struct dentry *dentry,
|
||||
struct file *od, unsigned flags,
|
||||
umode_t mode, int *opened);
|
||||
extern int ceph_release(struct inode *inode, struct file *filp);
|
||||
|
||||
/* dir.c */
|
||||
|
|
|
@ -797,6 +797,7 @@ struct file_system_type cifs_fs_type = {
|
|||
};
|
||||
const struct inode_operations cifs_dir_inode_ops = {
|
||||
.create = cifs_create,
|
||||
.atomic_open = cifs_atomic_open,
|
||||
.lookup = cifs_lookup,
|
||||
.getattr = cifs_getattr,
|
||||
.unlink = cifs_unlink,
|
||||
|
|
|
@ -49,9 +49,12 @@ extern void cifs_sb_deactive(struct super_block *sb);
|
|||
extern const struct inode_operations cifs_dir_inode_ops;
|
||||
extern struct inode *cifs_root_iget(struct super_block *);
|
||||
extern int cifs_create(struct inode *, struct dentry *, umode_t,
|
||||
struct nameidata *);
|
||||
bool excl);
|
||||
extern int cifs_atomic_open(struct inode *, struct dentry *,
|
||||
struct file *, unsigned, umode_t,
|
||||
int *);
|
||||
extern struct dentry *cifs_lookup(struct inode *, struct dentry *,
|
||||
struct nameidata *);
|
||||
unsigned int);
|
||||
extern int cifs_unlink(struct inode *dir, struct dentry *dentry);
|
||||
extern int cifs_hardlink(struct dentry *, struct inode *, struct dentry *);
|
||||
extern int cifs_mknod(struct inode *, struct dentry *, umode_t, dev_t);
|
||||
|
|
450
fs/cifs/dir.c
450
fs/cifs/dir.c
|
@ -133,100 +133,133 @@ cifs_bp_rename_retry:
|
|||
return full_path;
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't allow the separator character in a path component.
|
||||
* The VFS will not allow "/", but "\" is allowed by posix.
|
||||
*/
|
||||
static int
|
||||
check_name(struct dentry *direntry)
|
||||
{
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
|
||||
int i;
|
||||
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
|
||||
for (i = 0; i < direntry->d_name.len; i++) {
|
||||
if (direntry->d_name.name[i] == '\\') {
|
||||
cFYI(1, "Invalid file name");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Inode operations in similar order to how they appear in Linux file fs.h */
|
||||
|
||||
int
|
||||
cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
|
||||
struct nameidata *nd)
|
||||
static int cifs_do_create(struct inode *inode, struct dentry *direntry,
|
||||
int xid, struct tcon_link *tlink, unsigned oflags,
|
||||
umode_t mode, __u32 *oplock, __u16 *fileHandle,
|
||||
int *created)
|
||||
{
|
||||
int rc = -ENOENT;
|
||||
int xid;
|
||||
int create_options = CREATE_NOT_DIR;
|
||||
__u32 oplock = 0;
|
||||
int oflags;
|
||||
/*
|
||||
* BB below access is probably too much for mknod to request
|
||||
* but we have to do query and setpathinfo so requesting
|
||||
* less could fail (unless we want to request getatr and setatr
|
||||
* permissions (only). At least for POSIX we do not have to
|
||||
* request so much.
|
||||
*/
|
||||
int desiredAccess = GENERIC_READ | GENERIC_WRITE;
|
||||
__u16 fileHandle;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct tcon_link *tlink;
|
||||
struct cifs_tcon *tcon;
|
||||
int desiredAccess;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct cifs_tcon *tcon = tlink_tcon(tlink);
|
||||
char *full_path = NULL;
|
||||
FILE_ALL_INFO *buf = NULL;
|
||||
struct inode *newinode = NULL;
|
||||
int disposition = FILE_OVERWRITE_IF;
|
||||
|
||||
xid = GetXid();
|
||||
|
||||
cifs_sb = CIFS_SB(inode->i_sb);
|
||||
tlink = cifs_sb_tlink(cifs_sb);
|
||||
if (IS_ERR(tlink)) {
|
||||
FreeXid(xid);
|
||||
return PTR_ERR(tlink);
|
||||
}
|
||||
tcon = tlink_tcon(tlink);
|
||||
int disposition;
|
||||
|
||||
*oplock = 0;
|
||||
if (tcon->ses->server->oplocks)
|
||||
oplock = REQ_OPLOCK;
|
||||
|
||||
if (nd)
|
||||
oflags = nd->intent.open.file->f_flags;
|
||||
else
|
||||
oflags = O_RDONLY | O_CREAT;
|
||||
*oplock = REQ_OPLOCK;
|
||||
|
||||
full_path = build_path_from_dentry(direntry);
|
||||
if (full_path == NULL) {
|
||||
rc = -ENOMEM;
|
||||
goto cifs_create_out;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
|
||||
!tcon->broken_posix_open &&
|
||||
(CIFS_UNIX_POSIX_PATH_OPS_CAP &
|
||||
le64_to_cpu(tcon->fsUnixInfo.Capability))) {
|
||||
rc = cifs_posix_open(full_path, &newinode,
|
||||
inode->i_sb, mode, oflags, &oplock, &fileHandle, xid);
|
||||
/* EIO could indicate that (posix open) operation is not
|
||||
supported, despite what server claimed in capability
|
||||
negotiation. EREMOTE indicates DFS junction, which is not
|
||||
handled in posix open */
|
||||
|
||||
if (rc == 0) {
|
||||
if (newinode == NULL) /* query inode info */
|
||||
inode->i_sb, mode, oflags, oplock, fileHandle, xid);
|
||||
switch (rc) {
|
||||
case 0:
|
||||
if (newinode == NULL) {
|
||||
/* query inode info */
|
||||
goto cifs_create_get_file_info;
|
||||
else /* success, no need to query */
|
||||
goto cifs_create_set_dentry;
|
||||
} else if ((rc != -EIO) && (rc != -EREMOTE) &&
|
||||
(rc != -EOPNOTSUPP) && (rc != -EINVAL))
|
||||
goto cifs_create_out;
|
||||
/* else fallthrough to retry, using older open call, this is
|
||||
case where server does not support this SMB level, and
|
||||
falsely claims capability (also get here for DFS case
|
||||
which should be rare for path not covered on files) */
|
||||
}
|
||||
|
||||
if (!S_ISREG(newinode->i_mode)) {
|
||||
/*
|
||||
* The server may allow us to open things like
|
||||
* FIFOs, but the client isn't set up to deal
|
||||
* with that. If it's not a regular file, just
|
||||
* close it and proceed as if it were a normal
|
||||
* lookup.
|
||||
*/
|
||||
CIFSSMBClose(xid, tcon, *fileHandle);
|
||||
goto cifs_create_get_file_info;
|
||||
}
|
||||
/* success, no need to query */
|
||||
goto cifs_create_set_dentry;
|
||||
|
||||
case -ENOENT:
|
||||
goto cifs_create_get_file_info;
|
||||
|
||||
case -EIO:
|
||||
case -EINVAL:
|
||||
/*
|
||||
* EIO could indicate that (posix open) operation is not
|
||||
* supported, despite what server claimed in capability
|
||||
* negotiation.
|
||||
*
|
||||
* POSIX open in samba versions 3.3.1 and earlier could
|
||||
* incorrectly fail with invalid parameter.
|
||||
*/
|
||||
tcon->broken_posix_open = true;
|
||||
break;
|
||||
|
||||
case -EREMOTE:
|
||||
case -EOPNOTSUPP:
|
||||
/*
|
||||
* EREMOTE indicates DFS junction, which is not handled
|
||||
* in posix open. If either that or op not supported
|
||||
* returned, follow the normal lookup.
|
||||
*/
|
||||
break;
|
||||
|
||||
default:
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* fallthrough to retry, using older open call, this is case
|
||||
* where server does not support this SMB level, and falsely
|
||||
* claims capability (also get here for DFS case which should be
|
||||
* rare for path not covered on files)
|
||||
*/
|
||||
}
|
||||
|
||||
if (nd) {
|
||||
/* if the file is going to stay open, then we
|
||||
need to set the desired access properly */
|
||||
desiredAccess = 0;
|
||||
if (OPEN_FMODE(oflags) & FMODE_READ)
|
||||
desiredAccess |= GENERIC_READ; /* is this too little? */
|
||||
if (OPEN_FMODE(oflags) & FMODE_WRITE)
|
||||
desiredAccess |= GENERIC_WRITE;
|
||||
desiredAccess = 0;
|
||||
if (OPEN_FMODE(oflags) & FMODE_READ)
|
||||
desiredAccess |= GENERIC_READ; /* is this too little? */
|
||||
if (OPEN_FMODE(oflags) & FMODE_WRITE)
|
||||
desiredAccess |= GENERIC_WRITE;
|
||||
|
||||
if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
|
||||
disposition = FILE_CREATE;
|
||||
else if ((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
|
||||
disposition = FILE_OVERWRITE_IF;
|
||||
else if ((oflags & O_CREAT) == O_CREAT)
|
||||
disposition = FILE_OPEN_IF;
|
||||
else
|
||||
cFYI(1, "Create flag not set in create function");
|
||||
}
|
||||
disposition = FILE_OVERWRITE_IF;
|
||||
if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
|
||||
disposition = FILE_CREATE;
|
||||
else if ((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
|
||||
disposition = FILE_OVERWRITE_IF;
|
||||
else if ((oflags & O_CREAT) == O_CREAT)
|
||||
disposition = FILE_OPEN_IF;
|
||||
else
|
||||
cFYI(1, "Create flag not set in create function");
|
||||
|
||||
/* BB add processing to set equivalent of mode - e.g. via CreateX with
|
||||
ACLs */
|
||||
|
@ -234,7 +267,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
|
|||
buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
|
||||
if (buf == NULL) {
|
||||
rc = -ENOMEM;
|
||||
goto cifs_create_out;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -250,7 +283,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
|
|||
if (tcon->ses->capabilities & CAP_NT_SMBS)
|
||||
rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
|
||||
desiredAccess, create_options,
|
||||
&fileHandle, &oplock, buf, cifs_sb->local_nls,
|
||||
fileHandle, oplock, buf, cifs_sb->local_nls,
|
||||
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||
else
|
||||
rc = -EIO; /* no NT SMB support fall into legacy open below */
|
||||
|
@ -259,17 +292,17 @@ cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
|
|||
/* old server, retry the open legacy style */
|
||||
rc = SMBLegacyOpen(xid, tcon, full_path, disposition,
|
||||
desiredAccess, create_options,
|
||||
&fileHandle, &oplock, buf, cifs_sb->local_nls,
|
||||
fileHandle, oplock, buf, cifs_sb->local_nls,
|
||||
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||
}
|
||||
if (rc) {
|
||||
cFYI(1, "cifs_create returned 0x%x", rc);
|
||||
goto cifs_create_out;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* If Open reported that we actually created a file
|
||||
then we now have to set the mode if possible */
|
||||
if ((tcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) {
|
||||
if ((tcon->unix_ext) && (*oplock & CIFS_CREATE_ACTION)) {
|
||||
struct cifs_unix_set_info_args args = {
|
||||
.mode = mode,
|
||||
.ctime = NO_CHANGE_64,
|
||||
|
@ -278,6 +311,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
|
|||
.device = 0,
|
||||
};
|
||||
|
||||
*created |= FILE_CREATED;
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
|
||||
args.uid = (__u64) current_fsuid();
|
||||
if (inode->i_mode & S_ISGID)
|
||||
|
@ -288,7 +322,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
|
|||
args.uid = NO_CHANGE_64;
|
||||
args.gid = NO_CHANGE_64;
|
||||
}
|
||||
CIFSSMBUnixSetFileInfo(xid, tcon, &args, fileHandle,
|
||||
CIFSSMBUnixSetFileInfo(xid, tcon, &args, *fileHandle,
|
||||
current->tgid);
|
||||
} else {
|
||||
/* BB implement mode setting via Windows security
|
||||
|
@ -305,11 +339,11 @@ cifs_create_get_file_info:
|
|||
inode->i_sb, xid);
|
||||
else {
|
||||
rc = cifs_get_inode_info(&newinode, full_path, buf,
|
||||
inode->i_sb, xid, &fileHandle);
|
||||
inode->i_sb, xid, fileHandle);
|
||||
if (newinode) {
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
|
||||
newinode->i_mode = mode;
|
||||
if ((oplock & CIFS_CREATE_ACTION) &&
|
||||
if ((*oplock & CIFS_CREATE_ACTION) &&
|
||||
(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) {
|
||||
newinode->i_uid = current_fsuid();
|
||||
if (inode->i_mode & S_ISGID)
|
||||
|
@ -321,40 +355,139 @@ cifs_create_get_file_info:
|
|||
}
|
||||
|
||||
cifs_create_set_dentry:
|
||||
if (rc == 0)
|
||||
d_instantiate(direntry, newinode);
|
||||
else
|
||||
if (rc != 0) {
|
||||
cFYI(1, "Create worked, get_inode_info failed rc = %d", rc);
|
||||
|
||||
if (newinode && nd) {
|
||||
struct cifsFileInfo *pfile_info;
|
||||
struct file *filp;
|
||||
|
||||
filp = lookup_instantiate_filp(nd, direntry, generic_file_open);
|
||||
if (IS_ERR(filp)) {
|
||||
rc = PTR_ERR(filp);
|
||||
CIFSSMBClose(xid, tcon, fileHandle);
|
||||
goto cifs_create_out;
|
||||
}
|
||||
|
||||
pfile_info = cifs_new_fileinfo(fileHandle, filp, tlink, oplock);
|
||||
if (pfile_info == NULL) {
|
||||
fput(filp);
|
||||
CIFSSMBClose(xid, tcon, fileHandle);
|
||||
rc = -ENOMEM;
|
||||
}
|
||||
} else {
|
||||
CIFSSMBClose(xid, tcon, fileHandle);
|
||||
goto out;
|
||||
}
|
||||
d_drop(direntry);
|
||||
d_add(direntry, newinode);
|
||||
|
||||
cifs_create_out:
|
||||
/* ENOENT for create? How weird... */
|
||||
rc = -ENOENT;
|
||||
if (!newinode) {
|
||||
CIFSSMBClose(xid, tcon, *fileHandle);
|
||||
goto out;
|
||||
}
|
||||
rc = 0;
|
||||
|
||||
out:
|
||||
kfree(buf);
|
||||
kfree(full_path);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
cifs_atomic_open(struct inode *inode, struct dentry *direntry,
|
||||
struct file *file, unsigned oflags, umode_t mode,
|
||||
int *opened)
|
||||
{
|
||||
int rc;
|
||||
int xid;
|
||||
struct tcon_link *tlink;
|
||||
struct cifs_tcon *tcon;
|
||||
__u16 fileHandle;
|
||||
__u32 oplock;
|
||||
struct file *filp;
|
||||
struct cifsFileInfo *pfile_info;
|
||||
|
||||
/* Posix open is only called (at lookup time) for file create now. For
|
||||
* opens (rather than creates), because we do not know if it is a file
|
||||
* or directory yet, and current Samba no longer allows us to do posix
|
||||
* open on dirs, we could end up wasting an open call on what turns out
|
||||
* to be a dir. For file opens, we wait to call posix open till
|
||||
* cifs_open. It could be added to atomic_open in the future but the
|
||||
* performance tradeoff of the extra network request when EISDIR or
|
||||
* EACCES is returned would have to be weighed against the 50% reduction
|
||||
* in network traffic in the other paths.
|
||||
*/
|
||||
if (!(oflags & O_CREAT)) {
|
||||
struct dentry *res = cifs_lookup(inode, direntry, 0);
|
||||
if (IS_ERR(res))
|
||||
return PTR_ERR(res);
|
||||
|
||||
return finish_no_open(file, res);
|
||||
}
|
||||
|
||||
rc = check_name(direntry);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
xid = GetXid();
|
||||
|
||||
cFYI(1, "parent inode = 0x%p name is: %s and dentry = 0x%p",
|
||||
inode, direntry->d_name.name, direntry);
|
||||
|
||||
tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb));
|
||||
filp = ERR_CAST(tlink);
|
||||
if (IS_ERR(tlink))
|
||||
goto free_xid;
|
||||
|
||||
tcon = tlink_tcon(tlink);
|
||||
|
||||
rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
|
||||
&oplock, &fileHandle, opened);
|
||||
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
rc = finish_open(file, direntry, generic_file_open, opened);
|
||||
if (rc) {
|
||||
CIFSSMBClose(xid, tcon, fileHandle);
|
||||
goto out;
|
||||
}
|
||||
|
||||
pfile_info = cifs_new_fileinfo(fileHandle, filp, tlink, oplock);
|
||||
if (pfile_info == NULL) {
|
||||
CIFSSMBClose(xid, tcon, fileHandle);
|
||||
fput(filp);
|
||||
rc = -ENOMEM;
|
||||
}
|
||||
|
||||
out:
|
||||
cifs_put_tlink(tlink);
|
||||
free_xid:
|
||||
FreeXid(xid);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
|
||||
bool excl)
|
||||
{
|
||||
int rc;
|
||||
int xid = GetXid();
|
||||
/*
|
||||
* BB below access is probably too much for mknod to request
|
||||
* but we have to do query and setpathinfo so requesting
|
||||
* less could fail (unless we want to request getatr and setatr
|
||||
* permissions (only). At least for POSIX we do not have to
|
||||
* request so much.
|
||||
*/
|
||||
unsigned oflags = O_EXCL | O_CREAT | O_RDWR;
|
||||
struct tcon_link *tlink;
|
||||
__u16 fileHandle;
|
||||
__u32 oplock;
|
||||
int created = FILE_CREATED;
|
||||
|
||||
cFYI(1, "cifs_create parent inode = 0x%p name is: %s and dentry = 0x%p",
|
||||
inode, direntry->d_name.name, direntry);
|
||||
|
||||
tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb));
|
||||
rc = PTR_ERR(tlink);
|
||||
if (IS_ERR(tlink))
|
||||
goto free_xid;
|
||||
|
||||
rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
|
||||
&oplock, &fileHandle, &created);
|
||||
if (!rc)
|
||||
CIFSSMBClose(xid, tlink_tcon(tlink), fileHandle);
|
||||
|
||||
cifs_put_tlink(tlink);
|
||||
free_xid:
|
||||
FreeXid(xid);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode,
|
||||
dev_t device_number)
|
||||
{
|
||||
|
@ -488,20 +621,15 @@ mknod_out:
|
|||
|
||||
struct dentry *
|
||||
cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
|
||||
struct nameidata *nd)
|
||||
unsigned int flags)
|
||||
{
|
||||
int xid;
|
||||
int rc = 0; /* to get around spurious gcc warning, set to zero here */
|
||||
__u32 oplock;
|
||||
__u16 fileHandle = 0;
|
||||
bool posix_open = false;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct tcon_link *tlink;
|
||||
struct cifs_tcon *pTcon;
|
||||
struct cifsFileInfo *cfile;
|
||||
struct inode *newInode = NULL;
|
||||
char *full_path = NULL;
|
||||
struct file *filp;
|
||||
|
||||
xid = GetXid();
|
||||
|
||||
|
@ -518,31 +646,9 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
|
|||
}
|
||||
pTcon = tlink_tcon(tlink);
|
||||
|
||||
oplock = pTcon->ses->server->oplocks ? REQ_OPLOCK : 0;
|
||||
|
||||
/*
|
||||
* Don't allow the separator character in a path component.
|
||||
* The VFS will not allow "/", but "\" is allowed by posix.
|
||||
*/
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
|
||||
int i;
|
||||
for (i = 0; i < direntry->d_name.len; i++)
|
||||
if (direntry->d_name.name[i] == '\\') {
|
||||
cFYI(1, "Invalid file name");
|
||||
rc = -EINVAL;
|
||||
goto lookup_out;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* O_EXCL: optimize away the lookup, but don't hash the dentry. Let
|
||||
* the VFS handle the create.
|
||||
*/
|
||||
if (nd && (nd->flags & LOOKUP_EXCL)) {
|
||||
d_instantiate(direntry, NULL);
|
||||
rc = 0;
|
||||
rc = check_name(direntry);
|
||||
if (rc)
|
||||
goto lookup_out;
|
||||
}
|
||||
|
||||
/* can not grab the rename sem here since it would
|
||||
deadlock in the cases (beginning of sys_rename itself)
|
||||
|
@ -560,80 +666,16 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
|
|||
}
|
||||
cFYI(1, "Full path: %s inode = 0x%p", full_path, direntry->d_inode);
|
||||
|
||||
/* Posix open is only called (at lookup time) for file create now.
|
||||
* For opens (rather than creates), because we do not know if it
|
||||
* is a file or directory yet, and current Samba no longer allows
|
||||
* us to do posix open on dirs, we could end up wasting an open call
|
||||
* on what turns out to be a dir. For file opens, we wait to call posix
|
||||
* open till cifs_open. It could be added here (lookup) in the future
|
||||
* but the performance tradeoff of the extra network request when EISDIR
|
||||
* or EACCES is returned would have to be weighed against the 50%
|
||||
* reduction in network traffic in the other paths.
|
||||
*/
|
||||
if (pTcon->unix_ext) {
|
||||
if (nd && !(nd->flags & LOOKUP_DIRECTORY) &&
|
||||
(nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
|
||||
(nd->intent.open.file->f_flags & O_CREAT)) {
|
||||
rc = cifs_posix_open(full_path, &newInode,
|
||||
parent_dir_inode->i_sb,
|
||||
nd->intent.open.create_mode,
|
||||
nd->intent.open.file->f_flags, &oplock,
|
||||
&fileHandle, xid);
|
||||
/*
|
||||
* The check below works around a bug in POSIX
|
||||
* open in samba versions 3.3.1 and earlier where
|
||||
* open could incorrectly fail with invalid parameter.
|
||||
* If either that or op not supported returned, follow
|
||||
* the normal lookup.
|
||||
*/
|
||||
switch (rc) {
|
||||
case 0:
|
||||
/*
|
||||
* The server may allow us to open things like
|
||||
* FIFOs, but the client isn't set up to deal
|
||||
* with that. If it's not a regular file, just
|
||||
* close it and proceed as if it were a normal
|
||||
* lookup.
|
||||
*/
|
||||
if (newInode && !S_ISREG(newInode->i_mode)) {
|
||||
CIFSSMBClose(xid, pTcon, fileHandle);
|
||||
break;
|
||||
}
|
||||
case -ENOENT:
|
||||
posix_open = true;
|
||||
case -EOPNOTSUPP:
|
||||
break;
|
||||
default:
|
||||
pTcon->broken_posix_open = true;
|
||||
}
|
||||
}
|
||||
if (!posix_open)
|
||||
rc = cifs_get_inode_info_unix(&newInode, full_path,
|
||||
parent_dir_inode->i_sb, xid);
|
||||
} else
|
||||
rc = cifs_get_inode_info_unix(&newInode, full_path,
|
||||
parent_dir_inode->i_sb, xid);
|
||||
} else {
|
||||
rc = cifs_get_inode_info(&newInode, full_path, NULL,
|
||||
parent_dir_inode->i_sb, xid, NULL);
|
||||
}
|
||||
|
||||
if ((rc == 0) && (newInode != NULL)) {
|
||||
d_add(direntry, newInode);
|
||||
if (posix_open) {
|
||||
filp = lookup_instantiate_filp(nd, direntry,
|
||||
generic_file_open);
|
||||
if (IS_ERR(filp)) {
|
||||
rc = PTR_ERR(filp);
|
||||
CIFSSMBClose(xid, pTcon, fileHandle);
|
||||
goto lookup_out;
|
||||
}
|
||||
|
||||
cfile = cifs_new_fileinfo(fileHandle, filp, tlink,
|
||||
oplock);
|
||||
if (cfile == NULL) {
|
||||
fput(filp);
|
||||
CIFSSMBClose(xid, pTcon, fileHandle);
|
||||
rc = -ENOMEM;
|
||||
goto lookup_out;
|
||||
}
|
||||
}
|
||||
/* since paths are not looked up by component - the parent
|
||||
directories are presumed to be good here */
|
||||
renew_parental_timestamps(direntry);
|
||||
|
@ -658,9 +700,9 @@ lookup_out:
|
|||
}
|
||||
|
||||
static int
|
||||
cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
|
||||
cifs_d_revalidate(struct dentry *direntry, unsigned int flags)
|
||||
{
|
||||
if (nd && (nd->flags & LOOKUP_RCU))
|
||||
if (flags & LOOKUP_RCU)
|
||||
return -ECHILD;
|
||||
|
||||
if (direntry->d_inode) {
|
||||
|
@ -689,7 +731,7 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
|
|||
* This may be nfsd (or something), anyway, we can't see the
|
||||
* intent of this. So, since this can be for creation, drop it.
|
||||
*/
|
||||
if (!nd)
|
||||
if (!flags)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
|
@ -697,7 +739,7 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
|
|||
* case sensitive name which is specified by user if this is
|
||||
* for creation.
|
||||
*/
|
||||
if (nd->flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
|
||||
if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
|
||||
return 0;
|
||||
|
||||
if (time_after(jiffies, direntry->d_time + HZ) || !lookupCacheEnabled)
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
#include "coda_int.h"
|
||||
|
||||
/* dir inode-ops */
|
||||
static int coda_create(struct inode *dir, struct dentry *new, umode_t mode, struct nameidata *nd);
|
||||
static struct dentry *coda_lookup(struct inode *dir, struct dentry *target, struct nameidata *nd);
|
||||
static int coda_create(struct inode *dir, struct dentry *new, umode_t mode, bool excl);
|
||||
static struct dentry *coda_lookup(struct inode *dir, struct dentry *target, unsigned int flags);
|
||||
static int coda_link(struct dentry *old_dentry, struct inode *dir_inode,
|
||||
struct dentry *entry);
|
||||
static int coda_unlink(struct inode *dir_inode, struct dentry *entry);
|
||||
|
@ -46,7 +46,7 @@ static int coda_rename(struct inode *old_inode, struct dentry *old_dentry,
|
|||
static int coda_readdir(struct file *file, void *buf, filldir_t filldir);
|
||||
|
||||
/* dentry ops */
|
||||
static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd);
|
||||
static int coda_dentry_revalidate(struct dentry *de, unsigned int flags);
|
||||
static int coda_dentry_delete(const struct dentry *);
|
||||
|
||||
/* support routines */
|
||||
|
@ -94,7 +94,7 @@ const struct file_operations coda_dir_operations = {
|
|||
|
||||
/* inode operations for directories */
|
||||
/* access routines: lookup, readlink, permission */
|
||||
static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, struct nameidata *nd)
|
||||
static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, unsigned int flags)
|
||||
{
|
||||
struct super_block *sb = dir->i_sb;
|
||||
const char *name = entry->d_name.name;
|
||||
|
@ -188,7 +188,7 @@ static inline void coda_dir_drop_nlink(struct inode *dir)
|
|||
}
|
||||
|
||||
/* creation routines: create, mknod, mkdir, link, symlink */
|
||||
static int coda_create(struct inode *dir, struct dentry *de, umode_t mode, struct nameidata *nd)
|
||||
static int coda_create(struct inode *dir, struct dentry *de, umode_t mode, bool excl)
|
||||
{
|
||||
int error;
|
||||
const char *name=de->d_name.name;
|
||||
|
@ -536,12 +536,12 @@ out:
|
|||
}
|
||||
|
||||
/* called when a cache lookup succeeds */
|
||||
static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd)
|
||||
static int coda_dentry_revalidate(struct dentry *de, unsigned int flags)
|
||||
{
|
||||
struct inode *inode;
|
||||
struct coda_inode_info *cii;
|
||||
|
||||
if (nd->flags & LOOKUP_RCU)
|
||||
if (flags & LOOKUP_RCU)
|
||||
return -ECHILD;
|
||||
|
||||
inode = de->d_inode;
|
||||
|
|
12
fs/compat.c
12
fs/compat.c
|
@ -780,16 +780,16 @@ asmlinkage long compat_sys_mount(const char __user * dev_name,
|
|||
char *kernel_type;
|
||||
unsigned long data_page;
|
||||
char *kernel_dev;
|
||||
char *dir_page;
|
||||
struct filename *dir;
|
||||
int retval;
|
||||
|
||||
retval = copy_mount_string(type, &kernel_type);
|
||||
if (retval < 0)
|
||||
goto out;
|
||||
|
||||
dir_page = getname(dir_name);
|
||||
retval = PTR_ERR(dir_page);
|
||||
if (IS_ERR(dir_page))
|
||||
dir = getname(dir_name);
|
||||
retval = PTR_ERR(dir);
|
||||
if (IS_ERR(dir))
|
||||
goto out1;
|
||||
|
||||
retval = copy_mount_string(dev_name, &kernel_dev);
|
||||
|
@ -811,7 +811,7 @@ asmlinkage long compat_sys_mount(const char __user * dev_name,
|
|||
}
|
||||
}
|
||||
|
||||
retval = do_mount(kernel_dev, dir_page, kernel_type,
|
||||
retval = do_mount(kernel_dev, dir->name, kernel_type,
|
||||
flags, (void*)data_page);
|
||||
|
||||
out4:
|
||||
|
@ -819,7 +819,7 @@ asmlinkage long compat_sys_mount(const char __user * dev_name,
|
|||
out3:
|
||||
kfree(kernel_dev);
|
||||
out2:
|
||||
putname(dir_page);
|
||||
putname(dir);
|
||||
out1:
|
||||
kfree(kernel_type);
|
||||
out:
|
||||
|
|
|
@ -454,7 +454,7 @@ static int configfs_attach_attr(struct configfs_dirent * sd, struct dentry * den
|
|||
|
||||
static struct dentry * configfs_lookup(struct inode *dir,
|
||||
struct dentry *dentry,
|
||||
struct nameidata *nd)
|
||||
unsigned int flags)
|
||||
{
|
||||
struct configfs_dirent * parent_sd = dentry->d_parent->d_fsdata;
|
||||
struct configfs_dirent * sd;
|
||||
|
|
|
@ -417,7 +417,7 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
|||
/*
|
||||
* Lookup and fill in the inode data..
|
||||
*/
|
||||
static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
|
||||
static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
|
||||
{
|
||||
unsigned int offset = 0;
|
||||
struct inode *inode = NULL;
|
||||
|
|
208
fs/dcache.c
208
fs/dcache.c
|
@ -153,16 +153,12 @@ int proc_nr_dentry(ctl_table *table, int write, void __user *buffer,
|
|||
* In contrast, 'ct' and 'tcount' can be from a pathname, and do
|
||||
* need the careful unaligned handling.
|
||||
*/
|
||||
static inline int dentry_cmp(const unsigned char *cs, size_t scount,
|
||||
const unsigned char *ct, size_t tcount)
|
||||
static inline int dentry_string_cmp(const unsigned char *cs, const unsigned char *ct, unsigned tcount)
|
||||
{
|
||||
unsigned long a,b,mask;
|
||||
|
||||
if (unlikely(scount != tcount))
|
||||
return 1;
|
||||
|
||||
for (;;) {
|
||||
a = load_unaligned_zeropad(cs);
|
||||
a = *(unsigned long *)cs;
|
||||
b = load_unaligned_zeropad(ct);
|
||||
if (tcount < sizeof(unsigned long))
|
||||
break;
|
||||
|
@ -180,12 +176,8 @@ static inline int dentry_cmp(const unsigned char *cs, size_t scount,
|
|||
|
||||
#else
|
||||
|
||||
static inline int dentry_cmp(const unsigned char *cs, size_t scount,
|
||||
const unsigned char *ct, size_t tcount)
|
||||
static inline int dentry_string_cmp(const unsigned char *cs, const unsigned char *ct, unsigned tcount)
|
||||
{
|
||||
if (scount != tcount)
|
||||
return 1;
|
||||
|
||||
do {
|
||||
if (*cs != *ct)
|
||||
return 1;
|
||||
|
@ -198,6 +190,30 @@ static inline int dentry_cmp(const unsigned char *cs, size_t scount,
|
|||
|
||||
#endif
|
||||
|
||||
static inline int dentry_cmp(const struct dentry *dentry, const unsigned char *ct, unsigned tcount)
|
||||
{
|
||||
const unsigned char *cs;
|
||||
/*
|
||||
* Be careful about RCU walk racing with rename:
|
||||
* use ACCESS_ONCE to fetch the name pointer.
|
||||
*
|
||||
* NOTE! Even if a rename will mean that the length
|
||||
* was not loaded atomically, we don't care. The
|
||||
* RCU walk will check the sequence count eventually,
|
||||
* and catch it. And we won't overrun the buffer,
|
||||
* because we're reading the name pointer atomically,
|
||||
* and a dentry name is guaranteed to be properly
|
||||
* terminated with a NUL byte.
|
||||
*
|
||||
* End result: even if 'len' is wrong, we'll exit
|
||||
* early because the data cannot match (there can
|
||||
* be no NUL in the ct/tcount data)
|
||||
*/
|
||||
cs = ACCESS_ONCE(dentry->d_name.name);
|
||||
smp_read_barrier_depends();
|
||||
return dentry_string_cmp(cs, ct, tcount);
|
||||
}
|
||||
|
||||
static void __d_free(struct rcu_head *head)
|
||||
{
|
||||
struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu);
|
||||
|
@ -1309,6 +1325,13 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
|
|||
if (!dentry)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* We guarantee that the inline name is always NUL-terminated.
|
||||
* This way the memcpy() done by the name switching in rename
|
||||
* will still always have a NUL at the end, even if we might
|
||||
* be overwriting an internal NUL character
|
||||
*/
|
||||
dentry->d_iname[DNAME_INLINE_LEN-1] = 0;
|
||||
if (name->len > DNAME_INLINE_LEN-1) {
|
||||
dname = kmalloc(name->len + 1, GFP_KERNEL);
|
||||
if (!dname) {
|
||||
|
@ -1318,13 +1341,16 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
|
|||
} else {
|
||||
dname = dentry->d_iname;
|
||||
}
|
||||
dentry->d_name.name = dname;
|
||||
|
||||
dentry->d_name.len = name->len;
|
||||
dentry->d_name.hash = name->hash;
|
||||
memcpy(dname, name->name, name->len);
|
||||
dname[name->len] = 0;
|
||||
|
||||
/* Make sure we always see the terminating NUL character */
|
||||
smp_wmb();
|
||||
dentry->d_name.name = dname;
|
||||
|
||||
dentry->d_count = 1;
|
||||
dentry->d_flags = 0;
|
||||
spin_lock_init(&dentry->d_lock);
|
||||
|
@ -1490,18 +1516,18 @@ static struct dentry *__d_instantiate_unique(struct dentry *entry,
|
|||
}
|
||||
|
||||
list_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
|
||||
struct qstr *qstr = &alias->d_name;
|
||||
|
||||
/*
|
||||
* Don't need alias->d_lock here, because aliases with
|
||||
* d_parent == entry->d_parent are not subject to name or
|
||||
* parent changes, because the parent inode i_mutex is held.
|
||||
*/
|
||||
if (qstr->hash != hash)
|
||||
if (alias->d_name.hash != hash)
|
||||
continue;
|
||||
if (alias->d_parent != entry->d_parent)
|
||||
continue;
|
||||
if (dentry_cmp(qstr->name, qstr->len, name, len))
|
||||
if (alias->d_name.len != len)
|
||||
continue;
|
||||
if (dentry_cmp(alias, name, len))
|
||||
continue;
|
||||
__dget(alias);
|
||||
return alias;
|
||||
|
@ -1540,7 +1566,7 @@ struct dentry *d_make_root(struct inode *root_inode)
|
|||
struct dentry *res = NULL;
|
||||
|
||||
if (root_inode) {
|
||||
static const struct qstr name = { .name = "/", .len = 1 };
|
||||
static const struct qstr name = QSTR_INIT("/", 1);
|
||||
|
||||
res = __d_alloc(root_inode->i_sb, &name);
|
||||
if (res)
|
||||
|
@ -1778,6 +1804,48 @@ err_out:
|
|||
}
|
||||
EXPORT_SYMBOL(d_add_ci);
|
||||
|
||||
/*
|
||||
* Do the slow-case of the dentry name compare.
|
||||
*
|
||||
* Unlike the dentry_cmp() function, we need to atomically
|
||||
* load the name, length and inode information, so that the
|
||||
* filesystem can rely on them, and can use the 'name' and
|
||||
* 'len' information without worrying about walking off the
|
||||
* end of memory etc.
|
||||
*
|
||||
* Thus the read_seqcount_retry() and the "duplicate" info
|
||||
* in arguments (the low-level filesystem should not look
|
||||
* at the dentry inode or name contents directly, since
|
||||
* rename can change them while we're in RCU mode).
|
||||
*/
|
||||
enum slow_d_compare {
|
||||
D_COMP_OK,
|
||||
D_COMP_NOMATCH,
|
||||
D_COMP_SEQRETRY,
|
||||
};
|
||||
|
||||
static noinline enum slow_d_compare slow_dentry_cmp(
|
||||
const struct dentry *parent,
|
||||
struct inode *inode,
|
||||
struct dentry *dentry,
|
||||
unsigned int seq,
|
||||
const struct qstr *name)
|
||||
{
|
||||
int tlen = dentry->d_name.len;
|
||||
const char *tname = dentry->d_name.name;
|
||||
struct inode *i = dentry->d_inode;
|
||||
|
||||
if (read_seqcount_retry(&dentry->d_seq, seq)) {
|
||||
cpu_relax();
|
||||
return D_COMP_SEQRETRY;
|
||||
}
|
||||
if (parent->d_op->d_compare(parent, inode,
|
||||
dentry, i,
|
||||
tlen, tname, name))
|
||||
return D_COMP_NOMATCH;
|
||||
return D_COMP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* __d_lookup_rcu - search for a dentry (racy, store-free)
|
||||
* @parent: parent dentry
|
||||
|
@ -1804,15 +1872,17 @@ EXPORT_SYMBOL(d_add_ci);
|
|||
* the returned dentry, so long as its parent's seqlock is checked after the
|
||||
* child is looked up. Thus, an interlocking stepping of sequence lock checks
|
||||
* is formed, giving integrity down the path walk.
|
||||
*
|
||||
* NOTE! The caller *has* to check the resulting dentry against the sequence
|
||||
* number we've returned before using any of the resulting dentry state!
|
||||
*/
|
||||
struct dentry *__d_lookup_rcu(const struct dentry *parent,
|
||||
const struct qstr *name,
|
||||
unsigned *seqp, struct inode **inode)
|
||||
unsigned *seqp, struct inode *inode)
|
||||
{
|
||||
unsigned int len = name->len;
|
||||
unsigned int hash = name->hash;
|
||||
u64 hashlen = name->hash_len;
|
||||
const unsigned char *str = name->name;
|
||||
struct hlist_bl_head *b = d_hash(parent, hash);
|
||||
struct hlist_bl_head *b = d_hash(parent, hashlen_hash(hashlen));
|
||||
struct hlist_bl_node *node;
|
||||
struct dentry *dentry;
|
||||
|
||||
|
@ -1838,49 +1908,47 @@ struct dentry *__d_lookup_rcu(const struct dentry *parent,
|
|||
*/
|
||||
hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) {
|
||||
unsigned seq;
|
||||
struct inode *i;
|
||||
const char *tname;
|
||||
int tlen;
|
||||
|
||||
if (dentry->d_name.hash != hash)
|
||||
continue;
|
||||
|
||||
seqretry:
|
||||
seq = read_seqcount_begin(&dentry->d_seq);
|
||||
/*
|
||||
* The dentry sequence count protects us from concurrent
|
||||
* renames, and thus protects inode, parent and name fields.
|
||||
*
|
||||
* The caller must perform a seqcount check in order
|
||||
* to do anything useful with the returned dentry,
|
||||
* including using the 'd_inode' pointer.
|
||||
*
|
||||
* NOTE! We do a "raw" seqcount_begin here. That means that
|
||||
* we don't wait for the sequence count to stabilize if it
|
||||
* is in the middle of a sequence change. If we do the slow
|
||||
* dentry compare, we will do seqretries until it is stable,
|
||||
* and if we end up with a successful lookup, we actually
|
||||
* want to exit RCU lookup anyway.
|
||||
*/
|
||||
seq = raw_seqcount_begin(&dentry->d_seq);
|
||||
if (dentry->d_parent != parent)
|
||||
continue;
|
||||
if (d_unhashed(dentry))
|
||||
continue;
|
||||
tlen = dentry->d_name.len;
|
||||
tname = dentry->d_name.name;
|
||||
i = dentry->d_inode;
|
||||
prefetch(tname);
|
||||
/*
|
||||
* This seqcount check is required to ensure name and
|
||||
* len are loaded atomically, so as not to walk off the
|
||||
* edge of memory when walking. If we could load this
|
||||
* atomically some other way, we could drop this check.
|
||||
*/
|
||||
if (read_seqcount_retry(&dentry->d_seq, seq))
|
||||
goto seqretry;
|
||||
if (unlikely(parent->d_flags & DCACHE_OP_COMPARE)) {
|
||||
if (parent->d_op->d_compare(parent, *inode,
|
||||
dentry, i,
|
||||
tlen, tname, name))
|
||||
continue;
|
||||
} else {
|
||||
if (dentry_cmp(tname, tlen, str, len))
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* No extra seqcount check is required after the name
|
||||
* compare. The caller must perform a seqcount check in
|
||||
* order to do anything useful with the returned dentry
|
||||
* anyway.
|
||||
*/
|
||||
*seqp = seq;
|
||||
*inode = i;
|
||||
return dentry;
|
||||
|
||||
if (unlikely(parent->d_flags & DCACHE_OP_COMPARE)) {
|
||||
if (dentry->d_name.hash != hashlen_hash(hashlen))
|
||||
continue;
|
||||
switch (slow_dentry_cmp(parent, inode, dentry, seq, name)) {
|
||||
case D_COMP_OK:
|
||||
return dentry;
|
||||
case D_COMP_NOMATCH:
|
||||
continue;
|
||||
default:
|
||||
goto seqretry;
|
||||
}
|
||||
}
|
||||
|
||||
if (dentry->d_name.hash_len != hashlen)
|
||||
continue;
|
||||
if (!dentry_cmp(dentry, str, hashlen_len(hashlen)))
|
||||
return dentry;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1959,8 +2027,6 @@ struct dentry *__d_lookup(const struct dentry *parent, const struct qstr *name)
|
|||
rcu_read_lock();
|
||||
|
||||
hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) {
|
||||
const char *tname;
|
||||
int tlen;
|
||||
|
||||
if (dentry->d_name.hash != hash)
|
||||
continue;
|
||||
|
@ -1975,15 +2041,17 @@ struct dentry *__d_lookup(const struct dentry *parent, const struct qstr *name)
|
|||
* It is safe to compare names since d_move() cannot
|
||||
* change the qstr (protected by d_lock).
|
||||
*/
|
||||
tlen = dentry->d_name.len;
|
||||
tname = dentry->d_name.name;
|
||||
if (parent->d_flags & DCACHE_OP_COMPARE) {
|
||||
int tlen = dentry->d_name.len;
|
||||
const char *tname = dentry->d_name.name;
|
||||
if (parent->d_op->d_compare(parent, parent->d_inode,
|
||||
dentry, dentry->d_inode,
|
||||
tlen, tname, name))
|
||||
goto next;
|
||||
} else {
|
||||
if (dentry_cmp(tname, tlen, str, len))
|
||||
if (dentry->d_name.len != len)
|
||||
goto next;
|
||||
if (dentry_cmp(dentry, str, len))
|
||||
goto next;
|
||||
}
|
||||
|
||||
|
@ -3054,6 +3122,22 @@ rename_retry:
|
|||
goto again;
|
||||
}
|
||||
|
||||
void d_tmpfile(struct dentry *dentry, struct inode *inode)
|
||||
{
|
||||
inode_dec_link_count(inode);
|
||||
BUG_ON(dentry->d_name.name != dentry->d_iname ||
|
||||
!list_empty(&dentry->d_u.d_alias) ||
|
||||
!d_unlinked(dentry));
|
||||
spin_lock(&dentry->d_parent->d_lock);
|
||||
spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
|
||||
dentry->d_name.len = sprintf(dentry->d_iname, "#%llu",
|
||||
(unsigned long long)inode->i_ino);
|
||||
spin_unlock(&dentry->d_lock);
|
||||
spin_unlock(&dentry->d_parent->d_lock);
|
||||
d_instantiate(dentry, inode);
|
||||
}
|
||||
EXPORT_SYMBOL(d_tmpfile);
|
||||
|
||||
/**
|
||||
* find_inode_number - check for dentry with name
|
||||
* @dir: directory to check
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
/**
|
||||
* ecryptfs_d_revalidate - revalidate an ecryptfs dentry
|
||||
* @dentry: The ecryptfs dentry
|
||||
* @nd: The associated nameidata
|
||||
* @flags: lookup flags
|
||||
*
|
||||
* Called when the VFS needs to revalidate a dentry. This
|
||||
* is called whenever a name lookup finds a dentry in the
|
||||
|
@ -42,31 +42,19 @@
|
|||
* Returns 1 if valid, 0 otherwise.
|
||||
*
|
||||
*/
|
||||
static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
|
||||
static int ecryptfs_d_revalidate(struct dentry *dentry, unsigned int flags)
|
||||
{
|
||||
struct dentry *lower_dentry;
|
||||
struct vfsmount *lower_mnt;
|
||||
struct dentry *dentry_save = NULL;
|
||||
struct vfsmount *vfsmount_save = NULL;
|
||||
int rc = 1;
|
||||
|
||||
if (nd && nd->flags & LOOKUP_RCU)
|
||||
if (flags & LOOKUP_RCU)
|
||||
return -ECHILD;
|
||||
|
||||
lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
||||
lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
|
||||
if (lower_dentry->d_op && lower_dentry->d_op->d_revalidate) {
|
||||
if (nd) {
|
||||
dentry_save = nd->path.dentry;
|
||||
vfsmount_save = nd->path.mnt;
|
||||
nd->path.dentry = lower_dentry;
|
||||
nd->path.mnt = lower_mnt;
|
||||
}
|
||||
rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd);
|
||||
if (nd) {
|
||||
nd->path.dentry = dentry_save;
|
||||
nd->path.mnt = vfsmount_save;
|
||||
}
|
||||
rc = lower_dentry->d_op->d_revalidate(lower_dentry, flags);
|
||||
}
|
||||
if (dentry->d_inode) {
|
||||
struct inode *inode = dentry->d_inode;
|
||||
|
|
|
@ -198,7 +198,7 @@ ecryptfs_do_create(struct inode *directory_inode,
|
|||
inode = ERR_CAST(lower_dir_dentry);
|
||||
goto out;
|
||||
}
|
||||
rc = vfs_create(lower_dir_dentry->d_inode, lower_dentry, mode, NULL);
|
||||
rc = vfs_create(lower_dir_dentry->d_inode, lower_dentry, mode, true);
|
||||
if (rc) {
|
||||
printk(KERN_ERR "%s: Failure to create dentry in lower fs; "
|
||||
"rc = [%d]\n", __func__, rc);
|
||||
|
@ -267,7 +267,6 @@ out:
|
|||
* @dir: The inode of the directory in which to create the file.
|
||||
* @dentry: The eCryptfs dentry
|
||||
* @mode: The mode of the new file.
|
||||
* @nd: nameidata
|
||||
*
|
||||
* Creates a new file.
|
||||
*
|
||||
|
@ -275,7 +274,7 @@ out:
|
|||
*/
|
||||
static int
|
||||
ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry,
|
||||
umode_t mode, struct nameidata *nd)
|
||||
umode_t mode, bool excl)
|
||||
{
|
||||
struct inode *ecryptfs_inode;
|
||||
int rc;
|
||||
|
@ -403,7 +402,7 @@ static int ecryptfs_lookup_interpose(struct dentry *dentry,
|
|||
*/
|
||||
static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
|
||||
struct dentry *ecryptfs_dentry,
|
||||
struct nameidata *ecryptfs_nd)
|
||||
unsigned int flags)
|
||||
{
|
||||
char *encrypted_and_encoded_name = NULL;
|
||||
size_t encrypted_and_encoded_name_size;
|
||||
|
|
|
@ -129,7 +129,7 @@ extern struct inode *efs_iget(struct super_block *, unsigned long);
|
|||
extern efs_block_t efs_map_block(struct inode *, efs_block_t);
|
||||
extern int efs_get_block(struct inode *, sector_t, struct buffer_head *, int);
|
||||
|
||||
extern struct dentry *efs_lookup(struct inode *, struct dentry *, struct nameidata *);
|
||||
extern struct dentry *efs_lookup(struct inode *, struct dentry *, unsigned int);
|
||||
extern struct dentry *efs_fh_to_dentry(struct super_block *sb, struct fid *fid,
|
||||
int fh_len, int fh_type);
|
||||
extern struct dentry *efs_fh_to_parent(struct super_block *sb, struct fid *fid,
|
||||
|
|
|
@ -58,7 +58,8 @@ static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len)
|
|||
return(0);
|
||||
}
|
||||
|
||||
struct dentry *efs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) {
|
||||
struct dentry *efs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
|
||||
{
|
||||
efs_ino_t inodenum;
|
||||
struct inode *inode = NULL;
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ static inline void put_binfmt(struct linux_binfmt * fmt)
|
|||
SYSCALL_DEFINE1(uselib, const char __user *, library)
|
||||
{
|
||||
struct file *file;
|
||||
char *tmp = getname(library);
|
||||
struct filename *tmp = getname(library);
|
||||
int error = PTR_ERR(tmp);
|
||||
static const struct open_flags uselib_flags = {
|
||||
.open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC,
|
||||
|
@ -786,13 +786,14 @@ struct file *open_exec(const char *name)
|
|||
{
|
||||
struct file *file;
|
||||
int err;
|
||||
struct filename tmp = { .name = name };
|
||||
static const struct open_flags open_exec_flags = {
|
||||
.open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC,
|
||||
.acc_mode = MAY_EXEC | MAY_OPEN,
|
||||
.intent = LOOKUP_OPEN
|
||||
};
|
||||
|
||||
file = do_filp_open(AT_FDCWD, name, &open_exec_flags, LOOKUP_FOLLOW);
|
||||
file = do_filp_open(AT_FDCWD, &tmp, &open_exec_flags, LOOKUP_FOLLOW);
|
||||
if (IS_ERR(file))
|
||||
goto out;
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ static inline int exofs_add_nondir(struct dentry *dentry, struct inode *inode)
|
|||
}
|
||||
|
||||
static struct dentry *exofs_lookup(struct inode *dir, struct dentry *dentry,
|
||||
struct nameidata *nd)
|
||||
unsigned int flags)
|
||||
{
|
||||
struct inode *inode;
|
||||
ino_t ino;
|
||||
|
@ -60,7 +60,7 @@ static struct dentry *exofs_lookup(struct inode *dir, struct dentry *dentry,
|
|||
}
|
||||
|
||||
static int exofs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
|
||||
struct nameidata *nd)
|
||||
bool excl)
|
||||
{
|
||||
struct inode *inode = exofs_new_inode(dir, mode);
|
||||
int err = PTR_ERR(inode);
|
||||
|
|
|
@ -55,7 +55,7 @@ static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode)
|
|||
* Methods themselves.
|
||||
*/
|
||||
|
||||
static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
|
||||
static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, unsigned int flags)
|
||||
{
|
||||
struct inode * inode;
|
||||
ino_t ino;
|
||||
|
@ -79,7 +79,7 @@ static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, str
|
|||
|
||||
struct dentry *ext2_get_parent(struct dentry *child)
|
||||
{
|
||||
struct qstr dotdot = {.name = "..", .len = 2};
|
||||
struct qstr dotdot = QSTR_INIT("..", 2);
|
||||
unsigned long ino = ext2_inode_by_name(child->d_inode, &dotdot);
|
||||
if (!ino)
|
||||
return ERR_PTR(-ENOENT);
|
||||
|
@ -94,7 +94,7 @@ struct dentry *ext2_get_parent(struct dentry *child)
|
|||
* If the create succeeds, we fill in the inode information
|
||||
* with d_instantiate().
|
||||
*/
|
||||
static int ext2_create (struct inode * dir, struct dentry * dentry, umode_t mode, struct nameidata *nd)
|
||||
static int ext2_create (struct inode * dir, struct dentry * dentry, umode_t mode, bool excl)
|
||||
{
|
||||
struct inode *inode;
|
||||
|
||||
|
@ -119,6 +119,29 @@ static int ext2_create (struct inode * dir, struct dentry * dentry, umode_t mode
|
|||
return ext2_add_nondir(dentry, inode);
|
||||
}
|
||||
|
||||
static int ext2_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
struct inode *inode = ext2_new_inode(dir, mode, NULL);
|
||||
if (IS_ERR(inode))
|
||||
return PTR_ERR(inode);
|
||||
|
||||
inode->i_op = &ext2_file_inode_operations;
|
||||
if (ext2_use_xip(inode->i_sb)) {
|
||||
inode->i_mapping->a_ops = &ext2_aops_xip;
|
||||
inode->i_fop = &ext2_xip_file_operations;
|
||||
} else if (test_opt(inode->i_sb, NOBH)) {
|
||||
inode->i_mapping->a_ops = &ext2_nobh_aops;
|
||||
inode->i_fop = &ext2_file_operations;
|
||||
} else {
|
||||
inode->i_mapping->a_ops = &ext2_aops;
|
||||
inode->i_fop = &ext2_file_operations;
|
||||
}
|
||||
mark_inode_dirty(inode);
|
||||
d_tmpfile(dentry, inode);
|
||||
unlock_new_inode(inode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ext2_mknod (struct inode * dir, struct dentry *dentry, umode_t mode, dev_t rdev)
|
||||
{
|
||||
struct inode * inode;
|
||||
|
@ -398,6 +421,7 @@ const struct inode_operations ext2_dir_inode_operations = {
|
|||
#endif
|
||||
.setattr = ext2_setattr,
|
||||
.get_acl = ext2_get_acl,
|
||||
.tmpfile = ext2_tmpfile,
|
||||
};
|
||||
|
||||
const struct inode_operations ext2_special_inode_operations = {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue