Commit f4e0c30c191f87851c4a53454abb55ee276f4a7e

Authored by Al Viro
1 parent 60545d0d46

allow the temp files created by open() to be linked to

O_TMPFILE | O_CREAT => linkat() with AT_SYMLINK_FOLLOW and /proc/self/fd/<n>
as oldpath (i.e. flink()) will create a link
O_TMPFILE | O_CREAT | O_EXCL => ENOENT on attempt to link those guys

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Showing 3 changed files with 18 additions and 3 deletions Side-by-side Diff

... ... @@ -333,8 +333,10 @@
333 333 */
334 334 void inc_nlink(struct inode *inode)
335 335 {
336   - if (WARN_ON(inode->i_nlink == 0))
  336 + if (unlikely(inode->i_nlink == 0)) {
  337 + WARN_ON(!(inode->i_state & I_LINKABLE));
337 338 atomic_long_dec(&inode->i_sb->s_remove_count);
  339 + }
338 340  
339 341 inode->__i_nlink++;
340 342 }
... ... @@ -2948,8 +2948,14 @@
2948 2948 if (error)
2949 2949 goto out2;
2950 2950 error = open_check_o_direct(file);
2951   - if (error)
  2951 + if (error) {
2952 2952 fput(file);
  2953 + } else if (!(op->open_flag & O_EXCL)) {
  2954 + struct inode *inode = file_inode(file);
  2955 + spin_lock(&inode->i_lock);
  2956 + inode->i_state |= I_LINKABLE;
  2957 + spin_unlock(&inode->i_lock);
  2958 + }
2953 2959 out2:
2954 2960 mnt_drop_write(nd->path.mnt);
2955 2961 out:
2956 2962  
... ... @@ -3628,12 +3634,18 @@
3628 3634  
3629 3635 mutex_lock(&inode->i_mutex);
3630 3636 /* Make sure we don't allow creating hardlink to an unlinked file */
3631   - if (inode->i_nlink == 0)
  3637 + if (inode->i_nlink == 0 && !(inode->i_state & I_LINKABLE))
3632 3638 error = -ENOENT;
3633 3639 else if (max_links && inode->i_nlink >= max_links)
3634 3640 error = -EMLINK;
3635 3641 else
3636 3642 error = dir->i_op->link(old_dentry, dir, new_dentry);
  3643 +
  3644 + if (!error && (inode->i_state & I_LINKABLE)) {
  3645 + spin_lock(&inode->i_lock);
  3646 + inode->i_state &= ~I_LINKABLE;
  3647 + spin_unlock(&inode->i_lock);
  3648 + }
3637 3649 mutex_unlock(&inode->i_mutex);
3638 3650 if (!error)
3639 3651 fsnotify_link(dir, inode, new_dentry);
... ... @@ -1744,6 +1744,7 @@
1744 1744 #define I_REFERENCED (1 << 8)
1745 1745 #define __I_DIO_WAKEUP 9
1746 1746 #define I_DIO_WAKEUP (1 << I_DIO_WAKEUP)
  1747 +#define I_LINKABLE (1 << 10)
1747 1748  
1748 1749 #define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)
1749 1750