Merge f7301270a2 ("Merge tag 'm68k-for-v6.4-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k") into android-mainline

Steps on the way to 6.4-rc1

Change-Id: I8df228b545883b601b406d1bb36a3c56343e76f5
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2023-05-16 11:35:38 +00:00
112 changed files with 1323 additions and 1151 deletions
+2 -2
View File
@@ -40,8 +40,8 @@ Here are the main features of EROFS:
- Support multiple devices to refer to external blobs, which can be used
for container images;
- 4KiB block size and 32-bit block addresses for each device, therefore
16TiB address space at most for now;
- 32-bit block addresses for each device, therefore 16TiB address space at
most with 4KiB block size for now;
- Two inode layouts for different requirements:
+125 -53
View File
@@ -241,7 +241,7 @@ according to the filesystem's idmapping as this would give the wrong owner if
the caller is using an idmapping.
So the kernel will map the id back up in the idmapping of the caller. Let's
assume the caller has the slighly unconventional idmapping
assume the caller has the somewhat unconventional idmapping
``u3000:k20000:r10000`` then ``k21000`` would map back up to ``u4000``.
Consequently the user would see that this file is owned by ``u4000``.
@@ -320,6 +320,10 @@ and equally wrong::
from_kuid(u20000:k0:r10000, u1000) = k21000
~~~~~
Since userspace ids have type ``uid_t`` and ``gid_t`` and kernel ids have type
``kuid_t`` and ``kgid_t`` the compiler will throw an error when they are
conflated. So the two examples above would cause a compilation failure.
Idmappings when creating filesystem objects
-------------------------------------------
@@ -623,42 +627,105 @@ privileged users in the initial user namespace.
However, it is perfectly possible to combine idmapped mounts with filesystems
mountable inside user namespaces. We will touch on this further below.
Filesystem types vs idmapped mount types
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
With the introduction of idmapped mounts we need to distinguish between
filesystem ownership and mount ownership of a VFS object such as an inode. The
owner of a inode might be different when looked at from a filesystem
perspective than when looked at from an idmapped mount. Such fundamental
conceptual distinctions should almost always be clearly expressed in the code.
So, to distinguish idmapped mount ownership from filesystem ownership separate
types have been introduced.
If a uid or gid has been generated using the filesystem or caller's idmapping
then we will use the ``kuid_t`` and ``kgid_t`` types. However, if a uid or gid
has been generated using a mount idmapping then we will be using the dedicated
``vfsuid_t`` and ``vfsgid_t`` types.
All VFS helpers that generate or take uids and gids as arguments use the
``vfsuid_t`` and ``vfsgid_t`` types and we will be able to rely on the compiler
to catch errors that originate from conflating filesystem and VFS uids and gids.
The ``vfsuid_t`` and ``vfsgid_t`` types are often mapped from and to ``kuid_t``
and ``kgid_t`` types similar how ``kuid_t`` and ``kgid_t`` types are mapped
from and to ``uid_t`` and ``gid_t`` types::
uid_t <--> kuid_t <--> vfsuid_t
gid_t <--> kgid_t <--> vfsgid_t
Whenever we report ownership based on a ``vfsuid_t`` or ``vfsgid_t`` type,
e.g., during ``stat()``, or store ownership information in a shared VFS object
based on a ``vfsuid_t`` or ``vfsgid_t`` type, e.g., during ``chown()`` we can
use the ``vfsuid_into_kuid()`` and ``vfsgid_into_kgid()`` helpers.
To illustrate why this helper currently exists, consider what happens when we
change ownership of an inode from an idmapped mount. After we generated
a ``vfsuid_t`` or ``vfsgid_t`` based on the mount idmapping we later commit to
this ``vfsuid_t`` or ``vfsgid_t`` to become the new filesytem wide ownership.
Thus, we are turning the ``vfsuid_t`` or ``vfsgid_t`` into a global ``kuid_t``
or ``kgid_t``. And this can be done by using ``vfsuid_into_kuid()`` and
``vfsgid_into_kgid()``.
Note, whenever a shared VFS object, e.g., a cached ``struct inode`` or a cached
``struct posix_acl``, stores ownership information a filesystem or "global"
``kuid_t`` and ``kgid_t`` must be used. Ownership expressed via ``vfsuid_t``
and ``vfsgid_t`` is specific to an idmapped mount.
We already noted that ``vfsuid_t`` and ``vfsgid_t`` types are generated based
on mount idmappings whereas ``kuid_t`` and ``kgid_t`` types are generated based
on filesystem idmappings. To prevent abusing filesystem idmappings to generate
``vfsuid_t`` or ``vfsgid_t`` types or mount idmappings to generate ``kuid_t``
or ``kgid_t`` types filesystem idmappings and mount idmappings are different
types as well.
All helpers that map to or from ``vfsuid_t`` and ``vfsgid_t`` types require
a mount idmapping to be passed which is of type ``struct mnt_idmap``. Passing
a filesystem or caller idmapping will cause a compilation error.
Similar to how we prefix all userspace ids in this document with ``u`` and all
kernel ids with ``k`` we will prefix all VFS ids with ``v``. So a mount
idmapping will be written as: ``u0:v10000:r10000``.
Remapping helpers
~~~~~~~~~~~~~~~~~
Idmapping functions were added that translate between idmappings. They make use
of the remapping algorithm we've introduced earlier. We're going to look at
two:
of the remapping algorithm we've introduced earlier. We're going to look at:
- ``i_uid_into_mnt()`` and ``i_gid_into_mnt()``
- ``i_uid_into_vfsuid()`` and ``i_gid_into_vfsgid()``
The ``i_*id_into_mnt()`` functions translate filesystem's kernel ids into
kernel ids in the mount's idmapping::
The ``i_*id_into_vfs*id()`` functions translate filesystem's kernel ids into
VFS ids in the mount's idmapping::
/* Map the filesystem's kernel id up into a userspace id in the filesystem's idmapping. */
from_kuid(filesystem, kid) = uid
/* Map the filesystem's userspace id down ito a kernel id in the mount's idmapping. */
/* Map the filesystem's userspace id down ito a VFS id in the mount's idmapping. */
make_kuid(mount, uid) = kuid
- ``mapped_fsuid()`` and ``mapped_fsgid()``
The ``mapped_fs*id()`` functions translate the caller's kernel ids into
kernel ids in the filesystem's idmapping. This translation is achieved by
remapping the caller's kernel ids using the mount's idmapping::
remapping the caller's VFS ids using the mount's idmapping::
/* Map the caller's kernel id up into a userspace id in the mount's idmapping. */
/* Map the caller's VFS id up into a userspace id in the mount's idmapping. */
from_kuid(mount, kid) = uid
/* Map the mount's userspace id down into a kernel id in the filesystem's idmapping. */
make_kuid(filesystem, uid) = kuid
- ``vfsuid_into_kuid()`` and ``vfsgid_into_kgid()``
Whenever
Note that these two functions invert each other. Consider the following
idmappings::
caller idmapping: u0:k10000:r10000
filesystem idmapping: u0:k20000:r10000
mount idmapping: u0:k10000:r10000
mount idmapping: u0:v10000:r10000
Assume a file owned by ``u1000`` is read from disk. The filesystem maps this id
to ``k21000`` according to its idmapping. This is what is stored in the
@@ -669,20 +736,21 @@ would usually simply use the crossmapping algorithm and map the filesystem's
kernel id up to a userspace id in the caller's idmapping.
But when the caller is accessing the file on an idmapped mount the kernel will
first call ``i_uid_into_mnt()`` thereby translating the filesystem's kernel id
into a kernel id in the mount's idmapping::
first call ``i_uid_into_vfsuid()`` thereby translating the filesystem's kernel
id into a VFS id in the mount's idmapping::
i_uid_into_mnt(k21000):
i_uid_into_vfsuid(k21000):
/* Map the filesystem's kernel id up into a userspace id. */
from_kuid(u0:k20000:r10000, k21000) = u1000
/* Map the filesystem's userspace id down ito a kernel id in the mount's idmapping. */
make_kuid(u0:k10000:r10000, u1000) = k11000
/* Map the filesystem's userspace id down into a VFS id in the mount's idmapping. */
make_kuid(u0:v10000:r10000, u1000) = v11000
Finally, when the kernel reports the owner to the caller it will turn the
kernel id in the mount's idmapping into a userspace id in the caller's
VFS id in the mount's idmapping into a userspace id in the caller's
idmapping::
k11000 = vfsuid_into_kuid(v11000)
from_kuid(u0:k10000:r10000, k11000) = u1000
We can test whether this algorithm really works by verifying what happens when
@@ -696,18 +764,19 @@ fails.
But when the caller is accessing the file on an idmapped mount the kernel will
first call ``mapped_fs*id()`` thereby translating the caller's kernel id into
a kernel id according to the mount's idmapping::
a VFS id according to the mount's idmapping::
mapped_fsuid(k11000):
/* Map the caller's kernel id up into a userspace id in the mount's idmapping. */
from_kuid(u0:k10000:r10000, k11000) = u1000
/* Map the mount's userspace id down into a kernel id in the filesystem's idmapping. */
make_kuid(u0:k20000:r10000, u1000) = k21000
make_kuid(u0:v20000:r10000, u1000) = v21000
When finally writing to disk the kernel will then map ``k21000`` up into a
When finally writing to disk the kernel will then map ``v21000`` up into a
userspace id in the filesystem's idmapping::
k21000 = vfsuid_into_kuid(v21000)
from_kuid(u0:k20000:r10000, k21000) = u1000
As we can see, we end up with an invertible and therefore information
@@ -725,7 +794,7 @@ Example 2 reconsidered
caller id: u1000
caller idmapping: u0:k10000:r10000
filesystem idmapping: u0:k20000:r10000
mount idmapping: u0:k10000:r10000
mount idmapping: u0:v10000:r10000
When the caller is using a non-initial idmapping the common case is to attach
the same idmapping to the mount. We now perform three steps:
@@ -734,12 +803,12 @@ the same idmapping to the mount. We now perform three steps:
make_kuid(u0:k10000:r10000, u1000) = k11000
2. Translate the caller's kernel id into a kernel id in the filesystem's
2. Translate the caller's VFS id into a kernel id in the filesystem's
idmapping::
mapped_fsuid(k11000):
/* Map the kernel id up into a userspace id in the mount's idmapping. */
from_kuid(u0:k10000:r10000, k11000) = u1000
mapped_fsuid(v11000):
/* Map the VFS id up into a userspace id in the mount's idmapping. */
from_kuid(u0:v10000:r10000, v11000) = u1000
/* Map the userspace id down into a kernel id in the filesystem's idmapping. */
make_kuid(u0:k20000:r10000, u1000) = k21000
@@ -759,7 +828,7 @@ Example 3 reconsidered
caller id: u1000
caller idmapping: u0:k10000:r10000
filesystem idmapping: u0:k0:r4294967295
mount idmapping: u0:k10000:r10000
mount idmapping: u0:v10000:r10000
The same translation algorithm works with the third example.
@@ -767,12 +836,12 @@ The same translation algorithm works with the third example.
make_kuid(u0:k10000:r10000, u1000) = k11000
2. Translate the caller's kernel id into a kernel id in the filesystem's
2. Translate the caller's VFS id into a kernel id in the filesystem's
idmapping::
mapped_fsuid(k11000):
/* Map the kernel id up into a userspace id in the mount's idmapping. */
from_kuid(u0:k10000:r10000, k11000) = u1000
mapped_fsuid(v11000):
/* Map the VFS id up into a userspace id in the mount's idmapping. */
from_kuid(u0:v10000:r10000, v11000) = u1000
/* Map the userspace id down into a kernel id in the filesystem's idmapping. */
make_kuid(u0:k0:r4294967295, u1000) = k1000
@@ -792,7 +861,7 @@ Example 4 reconsidered
file id: u1000
caller idmapping: u0:k10000:r10000
filesystem idmapping: u0:k0:r4294967295
mount idmapping: u0:k10000:r10000
mount idmapping: u0:v10000:r10000
In order to report ownership to userspace the kernel now does three steps using
the translation algorithm we introduced earlier:
@@ -802,17 +871,18 @@ the translation algorithm we introduced earlier:
make_kuid(u0:k0:r4294967295, u1000) = k1000
2. Translate the kernel id into a kernel id in the mount's idmapping::
2. Translate the kernel id into a VFS id in the mount's idmapping::
i_uid_into_mnt(k1000):
i_uid_into_vfsuid(k1000):
/* Map the kernel id up into a userspace id in the filesystem's idmapping. */
from_kuid(u0:k0:r4294967295, k1000) = u1000
/* Map the userspace id down into a kernel id in the mounts's idmapping. */
make_kuid(u0:k10000:r10000, u1000) = k11000
/* Map the userspace id down into a VFS id in the mounts's idmapping. */
make_kuid(u0:v10000:r10000, u1000) = v11000
3. Map the kernel id up into a userspace id in the caller's idmapping::
3. Map the VFS id up into a userspace id in the caller's idmapping::
k11000 = vfsuid_into_kuid(v11000)
from_kuid(u0:k10000:r10000, k11000) = u1000
Earlier, the caller's kernel id couldn't be crossmapped in the filesystems's
@@ -828,7 +898,7 @@ Example 5 reconsidered
file id: u1000
caller idmapping: u0:k10000:r10000
filesystem idmapping: u0:k20000:r10000
mount idmapping: u0:k10000:r10000
mount idmapping: u0:v10000:r10000
Again, in order to report ownership to userspace the kernel now does three
steps using the translation algorithm we introduced earlier:
@@ -838,17 +908,18 @@ steps using the translation algorithm we introduced earlier:
make_kuid(u0:k20000:r10000, u1000) = k21000
2. Translate the kernel id into a kernel id in the mount's idmapping::
2. Translate the kernel id into a VFS id in the mount's idmapping::
i_uid_into_mnt(k21000):
i_uid_into_vfsuid(k21000):
/* Map the kernel id up into a userspace id in the filesystem's idmapping. */
from_kuid(u0:k20000:r10000, k21000) = u1000
/* Map the userspace id down into a kernel id in the mounts's idmapping. */
make_kuid(u0:k10000:r10000, u1000) = k11000
/* Map the userspace id down into a VFS id in the mounts's idmapping. */
make_kuid(u0:v10000:r10000, u1000) = v11000
3. Map the kernel id up into a userspace id in the caller's idmapping::
3. Map the VFS id up into a userspace id in the caller's idmapping::
k11000 = vfsuid_into_kuid(v11000)
from_kuid(u0:k10000:r10000, k11000) = u1000
Earlier, the file's kernel id couldn't be crossmapped in the filesystems's
@@ -899,23 +970,23 @@ from above:::
caller id: u1125
caller idmapping: u0:k0:r4294967295
filesystem idmapping: u0:k0:r4294967295
mount idmapping: u1000:k1125:r1
mount idmapping: u1000:v1125:r1
1. Map the caller's userspace ids into kernel ids in the caller's idmapping::
make_kuid(u0:k0:r4294967295, u1125) = k1125
2. Translate the caller's kernel id into a kernel id in the filesystem's
2. Translate the caller's VFS id into a kernel id in the filesystem's
idmapping::
mapped_fsuid(k1125):
/* Map the kernel id up into a userspace id in the mount's idmapping. */
from_kuid(u1000:k1125:r1, k1125) = u1000
mapped_fsuid(v1125):
/* Map the VFS id up into a userspace id in the mount's idmapping. */
from_kuid(u1000:v1125:r1, v1125) = u1000
/* Map the userspace id down into a kernel id in the filesystem's idmapping. */
make_kuid(u0:k0:r4294967295, u1000) = k1000
2. Verify that the caller's kernel ids can be mapped to userspace ids in the
2. Verify that the caller's filesystem ids can be mapped to userspace ids in the
filesystem's idmapping::
from_kuid(u0:k0:r4294967295, k1000) = u1000
@@ -930,24 +1001,25 @@ on their work computer:
file id: u1000
caller idmapping: u0:k0:r4294967295
filesystem idmapping: u0:k0:r4294967295
mount idmapping: u1000:k1125:r1
mount idmapping: u1000:v1125:r1
1. Map the userspace id on disk down into a kernel id in the filesystem's
idmapping::
make_kuid(u0:k0:r4294967295, u1000) = k1000
2. Translate the kernel id into a kernel id in the mount's idmapping::
2. Translate the kernel id into a VFS id in the mount's idmapping::
i_uid_into_mnt(k1000):
i_uid_into_vfsuid(k1000):
/* Map the kernel id up into a userspace id in the filesystem's idmapping. */
from_kuid(u0:k0:r4294967295, k1000) = u1000
/* Map the userspace id down into a kernel id in the mounts's idmapping. */
make_kuid(u1000:k1125:r1, u1000) = k1125
/* Map the userspace id down into a VFS id in the mounts's idmapping. */
make_kuid(u1000:v1125:r1, u1000) = v1125
3. Map the kernel id up into a userspace id in the caller's idmapping::
3. Map the VFS id up into a userspace id in the caller's idmapping::
k1125 = vfsuid_into_kuid(v1125)
from_kuid(u0:k0:r4294967295, k1125) = u1125
So ultimately the caller will be reported that the file belongs to ``u1125``
-1
View File
@@ -79,7 +79,6 @@ context. This is represented by the fs_context structure::
unsigned int sb_flags;
unsigned int sb_flags_mask;
unsigned int s_iflags;
unsigned int lsm_flags;
enum fs_context_purpose purpose:8;
...
};
-5
View File
@@ -36,11 +36,6 @@ config HIGHPROFILE
help
Use a fast secondary clock to produce profiling information.
config NO_KERNEL_MSG
bool "Suppress Kernel BUG Messages"
help
Do not output any debug BUG messages within the kernel.
config BDM_DISABLE
bool "Disable BDM signals"
depends on COLDFIRE
+2 -1
View File
@@ -214,7 +214,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_NETMAP=m
CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
@@ -495,6 +494,7 @@ CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
CONFIG_RPCSEC_GSS_KRB5=m
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
# CONFIG_CIFS_DEBUG is not set
@@ -621,6 +621,7 @@ CONFIG_WW_MUTEX_SELFTEST=m
CONFIG_EARLY_PRINTK=y
CONFIG_KUNIT=m
CONFIG_KUNIT_ALL_TESTS=m
CONFIG_TEST_DHRY=m
CONFIG_TEST_MIN_HEAP=m
CONFIG_TEST_DIV64=m
CONFIG_REED_SOLOMON_TEST=m
+2 -1
View File
@@ -210,7 +210,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_NETMAP=m
CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
@@ -452,6 +451,7 @@ CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
CONFIG_RPCSEC_GSS_KRB5=m
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
# CONFIG_CIFS_DEBUG is not set
@@ -577,6 +577,7 @@ CONFIG_WW_MUTEX_SELFTEST=m
CONFIG_EARLY_PRINTK=y
CONFIG_KUNIT=m
CONFIG_KUNIT_ALL_TESTS=m
CONFIG_TEST_DHRY=m
CONFIG_TEST_MIN_HEAP=m
CONFIG_TEST_DIV64=m
CONFIG_REED_SOLOMON_TEST=m
+2 -1
View File
@@ -217,7 +217,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_NETMAP=m
CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
@@ -472,6 +471,7 @@ CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
CONFIG_RPCSEC_GSS_KRB5=m
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
# CONFIG_CIFS_DEBUG is not set
@@ -598,6 +598,7 @@ CONFIG_WW_MUTEX_SELFTEST=m
CONFIG_EARLY_PRINTK=y
CONFIG_KUNIT=m
CONFIG_KUNIT_ALL_TESTS=m
CONFIG_TEST_DHRY=m
CONFIG_TEST_MIN_HEAP=m
CONFIG_TEST_DIV64=m
CONFIG_REED_SOLOMON_TEST=m
+2 -1
View File
@@ -207,7 +207,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_NETMAP=m
CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
@@ -444,6 +443,7 @@ CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
CONFIG_RPCSEC_GSS_KRB5=m
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
# CONFIG_CIFS_DEBUG is not set
@@ -569,6 +569,7 @@ CONFIG_WW_MUTEX_SELFTEST=m
CONFIG_EARLY_PRINTK=y
CONFIG_KUNIT=m
CONFIG_KUNIT_ALL_TESTS=m
CONFIG_TEST_DHRY=m
CONFIG_TEST_MIN_HEAP=m
CONFIG_TEST_DIV64=m
CONFIG_REED_SOLOMON_TEST=m
+2 -1
View File
@@ -209,7 +209,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_NETMAP=m
CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
@@ -454,6 +453,7 @@ CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
CONFIG_RPCSEC_GSS_KRB5=m
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
# CONFIG_CIFS_DEBUG is not set
@@ -579,6 +579,7 @@ CONFIG_WW_MUTEX_SELFTEST=m
CONFIG_EARLY_PRINTK=y
CONFIG_KUNIT=m
CONFIG_KUNIT_ALL_TESTS=m
CONFIG_TEST_DHRY=m
CONFIG_TEST_MIN_HEAP=m
CONFIG_TEST_DIV64=m
CONFIG_REED_SOLOMON_TEST=m
+2 -1
View File
@@ -208,7 +208,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_NETMAP=m
CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
@@ -474,6 +473,7 @@ CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
CONFIG_RPCSEC_GSS_KRB5=m
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
# CONFIG_CIFS_DEBUG is not set
@@ -600,6 +600,7 @@ CONFIG_WW_MUTEX_SELFTEST=m
CONFIG_EARLY_PRINTK=y
CONFIG_KUNIT=m
CONFIG_KUNIT_ALL_TESTS=m
CONFIG_TEST_DHRY=m
CONFIG_TEST_MIN_HEAP=m
CONFIG_TEST_DIV64=m
CONFIG_REED_SOLOMON_TEST=m
+2 -2
View File
@@ -228,7 +228,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_NETMAP=m
CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
@@ -314,7 +313,6 @@ CONFIG_AF_KCM=m
# CONFIG_WIRELESS is not set
CONFIG_PSAMPLE=m
CONFIG_NET_IFE=m
CONFIG_PCCARD=y
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_TEST_ASYNC_DRIVER_PROBE=m
@@ -561,6 +559,7 @@ CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
CONFIG_RPCSEC_GSS_KRB5=m
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
# CONFIG_CIFS_DEBUG is not set
@@ -687,6 +686,7 @@ CONFIG_WW_MUTEX_SELFTEST=m
CONFIG_EARLY_PRINTK=y
CONFIG_KUNIT=m
CONFIG_KUNIT_ALL_TESTS=m
CONFIG_TEST_DHRY=m
CONFIG_TEST_MIN_HEAP=m
CONFIG_TEST_DIV64=m
CONFIG_REED_SOLOMON_TEST=m
+2 -1
View File
@@ -206,7 +206,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_NETMAP=m
CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
@@ -443,6 +442,7 @@ CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
CONFIG_RPCSEC_GSS_KRB5=m
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
# CONFIG_CIFS_DEBUG is not set
@@ -568,6 +568,7 @@ CONFIG_WW_MUTEX_SELFTEST=m
CONFIG_EARLY_PRINTK=y
CONFIG_KUNIT=m
CONFIG_KUNIT_ALL_TESTS=m
CONFIG_TEST_DHRY=m
CONFIG_TEST_MIN_HEAP=m
CONFIG_TEST_DIV64=m
CONFIG_REED_SOLOMON_TEST=m
+2 -1
View File
@@ -207,7 +207,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_NETMAP=m
CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
@@ -444,6 +443,7 @@ CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
CONFIG_RPCSEC_GSS_KRB5=m
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
# CONFIG_CIFS_DEBUG is not set
@@ -569,6 +569,7 @@ CONFIG_WW_MUTEX_SELFTEST=m
CONFIG_EARLY_PRINTK=y
CONFIG_KUNIT=m
CONFIG_KUNIT_ALL_TESTS=m
CONFIG_TEST_DHRY=m
CONFIG_TEST_MIN_HEAP=m
CONFIG_TEST_DIV64=m
CONFIG_REED_SOLOMON_TEST=m
+2 -1
View File
@@ -208,7 +208,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_NETMAP=m
CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
@@ -461,6 +460,7 @@ CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
CONFIG_RPCSEC_GSS_KRB5=m
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
# CONFIG_CIFS_DEBUG is not set
@@ -587,6 +587,7 @@ CONFIG_WW_MUTEX_SELFTEST=m
CONFIG_EARLY_PRINTK=y
CONFIG_KUNIT=m
CONFIG_KUNIT_ALL_TESTS=m
CONFIG_TEST_DHRY=m
CONFIG_TEST_MIN_HEAP=m
CONFIG_TEST_DIV64=m
CONFIG_REED_SOLOMON_TEST=m
+2 -1
View File
@@ -204,7 +204,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_NETMAP=m
CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
@@ -443,6 +442,7 @@ CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
CONFIG_RPCSEC_GSS_KRB5=m
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
# CONFIG_CIFS_DEBUG is not set
@@ -567,6 +567,7 @@ CONFIG_TEST_LOCKUP=m
CONFIG_WW_MUTEX_SELFTEST=m
CONFIG_KUNIT=m
CONFIG_KUNIT_ALL_TESTS=m
CONFIG_TEST_DHRY=m
CONFIG_TEST_MIN_HEAP=m
CONFIG_TEST_DIV64=m
CONFIG_REED_SOLOMON_TEST=m
+2 -1
View File
@@ -204,7 +204,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_NETMAP=m
CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
@@ -442,6 +441,7 @@ CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
CONFIG_RPCSEC_GSS_KRB5=m
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
# CONFIG_CIFS_DEBUG is not set
@@ -567,6 +567,7 @@ CONFIG_WW_MUTEX_SELFTEST=m
CONFIG_EARLY_PRINTK=y
CONFIG_KUNIT=m
CONFIG_KUNIT_ALL_TESTS=m
CONFIG_TEST_DHRY=m
CONFIG_TEST_MIN_HEAP=m
CONFIG_TEST_DIV64=m
CONFIG_REED_SOLOMON_TEST=m
+1
View File
@@ -6,6 +6,7 @@
#include <linux/kexec.h>
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/reboot.h>
#include <asm/cacheflush.h>
#include <asm/page.h>
-3
View File
@@ -96,9 +96,6 @@ static inline struct thread_info *current_thread_info(void)
/* work to do on interrupt/exception return */
#define _TIF_WORK_MASK 0x0000FFFE
/* work to do on any return to u-space */
# define _TIF_ALLWORK_MASK 0x0000FFFF
#endif /* __KERNEL__ */
#endif /* _ASM_NIOS2_THREAD_INFO_H */
+5 -6
View File
@@ -892,20 +892,19 @@ static struct miscdevice sgx_dev_provision = {
int sgx_set_attribute(unsigned long *allowed_attributes,
unsigned int attribute_fd)
{
struct file *file;
struct fd f = fdget(attribute_fd);
file = fget(attribute_fd);
if (!file)
if (!f.file)
return -EINVAL;
if (file->f_op != &sgx_provision_fops) {
fput(file);
if (f.file->f_op != &sgx_provision_fops) {
fdput(f);
return -EINVAL;
}
*allowed_attributes |= SGX_ATTR_PROVISIONKEY;
fput(file);
fdput(f);
return 0;
}
EXPORT_SYMBOL_GPL(sgx_set_attribute);
+14 -12
View File
@@ -1767,18 +1767,20 @@ int sev_vm_move_enc_context_from(struct kvm *kvm, unsigned int source_fd)
{
struct kvm_sev_info *dst_sev = &to_kvm_svm(kvm)->sev_info;
struct kvm_sev_info *src_sev, *cg_cleanup_sev;
struct file *source_kvm_file;
struct fd f = fdget(source_fd);
struct kvm *source_kvm;
bool charged = false;
int ret;
source_kvm_file = fget(source_fd);
if (!file_is_kvm(source_kvm_file)) {
if (!f.file)
return -EBADF;
if (!file_is_kvm(f.file)) {
ret = -EBADF;
goto out_fput;
}
source_kvm = source_kvm_file->private_data;
source_kvm = f.file->private_data;
ret = sev_lock_two_vms(kvm, source_kvm);
if (ret)
goto out_fput;
@@ -1828,8 +1830,7 @@ out_dst_cgroup:
out_unlock:
sev_unlock_two_vms(kvm, source_kvm);
out_fput:
if (source_kvm_file)
fput(source_kvm_file);
fdput(f);
return ret;
}
@@ -2046,18 +2047,20 @@ failed:
int sev_vm_copy_enc_context_from(struct kvm *kvm, unsigned int source_fd)
{
struct file *source_kvm_file;
struct fd f = fdget(source_fd);
struct kvm *source_kvm;
struct kvm_sev_info *source_sev, *mirror_sev;
int ret;
source_kvm_file = fget(source_fd);
if (!file_is_kvm(source_kvm_file)) {
if (!f.file)
return -EBADF;
if (!file_is_kvm(f.file)) {
ret = -EBADF;
goto e_source_fput;
}
source_kvm = source_kvm_file->private_data;
source_kvm = f.file->private_data;
ret = sev_lock_two_vms(kvm, source_kvm);
if (ret)
goto e_source_fput;
@@ -2103,8 +2106,7 @@ int sev_vm_copy_enc_context_from(struct kvm *kvm, unsigned int source_fd)
e_unlock:
sev_unlock_two_vms(kvm, source_kvm);
e_source_fput:
if (source_kvm_file)
fput(source_kvm_file);
fdput(f);
return ret;
}
-6
View File
@@ -14,11 +14,6 @@
#define to_nubus_board(d) container_of(d, struct nubus_board, dev)
#define to_nubus_driver(d) container_of(d, struct nubus_driver, driver)
static int nubus_bus_match(struct device *dev, struct device_driver *driver)
{
return 1;
}
static int nubus_device_probe(struct device *dev)
{
struct nubus_driver *ndrv = to_nubus_driver(dev->driver);
@@ -39,7 +34,6 @@ static void nubus_device_remove(struct device *dev)
struct bus_type nubus_bus_type = {
.name = "nubus",
.match = nubus_bus_match,
.probe = nubus_device_probe,
.remove = nubus_device_remove,
};
-4
View File
@@ -185,10 +185,6 @@ static struct xattr_handler v9fs_xattr_security_handler = {
const struct xattr_handler *v9fs_xattr_handlers[] = {
&v9fs_xattr_user_handler,
&v9fs_xattr_trusted_handler,
#ifdef CONFIG_FS_POSIX_ACL
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
#endif
#ifdef CONFIG_9P_FS_SECURITY
&v9fs_xattr_security_handler,
#endif
+1
View File
@@ -47,6 +47,7 @@ int setattr_should_drop_sgid(struct mnt_idmap *idmap,
return ATTR_KILL_SGID;
return 0;
}
EXPORT_SYMBOL(setattr_should_drop_sgid);
/**
* setattr_should_drop_suidgid - determine whether the set{g,u}id bit needs to
-4
View File
@@ -444,10 +444,6 @@ static const struct xattr_handler btrfs_btrfs_xattr_handler = {
const struct xattr_handler *btrfs_xattr_handlers[] = {
&btrfs_security_xattr_handler,
#ifdef CONFIG_BTRFS_FS_POSIX_ACL
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
#endif
&btrfs_trusted_xattr_handler,
&btrfs_user_xattr_handler,
&btrfs_btrfs_xattr_handler,
+3 -6
View File
@@ -2581,7 +2581,7 @@ int block_truncate_page(struct address_space *mapping,
struct inode *inode = mapping->host;
struct page *page;
struct buffer_head *bh;
int err;
int err = 0;
blocksize = i_blocksize(inode);
length = offset & (blocksize - 1);
@@ -2594,9 +2594,8 @@ int block_truncate_page(struct address_space *mapping,
iblock = (sector_t)index << (PAGE_SHIFT - inode->i_blkbits);
page = grab_cache_page(mapping, index);
err = -ENOMEM;
if (!page)
goto out;
return -ENOMEM;
if (!page_has_buffers(page))
create_empty_buffers(page, blocksize, 0);
@@ -2610,7 +2609,6 @@ int block_truncate_page(struct address_space *mapping,
pos += blocksize;
}
err = 0;
if (!buffer_mapped(bh)) {
WARN_ON(bh->b_size != blocksize);
err = get_block(inode, iblock, bh, 0);
@@ -2634,12 +2632,11 @@ int block_truncate_page(struct address_space *mapping,
zero_user(page, offset, length);
mark_buffer_dirty(bh);
err = 0;
unlock:
unlock_page(page);
put_page(page);
out:
return err;
}
EXPORT_SYMBOL(block_truncate_page);
-4
View File
@@ -1411,10 +1411,6 @@ void ceph_release_acl_sec_ctx(struct ceph_acl_sec_ctx *as_ctx)
* attributes are handled directly.
*/
const struct xattr_handler *ceph_xattr_handlers[] = {
#ifdef CONFIG_CEPH_FS_POSIX_ACL
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
#endif
&ceph_other_xattr_handler,
NULL,
};
-4
View File
@@ -487,9 +487,5 @@ const struct xattr_handler *cifs_xattr_handlers[] = {
&smb3_ntsd_xattr_handler, /* alias for above since avoiding "cifs" */
&cifs_cifs_ntsd_full_xattr_handler,
&smb3_ntsd_full_xattr_handler, /* alias for above since avoiding "cifs" */
#ifdef CONFIG_FS_POSIX_ACL
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
#endif
NULL
};
+2 -7
View File
@@ -1599,12 +1599,6 @@ static int configfs_dir_close(struct inode *inode, struct file *file)
return 0;
}
/* Relationship between s_mode and the DT_xxx types */
static inline unsigned char dt_type(struct configfs_dirent *sd)
{
return (sd->s_mode >> 12) & 15;
}
static int configfs_readdir(struct file *file, struct dir_context *ctx)
{
struct dentry *dentry = file->f_path.dentry;
@@ -1654,7 +1648,8 @@ static int configfs_readdir(struct file *file, struct dir_context *ctx)
name = configfs_get_name(next);
len = strlen(name);
if (!dir_emit(ctx, name, len, ino, dt_type(next)))
if (!dir_emit(ctx, name, len, ino,
fs_umode_to_dtype(next->s_mode)))
return 0;
spin_lock(&configfs_dirent_lock);
+1 -19
View File
@@ -72,24 +72,6 @@ static struct ctl_table pty_table[] = {
{}
};
static struct ctl_table pty_kern_table[] = {
{
.procname = "pty",
.mode = 0555,
.child = pty_table,
},
{}
};
static struct ctl_table pty_root_table[] = {
{
.procname = "kernel",
.mode = 0555,
.child = pty_kern_table,
},
{}
};
struct pts_mount_opts {
int setuid;
int setgid;
@@ -630,7 +612,7 @@ static int __init init_devpts_fs(void)
{
int err = register_filesystem(&devpts_fs_type);
if (!err) {
register_sysctl_table(pty_root_table);
register_sysctl("kernel/pty", pty_table);
}
return err;
}
+2 -7
View File
@@ -86,7 +86,6 @@ struct dio_submit {
sector_t final_block_in_request;/* doesn't change */
int boundary; /* prev block is at a boundary */
get_block_t *get_block; /* block mapping function */
dio_submit_t *submit_io; /* IO submition function */
loff_t logical_offset_in_bio; /* current first logical block in bio */
sector_t final_block_in_bio; /* current final block in bio + 1 */
@@ -431,10 +430,7 @@ static inline void dio_bio_submit(struct dio *dio, struct dio_submit *sdio)
dio->bio_disk = bio->bi_bdev->bd_disk;
if (sdio->submit_io)
sdio->submit_io(bio, dio->inode, sdio->logical_offset_in_bio);
else
submit_bio(bio);
submit_bio(bio);
sdio->bio = NULL;
sdio->boundary = 0;
@@ -1098,7 +1094,7 @@ static inline int drop_refcount(struct dio *dio)
ssize_t __blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
struct block_device *bdev, struct iov_iter *iter,
get_block_t get_block, dio_iodone_t end_io,
dio_submit_t submit_io, int flags)
int flags)
{
unsigned i_blkbits = READ_ONCE(inode->i_blkbits);
unsigned blkbits = i_blkbits;
@@ -1215,7 +1211,6 @@ ssize_t __blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
sdio.get_block = get_block;
dio->end_io = end_io;
sdio.submit_io = submit_io;
sdio.final_block_in_bio = -1;
sdio.next_block_for_io = -1;
-4
View File
@@ -1210,10 +1210,6 @@ static const struct xattr_handler ecryptfs_xattr_handler = {
};
const struct xattr_handler *ecryptfs_xattr_handlers[] = {
#ifdef CONFIG_FS_POSIX_ACL
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
#endif
&ecryptfs_xattr_handler,
NULL
};
+47 -34
View File
@@ -27,11 +27,15 @@ void erofs_put_metabuf(struct erofs_buf *buf)
buf->page = NULL;
}
void *erofs_bread(struct erofs_buf *buf, struct inode *inode,
erofs_blk_t blkaddr, enum erofs_kmap_type type)
/*
* Derive the block size from inode->i_blkbits to make compatible with
* anonymous inode in fscache mode.
*/
void *erofs_bread(struct erofs_buf *buf, erofs_blk_t blkaddr,
enum erofs_kmap_type type)
{
struct address_space *const mapping = inode->i_mapping;
erofs_off_t offset = blknr_to_addr(blkaddr);
struct inode *inode = buf->inode;
erofs_off_t offset = (erofs_off_t)blkaddr << inode->i_blkbits;
pgoff_t index = offset >> PAGE_SHIFT;
struct page *page = buf->page;
struct folio *folio;
@@ -41,7 +45,7 @@ void *erofs_bread(struct erofs_buf *buf, struct inode *inode,
erofs_put_metabuf(buf);
nofs_flag = memalloc_nofs_save();
folio = read_cache_folio(mapping, index, NULL, NULL);
folio = read_cache_folio(inode->i_mapping, index, NULL, NULL);
memalloc_nofs_restore(nofs_flag);
if (IS_ERR(folio))
return folio;
@@ -63,14 +67,19 @@ void *erofs_bread(struct erofs_buf *buf, struct inode *inode,
return buf->base + (offset & ~PAGE_MASK);
}
void erofs_init_metabuf(struct erofs_buf *buf, struct super_block *sb)
{
if (erofs_is_fscache_mode(sb))
buf->inode = EROFS_SB(sb)->s_fscache->inode;
else
buf->inode = sb->s_bdev->bd_inode;
}
void *erofs_read_metabuf(struct erofs_buf *buf, struct super_block *sb,
erofs_blk_t blkaddr, enum erofs_kmap_type type)
{
if (erofs_is_fscache_mode(sb))
return erofs_bread(buf, EROFS_SB(sb)->s_fscache->inode,
blkaddr, type);
return erofs_bread(buf, sb->s_bdev->bd_inode, blkaddr, type);
erofs_init_metabuf(buf, sb);
return erofs_bread(buf, blkaddr, type);
}
static int erofs_map_blocks_flatmode(struct inode *inode,
@@ -79,33 +88,32 @@ static int erofs_map_blocks_flatmode(struct inode *inode,
erofs_blk_t nblocks, lastblk;
u64 offset = map->m_la;
struct erofs_inode *vi = EROFS_I(inode);
struct super_block *sb = inode->i_sb;
bool tailendpacking = (vi->datalayout == EROFS_INODE_FLAT_INLINE);
nblocks = DIV_ROUND_UP(inode->i_size, EROFS_BLKSIZ);
nblocks = erofs_iblks(inode);
lastblk = nblocks - tailendpacking;
/* there is no hole in flatmode */
map->m_flags = EROFS_MAP_MAPPED;
if (offset < blknr_to_addr(lastblk)) {
map->m_pa = blknr_to_addr(vi->raw_blkaddr) + map->m_la;
map->m_plen = blknr_to_addr(lastblk) - offset;
if (offset < erofs_pos(sb, lastblk)) {
map->m_pa = erofs_pos(sb, vi->raw_blkaddr) + map->m_la;
map->m_plen = erofs_pos(sb, lastblk) - offset;
} else if (tailendpacking) {
map->m_pa = erofs_iloc(inode) + vi->inode_isize +
vi->xattr_isize + erofs_blkoff(offset);
vi->xattr_isize + erofs_blkoff(sb, offset);
map->m_plen = inode->i_size - offset;
/* inline data should be located in the same meta block */
if (erofs_blkoff(map->m_pa) + map->m_plen > EROFS_BLKSIZ) {
erofs_err(inode->i_sb,
"inline data cross block boundary @ nid %llu",
if (erofs_blkoff(sb, map->m_pa) + map->m_plen > sb->s_blocksize) {
erofs_err(sb, "inline data cross block boundary @ nid %llu",
vi->nid);
DBG_BUGON(1);
return -EFSCORRUPTED;
}
map->m_flags |= EROFS_MAP_META;
} else {
erofs_err(inode->i_sb,
"internal error @ nid: %llu (size %llu), m_la 0x%llx",
erofs_err(sb, "internal error @ nid: %llu (size %llu), m_la 0x%llx",
vi->nid, inode->i_size, map->m_la);
DBG_BUGON(1);
return -EIO;
@@ -148,29 +156,29 @@ int erofs_map_blocks(struct inode *inode, struct erofs_map_blocks *map)
pos = ALIGN(erofs_iloc(inode) + vi->inode_isize +
vi->xattr_isize, unit) + unit * chunknr;
kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(pos), EROFS_KMAP);
kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(sb, pos), EROFS_KMAP);
if (IS_ERR(kaddr)) {
err = PTR_ERR(kaddr);
goto out;
}
map->m_la = chunknr << vi->chunkbits;
map->m_plen = min_t(erofs_off_t, 1UL << vi->chunkbits,
roundup(inode->i_size - map->m_la, EROFS_BLKSIZ));
round_up(inode->i_size - map->m_la, sb->s_blocksize));
/* handle block map */
if (!(vi->chunkformat & EROFS_CHUNK_FORMAT_INDEXES)) {
__le32 *blkaddr = kaddr + erofs_blkoff(pos);
__le32 *blkaddr = kaddr + erofs_blkoff(sb, pos);
if (le32_to_cpu(*blkaddr) == EROFS_NULL_ADDR) {
map->m_flags = 0;
} else {
map->m_pa = blknr_to_addr(le32_to_cpu(*blkaddr));
map->m_pa = erofs_pos(sb, le32_to_cpu(*blkaddr));
map->m_flags = EROFS_MAP_MAPPED;
}
goto out_unlock;
}
/* parse chunk indexes */
idx = kaddr + erofs_blkoff(pos);
idx = kaddr + erofs_blkoff(sb, pos);
switch (le32_to_cpu(idx->blkaddr)) {
case EROFS_NULL_ADDR:
map->m_flags = 0;
@@ -178,7 +186,7 @@ int erofs_map_blocks(struct inode *inode, struct erofs_map_blocks *map)
default:
map->m_deviceid = le16_to_cpu(idx->device_id) &
EROFS_SB(sb)->device_id_mask;
map->m_pa = blknr_to_addr(le32_to_cpu(idx->blkaddr));
map->m_pa = erofs_pos(sb, le32_to_cpu(idx->blkaddr));
map->m_flags = EROFS_MAP_MAPPED;
break;
}
@@ -197,7 +205,6 @@ int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *map)
struct erofs_device_info *dif;
int id;
/* primary device by default */
map->m_bdev = sb->s_bdev;
map->m_daxdev = EROFS_SB(sb)->dax_dev;
map->m_dax_part_off = EROFS_SB(sb)->dax_part_off;
@@ -210,20 +217,25 @@ int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *map)
up_read(&devs->rwsem);
return -ENODEV;
}
if (devs->flatdev) {
map->m_pa += erofs_pos(sb, dif->mapped_blkaddr);
up_read(&devs->rwsem);
return 0;
}
map->m_bdev = dif->bdev;
map->m_daxdev = dif->dax_dev;
map->m_dax_part_off = dif->dax_part_off;
map->m_fscache = dif->fscache;
up_read(&devs->rwsem);
} else if (devs->extra_devices) {
} else if (devs->extra_devices && !devs->flatdev) {
down_read(&devs->rwsem);
idr_for_each_entry(&devs->tree, dif, id) {
erofs_off_t startoff, length;
if (!dif->mapped_blkaddr)
continue;
startoff = blknr_to_addr(dif->mapped_blkaddr);
length = blknr_to_addr(dif->blocks);
startoff = erofs_pos(sb, dif->mapped_blkaddr);
length = erofs_pos(sb, dif->blocks);
if (map->m_pa >= startoff &&
map->m_pa < startoff + length) {
@@ -244,6 +256,7 @@ static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
unsigned int flags, struct iomap *iomap, struct iomap *srcmap)
{
int ret;
struct super_block *sb = inode->i_sb;
struct erofs_map_blocks map;
struct erofs_map_dev mdev;
@@ -258,7 +271,7 @@ static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
.m_deviceid = map.m_deviceid,
.m_pa = map.m_pa,
};
ret = erofs_map_dev(inode->i_sb, &mdev);
ret = erofs_map_dev(sb, &mdev);
if (ret)
return ret;
@@ -284,11 +297,11 @@ static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
iomap->type = IOMAP_INLINE;
ptr = erofs_read_metabuf(&buf, inode->i_sb,
erofs_blknr(mdev.m_pa), EROFS_KMAP);
ptr = erofs_read_metabuf(&buf, sb,
erofs_blknr(sb, mdev.m_pa), EROFS_KMAP);
if (IS_ERR(ptr))
return PTR_ERR(ptr);
iomap->inline_data = ptr + erofs_blkoff(mdev.m_pa);
iomap->inline_data = ptr + erofs_blkoff(sb, mdev.m_pa);
iomap->private = buf.base;
} else {
iomap->type = IOMAP_MAPPED;
+3 -3
View File
@@ -42,7 +42,7 @@ int z_erofs_load_lz4_config(struct super_block *sb,
if (!sbi->lz4.max_pclusterblks) {
sbi->lz4.max_pclusterblks = 1; /* reserved case */
} else if (sbi->lz4.max_pclusterblks >
Z_EROFS_PCLUSTER_MAX_SIZE / EROFS_BLKSIZ) {
erofs_blknr(sb, Z_EROFS_PCLUSTER_MAX_SIZE)) {
erofs_err(sb, "too large lz4 pclusterblks %u",
sbi->lz4.max_pclusterblks);
return -EINVAL;
@@ -221,13 +221,13 @@ static int z_erofs_lz4_decompress_mem(struct z_erofs_lz4_decompress_ctx *ctx,
support_0padding = true;
ret = z_erofs_fixup_insize(rq, headpage + rq->pageofs_in,
min_t(unsigned int, rq->inputsize,
EROFS_BLKSIZ - rq->pageofs_in));
rq->sb->s_blocksize - rq->pageofs_in));
if (ret) {
kunmap_atomic(headpage);
return ret;
}
may_inplace = !((rq->pageofs_in + rq->inputsize) &
(EROFS_BLKSIZ - 1));
(rq->sb->s_blocksize - 1));
}
inputmargin = rq->pageofs_in;
+2 -2
View File
@@ -166,8 +166,8 @@ int z_erofs_lzma_decompress(struct z_erofs_decompress_req *rq,
/* 1. get the exact LZMA compressed size */
kin = kmap(*rq->in);
err = z_erofs_fixup_insize(rq, kin + rq->pageofs_in,
min_t(unsigned int, rq->inputsize,
EROFS_BLKSIZ - rq->pageofs_in));
min_t(unsigned int, rq->inputsize,
rq->sb->s_blocksize - rq->pageofs_in));
if (err) {
kunmap(*rq->in);
return err;
+12 -13
View File
@@ -50,44 +50,43 @@ static int erofs_readdir(struct file *f, struct dir_context *ctx)
{
struct inode *dir = file_inode(f);
struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
struct super_block *sb = dir->i_sb;
unsigned long bsz = sb->s_blocksize;
const size_t dirsize = i_size_read(dir);
unsigned int i = ctx->pos / EROFS_BLKSIZ;
unsigned int ofs = ctx->pos % EROFS_BLKSIZ;
unsigned int i = erofs_blknr(sb, ctx->pos);
unsigned int ofs = erofs_blkoff(sb, ctx->pos);
int err = 0;
bool initial = true;
buf.inode = dir;
while (ctx->pos < dirsize) {
struct erofs_dirent *de;
unsigned int nameoff, maxsize;
de = erofs_bread(&buf, dir, i, EROFS_KMAP);
de = erofs_bread(&buf, i, EROFS_KMAP);
if (IS_ERR(de)) {
erofs_err(dir->i_sb,
"fail to readdir of logical block %u of nid %llu",
erofs_err(sb, "fail to readdir of logical block %u of nid %llu",
i, EROFS_I(dir)->nid);
err = PTR_ERR(de);
break;
}
nameoff = le16_to_cpu(de->nameoff);
if (nameoff < sizeof(struct erofs_dirent) ||
nameoff >= EROFS_BLKSIZ) {
erofs_err(dir->i_sb,
"invalid de[0].nameoff %u @ nid %llu",
if (nameoff < sizeof(struct erofs_dirent) || nameoff >= bsz) {
erofs_err(sb, "invalid de[0].nameoff %u @ nid %llu",
nameoff, EROFS_I(dir)->nid);
err = -EFSCORRUPTED;
break;
}
maxsize = min_t(unsigned int,
dirsize - ctx->pos + ofs, EROFS_BLKSIZ);
maxsize = min_t(unsigned int, dirsize - ctx->pos + ofs, bsz);
/* search dirents at the arbitrary position */
if (initial) {
initial = false;
ofs = roundup(ofs, sizeof(struct erofs_dirent));
ctx->pos = blknr_to_addr(i) + ofs;
ctx->pos = erofs_pos(sb, i) + ofs;
if (ofs >= nameoff)
goto skip_this;
}
@@ -97,7 +96,7 @@ static int erofs_readdir(struct file *f, struct dir_context *ctx)
if (err)
break;
skip_this:
ctx->pos = blknr_to_addr(i) + maxsize;
ctx->pos = erofs_pos(sb, i) + maxsize;
++i;
ofs = 0;
}
+85 -89
View File
@@ -27,6 +27,7 @@
#define EROFS_FEATURE_INCOMPAT_ZTAILPACKING 0x00000010
#define EROFS_FEATURE_INCOMPAT_FRAGMENTS 0x00000020
#define EROFS_FEATURE_INCOMPAT_DEDUPE 0x00000020
#define EROFS_FEATURE_INCOMPAT_XATTR_PREFIXES 0x00000040
#define EROFS_ALL_FEATURE_INCOMPAT \
(EROFS_FEATURE_INCOMPAT_ZERO_PADDING | \
EROFS_FEATURE_INCOMPAT_COMPR_CFGS | \
@@ -36,7 +37,8 @@
EROFS_FEATURE_INCOMPAT_COMPR_HEAD2 | \
EROFS_FEATURE_INCOMPAT_ZTAILPACKING | \
EROFS_FEATURE_INCOMPAT_FRAGMENTS | \
EROFS_FEATURE_INCOMPAT_DEDUPE)
EROFS_FEATURE_INCOMPAT_DEDUPE | \
EROFS_FEATURE_INCOMPAT_XATTR_PREFIXES)
#define EROFS_SB_EXTSLOT_SIZE 16
@@ -53,7 +55,7 @@ struct erofs_super_block {
__le32 magic; /* file system magic number */
__le32 checksum; /* crc32c(super_block) */
__le32 feature_compat;
__u8 blkszbits; /* support block_size == PAGE_SIZE only */
__u8 blkszbits; /* filesystem block size in bit shift */
__u8 sb_extslots; /* superblock size = 128 + sb_extslots * 16 */
__le16 root_nid; /* nid of root directory */
@@ -75,49 +77,46 @@ struct erofs_super_block {
} __packed u1;
__le16 extra_devices; /* # of devices besides the primary device */
__le16 devt_slotoff; /* startoff = devt_slotoff * devt_slotsize */
__u8 reserved[6];
__u8 dirblkbits; /* directory block size in bit shift */
__u8 xattr_prefix_count; /* # of long xattr name prefixes */
__le32 xattr_prefix_start; /* start of long xattr prefixes */
__le64 packed_nid; /* nid of the special packed inode */
__u8 reserved2[24];
};
/*
* erofs inode datalayout (i_format in on-disk inode):
* EROFS inode datalayout (i_format in on-disk inode):
* 0 - uncompressed flat inode without tail-packing inline data:
* inode, [xattrs], ... | ... | no-holed data
* 1 - compressed inode with non-compact indexes:
* inode, [xattrs], [map_header], extents ... | ...
* 2 - uncompressed flat inode with tail-packing inline data:
* inode, [xattrs], tailpacking data, ... | ... | no-holed data
* 3 - compressed inode with compact indexes:
* inode, [xattrs], map_header, extents ... | ...
* 4 - chunk-based inode with (optional) multi-device support:
* inode, [xattrs], chunk indexes ... | ...
* 5~7 - reserved
*/
enum {
EROFS_INODE_FLAT_PLAIN = 0,
EROFS_INODE_FLAT_COMPRESSION_LEGACY = 1,
EROFS_INODE_COMPRESSED_FULL = 1,
EROFS_INODE_FLAT_INLINE = 2,
EROFS_INODE_FLAT_COMPRESSION = 3,
EROFS_INODE_COMPRESSED_COMPACT = 3,
EROFS_INODE_CHUNK_BASED = 4,
EROFS_INODE_DATALAYOUT_MAX
};
static inline bool erofs_inode_is_data_compressed(unsigned int datamode)
{
return datamode == EROFS_INODE_FLAT_COMPRESSION ||
datamode == EROFS_INODE_FLAT_COMPRESSION_LEGACY;
return datamode == EROFS_INODE_COMPRESSED_COMPACT ||
datamode == EROFS_INODE_COMPRESSED_FULL;
}
/* bit definitions of inode i_format */
#define EROFS_I_VERSION_BITS 1
#define EROFS_I_DATALAYOUT_BITS 3
#define EROFS_I_VERSION_MASK 0x01
#define EROFS_I_DATALAYOUT_MASK 0x07
#define EROFS_I_VERSION_BIT 0
#define EROFS_I_DATALAYOUT_BIT 1
#define EROFS_I_ALL_BIT 4
#define EROFS_I_ALL \
((1 << (EROFS_I_DATALAYOUT_BIT + EROFS_I_DATALAYOUT_BITS)) - 1)
#define EROFS_I_ALL ((1 << EROFS_I_ALL_BIT) - 1)
/* indicate chunk blkbits, thus 'chunksize = blocksize << chunk blkbits' */
#define EROFS_CHUNK_FORMAT_BLKBITS_MASK 0x001F
@@ -127,11 +126,30 @@ static inline bool erofs_inode_is_data_compressed(unsigned int datamode)
#define EROFS_CHUNK_FORMAT_ALL \
(EROFS_CHUNK_FORMAT_BLKBITS_MASK | EROFS_CHUNK_FORMAT_INDEXES)
/* 32-byte on-disk inode */
#define EROFS_INODE_LAYOUT_COMPACT 0
/* 64-byte on-disk inode */
#define EROFS_INODE_LAYOUT_EXTENDED 1
struct erofs_inode_chunk_info {
__le16 format; /* chunk blkbits, etc. */
__le16 reserved;
};
union erofs_inode_i_u {
/* total compressed blocks for compressed inodes */
__le32 compressed_blocks;
/* block address for uncompressed flat inodes */
__le32 raw_blkaddr;
/* for device files, used to indicate old/new device # */
__le32 rdev;
/* for chunk-based files, it contains the summary info */
struct erofs_inode_chunk_info c;
};
/* 32-byte reduced form of an ondisk inode */
struct erofs_inode_compact {
__le16 i_format; /* inode format hints */
@@ -142,29 +160,14 @@ struct erofs_inode_compact {
__le16 i_nlink;
__le32 i_size;
__le32 i_reserved;
union {
/* total compressed blocks for compressed inodes */
__le32 compressed_blocks;
/* block address for uncompressed flat inodes */
__le32 raw_blkaddr;
union erofs_inode_i_u i_u;
/* for device files, used to indicate old/new device # */
__le32 rdev;
/* for chunk-based files, it contains the summary info */
struct erofs_inode_chunk_info c;
} i_u;
__le32 i_ino; /* only used for 32-bit stat compatibility */
__le32 i_ino; /* only used for 32-bit stat compatibility */
__le16 i_uid;
__le16 i_gid;
__le32 i_reserved2;
};
/* 32-byte on-disk inode */
#define EROFS_INODE_LAYOUT_COMPACT 0
/* 64-byte on-disk inode */
#define EROFS_INODE_LAYOUT_EXTENDED 1
/* 64-byte complete form of an ondisk inode */
struct erofs_inode_extended {
__le16 i_format; /* inode format hints */
@@ -174,22 +177,9 @@ struct erofs_inode_extended {
__le16 i_mode;
__le16 i_reserved;
__le64 i_size;
union {
/* total compressed blocks for compressed inodes */
__le32 compressed_blocks;
/* block address for uncompressed flat inodes */
__le32 raw_blkaddr;
/* for device files, used to indicate old/new device # */
__le32 rdev;
/* for chunk-based files, it contains the summary info */
struct erofs_inode_chunk_info c;
} i_u;
/* only used for 32-bit stat compatibility */
__le32 i_ino;
union erofs_inode_i_u i_u;
__le32 i_ino; /* only used for 32-bit stat compatibility */
__le32 i_uid;
__le32 i_gid;
__le64 i_mtime;
@@ -198,10 +188,6 @@ struct erofs_inode_extended {
__u8 i_reserved2[16];
};
#define EROFS_MAX_SHARED_XATTRS (128)
/* h_shared_count between 129 ... 255 are special # */
#define EROFS_SHARED_XATTR_EXTENT (255)
/*
* inline xattrs (n == i_xattr_icount):
* erofs_xattr_ibody_header(1) + (n - 1) * 4 bytes
@@ -228,6 +214,13 @@ struct erofs_xattr_ibody_header {
#define EROFS_XATTR_INDEX_LUSTRE 5
#define EROFS_XATTR_INDEX_SECURITY 6
/*
* bit 7 of e_name_index is set when it refers to a long xattr name prefix,
* while the remained lower bits represent the index of the prefix.
*/
#define EROFS_XATTR_LONG_PREFIX 0x80
#define EROFS_XATTR_LONG_PREFIX_MASK 0x7f
/* xattr entry (for both inline & shared xattrs) */
struct erofs_xattr_entry {
__u8 e_name_len; /* length of name */
@@ -237,6 +230,12 @@ struct erofs_xattr_entry {
char e_name[]; /* attribute name */
};
/* long xattr name prefix */
struct erofs_xattr_long_prefix {
__u8 base_index; /* short xattr name prefix index */
char infix[]; /* infix apart from short prefix */
};
static inline unsigned int erofs_xattr_ibody_size(__le16 i_xattr_icount)
{
if (!i_xattr_icount)
@@ -267,6 +266,22 @@ struct erofs_inode_chunk_index {
__le32 blkaddr; /* start block address of this inode chunk */
};
/* dirent sorts in alphabet order, thus we can do binary search */
struct erofs_dirent {
__le64 nid; /* node number */
__le16 nameoff; /* start offset of file name */
__u8 file_type; /* file type */
__u8 reserved; /* reserved */
} __packed;
/*
* EROFS file types should match generic FT_* types and
* it seems no need to add BUILD_BUG_ONs since potential
* unmatchness will break other fses as well...
*/
#define EROFS_NAME_LEN 255
/* maximum supported size of a physical compression cluster */
#define Z_EROFS_PCLUSTER_MAX_SIZE (1024 * 1024)
@@ -336,10 +351,8 @@ struct z_erofs_map_header {
__u8 h_clusterbits;
};
#define Z_EROFS_VLE_LEGACY_HEADER_PADDING 8
/*
* Fixed-sized output compression on-disk logical cluster type:
* On-disk logical cluster type:
* 0 - literal (uncompressed) lcluster
* 1,3 - compressed lcluster (for HEAD lclusters)
* 2 - compressed lcluster (for NONHEAD lclusters)
@@ -363,27 +376,27 @@ struct z_erofs_map_header {
* di_u.delta[1] = distance to the next HEAD lcluster
*/
enum {
Z_EROFS_VLE_CLUSTER_TYPE_PLAIN = 0,
Z_EROFS_VLE_CLUSTER_TYPE_HEAD1 = 1,
Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD = 2,
Z_EROFS_VLE_CLUSTER_TYPE_HEAD2 = 3,
Z_EROFS_VLE_CLUSTER_TYPE_MAX
Z_EROFS_LCLUSTER_TYPE_PLAIN = 0,
Z_EROFS_LCLUSTER_TYPE_HEAD1 = 1,
Z_EROFS_LCLUSTER_TYPE_NONHEAD = 2,
Z_EROFS_LCLUSTER_TYPE_HEAD2 = 3,
Z_EROFS_LCLUSTER_TYPE_MAX
};
#define Z_EROFS_VLE_DI_CLUSTER_TYPE_BITS 2
#define Z_EROFS_VLE_DI_CLUSTER_TYPE_BIT 0
#define Z_EROFS_LI_LCLUSTER_TYPE_BITS 2
#define Z_EROFS_LI_LCLUSTER_TYPE_BIT 0
/* (noncompact only, HEAD) This pcluster refers to partial decompressed data */
#define Z_EROFS_VLE_DI_PARTIAL_REF (1 << 15)
#define Z_EROFS_LI_PARTIAL_REF (1 << 15)
/*
* D0_CBLKCNT will be marked _only_ at the 1st non-head lcluster to store the
* compressed block count of a compressed extent (in logical clusters, aka.
* block count of a pcluster).
*/
#define Z_EROFS_VLE_DI_D0_CBLKCNT (1 << 11)
#define Z_EROFS_LI_D0_CBLKCNT (1 << 11)
struct z_erofs_vle_decompressed_index {
struct z_erofs_lcluster_index {
__le16 di_advise;
/* where to decompress in the head lcluster */
__le16 di_clusterofs;
@@ -400,25 +413,8 @@ struct z_erofs_vle_decompressed_index {
} di_u;
};
#define Z_EROFS_VLE_LEGACY_INDEX_ALIGN(size) \
(round_up(size, sizeof(struct z_erofs_vle_decompressed_index)) + \
sizeof(struct z_erofs_map_header) + Z_EROFS_VLE_LEGACY_HEADER_PADDING)
/* dirent sorts in alphabet order, thus we can do binary search */
struct erofs_dirent {
__le64 nid; /* node number */
__le16 nameoff; /* start offset of file name */
__u8 file_type; /* file type */
__u8 reserved; /* reserved */
} __packed;
/*
* EROFS file types should match generic FT_* types and
* it seems no need to add BUILD_BUG_ONs since potential
* unmatchness will break other fses as well...
*/
#define EROFS_NAME_LEN 255
#define Z_EROFS_FULL_INDEX_ALIGN(end) \
(ALIGN(end, 8) + sizeof(struct z_erofs_map_header) + 8)
/* check the EROFS on-disk layout strictly at compile time */
static inline void erofs_check_ondisk_layout_definitions(void)
@@ -435,15 +431,15 @@ static inline void erofs_check_ondisk_layout_definitions(void)
BUILD_BUG_ON(sizeof(struct erofs_inode_chunk_info) != 4);
BUILD_BUG_ON(sizeof(struct erofs_inode_chunk_index) != 8);
BUILD_BUG_ON(sizeof(struct z_erofs_map_header) != 8);
BUILD_BUG_ON(sizeof(struct z_erofs_vle_decompressed_index) != 8);
BUILD_BUG_ON(sizeof(struct z_erofs_lcluster_index) != 8);
BUILD_BUG_ON(sizeof(struct erofs_dirent) != 12);
/* keep in sync between 2 index structures for better extendibility */
BUILD_BUG_ON(sizeof(struct erofs_inode_chunk_index) !=
sizeof(struct z_erofs_vle_decompressed_index));
sizeof(struct z_erofs_lcluster_index));
BUILD_BUG_ON(sizeof(struct erofs_deviceslot) != 128);
BUILD_BUG_ON(BIT(Z_EROFS_VLE_DI_CLUSTER_TYPE_BITS) <
Z_EROFS_VLE_CLUSTER_TYPE_MAX - 1);
BUILD_BUG_ON(BIT(Z_EROFS_LI_LCLUSTER_TYPE_BITS) <
Z_EROFS_LCLUSTER_TYPE_MAX - 1);
/* exclude old compiler versions like gcc 7.5.0 */
BUILD_BUG_ON(__builtin_constant_p(fmh) ?
fmh != cpu_to_le64(1ULL << 63) : 0);
+3 -2
View File
@@ -209,8 +209,8 @@ static int erofs_fscache_data_read_slice(struct erofs_fscache_request *primary)
void *src;
/* For tail packing layout, the offset may be non-zero. */
offset = erofs_blkoff(map.m_pa);
blknr = erofs_blknr(map.m_pa);
offset = erofs_blkoff(sb, map.m_pa);
blknr = erofs_blknr(sb, map.m_pa);
size = map.m_llen;
src = erofs_read_metabuf(&buf, sb, blknr, EROFS_KMAP);
@@ -460,6 +460,7 @@ static struct erofs_fscache *erofs_fscache_acquire_cookie(struct super_block *sb
inode->i_size = OFFSET_MAX;
inode->i_mapping->a_ops = &erofs_fscache_meta_aops;
mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
inode->i_blkbits = EROFS_SB(sb)->blkszbits;
inode->i_private = ctx;
ctx->cookie = cookie;
+20 -16
View File
@@ -23,11 +23,8 @@ static void *erofs_read_inode(struct erofs_buf *buf,
unsigned int ifmt;
int err;
blkaddr = erofs_blknr(inode_loc);
*ofs = erofs_blkoff(inode_loc);
erofs_dbg("%s, reading inode nid %llu at %u of blkaddr %u",
__func__, vi->nid, *ofs, blkaddr);
blkaddr = erofs_blknr(sb, inode_loc);
*ofs = erofs_blkoff(sb, inode_loc);
kaddr = erofs_read_metabuf(buf, sb, blkaddr, EROFS_KMAP);
if (IS_ERR(kaddr)) {
@@ -58,11 +55,11 @@ static void *erofs_read_inode(struct erofs_buf *buf,
case EROFS_INODE_LAYOUT_EXTENDED:
vi->inode_isize = sizeof(struct erofs_inode_extended);
/* check if the extended inode acrosses block boundary */
if (*ofs + vi->inode_isize <= EROFS_BLKSIZ) {
if (*ofs + vi->inode_isize <= sb->s_blocksize) {
*ofs += vi->inode_isize;
die = (struct erofs_inode_extended *)dic;
} else {
const unsigned int gotten = EROFS_BLKSIZ - *ofs;
const unsigned int gotten = sb->s_blocksize - *ofs;
copied = kmalloc(vi->inode_isize, GFP_NOFS);
if (!copied) {
@@ -176,7 +173,7 @@ static void *erofs_read_inode(struct erofs_buf *buf,
err = -EOPNOTSUPP;
goto err_out;
}
vi->chunkbits = LOG_BLOCK_SIZE +
vi->chunkbits = sb->s_blocksize_bits +
(vi->chunkformat & EROFS_CHUNK_FORMAT_BLKBITS_MASK);
}
inode->i_mtime.tv_sec = inode->i_ctime.tv_sec;
@@ -188,11 +185,12 @@ static void *erofs_read_inode(struct erofs_buf *buf,
if (test_opt(&sbi->opt, DAX_ALWAYS) && S_ISREG(inode->i_mode) &&
vi->datalayout == EROFS_INODE_FLAT_PLAIN)
inode->i_flags |= S_DAX;
if (!nblks)
/* measure inode.i_blocks as generic filesystems */
inode->i_blocks = roundup(inode->i_size, EROFS_BLKSIZ) >> 9;
inode->i_blocks = round_up(inode->i_size, sb->s_blocksize) >> 9;
else
inode->i_blocks = nblks << LOG_SECTORS_PER_BLOCK;
inode->i_blocks = nblks << (sb->s_blocksize_bits - 9);
return kaddr;
bogusimode:
@@ -210,11 +208,12 @@ static int erofs_fill_symlink(struct inode *inode, void *kaddr,
unsigned int m_pofs)
{
struct erofs_inode *vi = EROFS_I(inode);
unsigned int bsz = i_blocksize(inode);
char *lnk;
/* if it cannot be handled with fast symlink scheme */
if (vi->datalayout != EROFS_INODE_FLAT_INLINE ||
inode->i_size >= EROFS_BLKSIZ || inode->i_size < 0) {
inode->i_size >= bsz || inode->i_size < 0) {
inode->i_op = &erofs_symlink_iops;
return 0;
}
@@ -225,7 +224,7 @@ static int erofs_fill_symlink(struct inode *inode, void *kaddr,
m_pofs += vi->xattr_isize;
/* inline symlink data shouldn't cross block boundary */
if (m_pofs + inode->i_size > EROFS_BLKSIZ) {
if (m_pofs + inode->i_size > bsz) {
kfree(lnk);
erofs_err(inode->i_sb,
"inline data cross block boundary @ nid %llu",
@@ -289,10 +288,15 @@ static int erofs_fill_inode(struct inode *inode)
}
if (erofs_inode_is_data_compressed(vi->datalayout)) {
if (!erofs_is_fscache_mode(inode->i_sb))
err = z_erofs_fill_inode(inode);
else
err = -EOPNOTSUPP;
#ifdef CONFIG_EROFS_FS_ZIP
if (!erofs_is_fscache_mode(inode->i_sb) &&
inode->i_sb->s_blocksize_bits == PAGE_SHIFT) {
inode->i_mapping->a_ops = &z_erofs_aops;
err = 0;
goto out_unlock;
}
#endif
err = -EOPNOTSUPP;
goto out_unlock;
}
inode->i_mapping->a_ops = &erofs_raw_access_aops;
+30 -43
View File
@@ -31,10 +31,8 @@ __printf(3, 4) void _erofs_info(struct super_block *sb,
#define erofs_info(sb, fmt, ...) \
_erofs_info(sb, __func__, fmt "\n", ##__VA_ARGS__)
#ifdef CONFIG_EROFS_FS_DEBUG
#define erofs_dbg(x, ...) pr_debug(x "\n", ##__VA_ARGS__)
#define DBG_BUGON BUG_ON
#else
#define erofs_dbg(x, ...) ((void)0)
#define DBG_BUGON(x) ((void)(x))
#endif /* !CONFIG_EROFS_FS_DEBUG */
@@ -81,6 +79,7 @@ struct erofs_dev_context {
struct rw_semaphore rwsem;
unsigned int extra_devices;
bool flatdev;
};
struct erofs_fs_context {
@@ -116,6 +115,11 @@ struct erofs_fscache {
char *name;
};
struct erofs_xattr_prefix_item {
struct erofs_xattr_long_prefix *prefix;
u8 infix_len;
};
struct erofs_sb_info {
struct erofs_mount_opts opt; /* options */
#ifdef CONFIG_EROFS_FS_ZIP
@@ -133,8 +137,8 @@ struct erofs_sb_info {
struct inode *managed_cache;
struct erofs_sb_lz4_info lz4;
struct inode *packed_inode;
#endif /* CONFIG_EROFS_FS_ZIP */
struct inode *packed_inode;
struct erofs_dev_context *devs;
struct dax_device *dax_dev;
u64 dax_part_off;
@@ -144,11 +148,14 @@ struct erofs_sb_info {
u32 meta_blkaddr;
#ifdef CONFIG_EROFS_FS_XATTR
u32 xattr_blkaddr;
u32 xattr_prefix_start;
u8 xattr_prefix_count;
struct erofs_xattr_prefix_item *xattr_prefixes;
#endif
u16 device_id_mask; /* valid bits of device id to be used */
/* inode slot unit size in bit shift */
unsigned char islotbits;
unsigned char islotbits; /* inode slot unit size in bit shift */
unsigned char blkszbits; /* filesystem block size in bit shift */
u32 sb_size; /* total superblock size */
u32 build_time_nsec;
@@ -156,6 +163,7 @@ struct erofs_sb_info {
/* what we really care is nid, rather than ino.. */
erofs_nid_t root_nid;
erofs_nid_t packed_nid;
/* used for statfs, f_files - f_favail */
u64 inos;
@@ -240,27 +248,13 @@ static inline int erofs_wait_on_workgroup_freezed(struct erofs_workgroup *grp)
VAL != EROFS_LOCKED_MAGIC);
}
/* we strictly follow PAGE_SIZE and no buffer head yet */
#define LOG_BLOCK_SIZE PAGE_SHIFT
#undef LOG_SECTORS_PER_BLOCK
#define LOG_SECTORS_PER_BLOCK (PAGE_SHIFT - 9)
#undef SECTORS_PER_BLOCK
#define SECTORS_PER_BLOCK (1 << SECTORS_PER_BLOCK)
#define EROFS_BLKSIZ (1 << LOG_BLOCK_SIZE)
#if (EROFS_BLKSIZ % 4096 || !EROFS_BLKSIZ)
#error erofs cannot be used in this platform
#endif
enum erofs_kmap_type {
EROFS_NO_KMAP, /* don't map the buffer */
EROFS_KMAP, /* use kmap_local_page() to map the buffer */
};
struct erofs_buf {
struct inode *inode;
struct page *page;
void *base;
enum erofs_kmap_type kmap_type;
@@ -269,9 +263,10 @@ struct erofs_buf {
#define ROOT_NID(sb) ((sb)->root_nid)
#define erofs_blknr(addr) ((addr) / EROFS_BLKSIZ)
#define erofs_blkoff(addr) ((addr) % EROFS_BLKSIZ)
#define blknr_to_addr(nr) ((erofs_off_t)(nr) * EROFS_BLKSIZ)
#define erofs_blknr(sb, addr) ((addr) >> (sb)->s_blocksize_bits)
#define erofs_blkoff(sb, addr) ((addr) & ((sb)->s_blocksize - 1))
#define erofs_pos(sb, blk) ((erofs_off_t)(blk) << (sb)->s_blocksize_bits)
#define erofs_iblks(i) (round_up((i)->i_size, i_blocksize(i)) >> (i)->i_blkbits)
#define EROFS_FEATURE_FUNCS(name, compat, feature) \
static inline bool erofs_sb_has_##name(struct erofs_sb_info *sbi) \
@@ -288,6 +283,7 @@ EROFS_FEATURE_FUNCS(compr_head2, incompat, INCOMPAT_COMPR_HEAD2)
EROFS_FEATURE_FUNCS(ztailpacking, incompat, INCOMPAT_ZTAILPACKING)
EROFS_FEATURE_FUNCS(fragments, incompat, INCOMPAT_FRAGMENTS)
EROFS_FEATURE_FUNCS(dedupe, incompat, INCOMPAT_DEDUPE)
EROFS_FEATURE_FUNCS(xattr_prefixes, incompat, INCOMPAT_XATTR_PREFIXES)
EROFS_FEATURE_FUNCS(sb_chksum, compat, COMPAT_SB_CHKSUM)
/* atomic flag definitions */
@@ -306,7 +302,7 @@ struct erofs_inode {
unsigned char datalayout;
unsigned char inode_isize;
unsigned short xattr_isize;
unsigned int xattr_isize;
unsigned int xattr_shared_count;
unsigned int *xattr_shared_xattrs;
@@ -343,28 +339,18 @@ static inline erofs_off_t erofs_iloc(struct inode *inode)
{
struct erofs_sb_info *sbi = EROFS_I_SB(inode);
return blknr_to_addr(sbi->meta_blkaddr) +
return erofs_pos(inode->i_sb, sbi->meta_blkaddr) +
(EROFS_I(inode)->nid << sbi->islotbits);
}
static inline unsigned int erofs_bitrange(unsigned int value, unsigned int bit,
unsigned int bits)
static inline unsigned int erofs_inode_version(unsigned int ifmt)
{
return (value >> bit) & ((1 << bits) - 1);
return (ifmt >> EROFS_I_VERSION_BIT) & EROFS_I_VERSION_MASK;
}
static inline unsigned int erofs_inode_version(unsigned int value)
static inline unsigned int erofs_inode_datalayout(unsigned int ifmt)
{
return erofs_bitrange(value, EROFS_I_VERSION_BIT,
EROFS_I_VERSION_BITS);
}
static inline unsigned int erofs_inode_datalayout(unsigned int value)
{
return erofs_bitrange(value, EROFS_I_DATALAYOUT_BIT,
EROFS_I_DATALAYOUT_BITS);
return (ifmt >> EROFS_I_DATALAYOUT_BIT) & EROFS_I_DATALAYOUT_MASK;
}
/*
@@ -451,10 +437,13 @@ extern const struct iomap_ops z_erofs_iomap_report_ops;
#define EROFS_REG_COOKIE_SHARE 0x0001
#define EROFS_REG_COOKIE_NEED_NOEXIST 0x0002
void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf,
erofs_off_t *offset, int *lengthp);
void erofs_unmap_metabuf(struct erofs_buf *buf);
void erofs_put_metabuf(struct erofs_buf *buf);
void *erofs_bread(struct erofs_buf *buf, struct inode *inode,
erofs_blk_t blkaddr, enum erofs_kmap_type type);
void *erofs_bread(struct erofs_buf *buf, erofs_blk_t blkaddr,
enum erofs_kmap_type type);
void erofs_init_metabuf(struct erofs_buf *buf, struct super_block *sb);
void *erofs_read_metabuf(struct erofs_buf *buf, struct super_block *sb,
erofs_blk_t blkaddr, enum erofs_kmap_type type);
int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *dev);
@@ -521,7 +510,6 @@ int erofs_try_to_free_cached_page(struct page *page);
int z_erofs_load_lz4_config(struct super_block *sb,
struct erofs_super_block *dsb,
struct z_erofs_lz4_cfgs *lz4, int len);
int z_erofs_fill_inode(struct inode *inode);
int z_erofs_map_blocks_iter(struct inode *inode, struct erofs_map_blocks *map,
int flags);
#else
@@ -541,7 +529,6 @@ static inline int z_erofs_load_lz4_config(struct super_block *sb,
}
return 0;
}
static inline int z_erofs_fill_inode(struct inode *inode) { return -EOPNOTSUPP; }
#endif /* !CONFIG_EROFS_FS_ZIP */
#ifdef CONFIG_EROFS_FS_ZIP_LZMA
+13 -14
View File
@@ -89,7 +89,8 @@ static struct erofs_dirent *find_target_dirent(struct erofs_qstr *name,
static void *erofs_find_target_block(struct erofs_buf *target,
struct inode *dir, struct erofs_qstr *name, int *_ndirents)
{
int head = 0, back = DIV_ROUND_UP(dir->i_size, EROFS_BLKSIZ) - 1;
unsigned int bsz = i_blocksize(dir);
int head = 0, back = erofs_iblks(dir) - 1;
unsigned int startprfx = 0, endprfx = 0;
void *candidate = ERR_PTR(-ENOENT);
@@ -98,10 +99,10 @@ static void *erofs_find_target_block(struct erofs_buf *target,
struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
struct erofs_dirent *de;
de = erofs_bread(&buf, dir, mid, EROFS_KMAP);
buf.inode = dir;
de = erofs_bread(&buf, mid, EROFS_KMAP);
if (!IS_ERR(de)) {
const int nameoff = nameoff_from_disk(de->nameoff,
EROFS_BLKSIZ);
const int nameoff = nameoff_from_disk(de->nameoff, bsz);
const int ndirents = nameoff / sizeof(*de);
int diff;
unsigned int matched;
@@ -121,11 +122,10 @@ static void *erofs_find_target_block(struct erofs_buf *target,
dname.name = (u8 *)de + nameoff;
if (ndirents == 1)
dname.end = (u8 *)de + EROFS_BLKSIZ;
dname.end = (u8 *)de + bsz;
else
dname.end = (u8 *)de +
nameoff_from_disk(de[1].nameoff,
EROFS_BLKSIZ);
nameoff_from_disk(de[1].nameoff, bsz);
/* string comparison without already matched prefix */
diff = erofs_dirnamecmp(name, &dname, &matched);
@@ -171,6 +171,7 @@ int erofs_namei(struct inode *dir, const struct qstr *name, erofs_nid_t *nid,
qn.name = name->name;
qn.end = name->name + name->len;
buf.inode = dir;
ndirents = 0;
de = erofs_find_target_block(&buf, dir, &qn, &ndirents);
@@ -178,7 +179,8 @@ int erofs_namei(struct inode *dir, const struct qstr *name, erofs_nid_t *nid,
return PTR_ERR(de);
if (ndirents)
de = find_target_dirent(&qn, (u8 *)de, EROFS_BLKSIZ, ndirents);
de = find_target_dirent(&qn, (u8 *)de, i_blocksize(dir),
ndirents);
if (!IS_ERR(de)) {
*nid = le64_to_cpu(de->nid);
@@ -203,16 +205,13 @@ static struct dentry *erofs_lookup(struct inode *dir, struct dentry *dentry,
err = erofs_namei(dir, &dentry->d_name, &nid, &d_type);
if (err == -ENOENT) {
if (err == -ENOENT)
/* negative dentry */
inode = NULL;
} else if (err) {
else if (err)
inode = ERR_PTR(err);
} else {
erofs_dbg("%s, %pd (nid %llu) found, d_type %u", __func__,
dentry, nid, d_type);
else
inode = erofs_iget(dir->i_sb, nid);
}
return d_splice_alias(inode, dentry);
}
+70 -46
View File
@@ -52,18 +52,21 @@ void _erofs_info(struct super_block *sb, const char *function,
static int erofs_superblock_csum_verify(struct super_block *sb, void *sbdata)
{
size_t len = 1 << EROFS_SB(sb)->blkszbits;
struct erofs_super_block *dsb;
u32 expected_crc, crc;
dsb = kmemdup(sbdata + EROFS_SUPER_OFFSET,
EROFS_BLKSIZ - EROFS_SUPER_OFFSET, GFP_KERNEL);
if (len > EROFS_SUPER_OFFSET)
len -= EROFS_SUPER_OFFSET;
dsb = kmemdup(sbdata + EROFS_SUPER_OFFSET, len, GFP_KERNEL);
if (!dsb)
return -ENOMEM;
expected_crc = le32_to_cpu(dsb->checksum);
dsb->checksum = 0;
/* to allow for x86 boot sectors and other oddities. */
crc = crc32c(~0, dsb, EROFS_BLKSIZ - EROFS_SUPER_OFFSET);
crc = crc32c(~0, dsb, len);
kfree(dsb);
if (crc != expected_crc) {
@@ -123,20 +126,19 @@ static bool check_layout_compatibility(struct super_block *sb,
return true;
}
#ifdef CONFIG_EROFS_FS_ZIP
/* read variable-sized metadata, offset will be aligned by 4-byte */
static void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf,
erofs_off_t *offset, int *lengthp)
void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf,
erofs_off_t *offset, int *lengthp)
{
u8 *buffer, *ptr;
int len, i, cnt;
*offset = round_up(*offset, 4);
ptr = erofs_read_metabuf(buf, sb, erofs_blknr(*offset), EROFS_KMAP);
ptr = erofs_bread(buf, erofs_blknr(sb, *offset), EROFS_KMAP);
if (IS_ERR(ptr))
return ptr;
len = le16_to_cpu(*(__le16 *)&ptr[erofs_blkoff(*offset)]);
len = le16_to_cpu(*(__le16 *)&ptr[erofs_blkoff(sb, *offset)]);
if (!len)
len = U16_MAX + 1;
buffer = kmalloc(len, GFP_KERNEL);
@@ -146,19 +148,20 @@ static void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf,
*lengthp = len;
for (i = 0; i < len; i += cnt) {
cnt = min(EROFS_BLKSIZ - (int)erofs_blkoff(*offset), len - i);
ptr = erofs_read_metabuf(buf, sb, erofs_blknr(*offset),
EROFS_KMAP);
cnt = min_t(int, sb->s_blocksize - erofs_blkoff(sb, *offset),
len - i);
ptr = erofs_bread(buf, erofs_blknr(sb, *offset), EROFS_KMAP);
if (IS_ERR(ptr)) {
kfree(buffer);
return ptr;
}
memcpy(buffer + i, ptr + erofs_blkoff(*offset), cnt);
memcpy(buffer + i, ptr + erofs_blkoff(sb, *offset), cnt);
*offset += cnt;
}
return buffer;
}
#ifdef CONFIG_EROFS_FS_ZIP
static int erofs_load_compr_cfgs(struct super_block *sb,
struct erofs_super_block *dsb)
{
@@ -175,6 +178,7 @@ static int erofs_load_compr_cfgs(struct super_block *sb,
return -EINVAL;
}
erofs_init_metabuf(&buf, sb);
offset = EROFS_SUPER_OFFSET + sbi->sb_size;
alg = 0;
for (algs = sbi->available_compr_algs; algs; algs >>= 1, ++alg) {
@@ -228,10 +232,10 @@ static int erofs_init_device(struct erofs_buf *buf, struct super_block *sb,
struct block_device *bdev;
void *ptr;
ptr = erofs_read_metabuf(buf, sb, erofs_blknr(*pos), EROFS_KMAP);
ptr = erofs_read_metabuf(buf, sb, erofs_blknr(sb, *pos), EROFS_KMAP);
if (IS_ERR(ptr))
return PTR_ERR(ptr);
dis = ptr + erofs_blkoff(*pos);
dis = ptr + erofs_blkoff(sb, *pos);
if (!dif->path) {
if (!dis->tag[0]) {
@@ -248,7 +252,7 @@ static int erofs_init_device(struct erofs_buf *buf, struct super_block *sb,
if (IS_ERR(fscache))
return PTR_ERR(fscache);
dif->fscache = fscache;
} else {
} else if (!sbi->devs->flatdev) {
bdev = blkdev_get_by_path(dif->path, FMODE_READ | FMODE_EXCL,
sb->s_type);
if (IS_ERR(bdev))
@@ -290,6 +294,9 @@ static int erofs_scan_devices(struct super_block *sb,
if (!ondisk_extradevs)
return 0;
if (!sbi->devs->extra_devices && !erofs_is_fscache_mode(sb))
sbi->devs->flatdev = true;
sbi->device_id_mask = roundup_pow_of_two(ondisk_extradevs + 1) - 1;
pos = le16_to_cpu(dsb->devt_slotoff) * EROFS_DEVT_SLOT_SIZE;
down_read(&sbi->devs->rwsem);
@@ -329,7 +336,6 @@ static int erofs_read_superblock(struct super_block *sb)
struct erofs_sb_info *sbi;
struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
struct erofs_super_block *dsb;
unsigned int blkszbits;
void *data;
int ret;
@@ -348,6 +354,16 @@ static int erofs_read_superblock(struct super_block *sb)
goto out;
}
sbi->blkszbits = dsb->blkszbits;
if (sbi->blkszbits < 9 || sbi->blkszbits > PAGE_SHIFT) {
erofs_err(sb, "blkszbits %u isn't supported", sbi->blkszbits);
goto out;
}
if (dsb->dirblkbits) {
erofs_err(sb, "dirblkbits %u isn't supported", dsb->dirblkbits);
goto out;
}
sbi->feature_compat = le32_to_cpu(dsb->feature_compat);
if (erofs_sb_has_sb_chksum(sbi)) {
ret = erofs_superblock_csum_verify(sb, data);
@@ -356,19 +372,11 @@ static int erofs_read_superblock(struct super_block *sb)
}
ret = -EINVAL;
blkszbits = dsb->blkszbits;
/* 9(512 bytes) + LOG_SECTORS_PER_BLOCK == LOG_BLOCK_SIZE */
if (blkszbits != LOG_BLOCK_SIZE) {
erofs_err(sb, "blkszbits %u isn't supported on this platform",
blkszbits);
goto out;
}
if (!check_layout_compatibility(sb, dsb))
goto out;
sbi->sb_size = 128 + dsb->sb_extslots * EROFS_SB_EXTSLOT_SIZE;
if (sbi->sb_size > EROFS_BLKSIZ) {
if (sbi->sb_size > PAGE_SIZE - EROFS_SUPER_OFFSET) {
erofs_err(sb, "invalid sb_extslots %u (more than a fs block)",
sbi->sb_size);
goto out;
@@ -377,20 +385,12 @@ static int erofs_read_superblock(struct super_block *sb)
sbi->meta_blkaddr = le32_to_cpu(dsb->meta_blkaddr);
#ifdef CONFIG_EROFS_FS_XATTR
sbi->xattr_blkaddr = le32_to_cpu(dsb->xattr_blkaddr);
sbi->xattr_prefix_start = le32_to_cpu(dsb->xattr_prefix_start);
sbi->xattr_prefix_count = dsb->xattr_prefix_count;
#endif
sbi->islotbits = ilog2(sizeof(struct erofs_inode_compact));
sbi->root_nid = le16_to_cpu(dsb->root_nid);
#ifdef CONFIG_EROFS_FS_ZIP
sbi->packed_inode = NULL;
if (erofs_sb_has_fragments(sbi) && dsb->packed_nid) {
sbi->packed_inode =
erofs_iget(sb, le64_to_cpu(dsb->packed_nid));
if (IS_ERR(sbi->packed_inode)) {
ret = PTR_ERR(sbi->packed_inode);
goto out;
}
}
#endif
sbi->packed_nid = le64_to_cpu(dsb->packed_nid);
sbi->inos = le64_to_cpu(dsb->inos);
sbi->build_time = le64_to_cpu(dsb->build_time);
@@ -417,8 +417,6 @@ static int erofs_read_superblock(struct super_block *sb)
/* handle multiple devices */
ret = erofs_scan_devices(sb, dsb);
if (erofs_sb_has_ztailpacking(sbi))
erofs_info(sb, "EXPERIMENTAL compressed inline data feature in use. Use at your own risk!");
if (erofs_is_fscache_mode(sb))
erofs_info(sb, "EXPERIMENTAL fscache-based on-demand read feature in use. Use at your own risk!");
if (erofs_sb_has_fragments(sbi))
@@ -733,9 +731,10 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
sbi->domain_id = ctx->domain_id;
ctx->domain_id = NULL;
sbi->blkszbits = PAGE_SHIFT;
if (erofs_is_fscache_mode(sb)) {
sb->s_blocksize = EROFS_BLKSIZ;
sb->s_blocksize_bits = LOG_BLOCK_SIZE;
sb->s_blocksize = PAGE_SIZE;
sb->s_blocksize_bits = PAGE_SHIFT;
err = erofs_fscache_register_fs(sb);
if (err)
@@ -745,8 +744,8 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
if (err)
return err;
} else {
if (!sb_set_blocksize(sb, EROFS_BLKSIZ)) {
erofs_err(sb, "failed to set erofs blksize");
if (!sb_set_blocksize(sb, PAGE_SIZE)) {
errorfc(fc, "failed to set initial blksize");
return -EINVAL;
}
@@ -759,12 +758,24 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
if (err)
return err;
if (test_opt(&sbi->opt, DAX_ALWAYS)) {
BUILD_BUG_ON(EROFS_BLKSIZ != PAGE_SIZE);
if (sb->s_blocksize_bits != sbi->blkszbits) {
if (erofs_is_fscache_mode(sb)) {
errorfc(fc, "unsupported blksize for fscache mode");
return -EINVAL;
}
if (!sb_set_blocksize(sb, 1 << sbi->blkszbits)) {
errorfc(fc, "failed to set erofs blksize");
return -EINVAL;
}
}
if (test_opt(&sbi->opt, DAX_ALWAYS)) {
if (!sbi->dax_dev) {
errorfc(fc, "DAX unsupported by block device. Turning off DAX.");
clear_opt(&sbi->opt, DAX_ALWAYS);
} else if (sbi->blkszbits != PAGE_SHIFT) {
errorfc(fc, "unsupported blocksize for DAX");
clear_opt(&sbi->opt, DAX_ALWAYS);
}
}
@@ -799,10 +810,22 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
erofs_shrinker_register(sb);
/* sb->s_umount is already locked, SB_ACTIVE and SB_BORN are not set */
if (erofs_sb_has_fragments(sbi) && sbi->packed_nid) {
sbi->packed_inode = erofs_iget(sb, sbi->packed_nid);
if (IS_ERR(sbi->packed_inode)) {
err = PTR_ERR(sbi->packed_inode);
sbi->packed_inode = NULL;
return err;
}
}
err = erofs_init_managed_cache(sb);
if (err)
return err;
err = erofs_xattr_prefixes_init(sb);
if (err)
return err;
err = erofs_register_sysfs(sb);
if (err)
return err;
@@ -962,12 +985,13 @@ static void erofs_put_super(struct super_block *sb)
erofs_unregister_sysfs(sb);
erofs_shrinker_unregister(sb);
erofs_xattr_prefixes_cleanup(sb);
#ifdef CONFIG_EROFS_FS_ZIP
iput(sbi->managed_cache);
sbi->managed_cache = NULL;
#endif
iput(sbi->packed_inode);
sbi->packed_inode = NULL;
#endif
erofs_free_dev_context(sbi->devs);
sbi->devs = NULL;
erofs_fscache_unregister_fs(sb);
@@ -1060,7 +1084,7 @@ static int erofs_statfs(struct dentry *dentry, struct kstatfs *buf)
id = huge_encode_dev(sb->s_bdev->bd_dev);
buf->f_type = sb->s_magic;
buf->f_bsize = EROFS_BLKSIZ;
buf->f_bsize = sb->s_blocksize;
buf->f_blocks = sbi->total_blocks;
buf->f_bfree = buf->f_bavail = 0;
+161 -71
View File
@@ -7,6 +7,19 @@
#include <linux/security.h>
#include "xattr.h"
static inline erofs_blk_t erofs_xattr_blkaddr(struct super_block *sb,
unsigned int xattr_id)
{
return EROFS_SB(sb)->xattr_blkaddr +
erofs_blknr(sb, xattr_id * sizeof(__u32));
}
static inline unsigned int erofs_xattr_blkoff(struct super_block *sb,
unsigned int xattr_id)
{
return erofs_blkoff(sb, xattr_id * sizeof(__u32));
}
struct xattr_iter {
struct super_block *sb;
struct erofs_buf buf;
@@ -16,7 +29,7 @@ struct xattr_iter {
unsigned int ofs;
};
static int init_inode_xattrs(struct inode *inode)
static int erofs_init_inode_xattrs(struct inode *inode)
{
struct erofs_inode *const vi = EROFS_I(inode);
struct xattr_iter it;
@@ -68,8 +81,8 @@ static int init_inode_xattrs(struct inode *inode)
}
it.buf = __EROFS_BUF_INITIALIZER;
it.blkaddr = erofs_blknr(erofs_iloc(inode) + vi->inode_isize);
it.ofs = erofs_blkoff(erofs_iloc(inode) + vi->inode_isize);
it.blkaddr = erofs_blknr(sb, erofs_iloc(inode) + vi->inode_isize);
it.ofs = erofs_blkoff(sb, erofs_iloc(inode) + vi->inode_isize);
/* read in shared xattr array (non-atomic, see kmalloc below) */
it.kaddr = erofs_read_metabuf(&it.buf, sb, it.blkaddr, EROFS_KMAP);
@@ -92,9 +105,9 @@ static int init_inode_xattrs(struct inode *inode)
it.ofs += sizeof(struct erofs_xattr_ibody_header);
for (i = 0; i < vi->xattr_shared_count; ++i) {
if (it.ofs >= EROFS_BLKSIZ) {
if (it.ofs >= sb->s_blocksize) {
/* cannot be unaligned */
DBG_BUGON(it.ofs != EROFS_BLKSIZ);
DBG_BUGON(it.ofs != sb->s_blocksize);
it.kaddr = erofs_read_metabuf(&it.buf, sb, ++it.blkaddr,
EROFS_KMAP);
@@ -139,15 +152,15 @@ struct xattr_iter_handlers {
static inline int xattr_iter_fixup(struct xattr_iter *it)
{
if (it->ofs < EROFS_BLKSIZ)
if (it->ofs < it->sb->s_blocksize)
return 0;
it->blkaddr += erofs_blknr(it->ofs);
it->blkaddr += erofs_blknr(it->sb, it->ofs);
it->kaddr = erofs_read_metabuf(&it->buf, it->sb, it->blkaddr,
EROFS_KMAP);
if (IS_ERR(it->kaddr))
return PTR_ERR(it->kaddr);
it->ofs = erofs_blkoff(it->ofs);
it->ofs = erofs_blkoff(it->sb, it->ofs);
return 0;
}
@@ -157,7 +170,8 @@ static int inline_xattr_iter_begin(struct xattr_iter *it,
struct erofs_inode *const vi = EROFS_I(inode);
unsigned int xattr_header_sz, inline_xattr_ofs;
xattr_header_sz = inlinexattr_header_size(inode);
xattr_header_sz = sizeof(struct erofs_xattr_ibody_header) +
sizeof(u32) * vi->xattr_shared_count;
if (xattr_header_sz >= vi->xattr_isize) {
DBG_BUGON(xattr_header_sz > vi->xattr_isize);
return -ENOATTR;
@@ -165,8 +179,8 @@ static int inline_xattr_iter_begin(struct xattr_iter *it,
inline_xattr_ofs = vi->inode_isize + xattr_header_sz;
it->blkaddr = erofs_blknr(erofs_iloc(inode) + inline_xattr_ofs);
it->ofs = erofs_blkoff(erofs_iloc(inode) + inline_xattr_ofs);
it->blkaddr = erofs_blknr(it->sb, erofs_iloc(inode) + inline_xattr_ofs);
it->ofs = erofs_blkoff(it->sb, erofs_iloc(inode) + inline_xattr_ofs);
it->kaddr = erofs_read_metabuf(&it->buf, inode->i_sb, it->blkaddr,
EROFS_KMAP);
if (IS_ERR(it->kaddr))
@@ -222,8 +236,8 @@ static int xattr_foreach(struct xattr_iter *it,
processed = 0;
while (processed < entry.e_name_len) {
if (it->ofs >= EROFS_BLKSIZ) {
DBG_BUGON(it->ofs > EROFS_BLKSIZ);
if (it->ofs >= it->sb->s_blocksize) {
DBG_BUGON(it->ofs > it->sb->s_blocksize);
err = xattr_iter_fixup(it);
if (err)
@@ -231,7 +245,7 @@ static int xattr_foreach(struct xattr_iter *it,
it->ofs = 0;
}
slice = min_t(unsigned int, EROFS_BLKSIZ - it->ofs,
slice = min_t(unsigned int, it->sb->s_blocksize - it->ofs,
entry.e_name_len - processed);
/* handle name */
@@ -257,8 +271,8 @@ static int xattr_foreach(struct xattr_iter *it,
}
while (processed < value_sz) {
if (it->ofs >= EROFS_BLKSIZ) {
DBG_BUGON(it->ofs > EROFS_BLKSIZ);
if (it->ofs >= it->sb->s_blocksize) {
DBG_BUGON(it->ofs > it->sb->s_blocksize);
err = xattr_iter_fixup(it);
if (err)
@@ -266,7 +280,7 @@ static int xattr_foreach(struct xattr_iter *it,
it->ofs = 0;
}
slice = min_t(unsigned int, EROFS_BLKSIZ - it->ofs,
slice = min_t(unsigned int, it->sb->s_blocksize - it->ofs,
value_sz - processed);
op->value(it, processed, it->kaddr + it->ofs, slice);
it->ofs += slice;
@@ -283,17 +297,45 @@ struct getxattr_iter {
struct xattr_iter it;
char *buffer;
int buffer_size, index;
int buffer_size, index, infix_len;
struct qstr name;
};
static int erofs_xattr_long_entrymatch(struct getxattr_iter *it,
struct erofs_xattr_entry *entry)
{
struct erofs_sb_info *sbi = EROFS_SB(it->it.sb);
struct erofs_xattr_prefix_item *pf = sbi->xattr_prefixes +
(entry->e_name_index & EROFS_XATTR_LONG_PREFIX_MASK);
if (pf >= sbi->xattr_prefixes + sbi->xattr_prefix_count)
return -ENOATTR;
if (it->index != pf->prefix->base_index ||
it->name.len != entry->e_name_len + pf->infix_len)
return -ENOATTR;
if (memcmp(it->name.name, pf->prefix->infix, pf->infix_len))
return -ENOATTR;
it->infix_len = pf->infix_len;
return 0;
}
static int xattr_entrymatch(struct xattr_iter *_it,
struct erofs_xattr_entry *entry)
{
struct getxattr_iter *it = container_of(_it, struct getxattr_iter, it);
return (it->index != entry->e_name_index ||
it->name.len != entry->e_name_len) ? -ENOATTR : 0;
/* should also match the infix for long name prefixes */
if (entry->e_name_index & EROFS_XATTR_LONG_PREFIX)
return erofs_xattr_long_entrymatch(it, entry);
if (it->index != entry->e_name_index ||
it->name.len != entry->e_name_len)
return -ENOATTR;
it->infix_len = 0;
return 0;
}
static int xattr_namematch(struct xattr_iter *_it,
@@ -301,7 +343,9 @@ static int xattr_namematch(struct xattr_iter *_it,
{
struct getxattr_iter *it = container_of(_it, struct getxattr_iter, it);
return memcmp(buf, it->name.name + processed, len) ? -ENOATTR : 0;
if (memcmp(buf, it->name.name + it->infix_len + processed, len))
return -ENOATTR;
return 0;
}
static int xattr_checkbuffer(struct xattr_iter *_it,
@@ -351,21 +395,18 @@ static int inline_getxattr(struct inode *inode, struct getxattr_iter *it)
static int shared_getxattr(struct inode *inode, struct getxattr_iter *it)
{
struct erofs_inode *const vi = EROFS_I(inode);
struct super_block *const sb = inode->i_sb;
struct erofs_sb_info *const sbi = EROFS_SB(sb);
unsigned int i;
struct super_block *const sb = it->it.sb;
unsigned int i, xsid;
int ret = -ENOATTR;
for (i = 0; i < vi->xattr_shared_count; ++i) {
erofs_blk_t blkaddr =
xattrblock_addr(sbi, vi->xattr_shared_xattrs[i]);
it->it.ofs = xattrblock_offset(sbi, vi->xattr_shared_xattrs[i]);
it->it.kaddr = erofs_read_metabuf(&it->it.buf, sb, blkaddr,
EROFS_KMAP);
xsid = vi->xattr_shared_xattrs[i];
it->it.blkaddr = erofs_xattr_blkaddr(sb, xsid);
it->it.ofs = erofs_xattr_blkoff(sb, xsid);
it->it.kaddr = erofs_read_metabuf(&it->it.buf, sb,
it->it.blkaddr, EROFS_KMAP);
if (IS_ERR(it->it.kaddr))
return PTR_ERR(it->it.kaddr);
it->it.blkaddr = blkaddr;
ret = xattr_foreach(&it->it, &find_xattr_handlers, NULL);
if (ret != -ENOATTR)
@@ -394,7 +435,7 @@ int erofs_getxattr(struct inode *inode, int index,
if (!name)
return -EINVAL;
ret = init_inode_xattrs(inode);
ret = erofs_init_inode_xattrs(inode);
if (ret)
return ret;
@@ -421,20 +462,9 @@ static int erofs_xattr_generic_get(const struct xattr_handler *handler,
struct dentry *unused, struct inode *inode,
const char *name, void *buffer, size_t size)
{
struct erofs_sb_info *const sbi = EROFS_I_SB(inode);
switch (handler->flags) {
case EROFS_XATTR_INDEX_USER:
if (!test_opt(&sbi->opt, XATTR_USER))
return -EOPNOTSUPP;
break;
case EROFS_XATTR_INDEX_TRUSTED:
break;
case EROFS_XATTR_INDEX_SECURITY:
break;
default:
return -EINVAL;
}
if (handler->flags == EROFS_XATTR_INDEX_USER &&
!test_opt(&EROFS_I_SB(inode)->opt, XATTR_USER))
return -EOPNOTSUPP;
return erofs_getxattr(inode, handler->flags, name, buffer, size);
}
@@ -463,10 +493,6 @@ const struct xattr_handler __maybe_unused erofs_xattr_security_handler = {
const struct xattr_handler *erofs_xattr_handlers[] = {
&erofs_xattr_user_handler,
#ifdef CONFIG_EROFS_FS_POSIX_ACL
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
#endif
&erofs_xattr_trusted_handler,
#ifdef CONFIG_EROFS_FS_SECURITY
&erofs_xattr_security_handler,
@@ -487,29 +513,40 @@ static int xattr_entrylist(struct xattr_iter *_it,
{
struct listxattr_iter *it =
container_of(_it, struct listxattr_iter, it);
unsigned int prefix_len;
const char *prefix;
unsigned int base_index = entry->e_name_index;
unsigned int prefix_len, infix_len = 0;
const char *prefix, *infix = NULL;
const struct xattr_handler *h =
erofs_xattr_handler(entry->e_name_index);
if (entry->e_name_index & EROFS_XATTR_LONG_PREFIX) {
struct erofs_sb_info *sbi = EROFS_SB(_it->sb);
struct erofs_xattr_prefix_item *pf = sbi->xattr_prefixes +
(entry->e_name_index & EROFS_XATTR_LONG_PREFIX_MASK);
if (!h || (h->list && !h->list(it->dentry)))
if (pf >= sbi->xattr_prefixes + sbi->xattr_prefix_count)
return 1;
infix = pf->prefix->infix;
infix_len = pf->infix_len;
base_index = pf->prefix->base_index;
}
prefix = erofs_xattr_prefix(base_index, it->dentry);
if (!prefix)
return 1;
prefix = xattr_prefix(h);
prefix_len = strlen(prefix);
if (!it->buffer) {
it->buffer_ofs += prefix_len + entry->e_name_len + 1;
it->buffer_ofs += prefix_len + infix_len +
entry->e_name_len + 1;
return 1;
}
if (it->buffer_ofs + prefix_len
if (it->buffer_ofs + prefix_len + infix_len +
+ entry->e_name_len + 1 > it->buffer_size)
return -ERANGE;
memcpy(it->buffer + it->buffer_ofs, prefix, prefix_len);
it->buffer_ofs += prefix_len;
memcpy(it->buffer + it->buffer_ofs + prefix_len, infix, infix_len);
it->buffer_ofs += prefix_len + infix_len;
return 0;
}
@@ -563,21 +600,18 @@ static int shared_listxattr(struct listxattr_iter *it)
{
struct inode *const inode = d_inode(it->dentry);
struct erofs_inode *const vi = EROFS_I(inode);
struct super_block *const sb = inode->i_sb;
struct erofs_sb_info *const sbi = EROFS_SB(sb);
unsigned int i;
struct super_block *const sb = it->it.sb;
unsigned int i, xsid;
int ret = 0;
for (i = 0; i < vi->xattr_shared_count; ++i) {
erofs_blk_t blkaddr =
xattrblock_addr(sbi, vi->xattr_shared_xattrs[i]);
it->it.ofs = xattrblock_offset(sbi, vi->xattr_shared_xattrs[i]);
it->it.kaddr = erofs_read_metabuf(&it->it.buf, sb, blkaddr,
EROFS_KMAP);
xsid = vi->xattr_shared_xattrs[i];
it->it.blkaddr = erofs_xattr_blkaddr(sb, xsid);
it->it.ofs = erofs_xattr_blkoff(sb, xsid);
it->it.kaddr = erofs_read_metabuf(&it->it.buf, sb,
it->it.blkaddr, EROFS_KMAP);
if (IS_ERR(it->it.kaddr))
return PTR_ERR(it->it.kaddr);
it->it.blkaddr = blkaddr;
ret = xattr_foreach(&it->it, &list_xattr_handlers, NULL);
if (ret)
@@ -592,7 +626,7 @@ ssize_t erofs_listxattr(struct dentry *dentry,
int ret;
struct listxattr_iter it;
ret = init_inode_xattrs(d_inode(dentry));
ret = erofs_init_inode_xattrs(d_inode(dentry));
if (ret == -ENOATTR)
return 0;
if (ret)
@@ -613,6 +647,62 @@ ssize_t erofs_listxattr(struct dentry *dentry,
return ret;
}
void erofs_xattr_prefixes_cleanup(struct super_block *sb)
{
struct erofs_sb_info *sbi = EROFS_SB(sb);
int i;
if (sbi->xattr_prefixes) {
for (i = 0; i < sbi->xattr_prefix_count; i++)
kfree(sbi->xattr_prefixes[i].prefix);
kfree(sbi->xattr_prefixes);
sbi->xattr_prefixes = NULL;
}
}
int erofs_xattr_prefixes_init(struct super_block *sb)
{
struct erofs_sb_info *sbi = EROFS_SB(sb);
struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
erofs_off_t pos = (erofs_off_t)sbi->xattr_prefix_start << 2;
struct erofs_xattr_prefix_item *pfs;
int ret = 0, i, len;
if (!sbi->xattr_prefix_count)
return 0;
pfs = kzalloc(sbi->xattr_prefix_count * sizeof(*pfs), GFP_KERNEL);
if (!pfs)
return -ENOMEM;
if (erofs_sb_has_fragments(sbi))
buf.inode = sbi->packed_inode;
else
erofs_init_metabuf(&buf, sb);
for (i = 0; i < sbi->xattr_prefix_count; i++) {
void *ptr = erofs_read_metadata(sb, &buf, &pos, &len);
if (IS_ERR(ptr)) {
ret = PTR_ERR(ptr);
break;
} else if (len < sizeof(*pfs->prefix) ||
len > EROFS_NAME_LEN + sizeof(*pfs->prefix)) {
kfree(ptr);
ret = -EFSCORRUPTED;
break;
}
pfs[i].prefix = ptr;
pfs[i].infix_len = len - sizeof(struct erofs_xattr_long_prefix);
}
erofs_put_metabuf(&buf);
sbi->xattr_prefixes = pfs;
if (ret)
erofs_xattr_prefixes_cleanup(sb);
return ret;
}
#ifdef CONFIG_EROFS_FS_POSIX_ACL
struct posix_acl *erofs_get_acl(struct inode *inode, int type, bool rcu)
{
+17 -30
View File
@@ -13,43 +13,21 @@
/* Attribute not found */
#define ENOATTR ENODATA
static inline unsigned int inlinexattr_header_size(struct inode *inode)
{
return sizeof(struct erofs_xattr_ibody_header) +
sizeof(u32) * EROFS_I(inode)->xattr_shared_count;
}
static inline erofs_blk_t xattrblock_addr(struct erofs_sb_info *sbi,
unsigned int xattr_id)
{
#ifdef CONFIG_EROFS_FS_XATTR
return sbi->xattr_blkaddr +
xattr_id * sizeof(__u32) / EROFS_BLKSIZ;
#else
return 0;
#endif
}
static inline unsigned int xattrblock_offset(struct erofs_sb_info *sbi,
unsigned int xattr_id)
{
return (xattr_id * sizeof(__u32)) % EROFS_BLKSIZ;
}
#ifdef CONFIG_EROFS_FS_XATTR
extern const struct xattr_handler erofs_xattr_user_handler;
extern const struct xattr_handler erofs_xattr_trusted_handler;
extern const struct xattr_handler erofs_xattr_security_handler;
static inline const struct xattr_handler *erofs_xattr_handler(unsigned int idx)
static inline const char *erofs_xattr_prefix(unsigned int idx,
struct dentry *dentry)
{
const struct xattr_handler *handler = NULL;
static const struct xattr_handler *xattr_handler_map[] = {
[EROFS_XATTR_INDEX_USER] = &erofs_xattr_user_handler,
#ifdef CONFIG_EROFS_FS_POSIX_ACL
[EROFS_XATTR_INDEX_POSIX_ACL_ACCESS] =
&posix_acl_access_xattr_handler,
[EROFS_XATTR_INDEX_POSIX_ACL_DEFAULT] =
&posix_acl_default_xattr_handler,
[EROFS_XATTR_INDEX_POSIX_ACL_ACCESS] = &nop_posix_acl_access,
[EROFS_XATTR_INDEX_POSIX_ACL_DEFAULT] = &nop_posix_acl_default,
#endif
[EROFS_XATTR_INDEX_TRUSTED] = &erofs_xattr_trusted_handler,
#ifdef CONFIG_EROFS_FS_SECURITY
@@ -57,15 +35,24 @@ static inline const struct xattr_handler *erofs_xattr_handler(unsigned int idx)
#endif
};
return idx && idx < ARRAY_SIZE(xattr_handler_map) ?
xattr_handler_map[idx] : NULL;
if (idx && idx < ARRAY_SIZE(xattr_handler_map))
handler = xattr_handler_map[idx];
if (!xattr_handler_can_list(handler, dentry))
return NULL;
return xattr_prefix(handler);
}
extern const struct xattr_handler *erofs_xattr_handlers[];
int erofs_xattr_prefixes_init(struct super_block *sb);
void erofs_xattr_prefixes_cleanup(struct super_block *sb);
int erofs_getxattr(struct inode *, int, const char *, void *, size_t);
ssize_t erofs_listxattr(struct dentry *, char *, size_t);
#else
static inline int erofs_xattr_prefixes_init(struct super_block *sb) { return 0; }
static inline void erofs_xattr_prefixes_cleanup(struct super_block *sb) {}
static inline int erofs_getxattr(struct inode *inode, int index,
const char *name, void *buffer,
size_t buffer_size)
+11 -14
View File
@@ -807,7 +807,7 @@ static int z_erofs_register_pcluster(struct z_erofs_decompress_frontend *fe)
if (ztailpacking) {
pcl->obj.index = 0; /* which indicates ztailpacking */
pcl->pageofs_in = erofs_blkoff(map->m_pa);
pcl->pageofs_in = erofs_blkoff(fe->inode->i_sb, map->m_pa);
pcl->tailpacking_size = map->m_plen;
} else {
pcl->obj.index = map->m_pa >> PAGE_SHIFT;
@@ -930,6 +930,7 @@ static int z_erofs_read_fragment(struct inode *inode, erofs_off_t pos,
struct page *page, unsigned int pageofs,
unsigned int len)
{
struct super_block *sb = inode->i_sb;
struct inode *packed_inode = EROFS_I_SB(inode)->packed_inode;
struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
u8 *src, *dst;
@@ -938,19 +939,19 @@ static int z_erofs_read_fragment(struct inode *inode, erofs_off_t pos,
if (!packed_inode)
return -EFSCORRUPTED;
buf.inode = packed_inode;
pos += EROFS_I(inode)->z_fragmentoff;
for (i = 0; i < len; i += cnt) {
cnt = min_t(unsigned int, len - i,
EROFS_BLKSIZ - erofs_blkoff(pos));
src = erofs_bread(&buf, packed_inode,
erofs_blknr(pos), EROFS_KMAP);
sb->s_blocksize - erofs_blkoff(sb, pos));
src = erofs_bread(&buf, erofs_blknr(sb, pos), EROFS_KMAP);
if (IS_ERR(src)) {
erofs_put_metabuf(&buf);
return PTR_ERR(src);
}
dst = kmap_local_page(page);
memcpy(dst + pageofs + i, src + erofs_blkoff(pos), cnt);
memcpy(dst + pageofs + i, src + erofs_blkoff(sb, pos), cnt);
kunmap_local(dst);
pos += cnt;
}
@@ -978,8 +979,6 @@ repeat:
if (offset + cur < map->m_la ||
offset + cur >= map->m_la + map->m_llen) {
erofs_dbg("out-of-range map @ pos %llu", offset + cur);
if (z_erofs_collector_end(fe))
fe->backmost = false;
map->m_la = offset + cur;
@@ -1005,7 +1004,8 @@ repeat:
void *mp;
mp = erofs_read_metabuf(&fe->map.buf, inode->i_sb,
erofs_blknr(map->m_pa), EROFS_NO_KMAP);
erofs_blknr(inode->i_sb, map->m_pa),
EROFS_NO_KMAP);
if (IS_ERR(mp)) {
err = PTR_ERR(mp);
erofs_err(inode->i_sb,
@@ -1103,9 +1103,6 @@ out:
if (err)
z_erofs_page_mark_eio(page);
z_erofs_onlinepage_endio(page);
erofs_dbg("%s, finish page: %pK spiltted: %u map->m_llen %llu",
__func__, page, spiltted, map->m_llen);
return err;
}
@@ -1726,11 +1723,11 @@ static void z_erofs_submit_queue(struct z_erofs_decompress_frontend *f,
/* no device id here, thus it will always succeed */
mdev = (struct erofs_map_dev) {
.m_pa = blknr_to_addr(pcl->obj.index),
.m_pa = erofs_pos(sb, pcl->obj.index),
};
(void)erofs_map_dev(sb, &mdev);
cur = erofs_blknr(mdev.m_pa);
cur = erofs_blknr(sb, mdev.m_pa);
end = cur + pcl->pclusterpages;
do {
@@ -1764,7 +1761,7 @@ submit_bio_retry:
last_bdev = mdev.m_bdev;
bio->bi_iter.bi_sector = (sector_t)cur <<
LOG_SECTORS_PER_BLOCK;
(sb->s_blocksize_bits - 9);
bio->bi_private = q[JQ_SUBMIT];
if (f->readahead)
bio->bi_opf |= REQ_RAHEAD;
+74 -92
View File
@@ -7,24 +7,6 @@
#include <asm/unaligned.h>
#include <trace/events/erofs.h>
int z_erofs_fill_inode(struct inode *inode)
{
struct erofs_inode *const vi = EROFS_I(inode);
struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb);
if (!erofs_sb_has_big_pcluster(sbi) &&
!erofs_sb_has_ztailpacking(sbi) && !erofs_sb_has_fragments(sbi) &&
vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY) {
vi->z_advise = 0;
vi->z_algorithmtype[0] = 0;
vi->z_algorithmtype[1] = 0;
vi->z_logical_clusterbits = LOG_BLOCK_SIZE;
set_bit(EROFS_I_Z_INITED_BIT, &vi->flags);
}
inode->i_mapping->a_ops = &z_erofs_aops;
return 0;
}
struct z_erofs_maprecorder {
struct inode *inode;
struct erofs_map_blocks *map;
@@ -45,47 +27,50 @@ static int legacy_load_cluster_from_disk(struct z_erofs_maprecorder *m,
{
struct inode *const inode = m->inode;
struct erofs_inode *const vi = EROFS_I(inode);
const erofs_off_t pos =
Z_EROFS_VLE_LEGACY_INDEX_ALIGN(erofs_iloc(inode) +
vi->inode_isize + vi->xattr_isize) +
lcn * sizeof(struct z_erofs_vle_decompressed_index);
struct z_erofs_vle_decompressed_index *di;
const erofs_off_t pos = Z_EROFS_FULL_INDEX_ALIGN(erofs_iloc(inode) +
vi->inode_isize + vi->xattr_isize) +
lcn * sizeof(struct z_erofs_lcluster_index);
struct z_erofs_lcluster_index *di;
unsigned int advise, type;
m->kaddr = erofs_read_metabuf(&m->map->buf, inode->i_sb,
erofs_blknr(pos), EROFS_KMAP);
erofs_blknr(inode->i_sb, pos), EROFS_KMAP);
if (IS_ERR(m->kaddr))
return PTR_ERR(m->kaddr);
m->nextpackoff = pos + sizeof(struct z_erofs_vle_decompressed_index);
m->nextpackoff = pos + sizeof(struct z_erofs_lcluster_index);
m->lcn = lcn;
di = m->kaddr + erofs_blkoff(pos);
di = m->kaddr + erofs_blkoff(inode->i_sb, pos);
advise = le16_to_cpu(di->di_advise);
type = (advise >> Z_EROFS_VLE_DI_CLUSTER_TYPE_BIT) &
((1 << Z_EROFS_VLE_DI_CLUSTER_TYPE_BITS) - 1);
type = (advise >> Z_EROFS_LI_LCLUSTER_TYPE_BIT) &
((1 << Z_EROFS_LI_LCLUSTER_TYPE_BITS) - 1);
switch (type) {
case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
case Z_EROFS_LCLUSTER_TYPE_NONHEAD:
m->clusterofs = 1 << vi->z_logical_clusterbits;
m->delta[0] = le16_to_cpu(di->di_u.delta[0]);
if (m->delta[0] & Z_EROFS_VLE_DI_D0_CBLKCNT) {
if (m->delta[0] & Z_EROFS_LI_D0_CBLKCNT) {
if (!(vi->z_advise & (Z_EROFS_ADVISE_BIG_PCLUSTER_1 |
Z_EROFS_ADVISE_BIG_PCLUSTER_2))) {
DBG_BUGON(1);
return -EFSCORRUPTED;
}
m->compressedblks = m->delta[0] &
~Z_EROFS_VLE_DI_D0_CBLKCNT;
~Z_EROFS_LI_D0_CBLKCNT;
m->delta[0] = 1;
}
m->delta[1] = le16_to_cpu(di->di_u.delta[1]);
break;
case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN:
case Z_EROFS_VLE_CLUSTER_TYPE_HEAD1:
case Z_EROFS_VLE_CLUSTER_TYPE_HEAD2:
if (advise & Z_EROFS_VLE_DI_PARTIAL_REF)
case Z_EROFS_LCLUSTER_TYPE_PLAIN:
case Z_EROFS_LCLUSTER_TYPE_HEAD1:
case Z_EROFS_LCLUSTER_TYPE_HEAD2:
if (advise & Z_EROFS_LI_PARTIAL_REF)
m->partialref = true;
m->clusterofs = le16_to_cpu(di->di_clusterofs);
if (m->clusterofs >= 1 << vi->z_logical_clusterbits) {
DBG_BUGON(1);
return -EFSCORRUPTED;
}
m->pblk = le32_to_cpu(di->di_u.blkaddr);
break;
default:
@@ -121,13 +106,13 @@ static int get_compacted_la_distance(unsigned int lclusterbits,
lo = decode_compactedbits(lclusterbits, lomask,
in, encodebits * i, &type);
if (type != Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD)
if (type != Z_EROFS_LCLUSTER_TYPE_NONHEAD)
return d1;
++d1;
} while (++i < vcnt);
/* vcnt - 1 (Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) item */
if (!(lo & Z_EROFS_VLE_DI_D0_CBLKCNT))
/* vcnt - 1 (Z_EROFS_LCLUSTER_TYPE_NONHEAD) item */
if (!(lo & Z_EROFS_LI_D0_CBLKCNT))
d1 += lo - 1;
return d1;
}
@@ -156,7 +141,7 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
(vcnt << amortizedshift);
big_pcluster = vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1;
encodebits = ((vcnt << amortizedshift) - sizeof(__le32)) * 8 / vcnt;
eofs = erofs_blkoff(pos);
eofs = erofs_blkoff(m->inode->i_sb, pos);
base = round_down(eofs, vcnt << amortizedshift);
in = m->kaddr + base;
@@ -165,19 +150,19 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
lo = decode_compactedbits(lclusterbits, lomask,
in, encodebits * i, &type);
m->type = type;
if (type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) {
if (type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
m->clusterofs = 1 << lclusterbits;
/* figure out lookahead_distance: delta[1] if needed */
if (lookahead)
m->delta[1] = get_compacted_la_distance(lclusterbits,
encodebits, vcnt, in, i);
if (lo & Z_EROFS_VLE_DI_D0_CBLKCNT) {
if (lo & Z_EROFS_LI_D0_CBLKCNT) {
if (!big_pcluster) {
DBG_BUGON(1);
return -EFSCORRUPTED;
}
m->compressedblks = lo & ~Z_EROFS_VLE_DI_D0_CBLKCNT;
m->compressedblks = lo & ~Z_EROFS_LI_D0_CBLKCNT;
m->delta[0] = 1;
return 0;
} else if (i + 1 != (int)vcnt) {
@@ -191,9 +176,9 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
*/
lo = decode_compactedbits(lclusterbits, lomask,
in, encodebits * (i - 1), &type);
if (type != Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD)
if (type != Z_EROFS_LCLUSTER_TYPE_NONHEAD)
lo = 0;
else if (lo & Z_EROFS_VLE_DI_D0_CBLKCNT)
else if (lo & Z_EROFS_LI_D0_CBLKCNT)
lo = 1;
m->delta[0] = lo + 1;
return 0;
@@ -207,7 +192,7 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
--i;
lo = decode_compactedbits(lclusterbits, lomask,
in, encodebits * i, &type);
if (type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD)
if (type == Z_EROFS_LCLUSTER_TYPE_NONHEAD)
i -= lo;
if (i >= 0)
@@ -219,10 +204,10 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
--i;
lo = decode_compactedbits(lclusterbits, lomask,
in, encodebits * i, &type);
if (type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) {
if (lo & Z_EROFS_VLE_DI_D0_CBLKCNT) {
if (type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
if (lo & Z_EROFS_LI_D0_CBLKCNT) {
--i;
nblk += lo & ~Z_EROFS_VLE_DI_D0_CBLKCNT;
nblk += lo & ~Z_EROFS_LI_D0_CBLKCNT;
continue;
}
/* bigpcluster shouldn't have plain d0 == 1 */
@@ -249,7 +234,7 @@ static int compacted_load_cluster_from_disk(struct z_erofs_maprecorder *m,
const unsigned int lclusterbits = vi->z_logical_clusterbits;
const erofs_off_t ebase = sizeof(struct z_erofs_map_header) +
ALIGN(erofs_iloc(inode) + vi->inode_isize + vi->xattr_isize, 8);
const unsigned int totalidx = DIV_ROUND_UP(inode->i_size, EROFS_BLKSIZ);
unsigned int totalidx = erofs_iblks(inode);
unsigned int compacted_4b_initial, compacted_2b;
unsigned int amortizedshift;
erofs_off_t pos;
@@ -290,7 +275,7 @@ static int compacted_load_cluster_from_disk(struct z_erofs_maprecorder *m,
out:
pos += lcn * (1 << amortizedshift);
m->kaddr = erofs_read_metabuf(&m->map->buf, inode->i_sb,
erofs_blknr(pos), EROFS_KMAP);
erofs_blknr(inode->i_sb, pos), EROFS_KMAP);
if (IS_ERR(m->kaddr))
return PTR_ERR(m->kaddr);
return unpack_compacted_index(m, amortizedshift, pos, lookahead);
@@ -301,10 +286,10 @@ static int z_erofs_load_cluster_from_disk(struct z_erofs_maprecorder *m,
{
const unsigned int datamode = EROFS_I(m->inode)->datalayout;
if (datamode == EROFS_INODE_FLAT_COMPRESSION_LEGACY)
if (datamode == EROFS_INODE_COMPRESSED_FULL)
return legacy_load_cluster_from_disk(m, lcn);
if (datamode == EROFS_INODE_FLAT_COMPRESSION)
if (datamode == EROFS_INODE_COMPRESSED_COMPACT)
return compacted_load_cluster_from_disk(m, lcn, lookahead);
return -EINVAL;
@@ -326,7 +311,7 @@ static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m,
return err;
switch (m->type) {
case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
case Z_EROFS_LCLUSTER_TYPE_NONHEAD:
if (!m->delta[0]) {
erofs_err(m->inode->i_sb,
"invalid lookback distance 0 @ nid %llu",
@@ -336,9 +321,9 @@ static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m,
}
lookback_distance = m->delta[0];
continue;
case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN:
case Z_EROFS_VLE_CLUSTER_TYPE_HEAD1:
case Z_EROFS_VLE_CLUSTER_TYPE_HEAD2:
case Z_EROFS_LCLUSTER_TYPE_PLAIN:
case Z_EROFS_LCLUSTER_TYPE_HEAD1:
case Z_EROFS_LCLUSTER_TYPE_HEAD2:
m->headtype = m->type;
m->map->m_la = (lcn << lclusterbits) | m->clusterofs;
return 0;
@@ -360,21 +345,22 @@ static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m,
static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m,
unsigned int initial_lcn)
{
struct super_block *sb = m->inode->i_sb;
struct erofs_inode *const vi = EROFS_I(m->inode);
struct erofs_map_blocks *const map = m->map;
const unsigned int lclusterbits = vi->z_logical_clusterbits;
unsigned long lcn;
int err;
DBG_BUGON(m->type != Z_EROFS_VLE_CLUSTER_TYPE_PLAIN &&
m->type != Z_EROFS_VLE_CLUSTER_TYPE_HEAD1 &&
m->type != Z_EROFS_VLE_CLUSTER_TYPE_HEAD2);
DBG_BUGON(m->type != Z_EROFS_LCLUSTER_TYPE_PLAIN &&
m->type != Z_EROFS_LCLUSTER_TYPE_HEAD1 &&
m->type != Z_EROFS_LCLUSTER_TYPE_HEAD2);
DBG_BUGON(m->type != m->headtype);
if (m->headtype == Z_EROFS_VLE_CLUSTER_TYPE_PLAIN ||
((m->headtype == Z_EROFS_VLE_CLUSTER_TYPE_HEAD1) &&
if (m->headtype == Z_EROFS_LCLUSTER_TYPE_PLAIN ||
((m->headtype == Z_EROFS_LCLUSTER_TYPE_HEAD1) &&
!(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1)) ||
((m->headtype == Z_EROFS_VLE_CLUSTER_TYPE_HEAD2) &&
((m->headtype == Z_EROFS_LCLUSTER_TYPE_HEAD2) &&
!(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_2))) {
map->m_plen = 1ULL << lclusterbits;
return 0;
@@ -396,19 +382,19 @@ static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m,
* BUG_ON in the debugging mode only for developers to notice that.
*/
DBG_BUGON(lcn == initial_lcn &&
m->type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD);
m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD);
switch (m->type) {
case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN:
case Z_EROFS_VLE_CLUSTER_TYPE_HEAD1:
case Z_EROFS_VLE_CLUSTER_TYPE_HEAD2:
case Z_EROFS_LCLUSTER_TYPE_PLAIN:
case Z_EROFS_LCLUSTER_TYPE_HEAD1:
case Z_EROFS_LCLUSTER_TYPE_HEAD2:
/*
* if the 1st NONHEAD lcluster is actually PLAIN or HEAD type
* rather than CBLKCNT, it's a 1 lcluster-sized pcluster.
*/
m->compressedblks = 1 << (lclusterbits - LOG_BLOCK_SIZE);
m->compressedblks = 1 << (lclusterbits - sb->s_blocksize_bits);
break;
case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
case Z_EROFS_LCLUSTER_TYPE_NONHEAD:
if (m->delta[0] != 1)
goto err_bonus_cblkcnt;
if (m->compressedblks)
@@ -422,7 +408,7 @@ static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m,
return -EFSCORRUPTED;
}
out:
map->m_plen = (u64)m->compressedblks << LOG_BLOCK_SIZE;
map->m_plen = erofs_pos(sb, m->compressedblks);
return 0;
err_bonus_cblkcnt:
erofs_err(m->inode->i_sb,
@@ -452,12 +438,12 @@ static int z_erofs_get_extent_decompressedlen(struct z_erofs_maprecorder *m)
if (err)
return err;
if (m->type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) {
if (m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
DBG_BUGON(!m->delta[1] &&
m->clusterofs != 1 << lclusterbits);
} else if (m->type == Z_EROFS_VLE_CLUSTER_TYPE_PLAIN ||
m->type == Z_EROFS_VLE_CLUSTER_TYPE_HEAD1 ||
m->type == Z_EROFS_VLE_CLUSTER_TYPE_HEAD2) {
} else if (m->type == Z_EROFS_LCLUSTER_TYPE_PLAIN ||
m->type == Z_EROFS_LCLUSTER_TYPE_HEAD1 ||
m->type == Z_EROFS_LCLUSTER_TYPE_HEAD2) {
/* go on until the next HEAD lcluster */
if (lcn != headlcn)
break;
@@ -476,8 +462,7 @@ static int z_erofs_get_extent_decompressedlen(struct z_erofs_maprecorder *m)
}
static int z_erofs_do_map_blocks(struct inode *inode,
struct erofs_map_blocks *map,
int flags)
struct erofs_map_blocks *map, int flags)
{
struct erofs_inode *const vi = EROFS_I(inode);
bool ztailpacking = vi->z_advise & Z_EROFS_ADVISE_INLINE_PCLUSTER;
@@ -507,9 +492,9 @@ static int z_erofs_do_map_blocks(struct inode *inode,
end = (m.lcn + 1ULL) << lclusterbits;
switch (m.type) {
case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN:
case Z_EROFS_VLE_CLUSTER_TYPE_HEAD1:
case Z_EROFS_VLE_CLUSTER_TYPE_HEAD2:
case Z_EROFS_LCLUSTER_TYPE_PLAIN:
case Z_EROFS_LCLUSTER_TYPE_HEAD1:
case Z_EROFS_LCLUSTER_TYPE_HEAD2:
if (endoff >= m.clusterofs) {
m.headtype = m.type;
map->m_la = (m.lcn << lclusterbits) | m.clusterofs;
@@ -534,7 +519,7 @@ static int z_erofs_do_map_blocks(struct inode *inode,
map->m_flags |= EROFS_MAP_FULL_MAPPED;
m.delta[0] = 1;
fallthrough;
case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
case Z_EROFS_LCLUSTER_TYPE_NONHEAD:
/* get the corresponding first chunk */
err = z_erofs_extent_lookback(&m, m.delta[0]);
if (err)
@@ -555,7 +540,7 @@ static int z_erofs_do_map_blocks(struct inode *inode,
vi->z_tailextent_headlcn = m.lcn;
/* for non-compact indexes, fragmentoff is 64 bits */
if (fragment &&
vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY)
vi->datalayout == EROFS_INODE_COMPRESSED_FULL)
vi->z_fragmentoff |= (u64)m.pblk << 32;
}
if (ztailpacking && m.lcn == vi->z_tailextent_headlcn) {
@@ -565,13 +550,13 @@ static int z_erofs_do_map_blocks(struct inode *inode,
} else if (fragment && m.lcn == vi->z_tailextent_headlcn) {
map->m_flags |= EROFS_MAP_FRAGMENT;
} else {
map->m_pa = blknr_to_addr(m.pblk);
map->m_pa = erofs_pos(inode->i_sb, m.pblk);
err = z_erofs_get_extent_compressedlen(&m, initial_lcn);
if (err)
goto unmap_out;
}
if (m.headtype == Z_EROFS_VLE_CLUSTER_TYPE_PLAIN) {
if (m.headtype == Z_EROFS_LCLUSTER_TYPE_PLAIN) {
if (map->m_llen > map->m_plen) {
DBG_BUGON(1);
err = -EFSCORRUPTED;
@@ -583,7 +568,7 @@ static int z_erofs_do_map_blocks(struct inode *inode,
else
map->m_algorithmformat =
Z_EROFS_COMPRESSION_SHIFTED;
} else if (m.headtype == Z_EROFS_VLE_CLUSTER_TYPE_HEAD2) {
} else if (m.headtype == Z_EROFS_LCLUSTER_TYPE_HEAD2) {
map->m_algorithmformat = vi->z_algorithmtype[1];
} else {
map->m_algorithmformat = vi->z_algorithmtype[0];
@@ -592,7 +577,7 @@ static int z_erofs_do_map_blocks(struct inode *inode,
if ((flags & EROFS_GET_BLOCKS_FIEMAP) ||
((flags & EROFS_GET_BLOCKS_READMORE) &&
map->m_algorithmformat == Z_EROFS_COMPRESSION_LZMA &&
map->m_llen >= EROFS_BLKSIZ)) {
map->m_llen >= i_blocksize(inode))) {
err = z_erofs_get_extent_decompressedlen(&m);
if (!err)
map->m_flags |= EROFS_MAP_FULL_MAPPED;
@@ -600,9 +585,6 @@ static int z_erofs_do_map_blocks(struct inode *inode,
unmap_out:
erofs_unmap_metabuf(&m.map->buf);
erofs_dbg("%s, m_la %llu m_pa %llu m_llen %llu m_plen %llu m_flags 0%o",
__func__, map->m_la, map->m_pa,
map->m_llen, map->m_plen, map->m_flags);
return err;
}
@@ -633,13 +615,13 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
goto out_unlock;
pos = ALIGN(erofs_iloc(inode) + vi->inode_isize + vi->xattr_isize, 8);
kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(pos), EROFS_KMAP);
kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(sb, pos), EROFS_KMAP);
if (IS_ERR(kaddr)) {
err = PTR_ERR(kaddr);
goto out_unlock;
}
h = kaddr + erofs_blkoff(pos);
h = kaddr + erofs_blkoff(sb, pos);
/*
* if the highest bit of the 8-byte map header is set, the whole file
* is stored in the packed inode. The rest bits keeps z_fragmentoff.
@@ -663,7 +645,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
goto out_put_metabuf;
}
vi->z_logical_clusterbits = LOG_BLOCK_SIZE + (h->h_clusterbits & 7);
vi->z_logical_clusterbits = sb->s_blocksize_bits + (h->h_clusterbits & 7);
if (!erofs_sb_has_big_pcluster(EROFS_SB(sb)) &&
vi->z_advise & (Z_EROFS_ADVISE_BIG_PCLUSTER_1 |
Z_EROFS_ADVISE_BIG_PCLUSTER_2)) {
@@ -672,7 +654,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
err = -EFSCORRUPTED;
goto out_put_metabuf;
}
if (vi->datalayout == EROFS_INODE_FLAT_COMPRESSION &&
if (vi->datalayout == EROFS_INODE_COMPRESSED_COMPACT &&
!(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1) ^
!(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_2)) {
erofs_err(sb, "big pcluster head1/2 of compact indexes should be consistent for nid %llu",
@@ -692,7 +674,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
erofs_put_metabuf(&map.buf);
if (!map.m_plen ||
erofs_blkoff(map.m_pa) + map.m_plen > EROFS_BLKSIZ) {
erofs_blkoff(sb, map.m_pa) + map.m_plen > sb->s_blocksize) {
erofs_err(sb, "invalid tail-packing pclustersize %llu",
map.m_plen);
err = -EFSCORRUPTED;
+7 -34
View File
@@ -228,7 +228,6 @@ static ssize_t eventfd_read(struct kiocb *iocb, struct iov_iter *to)
struct file *file = iocb->ki_filp;
struct eventfd_ctx *ctx = file->private_data;
__u64 ucnt = 0;
DECLARE_WAITQUEUE(wait, current);
if (iov_iter_count(to) < sizeof(ucnt))
return -EINVAL;
@@ -239,23 +238,11 @@ static ssize_t eventfd_read(struct kiocb *iocb, struct iov_iter *to)
spin_unlock_irq(&ctx->wqh.lock);
return -EAGAIN;
}
__add_wait_queue(&ctx->wqh, &wait);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
if (ctx->count)
break;
if (signal_pending(current)) {
__remove_wait_queue(&ctx->wqh, &wait);
__set_current_state(TASK_RUNNING);
spin_unlock_irq(&ctx->wqh.lock);
return -ERESTARTSYS;
}
if (wait_event_interruptible_locked_irq(ctx->wqh, ctx->count)) {
spin_unlock_irq(&ctx->wqh.lock);
schedule();
spin_lock_irq(&ctx->wqh.lock);
return -ERESTARTSYS;
}
__remove_wait_queue(&ctx->wqh, &wait);
__set_current_state(TASK_RUNNING);
}
eventfd_ctx_do_read(ctx, &ucnt);
current->in_eventfd = 1;
@@ -275,7 +262,6 @@ static ssize_t eventfd_write(struct file *file, const char __user *buf, size_t c
struct eventfd_ctx *ctx = file->private_data;
ssize_t res;
__u64 ucnt;
DECLARE_WAITQUEUE(wait, current);
if (count < sizeof(ucnt))
return -EINVAL;
@@ -288,23 +274,10 @@ static ssize_t eventfd_write(struct file *file, const char __user *buf, size_t c
if (ULLONG_MAX - ctx->count > ucnt)
res = sizeof(ucnt);
else if (!(file->f_flags & O_NONBLOCK)) {
__add_wait_queue(&ctx->wqh, &wait);
for (res = 0;;) {
set_current_state(TASK_INTERRUPTIBLE);
if (ULLONG_MAX - ctx->count > ucnt) {
res = sizeof(ucnt);
break;
}
if (signal_pending(current)) {
res = -ERESTARTSYS;
break;
}
spin_unlock_irq(&ctx->wqh.lock);
schedule();
spin_lock_irq(&ctx->wqh.lock);
}
__remove_wait_queue(&ctx->wqh, &wait);
__set_current_state(TASK_RUNNING);
res = wait_event_interruptible_locked_irq(ctx->wqh,
ULLONG_MAX - ctx->count > ucnt);
if (!res)
res = sizeof(ucnt);
}
if (likely(res > 0)) {
ctx->count += ucnt;
+2 -2
View File
@@ -483,8 +483,8 @@ static inline void ep_set_busy_poll_napi_id(struct epitem *epi)
* (efd1) notices that it may have some event ready, so it needs to wake up
* the waiters on its poll wait list (efd2). So it calls ep_poll_safewake()
* that ends up in another wake_up(), after having checked about the
* recursion constraints. That are, no more than EP_MAX_POLLWAKE_NESTS, to
* avoid stack blasting.
* recursion constraints. That are, no more than EP_MAX_NESTS, to avoid
* stack blasting.
*
* When CONFIG_DEBUG_LOCK_ALLOC is enabled, make sure lockdep can handle
* this special case of epoll.
+12 -13
View File
@@ -101,8 +101,8 @@ static void ext2_xattr_rehash(struct ext2_xattr_header *,
static const struct xattr_handler *ext2_xattr_handler_map[] = {
[EXT2_XATTR_INDEX_USER] = &ext2_xattr_user_handler,
#ifdef CONFIG_EXT2_FS_POSIX_ACL
[EXT2_XATTR_INDEX_POSIX_ACL_ACCESS] = &posix_acl_access_xattr_handler,
[EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT] = &posix_acl_default_xattr_handler,
[EXT2_XATTR_INDEX_POSIX_ACL_ACCESS] = &nop_posix_acl_access,
[EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT] = &nop_posix_acl_default,
#endif
[EXT2_XATTR_INDEX_TRUSTED] = &ext2_xattr_trusted_handler,
#ifdef CONFIG_EXT2_FS_SECURITY
@@ -113,10 +113,6 @@ static const struct xattr_handler *ext2_xattr_handler_map[] = {
const struct xattr_handler *ext2_xattr_handlers[] = {
&ext2_xattr_user_handler,
&ext2_xattr_trusted_handler,
#ifdef CONFIG_EXT2_FS_POSIX_ACL
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
#endif
#ifdef CONFIG_EXT2_FS_SECURITY
&ext2_xattr_security_handler,
#endif
@@ -125,14 +121,18 @@ const struct xattr_handler *ext2_xattr_handlers[] = {
#define EA_BLOCK_CACHE(inode) (EXT2_SB(inode->i_sb)->s_ea_block_cache)
static inline const struct xattr_handler *
ext2_xattr_handler(int name_index)
static inline const char *ext2_xattr_prefix(int name_index,
struct dentry *dentry)
{
const struct xattr_handler *handler = NULL;
if (name_index > 0 && name_index < ARRAY_SIZE(ext2_xattr_handler_map))
handler = ext2_xattr_handler_map[name_index];
return handler;
if (!xattr_handler_can_list(handler, dentry))
return NULL;
return xattr_prefix(handler);
}
static bool
@@ -333,11 +333,10 @@ bad_block:
/* list the attribute names */
for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
entry = EXT2_XATTR_NEXT(entry)) {
const struct xattr_handler *handler =
ext2_xattr_handler(entry->e_name_index);
const char *prefix;
if (handler && (!handler->list || handler->list(dentry))) {
const char *prefix = handler->prefix ?: handler->name;
prefix = ext2_xattr_prefix(entry->e_name_index, dentry);
if (prefix) {
size_t prefix_len = strlen(prefix);
size_t size = prefix_len + entry->e_name_len + 1;
+12 -13
View File
@@ -88,8 +88,8 @@ static void ext4_xattr_rehash(struct ext4_xattr_header *);
static const struct xattr_handler * const ext4_xattr_handler_map[] = {
[EXT4_XATTR_INDEX_USER] = &ext4_xattr_user_handler,
#ifdef CONFIG_EXT4_FS_POSIX_ACL
[EXT4_XATTR_INDEX_POSIX_ACL_ACCESS] = &posix_acl_access_xattr_handler,
[EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT] = &posix_acl_default_xattr_handler,
[EXT4_XATTR_INDEX_POSIX_ACL_ACCESS] = &nop_posix_acl_access,
[EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT] = &nop_posix_acl_default,
#endif
[EXT4_XATTR_INDEX_TRUSTED] = &ext4_xattr_trusted_handler,
#ifdef CONFIG_EXT4_FS_SECURITY
@@ -101,10 +101,6 @@ static const struct xattr_handler * const ext4_xattr_handler_map[] = {
const struct xattr_handler *ext4_xattr_handlers[] = {
&ext4_xattr_user_handler,
&ext4_xattr_trusted_handler,
#ifdef CONFIG_EXT4_FS_POSIX_ACL
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
#endif
#ifdef CONFIG_EXT4_FS_SECURITY
&ext4_xattr_security_handler,
#endif
@@ -173,14 +169,18 @@ static void ext4_xattr_block_csum_set(struct inode *inode,
bh->b_blocknr, BHDR(bh));
}
static inline const struct xattr_handler *
ext4_xattr_handler(int name_index)
static inline const char *ext4_xattr_prefix(int name_index,
struct dentry *dentry)
{
const struct xattr_handler *handler = NULL;
if (name_index > 0 && name_index < ARRAY_SIZE(ext4_xattr_handler_map))
handler = ext4_xattr_handler_map[name_index];
return handler;
if (!xattr_handler_can_list(handler, dentry))
return NULL;
return xattr_prefix(handler);
}
static int
@@ -740,11 +740,10 @@ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry,
size_t rest = buffer_size;
for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) {
const struct xattr_handler *handler =
ext4_xattr_handler(entry->e_name_index);
const char *prefix;
if (handler && (!handler->list || handler->list(dentry))) {
const char *prefix = handler->prefix ?: handler->name;
prefix = ext4_xattr_prefix(entry->e_name_index, dentry);
if (prefix) {
size_t prefix_len = strlen(prefix);
size_t size = prefix_len + entry->e_name_len + 1;
+12 -12
View File
@@ -192,8 +192,8 @@ const struct xattr_handler f2fs_xattr_security_handler = {
static const struct xattr_handler *f2fs_xattr_handler_map[] = {
[F2FS_XATTR_INDEX_USER] = &f2fs_xattr_user_handler,
#ifdef CONFIG_F2FS_FS_POSIX_ACL
[F2FS_XATTR_INDEX_POSIX_ACL_ACCESS] = &posix_acl_access_xattr_handler,
[F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT] = &posix_acl_default_xattr_handler,
[F2FS_XATTR_INDEX_POSIX_ACL_ACCESS] = &nop_posix_acl_access,
[F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT] = &nop_posix_acl_default,
#endif
[F2FS_XATTR_INDEX_TRUSTED] = &f2fs_xattr_trusted_handler,
#ifdef CONFIG_F2FS_FS_SECURITY
@@ -204,10 +204,6 @@ static const struct xattr_handler *f2fs_xattr_handler_map[] = {
const struct xattr_handler *f2fs_xattr_handlers[] = {
&f2fs_xattr_user_handler,
#ifdef CONFIG_F2FS_FS_POSIX_ACL
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
#endif
&f2fs_xattr_trusted_handler,
#ifdef CONFIG_F2FS_FS_SECURITY
&f2fs_xattr_security_handler,
@@ -216,13 +212,18 @@ const struct xattr_handler *f2fs_xattr_handlers[] = {
NULL,
};
static inline const struct xattr_handler *f2fs_xattr_handler(int index)
static inline const char *f2fs_xattr_prefix(int index,
struct dentry *dentry)
{
const struct xattr_handler *handler = NULL;
if (index > 0 && index < ARRAY_SIZE(f2fs_xattr_handler_map))
handler = f2fs_xattr_handler_map[index];
return handler;
if (!xattr_handler_can_list(handler, dentry))
return NULL;
return xattr_prefix(handler);
}
static struct f2fs_xattr_entry *__find_xattr(void *base_addr,
@@ -573,12 +574,12 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
last_base_addr = (void *)base_addr + XATTR_SIZE(inode);
list_for_each_xattr(entry, base_addr) {
const struct xattr_handler *handler =
f2fs_xattr_handler(entry->e_name_index);
const char *prefix;
size_t prefix_len;
size_t size;
prefix = f2fs_xattr_prefix(entry->e_name_index, dentry);
if ((void *)(entry) + sizeof(__u32) > last_base_addr ||
(void *)XATTR_NEXT_ENTRY(entry) > last_base_addr) {
f2fs_err(F2FS_I_SB(inode), "inode (%lu) has corrupted xattr",
@@ -590,10 +591,9 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
goto cleanup;
}
if (!handler || (handler->list && !handler->list(dentry)))
if (!prefix)
continue;
prefix = xattr_prefix(handler);
prefix_len = strlen(prefix);
size = prefix_len + entry->e_name_len + 1;
if (buffer) {
+19 -18
View File
@@ -2269,30 +2269,31 @@ static long fuse_dev_ioctl(struct file *file, unsigned int cmd,
int res;
int oldfd;
struct fuse_dev *fud = NULL;
struct fd f;
switch (cmd) {
case FUSE_DEV_IOC_CLONE:
res = -EFAULT;
if (!get_user(oldfd, (__u32 __user *)arg)) {
struct file *old = fget(oldfd);
if (get_user(oldfd, (__u32 __user *)arg))
return -EFAULT;
res = -EINVAL;
if (old) {
/*
* Check against file->f_op because CUSE
* uses the same ioctl handler.
*/
if (old->f_op == file->f_op)
fud = fuse_get_dev(old);
f = fdget(oldfd);
if (!f.file)
return -EINVAL;
if (fud) {
mutex_lock(&fuse_mutex);
res = fuse_device_clone(fud->fc, file);
mutex_unlock(&fuse_mutex);
}
fput(old);
}
/*
* Check against file->f_op because CUSE
* uses the same ioctl handler.
*/
if (f.file->f_op == file->f_op)
fud = fuse_get_dev(f.file);
res = -EINVAL;
if (fud) {
mutex_lock(&fuse_mutex);
res = fuse_device_clone(fud->fc, file);
mutex_unlock(&fuse_mutex);
}
fdput(f);
break;
case FUSE_DEV_IOC_PASSTHROUGH_OPEN:
res = -EFAULT;
-2
View File
@@ -1501,8 +1501,6 @@ const struct xattr_handler *gfs2_xattr_handlers_max[] = {
/* GFS2_FS_FORMAT_MIN */
&gfs2_xattr_user_handler,
&gfs2_xattr_security_handler,
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
NULL,
};
+23 -5
View File
@@ -511,7 +511,11 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
if (type == HFSPLUS_FOLDER) {
struct hfsplus_cat_folder *folder = &entry.folder;
WARN_ON(fd->entrylength < sizeof(struct hfsplus_cat_folder));
if (fd->entrylength < sizeof(struct hfsplus_cat_folder)) {
pr_err("bad catalog folder entry\n");
res = -EIO;
goto out;
}
hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
sizeof(struct hfsplus_cat_folder));
hfsplus_get_perms(inode, &folder->permissions, 1);
@@ -531,7 +535,11 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
} else if (type == HFSPLUS_FILE) {
struct hfsplus_cat_file *file = &entry.file;
WARN_ON(fd->entrylength < sizeof(struct hfsplus_cat_file));
if (fd->entrylength < sizeof(struct hfsplus_cat_file)) {
pr_err("bad catalog file entry\n");
res = -EIO;
goto out;
}
hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
sizeof(struct hfsplus_cat_file));
@@ -562,6 +570,7 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
pr_err("bad catalog entry used to create inode\n");
res = -EIO;
}
out:
return res;
}
@@ -570,6 +579,7 @@ int hfsplus_cat_write_inode(struct inode *inode)
struct inode *main_inode = inode;
struct hfs_find_data fd;
hfsplus_cat_entry entry;
int res = 0;
if (HFSPLUS_IS_RSRC(inode))
main_inode = HFSPLUS_I(inode)->rsrc_inode;
@@ -588,7 +598,11 @@ int hfsplus_cat_write_inode(struct inode *inode)
if (S_ISDIR(main_inode->i_mode)) {
struct hfsplus_cat_folder *folder = &entry.folder;
WARN_ON(fd.entrylength < sizeof(struct hfsplus_cat_folder));
if (fd.entrylength < sizeof(struct hfsplus_cat_folder)) {
pr_err("bad catalog folder entry\n");
res = -EIO;
goto out;
}
hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
sizeof(struct hfsplus_cat_folder));
/* simple node checks? */
@@ -613,7 +627,11 @@ int hfsplus_cat_write_inode(struct inode *inode)
} else {
struct hfsplus_cat_file *file = &entry.file;
WARN_ON(fd.entrylength < sizeof(struct hfsplus_cat_file));
if (fd.entrylength < sizeof(struct hfsplus_cat_file)) {
pr_err("bad catalog file entry\n");
res = -EIO;
goto out;
}
hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
sizeof(struct hfsplus_cat_file));
hfsplus_inode_write_fork(inode, &file->data_fork);
@@ -634,7 +652,7 @@ int hfsplus_cat_write_inode(struct inode *inode)
set_bit(HFSPLUS_I_CAT_DIRTY, &HFSPLUS_I(inode)->flags);
out:
hfs_find_exit(&fd);
return 0;
return res;
}
int hfsplus_fileattr_get(struct dentry *dentry, struct fileattr *fa)
+4 -4
View File
@@ -1804,8 +1804,8 @@ EXPORT_SYMBOL(bmap);
/*
* With relative atime, only update atime if the previous atime is
* earlier than either the ctime or mtime or if at least a day has
* passed since the last atime update.
* earlier than or equal to either the ctime or mtime,
* or if at least a day has passed since the last atime update.
*/
static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
struct timespec64 now)
@@ -1814,12 +1814,12 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
if (!(mnt->mnt_flags & MNT_RELATIME))
return 1;
/*
* Is mtime younger than atime? If yes, update atime:
* Is mtime younger than or equal to atime? If yes, update atime:
*/
if (timespec64_compare(&inode->i_mtime, &inode->i_atime) >= 0)
return 1;
/*
* Is ctime younger than atime? If yes, update atime:
* Is ctime younger than or equal to atime? If yes, update atime:
*/
if (timespec64_compare(&inode->i_ctime, &inode->i_atime) >= 0)
return 1;
-2
View File
@@ -259,8 +259,6 @@ ssize_t __kernel_write_iter(struct file *file, struct iov_iter *from, loff_t *po
/*
* fs/attr.c
*/
int setattr_should_drop_sgid(struct mnt_idmap *idmap,
const struct inode *inode);
struct mnt_idmap *alloc_mnt_idmap(struct user_namespace *mnt_userns);
struct mnt_idmap *mnt_idmap_get(struct mnt_idmap *idmap);
void mnt_idmap_put(struct mnt_idmap *idmap);
+14 -15
View File
@@ -919,17 +919,14 @@ const struct xattr_handler *jffs2_xattr_handlers[] = {
&jffs2_user_xattr_handler,
#ifdef CONFIG_JFFS2_FS_SECURITY
&jffs2_security_xattr_handler,
#endif
#ifdef CONFIG_JFFS2_FS_POSIX_ACL
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
#endif
&jffs2_trusted_xattr_handler,
NULL
};
static const struct xattr_handler *xprefix_to_handler(int xprefix) {
const struct xattr_handler *ret;
static const char *jffs2_xattr_prefix(int xprefix, struct dentry *dentry)
{
const struct xattr_handler *ret = NULL;
switch (xprefix) {
case JFFS2_XPREFIX_USER:
@@ -942,20 +939,23 @@ static const struct xattr_handler *xprefix_to_handler(int xprefix) {
#endif
#ifdef CONFIG_JFFS2_FS_POSIX_ACL
case JFFS2_XPREFIX_ACL_ACCESS:
ret = &posix_acl_access_xattr_handler;
ret = &nop_posix_acl_access;
break;
case JFFS2_XPREFIX_ACL_DEFAULT:
ret = &posix_acl_default_xattr_handler;
ret = &nop_posix_acl_default;
break;
#endif
case JFFS2_XPREFIX_TRUSTED:
ret = &jffs2_trusted_xattr_handler;
break;
default:
ret = NULL;
break;
return NULL;
}
return ret;
if (!xattr_handler_can_list(ret, dentry))
return NULL;
return xattr_prefix(ret);
}
ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
@@ -966,7 +966,6 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
struct jffs2_inode_cache *ic = f->inocache;
struct jffs2_xattr_ref *ref, **pref;
struct jffs2_xattr_datum *xd;
const struct xattr_handler *xhandle;
const char *prefix;
ssize_t prefix_len, len, rc;
int retry = 0;
@@ -998,10 +997,10 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
goto out;
}
}
xhandle = xprefix_to_handler(xd->xprefix);
if (!xhandle || (xhandle->list && !xhandle->list(dentry)))
prefix = jffs2_xattr_prefix(xd->xprefix, dentry);
if (!prefix)
continue;
prefix = xhandle->prefix ?: xhandle->name;
prefix_len = strlen(prefix);
rc = prefix_len + xd->name_len + 1;
+34 -5
View File
@@ -691,6 +691,35 @@ void grab_metapage(struct metapage * mp)
unlock_page(mp->page);
}
static int metapage_write_one(struct page *page)
{
struct folio *folio = page_folio(page);
struct address_space *mapping = folio->mapping;
struct writeback_control wbc = {
.sync_mode = WB_SYNC_ALL,
.nr_to_write = folio_nr_pages(folio),
};
int ret = 0;
BUG_ON(!folio_test_locked(folio));
folio_wait_writeback(folio);
if (folio_clear_dirty_for_io(folio)) {
folio_get(folio);
ret = metapage_writepage(page, &wbc);
if (ret == 0)
folio_wait_writeback(folio);
folio_put(folio);
} else {
folio_unlock(folio);
}
if (!ret)
ret = filemap_check_errors(mapping);
return ret;
}
void force_metapage(struct metapage *mp)
{
struct page *page = mp->page;
@@ -700,8 +729,8 @@ void force_metapage(struct metapage *mp)
get_page(page);
lock_page(page);
set_page_dirty(page);
if (write_one_page(page))
jfs_error(mp->sb, "write_one_page() failed\n");
if (metapage_write_one(page))
jfs_error(mp->sb, "metapage_write_one() failed\n");
clear_bit(META_forcewrite, &mp->flag);
put_page(page);
}
@@ -746,9 +775,9 @@ void release_metapage(struct metapage * mp)
set_page_dirty(page);
if (test_bit(META_sync, &mp->flag)) {
clear_bit(META_sync, &mp->flag);
if (write_one_page(page))
jfs_error(mp->sb, "write_one_page() failed\n");
lock_page(page); /* write_one_page unlocks the page */
if (metapage_write_one(page))
jfs_error(mp->sb, "metapage_write_one() failed\n");
lock_page(page);
}
} else if (mp->lsn) /* discard_metapage doesn't remove it */
remove_from_logsync(mp);
-4
View File
@@ -986,10 +986,6 @@ static const struct xattr_handler jfs_trusted_xattr_handler = {
};
const struct xattr_handler *jfs_xattr_handlers[] = {
#ifdef CONFIG_JFS_POSIX_ACL
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
#endif
&jfs_os2_xattr_handler,
&jfs_user_xattr_handler,
&jfs_security_xattr_handler,
+1 -7
View File
@@ -1748,12 +1748,6 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent,
return error;
}
/* Relationship between mode and the DT_xxx types */
static inline unsigned char dt_type(struct kernfs_node *kn)
{
return (kn->mode >> 12) & 15;
}
static int kernfs_dir_fop_release(struct inode *inode, struct file *filp)
{
kernfs_put(filp->private_data);
@@ -1831,7 +1825,7 @@ static int kernfs_fop_readdir(struct file *file, struct dir_context *ctx)
pos;
pos = kernfs_dir_next_pos(ns, parent, ctx->pos, pos)) {
const char *name = pos->name;
unsigned int type = dt_type(pos);
unsigned int type = fs_umode_to_dtype(pos->mode);
int len = strlen(name);
ino_t ino = kernfs_ino(pos);
+2 -7
View File
@@ -174,12 +174,6 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int whence)
}
EXPORT_SYMBOL(dcache_dir_lseek);
/* Relationship between i_mode and the DT_xxx types */
static inline unsigned char dt_type(struct inode *inode)
{
return (inode->i_mode >> 12) & 15;
}
/*
* Directory is locked and all positive dentries in it are safe, since
* for ramfs-type trees they can't go away without unlink() or rmdir(),
@@ -206,7 +200,8 @@ int dcache_readdir(struct file *file, struct dir_context *ctx)
while ((next = scan_positives(cursor, p, 1, next)) != NULL) {
if (!dir_emit(ctx, next->d_name.name, next->d_name.len,
d_inode(next)->i_ino, dt_type(d_inode(next))))
d_inode(next)->i_ino,
fs_umode_to_dtype(d_inode(next)->i_mode)))
break;
ctx->pos++;
p = &next->d_child;
+2 -2
View File
@@ -3574,9 +3574,9 @@ static int do_open(struct nameidata *nd,
/**
* vfs_tmpfile - create tmpfile
* @idmap: idmap of the mount the inode was found from
* @dentry: pointer to dentry of the base directory
* @parentpath: pointer to the path of the base directory
* @file: file descriptor of the new tmpfile
* @mode: mode of the new tmpfile
* @open_flag: flags
*
* Create a temporary file.
*
+9 -12
View File
@@ -2617,15 +2617,12 @@ static void mnt_warn_timestamp_expiry(struct path *mountpoint, struct vfsmount *
(ktime_get_real_seconds() + TIME_UPTIME_SEC_MAX > sb->s_time_max)) {
char *buf = (char *)__get_free_page(GFP_KERNEL);
char *mntpath = buf ? d_path(mountpoint, buf, PAGE_SIZE) : ERR_PTR(-ENOMEM);
struct tm tm;
time64_to_tm(sb->s_time_max, 0, &tm);
pr_warn("%s filesystem being %s at %s supports timestamps until %04ld (0x%llx)\n",
pr_warn("%s filesystem being %s at %s supports timestamps until %ptTd (0x%llx)\n",
sb->s_type->name,
is_mounted(mnt) ? "remounted" : "mounted",
mntpath,
tm.tm_year+1900, (unsigned long long)sb->s_time_max);
mntpath, &sb->s_time_max,
(unsigned long long)sb->s_time_max);
free_page((unsigned long)buf);
sb->s_iflags |= SB_I_TS_EXPIRY_WARNED;
@@ -4197,7 +4194,7 @@ static int build_mount_idmapped(const struct mount_attr *attr, size_t usize,
int err = 0;
struct ns_common *ns;
struct user_namespace *mnt_userns;
struct file *file;
struct fd f;
if (!((attr->attr_set | attr->attr_clr) & MOUNT_ATTR_IDMAP))
return 0;
@@ -4213,16 +4210,16 @@ static int build_mount_idmapped(const struct mount_attr *attr, size_t usize,
if (attr->userns_fd > INT_MAX)
return -EINVAL;
file = fget(attr->userns_fd);
if (!file)
f = fdget(attr->userns_fd);
if (!f.file)
return -EBADF;
if (!proc_ns_file(file)) {
if (!proc_ns_file(f.file)) {
err = -EINVAL;
goto out_fput;
}
ns = get_proc_ns(file_inode(file));
ns = get_proc_ns(file_inode(f.file));
if (ns->ops->type != CLONE_NEWUSER) {
err = -EINVAL;
goto out_fput;
@@ -4251,7 +4248,7 @@ static int build_mount_idmapped(const struct mount_attr *attr, size_t usize,
kattr->mnt_userns = get_user_ns(mnt_userns);
out_fput:
fput(file);
fdput(f);
return err;
}
+1 -3
View File
@@ -717,9 +717,7 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr,
if ((attr->ia_valid & ATTR_KILL_SUID) != 0 &&
inode->i_mode & S_ISUID)
inode->i_mode &= ~S_ISUID;
if ((attr->ia_valid & ATTR_KILL_SGID) != 0 &&
(inode->i_mode & (S_ISGID | S_IXGRP)) ==
(S_ISGID | S_IXGRP))
if (setattr_should_drop_sgid(&nop_mnt_idmap, inode))
inode->i_mode &= ~S_ISGID;
if ((attr->ia_valid & ATTR_MODE) != 0) {
int mode = attr->ia_mode & S_IALLUGO;
-1
View File
@@ -17,7 +17,6 @@ extern int nfs3_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
extern int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
struct posix_acl *dfacl);
extern ssize_t nfs3_listxattr(struct dentry *, char *, size_t);
extern const struct xattr_handler *nfs3_xattr_handlers[];
#else
static inline int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
struct posix_acl *dfacl)
-6
View File
@@ -300,12 +300,6 @@ fail:
goto out;
}
const struct xattr_handler *nfs3_xattr_handlers[] = {
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
NULL,
};
static int
nfs3_list_one_acl(struct inode *inode, int type, const char *name, void *data,
size_t size, ssize_t *result)
-3
View File
@@ -14,9 +14,6 @@ struct nfs_subversion nfs_v3 = {
.rpc_vers = &nfs_version3,
.rpc_ops = &nfs_v3_clientops,
.sops = &nfs_sops,
#ifdef CONFIG_NFS_V3_ACL
.xattr = nfs3_xattr_handlers,
#endif
};
static int __init init_nfs_v3(void)
-3
View File
@@ -1274,9 +1274,6 @@ int nfs_get_tree_common(struct fs_context *fc)
if (ctx->clone_data.sb->s_flags & SB_SYNCHRONOUS)
fc->sb_flags |= SB_SYNCHRONOUS;
if (server->caps & NFS_CAP_SECURITY_LABEL)
fc->lsm_flags |= SECURITY_LSM_NATIVE_LABELS;
/* Get a superblock - note that we may end up sharing one that already exists */
fc->s_fs_info = server;
s = sget_fc(fc, compare_super, nfs_set_super);
+1 -2
View File
@@ -3446,8 +3446,7 @@ out_acl:
p = xdr_reserve_space(xdr, 4);
if (!p)
goto out_resource;
err = xattr_supported_namespace(d_inode(dentry),
XATTR_USER_PREFIX);
err = xattr_supports_user_prefix(d_inode(dentry));
*p++ = cpu_to_be32(err == 0);
}
+9 -4
View File
@@ -663,7 +663,7 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
struct fanotify_info *info = fanotify_event_info(event);
unsigned int info_mode = FAN_GROUP_FLAG(group, FANOTIFY_INFO_MODES);
unsigned int pidfd_mode = info_mode & FAN_REPORT_PIDFD;
struct file *f = NULL;
struct file *f = NULL, *pidfd_file = NULL;
int ret, pidfd = FAN_NOPIDFD, fd = FAN_NOFD;
pr_debug("%s: group=%p event=%p\n", __func__, group, event);
@@ -718,7 +718,7 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
!pid_has_task(event->pid, PIDTYPE_TGID)) {
pidfd = FAN_NOPIDFD;
} else {
pidfd = pidfd_create(event->pid, 0);
pidfd = pidfd_prepare(event->pid, 0, &pidfd_file);
if (pidfd < 0)
pidfd = FAN_EPIDFD;
}
@@ -751,6 +751,9 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
if (f)
fd_install(fd, f);
if (pidfd_file)
fd_install(pidfd, pidfd_file);
return metadata.event_len;
out_close_fd:
@@ -759,8 +762,10 @@ out_close_fd:
fput(f);
}
if (pidfd >= 0)
close_fd(pidfd);
if (pidfd >= 0) {
put_unused_fd(pidfd);
fput(pidfd_file);
}
return ret;
}
-18
View File
@@ -235,24 +235,6 @@ bool proc_ns_file(const struct file *file)
return file->f_op == &ns_file_operations;
}
struct file *proc_ns_fget(int fd)
{
struct file *file;
file = fget(fd);
if (!file)
return ERR_PTR(-EBADF);
if (file->f_op != &ns_file_operations)
goto out_invalid;
return file;
out_invalid:
fput(file);
return ERR_PTR(-EINVAL);
}
/**
* ns_match() - Returns true if current namespace matches dev/ino provided.
* @ns: current namespace
-4
View File
@@ -1033,10 +1033,6 @@ static const struct xattr_handler ntfs_other_xattr_handler = {
};
const struct xattr_handler *ntfs_xattr_handlers[] = {
#ifdef CONFIG_NTFS3_FS_POSIX_ACL
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
#endif
&ntfs_other_xattr_handler,
NULL,
};
+1 -1
View File
@@ -2463,7 +2463,7 @@ static ssize_t ocfs2_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
return __blockdev_direct_IO(iocb, inode, inode->i_sb->s_bdev,
iter, get_block,
ocfs2_dio_end_io, NULL, 0);
ocfs2_dio_end_io, 0);
}
const struct address_space_operations ocfs2_aops = {
+5 -4
View File
@@ -2952,10 +2952,11 @@ retry:
*/
if (PAGE_SIZE <= OCFS2_SB(sb)->s_clustersize) {
if (PageDirty(page)) {
/*
* write_on_page will unlock the page on return
*/
ret = write_one_page(page);
unlock_page(page);
put_page(page);
ret = filemap_write_and_wait_range(mapping,
offset, map_end - 1);
goto retry;
}
}
+5 -9
View File
@@ -89,21 +89,17 @@ static struct ocfs2_xattr_def_value_root def_xv = {
const struct xattr_handler *ocfs2_xattr_handlers[] = {
&ocfs2_xattr_user_handler,
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
&ocfs2_xattr_trusted_handler,
&ocfs2_xattr_security_handler,
NULL
};
static const struct xattr_handler *ocfs2_xattr_handler_map[OCFS2_XATTR_MAX] = {
[OCFS2_XATTR_INDEX_USER] = &ocfs2_xattr_user_handler,
[OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS]
= &posix_acl_access_xattr_handler,
[OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT]
= &posix_acl_default_xattr_handler,
[OCFS2_XATTR_INDEX_TRUSTED] = &ocfs2_xattr_trusted_handler,
[OCFS2_XATTR_INDEX_SECURITY] = &ocfs2_xattr_security_handler,
[OCFS2_XATTR_INDEX_USER] = &ocfs2_xattr_user_handler,
[OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS] = &nop_posix_acl_access,
[OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT] = &nop_posix_acl_default,
[OCFS2_XATTR_INDEX_TRUSTED] = &ocfs2_xattr_trusted_handler,
[OCFS2_XATTR_INDEX_SECURITY] = &ocfs2_xattr_security_handler,
};
struct ocfs2_xattr_info {
+13 -5
View File
@@ -1198,13 +1198,21 @@ inline int build_open_flags(const struct open_how *how, struct open_flags *op)
}
/*
* In order to ensure programs get explicit errors when trying to use
* O_TMPFILE on old kernels, O_TMPFILE is implemented such that it
* looks like (O_DIRECTORY|O_RDWR & ~O_CREAT) to old kernels. But we
* have to require userspace to explicitly set it.
* Block bugs where O_DIRECTORY | O_CREAT created regular files.
* Note, that blocking O_DIRECTORY | O_CREAT here also protects
* O_TMPFILE below which requires O_DIRECTORY being raised.
*/
if ((flags & (O_DIRECTORY | O_CREAT)) == (O_DIRECTORY | O_CREAT))
return -EINVAL;
/* Now handle the creative implementation of O_TMPFILE. */
if (flags & __O_TMPFILE) {
if ((flags & O_TMPFILE_MASK) != O_TMPFILE)
/*
* In order to ensure programs get explicit errors when trying
* to use O_TMPFILE on old kernels we enforce that O_DIRECTORY
* is raised alongside __O_TMPFILE.
*/
if (!(flags & O_DIRECTORY))
return -EINVAL;
if (!(acc_mode & MAY_WRITE))
return -EINVAL;
-2
View File
@@ -555,8 +555,6 @@ static const struct xattr_handler orangefs_xattr_default_handler = {
};
const struct xattr_handler *orangefs_xattr_handlers[] = {
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
&orangefs_xattr_default_handler,
NULL
};
+1 -2
View File
@@ -81,8 +81,7 @@ int ovl_copy_xattr(struct super_block *sb, const struct path *oldpath, struct de
int error = 0;
size_t slen;
if (!(old->d_inode->i_opflags & IOP_XATTR) ||
!(new->d_inode->i_opflags & IOP_XATTR))
if (!old->d_inode->i_op->listxattr || !new->d_inode->i_op->listxattr)
return 0;
list_size = vfs_listxattr(old, NULL, 0);
-8
View File
@@ -1076,20 +1076,12 @@ static const struct xattr_handler ovl_other_xattr_handler = {
};
static const struct xattr_handler *ovl_trusted_xattr_handlers[] = {
#ifdef CONFIG_FS_POSIX_ACL
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
#endif
&ovl_own_trusted_xattr_handler,
&ovl_other_xattr_handler,
NULL
};
static const struct xattr_handler *ovl_user_xattr_handlers[] = {
#ifdef CONFIG_FS_POSIX_ACL
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
#endif
&ovl_own_user_xattr_handler,
&ovl_other_xattr_handler,
NULL
+5 -7
View File
@@ -214,7 +214,6 @@ static struct mount *next_group(struct mount *m, struct mount *origin)
/* all accesses are serialized by namespace_sem */
static struct mount *last_dest, *first_source, *last_source, *dest_master;
static struct mountpoint *mp;
static struct hlist_head *list;
static inline bool peers(struct mount *m1, struct mount *m2)
@@ -222,7 +221,7 @@ static inline bool peers(struct mount *m1, struct mount *m2)
return m1->mnt_group_id == m2->mnt_group_id && m1->mnt_group_id;
}
static int propagate_one(struct mount *m)
static int propagate_one(struct mount *m, struct mountpoint *dest_mp)
{
struct mount *child;
int type;
@@ -230,7 +229,7 @@ static int propagate_one(struct mount *m)
if (IS_MNT_NEW(m))
return 0;
/* skip if mountpoint isn't covered by it */
if (!is_subdir(mp->m_dentry, m->mnt.mnt_root))
if (!is_subdir(dest_mp->m_dentry, m->mnt.mnt_root))
return 0;
if (peers(m, last_dest)) {
type = CL_MAKE_SHARED;
@@ -262,7 +261,7 @@ static int propagate_one(struct mount *m)
if (IS_ERR(child))
return PTR_ERR(child);
read_seqlock_excl(&mount_lock);
mnt_set_mountpoint(m, mp, child);
mnt_set_mountpoint(m, dest_mp, child);
if (m->mnt_master != dest_master)
SET_MNT_MARK(m->mnt_master);
read_sequnlock_excl(&mount_lock);
@@ -299,13 +298,12 @@ int propagate_mnt(struct mount *dest_mnt, struct mountpoint *dest_mp,
last_dest = dest_mnt;
first_source = source_mnt;
last_source = source_mnt;
mp = dest_mp;
list = tree_list;
dest_master = dest_mnt->mnt_master;
/* all peers of dest_mnt, except dest_mnt itself */
for (n = next_peer(dest_mnt); n != dest_mnt; n = next_peer(n)) {
ret = propagate_one(n);
ret = propagate_one(n, dest_mp);
if (ret)
goto out;
}
@@ -316,7 +314,7 @@ int propagate_mnt(struct mount *dest_mnt, struct mountpoint *dest_mp,
/* everything in that slave group */
n = m;
do {
ret = propagate_one(n);
ret = propagate_one(n, dest_mp);
if (ret)
goto out;
n = next_peer(n);
+47 -14
View File
@@ -957,25 +957,62 @@ set_posix_acl(struct mnt_idmap *idmap, struct dentry *dentry,
}
EXPORT_SYMBOL(set_posix_acl);
int posix_acl_listxattr(struct inode *inode, char **buffer,
ssize_t *remaining_size)
{
int err;
if (!IS_POSIXACL(inode))
return 0;
if (inode->i_acl) {
err = xattr_list_one(buffer, remaining_size,
XATTR_NAME_POSIX_ACL_ACCESS);
if (err)
return err;
}
if (inode->i_default_acl) {
err = xattr_list_one(buffer, remaining_size,
XATTR_NAME_POSIX_ACL_DEFAULT);
if (err)
return err;
}
return 0;
}
static bool
posix_acl_xattr_list(struct dentry *dentry)
{
return IS_POSIXACL(d_backing_inode(dentry));
}
const struct xattr_handler posix_acl_access_xattr_handler = {
/*
* nop_posix_acl_access - legacy xattr handler for access POSIX ACLs
*
* This is the legacy POSIX ACL access xattr handler. It is used by some
* filesystems to implement their ->listxattr() inode operation. New code
* should never use them.
*/
const struct xattr_handler nop_posix_acl_access = {
.name = XATTR_NAME_POSIX_ACL_ACCESS,
.flags = ACL_TYPE_ACCESS,
.list = posix_acl_xattr_list,
};
EXPORT_SYMBOL_GPL(posix_acl_access_xattr_handler);
EXPORT_SYMBOL_GPL(nop_posix_acl_access);
const struct xattr_handler posix_acl_default_xattr_handler = {
/*
* nop_posix_acl_default - legacy xattr handler for default POSIX ACLs
*
* This is the legacy POSIX ACL default xattr handler. It is used by some
* filesystems to implement their ->listxattr() inode operation. New code
* should never use them.
*/
const struct xattr_handler nop_posix_acl_default = {
.name = XATTR_NAME_POSIX_ACL_DEFAULT,
.flags = ACL_TYPE_DEFAULT,
.list = posix_acl_xattr_list,
};
EXPORT_SYMBOL_GPL(posix_acl_default_xattr_handler);
EXPORT_SYMBOL_GPL(nop_posix_acl_default);
int simple_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
struct posix_acl *acl, int type)
@@ -1094,12 +1131,10 @@ retry_deleg:
if (error)
goto out_inode_unlock;
if (inode->i_opflags & IOP_XATTR)
if (likely(!is_bad_inode(inode)))
error = set_posix_acl(idmap, dentry, acl_type, kacl);
else if (unlikely(is_bad_inode(inode)))
error = -EIO;
else
error = -EOPNOTSUPP;
error = -EIO;
if (!error) {
fsnotify_xattr(dentry);
evm_inode_post_set_acl(dentry, acl_name, kacl);
@@ -1204,12 +1239,10 @@ retry_deleg:
if (error)
goto out_inode_unlock;
if (inode->i_opflags & IOP_XATTR)
if (likely(!is_bad_inode(inode)))
error = set_posix_acl(idmap, dentry, acl_type, NULL);
else if (unlikely(is_bad_inode(inode)))
error = -EIO;
else
error = -EOPNOTSUPP;
error = -EIO;
if (!error) {
fsnotify_xattr(dentry);
evm_inode_post_remove_acl(idmap, dentry, acl_name);
+7
View File
@@ -261,3 +261,10 @@ const struct inode_operations reiserfs_file_inode_operations = {
.fileattr_get = reiserfs_fileattr_get,
.fileattr_set = reiserfs_fileattr_set,
};
const struct inode_operations reiserfs_priv_file_inode_operations = {
.setattr = reiserfs_setattr,
.permission = reiserfs_permission,
.fileattr_get = reiserfs_fileattr_get,
.fileattr_set = reiserfs_fileattr_set,
};
+2 -4
View File
@@ -2087,10 +2087,8 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
* Mark it private if we're creating the privroot
* or something under it.
*/
if (IS_PRIVATE(dir) || dentry == REISERFS_SB(sb)->priv_root) {
inode->i_flags |= S_PRIVATE;
inode->i_opflags &= ~IOP_XATTR;
}
if (IS_PRIVATE(dir) || dentry == REISERFS_SB(sb)->priv_root)
reiserfs_init_priv_inode(inode);
if (reiserfs_posixacl(inode->i_sb)) {
reiserfs_write_unlock(inode->i_sb);
+45 -5
View File
@@ -378,13 +378,11 @@ static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry,
/*
* Propagate the private flag so we know we're
* in the priv tree. Also clear IOP_XATTR
* in the priv tree. Also clear xattr support
* since we don't have xattrs on xattr files.
*/
if (IS_PRIVATE(dir)) {
inode->i_flags |= S_PRIVATE;
inode->i_opflags &= ~IOP_XATTR;
}
if (IS_PRIVATE(dir))
reiserfs_init_priv_inode(inode);
}
reiserfs_write_unlock(dir->i_sb);
if (retval == IO_ERROR) {
@@ -1649,6 +1647,48 @@ static int reiserfs_rename(struct mnt_idmap *idmap,
return retval;
}
static const struct inode_operations reiserfs_priv_dir_inode_operations = {
.create = reiserfs_create,
.lookup = reiserfs_lookup,
.link = reiserfs_link,
.unlink = reiserfs_unlink,
.symlink = reiserfs_symlink,
.mkdir = reiserfs_mkdir,
.rmdir = reiserfs_rmdir,
.mknod = reiserfs_mknod,
.rename = reiserfs_rename,
.setattr = reiserfs_setattr,
.permission = reiserfs_permission,
.fileattr_get = reiserfs_fileattr_get,
.fileattr_set = reiserfs_fileattr_set,
};
static const struct inode_operations reiserfs_priv_symlink_inode_operations = {
.get_link = page_get_link,
.setattr = reiserfs_setattr,
.permission = reiserfs_permission,
};
static const struct inode_operations reiserfs_priv_special_inode_operations = {
.setattr = reiserfs_setattr,
.permission = reiserfs_permission,
};
void reiserfs_init_priv_inode(struct inode *inode)
{
inode->i_flags |= S_PRIVATE;
inode->i_opflags &= ~IOP_XATTR;
if (S_ISREG(inode->i_mode))
inode->i_op = &reiserfs_priv_file_inode_operations;
else if (S_ISDIR(inode->i_mode))
inode->i_op = &reiserfs_priv_dir_inode_operations;
else if (S_ISLNK(inode->i_mode))
inode->i_op = &reiserfs_priv_symlink_inode_operations;
else
inode->i_op = &reiserfs_priv_special_inode_operations;
}
/* directories can handle most operations... */
const struct inode_operations reiserfs_dir_inode_operations = {
.create = reiserfs_create,
+2
View File
@@ -3106,6 +3106,7 @@ int reiserfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
int __reiserfs_write_begin(struct page *page, unsigned from, unsigned len);
/* namei.c */
void reiserfs_init_priv_inode(struct inode *inode);
void set_de_name_and_namelen(struct reiserfs_dir_entry *de);
int search_by_entry_key(struct super_block *sb, const struct cpu_key *key,
struct treepath *path, struct reiserfs_dir_entry *de);
@@ -3175,6 +3176,7 @@ void reiserfs_unmap_buffer(struct buffer_head *);
/* file.c */
extern const struct inode_operations reiserfs_file_inode_operations;
extern const struct inode_operations reiserfs_priv_file_inode_operations;
extern const struct file_operations reiserfs_file_operations;
extern const struct address_space_operations reiserfs_address_space_operations;
+29 -28
View File
@@ -52,6 +52,7 @@
#include <linux/quotaops.h>
#include <linux/security.h>
#include <linux/posix_acl_xattr.h>
#include <linux/xattr.h>
#define PRIVROOT_NAME ".reiserfs_priv"
#define XAROOT_NAME "xattrs"
@@ -770,23 +771,34 @@ out:
(handler) != NULL; \
(handler) = *(handlers)++)
/* This is the implementation for the xattr plugin infrastructure */
static inline const struct xattr_handler *
find_xattr_handler_prefix(const struct xattr_handler **handlers,
const char *name)
static inline bool reiserfs_posix_acl_list(const char *name,
struct dentry *dentry)
{
const struct xattr_handler *xah;
return (posix_acl_type(name) >= 0) &&
IS_POSIXACL(d_backing_inode(dentry));
}
if (!handlers)
return NULL;
/* This is the implementation for the xattr plugin infrastructure */
static inline bool reiserfs_xattr_list(const struct xattr_handler **handlers,
const char *name, struct dentry *dentry)
{
if (handlers) {
const struct xattr_handler *xah = NULL;
for_each_xattr_handler(handlers, xah) {
const char *prefix = xattr_prefix(xah);
if (strncmp(prefix, name, strlen(prefix)) == 0)
break;
for_each_xattr_handler(handlers, xah) {
const char *prefix = xattr_prefix(xah);
if (strncmp(prefix, name, strlen(prefix)))
continue;
if (!xattr_handler_can_list(xah, dentry))
return false;
return true;
}
}
return xah;
return reiserfs_posix_acl_list(name, dentry);
}
struct listxattr_buf {
@@ -807,12 +819,8 @@ static bool listxattr_filler(struct dir_context *ctx, const char *name,
if (name[0] != '.' ||
(namelen != 1 && (name[1] != '.' || namelen != 2))) {
const struct xattr_handler *handler;
handler = find_xattr_handler_prefix(b->dentry->d_sb->s_xattr,
name);
if (!handler /* Unsupported xattr name */ ||
(handler->list && !handler->list(b->dentry)))
if (!reiserfs_xattr_list(b->dentry->d_sb->s_xattr, name,
b->dentry))
return true;
size = namelen + 1;
if (b->buf) {
@@ -888,8 +896,7 @@ static int create_privroot(struct dentry *dentry)
return -EOPNOTSUPP;
}
d_inode(dentry)->i_flags |= S_PRIVATE;
d_inode(dentry)->i_opflags &= ~IOP_XATTR;
reiserfs_init_priv_inode(d_inode(dentry));
reiserfs_info(dentry->d_sb, "Created %s - reserved for xattr "
"storage.\n", PRIVROOT_NAME);
@@ -910,10 +917,6 @@ const struct xattr_handler *reiserfs_xattr_handlers[] = {
#endif
#ifdef CONFIG_REISERFS_FS_SECURITY
&reiserfs_xattr_security_handler,
#endif
#ifdef CONFIG_REISERFS_FS_POSIX_ACL
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
#endif
NULL
};
@@ -975,10 +978,8 @@ int reiserfs_lookup_privroot(struct super_block *s)
if (!IS_ERR(dentry)) {
REISERFS_SB(s)->priv_root = dentry;
d_set_d_op(dentry, &xattr_lookup_poison_ops);
if (d_really_is_positive(dentry)) {
d_inode(dentry)->i_flags |= S_PRIVATE;
d_inode(dentry)->i_opflags &= ~IOP_XATTR;
}
if (d_really_is_positive(dentry))
reiserfs_init_priv_inode(d_inode(dentry));
} else
err = PTR_ERR(dentry);
inode_unlock(d_inode(s->s_root));
+8
View File
@@ -30,6 +30,7 @@
#include <linux/export.h>
#include <linux/syscalls.h>
#include <linux/uio.h>
#include <linux/fsnotify.h>
#include <linux/security.h>
#include <linux/gfp.h>
#include <linux/socket.h>
@@ -1165,6 +1166,9 @@ long do_splice(struct file *in, loff_t *off_in, struct file *out,
ret = do_splice_from(ipipe, out, &offset, len, flags);
file_end_write(out);
if (ret > 0)
fsnotify_modify(out);
if (!off_out)
out->f_pos = offset;
else
@@ -1188,6 +1192,10 @@ long do_splice(struct file *in, loff_t *off_in, struct file *out,
flags |= SPLICE_F_NONBLOCK;
ret = splice_file_to_pipe(in, opipe, &offset, len, flags);
if (ret > 0)
fsnotify_access(in);
if (!off_in)
in->f_pos = offset;
else
+11 -17
View File
@@ -28,12 +28,6 @@ const struct file_operations sysv_dir_operations = {
.fsync = generic_file_fsync,
};
inline void dir_put_page(struct page *page, void *page_addr)
{
kunmap_local((void *)((unsigned long)page_addr & PAGE_MASK));
put_page(page);
}
static void dir_commit_chunk(struct page *page, loff_t pos, unsigned len)
{
struct address_space *mapping = page->mapping;
@@ -58,7 +52,7 @@ static int sysv_handle_dirsync(struct inode *dir)
}
/*
* Calls to dir_get_page()/dir_put_page() must be nested according to the
* Calls to dir_get_page()/put_and_unmap_page() must be nested according to the
* rules documented in mm/highmem.rst.
*
* NOTE: sysv_find_entry() and sysv_dotdot() act as calls to dir_get_page()
@@ -109,11 +103,11 @@ static int sysv_readdir(struct file *file, struct dir_context *ctx)
if (!dir_emit(ctx, name, strnlen(name,SYSV_NAMELEN),
fs16_to_cpu(SYSV_SB(sb), de->inode),
DT_UNKNOWN)) {
dir_put_page(page, kaddr);
put_and_unmap_page(page, kaddr);
return 0;
}
}
dir_put_page(page, kaddr);
put_and_unmap_page(page, kaddr);
}
return 0;
}
@@ -137,7 +131,7 @@ static inline int namecompare(int len, int maxlen,
* itself (as a parameter - res_dir). It does NOT read the inode of the
* entry - you'll have to do that yourself if you want to.
*
* On Success dir_put_page() should be called on *res_page.
* On Success put_and_unmap_page() should be called on *res_page.
*
* sysv_find_entry() acts as a call to dir_get_page() and must be treated
* accordingly for nesting purposes.
@@ -172,7 +166,7 @@ struct sysv_dir_entry *sysv_find_entry(struct dentry *dentry, struct page **res_
name, de->name))
goto found;
}
dir_put_page(page, kaddr);
put_and_unmap_page(page, kaddr);
}
if (++n >= npages)
@@ -215,7 +209,7 @@ int sysv_add_link(struct dentry *dentry, struct inode *inode)
goto out_page;
de++;
}
dir_put_page(page, kaddr);
put_and_unmap_page(page, kaddr);
}
BUG();
return -EINVAL;
@@ -234,7 +228,7 @@ got_it:
mark_inode_dirty(dir);
err = sysv_handle_dirsync(dir);
out_page:
dir_put_page(page, kaddr);
put_and_unmap_page(page, kaddr);
return err;
out_unlock:
unlock_page(page);
@@ -327,12 +321,12 @@ int sysv_empty_dir(struct inode * inode)
if (de->name[1] != '.' || de->name[2])
goto not_empty;
}
dir_put_page(page, kaddr);
put_and_unmap_page(page, kaddr);
}
return 1;
not_empty:
dir_put_page(page, kaddr);
put_and_unmap_page(page, kaddr);
return 0;
}
@@ -358,7 +352,7 @@ int sysv_set_link(struct sysv_dir_entry *de, struct page *page,
}
/*
* Calls to dir_get_page()/dir_put_page() must be nested according to the
* Calls to dir_get_page()/put_and_unmap_page() must be nested according to the
* rules documented in mm/highmem.rst.
*
* sysv_dotdot() acts as a call to dir_get_page() and must be treated
@@ -382,7 +376,7 @@ ino_t sysv_inode_by_name(struct dentry *dentry)
if (de) {
res = fs16_to_cpu(SYSV_SB(dentry->d_sb), de->inode);
dir_put_page(page, de);
put_and_unmap_page(page, de);
}
return res;
}
+4 -4
View File
@@ -164,7 +164,7 @@ static int sysv_unlink(struct inode * dir, struct dentry * dentry)
inode->i_ctime = dir->i_ctime;
inode_dec_link_count(inode);
}
dir_put_page(page, de);
put_and_unmap_page(page, de);
return err;
}
@@ -227,7 +227,7 @@ static int sysv_rename(struct mnt_idmap *idmap, struct inode *old_dir,
if (!new_de)
goto out_dir;
err = sysv_set_link(new_de, new_page, old_inode);
dir_put_page(new_page, new_de);
put_and_unmap_page(new_page, new_de);
if (err)
goto out_dir;
new_inode->i_ctime = current_time(new_inode);
@@ -256,9 +256,9 @@ static int sysv_rename(struct mnt_idmap *idmap, struct inode *old_dir,
out_dir:
if (dir_de)
dir_put_page(dir_page, dir_de);
put_and_unmap_page(dir_page, dir_de);
out_old:
dir_put_page(old_page, old_de);
put_and_unmap_page(old_page, old_de);
out:
return err;
}
-1
View File
@@ -148,7 +148,6 @@ extern void sysv_destroy_icache(void);
/* dir.c */
extern void dir_put_page(struct page *page, void *vaddr);
extern struct sysv_dir_entry *sysv_find_entry(struct dentry *, struct page **);
extern int sysv_add_link(struct dentry *, struct inode *);
extern int sysv_delete_entry(struct sysv_dir_entry *, struct page *);
+19 -10
View File
@@ -42,11 +42,10 @@ static inline int ufs_match(struct super_block *sb, int len,
return !memcmp(name, de->d_name, len);
}
static int ufs_commit_chunk(struct page *page, loff_t pos, unsigned len)
static void ufs_commit_chunk(struct page *page, loff_t pos, unsigned len)
{
struct address_space *mapping = page->mapping;
struct inode *dir = mapping->host;
int err = 0;
inode_inc_iversion(dir);
block_write_end(NULL, mapping, pos, len, len, page, NULL);
@@ -54,10 +53,16 @@ static int ufs_commit_chunk(struct page *page, loff_t pos, unsigned len)
i_size_write(dir, pos+len);
mark_inode_dirty(dir);
}
if (IS_DIRSYNC(dir))
err = write_one_page(page);
else
unlock_page(page);
unlock_page(page);
}
static int ufs_handle_dirsync(struct inode *dir)
{
int err;
err = filemap_write_and_wait(dir->i_mapping);
if (!err)
err = sync_inode_metadata(dir, 1);
return err;
}
@@ -99,11 +104,12 @@ void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
de->d_ino = cpu_to_fs32(dir->i_sb, inode->i_ino);
ufs_set_de_type(dir->i_sb, de, inode->i_mode);
err = ufs_commit_chunk(page, pos, len);
ufs_commit_chunk(page, pos, len);
ufs_put_page(page);
if (update_times)
dir->i_mtime = dir->i_ctime = current_time(dir);
mark_inode_dirty(dir);
ufs_handle_dirsync(dir);
}
@@ -390,10 +396,11 @@ got_it:
de->d_ino = cpu_to_fs32(sb, inode->i_ino);
ufs_set_de_type(sb, de, inode->i_mode);
err = ufs_commit_chunk(page, pos, rec_len);
ufs_commit_chunk(page, pos, rec_len);
dir->i_mtime = dir->i_ctime = current_time(dir);
mark_inode_dirty(dir);
err = ufs_handle_dirsync(dir);
/* OFFSET_CACHE */
out_put:
ufs_put_page(page);
@@ -531,9 +538,10 @@ int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir,
if (pde)
pde->d_reclen = cpu_to_fs16(sb, to - from);
dir->d_ino = 0;
err = ufs_commit_chunk(page, pos, to - from);
ufs_commit_chunk(page, pos, to - from);
inode->i_ctime = inode->i_mtime = current_time(inode);
mark_inode_dirty(inode);
err = ufs_handle_dirsync(inode);
out:
ufs_put_page(page);
UFSD("EXIT\n");
@@ -579,7 +587,8 @@ int ufs_make_empty(struct inode * inode, struct inode *dir)
strcpy (de->d_name, "..");
kunmap(page);
err = ufs_commit_chunk(page, 0, chunk_size);
ufs_commit_chunk(page, 0, chunk_size);
err = ufs_handle_dirsync(inode);
fail:
put_page(page);
return err;
+59 -61
View File
@@ -160,11 +160,10 @@ xattr_permission(struct mnt_idmap *idmap, struct inode *inode,
* Look for any handler that deals with the specified namespace.
*/
int
xattr_supported_namespace(struct inode *inode, const char *prefix)
xattr_supports_user_prefix(struct inode *inode)
{
const struct xattr_handler **handlers = inode->i_sb->s_xattr;
const struct xattr_handler *handler;
size_t preflen;
if (!(inode->i_opflags & IOP_XATTR)) {
if (unlikely(is_bad_inode(inode)))
@@ -172,16 +171,15 @@ xattr_supported_namespace(struct inode *inode, const char *prefix)
return -EOPNOTSUPP;
}
preflen = strlen(prefix);
for_each_xattr_handler(handlers, handler) {
if (!strncmp(xattr_prefix(handler), prefix, preflen))
if (!strncmp(xattr_prefix(handler), XATTR_USER_PREFIX,
XATTR_USER_PREFIX_LEN))
return 0;
}
return -EOPNOTSUPP;
}
EXPORT_SYMBOL(xattr_supported_namespace);
EXPORT_SYMBOL(xattr_supports_user_prefix);
int
__vfs_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
@@ -460,6 +458,28 @@ nolsm:
}
EXPORT_SYMBOL_GPL(vfs_getxattr);
/**
* vfs_listxattr - retrieve \0 separated list of xattr names
* @dentry: the dentry from whose inode the xattr names are retrieved
* @list: buffer to store xattr names into
* @size: size of the buffer
*
* This function returns the names of all xattrs associated with the
* inode of @dentry.
*
* Note, for legacy reasons the vfs_listxattr() function lists POSIX
* ACLs as well. Since POSIX ACLs are decoupled from IOP_XATTR the
* vfs_listxattr() function doesn't check for this flag since a
* filesystem could implement POSIX ACLs without implementing any other
* xattrs.
*
* However, since all codepaths that remove IOP_XATTR also assign of
* inode operations that either don't implement or implement a stub
* ->listxattr() operation.
*
* Return: On success, the size of the buffer that was used. On error a
* negative error code.
*/
ssize_t
vfs_listxattr(struct dentry *dentry, char *list, size_t size)
{
@@ -469,7 +489,8 @@ vfs_listxattr(struct dentry *dentry, char *list, size_t size)
error = security_inode_listxattr(dentry);
if (error)
return error;
if (inode->i_op->listxattr && (inode->i_opflags & IOP_XATTR)) {
if (inode->i_op->listxattr) {
error = inode->i_op->listxattr(dentry, list, size);
} else {
error = security_inode_listsecurity(inode, list, size);
@@ -949,6 +970,21 @@ SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name)
return error;
}
int xattr_list_one(char **buffer, ssize_t *remaining_size, const char *name)
{
size_t len;
len = strlen(name) + 1;
if (*buffer) {
if (*remaining_size < len)
return -ERANGE;
memcpy(*buffer, name, len);
*buffer += len;
}
*remaining_size -= len;
return 0;
}
/*
* Combine the results of the list() operation from every xattr_handler in the
* list.
@@ -957,33 +993,22 @@ ssize_t
generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
{
const struct xattr_handler *handler, **handlers = dentry->d_sb->s_xattr;
unsigned int size = 0;
ssize_t remaining_size = buffer_size;
int err = 0;
if (!buffer) {
for_each_xattr_handler(handlers, handler) {
if (!handler->name ||
(handler->list && !handler->list(dentry)))
continue;
size += strlen(handler->name) + 1;
}
} else {
char *buf = buffer;
size_t len;
err = posix_acl_listxattr(d_inode(dentry), &buffer, &remaining_size);
if (err)
return err;
for_each_xattr_handler(handlers, handler) {
if (!handler->name ||
(handler->list && !handler->list(dentry)))
continue;
len = strlen(handler->name);
if (len + 1 > buffer_size)
return -ERANGE;
memcpy(buf, handler->name, len + 1);
buf += len + 1;
buffer_size -= len + 1;
}
size = buf - buffer;
for_each_xattr_handler(handlers, handler) {
if (!handler->name || (handler->list && !handler->list(dentry)))
continue;
err = xattr_list_one(&buffer, &remaining_size, handler->name);
if (err)
return err;
}
return size;
return err ? err : buffer_size - remaining_size;
}
EXPORT_SYMBOL(generic_listxattr);
@@ -1245,20 +1270,6 @@ static bool xattr_is_trusted(const char *name)
return !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN);
}
static int xattr_list_one(char **buffer, ssize_t *remaining_size,
const char *name)
{
size_t len = strlen(name) + 1;
if (*buffer) {
if (*remaining_size < len)
return -ERANGE;
memcpy(*buffer, name, len);
*buffer += len;
}
*remaining_size -= len;
return 0;
}
/**
* simple_xattr_list - list all xattr objects
* @inode: inode from which to get the xattrs
@@ -1287,22 +1298,9 @@ ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
ssize_t remaining_size = size;
int err = 0;
#ifdef CONFIG_FS_POSIX_ACL
if (IS_POSIXACL(inode)) {
if (inode->i_acl) {
err = xattr_list_one(&buffer, &remaining_size,
XATTR_NAME_POSIX_ACL_ACCESS);
if (err)
return err;
}
if (inode->i_default_acl) {
err = xattr_list_one(&buffer, &remaining_size,
XATTR_NAME_POSIX_ACL_DEFAULT);
if (err)
return err;
}
}
#endif
err = posix_acl_listxattr(inode, &buffer, &remaining_size);
if (err)
return err;
read_lock(&xattrs->lock);
for (rbp = rb_first(&xattrs->rb_root); rbp; rbp = rb_next(rbp)) {
-4
View File
@@ -179,10 +179,6 @@ const struct xattr_handler *xfs_xattr_handlers[] = {
&xfs_xattr_user_handler,
&xfs_xattr_trusted_handler,
&xfs_xattr_security_handler,
#ifdef CONFIG_XFS_POSIX_ACL
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
#endif
NULL
};
+4 -2
View File
@@ -2675,6 +2675,8 @@ extern struct inode *new_inode(struct super_block *sb);
extern void free_inode_nonrcu(struct inode *inode);
extern int setattr_should_drop_suidgid(struct mnt_idmap *, struct inode *);
extern int file_remove_privs(struct file *);
int setattr_should_drop_sgid(struct mnt_idmap *idmap,
const struct inode *inode);
/*
* This must be used for allocating filesystems specific inodes to set
@@ -2778,7 +2780,7 @@ enum {
ssize_t __blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
struct block_device *bdev, struct iov_iter *iter,
get_block_t get_block,
dio_iodone_t end_io, dio_submit_t submit_io,
dio_iodone_t end_io,
int flags);
static inline ssize_t blockdev_direct_IO(struct kiocb *iocb,
@@ -2787,7 +2789,7 @@ static inline ssize_t blockdev_direct_IO(struct kiocb *iocb,
get_block_t get_block)
{
return __blockdev_direct_IO(iocb, inode, inode->i_sb->s_bdev, iter,
get_block, NULL, NULL, DIO_LOCKING | DIO_SKIP_HOLES);
get_block, NULL, DIO_LOCKING | DIO_SKIP_HOLES);
}
#endif
-1
View File
@@ -104,7 +104,6 @@ struct fs_context {
unsigned int sb_flags; /* Proposed superblock flags (SB_*) */
unsigned int sb_flags_mask; /* Superblock flags that were changed */
unsigned int s_iflags; /* OR'd with sb->s_iflags */
unsigned int lsm_flags; /* Information flags from the fs to the LSM */
enum fs_context_purpose purpose:8;
enum fs_context_phase phase:8; /* The phase the context is in */
bool need_free:1; /* Need to call ops->free() */
-6
View File
@@ -1066,12 +1066,6 @@ static inline void folio_cancel_dirty(struct folio *folio)
bool folio_clear_dirty_for_io(struct folio *folio);
bool clear_page_dirty_for_io(struct page *page);
void folio_invalidate(struct folio *folio, size_t offset, size_t length);
int __must_check folio_write_one(struct folio *folio);
static inline int __must_check write_one_page(struct page *page)
{
return folio_write_one(page_folio(page));
}
int __set_page_dirty_nobuffers(struct page *page);
bool noop_dirty_folio(struct address_space *mapping, struct folio *folio);
+1
View File
@@ -80,6 +80,7 @@ extern struct pid *pidfd_pid(const struct file *file);
struct pid *pidfd_get_pid(unsigned int fd, unsigned int *flags);
struct task_struct *pidfd_get_task(int pidfd, unsigned int *flags);
int pidfd_create(struct pid *pid, unsigned int flags);
int pidfd_prepare(struct pid *pid, unsigned int flags, struct file **ret);
static inline struct pid *get_pid(struct pid *pid)
{
+7
View File
@@ -106,6 +106,8 @@ struct posix_acl *vfs_get_acl(struct mnt_idmap *idmap,
struct dentry *dentry, const char *acl_name);
int vfs_remove_acl(struct mnt_idmap *idmap, struct dentry *dentry,
const char *acl_name);
int posix_acl_listxattr(struct inode *inode, char **buffer,
ssize_t *remaining_size);
#else
static inline int posix_acl_chmod(struct mnt_idmap *idmap,
struct dentry *dentry, umode_t mode)
@@ -153,6 +155,11 @@ static inline int vfs_remove_acl(struct mnt_idmap *idmap,
{
return -EOPNOTSUPP;
}
static inline int posix_acl_listxattr(struct inode *inode, char **buffer,
ssize_t *remaining_size)
{
return 0;
}
#endif /* CONFIG_FS_POSIX_ACL */
struct posix_acl *get_inode_acl(struct inode *inode, int type);
+3 -2
View File
@@ -68,7 +68,8 @@ static inline int posix_acl_type(const char *name)
return -1;
}
extern const struct xattr_handler posix_acl_access_xattr_handler;
extern const struct xattr_handler posix_acl_default_xattr_handler;
/* These are legacy handlers. Don't use them for new code. */
extern const struct xattr_handler nop_posix_acl_access;
extern const struct xattr_handler nop_posix_acl_default;
#endif /* _POSIX_ACL_XATTR_H */
-1
View File
@@ -72,7 +72,6 @@ static inline int ns_alloc_inum(struct ns_common *ns)
#define ns_free_inum(ns) proc_free_inum((ns)->inum)
extern struct file *proc_ns_fget(int fd);
#define get_proc_ns(inode) ((struct ns_common *)(inode)->i_private)
extern int ns_get_path(struct path *path, struct task_struct *task,
const struct proc_ns_operations *ns_ops);
+1 -1
View File
@@ -68,7 +68,7 @@ struct watch_notification;
/* If capable is being called by a setid function */
#define CAP_OPT_INSETID BIT(2)
/* LSM Agnostic defines for fs_context::lsm_flags */
/* LSM Agnostic defines for security_sb_set_mnt_opts() flags */
#define SECURITY_LSM_NATIVE_LABELS 1
struct ctl_table;

Some files were not shown because too many files have changed in this diff Show More