Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 347838
b: refs/heads/master
c: 21e89c0
h: refs/heads/master
v: v3
  • Loading branch information
Al Viro committed Dec 20, 2012
1 parent d38ddf7 commit 9ab6fe7
Show file tree
Hide file tree
Showing 47 changed files with 237 additions and 271 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 91c7fbbf63f33c77d8d28de624834a21888842bb
refs/heads/master: 21e89c0c48bb799beb09181740796fc80c9676e2
6 changes: 0 additions & 6 deletions trunk/Documentation/filesystems/Locking
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ rename: yes (all) (see below)
readlink: no
follow_link: no
put_link: no
truncate: yes (see below)
setattr: yes
permission: no (may not block if called in rcu-walk mode)
get_acl: no
Expand All @@ -96,11 +95,6 @@ atomic_open: yes
Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on
victim.
cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem.
->truncate() is never called directly - it's a callback, not a
method. It's called by vmtruncate() - deprecated library function used by
->setattr(). Locking information above applies to that call (i.e. is
inherited from ->setattr() - vmtruncate() is used when ATTR_SIZE had been
passed).

See Documentation/filesystems/directory-locking for more detailed discussion
of the locking scheme for directory operations.
Expand Down
2 changes: 1 addition & 1 deletion trunk/Documentation/filesystems/porting
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ ext2_write_failed and callers for an example.

[mandatory]

->truncate is going away. The whole truncate sequence needs to be
->truncate is gone. The whole truncate sequence needs to be
implemented in ->setattr, which is now mandatory for filesystems
implementing on-disk size changes. Start with a copy of the old inode_setattr
and vmtruncate, and the reorder the vmtruncate + foofs_vmtruncate sequence to
Expand Down
11 changes: 0 additions & 11 deletions trunk/Documentation/filesystems/vfs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,6 @@ struct inode_operations {
int (*readlink) (struct dentry *, char __user *,int);
void * (*follow_link) (struct dentry *, struct nameidata *);
void (*put_link) (struct dentry *, struct nameidata *, void *);
void (*truncate) (struct inode *);
int (*permission) (struct inode *, int);
int (*get_acl)(struct inode *, int);
int (*setattr) (struct dentry *, struct iattr *);
Expand Down Expand Up @@ -431,16 +430,6 @@ otherwise noted.
started might not be in the page cache at the end of the
walk).

truncate: Deprecated. This will not be called if ->setsize is defined.
Called by the VFS to change the size of a file. The
i_size field of the inode is set to the desired size by the
VFS before this method is called. This method is called by
the truncate(2) system call and related functionality.

Note: ->truncate and vmtruncate are deprecated. Do not add new
instances/calls of these. Filesystems should be converted to do their
truncate sequence via ->setattr().

permission: called by the VFS to check for access rights on a POSIX-like
filesystem.

Expand Down
15 changes: 10 additions & 5 deletions trunk/fs/adfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ static int adfs_readpage(struct file *file, struct page *page)
return block_read_full_page(page, adfs_get_block);
}

static void adfs_write_failed(struct address_space *mapping, loff_t to)
{
struct inode *inode = mapping->host;

if (to > inode->i_size)
truncate_pagecache(inode, to, inode->i_size);
}

static int adfs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
Expand All @@ -55,11 +63,8 @@ static int adfs_write_begin(struct file *file, struct address_space *mapping,
ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
adfs_get_block,
&ADFS_I(mapping->host)->mmu_private);
if (unlikely(ret)) {
loff_t isize = mapping->host->i_size;
if (pos + len > isize)
vmtruncate(mapping->host, isize);
}
if (unlikely(ret))
adfs_write_failed(mapping, pos + len);

return ret;
}
Expand Down
18 changes: 12 additions & 6 deletions trunk/fs/affs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ const struct file_operations affs_file_operations = {
};

const struct inode_operations affs_file_inode_operations = {
.truncate = affs_truncate,
.setattr = affs_notify_change,
};

Expand Down Expand Up @@ -402,6 +401,16 @@ static int affs_readpage(struct file *file, struct page *page)
return block_read_full_page(page, affs_get_block);
}

