CIFS: Move hardlink to ops struct
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org> Signed-off-by: Steve French <sfrench@us.ibm.com> Signed-off-by: Steve French <smfrench@gmail.com>
This commit is contained in:
parent
35143eb5c2
commit
d6e906f1b5
|
@ -278,6 +278,10 @@ struct smb_version_operations {
|
||||||
/* send rename request */
|
/* send rename request */
|
||||||
int (*rename)(const unsigned int, struct cifs_tcon *, const char *,
|
int (*rename)(const unsigned int, struct cifs_tcon *, const char *,
|
||||||
const char *, struct cifs_sb_info *);
|
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 */
|
/* open a file for non-posix mounts */
|
||||||
int (*open)(const unsigned int, struct cifs_tcon *, const char *, int,
|
int (*open)(const unsigned int, struct cifs_tcon *, const char *, int,
|
||||||
int, int, struct cifs_fid *, __u32 *, FILE_ALL_INFO *,
|
int, int, struct cifs_fid *, __u32 *, FILE_ALL_INFO *,
|
||||||
|
|
|
@ -316,11 +316,9 @@ extern int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *tcon,
|
||||||
int netfid, const char *target_name,
|
int netfid, const char *target_name,
|
||||||
const struct nls_table *nls_codepage,
|
const struct nls_table *nls_codepage,
|
||||||
int remap_special_chars);
|
int remap_special_chars);
|
||||||
extern int CIFSCreateHardLink(const unsigned int xid,
|
extern int CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
|
||||||
struct cifs_tcon *tcon,
|
const char *from_name, const char *to_name,
|
||||||
const char *fromName, const char *toName,
|
struct cifs_sb_info *cifs_sb);
|
||||||
const struct nls_table *nls_codepage,
|
|
||||||
int remap_special_chars);
|
|
||||||
extern int CIFSUnixCreateHardLink(const unsigned int xid,
|
extern int CIFSUnixCreateHardLink(const unsigned int xid,
|
||||||
struct cifs_tcon *tcon,
|
struct cifs_tcon *tcon,
|
||||||
const char *fromName, const char *toName,
|
const char *fromName, const char *toName,
|
||||||
|
|
|
@ -2924,8 +2924,8 @@ createHardLinkRetry:
|
||||||
|
|
||||||
int
|
int
|
||||||
CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
|
CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
|
||||||
const char *fromName, const char *toName,
|
const char *from_name, const char *to_name,
|
||||||
const struct nls_table *nls_codepage, int remap)
|
struct cifs_sb_info *cifs_sb)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
NT_RENAME_REQ *pSMB = NULL;
|
NT_RENAME_REQ *pSMB = NULL;
|
||||||
|
@ -2933,6 +2933,7 @@ CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
|
||||||
int bytes_returned;
|
int bytes_returned;
|
||||||
int name_len, name_len2;
|
int name_len, name_len2;
|
||||||
__u16 count;
|
__u16 count;
|
||||||
|
int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
|
||||||
|
|
||||||
cFYI(1, "In CIFSCreateHardLink");
|
cFYI(1, "In CIFSCreateHardLink");
|
||||||
winCreateHardLinkRetry:
|
winCreateHardLinkRetry:
|
||||||
|
@ -2952,8 +2953,8 @@ winCreateHardLinkRetry:
|
||||||
|
|
||||||
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
|
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
|
||||||
name_len =
|
name_len =
|
||||||
cifsConvertToUTF16((__le16 *) pSMB->OldFileName, fromName,
|
cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name,
|
||||||
PATH_MAX, nls_codepage, remap);
|
PATH_MAX, cifs_sb->local_nls, remap);
|
||||||
name_len++; /* trailing null */
|
name_len++; /* trailing null */
|
||||||
name_len *= 2;
|
name_len *= 2;
|
||||||
|
|
||||||
|
@ -2962,17 +2963,18 @@ winCreateHardLinkRetry:
|
||||||
pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
|
pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
|
||||||
name_len2 =
|
name_len2 =
|
||||||
cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
|
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 += 1 /* trailing null */ + 1 /* Signature word */ ;
|
||||||
name_len2 *= 2; /* convert to bytes */
|
name_len2 *= 2; /* convert to bytes */
|
||||||
} else { /* BB improve the check for buffer overruns BB */
|
} 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 */
|
name_len++; /* trailing null */
|
||||||
strncpy(pSMB->OldFileName, fromName, name_len);
|
strncpy(pSMB->OldFileName, from_name, name_len);
|
||||||
name_len2 = strnlen(toName, PATH_MAX);
|
name_len2 = strnlen(to_name, PATH_MAX);
|
||||||
name_len2++; /* trailing null */
|
name_len2++; /* trailing null */
|
||||||
pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
|
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++; /* trailing null */
|
||||||
name_len2++; /* signature byte */
|
name_len2++; /* signature byte */
|
||||||
}
|
}
|
||||||
|
|
|
@ -391,72 +391,86 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
|
||||||
{
|
{
|
||||||
int rc = -EACCES;
|
int rc = -EACCES;
|
||||||
unsigned int xid;
|
unsigned int xid;
|
||||||
char *fromName = NULL;
|
char *from_name = NULL;
|
||||||
char *toName = NULL;
|
char *to_name = NULL;
|
||||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||||
struct tcon_link *tlink;
|
struct tcon_link *tlink;
|
||||||
struct cifs_tcon *pTcon;
|
struct cifs_tcon *tcon;
|
||||||
|
struct TCP_Server_Info *server;
|
||||||
struct cifsInodeInfo *cifsInode;
|
struct cifsInodeInfo *cifsInode;
|
||||||
|
|
||||||
tlink = cifs_sb_tlink(cifs_sb);
|
tlink = cifs_sb_tlink(cifs_sb);
|
||||||
if (IS_ERR(tlink))
|
if (IS_ERR(tlink))
|
||||||
return PTR_ERR(tlink);
|
return PTR_ERR(tlink);
|
||||||
pTcon = tlink_tcon(tlink);
|
tcon = tlink_tcon(tlink);
|
||||||
|
|
||||||
xid = get_xid();
|
xid = get_xid();
|
||||||
|
|
||||||
fromName = build_path_from_dentry(old_file);
|
from_name = build_path_from_dentry(old_file);
|
||||||
toName = build_path_from_dentry(direntry);
|
to_name = build_path_from_dentry(direntry);
|
||||||
if ((fromName == NULL) || (toName == NULL)) {
|
if ((from_name == NULL) || (to_name == NULL)) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto cifs_hl_exit;
|
goto cifs_hl_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pTcon->unix_ext)
|
if (tcon->unix_ext)
|
||||||
rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName,
|
rc = CIFSUnixCreateHardLink(xid, tcon, from_name, to_name,
|
||||||
cifs_sb->local_nls,
|
cifs_sb->local_nls,
|
||||||
cifs_sb->mnt_cifs_flags &
|
cifs_sb->mnt_cifs_flags &
|
||||||
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||||
else {
|
else {
|
||||||
rc = CIFSCreateHardLink(xid, pTcon, fromName, toName,
|
server = tcon->ses->server;
|
||||||
cifs_sb->local_nls,
|
if (!server->ops->create_hardlink)
|
||||||
cifs_sb->mnt_cifs_flags &
|
return -ENOSYS;
|
||||||
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
rc = server->ops->create_hardlink(xid, tcon, from_name, to_name,
|
||||||
|
cifs_sb);
|
||||||
if ((rc == -EIO) || (rc == -EINVAL))
|
if ((rc == -EIO) || (rc == -EINVAL))
|
||||||
rc = -EOPNOTSUPP;
|
rc = -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
d_drop(direntry); /* force new lookup from server of target */
|
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) {
|
if (old_file->d_inode) {
|
||||||
cifsInode = CIFS_I(old_file->d_inode);
|
cifsInode = CIFS_I(old_file->d_inode);
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
spin_lock(&old_file->d_inode->i_lock);
|
spin_lock(&old_file->d_inode->i_lock);
|
||||||
inc_nlink(old_file->d_inode);
|
inc_nlink(old_file->d_inode);
|
||||||
spin_unlock(&old_file->d_inode->i_lock);
|
spin_unlock(&old_file->d_inode->i_lock);
|
||||||
/* BB should we make this contingent on superblock flag NOATIME? */
|
/*
|
||||||
/* old_file->d_inode->i_ctime = CURRENT_TIME;*/
|
* BB should we make this contingent on superblock flag
|
||||||
/* parent dir timestamps will update from srv
|
* NOATIME?
|
||||||
within a second, would it really be worth it
|
*/
|
||||||
to set the parent dir cifs inode time to zero
|
/* old_file->d_inode->i_ctime = CURRENT_TIME; */
|
||||||
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;
|
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
|
* Will update parent dir timestamps from srv within a second.
|
||||||
inode) time field to zero to force revalidate on parent
|
* Would it really be worth it to set the parent dir (cifs
|
||||||
directory faster ie
|
* inode) time field to zero to force revalidate on parent
|
||||||
CIFS_I(inode)->time = 0; */
|
* directory faster ie
|
||||||
|
*
|
||||||
|
* CIFS_I(inode)->time = 0;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
cifs_hl_exit:
|
cifs_hl_exit:
|
||||||
kfree(fromName);
|
kfree(from_name);
|
||||||
kfree(toName);
|
kfree(to_name);
|
||||||
free_xid(xid);
|
free_xid(xid);
|
||||||
cifs_put_tlink(tlink);
|
cifs_put_tlink(tlink);
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
@ -801,6 +801,7 @@ struct smb_version_operations smb1_operations = {
|
||||||
.unlink = CIFSSMBDelFile,
|
.unlink = CIFSSMBDelFile,
|
||||||
.rename_pending_delete = cifs_rename_pending_delete,
|
.rename_pending_delete = cifs_rename_pending_delete,
|
||||||
.rename = CIFSSMBRename,
|
.rename = CIFSSMBRename,
|
||||||
|
.create_hardlink = CIFSCreateHardLink,
|
||||||
.open = cifs_open_file,
|
.open = cifs_open_file,
|
||||||
.set_fid = cifs_set_fid,
|
.set_fid = cifs_set_fid,
|
||||||
.close = cifs_close_file,
|
.close = cifs_close_file,
|
||||||
|
|
Loading…
Reference in New Issue