From patchwork Wed Jul 18 15:48:19 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Shilovsky X-Patchwork-Id: 1211901 Return-Path: X-Original-To: patchwork-cifs-client@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 665E7E0079 for ; Wed, 18 Jul 2012 15:49:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751387Ab2GRPt5 (ORCPT ); Wed, 18 Jul 2012 11:49:57 -0400 Received: from mail-lb0-f174.google.com ([209.85.217.174]:57672 "EHLO mail-lb0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753703Ab2GRPt4 (ORCPT ); Wed, 18 Jul 2012 11:49:56 -0400 Received: by mail-lb0-f174.google.com with SMTP id gm6so2257593lbb.19 for ; Wed, 18 Jul 2012 08:49:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=wYSIOb84LKOrpUuGwzrBFUv3ErokATx40Y3hpuOp0Z0=; b=0c8PnuPFBhXDcZqC5N7cjisP0DDhyzyz3u4wbETeKuqpcZH5MfTJWqKzlfd4fSrz0f JdGD70fGi+o4wlfmzZrSV/k6kpvJ2HQGZpiWpZHRRlj4jWp7jviIYJuXLIq0axn+CuIN XwxrCeGFlb4WgXrHsXWxvo+xpbtAWomrkg/R07VrQUNy2qRARRNPQJq2YUMX1VR6a3t+ DS2Zfjq1QVWgTjqIsqzbzRjzp3ahkjVsXr7xMqpnRiTzTCUxuCuKEVYqhSmlSAYrvTJS ljGObD6oy8pHVTNJan1gwlQoMlSTIJMuLiTM6uiSOjrUB2ZLb7wwtfQ2v+ITp6dIBYMy 6UcQ== Received: by 10.112.99.98 with SMTP id ep2mr2127718lbb.45.1342626595332; Wed, 18 Jul 2012 08:49:55 -0700 (PDT) Received: from localhost.localdomain ([178.45.208.11]) by mx.google.com with ESMTPS id p2sm4826985lbj.4.2012.07.18.08.49.51 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 18 Jul 2012 08:49:52 -0700 (PDT) From: Pavel Shilovsky To: linux-cifs@vger.kernel.org Cc: Pavel Shilovsky Subject: [PATCH 03/45] CIFS: Separate protocol specific part from mkdir Date: Wed, 18 Jul 2012 19:48:19 +0400 Message-Id: <1342626541-29872-4-git-send-email-pshilovsky@samba.org> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1342626541-29872-1-git-send-email-pshilovsky@samba.org> References: <1342626541-29872-1-git-send-email-pshilovsky@samba.org> Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org From: Pavel Shilovsky Signed-off-by: Pavel Shilovsky Acked-by: Jeff Layton --- fs/cifs/cifsglob.h | 7 +++++++ fs/cifs/cifsproto.h | 4 +--- fs/cifs/cifssmb.c | 8 +++++--- fs/cifs/inode.c | 32 +++++++++++++------------------- fs/cifs/smb1ops.c | 23 +++++++++++++++++++++++ 5 files changed, 49 insertions(+), 25 deletions(-) diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 5695693..1ae7531 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -246,6 +246,13 @@ struct smb_version_operations { bool (*can_echo)(struct TCP_Server_Info *); /* send echo request */ int (*echo)(struct TCP_Server_Info *); + /* create directory */ + int (*mkdir)(const unsigned int, struct cifs_tcon *, const char *, + struct cifs_sb_info *); + /* set info on created directory */ + void (*mkdir_setinfo)(struct inode *, const char *, + struct cifs_sb_info *, struct cifs_tcon *, + const unsigned int); }; struct smb_version_values { diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 51fbdf2..7e02362 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -295,9 +295,7 @@ extern int CIFSSMBUnixSetPathInfo(const unsigned int xid, int remap); extern int CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, - const char *newName, - const struct nls_table *nls_codepage, - int remap_special_chars); + const char *name, struct cifs_sb_info *cifs_sb); extern int CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, const struct nls_table *nls_codepage, int remap_special_chars); diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index ed472aa..d49eedf 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -992,14 +992,15 @@ RmDirRetry: } int -CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, - const char *name, const struct nls_table *nls_codepage, int remap) +CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, + struct cifs_sb_info *cifs_sb) { int rc = 0; CREATE_DIRECTORY_REQ *pSMB = NULL; CREATE_DIRECTORY_RSP *pSMBr = NULL; int bytes_returned; int name_len; + int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR; cFYI(1, "In CIFSSMBMkDir"); MkDirRetry: @@ -1010,7 +1011,8 @@ MkDirRetry: if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name, - PATH_MAX, nls_codepage, remap); + PATH_MAX, cifs_sb->local_nls, + remap); name_len++; /* trailing null */ name_len *= 2; } else { /* BB improve check for buffer overruns BB */ diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index e9ba1a1..d7e74b1 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -1272,24 +1272,11 @@ cifs_mkdir_qinfo(struct inode *inode, struct dentry *dentry, umode_t mode, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); } else { + struct TCP_Server_Info *server = tcon->ses->server; if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && - (mode & S_IWUGO) == 0) { - FILE_BASIC_INFO info; - struct cifsInodeInfo *cifsInode; - u32 dosattrs; - int tmprc; - - memset(&info, 0, sizeof(info)); - cifsInode = CIFS_I(newinode); - dosattrs = cifsInode->cifsAttrs|ATTR_READONLY; - info.Attributes = cpu_to_le32(dosattrs); - tmprc = CIFSSMBSetPathInfo(xid, tcon, full_path, &info, - cifs_sb->local_nls, - cifs_sb->mnt_cifs_flags & - CIFS_MOUNT_MAP_SPECIAL_CHR); - if (tmprc == 0) - cifsInode->cifsAttrs = dosattrs; - } + (mode & S_IWUGO) == 0 && server->ops->mkdir_setinfo) + server->ops->mkdir_setinfo(newinode, full_path, cifs_sb, + tcon, xid); if (dentry->d_inode) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) dentry->d_inode->i_mode = (mode | S_IFDIR); @@ -1377,6 +1364,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode) struct cifs_sb_info *cifs_sb; struct tcon_link *tlink; struct cifs_tcon *tcon; + struct TCP_Server_Info *server; char *full_path; cFYI(1, "In cifs_mkdir, mode = 0x%hx inode = 0x%p", mode, inode); @@ -1403,9 +1391,15 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode) goto mkdir_out; } + server = tcon->ses->server; + + if (!server->ops->mkdir) { + rc = -ENOSYS; + goto mkdir_out; + } + /* BB add setting the equivalent of mode via CreateX w/ACLs */ - rc = CIFSSMBMkDir(xid, tcon, full_path, cifs_sb->local_nls, - cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); + rc = server->ops->mkdir(xid, tcon, full_path, cifs_sb); if (rc) { cFYI(1, "cifs_mkdir returned 0x%x", rc); d_drop(direntry); diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index c40356d..861e2df 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c @@ -586,6 +586,27 @@ cifs_print_stats(struct seq_file *m, struct cifs_tcon *tcon) #endif } +static void +cifs_mkdir_setinfo(struct inode *inode, const char *full_path, + struct cifs_sb_info *cifs_sb, struct cifs_tcon *tcon, + const unsigned int xid) +{ + FILE_BASIC_INFO info; + struct cifsInodeInfo *cifsInode; + u32 dosattrs; + int rc; + + memset(&info, 0, sizeof(info)); + cifsInode = CIFS_I(inode); + dosattrs = cifsInode->cifsAttrs|ATTR_READONLY; + info.Attributes = cpu_to_le32(dosattrs); + rc = CIFSSMBSetPathInfo(xid, tcon, full_path, &info, cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); + if (rc == 0) + cifsInode->cifsAttrs = dosattrs; +} + struct smb_version_operations smb1_operations = { .send_cancel = send_nt_cancel, .compare_fids = cifs_compare_fids, @@ -620,6 +641,8 @@ struct smb_version_operations smb1_operations = { .get_srv_inum = cifs_get_srv_inum, .build_path_to_root = cifs_build_path_to_root, .echo = CIFSSMBEcho, + .mkdir = CIFSSMBMkDir, + .mkdir_setinfo = cifs_mkdir_setinfo, }; struct smb_version_values smb1_values = {