本文整理汇总了C++中CIFS_SB函数的典型用法代码示例。如果您正苦于以下问题:C++ CIFS_SB函数的具体用法?C++ CIFS_SB怎么用?C++ CIFS_SB使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了CIFS_SB函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: cifs_mknod
int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
dev_t device_number)
{
int rc = -EPERM;
int xid;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
char *full_path = NULL;
struct inode *newinode = NULL;
int oplock = 0;
u16 fileHandle;
FILE_ALL_INFO *buf = NULL;
unsigned int bytes_written;
struct win_dev *pdev;
if (!old_valid_dev(device_number))
return -EINVAL;
xid = GetXid();
cifs_sb = CIFS_SB(inode->i_sb);
pTcon = cifs_sb->tcon;
full_path = build_path_from_dentry(direntry);
if (full_path == NULL) {
rc = -ENOMEM;
goto mknod_out;
}
if (pTcon->unix_ext) {
struct cifs_unix_set_info_args args = {
.mode = mode & ~current_umask(),
.ctime = NO_CHANGE_64,
.atime = NO_CHANGE_64,
.mtime = NO_CHANGE_64,
.device = device_number,
};
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
args.uid = (__u64) current_fsuid();
args.gid = (__u64) current_fsgid();
} else {
args.uid = NO_CHANGE_64;
args.gid = NO_CHANGE_64;
}
rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args,
cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
if (rc)
goto mknod_out;
rc = cifs_get_inode_info_unix(&newinode, full_path,
inode->i_sb, xid);
if (pTcon->nocase)
direntry->d_op = &cifs_ci_dentry_ops;
else
direntry->d_op = &cifs_dentry_ops;
if (rc == 0)
d_instantiate(direntry, newinode);
goto mknod_out;
}
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL))
goto mknod_out;
cFYI(1, "sfu compat create special file");
buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
if (buf == NULL) {
kfree(full_path);
rc = -ENOMEM;
FreeXid(xid);
return rc;
}
rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_CREATE,
GENERIC_WRITE, CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
&fileHandle, &oplock, buf, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
if (rc)
goto mknod_out;
/* BB Do not bother to decode buf since no local inode yet to put
* timestamps in, but we can reuse it safely */
pdev = (struct win_dev *)buf;
if (S_ISCHR(mode)) {
memcpy(pdev->type, "IntxCHR", 8);
pdev->major =
cpu_to_le64(MAJOR(device_number));
pdev->minor =
cpu_to_le64(MINOR(device_number));
rc = CIFSSMBWrite(xid, pTcon,
fileHandle,
sizeof(struct win_dev),
0, &bytes_written, (char *)pdev,
NULL, 0);
} else if (S_ISBLK(mode)) {
//.........这里部分代码省略.........
示例2: cifs_kill_sb
static void cifs_kill_sb(struct super_block *sb)
{
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
kill_anon_super(sb);
cifs_umount(cifs_sb);
}
示例3: cifs_read_super
static int
cifs_read_super(struct super_block *sb, void *data,
const char *devname, int silent)
{
struct inode *inode;
struct cifs_sb_info *cifs_sb;
int rc = 0;
sb->s_flags |= MS_NODIRATIME; /* and probably even noatime */
sb->s_fs_info = kmalloc(sizeof(struct cifs_sb_info),GFP_KERNEL);
cifs_sb = CIFS_SB(sb);
if(cifs_sb == NULL)
return -ENOMEM;
else
memset(cifs_sb,0,sizeof(struct cifs_sb_info));
rc = cifs_mount(sb, cifs_sb, data, devname);
if (rc) {
if (!silent)
cERROR(1,
("cifs_mount failed w/return code = %d", rc));
goto out_mount_failed;
}
sb->s_magic = CIFS_MAGIC_NUMBER;
sb->s_op = &cifs_super_ops;
/* if(cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
sb->s_blocksize = cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
#ifdef CONFIG_CIFS_QUOTA
sb->s_qcop = &cifs_quotactl_ops;
#endif
sb->s_blocksize = CIFS_MAX_MSGSIZE;
sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */
inode = iget(sb, ROOT_I);
if (!inode) {
rc = -ENOMEM;
goto out_no_root;
}
sb->s_root = d_alloc_root(inode);
if (!sb->s_root) {
rc = -ENOMEM;
goto out_no_root;
}
return 0;
out_no_root:
cERROR(1, ("cifs_read_super: get root inode failed"));
if (inode)
iput(inode);
out_mount_failed:
if(cifs_sb) {
if(cifs_sb->local_nls)
unload_nls(cifs_sb->local_nls);
kfree(cifs_sb);
}
return rc;
}
示例4: initiate_cifs_search
static int initiate_cifs_search(const int xid, struct file *file)
{
int rc = 0;
char *full_path = NULL;
struct cifsFileInfo *cifsFile;
struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
struct tcon_link *tlink = NULL;
struct cifs_tcon *pTcon;
if (file->private_data == NULL) {
tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink))
return PTR_ERR(tlink);
cifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
if (cifsFile == NULL) {
rc = -ENOMEM;
goto error_exit;
}
file->private_data = cifsFile;
cifsFile->tlink = cifs_get_tlink(tlink);
pTcon = tlink_tcon(tlink);
} else {
cifsFile = file->private_data;
pTcon = tlink_tcon(cifsFile->tlink);
}
cifsFile->invalidHandle = true;
cifsFile->srch_inf.endOfSearch = false;
full_path = build_path_from_dentry(file->f_path.dentry);
if (full_path == NULL) {
rc = -ENOMEM;
goto error_exit;
}
cFYI(1, "Full path: %s start at: %lld", full_path, file->f_pos);
ffirst_retry:
/* test for Unix extensions */
/* but now check for them on the share/mount not on the SMB session */
/* if (pTcon->ses->capabilities & CAP_UNIX) { */
if (pTcon->unix_ext)
cifsFile->srch_inf.info_level = SMB_FIND_FILE_UNIX;
else if ((pTcon->ses->capabilities &
(CAP_NT_SMBS | CAP_NT_FIND)) == 0) {
cifsFile->srch_inf.info_level = SMB_FIND_FILE_INFO_STANDARD;
} else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
cifsFile->srch_inf.info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO;
} else /* not srvinos - BB fixme add check for backlevel? */ {
cifsFile->srch_inf.info_level = SMB_FIND_FILE_DIRECTORY_INFO;
}
rc = CIFSFindFirst(xid, pTcon, full_path, cifs_sb->local_nls,
&cifsFile->netfid, &cifsFile->srch_inf,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb));
if (rc == 0)
cifsFile->invalidHandle = false;
/* BB add following call to handle readdir on new NTFS symlink errors
else if STATUS_STOPPED_ON_SYMLINK
call get_symlink_reparse_path and retry with new path */
else if ((rc == -EOPNOTSUPP) &&
(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
goto ffirst_retry;
}
error_exit:
kfree(full_path);
cifs_put_tlink(tlink);
return rc;
}
示例5: cifs_read_super
static int
cifs_read_super(struct super_block *sb, void *data,
const char *devname, int silent)
{
struct inode *inode;
struct cifs_sb_info *cifs_sb;
int rc = 0;
/* BB should we make this contingent on mount parm? */
sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL);
cifs_sb = CIFS_SB(sb);
if (cifs_sb == NULL)
return -ENOMEM;
#ifdef CONFIG_CIFS_DFS_UPCALL
/* copy mount params to sb for use in submounts */
/* BB: should we move this after the mount so we
* do not have to do the copy on failed mounts?
* BB: May be it is better to do simple copy before
* complex operation (mount), and in case of fail
* just exit instead of doing mount and attempting
* undo it if this copy fails?*/
if (data) {
int len = strlen(data);
cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL);
if (cifs_sb->mountdata == NULL) {
kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
return -ENOMEM;
}
strncpy(cifs_sb->mountdata, data, len + 1);
cifs_sb->mountdata[len] = '\0';
}
#endif
rc = cifs_mount(sb, cifs_sb, data, devname);
if (rc) {
if (!silent)
cERROR(1,
("cifs_mount failed w/return code = %d", rc));
goto out_mount_failed;
}
sb->s_magic = CIFS_MAGIC_NUMBER;
sb->s_op = &cifs_super_ops;
/* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
sb->s_blocksize =
cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
#ifdef CONFIG_CIFS_QUOTA
sb->s_qcop = &cifs_quotactl_ops;
#endif
sb->s_blocksize = CIFS_MAX_MSGSIZE;
sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */
inode = cifs_root_iget(sb, ROOT_I);
if (IS_ERR(inode)) {
rc = PTR_ERR(inode);
inode = NULL;
goto out_no_root;
}
sb->s_root = d_alloc_root(inode);
if (!sb->s_root) {
rc = -ENOMEM;
goto out_no_root;
}
#ifdef CONFIG_CIFS_EXPERIMENTAL
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
cFYI(1, ("export ops supported"));
sb->s_export_op = &cifs_export_ops;
}
#endif /* EXPERIMENTAL */
return 0;
out_no_root:
cERROR(1, ("cifs_read_super: get root inode failed"));
if (inode)
iput(inode);
cifs_umount(sb, cifs_sb);
out_mount_failed:
if (cifs_sb) {
#ifdef CONFIG_CIFS_DFS_UPCALL
if (cifs_sb->mountdata) {
kfree(cifs_sb->mountdata);
cifs_sb->mountdata = NULL;
}
#endif
if (cifs_sb->local_nls)
unload_nls(cifs_sb->local_nls);
kfree(cifs_sb);
}
return rc;
}
示例6: cifs_xattr_get
static int cifs_xattr_get(const struct xattr_handler *handler,
struct dentry *dentry, struct inode *inode,
const char *name, void *value, size_t size)
{
ssize_t rc = -EOPNOTSUPP;
unsigned int xid;
struct super_block *sb = dentry->d_sb;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct tcon_link *tlink;
struct cifs_tcon *pTcon;
char *full_path;
tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink))
return PTR_ERR(tlink);
pTcon = tlink_tcon(tlink);
xid = get_xid();
full_path = build_path_from_dentry(dentry);
if (full_path == NULL) {
rc = -ENOMEM;
goto out;
}
/* return alt name if available as pseudo attr */
switch (handler->flags) {
case XATTR_USER:
cifs_dbg(FYI, "%s:querying user xattr %s\n", __func__, name);
if (strcmp(name, CIFS_XATTR_ATTRIB) == 0) {
rc = cifs_attrib_get(dentry, inode, value, size);
break;
} else if (strcmp(name, CIFS_XATTR_CREATETIME) == 0) {
rc = cifs_creation_time_get(dentry, inode, value, size);
break;
}
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
goto out;
if (pTcon->ses->server->ops->query_all_EAs)
rc = pTcon->ses->server->ops->query_all_EAs(xid, pTcon,
full_path, name, value, size, cifs_sb);
break;
case XATTR_CIFS_ACL: {
#ifdef CONFIG_CIFS_ACL
u32 acllen;
struct cifs_ntsd *pacl;
if (pTcon->ses->server->ops->get_acl == NULL)
goto out; /* rc already EOPNOTSUPP */
pacl = pTcon->ses->server->ops->get_acl(cifs_sb,
inode, full_path, &acllen);
if (IS_ERR(pacl)) {
rc = PTR_ERR(pacl);
cifs_dbg(VFS, "%s: error %zd getting sec desc\n",
__func__, rc);
} else {
if (value) {
if (acllen > size)
acllen = -ERANGE;
else
memcpy(value, pacl, acllen);
}
rc = acllen;
kfree(pacl);
}
#endif /* CONFIG_CIFS_ACL */
break;
}
case XATTR_ACL_ACCESS:
#ifdef CONFIG_CIFS_POSIX
if (sb->s_flags & SB_POSIXACL)
rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
value, size, ACL_TYPE_ACCESS,
cifs_sb->local_nls,
cifs_remap(cifs_sb));
#endif /* CONFIG_CIFS_POSIX */
break;
case XATTR_ACL_DEFAULT:
#ifdef CONFIG_CIFS_POSIX
if (sb->s_flags & SB_POSIXACL)
rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
value, size, ACL_TYPE_DEFAULT,
cifs_sb->local_nls,
cifs_remap(cifs_sb));
#endif /* CONFIG_CIFS_POSIX */
break;
}
/* We could add an additional check for streams ie
if proc/fs/cifs/streamstoxattr is set then
search server for EAs or streams to
returns as xattrs */
if (rc == -EINVAL)
//.........这里部分代码省略.........
示例7: cifs_symlink
int
cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
{
int rc = -EOPNOTSUPP;
int xid;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink;
struct cifs_tcon *pTcon;
char *full_path = NULL;
struct inode *newinode = NULL;
xid = GetXid();
tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink)) {
rc = PTR_ERR(tlink);
goto symlink_exit;
}
pTcon = tlink_tcon(tlink);
full_path = build_path_from_dentry(direntry);
if (full_path == NULL) {
rc = -ENOMEM;
goto symlink_exit;
}
cFYI(1, "Full path: %s", full_path);
cFYI(1, "symname is %s", symname);
/* BB what if DFS and this volume is on different share? BB */
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
rc = CIFSCreateMFSymLink(xid, pTcon, full_path, symname,
cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
else if (pTcon->unix_ext)
rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,
cifs_sb->local_nls);
/* else
rc = CIFSCreateReparseSymLink(xid, pTcon, fromName, toName,
cifs_sb_target->local_nls); */
if (rc == 0) {
if (pTcon->unix_ext)
rc = cifs_get_inode_info_unix(&newinode, full_path,
inode->i_sb, xid);
else
rc = cifs_get_inode_info(&newinode, full_path, NULL,
inode->i_sb, xid, NULL);
if (rc != 0) {
cFYI(1, "Create symlink ok, getinodeinfo fail rc = %d",
rc);
} else {
d_instantiate(direntry, newinode);
}
}
symlink_exit:
kfree(full_path);
cifs_put_tlink(tlink);
FreeXid(xid);
return rc;
}
示例8: cifs_show_options
/*
* cifs_show_options() is for displaying mount options in /proc/mounts.
* Not all settable options are displayed but most of the important
* ones are.
*/
static int
cifs_show_options(struct seq_file *s, struct vfsmount *m)
{
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *tcon;
cifs_sb = CIFS_SB(m->mnt_sb);
tcon = cifs_sb->tcon;
seq_printf(s, ",unc=%s", cifs_sb->tcon->treeName);
if (tcon->ses->userName)
seq_printf(s, ",username=%s", tcon->ses->userName);
if (tcon->ses->domainName)
seq_printf(s, ",domain=%s", tcon->ses->domainName);
seq_printf(s, ",uid=%d", cifs_sb->mnt_uid);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
seq_printf(s, ",forceuid");
seq_printf(s, ",gid=%d", cifs_sb->mnt_gid);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
seq_printf(s, ",forcegid");
cifs_show_address(s, tcon->ses->server);
if (!tcon->unix_ext)
seq_printf(s, ",file_mode=0%o,dir_mode=0%o",
cifs_sb->mnt_file_mode,
cifs_sb->mnt_dir_mode);
if (tcon->seal)
seq_printf(s, ",seal");
if (tcon->nocase)
seq_printf(s, ",nocase");
if (tcon->retry)
seq_printf(s, ",hard");
if (cifs_sb->prepath)
seq_printf(s, ",prepath=%s", cifs_sb->prepath);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
seq_printf(s, ",posixpaths");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)
seq_printf(s, ",setuids");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
seq_printf(s, ",serverino");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
seq_printf(s, ",directio");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
seq_printf(s, ",nouser_xattr");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
seq_printf(s, ",mapchars");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
seq_printf(s, ",sfu");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
seq_printf(s, ",nobrl");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
seq_printf(s, ",cifsacl");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
seq_printf(s, ",dynperm");
if (m->mnt_sb->s_flags & MS_POSIXACL)
seq_printf(s, ",acl");
seq_printf(s, ",rsize=%d", cifs_sb->rsize);
seq_printf(s, ",wsize=%d", cifs_sb->wsize);
return 0;
}
示例9: cifs_follow_link
void *
cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
{
struct inode *inode = direntry->d_inode;
int rc = -ENOMEM;
int xid;
char *full_path = NULL;
char *target_path = NULL;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink = NULL;
struct cifs_tcon *tcon;
xid = GetXid();
tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink)) {
rc = PTR_ERR(tlink);
tlink = NULL;
goto out;
}
tcon = tlink_tcon(tlink);
/*
* For now, we just handle symlinks with unix extensions enabled.
* Eventually we should handle NTFS reparse points, and MacOS
* symlink support. For instance...
*
* rc = CIFSSMBQueryReparseLinkInfo(...)
*
* For now, just return -EACCES when the server doesn't support posix
* extensions. Note that we still allow querying symlinks when posix
* extensions are manually disabled. We could disable these as well
* but there doesn't seem to be any harm in allowing the client to
* read them.
*/
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
&& !(tcon->ses->capabilities & CAP_UNIX)) {
rc = -EACCES;
goto out;
}
full_path = build_path_from_dentry(direntry);
if (!full_path)
goto out;
cFYI(1, "Full path: %s inode = 0x%p", full_path, inode);
rc = -EACCES;
/*
* First try Minshall+French Symlinks, if configured
* and fallback to UNIX Extensions Symlinks.
*/
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
rc = CIFSQueryMFSymLink(xid, tcon, full_path, &target_path,
cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
if ((rc != 0) && (tcon->ses->capabilities & CAP_UNIX))
rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path,
cifs_sb->local_nls);
kfree(full_path);
out:
if (rc != 0) {
kfree(target_path);
target_path = ERR_PTR(rc);
}
FreeXid(xid);
if (tlink)
cifs_put_tlink(tlink);
nd_set_link(nd, target_path);
return NULL;
}
示例10: cifs_hardlink
int
cifs_hardlink(struct dentry *old_file, struct inode *inode,
struct dentry *direntry)
{
int rc = -EACCES;
int xid;
char *fromName = NULL;
char *toName = NULL;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink;
struct cifs_tcon *pTcon;
struct cifsInodeInfo *cifsInode;
tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink))
return PTR_ERR(tlink);
pTcon = tlink_tcon(tlink);
xid = GetXid();
fromName = build_path_from_dentry(old_file);
toName = build_path_from_dentry(direntry);
if ((fromName == NULL) || (toName == NULL)) {
rc = -ENOMEM;
goto cifs_hl_exit;
}
if (pTcon->unix_ext)
rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName,
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);
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 (old_file->d_inode) {
cifsInode = CIFS_I(old_file->d_inode);
if (rc == 0) {
old_file->d_inode->i_nlink++;
/* 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? */
}
/* 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; */
}
cifs_hl_exit:
kfree(fromName);
kfree(toName);
FreeXid(xid);
cifs_put_tlink(tlink);
return rc;
}
示例11: cifs_lookup
struct dentry *
cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
struct nameidata *nd)
{
int xid;
int rc = 0; /* to get around spurious gcc warning, set to zero here */
__u32 oplock = 0;
__u16 fileHandle = 0;
bool posix_open = false;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
struct cifsFileInfo *cfile;
struct inode *newInode = NULL;
char *full_path = NULL;
struct file *filp;
xid = GetXid();
cFYI(1, "parent inode = 0x%p name is: %s and dentry = 0x%p",
parent_dir_inode, direntry->d_name.name, direntry);
/* check whether path exists */
cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
pTcon = cifs_sb->tcon;
/*
* Don't allow the separator character in a path component.
* The VFS will not allow "/", but "\" is allowed by posix.
*/
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
int i;
for (i = 0; i < direntry->d_name.len; i++)
if (direntry->d_name.name[i] == '\\') {
cFYI(1, "Invalid file name");
FreeXid(xid);
return ERR_PTR(-EINVAL);
}
}
/*
* O_EXCL: optimize away the lookup, but don't hash the dentry. Let
* the VFS handle the create.
*/
if (nd && (nd->flags & LOOKUP_EXCL)) {
d_instantiate(direntry, NULL);
return NULL;
}
/* can not grab the rename sem here since it would
deadlock in the cases (beginning of sys_rename itself)
in which we already have the sb rename sem */
full_path = build_path_from_dentry(direntry);
if (full_path == NULL) {
FreeXid(xid);
return ERR_PTR(-ENOMEM);
}
if (direntry->d_inode != NULL) {
cFYI(1, "non-NULL inode in lookup");
} else {
cFYI(1, "NULL inode in lookup");
}
cFYI(1, "Full path: %s inode = 0x%p", full_path, direntry->d_inode);
/* Posix open is only called (at lookup time) for file create now.
* For opens (rather than creates), because we do not know if it
* is a file or directory yet, and current Samba no longer allows
* us to do posix open on dirs, we could end up wasting an open call
* on what turns out to be a dir. For file opens, we wait to call posix
* open till cifs_open. It could be added here (lookup) in the future
* but the performance tradeoff of the extra network request when EISDIR
* or EACCES is returned would have to be weighed against the 50%
* reduction in network traffic in the other paths.
*/
if (pTcon->unix_ext) {
if (nd && !(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) &&
(nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
(nd->intent.open.flags & O_CREAT)) {
rc = cifs_posix_open(full_path, &newInode,
parent_dir_inode->i_sb,
nd->intent.open.create_mode,
nd->intent.open.flags, &oplock,
&fileHandle, xid);
/*
* The check below works around a bug in POSIX
* open in samba versions 3.3.1 and earlier where
* open could incorrectly fail with invalid parameter.
* If either that or op not supported returned, follow
* the normal lookup.
*/
if ((rc == 0) || (rc == -ENOENT))
posix_open = true;
else if ((rc == -EINVAL) || (rc != -EOPNOTSUPP))
pTcon->broken_posix_open = true;
}
if (!posix_open)
rc = cifs_get_inode_info_unix(&newInode, full_path,
parent_dir_inode->i_sb, xid);
} else
//.........这里部分代码省略.........
示例12: cifs_setxattr
int cifs_setxattr(struct dentry * direntry, const char * ea_name,
const void * ea_value, size_t value_size, int flags)
{
int rc = -EOPNOTSUPP;
#ifdef CONFIG_CIFS_XATTR
int xid;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
struct super_block * sb;
char * full_path;
if(direntry == NULL)
return -EIO;
if(direntry->d_inode == NULL)
return -EIO;
sb = direntry->d_inode->i_sb;
if(sb == NULL)
return -EIO;
xid = GetXid();
cifs_sb = CIFS_SB(sb);
pTcon = cifs_sb->tcon;
down(&sb->s_vfs_rename_sem);
full_path = build_path_from_dentry(direntry);
up(&sb->s_vfs_rename_sem);
if(full_path == NULL) {
FreeXid(xid);
return -ENOMEM;
}
/* return dos attributes as pseudo xattr */
/* return alt name if available as pseudo attr */
/* if proc/fs/cifs/streamstoxattr is set then
search server for EAs or streams to
returns as xattrs */
if(value_size > MAX_EA_VALUE_SIZE) {
cFYI(1,("size of EA value too large"));
kfree(full_path);
FreeXid(xid);
return -EOPNOTSUPP;
}
if(ea_name == NULL) {
cFYI(1,("Null xattr names not supported"));
} else if(strncmp(ea_name,CIFS_XATTR_USER_PREFIX,5) == 0) {
if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
goto set_ea_exit;
if(strncmp(ea_name,CIFS_XATTR_DOS_ATTRIB,14) == 0) {
cFYI(1,("attempt to set cifs inode metadata"));
}
ea_name += 5; /* skip past user. prefix */
rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,ea_value,
(__u16)value_size, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
} else if(strncmp(ea_name, CIFS_XATTR_OS2_PREFIX,4) == 0) {
if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
goto set_ea_exit;
ea_name += 4; /* skip past os2. prefix */
rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,ea_value,
(__u16)value_size, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
} else {
int temp;
temp = strncmp(ea_name,POSIX_ACL_XATTR_ACCESS,
strlen(POSIX_ACL_XATTR_ACCESS));
if (temp == 0) {
#ifdef CONFIG_CIFS_POSIX
if(sb->s_flags & MS_POSIXACL)
rc = CIFSSMBSetPosixACL(xid, pTcon,full_path,
ea_value, (const int)value_size,
ACL_TYPE_ACCESS,cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
cFYI(1,("set POSIX ACL rc %d",rc));
#else
cFYI(1,("set POSIX ACL not supported"));
#endif
} else if(strncmp(ea_name,POSIX_ACL_XATTR_DEFAULT,strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
#ifdef CONFIG_CIFS_POSIX
if(sb->s_flags & MS_POSIXACL)
rc = CIFSSMBSetPosixACL(xid, pTcon,full_path,
ea_value, (const int)value_size,
ACL_TYPE_DEFAULT, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
cFYI(1,("set POSIX default ACL rc %d",rc));
#else
cFYI(1,("set default POSIX ACL not supported"));
#endif
} else {
cFYI(1,("illegal xattr request %s (only user namespace supported)",ea_name));
/* BB what if no namespace prefix? */
/* Should we just pass them to server, except for
system and perhaps security prefixes? */
}
}
set_ea_exit:
//.........这里部分代码省略.........
示例13: cifs_xattr_set
static int cifs_xattr_set(const struct xattr_handler *handler,
struct dentry *dentry, struct inode *inode,
const char *name, const void *value,
size_t size, int flags)
{
int rc = -EOPNOTSUPP;
unsigned int xid;
struct super_block *sb = dentry->d_sb;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct tcon_link *tlink;
struct cifs_tcon *pTcon;
char *full_path;
tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink))
return PTR_ERR(tlink);
pTcon = tlink_tcon(tlink);
xid = get_xid();
full_path = build_path_from_dentry(dentry);
if (full_path == NULL) {
rc = -ENOMEM;
goto out;
}
/* return dos attributes as pseudo xattr */
/* return alt name if available as pseudo attr */
/* if proc/fs/cifs/streamstoxattr is set then
search server for EAs or streams to
returns as xattrs */
if (size > MAX_EA_VALUE_SIZE) {
cifs_dbg(FYI, "size of EA value too large\n");
rc = -EOPNOTSUPP;
goto out;
}
switch (handler->flags) {
case XATTR_USER:
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
goto out;
if (pTcon->ses->server->ops->set_EA)
rc = pTcon->ses->server->ops->set_EA(xid, pTcon,
full_path, name, value, (__u16)size,
cifs_sb->local_nls, cifs_sb);
break;
case XATTR_CIFS_ACL: {
#ifdef CONFIG_CIFS_ACL
struct cifs_ntsd *pacl;
if (!value)
goto out;
pacl = kmalloc(size, GFP_KERNEL);
if (!pacl) {
rc = -ENOMEM;
} else {
memcpy(pacl, value, size);
if (value &&
pTcon->ses->server->ops->set_acl)
rc = pTcon->ses->server->ops->set_acl(pacl,
size, inode,
full_path, CIFS_ACL_DACL);
else
rc = -EOPNOTSUPP;
if (rc == 0) /* force revalidate of the inode */
CIFS_I(inode)->time = 0;
kfree(pacl);
}
#endif /* CONFIG_CIFS_ACL */
break;
}
case XATTR_ACL_ACCESS:
#ifdef CONFIG_CIFS_POSIX
if (!value)
goto out;
if (sb->s_flags & SB_POSIXACL)
rc = CIFSSMBSetPosixACL(xid, pTcon, full_path,
value, (const int)size,
ACL_TYPE_ACCESS, cifs_sb->local_nls,
cifs_remap(cifs_sb));
#endif /* CONFIG_CIFS_POSIX */
break;
case XATTR_ACL_DEFAULT:
#ifdef CONFIG_CIFS_POSIX
if (!value)
goto out;
if (sb->s_flags & SB_POSIXACL)
rc = CIFSSMBSetPosixACL(xid, pTcon, full_path,
value, (const int)size,
ACL_TYPE_DEFAULT, cifs_sb->local_nls,
cifs_remap(cifs_sb));
#endif /* CONFIG_CIFS_POSIX */
break;
}
out:
//.........这里部分代码省略.........
示例14: cifs_filldir
static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir,
void *direntry, char *scratch_buf, unsigned int max_len)
{
int rc = 0;
struct qstr qstring;
struct cifsFileInfo *pCifsF;
u64 inum;
ino_t ino;
struct super_block *sb;
struct cifs_sb_info *cifs_sb;
struct dentry *tmp_dentry;
struct cifs_fattr fattr;
/* get filename and len into qstring */
/* get dentry */
/* decide whether to create and populate ionde */
if ((direntry == NULL) || (file == NULL))
return -EINVAL;
pCifsF = file->private_data;
if ((scratch_buf == NULL) || (pfindEntry == NULL) || (pCifsF == NULL))
return -ENOENT;
rc = cifs_entry_is_dot(pfindEntry, pCifsF);
/* skip . and .. since we added them first */
if (rc != 0)
return 0;
sb = file->f_path.dentry->d_sb;
cifs_sb = CIFS_SB(sb);
qstring.name = scratch_buf;
rc = cifs_get_name_from_search_buf(&qstring, pfindEntry,
pCifsF->srch_inf.info_level,
pCifsF->srch_inf.unicode, cifs_sb,
max_len, &inum /* returned */);
if (rc)
return rc;
if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX)
cifs_unix_basic_to_fattr(&fattr,
&((FILE_UNIX_INFO *) pfindEntry)->basic,
cifs_sb);
else if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD)
cifs_std_info_to_fattr(&fattr, (FIND_FILE_STANDARD_INFO *)
pfindEntry, cifs_sb);
else
cifs_dir_info_to_fattr(&fattr, (FILE_DIRECTORY_INFO *)
pfindEntry, cifs_sb);
if (inum && (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
fattr.cf_uniqueid = inum;
} else {
fattr.cf_uniqueid = iunique(sb, ROOT_I);
cifs_autodisable_serverino(cifs_sb);
}
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) &&
CIFSCouldBeMFSymlink(&fattr))
/*
* trying to get the type and mode can be slow,
* so just call those regular files for now, and mark
* for reval
*/
fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid);
tmp_dentry = cifs_readdir_lookup(file->f_dentry, &qstring, &fattr);
rc = filldir(direntry, qstring.name, qstring.len, file->f_pos,
ino, fattr.cf_dtype);
dput(tmp_dentry);
return rc;
}
示例15: cifs_ioctl
int cifs_ioctl (struct inode * inode, struct file * filep,
unsigned int command, unsigned long arg)
{
int rc = -ENOTTY; /* strange error - but the precedent */
int xid;
struct cifs_sb_info *cifs_sb;
#ifdef CONFIG_CIFS_POSIX
__u64 ExtAttrBits = 0;
__u64 ExtAttrMask = 0;
__u64 caps;
struct cifsTconInfo *tcon;
struct cifsFileInfo *pSMBFile =
(struct cifsFileInfo *)filep->private_data;
#endif /* CONFIG_CIFS_POSIX */
xid = GetXid();
cFYI(1,("ioctl file %p cmd %u arg %lu",filep,command,arg));
cifs_sb = CIFS_SB(inode->i_sb);
#ifdef CONFIG_CIFS_POSIX
tcon = cifs_sb->tcon;
if(tcon)
caps = le64_to_cpu(tcon->fsUnixInfo.Capability);
else {
rc = -EIO;
FreeXid(xid);
return -EIO;
}
#endif /* CONFIG_CIFS_POSIX */
switch(command) {
case CIFS_IOC_CHECKUMOUNT:
cFYI(1,("User unmount attempted"));
if(cifs_sb->mnt_uid == current->uid)
rc = 0;
else {
rc = -EACCES;
cFYI(1,("uids do not match"));
}
break;
#ifdef CONFIG_CIFS_POSIX
case FS_IOC_GETFLAGS:
if(CIFS_UNIX_EXTATTR_CAP & caps) {
if (pSMBFile == NULL)
break;
rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid,
&ExtAttrBits, &ExtAttrMask);
if(rc == 0)
rc = put_user(ExtAttrBits &
FS_FL_USER_VISIBLE,
(int __user *)arg);
}
break;
case FS_IOC_SETFLAGS:
if(CIFS_UNIX_EXTATTR_CAP & caps) {
if(get_user(ExtAttrBits,(int __user *)arg)) {
rc = -EFAULT;
break;
}
if (pSMBFile == NULL)
break;
/* rc= CIFSGetExtAttr(xid,tcon,pSMBFile->netfid,
extAttrBits, &ExtAttrMask);*/
}
cFYI(1,("set flags not implemented yet"));
break;
#endif /* CONFIG_CIFS_POSIX */
default:
cFYI(1,("unsupported ioctl"));
break;
}
FreeXid(xid);
return rc;
}