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:
Steve French 2012-09-18 16:20:31 -07:00
parent 35143eb5c2
commit d6e906f1b5
5 changed files with 63 additions and 44 deletions

View File

@ -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 *,

View File

@ -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,

View File

@ -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 */
} }

View File

@ -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;

View File

@ -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,