Loading fs/cifs/cifsglob.h +4 −0 Original line number Diff line number Diff line Loading @@ -278,6 +278,10 @@ struct smb_version_operations { /* send rename request */ int (*rename)(const unsigned int, struct cifs_tcon *, const char *, const char *, struct cifs_sb_info *); /* send create hardlink request */ int (*create_hardlink)(const unsigned int, struct cifs_tcon *, const char *, const char *, struct cifs_sb_info *); /* open a file for non-posix mounts */ int (*open)(const unsigned int, struct cifs_tcon *, const char *, int, int, int, struct cifs_fid *, __u32 *, FILE_ALL_INFO *, Loading fs/cifs/cifsproto.h +3 −5 Original line number Diff line number Diff line Loading @@ -316,11 +316,9 @@ extern int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *tcon, int netfid, const char *target_name, const struct nls_table *nls_codepage, int remap_special_chars); extern int CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon, const char *fromName, const char *toName, const struct nls_table *nls_codepage, int remap_special_chars); extern int CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon, const char *from_name, const char *to_name, struct cifs_sb_info *cifs_sb); extern int CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon, const char *fromName, const char *toName, Loading fs/cifs/cifssmb.c +11 −9 Original line number Diff line number Diff line Loading @@ -2924,8 +2924,8 @@ CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon, int CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon, const char *fromName, const char *toName, const struct nls_table *nls_codepage, int remap) const char *from_name, const char *to_name, struct cifs_sb_info *cifs_sb) { int rc = 0; NT_RENAME_REQ *pSMB = NULL; Loading @@ -2933,6 +2933,7 @@ CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon, int bytes_returned; int name_len, name_len2; __u16 count; int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR; cFYI(1, "In CIFSCreateHardLink"); winCreateHardLinkRetry: Loading @@ -2952,8 +2953,8 @@ CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon, if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName, fromName, PATH_MAX, nls_codepage, remap); cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name, PATH_MAX, cifs_sb->local_nls, remap); name_len++; /* trailing null */ name_len *= 2; Loading @@ -2962,17 +2963,18 @@ CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon, pSMB->OldFileName[name_len + 1] = 0x00; /* pad */ name_len2 = cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2], toName, PATH_MAX, nls_codepage, remap); to_name, PATH_MAX, cifs_sb->local_nls, remap); name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; name_len2 *= 2; /* convert to bytes */ } else { /* BB improve the check for buffer overruns BB */ name_len = strnlen(fromName, PATH_MAX); name_len = strnlen(from_name, PATH_MAX); name_len++; /* trailing null */ strncpy(pSMB->OldFileName, fromName, name_len); name_len2 = strnlen(toName, PATH_MAX); strncpy(pSMB->OldFileName, from_name, name_len); name_len2 = strnlen(to_name, PATH_MAX); name_len2++; /* trailing null */ pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */ strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2); strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2); name_len2++; /* trailing null */ name_len2++; /* signature byte */ } Loading fs/cifs/link.c +44 −30 Original line number Diff line number Diff line Loading @@ -391,72 +391,86 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode, { int rc = -EACCES; unsigned int xid; char *fromName = NULL; char *toName = NULL; char *from_name = NULL; char *to_name = NULL; struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct tcon_link *tlink; struct cifs_tcon *pTcon; struct cifs_tcon *tcon; struct TCP_Server_Info *server; struct cifsInodeInfo *cifsInode; tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); pTcon = tlink_tcon(tlink); tcon = tlink_tcon(tlink); xid = get_xid(); fromName = build_path_from_dentry(old_file); toName = build_path_from_dentry(direntry); if ((fromName == NULL) || (toName == NULL)) { from_name = build_path_from_dentry(old_file); to_name = build_path_from_dentry(direntry); if ((from_name == NULL) || (to_name == NULL)) { rc = -ENOMEM; goto cifs_hl_exit; } if (pTcon->unix_ext) rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName, if (tcon->unix_ext) rc = CIFSUnixCreateHardLink(xid, tcon, from_name, to_name, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); else { rc = CIFSCreateHardLink(xid, pTcon, fromName, toName, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); server = tcon->ses->server; if (!server->ops->create_hardlink) return -ENOSYS; rc = server->ops->create_hardlink(xid, tcon, from_name, to_name, cifs_sb); if ((rc == -EIO) || (rc == -EINVAL)) rc = -EOPNOTSUPP; } d_drop(direntry); /* force new lookup from server of target */ /* if source file is cached (oplocked) revalidate will not go to server until the file is closed or oplock broken so update nlinks locally */ /* * if source file is cached (oplocked) revalidate will not go to server * until the file is closed or oplock broken so update nlinks locally */ if (old_file->d_inode) { cifsInode = CIFS_I(old_file->d_inode); if (rc == 0) { spin_lock(&old_file->d_inode->i_lock); inc_nlink(old_file->d_inode); spin_unlock(&old_file->d_inode->i_lock); /* BB should we make this contingent on superblock flag NOATIME? */ /* * BB should we make this contingent on superblock flag * NOATIME? */ /* old_file->d_inode->i_ctime = CURRENT_TIME; */ /* parent dir timestamps will update from srv within a second, would it really be worth it to set the parent dir cifs inode time to zero to force revalidate (faster) for it too? */ /* * parent dir timestamps will update from srv within a * second, would it really be worth it to set the parent * dir cifs inode time to zero to force revalidate * (faster) for it too? */ } /* if not oplocked will force revalidate to get info on source file from srv */ /* * if not oplocked will force revalidate to get info on source * file from srv */ cifsInode->time = 0; /* Will update parent dir timestamps from srv within a second. Would it really be worth it to set the parent dir (cifs inode) time field to zero to force revalidate on parent directory faster ie CIFS_I(inode)->time = 0; */ /* * Will update parent dir timestamps from srv within a second. * Would it really be worth it to set the parent dir (cifs * inode) time field to zero to force revalidate on parent * directory faster ie * * CIFS_I(inode)->time = 0; */ } cifs_hl_exit: kfree(fromName); kfree(toName); kfree(from_name); kfree(to_name); free_xid(xid); cifs_put_tlink(tlink); return rc; Loading fs/cifs/smb1ops.c +1 −0 Original line number Diff line number Diff line Loading @@ -801,6 +801,7 @@ struct smb_version_operations smb1_operations = { .unlink = CIFSSMBDelFile, .rename_pending_delete = cifs_rename_pending_delete, .rename = CIFSSMBRename, .create_hardlink = CIFSCreateHardLink, .open = cifs_open_file, .set_fid = cifs_set_fid, .close = cifs_close_file, Loading Loading
fs/cifs/cifsglob.h +4 −0 Original line number Diff line number Diff line Loading @@ -278,6 +278,10 @@ struct smb_version_operations { /* send rename request */ int (*rename)(const unsigned int, struct cifs_tcon *, const char *, const char *, struct cifs_sb_info *); /* send create hardlink request */ int (*create_hardlink)(const unsigned int, struct cifs_tcon *, const char *, const char *, struct cifs_sb_info *); /* open a file for non-posix mounts */ int (*open)(const unsigned int, struct cifs_tcon *, const char *, int, int, int, struct cifs_fid *, __u32 *, FILE_ALL_INFO *, Loading
fs/cifs/cifsproto.h +3 −5 Original line number Diff line number Diff line Loading @@ -316,11 +316,9 @@ extern int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *tcon, int netfid, const char *target_name, const struct nls_table *nls_codepage, int remap_special_chars); extern int CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon, const char *fromName, const char *toName, const struct nls_table *nls_codepage, int remap_special_chars); extern int CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon, const char *from_name, const char *to_name, struct cifs_sb_info *cifs_sb); extern int CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon, const char *fromName, const char *toName, Loading
fs/cifs/cifssmb.c +11 −9 Original line number Diff line number Diff line Loading @@ -2924,8 +2924,8 @@ CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon, int CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon, const char *fromName, const char *toName, const struct nls_table *nls_codepage, int remap) const char *from_name, const char *to_name, struct cifs_sb_info *cifs_sb) { int rc = 0; NT_RENAME_REQ *pSMB = NULL; Loading @@ -2933,6 +2933,7 @@ CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon, int bytes_returned; int name_len, name_len2; __u16 count; int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR; cFYI(1, "In CIFSCreateHardLink"); winCreateHardLinkRetry: Loading @@ -2952,8 +2953,8 @@ CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon, if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName, fromName, PATH_MAX, nls_codepage, remap); cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name, PATH_MAX, cifs_sb->local_nls, remap); name_len++; /* trailing null */ name_len *= 2; Loading @@ -2962,17 +2963,18 @@ CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon, pSMB->OldFileName[name_len + 1] = 0x00; /* pad */ name_len2 = cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2], toName, PATH_MAX, nls_codepage, remap); to_name, PATH_MAX, cifs_sb->local_nls, remap); name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; name_len2 *= 2; /* convert to bytes */ } else { /* BB improve the check for buffer overruns BB */ name_len = strnlen(fromName, PATH_MAX); name_len = strnlen(from_name, PATH_MAX); name_len++; /* trailing null */ strncpy(pSMB->OldFileName, fromName, name_len); name_len2 = strnlen(toName, PATH_MAX); strncpy(pSMB->OldFileName, from_name, name_len); name_len2 = strnlen(to_name, PATH_MAX); name_len2++; /* trailing null */ pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */ strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2); strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2); name_len2++; /* trailing null */ name_len2++; /* signature byte */ } Loading
fs/cifs/link.c +44 −30 Original line number Diff line number Diff line Loading @@ -391,72 +391,86 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode, { int rc = -EACCES; unsigned int xid; char *fromName = NULL; char *toName = NULL; char *from_name = NULL; char *to_name = NULL; struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct tcon_link *tlink; struct cifs_tcon *pTcon; struct cifs_tcon *tcon; struct TCP_Server_Info *server; struct cifsInodeInfo *cifsInode; tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); pTcon = tlink_tcon(tlink); tcon = tlink_tcon(tlink); xid = get_xid(); fromName = build_path_from_dentry(old_file); toName = build_path_from_dentry(direntry); if ((fromName == NULL) || (toName == NULL)) { from_name = build_path_from_dentry(old_file); to_name = build_path_from_dentry(direntry); if ((from_name == NULL) || (to_name == NULL)) { rc = -ENOMEM; goto cifs_hl_exit; } if (pTcon->unix_ext) rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName, if (tcon->unix_ext) rc = CIFSUnixCreateHardLink(xid, tcon, from_name, to_name, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); else { rc = CIFSCreateHardLink(xid, pTcon, fromName, toName, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); server = tcon->ses->server; if (!server->ops->create_hardlink) return -ENOSYS; rc = server->ops->create_hardlink(xid, tcon, from_name, to_name, cifs_sb); if ((rc == -EIO) || (rc == -EINVAL)) rc = -EOPNOTSUPP; } d_drop(direntry); /* force new lookup from server of target */ /* if source file is cached (oplocked) revalidate will not go to server until the file is closed or oplock broken so update nlinks locally */ /* * if source file is cached (oplocked) revalidate will not go to server * until the file is closed or oplock broken so update nlinks locally */ if (old_file->d_inode) { cifsInode = CIFS_I(old_file->d_inode); if (rc == 0) { spin_lock(&old_file->d_inode->i_lock); inc_nlink(old_file->d_inode); spin_unlock(&old_file->d_inode->i_lock); /* BB should we make this contingent on superblock flag NOATIME? */ /* * BB should we make this contingent on superblock flag * NOATIME? */ /* old_file->d_inode->i_ctime = CURRENT_TIME; */ /* parent dir timestamps will update from srv within a second, would it really be worth it to set the parent dir cifs inode time to zero to force revalidate (faster) for it too? */ /* * parent dir timestamps will update from srv within a * second, would it really be worth it to set the parent * dir cifs inode time to zero to force revalidate * (faster) for it too? */ } /* if not oplocked will force revalidate to get info on source file from srv */ /* * if not oplocked will force revalidate to get info on source * file from srv */ cifsInode->time = 0; /* Will update parent dir timestamps from srv within a second. Would it really be worth it to set the parent dir (cifs inode) time field to zero to force revalidate on parent directory faster ie CIFS_I(inode)->time = 0; */ /* * Will update parent dir timestamps from srv within a second. * Would it really be worth it to set the parent dir (cifs * inode) time field to zero to force revalidate on parent * directory faster ie * * CIFS_I(inode)->time = 0; */ } cifs_hl_exit: kfree(fromName); kfree(toName); kfree(from_name); kfree(to_name); free_xid(xid); cifs_put_tlink(tlink); return rc; Loading
fs/cifs/smb1ops.c +1 −0 Original line number Diff line number Diff line Loading @@ -801,6 +801,7 @@ struct smb_version_operations smb1_operations = { .unlink = CIFSSMBDelFile, .rename_pending_delete = cifs_rename_pending_delete, .rename = CIFSSMBRename, .create_hardlink = CIFSCreateHardLink, .open = cifs_open_file, .set_fid = cifs_set_fid, .close = cifs_close_file, Loading