[PATCH 21/50] CIFS: Add SMB2 support for unlink operation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Pavel Shilovsky <piastryyy@xxxxxxxxx>

Signed-off-by: Pavel Shilovsky <piastryyy@xxxxxxxxx>
---
 fs/cifs/smb2inode.c |   66 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 fs/cifs/smb2proto.h |    1 +
 2 files changed, 66 insertions(+), 1 deletions(-)

diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
index 73cf635..667723a 100644
--- a/fs/cifs/smb2inode.c
+++ b/fs/cifs/smb2inode.c
@@ -39,7 +39,7 @@ const struct inode_operations smb2_dir_inode_ops = {
 	.create = cifs_create,
 	.lookup = cifs_lookup,
 	.getattr = cifs_getattr,
-	.unlink = cifs_unlink,
+	.unlink = smb2_unlink,
 	.link = cifs_hardlink,
 	.mkdir = smb2_mkdir,
 	.rmdir = smb2_rmdir,
@@ -442,3 +442,67 @@ rmdir_exit:
 	FreeXid(xid);
 	return rc;
 }
+
+int smb2_unlink(struct inode *dir, struct dentry *dentry)
+{
+	int rc = 0;
+	int xid;
+	struct inode *inode = dentry->d_inode;
+	struct cifsInodeInfo *cifs_inode;
+	struct super_block *sb = dir->i_sb;
+	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+	struct tcon_link *tlink;
+	struct cifs_tcon *tcon;
+	__le16 *utf16_path = NULL;
+
+	cFYI(1, "%s: dir=0x%p, dentry=0x%p", __func__, dir, dentry);
+
+	tlink = cifs_sb_tlink(cifs_sb);
+	if (IS_ERR(tlink))
+		return PTR_ERR(tlink);
+	tcon = tlink_tcon(tlink);
+
+	xid = GetXid();
+
+	/*
+	 * Unlink can be called from rename so we can not take the
+	 * sb->s_vfs_rename_mutex here.
+	 */
+	utf16_path = cifs_build_utf16path_from_dentry(dentry);
+	if (utf16_path == NULL) {
+		rc = -ENOMEM;
+		goto unlink_out;
+	}
+
+	rc = smb2_open_op_close(xid, tcon, utf16_path, DELETE,
+				FILE_OPEN, 0, CREATE_DELETE_ON_CLOSE, NULL,
+				SMB2_OP_DELETE);
+	if (!rc) {
+		if (inode)
+			drop_nlink(inode);
+	} else if (rc == -ENOENT) {
+		d_drop(dentry);
+	} else if (rc == -ETXTBSY) {
+		/* rc = cifs_rename_pending_delete(full_path, dentry, xid);
+		if (rc == 0)
+			drop_nlink(inode); */
+	} else if ((rc == -EACCES) && inode)
+		/* BB reset dos attributes and retry once */
+
+	/* BB undo the setattr if we errored out and it's needed */
+	if (inode) {
+		cifs_inode = CIFS_I(inode);
+		/* will force revalidate to get info when needed */
+		cifs_inode->time = 0;
+		inode->i_ctime = current_fs_time(sb);
+	}
+	dir->i_ctime = dir->i_mtime = current_fs_time(sb);
+	cifs_inode = CIFS_I(dir);
+	/* force revalidate of dir as well */
+	CIFS_I(dir)->time = 0;
+unlink_out:
+	kfree(utf16_path);
+	FreeXid(xid);
+	cifs_put_tlink(tlink);
+	return rc;
+}
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
index 8c2f734..32c064c 100644
--- a/fs/cifs/smb2proto.h
+++ b/fs/cifs/smb2proto.h
@@ -60,6 +60,7 @@ extern int smb2_query_inode_info(struct inode **pinode, const char *full_path,
 extern void smb2_set_ops(struct inode *inode);
 extern int smb2_mkdir(struct inode *inode, struct dentry *direntry, int mode);
 extern int smb2_rmdir(struct inode *inode, struct dentry *direntry);
+extern int smb2_unlink(struct inode *dir, struct dentry *dentry);
 
 /*
  *  SMB2 Worker functions - most of protocol specific implementation details
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux