Commit 1b5dd0c2 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] move library functions from ramfs into libfs

From Bill Irwin

The simple_link(), simple_unlink(), simple_rename(),
simple_sync_file(), simple_rmdir(), and simple_empty() functions are
easy to duplicate.  Basically, I duplicated them in an fs patch of
mine, and Linus told me to put them in libfs.c

Pat Mochel has acked the changes for driverfs (in that he'll convert
the stuff over when they're available from libfs), and my hugetlbfs
implementation was the thing that spurred the whole incident.
parent 5b73f882
......@@ -208,3 +208,73 @@ get_sb_pseudo(struct file_system_type *fs_type, char *name,
deactivate_super(s);
return ERR_PTR(-ENOMEM);
}
int simple_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
{
struct inode *inode = old_dentry->d_inode;
inode->i_nlink++;
atomic_inc(&inode->i_count);
dget(dentry);
d_instantiate(dentry, inode);
return 0;
}
static inline int simple_positive(struct dentry *dentry)
{
return dentry->d_inode && !d_unhashed(dentry);
}
int simple_empty(struct dentry *dentry)
{
struct dentry *child;
int ret = 0;
spin_lock(&dcache_lock);
list_for_each_entry(child, &dentry->d_subdirs, d_child)
if (simple_positive(child))
goto out;
ret = 1;
out:
spin_unlock(&dcache_lock);
return ret;
}
int simple_unlink(struct inode *dir, struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
inode->i_nlink--;
dput(dentry);
return 0;
}
int simple_rmdir(struct inode *dir, struct dentry *dentry)
{
if (!simple_empty(dentry))
return -ENOTEMPTY;
dentry->d_inode->i_nlink--;
simple_unlink(dir, dentry);
dir->i_nlink--;
return 0;
}
int simple_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry)
{
struct inode *inode;
if (!simple_empty(new_dentry))
return -ENOTEMPTY;
inode = new_dentry->d_inode;
if (inode) {
inode->i_nlink--;
dput(new_dentry);
}
if (S_ISDIR(old_dentry->d_inode->i_mode)) {
old_dir->i_nlink--;
new_dir->i_nlink++;
}
return 0;
}
......@@ -155,102 +155,6 @@ static int ramfs_create(struct inode *dir, struct dentry *dentry, int mode)
return ramfs_mknod(dir, dentry, mode | S_IFREG, 0);
}
/*
* Link a file..
*/
static int ramfs_link(struct dentry *old_dentry, struct inode * dir, struct dentry * dentry)
{
struct inode *inode = old_dentry->d_inode;
inode->i_nlink++;
atomic_inc(&inode->i_count); /* New dentry reference */
dget(dentry); /* Extra pinning count for the created dentry */
d_instantiate(dentry, inode);
return 0;
}
static inline int ramfs_positive(struct dentry *dentry)
{
return dentry->d_inode && !d_unhashed(dentry);
}
/*
* Check that a directory is empty (this works
* for regular files too, they'll just always be
* considered empty..).
*
* Note that an empty directory can still have
* children, they just all have to be negative..
*/
static int ramfs_empty(struct dentry *dentry)
{
struct list_head *list;
spin_lock(&dcache_lock);
list = dentry->d_subdirs.next;
while (list != &dentry->d_subdirs) {
struct dentry *de = list_entry(list, struct dentry, d_child);
if (ramfs_positive(de)) {
spin_unlock(&dcache_lock);
return 0;
}
list = list->next;
}
spin_unlock(&dcache_lock);
return 1;
}
/*
* Unlink a ramfs entry
*/
static int ramfs_unlink(struct inode * dir, struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
inode->i_nlink--;
dput(dentry); /* Undo the count from "create" - this does all the work */
return 0;
}
static int ramfs_rmdir(struct inode * dir, struct dentry *dentry)
{
int retval = -ENOTEMPTY;
if (ramfs_empty(dentry)) {
dentry->d_inode->i_nlink--;
ramfs_unlink(dir, dentry);
dir->i_nlink--;
retval = 0;
}
return retval;
}
/*
* The VFS layer already does all the dentry stuff for rename,
* we just have to decrement the usage count for the target if
* it exists so that the VFS layer correctly free's it when it
* gets overwritten.
*/
static int ramfs_rename(struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir,struct dentry *new_dentry)
{
int error = -ENOTEMPTY;
if (ramfs_empty(new_dentry)) {
struct inode *inode = new_dentry->d_inode;
if (inode) {
inode->i_nlink--;
dput(new_dentry);
}
if (S_ISDIR(old_dentry->d_inode->i_mode)) {
old_dir->i_nlink--;
new_dir->i_nlink++;
}
error = 0;
}
return error;
}
static int ramfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname)
{
......@@ -270,11 +174,6 @@ static int ramfs_symlink(struct inode * dir, struct dentry *dentry, const char *
return error;
}
static int ramfs_sync_file(struct file * file, struct dentry *dentry, int datasync)
{
return 0;
}
static struct address_space_operations ramfs_aops = {
.readpage = ramfs_readpage,
.writepage = fail_writepage,
......@@ -286,20 +185,20 @@ static struct file_operations ramfs_file_operations = {
.read = generic_file_read,
.write = generic_file_write,
.mmap = generic_file_mmap,
.fsync = ramfs_sync_file,
.fsync = simple_sync_file,
.sendfile = generic_file_sendfile,
};
static struct inode_operations ramfs_dir_inode_operations = {
.create = ramfs_create,
.lookup = simple_lookup,
.link = ramfs_link,
.unlink = ramfs_unlink,
.link = simple_link,
.unlink = simple_unlink,
.symlink = ramfs_symlink,
.mkdir = ramfs_mkdir,
.rmdir = ramfs_rmdir,
.rmdir = simple_rmdir,
.mknod = ramfs_mknod,
.rename = ramfs_rename,
.rename = simple_rename,
};
static struct super_operations ramfs_ops = {
......
......@@ -1286,6 +1286,12 @@ extern int dcache_dir_close(struct inode *, struct file *);
extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
extern int dcache_readdir(struct file *, void *, filldir_t);
extern int simple_statfs(struct super_block *, struct statfs *);
extern int simple_link(struct dentry *, struct inode *, struct dentry *);
extern int simple_unlink(struct inode *, struct dentry *);
extern int simple_rmdir(struct inode *, struct dentry *);
extern int simple_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
extern int simple_sync_file(struct file *, struct dentry *, int);
extern int simple_empty(struct dentry *);
extern struct dentry *simple_lookup(struct inode *, struct dentry *);
extern ssize_t generic_read_dir(struct file *, char *, size_t, loff_t *);
extern struct file_operations simple_dir_operations;
......
......@@ -303,6 +303,12 @@ EXPORT_SYMBOL(simple_statfs);
EXPORT_SYMBOL(simple_lookup);
EXPORT_SYMBOL(simple_dir_operations);
EXPORT_SYMBOL(simple_dir_inode_operations);
EXPORT_SYMBOL(simple_link);
EXPORT_SYMBOL(simple_unlink);
EXPORT_SYMBOL(simple_rmdir);
EXPORT_SYMBOL(simple_rename);
EXPORT_SYMBOL(simple_sync_file);
EXPORT_SYMBOL(simple_empty);
EXPORT_SYMBOL(fd_install);
EXPORT_SYMBOL(put_unused_fd);
EXPORT_SYMBOL(get_sb_bdev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment