aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-06-11 04:52:02 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-06-29 04:57:12 -0400
commite6bbef95429374fd3cac81c36b5894f55b2612dc (patch)
tree944383bd7048bb72f34aac73fc4e5cca6e87a615 /fs
parentf4e0c30c191f87851c4a53454abb55ee276f4a7e (diff)
ext3 ->tmpfile() support
In this case we do need a bit more than usual, due to orphan list handling. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/ext3/namei.c47
1 files changed, 46 insertions, 1 deletions
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index 692de13e3596..7523c61f796c 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -1762,6 +1762,45 @@ retry:
1762 return err; 1762 return err;
1763} 1763}
1764 1764
1765static int ext3_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
1766{
1767 handle_t *handle;
1768 struct inode *inode;
1769 int err, retries = 0;
1770
1771 dquot_initialize(dir);
1772
1773retry:
1774 handle = ext3_journal_start(dir, EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb) +
1775 4 + EXT3_XATTR_TRANS_BLOCKS);
1776
1777 if (IS_ERR(handle))
1778 return PTR_ERR(handle);
1779
1780 inode = ext3_new_inode (handle, dir, NULL, mode);
1781 err = PTR_ERR(inode);
1782 if (!IS_ERR(inode)) {
1783 inode->i_op = &ext3_file_inode_operations;
1784 inode->i_fop = &ext3_file_operations;
1785 ext3_set_aops(inode);
1786 err = ext3_orphan_add(handle, inode);
1787 if (err)
1788 goto err_drop_inode;
1789 mark_inode_dirty(inode);
1790 d_tmpfile(dentry, inode);
1791 unlock_new_inode(inode);
1792 }
1793 ext3_journal_stop(handle);
1794 if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries))
1795 goto retry;
1796 return err;
1797err_drop_inode:
1798 ext3_journal_stop(handle);
1799 unlock_new_inode(inode);
1800 iput(inode);
1801 return err;
1802}
1803
1765static int ext3_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) 1804static int ext3_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode)
1766{ 1805{
1767 handle_t *handle; 1806 handle_t *handle;
@@ -2303,7 +2342,7 @@ static int ext3_link (struct dentry * old_dentry,
2303 2342
2304retry: 2343retry:
2305 handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + 2344 handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
2306 EXT3_INDEX_EXTRA_TRANS_BLOCKS); 2345 EXT3_INDEX_EXTRA_TRANS_BLOCKS + 1);
2307 if (IS_ERR(handle)) 2346 if (IS_ERR(handle))
2308 return PTR_ERR(handle); 2347 return PTR_ERR(handle);
2309 2348
@@ -2317,6 +2356,11 @@ retry:
2317 err = ext3_add_entry(handle, dentry, inode); 2356 err = ext3_add_entry(handle, dentry, inode);
2318 if (!err) { 2357 if (!err) {
2319 ext3_mark_inode_dirty(handle, inode); 2358 ext3_mark_inode_dirty(handle, inode);
2359 /* this can happen only for tmpfile being
2360 * linked the first time
2361 */
2362 if (inode->i_nlink == 1)
2363 ext3_orphan_del(handle, inode);
2320 d_instantiate(dentry, inode); 2364 d_instantiate(dentry, inode);
2321 } else { 2365 } else {
2322 drop_nlink(inode); 2366 drop_nlink(inode);
@@ -2519,6 +2563,7 @@ const struct inode_operations ext3_dir_inode_operations = {
2519 .mkdir = ext3_mkdir, 2563 .mkdir = ext3_mkdir,
2520 .rmdir = ext3_rmdir, 2564 .rmdir = ext3_rmdir,
2521 .mknod = ext3_mknod, 2565 .mknod = ext3_mknod,
2566 .tmpfile = ext3_tmpfile,
2522 .rename = ext3_rename, 2567 .rename = ext3_rename,
2523 .setattr = ext3_setattr, 2568 .setattr = ext3_setattr,
2524#ifdef CONFIG_EXT3_FS_XATTR 2569#ifdef CONFIG_EXT3_FS_XATTR