static void affs_write_failed(struct address_space *mapping, loff_t to)
{
struct inode *inode = mapping->host;

if (to > inode->i_size) {
truncate_pagecache(inode, to, inode->i_size);
affs_truncate(inode);
}
}

static int affs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
Expand All @@ -412,11 +421,8 @@ static int affs_write_begin(struct file *file, struct address_space *mapping,
ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
affs_get_block,
&AFFS_I(mapping->host)->mmu_private);
if (unlikely(ret)) {
loff_t isize = mapping->host->i_size;
if (pos + len > isize)
vmtruncate(mapping->host, isize);
}
if (unlikely(ret))
affs_write_failed(mapping, pos + len);

return ret;
}
Expand Down
5 changes: 4 additions & 1 deletion trunk/fs/affs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,12 @@ affs_notify_change(struct dentry *dentry, struct iattr *attr)

if ((attr->ia_valid & ATTR_SIZE) &&
attr->ia_size != i_size_read(inode)) {
error = vmtruncate(inode, attr->ia_size);
error = inode_newsize_ok(inode, attr->ia_size);
if (error)
return error;

truncate_setsize(inode, attr->ia_size);
affs_truncate(inode);
}

setattr_copy(inode, attr);
Expand Down
15 changes: 10 additions & 5 deletions trunk/fs/bfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,14 @@ static int bfs_readpage(struct file *file, struct page *page)
return block_read_full_page(page, bfs_get_block);
}

static void bfs_write_failed(struct address_space *mapping, loff_t to)
{
struct inode *inode = mapping->host;

if (to > inode->i_size)
truncate_pagecache(inode, to, inode->i_size);
}

static int bfs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
Expand All @@ -169,11 +177,8 @@ static int bfs_write_begin(struct file *file, struct address_space *mapping,

ret = block_write_begin(mapping, pos, len, flags, pagep,
bfs_get_block);
if (unlikely(ret)) {
loff_t isize = mapping->host->i_size;
if (pos + len > isize)
vmtruncate(mapping->host, isize);
}
if (unlikely(ret))
bfs_write_failed(mapping, pos + len);

return ret;
}
Expand Down
16 changes: 1 addition & 15 deletions trunk/fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -4262,16 +4262,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
if (dentry->d_name.len > BTRFS_NAME_LEN)
return ERR_PTR(-ENAMETOOLONG);

if (unlikely(d_need_lookup(dentry))) {
memcpy(&location, dentry->d_fsdata, sizeof(struct btrfs_key));
kfree(dentry->d_fsdata);
dentry->d_fsdata = NULL;
/* This thing is hashed, drop it for now */
d_drop(dentry);
} else {
ret = btrfs_inode_by_name(dir, dentry, &location);
}

ret = btrfs_inode_by_name(dir, dentry, &location);
if (ret < 0)
return ERR_PTR(ret);

Expand Down Expand Up @@ -4341,11 +4332,6 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
struct dentry *ret;

ret = d_splice_alias(btrfs_lookup_dentry(dir, dentry), dentry);
if (unlikely(d_need_lookup(dentry))) {
spin_lock(&dentry->d_lock);
dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
spin_unlock(&dentry->d_lock);
}
return ret;
}

Expand Down
35 changes: 2 additions & 33 deletions trunk/fs/dcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -454,24 +454,6 @@ void d_drop(struct dentry *dentry)
}
EXPORT_SYMBOL(d_drop);

/*
* d_clear_need_lookup - drop a dentry from cache and clear the need lookup flag
* @dentry: dentry to drop
*
* This is called when we do a lookup on a placeholder dentry that needed to be
* looked up. The dentry should have been hashed in order for it to be found by
* the lookup code, but now needs to be unhashed while we do the actual lookup
* and clear the DCACHE_NEED_LOOKUP flag.
*/
void d_clear_need_lookup(struct dentry *dentry)
{
spin_lock(&dentry->d_lock);
__d_drop(dentry);
dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
spin_unlock(&dentry->d_lock);
}
EXPORT_SYMBOL(d_clear_need_lookup);

