aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-11 14:44:11 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-11 14:44:11 -0400
commitf6f993328b2abcab86a3c99d7bd9f2066ab03d36 (patch)
treeea6f3902a0fa546493731b3b52a31d98cc747a90 /fs/cifs
parentc7a19c795b4b0a3232c157ed29eea85077e95da6 (diff)
parent12a5b5294cb1896e9a3c9fca8ff5a7e3def4e8c6 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs updates from Al Viro: "Stuff in here: - acct.c fixes and general rework of mnt_pin mechanism. That allows to go for delayed-mntput stuff, which will permit mntput() on deep stack without worrying about stack overflows - fs shutdown will happen on shallow stack. IOW, we can do Eric's umount-on-rmdir series without introducing tons of stack overflows on new mntput() call chains it introduces. - Bruce's d_splice_alias() patches - more Miklos' rename() stuff. - a couple of regression fixes (stable fodder, in the end of branch) and a fix for API idiocy in iov_iter.c. There definitely will be another pile, maybe even two. I'd like to get Eric's series in this time, but even if we miss it, it'll go right in the beginning of for-next in the next cycle - the tricky part of prereqs is in this pile" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (40 commits) fix copy_tree() regression __generic_file_write_iter(): fix handling of sync error after DIO switch iov_iter_get_pages() to passing maximal number of pages fs: mark __d_obtain_alias static dcache: d_splice_alias should detect loops exportfs: update Exporting documentation dcache: d_find_alias needn't recheck IS_ROOT && DCACHE_DISCONNECTED dcache: remove unused d_find_alias parameter dcache: d_obtain_alias callers don't all want DISCONNECTED dcache: d_splice_alias should ignore DCACHE_DISCONNECTED dcache: d_splice_alias mustn't create directory aliases dcache: close d_move race in d_splice_alias dcache: move d_splice_alias namei: trivial fix to vfs_rename_dir comment VFS: allow ->d_manage() to declare -EISDIR in rcu_walk mode. cifs: support RENAME_NOREPLACE hostfs: support rename flags shmem: support RENAME_EXCHANGE shmem: support RENAME_NOREPLACE btrfs: add RENAME_NOREPLACE ...
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifsfs.c2
-rw-r--r--fs/cifs/cifsfs.h4
-rw-r--r--fs/cifs/inode.c14
3 files changed, 15 insertions, 5 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 888398067420..ac4f260155c8 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -848,7 +848,7 @@ const struct inode_operations cifs_dir_inode_ops = {
848 .link = cifs_hardlink, 848 .link = cifs_hardlink,
849 .mkdir = cifs_mkdir, 849 .mkdir = cifs_mkdir,
850 .rmdir = cifs_rmdir, 850 .rmdir = cifs_rmdir,
851 .rename = cifs_rename, 851 .rename2 = cifs_rename2,
852 .permission = cifs_permission, 852 .permission = cifs_permission,
853/* revalidate:cifs_revalidate, */ 853/* revalidate:cifs_revalidate, */
854 .setattr = cifs_setattr, 854 .setattr = cifs_setattr,
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 560480263336..b0fafa499505 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -68,8 +68,8 @@ extern int cifs_hardlink(struct dentry *, struct inode *, struct dentry *);
68extern int cifs_mknod(struct inode *, struct dentry *, umode_t, dev_t); 68extern int cifs_mknod(struct inode *, struct dentry *, umode_t, dev_t);
69extern int cifs_mkdir(struct inode *, struct dentry *, umode_t); 69extern int cifs_mkdir(struct inode *, struct dentry *, umode_t);
70extern int cifs_rmdir(struct inode *, struct dentry *); 70extern int cifs_rmdir(struct inode *, struct dentry *);
71extern int cifs_rename(struct inode *, struct dentry *, struct inode *, 71extern int cifs_rename2(struct inode *, struct dentry *, struct inode *,
72 struct dentry *); 72 struct dentry *, unsigned int);
73extern int cifs_revalidate_file_attr(struct file *filp); 73extern int cifs_revalidate_file_attr(struct file *filp);
74extern int cifs_revalidate_dentry_attr(struct dentry *); 74extern int cifs_revalidate_dentry_attr(struct dentry *);
75extern int cifs_revalidate_file(struct file *filp); 75extern int cifs_revalidate_file(struct file *filp);
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 41de3935caa0..426d6c6ad8bf 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1627,8 +1627,9 @@ do_rename_exit:
1627} 1627}
1628 1628
1629int 1629int
1630cifs_rename(struct inode *source_dir, struct dentry *source_dentry, 1630cifs_rename2(struct inode *source_dir, struct dentry *source_dentry,
1631 struct inode *target_dir, struct dentry *target_dentry) 1631 struct inode *target_dir, struct dentry *target_dentry,
1632 unsigned int flags)
1632{ 1633{
1633 char *from_name = NULL; 1634 char *from_name = NULL;
1634 char *to_name = NULL; 1635 char *to_name = NULL;
@@ -1640,6 +1641,9 @@ cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
1640 unsigned int xid; 1641 unsigned int xid;
1641 int rc, tmprc; 1642 int rc, tmprc;
1642 1643
1644 if (flags & ~RENAME_NOREPLACE)
1645 return -EINVAL;
1646
1643 cifs_sb = CIFS_SB(source_dir->i_sb); 1647 cifs_sb = CIFS_SB(source_dir->i_sb);
1644 tlink = cifs_sb_tlink(cifs_sb); 1648 tlink = cifs_sb_tlink(cifs_sb);
1645 if (IS_ERR(tlink)) 1649 if (IS_ERR(tlink))
@@ -1667,6 +1671,12 @@ cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
1667 rc = cifs_do_rename(xid, source_dentry, from_name, target_dentry, 1671 rc = cifs_do_rename(xid, source_dentry, from_name, target_dentry,
1668 to_name); 1672 to_name);
1669 1673
1674 /*
1675 * No-replace is the natural behavior for CIFS, so skip unlink hacks.
1676 */
1677 if (flags & RENAME_NOREPLACE)
1678 goto cifs_rename_exit;
1679
1670 if (rc == -EEXIST && tcon->unix_ext) { 1680 if (rc == -EEXIST && tcon->unix_ext) {
1671 /* 1681 /*
1672 * Are src and dst hardlinks of same inode? We can only tell 1682 * Are src and dst hardlinks of same inode? We can only tell