diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2013-06-11 04:52:02 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-06-29 04:57:12 -0400 |
commit | e6bbef95429374fd3cac81c36b5894f55b2612dc (patch) | |
tree | 944383bd7048bb72f34aac73fc4e5cca6e87a615 /fs | |
parent | f4e0c30c191f87851c4a53454abb55ee276f4a7e (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.c | 47 |
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 | ||
1765 | static 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 | |||
1773 | retry: | ||
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; | ||
1797 | err_drop_inode: | ||
1798 | ext3_journal_stop(handle); | ||
1799 | unlock_new_inode(inode); | ||
1800 | iput(inode); | ||
1801 | return err; | ||
1802 | } | ||
1803 | |||
1765 | static int ext3_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) | 1804 | static 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 | ||
2304 | retry: | 2343 | retry: |
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 |