mirror of
https://github.com/t2linux/kernel.git
synced 2026-04-30 13:48:59 -07:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs updates from Al Viro:
- more ->d_init() stuff (work.dcache)
- pathname resolution cleanups (work.namei)
- a few missing iov_iter primitives - copy_from_iter_full() and
friends. Either copy the full requested amount, advance the iterator
and return true, or fail, return false and do _not_ advance the
iterator. Quite a few open-coded callers converted (and became more
readable and harder to fuck up that way) (work.iov_iter)
- several assorted patches, the big one being logfs removal
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
logfs: remove from tree
vfs: fix put_compat_statfs64() does not handle errors
namei: fold should_follow_link() with the step into not-followed link
namei: pass both WALK_GET and WALK_MORE to should_follow_link()
namei: invert WALK_PUT logics
namei: shift interpretation of LOOKUP_FOLLOW inside should_follow_link()
namei: saner calling conventions for mountpoint_last()
namei.c: get rid of user_path_parent()
switch getfrag callbacks to ..._full() primitives
make skb_add_data,{_nocache}() and skb_copy_to_page_nocache() advance only on success
[iov_iter] new primitives - copy_from_iter_full() and friends
don't open-code file_inode()
ceph: switch to use of ->d_init()
ceph: unify dentry_operations instances
lustre: switch to use of ->d_init()
This commit is contained in:
@@ -87,8 +87,6 @@ jfs.txt
|
||||
- info and mount options for the JFS filesystem.
|
||||
locks.txt
|
||||
- info on file locking implementations, flock() vs. fcntl(), etc.
|
||||
logfs.txt
|
||||
- info on the LogFS flash filesystem.
|
||||
mandatory-locking.txt
|
||||
- info on the Linux implementation of Sys V mandatory file locking.
|
||||
ncpfs.txt
|
||||
|
||||
@@ -1,241 +0,0 @@
|
||||
|
||||
The LogFS Flash Filesystem
|
||||
==========================
|
||||
|
||||
Specification
|
||||
=============
|
||||
|
||||
Superblocks
|
||||
-----------
|
||||
|
||||
Two superblocks exist at the beginning and end of the filesystem.
|
||||
Each superblock is 256 Bytes large, with another 3840 Bytes reserved
|
||||
for future purposes, making a total of 4096 Bytes.
|
||||
|
||||
Superblock locations may differ for MTD and block devices. On MTD the
|
||||
first non-bad block contains a superblock in the first 4096 Bytes and
|
||||
the last non-bad block contains a superblock in the last 4096 Bytes.
|
||||
On block devices, the first 4096 Bytes of the device contain the first
|
||||
superblock and the last aligned 4096 Byte-block contains the second
|
||||
superblock.
|
||||
|
||||
For the most part, the superblocks can be considered read-only. They
|
||||
are written only to correct errors detected within the superblocks,
|
||||
move the journal and change the filesystem parameters through tunefs.
|
||||
As a result, the superblock does not contain any fields that require
|
||||
constant updates, like the amount of free space, etc.
|
||||
|
||||
Segments
|
||||
--------
|
||||
|
||||
The space in the device is split up into equal-sized segments.
|
||||
Segments are the primary write unit of LogFS. Within each segments,
|
||||
writes happen from front (low addresses) to back (high addresses. If
|
||||
only a partial segment has been written, the segment number, the
|
||||
current position within and optionally a write buffer are stored in
|
||||
the journal.
|
||||
|
||||
Segments are erased as a whole. Therefore Garbage Collection may be
|
||||
required to completely free a segment before doing so.
|
||||
|
||||
Journal
|
||||
--------
|
||||
|
||||
The journal contains all global information about the filesystem that
|
||||
is subject to frequent change. At mount time, it has to be scanned
|
||||
for the most recent commit entry, which contains a list of pointers to
|
||||
all currently valid entries.
|
||||
|
||||
Object Store
|
||||
------------
|
||||
|
||||
All space except for the superblocks and journal is part of the object
|
||||
store. Each segment contains a segment header and a number of
|
||||
objects, each consisting of the object header and the payload.
|
||||
Objects are either inodes, directory entries (dentries), file data
|
||||
blocks or indirect blocks.
|
||||
|
||||
Levels
|
||||
------
|
||||
|
||||
Garbage collection (GC) may fail if all data is written
|
||||
indiscriminately. One requirement of GC is that data is separated
|
||||
roughly according to the distance between the tree root and the data.
|
||||
Effectively that means all file data is on level 0, indirect blocks
|
||||
are on levels 1, 2, 3 4 or 5 for 1x, 2x, 3x, 4x or 5x indirect blocks,
|
||||
respectively. Inode file data is on level 6 for the inodes and 7-11
|
||||
for indirect blocks.
|
||||
|
||||
Each segment contains objects of a single level only. As a result,
|
||||
each level requires its own separate segment to be open for writing.
|
||||
|
||||
Inode File
|
||||
----------
|
||||
|
||||
All inodes are stored in a special file, the inode file. Single
|
||||
exception is the inode file's inode (master inode) which for obvious
|
||||
reasons is stored in the journal instead. Instead of data blocks, the
|
||||
leaf nodes of the inode files are inodes.
|
||||
|
||||
Aliases
|
||||
-------
|
||||
|
||||
Writes in LogFS are done by means of a wandering tree. A naïve
|
||||
implementation would require that for each write or a block, all
|
||||
parent blocks are written as well, since the block pointers have
|
||||
changed. Such an implementation would not be very efficient.
|
||||
|
||||
In LogFS, the block pointer changes are cached in the journal by means
|
||||
of alias entries. Each alias consists of its logical address - inode
|
||||
number, block index, level and child number (index into block) - and
|
||||
the changed data. Any 8-byte word can be changes in this manner.
|
||||
|
||||
Currently aliases are used for block pointers, file size, file used
|
||||
bytes and the height of an inodes indirect tree.
|
||||
|
||||
Segment Aliases
|
||||
---------------
|
||||
|
||||
Related to regular aliases, these are used to handle bad blocks.
|
||||
Initially, bad blocks are handled by moving the affected segment
|
||||
content to a spare segment and noting this move in the journal with a
|
||||
segment alias, a simple (to, from) tupel. GC will later empty this
|
||||
segment and the alias can be removed again. This is used on MTD only.
|
||||
|
||||
Vim
|
||||
---
|
||||
|
||||
By cleverly predicting the life time of data, it is possible to
|
||||
separate long-living data from short-living data and thereby reduce
|
||||
the GC overhead later. Each type of distinc life expectency (vim) can
|
||||
have a separate segment open for writing. Each (level, vim) tupel can
|
||||
be open just once. If an open segment with unknown vim is encountered
|
||||
at mount time, it is closed and ignored henceforth.
|
||||
|
||||
Indirect Tree
|
||||
-------------
|
||||
|
||||
Inodes in LogFS are similar to FFS-style filesystems with direct and
|
||||
indirect block pointers. One difference is that LogFS uses a single
|
||||
indirect pointer that can be either a 1x, 2x, etc. indirect pointer.
|
||||
A height field in the inode defines the height of the indirect tree
|
||||
and thereby the indirection of the pointer.
|
||||
|
||||
Another difference is the addressing of indirect blocks. In LogFS,
|
||||
the first 16 pointers in the first indirect block are left empty,
|
||||
corresponding to the 16 direct pointers in the inode. In ext2 (maybe
|
||||
others as well) the first pointer in the first indirect block
|
||||
corresponds to logical block 12, skipping the 12 direct pointers.
|
||||
So where ext2 is using arithmetic to better utilize space, LogFS keeps
|
||||
arithmetic simple and uses compression to save space.
|
||||
|
||||
Compression
|
||||
-----------
|
||||
|
||||
Both file data and metadata can be compressed. Compression for file
|
||||
data can be enabled with chattr +c and disabled with chattr -c. Doing
|
||||
so has no effect on existing data, but new data will be stored
|
||||
accordingly. New inodes will inherit the compression flag of the
|
||||
parent directory.
|
||||
|
||||
Metadata is always compressed. However, the space accounting ignores
|
||||
this and charges for the uncompressed size. Failing to do so could
|
||||
result in GC failures when, after moving some data, indirect blocks
|
||||
compress worse than previously. Even on a 100% full medium, GC may
|
||||
not consume any extra space, so the compression gains are lost space
|
||||
to the user.
|
||||
|
||||
However, they are not lost space to the filesystem internals. By
|
||||
cheating the user for those bytes, the filesystem gained some slack
|
||||
space and GC will run less often and faster.
|
||||
|
||||
Garbage Collection and Wear Leveling
|
||||
------------------------------------
|
||||
|
||||
Garbage collection is invoked whenever the number of free segments
|
||||
falls below a threshold. The best (known) candidate is picked based
|
||||
on the least amount of valid data contained in the segment. All
|
||||
remaining valid data is copied elsewhere, thereby invalidating it.
|
||||
|
||||
The GC code also checks for aliases and writes then back if their
|
||||
number gets too large.
|
||||
|
||||
Wear leveling is done by occasionally picking a suboptimal segment for
|
||||
garbage collection. If a stale segments erase count is significantly
|
||||
lower than the active segments' erase counts, it will be picked. Wear
|
||||
leveling is rate limited, so it will never monopolize the device for
|
||||
more than one segment worth at a time.
|
||||
|
||||
Values for "occasionally", "significantly lower" are compile time
|
||||
constants.
|
||||
|
||||
Hashed directories
|
||||
------------------
|
||||
|
||||
To satisfy efficient lookup(), directory entries are hashed and
|
||||
located based on the hash. In order to both support large directories
|
||||
and not be overly inefficient for small directories, several hash
|
||||
tables of increasing size are used. For each table, the hash value
|
||||
modulo the table size gives the table index.
|
||||
|
||||
Tables sizes are chosen to limit the number of indirect blocks with a
|
||||
fully populated table to 0, 1, 2 or 3 respectively. So the first
|
||||
table contains 16 entries, the second 512-16, etc.
|
||||
|
||||
The last table is special in several ways. First its size depends on
|
||||
the effective 32bit limit on telldir/seekdir cookies. Since logfs
|
||||
uses the upper half of the address space for indirect blocks, the size
|
||||
is limited to 2^31. Secondly the table contains hash buckets with 16
|
||||
entries each.
|
||||
|
||||
Using single-entry buckets would result in birthday "attacks". At
|
||||
just 2^16 used entries, hash collisions would be likely (P >= 0.5).
|
||||
My math skills are insufficient to do the combinatorics for the 17x
|
||||
collisions necessary to overflow a bucket, but testing showed that in
|
||||
10,000 runs the lowest directory fill before a bucket overflow was
|
||||
188,057,130 entries with an average of 315,149,915 entries. So for
|
||||
directory sizes of up to a million, bucket overflows should be
|
||||
virtually impossible under normal circumstances.
|
||||
|
||||
With carefully chosen filenames, it is obviously possible to cause an
|
||||
overflow with just 21 entries (4 higher tables + 16 entries + 1). So
|
||||
there may be a security concern if a malicious user has write access
|
||||
to a directory.
|
||||
|
||||
Open For Discussion
|
||||
===================
|
||||
|
||||
Device Address Space
|
||||
--------------------
|
||||
|
||||
A device address space is used for caching. Both block devices and
|
||||
MTD provide functions to either read a single page or write a segment.
|
||||
Partial segments may be written for data integrity, but where possible
|
||||
complete segments are written for performance on simple block device
|
||||
flash media.
|
||||
|
||||
Meta Inodes
|
||||
-----------
|
||||
|
||||
Inodes are stored in the inode file, which is just a regular file for
|
||||
most purposes. At umount time, however, the inode file needs to
|
||||
remain open until all dirty inodes are written. So
|
||||
generic_shutdown_super() may not close this inode, but shouldn't
|
||||
complain about remaining inodes due to the inode file either. Same
|
||||
goes for mapping inode of the device address space.
|
||||
|
||||
Currently logfs uses a hack that essentially copies part of fs/inode.c
|
||||
code over. A general solution would be preferred.
|
||||
|
||||
Indirect block mapping
|
||||
----------------------
|
||||
|
||||
With compression, the block device (or mapping inode) cannot be used
|
||||
to cache indirect blocks. Some other place is required. Currently
|
||||
logfs uses the top half of each inode's address space. The low 8TB
|
||||
(on 32bit) are filled with file data, the high 8TB are used for
|
||||
indirect blocks.
|
||||
|
||||
One problem is that 16TB files created on 64bit systems actually have
|
||||
data in the top 8TB. But files >16TB would cause problems anyway, so
|
||||
only the limit has changed.
|
||||
@@ -7564,14 +7564,6 @@ S: Maintained
|
||||
F: Documentation/ldm.txt
|
||||
F: block/partitions/ldm.*
|
||||
|
||||
LogFS
|
||||
M: Joern Engel <joern@logfs.org>
|
||||
M: Prasad Joshi <prasadjoshi.linux@gmail.com>
|
||||
L: logfs@logfs.org
|
||||
W: logfs.org
|
||||
S: Maintained
|
||||
F: fs/logfs/
|
||||
|
||||
LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
|
||||
M: Sathya Prakash <sathya.prakash@broadcom.com>
|
||||
M: Chaitra P B <chaitra.basappa@broadcom.com>
|
||||
|
||||
@@ -181,7 +181,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
if (copy_from_iter(skb_put(skb, len), len, from) != len) {
|
||||
if (!copy_from_iter_full(skb_put(skb, len), len, from)) {
|
||||
kfree_skb(skb);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
@@ -2523,7 +2523,7 @@ static void amdgpu_debugfs_remove_files(struct amdgpu_device *adev)
|
||||
static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
|
||||
size_t size, loff_t *pos)
|
||||
{
|
||||
struct amdgpu_device *adev = f->f_inode->i_private;
|
||||
struct amdgpu_device *adev = file_inode(f)->i_private;
|
||||
ssize_t result = 0;
|
||||
int r;
|
||||
bool pm_pg_lock, use_bank;
|
||||
@@ -2599,7 +2599,7 @@ end:
|
||||
static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf,
|
||||
size_t size, loff_t *pos)
|
||||
{
|
||||
struct amdgpu_device *adev = f->f_inode->i_private;
|
||||
struct amdgpu_device *adev = file_inode(f)->i_private;
|
||||
ssize_t result = 0;
|
||||
int r;
|
||||
bool pm_pg_lock, use_bank;
|
||||
@@ -2673,7 +2673,7 @@ static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf,
|
||||
static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf,
|
||||
size_t size, loff_t *pos)
|
||||
{
|
||||
struct amdgpu_device *adev = f->f_inode->i_private;
|
||||
struct amdgpu_device *adev = file_inode(f)->i_private;
|
||||
ssize_t result = 0;
|
||||
int r;
|
||||
|
||||
@@ -2700,7 +2700,7 @@ static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf,
|
||||
static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user *buf,
|
||||
size_t size, loff_t *pos)
|
||||
{
|
||||
struct amdgpu_device *adev = f->f_inode->i_private;
|
||||
struct amdgpu_device *adev = file_inode(f)->i_private;
|
||||
ssize_t result = 0;
|
||||
int r;
|
||||
|
||||
@@ -2728,7 +2728,7 @@ static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user
|
||||
static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf,
|
||||
size_t size, loff_t *pos)
|
||||
{
|
||||
struct amdgpu_device *adev = f->f_inode->i_private;
|
||||
struct amdgpu_device *adev = file_inode(f)->i_private;
|
||||
ssize_t result = 0;
|
||||
int r;
|
||||
|
||||
@@ -2755,7 +2755,7 @@ static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf,
|
||||
static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user *buf,
|
||||
size_t size, loff_t *pos)
|
||||
{
|
||||
struct amdgpu_device *adev = f->f_inode->i_private;
|
||||
struct amdgpu_device *adev = file_inode(f)->i_private;
|
||||
ssize_t result = 0;
|
||||
int r;
|
||||
|
||||
@@ -2783,7 +2783,7 @@ static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user
|
||||
static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf,
|
||||
size_t size, loff_t *pos)
|
||||
{
|
||||
struct amdgpu_device *adev = f->f_inode->i_private;
|
||||
struct amdgpu_device *adev = file_inode(f)->i_private;
|
||||
ssize_t result = 0;
|
||||
int r;
|
||||
|
||||
@@ -2810,7 +2810,7 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf,
|
||||
static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *buf,
|
||||
size_t size, loff_t *pos)
|
||||
{
|
||||
struct amdgpu_device *adev = f->f_inode->i_private;
|
||||
struct amdgpu_device *adev = file_inode(f)->i_private;
|
||||
ssize_t result = 0;
|
||||
int r;
|
||||
|
||||
@@ -2838,7 +2838,7 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *
|
||||
static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf,
|
||||
size_t size, loff_t *pos)
|
||||
{
|
||||
struct amdgpu_device *adev = f->f_inode->i_private;
|
||||
struct amdgpu_device *adev = file_inode(f)->i_private;
|
||||
ssize_t result = 0;
|
||||
int r;
|
||||
uint32_t *config, no_regs = 0;
|
||||
@@ -2908,7 +2908,7 @@ static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf,
|
||||
static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf,
|
||||
size_t size, loff_t *pos)
|
||||
{
|
||||
struct amdgpu_device *adev = f->f_inode->i_private;
|
||||
struct amdgpu_device *adev = file_inode(f)->i_private;
|
||||
int idx, r;
|
||||
int32_t value;
|
||||
|
||||
|
||||
@@ -280,7 +280,7 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring)
|
||||
static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf,
|
||||
size_t size, loff_t *pos)
|
||||
{
|
||||
struct amdgpu_ring *ring = (struct amdgpu_ring*)f->f_inode->i_private;
|
||||
struct amdgpu_ring *ring = file_inode(f)->i_private;
|
||||
int r, i;
|
||||
uint32_t value, result, early[3];
|
||||
|
||||
|
||||
@@ -1511,7 +1511,7 @@ static const struct drm_info_list amdgpu_ttm_debugfs_list[] = {
|
||||
static ssize_t amdgpu_ttm_vram_read(struct file *f, char __user *buf,
|
||||
size_t size, loff_t *pos)
|
||||
{
|
||||
struct amdgpu_device *adev = f->f_inode->i_private;
|
||||
struct amdgpu_device *adev = file_inode(f)->i_private;
|
||||
ssize_t result = 0;
|
||||
int r;
|
||||
|
||||
@@ -1555,7 +1555,7 @@ static const struct file_operations amdgpu_ttm_vram_fops = {
|
||||
static ssize_t amdgpu_ttm_gtt_read(struct file *f, char __user *buf,
|
||||
size_t size, loff_t *pos)
|
||||
{
|
||||
struct amdgpu_device *adev = f->f_inode->i_private;
|
||||
struct amdgpu_device *adev = file_inode(f)->i_private;
|
||||
ssize_t result = 0;
|
||||
int r;
|
||||
|
||||
|
||||
@@ -679,7 +679,6 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
|
||||
int depth;
|
||||
bool zerocopy = false;
|
||||
size_t linear;
|
||||
ssize_t n;
|
||||
|
||||
if (q->flags & IFF_VNET_HDR) {
|
||||
vnet_hdr_len = q->vnet_hdr_sz;
|
||||
@@ -690,8 +689,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
|
||||
len -= vnet_hdr_len;
|
||||
|
||||
err = -EFAULT;
|
||||
n = copy_from_iter(&vnet_hdr, sizeof(vnet_hdr), from);
|
||||
if (n != sizeof(vnet_hdr))
|
||||
if (!copy_from_iter_full(&vnet_hdr, sizeof(vnet_hdr), from))
|
||||
goto err;
|
||||
iov_iter_advance(from, vnet_hdr_len - sizeof(vnet_hdr));
|
||||
if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
|
||||
|
||||
+2
-5
@@ -1156,7 +1156,6 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
|
||||
bool zerocopy = false;
|
||||
int err;
|
||||
u32 rxhash;
|
||||
ssize_t n;
|
||||
|
||||
if (!(tun->dev->flags & IFF_UP))
|
||||
return -EIO;
|
||||
@@ -1166,8 +1165,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
|
||||
return -EINVAL;
|
||||
len -= sizeof(pi);
|
||||
|
||||
n = copy_from_iter(&pi, sizeof(pi), from);
|
||||
if (n != sizeof(pi))
|
||||
if (!copy_from_iter_full(&pi, sizeof(pi), from))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
@@ -1176,8 +1174,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
|
||||
return -EINVAL;
|
||||
len -= tun->vnet_hdr_sz;
|
||||
|
||||
n = copy_from_iter(&gso, sizeof(gso), from);
|
||||
if (n != sizeof(gso))
|
||||
if (!copy_from_iter_full(&gso, sizeof(gso), from))
|
||||
return -EFAULT;
|
||||
|
||||
if ((gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
|
||||
|
||||
@@ -1092,7 +1092,7 @@ static ssize_t gb_camera_debugfs_read(struct file *file, char __user *buf,
|
||||
size_t len, loff_t *offset)
|
||||
{
|
||||
const struct gb_camera_debugfs_entry *op = file->private_data;
|
||||
struct gb_camera *gcam = file->f_inode->i_private;
|
||||
struct gb_camera *gcam = file_inode(file)->i_private;
|
||||
struct gb_camera_debugfs_buffer *buffer;
|
||||
ssize_t ret;
|
||||
|
||||
@@ -1114,7 +1114,7 @@ static ssize_t gb_camera_debugfs_write(struct file *file,
|
||||
loff_t *offset)
|
||||
{
|
||||
const struct gb_camera_debugfs_entry *op = file->private_data;
|
||||
struct gb_camera *gcam = file->f_inode->i_private;
|
||||
struct gb_camera *gcam = file_inode(file)->i_private;
|
||||
ssize_t ret;
|
||||
char *kbuf;
|
||||
|
||||
|
||||
@@ -1249,7 +1249,7 @@ static int apb_log_poll(void *data)
|
||||
static ssize_t apb_log_read(struct file *f, char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct es2_ap_dev *es2 = f->f_inode->i_private;
|
||||
struct es2_ap_dev *es2 = file_inode(f)->i_private;
|
||||
ssize_t ret;
|
||||
size_t copied;
|
||||
char *tmp_buf;
|
||||
@@ -1303,7 +1303,7 @@ static void usb_log_disable(struct es2_ap_dev *es2)
|
||||
static ssize_t apb_log_enable_read(struct file *f, char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct es2_ap_dev *es2 = f->f_inode->i_private;
|
||||
struct es2_ap_dev *es2 = file_inode(f)->i_private;
|
||||
int enable = !IS_ERR_OR_NULL(es2->apb_log_task);
|
||||
char tmp_buf[3];
|
||||
|
||||
@@ -1316,7 +1316,7 @@ static ssize_t apb_log_enable_write(struct file *f, const char __user *buf,
|
||||
{
|
||||
int enable;
|
||||
ssize_t retval;
|
||||
struct es2_ap_dev *es2 = f->f_inode->i_private;
|
||||
struct es2_ap_dev *es2 = file_inode(f)->i_private;
|
||||
|
||||
retval = kstrtoint_from_user(buf, count, 10, &enable);
|
||||
if (retval)
|
||||
|
||||
@@ -757,7 +757,7 @@ static int gb_svc_version_request(struct gb_operation *op)
|
||||
static ssize_t pwr_debugfs_voltage_read(struct file *file, char __user *buf,
|
||||
size_t len, loff_t *offset)
|
||||
{
|
||||
struct svc_debugfs_pwrmon_rail *pwrmon_rails = file->f_inode->i_private;
|
||||
struct svc_debugfs_pwrmon_rail *pwrmon_rails = file_inode(file)->i_private;
|
||||
struct gb_svc *svc = pwrmon_rails->svc;
|
||||
int ret, desc;
|
||||
u32 value;
|
||||
@@ -780,7 +780,7 @@ static ssize_t pwr_debugfs_voltage_read(struct file *file, char __user *buf,
|
||||
static ssize_t pwr_debugfs_current_read(struct file *file, char __user *buf,
|
||||
size_t len, loff_t *offset)
|
||||
{
|
||||
struct svc_debugfs_pwrmon_rail *pwrmon_rails = file->f_inode->i_private;
|
||||
struct svc_debugfs_pwrmon_rail *pwrmon_rails = file_inode(file)->i_private;
|
||||
struct gb_svc *svc = pwrmon_rails->svc;
|
||||
int ret, desc;
|
||||
u32 value;
|
||||
@@ -803,7 +803,7 @@ static ssize_t pwr_debugfs_current_read(struct file *file, char __user *buf,
|
||||
static ssize_t pwr_debugfs_power_read(struct file *file, char __user *buf,
|
||||
size_t len, loff_t *offset)
|
||||
{
|
||||
struct svc_debugfs_pwrmon_rail *pwrmon_rails = file->f_inode->i_private;
|
||||
struct svc_debugfs_pwrmon_rail *pwrmon_rails = file_inode(file)->i_private;
|
||||
struct gb_svc *svc = pwrmon_rails->svc;
|
||||
int ret, desc;
|
||||
u32 value;
|
||||
|
||||
@@ -921,7 +921,7 @@ EXPORT_SYMBOL_GPL(gb_timesync_schedule_asynchronous);
|
||||
static ssize_t gb_timesync_ping_read(struct file *file, char __user *ubuf,
|
||||
size_t len, loff_t *offset, bool ktime)
|
||||
{
|
||||
struct gb_timesync_svc *timesync_svc = file->f_inode->i_private;
|
||||
struct gb_timesync_svc *timesync_svc = file_inode(file)->i_private;
|
||||
char *buf;
|
||||
ssize_t ret = 0;
|
||||
|
||||
|
||||
@@ -57,9 +57,6 @@ static void ll_release(struct dentry *de)
|
||||
|
||||
LASSERT(de);
|
||||
lld = ll_d2d(de);
|
||||
if (!lld) /* NFS copies the de->d_op methods (bug 4655) */
|
||||
return;
|
||||
|
||||
if (lld->lld_it) {
|
||||
ll_intent_release(lld->lld_it);
|
||||
kfree(lld->lld_it);
|
||||
@@ -126,30 +123,13 @@ static int ll_ddelete(const struct dentry *de)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ll_d_init(struct dentry *de)
|
||||
static int ll_d_init(struct dentry *de)
|
||||
{
|
||||
CDEBUG(D_DENTRY, "ldd on dentry %pd (%p) parent %p inode %p refc %d\n",
|
||||
de, de, de->d_parent, d_inode(de), d_count(de));
|
||||
|
||||
if (!de->d_fsdata) {
|
||||
struct ll_dentry_data *lld;
|
||||
|
||||
lld = kzalloc(sizeof(*lld), GFP_NOFS);
|
||||
if (likely(lld)) {
|
||||
spin_lock(&de->d_lock);
|
||||
if (likely(!de->d_fsdata)) {
|
||||
de->d_fsdata = lld;
|
||||
__d_lustre_invalidate(de);
|
||||
} else {
|
||||
kfree(lld);
|
||||
}
|
||||
spin_unlock(&de->d_lock);
|
||||
} else {
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
LASSERT(de->d_op == &ll_d_ops);
|
||||
|
||||
struct ll_dentry_data *lld = kzalloc(sizeof(*lld), GFP_KERNEL);
|
||||
if (unlikely(!lld))
|
||||
return -ENOMEM;
|
||||
lld->lld_invalid = 1;
|
||||
de->d_fsdata = lld;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -300,6 +280,7 @@ static int ll_revalidate_nd(struct dentry *dentry, unsigned int flags)
|
||||
}
|
||||
|
||||
const struct dentry_operations ll_d_ops = {
|
||||
.d_init = ll_d_init,
|
||||
.d_revalidate = ll_revalidate_nd,
|
||||
.d_release = ll_release,
|
||||
.d_delete = ll_ddelete,
|
||||
|
||||
@@ -769,7 +769,6 @@ int ll_hsm_release(struct inode *inode);
|
||||
|
||||
/* llite/dcache.c */
|
||||
|
||||
int ll_d_init(struct dentry *de);
|
||||
extern const struct dentry_operations ll_d_ops;
|
||||
void ll_intent_drop_lock(struct lookup_intent *);
|
||||
void ll_intent_release(struct lookup_intent *);
|
||||
@@ -1148,7 +1147,7 @@ dentry_may_statahead(struct inode *dir, struct dentry *dentry)
|
||||
* 'lld_sa_generation == lli->lli_sa_generation'.
|
||||
*/
|
||||
ldd = ll_d2d(dentry);
|
||||
if (ldd && ldd->lld_sa_generation == lli->lli_sa_generation)
|
||||
if (ldd->lld_sa_generation == lli->lli_sa_generation)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -1267,17 +1266,7 @@ static inline void ll_set_lock_data(struct obd_export *exp, struct inode *inode,
|
||||
|
||||
static inline int d_lustre_invalid(const struct dentry *dentry)
|
||||
{
|
||||
struct ll_dentry_data *lld = ll_d2d(dentry);
|
||||
|
||||
return !lld || lld->lld_invalid;
|
||||
}
|
||||
|
||||
static inline void __d_lustre_invalidate(struct dentry *dentry)
|
||||
{
|
||||
struct ll_dentry_data *lld = ll_d2d(dentry);
|
||||
|
||||
if (lld)
|
||||
lld->lld_invalid = 1;
|
||||
return ll_d2d(dentry)->lld_invalid;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1293,7 +1282,7 @@ static inline void d_lustre_invalidate(struct dentry *dentry, int nested)
|
||||
|
||||
spin_lock_nested(&dentry->d_lock,
|
||||
nested ? DENTRY_D_LOCK_NESTED : DENTRY_D_LOCK_NORMAL);
|
||||
__d_lustre_invalidate(dentry);
|
||||
ll_d2d(dentry)->lld_invalid = 1;
|
||||
/*
|
||||
* We should be careful about dentries created by d_obtain_alias().
|
||||
* These dentries are not put in the dentry tree, instead they are
|
||||
|
||||
@@ -169,22 +169,12 @@ ll_iget_for_nfs(struct super_block *sb, struct lu_fid *fid, struct lu_fid *paren
|
||||
/* N.B. d_obtain_alias() drops inode ref on error */
|
||||
result = d_obtain_alias(inode);
|
||||
if (!IS_ERR(result)) {
|
||||
int rc;
|
||||
|
||||
rc = ll_d_init(result);
|
||||
if (rc < 0) {
|
||||
dput(result);
|
||||
result = ERR_PTR(rc);
|
||||
} else {
|
||||
struct ll_dentry_data *ldd = ll_d2d(result);
|
||||
|
||||
/*
|
||||
* Need to signal to the ll_intent_file_open that
|
||||
* we came from NFS and so opencache needs to be
|
||||
* enabled for this one
|
||||
*/
|
||||
ldd->lld_nfs_dentry = 1;
|
||||
}
|
||||
/*
|
||||
* Need to signal to the ll_intent_file_open that
|
||||
* we came from NFS and so opencache needs to be
|
||||
* enabled for this one
|
||||
*/
|
||||
ll_d2d(result)->lld_nfs_dentry = 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -432,17 +432,9 @@ static struct dentry *ll_find_alias(struct inode *inode, struct dentry *dentry)
|
||||
*/
|
||||
struct dentry *ll_splice_alias(struct inode *inode, struct dentry *de)
|
||||
{
|
||||
struct dentry *new;
|
||||
int rc;
|
||||
|
||||
if (inode) {
|
||||
new = ll_find_alias(inode, de);
|
||||
struct dentry *new = ll_find_alias(inode, de);
|
||||
if (new) {
|
||||
rc = ll_d_init(new);
|
||||
if (rc < 0) {
|
||||
dput(new);
|
||||
return ERR_PTR(rc);
|
||||
}
|
||||
d_move(new, de);
|
||||
iput(inode);
|
||||
CDEBUG(D_DENTRY,
|
||||
@@ -451,9 +443,6 @@ struct dentry *ll_splice_alias(struct inode *inode, struct dentry *de)
|
||||
return new;
|
||||
}
|
||||
}
|
||||
rc = ll_d_init(de);
|
||||
if (rc < 0)
|
||||
return ERR_PTR(rc);
|
||||
d_add(de, inode);
|
||||
CDEBUG(D_DENTRY, "Add dentry %p inode %p refc %d flags %#x\n",
|
||||
de, d_inode(de), d_count(de), de->d_flags);
|
||||
|
||||
@@ -1519,9 +1519,7 @@ out_unplug:
|
||||
* dentry_may_statahead().
|
||||
*/
|
||||
ldd = ll_d2d(*dentryp);
|
||||
/* ldd can be NULL if llite lookup failed. */
|
||||
if (ldd)
|
||||
ldd->lld_sa_generation = lli->lli_sa_generation;
|
||||
ldd->lld_sa_generation = lli->lli_sa_generation;
|
||||
sa_put(sai, entry);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ static ssize_t target_core_item_dbroot_store(struct config_item *item,
|
||||
pr_err("db_root: cannot open: %s\n", db_root_stage);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!S_ISDIR(fp->f_inode->i_mode)) {
|
||||
if (!S_ISDIR(file_inode(fp)->i_mode)) {
|
||||
filp_close(fp, 0);
|
||||
mutex_unlock(&g_tf_lock);
|
||||
pr_err("db_root: not a directory: %s\n", db_root_stage);
|
||||
|
||||
@@ -949,7 +949,7 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
|
||||
goto error_mutex;
|
||||
}
|
||||
if (!io_data->read &&
|
||||
copy_from_iter(data, data_len, &io_data->data) != data_len) {
|
||||
!copy_from_iter_full(data, data_len, &io_data->data)) {
|
||||
ret = -EFAULT;
|
||||
goto error_mutex;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user