Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6: [CIFS] don't allow demultiplex thread to exit until kthread_stop is called [CIFS] when not using unix extensions, check for and set ATTR_READONLY on create and mkdir [CIFS] add local struct inode pointer to cifs_setattr [CIFS] cifs_find_tcp_session cleanup
This commit is contained in:
commit
542dafadd8
|
@ -340,6 +340,7 @@
|
||||||
#define OPEN_NO_RECALL 0x00400000
|
#define OPEN_NO_RECALL 0x00400000
|
||||||
#define OPEN_FREE_SPACE_QUERY 0x00800000 /* should be zero */
|
#define OPEN_FREE_SPACE_QUERY 0x00800000 /* should be zero */
|
||||||
#define CREATE_OPTIONS_MASK 0x007FFFFF
|
#define CREATE_OPTIONS_MASK 0x007FFFFF
|
||||||
|
#define CREATE_OPTION_READONLY 0x10000000
|
||||||
#define CREATE_OPTION_SPECIAL 0x20000000 /* system. NB not sent over wire */
|
#define CREATE_OPTION_SPECIAL 0x20000000 /* system. NB not sent over wire */
|
||||||
|
|
||||||
/* ImpersonationLevel flags */
|
/* ImpersonationLevel flags */
|
||||||
|
|
|
@ -1224,11 +1224,8 @@ OldOpenRetry:
|
||||||
else /* BB FIXME BB */
|
else /* BB FIXME BB */
|
||||||
pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
|
pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
|
||||||
|
|
||||||
/* if ((omode & S_IWUGO) == 0)
|
if (create_options & CREATE_OPTION_READONLY)
|
||||||
pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/
|
pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
|
||||||
/* Above line causes problems due to vfs splitting create into two
|
|
||||||
pieces - need to set mode after file created not while it is
|
|
||||||
being created */
|
|
||||||
|
|
||||||
/* BB FIXME BB */
|
/* BB FIXME BB */
|
||||||
/* pSMB->CreateOptions = cpu_to_le32(create_options &
|
/* pSMB->CreateOptions = cpu_to_le32(create_options &
|
||||||
|
@ -1331,17 +1328,16 @@ openRetry:
|
||||||
pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
|
pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
|
||||||
else
|
else
|
||||||
pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);
|
pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);
|
||||||
|
|
||||||
/* XP does not handle ATTR_POSIX_SEMANTICS */
|
/* XP does not handle ATTR_POSIX_SEMANTICS */
|
||||||
/* but it helps speed up case sensitive checks for other
|
/* but it helps speed up case sensitive checks for other
|
||||||
servers such as Samba */
|
servers such as Samba */
|
||||||
if (tcon->ses->capabilities & CAP_UNIX)
|
if (tcon->ses->capabilities & CAP_UNIX)
|
||||||
pSMB->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
|
pSMB->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
|
||||||
|
|
||||||
/* if ((omode & S_IWUGO) == 0)
|
if (create_options & CREATE_OPTION_READONLY)
|
||||||
pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/
|
pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);
|
||||||
/* Above line causes problems due to vfs splitting create into two
|
|
||||||
pieces - need to set mode after file created not while it is
|
|
||||||
being created */
|
|
||||||
pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
|
pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
|
||||||
pSMB->CreateDisposition = cpu_to_le32(openDisposition);
|
pSMB->CreateDisposition = cpu_to_le32(openDisposition);
|
||||||
pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
|
pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
|
||||||
|
|
|
@ -348,7 +348,6 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
|
||||||
int reconnect;
|
int reconnect;
|
||||||
|
|
||||||
current->flags |= PF_MEMALLOC;
|
current->flags |= PF_MEMALLOC;
|
||||||
server->tsk = current; /* save process info to wake at shutdown */
|
|
||||||
cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current)));
|
cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current)));
|
||||||
write_lock(&GlobalSMBSeslock);
|
write_lock(&GlobalSMBSeslock);
|
||||||
atomic_inc(&tcpSesAllocCount);
|
atomic_inc(&tcpSesAllocCount);
|
||||||
|
@ -651,10 +650,20 @@ multi_t2_fnd:
|
||||||
|
|
||||||
spin_lock(&GlobalMid_Lock);
|
spin_lock(&GlobalMid_Lock);
|
||||||
server->tcpStatus = CifsExiting;
|
server->tcpStatus = CifsExiting;
|
||||||
server->tsk = NULL;
|
spin_unlock(&GlobalMid_Lock);
|
||||||
|
|
||||||
|
/* don't exit until kthread_stop is called */
|
||||||
|
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||||
|
while (!kthread_should_stop()) {
|
||||||
|
schedule();
|
||||||
|
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||||
|
}
|
||||||
|
set_current_state(TASK_RUNNING);
|
||||||
|
|
||||||
/* check if we have blocked requests that need to free */
|
/* check if we have blocked requests that need to free */
|
||||||
/* Note that cifs_max_pending is normally 50, but
|
/* Note that cifs_max_pending is normally 50, but
|
||||||
can be set at module install time to as little as two */
|
can be set at module install time to as little as two */
|
||||||
|
spin_lock(&GlobalMid_Lock);
|
||||||
if (atomic_read(&server->inFlight) >= cifs_max_pending)
|
if (atomic_read(&server->inFlight) >= cifs_max_pending)
|
||||||
atomic_set(&server->inFlight, cifs_max_pending - 1);
|
atomic_set(&server->inFlight, cifs_max_pending - 1);
|
||||||
/* We do not want to set the max_pending too low or we
|
/* We do not want to set the max_pending too low or we
|
||||||
|
@ -1318,42 +1327,43 @@ cifs_parse_mount_options(char *options, const char *devname,
|
||||||
|
|
||||||
static struct cifsSesInfo *
|
static struct cifsSesInfo *
|
||||||
cifs_find_tcp_session(struct in_addr *target_ip_addr,
|
cifs_find_tcp_session(struct in_addr *target_ip_addr,
|
||||||
struct in6_addr *target_ip6_addr,
|
struct in6_addr *target_ip6_addr,
|
||||||
char *userName, struct TCP_Server_Info **psrvTcp)
|
char *userName, struct TCP_Server_Info **psrvTcp)
|
||||||
{
|
{
|
||||||
struct list_head *tmp;
|
struct list_head *tmp;
|
||||||
struct cifsSesInfo *ses;
|
struct cifsSesInfo *ses;
|
||||||
*psrvTcp = NULL;
|
|
||||||
read_lock(&GlobalSMBSeslock);
|
|
||||||
|
|
||||||
|
*psrvTcp = NULL;
|
||||||
|
|
||||||
|
read_lock(&GlobalSMBSeslock);
|
||||||
list_for_each(tmp, &GlobalSMBSessionList) {
|
list_for_each(tmp, &GlobalSMBSessionList) {
|
||||||
ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
|
ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
|
||||||
if (ses->server) {
|
if (!ses->server)
|
||||||
if ((target_ip_addr &&
|
continue;
|
||||||
(ses->server->addr.sockAddr.sin_addr.s_addr
|
|
||||||
== target_ip_addr->s_addr)) || (target_ip6_addr
|
|
||||||
&& memcmp(&ses->server->addr.sockAddr6.sin6_addr,
|
|
||||||
target_ip6_addr, sizeof(*target_ip6_addr)))) {
|
|
||||||
/* BB lock server and tcp session and increment
|
|
||||||
use count here?? */
|
|
||||||
|
|
||||||
/* found a match on the TCP session */
|
if (target_ip_addr &&
|
||||||
*psrvTcp = ses->server;
|
ses->server->addr.sockAddr.sin_addr.s_addr != target_ip_addr->s_addr)
|
||||||
|
continue;
|
||||||
|
else if (target_ip6_addr &&
|
||||||
|
memcmp(&ses->server->addr.sockAddr6.sin6_addr,
|
||||||
|
target_ip6_addr, sizeof(*target_ip6_addr)))
|
||||||
|
continue;
|
||||||
|
/* BB lock server and tcp session; increment use count here?? */
|
||||||
|
|
||||||
/* BB check if reconnection needed */
|
/* found a match on the TCP session */
|
||||||
if (strncmp
|
*psrvTcp = ses->server;
|
||||||
(ses->userName, userName,
|
|
||||||
MAX_USERNAME_SIZE) == 0){
|
/* BB check if reconnection needed */
|
||||||
read_unlock(&GlobalSMBSeslock);
|
if (strncmp(ses->userName, userName, MAX_USERNAME_SIZE) == 0) {
|
||||||
/* Found exact match on both TCP and
|
read_unlock(&GlobalSMBSeslock);
|
||||||
SMB sessions */
|
/* Found exact match on both TCP and
|
||||||
return ses;
|
SMB sessions */
|
||||||
}
|
return ses;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* else tcp and smb sessions need reconnection */
|
/* else tcp and smb sessions need reconnection */
|
||||||
}
|
}
|
||||||
read_unlock(&GlobalSMBSeslock);
|
read_unlock(&GlobalSMBSeslock);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2186,15 +2196,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
|
||||||
srvTcp->tcpStatus = CifsExiting;
|
srvTcp->tcpStatus = CifsExiting;
|
||||||
spin_unlock(&GlobalMid_Lock);
|
spin_unlock(&GlobalMid_Lock);
|
||||||
if (srvTcp->tsk) {
|
if (srvTcp->tsk) {
|
||||||
struct task_struct *tsk;
|
|
||||||
/* If we could verify that kthread_stop would
|
/* If we could verify that kthread_stop would
|
||||||
always wake up processes blocked in
|
always wake up processes blocked in
|
||||||
tcp in recv_mesg then we could remove the
|
tcp in recv_mesg then we could remove the
|
||||||
send_sig call */
|
send_sig call */
|
||||||
force_sig(SIGKILL, srvTcp->tsk);
|
force_sig(SIGKILL, srvTcp->tsk);
|
||||||
tsk = srvTcp->tsk;
|
kthread_stop(srvTcp->tsk);
|
||||||
if (tsk)
|
|
||||||
kthread_stop(tsk);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* If find_unc succeeded then rc == 0 so we can not end */
|
/* If find_unc succeeded then rc == 0 so we can not end */
|
||||||
|
@ -2210,23 +2217,17 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
|
||||||
if ((temp_rc == -ESHUTDOWN) &&
|
if ((temp_rc == -ESHUTDOWN) &&
|
||||||
(pSesInfo->server) &&
|
(pSesInfo->server) &&
|
||||||
(pSesInfo->server->tsk)) {
|
(pSesInfo->server->tsk)) {
|
||||||
struct task_struct *tsk;
|
|
||||||
force_sig(SIGKILL,
|
force_sig(SIGKILL,
|
||||||
pSesInfo->server->tsk);
|
pSesInfo->server->tsk);
|
||||||
tsk = pSesInfo->server->tsk;
|
kthread_stop(pSesInfo->server->tsk);
|
||||||
if (tsk)
|
|
||||||
kthread_stop(tsk);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cFYI(1, ("No session or bad tcon"));
|
cFYI(1, ("No session or bad tcon"));
|
||||||
if ((pSesInfo->server) &&
|
if ((pSesInfo->server) &&
|
||||||
(pSesInfo->server->tsk)) {
|
(pSesInfo->server->tsk)) {
|
||||||
struct task_struct *tsk;
|
|
||||||
force_sig(SIGKILL,
|
force_sig(SIGKILL,
|
||||||
pSesInfo->server->tsk);
|
pSesInfo->server->tsk);
|
||||||
tsk = pSesInfo->server->tsk;
|
kthread_stop(pSesInfo->server->tsk);
|
||||||
if (tsk)
|
|
||||||
kthread_stop(tsk);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sesInfoFree(pSesInfo);
|
sesInfoFree(pSesInfo);
|
||||||
|
|
|
@ -119,6 +119,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
|
||||||
{
|
{
|
||||||
int rc = -ENOENT;
|
int rc = -ENOENT;
|
||||||
int xid;
|
int xid;
|
||||||
|
int create_options = CREATE_NOT_DIR;
|
||||||
int oplock = 0;
|
int oplock = 0;
|
||||||
int desiredAccess = GENERIC_READ | GENERIC_WRITE;
|
int desiredAccess = GENERIC_READ | GENERIC_WRITE;
|
||||||
__u16 fileHandle;
|
__u16 fileHandle;
|
||||||
|
@ -176,9 +177,19 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
|
||||||
FreeXid(xid);
|
FreeXid(xid);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mode &= ~current->fs->umask;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if we're not using unix extensions, see if we need to set
|
||||||
|
* ATTR_READONLY on the create call
|
||||||
|
*/
|
||||||
|
if (!pTcon->unix_ext && (mode & S_IWUGO) == 0)
|
||||||
|
create_options |= CREATE_OPTION_READONLY;
|
||||||
|
|
||||||
if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS)
|
if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS)
|
||||||
rc = CIFSSMBOpen(xid, pTcon, full_path, disposition,
|
rc = CIFSSMBOpen(xid, pTcon, full_path, disposition,
|
||||||
desiredAccess, CREATE_NOT_DIR,
|
desiredAccess, create_options,
|
||||||
&fileHandle, &oplock, buf, cifs_sb->local_nls,
|
&fileHandle, &oplock, buf, cifs_sb->local_nls,
|
||||||
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
|
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||||
else
|
else
|
||||||
|
@ -187,7 +198,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
|
||||||
if (rc == -EIO) {
|
if (rc == -EIO) {
|
||||||
/* old server, retry the open legacy style */
|
/* old server, retry the open legacy style */
|
||||||
rc = SMBLegacyOpen(xid, pTcon, full_path, disposition,
|
rc = SMBLegacyOpen(xid, pTcon, full_path, disposition,
|
||||||
desiredAccess, CREATE_NOT_DIR,
|
desiredAccess, create_options,
|
||||||
&fileHandle, &oplock, buf, cifs_sb->local_nls,
|
&fileHandle, &oplock, buf, cifs_sb->local_nls,
|
||||||
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
|
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||||
}
|
}
|
||||||
|
@ -197,7 +208,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
|
||||||
/* If Open reported that we actually created a file
|
/* If Open reported that we actually created a file
|
||||||
then we now have to set the mode if possible */
|
then we now have to set the mode if possible */
|
||||||
if ((pTcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) {
|
if ((pTcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) {
|
||||||
mode &= ~current->fs->umask;
|
|
||||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
|
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
|
||||||
CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
|
CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
|
||||||
(__u64)current->fsuid,
|
(__u64)current->fsuid,
|
||||||
|
|
|
@ -974,8 +974,8 @@ mkdir_get_info:
|
||||||
* failed to get it from the server or was set bogus */
|
* failed to get it from the server or was set bogus */
|
||||||
if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
|
if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
|
||||||
direntry->d_inode->i_nlink = 2;
|
direntry->d_inode->i_nlink = 2;
|
||||||
|
mode &= ~current->fs->umask;
|
||||||
if (pTcon->unix_ext) {
|
if (pTcon->unix_ext) {
|
||||||
mode &= ~current->fs->umask;
|
|
||||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
|
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
|
||||||
CIFSSMBUnixSetPerms(xid, pTcon, full_path,
|
CIFSSMBUnixSetPerms(xid, pTcon, full_path,
|
||||||
mode,
|
mode,
|
||||||
|
@ -994,9 +994,16 @@ mkdir_get_info:
|
||||||
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* BB to be implemented via Windows secrty descriptors
|
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
|
||||||
eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
|
(mode & S_IWUGO) == 0) {
|
||||||
-1, -1, local_nls); */
|
FILE_BASIC_INFO pInfo;
|
||||||
|
memset(&pInfo, 0, sizeof(pInfo));
|
||||||
|
pInfo.Attributes = cpu_to_le32(ATTR_READONLY);
|
||||||
|
CIFSSMBSetTimes(xid, pTcon, full_path,
|
||||||
|
&pInfo, cifs_sb->local_nls,
|
||||||
|
cifs_sb->mnt_cifs_flags &
|
||||||
|
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||||
|
}
|
||||||
if (direntry->d_inode) {
|
if (direntry->d_inode) {
|
||||||
direntry->d_inode->i_mode = mode;
|
direntry->d_inode->i_mode = mode;
|
||||||
direntry->d_inode->i_mode |= S_IFDIR;
|
direntry->d_inode->i_mode |= S_IFDIR;
|
||||||
|
@ -1408,18 +1415,19 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
|
||||||
__u64 uid = 0xFFFFFFFFFFFFFFFFULL;
|
__u64 uid = 0xFFFFFFFFFFFFFFFFULL;
|
||||||
__u64 gid = 0xFFFFFFFFFFFFFFFFULL;
|
__u64 gid = 0xFFFFFFFFFFFFFFFFULL;
|
||||||
struct cifsInodeInfo *cifsInode;
|
struct cifsInodeInfo *cifsInode;
|
||||||
|
struct inode *inode = direntry->d_inode;
|
||||||
|
|
||||||
xid = GetXid();
|
xid = GetXid();
|
||||||
|
|
||||||
cFYI(1, ("setattr on file %s attrs->iavalid 0x%x",
|
cFYI(1, ("setattr on file %s attrs->iavalid 0x%x",
|
||||||
direntry->d_name.name, attrs->ia_valid));
|
direntry->d_name.name, attrs->ia_valid));
|
||||||
|
|
||||||
cifs_sb = CIFS_SB(direntry->d_inode->i_sb);
|
cifs_sb = CIFS_SB(inode->i_sb);
|
||||||
pTcon = cifs_sb->tcon;
|
pTcon = cifs_sb->tcon;
|
||||||
|
|
||||||
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
|
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
|
||||||
/* check if we have permission to change attrs */
|
/* check if we have permission to change attrs */
|
||||||
rc = inode_change_ok(direntry->d_inode, attrs);
|
rc = inode_change_ok(inode, attrs);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
FreeXid(xid);
|
FreeXid(xid);
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -1432,7 +1440,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
|
||||||
FreeXid(xid);
|
FreeXid(xid);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
cifsInode = CIFS_I(direntry->d_inode);
|
cifsInode = CIFS_I(inode);
|
||||||
|
|
||||||
if ((attrs->ia_valid & ATTR_MTIME) || (attrs->ia_valid & ATTR_SIZE)) {
|
if ((attrs->ia_valid & ATTR_MTIME) || (attrs->ia_valid & ATTR_SIZE)) {
|
||||||
/*
|
/*
|
||||||
|
@ -1443,9 +1451,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
|
||||||
will be truncated anyway? Also, should we error out here if
|
will be truncated anyway? Also, should we error out here if
|
||||||
the flush returns error?
|
the flush returns error?
|
||||||
*/
|
*/
|
||||||
rc = filemap_write_and_wait(direntry->d_inode->i_mapping);
|
rc = filemap_write_and_wait(inode->i_mapping);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
CIFS_I(direntry->d_inode)->write_behind_rc = rc;
|
cifsInode->write_behind_rc = rc;
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1521,9 +1529,8 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
rc = cifs_vmtruncate(direntry->d_inode, attrs->ia_size);
|
rc = cifs_vmtruncate(inode, attrs->ia_size);
|
||||||
cifs_truncate_page(direntry->d_inode->i_mapping,
|
cifs_truncate_page(inode->i_mapping, inode->i_size);
|
||||||
direntry->d_inode->i_size);
|
|
||||||
} else
|
} else
|
||||||
goto cifs_setattr_exit;
|
goto cifs_setattr_exit;
|
||||||
}
|
}
|
||||||
|
@ -1557,7 +1564,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
|
||||||
rc = 0;
|
rc = 0;
|
||||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
||||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
|
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
|
||||||
rc = mode_to_acl(direntry->d_inode, full_path, mode);
|
rc = mode_to_acl(inode, full_path, mode);
|
||||||
else if ((mode & S_IWUGO) == 0) {
|
else if ((mode & S_IWUGO) == 0) {
|
||||||
#else
|
#else
|
||||||
if ((mode & S_IWUGO) == 0) {
|
if ((mode & S_IWUGO) == 0) {
|
||||||
|
@ -1665,7 +1672,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
|
||||||
/* do not need local check to inode_check_ok since the server does
|
/* do not need local check to inode_check_ok since the server does
|
||||||
that */
|
that */
|
||||||
if (!rc)
|
if (!rc)
|
||||||
rc = inode_setattr(direntry->d_inode, attrs);
|
rc = inode_setattr(inode, attrs);
|
||||||
cifs_setattr_exit:
|
cifs_setattr_exit:
|
||||||
kfree(full_path);
|
kfree(full_path);
|
||||||
FreeXid(xid);
|
FreeXid(xid);
|
||||||
|
|
Loading…
Reference in New Issue