/*
* Finish off a dentry we've decided to kill.
* dentry->d_lock must be held, returns with it unlocked.
Expand Down Expand Up @@ -565,13 +547,7 @@ void dput(struct dentry *dentry)
if (d_unhashed(dentry))
goto kill_it;

/*
* If this dentry needs lookup, don't set the referenced flag so that it
* is more likely to be cleaned up by the dcache shrinker in case of
* memory pressure.
*/
if (!d_need_lookup(dentry))
dentry->d_flags |= DCACHE_REFERENCED;
dentry->d_flags |= DCACHE_REFERENCED;
dentry_lru_add(dentry);

dentry->d_count--;
Expand Down Expand Up @@ -1583,7 +1559,7 @@ EXPORT_SYMBOL(d_find_any_alias);
*/
struct dentry *d_obtain_alias(struct inode *inode)
{
static const struct qstr anonstring = { .name = "" };
static const struct qstr anonstring = QSTR_INIT("/", 1);
struct dentry *tmp;
struct dentry *res;

Expand Down Expand Up @@ -1736,13 +1712,6 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode,
return found;
}

/*
* We are going to instantiate this dentry, unhash it and clear the
* lookup flag so we can do that.
*/
if (unlikely(d_need_lookup(found)))
d_clear_need_lookup(found);

/*
* Negative dentry: instantiate it unless the inode is a directory and
* already has a dentry.
Expand Down
2 changes: 1 addition & 1 deletion trunk/fs/file_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -458,8 +458,8 @@ void mark_files_ro(struct super_block *sb)
spin_unlock(&f->f_lock);
if (file_check_writeable(f) != 0)
continue;
__mnt_drop_write(f->f_path.mnt);
file_release_write(f);
mnt_drop_write_file(f);
} while_file_list_for_each_entry;
lg_global_unlock(&files_lglock);
}
Expand Down
26 changes: 18 additions & 8 deletions trunk/fs/hfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ static int hfs_readpage(struct file *file, struct page *page)
return block_read_full_page(page, hfs_get_block);
}

static void hfs_write_failed(struct address_space *mapping, loff_t to)
{
struct inode *inode = mapping->host;

if (to > inode->i_size) {
truncate_pagecache(inode, to, inode->i_size);
hfs_file_truncate(inode);
}
}

static int hfs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
Expand All @@ -45,11 +55,8 @@ static int hfs_write_begin(struct file *file, struct address_space *mapping,
ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
hfs_get_block,
&HFS_I(mapping->host)->phys_size);
if (unlikely(ret)) {
loff_t isize = mapping->host->i_size;
if (pos + len > isize)
vmtruncate(mapping->host, isize);
}
if (unlikely(ret))
hfs_write_failed(mapping, pos + len);

return ret;
}
Expand Down Expand Up @@ -120,6 +127,7 @@ static ssize_t hfs_direct_IO(int rw, struct kiocb *iocb,
const struct iovec *iov, loff_t offset, unsigned long nr_segs)
{
struct file *file = iocb->ki_filp;
struct address_space *mapping = file->f_mapping;
struct inode *inode = file->f_path.dentry->d_inode->i_mapping->host;
ssize_t ret;

Expand All @@ -135,7 +143,7 @@ static ssize_t hfs_direct_IO(int rw, struct kiocb *iocb,
loff_t end = offset + iov_length(iov, nr_segs);

if (end > isize)
vmtruncate(inode, isize);
hfs_write_failed(mapping, end);
}

return ret;
Expand Down Expand Up @@ -617,9 +625,12 @@ int hfs_inode_setattr(struct dentry *dentry, struct iattr * attr)
attr->ia_size != i_size_read(inode)) {
inode_dio_wait(inode);

error = vmtruncate(inode, attr->ia_size);
error = inode_newsize_ok(inode, attr->ia_size);
if (error)
return error;

truncate_setsize(inode, attr->ia_size);
hfs_file_truncate(inode);
}

setattr_copy(inode, attr);
Expand Down Expand Up @@ -668,7 +679,6 @@ static const struct file_operations hfs_file_operations = {

static const struct inode_operations hfs_file_inode_operations = {
.lookup = hfs_file_lookup,
.truncate = hfs_file_truncate,
.setattr = hfs_inode_setattr,
.setxattr = hfs_setxattr,
.getxattr = hfs_getxattr,
Expand Down
Loading

0 comments on commit 9ab6fe7

Please sign in to comment.