From db8b631d4bc4eaa9f7e13a6b0a287306cac0cb72 Mon Sep 17 00:00:00 2001 From: Steve French Date: Mon, 22 Sep 2014 05:13:55 -0500 Subject: Allow mknod and mkfifo on SMB2/SMB3 mounts The "sfu" mount option did not work on SMB2/SMB3 mounts. With these changes when the "sfu" mount option is passed in on an smb2/smb2.1/smb3 mount the client can emulate (and recognize) fifo and device (character and device files). In addition the "sfu" mount option should not conflict with "mfsymlinks" (symlink emulation) as we will never create "sfu" style symlinks, but using "sfu" mount option will allow us to recognize existing symlinks, created with Microsoft "Services for Unix" (SFU and SUA). To enable the "sfu" mount option for SMB2/SMB3 the calling syntax of the generic cifs/smb2/smb3 sync_read and sync_write protocol dependent function needed to be changed (we don't have a file struct in all cases), but this actually ended up simplifying the code a little. Signed-off-by: Steve French --- fs/cifs/inode.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'fs/cifs/inode.c') diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 8fd4ee8e07ff..4ff36ea8c693 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -412,7 +412,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const char *path, struct cifs_sb_info *cifs_sb, unsigned int xid) { int rc; - int oplock = 0; + __u32 oplock; struct tcon_link *tlink; struct cifs_tcon *tcon; struct cifs_fid fid; @@ -451,8 +451,13 @@ cifs_sfu_type(struct cifs_fattr *fattr, const char *path, oparms.fid = &fid; oparms.reconnect = false; - rc = CIFS_open(xid, &oparms, &oplock, NULL); + if (tcon->ses->server->oplocks) + oplock = REQ_OPLOCK; + else + oplock = 0; + rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, NULL); if (rc) { + cifs_dbg(FYI, "check sfu type of %s, open rc = %d\n", path, rc); cifs_put_tlink(tlink); return rc; } @@ -464,7 +469,8 @@ cifs_sfu_type(struct cifs_fattr *fattr, const char *path, io_parms.offset = 0; io_parms.length = 24; - rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type); + rc = tcon->ses->server->ops->sync_read(xid, &fid, &io_parms, + &bytes_read, &pbuf, &buf_type); if ((rc == 0) && (bytes_read >= 8)) { if (memcmp("IntxBLK", pbuf, 8) == 0) { cifs_dbg(FYI, "Block device\n"); @@ -504,7 +510,8 @@ cifs_sfu_type(struct cifs_fattr *fattr, const char *path, fattr->cf_dtype = DT_REG; rc = -EOPNOTSUPP; /* or some unknown SFU type */ } - CIFSSMBClose(xid, tcon, fid.netfid); + + tcon->ses->server->ops->close(xid, tcon, &fid); cifs_put_tlink(tlink); return rc; } -- cgit v1.2.3