|
@@ -2,7 +2,7 @@
|
|
* fs/cifs/dir.c
|
|
* fs/cifs/dir.c
|
|
*
|
|
*
|
|
* vfs operations that deal with dentries
|
|
* vfs operations that deal with dentries
|
|
- *
|
|
|
|
|
|
+ *
|
|
* Copyright (C) International Business Machines Corp., 2002,2005
|
|
* Copyright (C) International Business Machines Corp., 2002,2005
|
|
* Author(s): Steve French (sfrench@us.ibm.com)
|
|
* Author(s): Steve French (sfrench@us.ibm.com)
|
|
*
|
|
*
|
|
@@ -34,11 +34,12 @@
|
|
static void
|
|
static void
|
|
renew_parental_timestamps(struct dentry *direntry)
|
|
renew_parental_timestamps(struct dentry *direntry)
|
|
{
|
|
{
|
|
- /* BB check if there is a way to get the kernel to do this or if we really need this */
|
|
|
|
|
|
+ /* BB check if there is a way to get the kernel to do this or if we
|
|
|
|
+ really need this */
|
|
do {
|
|
do {
|
|
direntry->d_time = jiffies;
|
|
direntry->d_time = jiffies;
|
|
direntry = direntry->d_parent;
|
|
direntry = direntry->d_parent;
|
|
- } while (!IS_ROOT(direntry));
|
|
|
|
|
|
+ } while (!IS_ROOT(direntry));
|
|
}
|
|
}
|
|
|
|
|
|
/* Note: caller must free return buffer */
|
|
/* Note: caller must free return buffer */
|
|
@@ -51,7 +52,7 @@ build_path_from_dentry(struct dentry *direntry)
|
|
char *full_path;
|
|
char *full_path;
|
|
char dirsep;
|
|
char dirsep;
|
|
|
|
|
|
- if(direntry == NULL)
|
|
|
|
|
|
+ if (direntry == NULL)
|
|
return NULL; /* not much we can do if dentry is freed and
|
|
return NULL; /* not much we can do if dentry is freed and
|
|
we need to reopen the file after it was closed implicitly
|
|
we need to reopen the file after it was closed implicitly
|
|
when the server crashed */
|
|
when the server crashed */
|
|
@@ -59,18 +60,18 @@ build_path_from_dentry(struct dentry *direntry)
|
|
dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb));
|
|
dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb));
|
|
pplen = CIFS_SB(direntry->d_sb)->prepathlen;
|
|
pplen = CIFS_SB(direntry->d_sb)->prepathlen;
|
|
cifs_bp_rename_retry:
|
|
cifs_bp_rename_retry:
|
|
- namelen = pplen;
|
|
|
|
|
|
+ namelen = pplen;
|
|
for (temp = direntry; !IS_ROOT(temp);) {
|
|
for (temp = direntry; !IS_ROOT(temp);) {
|
|
namelen += (1 + temp->d_name.len);
|
|
namelen += (1 + temp->d_name.len);
|
|
temp = temp->d_parent;
|
|
temp = temp->d_parent;
|
|
- if(temp == NULL) {
|
|
|
|
- cERROR(1,("corrupt dentry"));
|
|
|
|
|
|
+ if (temp == NULL) {
|
|
|
|
+ cERROR(1, ("corrupt dentry"));
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
full_path = kmalloc(namelen+1, GFP_KERNEL);
|
|
full_path = kmalloc(namelen+1, GFP_KERNEL);
|
|
- if(full_path == NULL)
|
|
|
|
|
|
+ if (full_path == NULL)
|
|
return full_path;
|
|
return full_path;
|
|
full_path[namelen] = 0; /* trailing null */
|
|
full_path[namelen] = 0; /* trailing null */
|
|
for (temp = direntry; !IS_ROOT(temp);) {
|
|
for (temp = direntry; !IS_ROOT(temp);) {
|
|
@@ -84,8 +85,8 @@ cifs_bp_rename_retry:
|
|
cFYI(0, ("name: %s", full_path + namelen));
|
|
cFYI(0, ("name: %s", full_path + namelen));
|
|
}
|
|
}
|
|
temp = temp->d_parent;
|
|
temp = temp->d_parent;
|
|
- if(temp == NULL) {
|
|
|
|
- cERROR(1,("corrupt dentry"));
|
|
|
|
|
|
+ if (temp == NULL) {
|
|
|
|
+ cERROR(1, ("corrupt dentry"));
|
|
kfree(full_path);
|
|
kfree(full_path);
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
@@ -94,7 +95,7 @@ cifs_bp_rename_retry:
|
|
cERROR(1,
|
|
cERROR(1,
|
|
("did not end path lookup where expected namelen is %d",
|
|
("did not end path lookup where expected namelen is %d",
|
|
namelen));
|
|
namelen));
|
|
- /* presumably this is only possible if racing with a rename
|
|
|
|
|
|
+ /* presumably this is only possible if racing with a rename
|
|
of one of the parent directories (we can not lock the dentries
|
|
of one of the parent directories (we can not lock the dentries
|
|
above us to prevent this, but retrying should be harmless) */
|
|
above us to prevent this, but retrying should be harmless) */
|
|
kfree(full_path);
|
|
kfree(full_path);
|
|
@@ -106,7 +107,7 @@ cifs_bp_rename_retry:
|
|
since the '\' is a valid posix character so we can not switch
|
|
since the '\' is a valid posix character so we can not switch
|
|
those safely to '/' if any are found in the middle of the prepath */
|
|
those safely to '/' if any are found in the middle of the prepath */
|
|
/* BB test paths to Windows with '/' in the midst of prepath */
|
|
/* BB test paths to Windows with '/' in the midst of prepath */
|
|
- strncpy(full_path,CIFS_SB(direntry->d_sb)->prepath,pplen);
|
|
|
|
|
|
+ strncpy(full_path, CIFS_SB(direntry->d_sb)->prepath, pplen);
|
|
return full_path;
|
|
return full_path;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -147,12 +148,12 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
|
|
pTcon = cifs_sb->tcon;
|
|
pTcon = cifs_sb->tcon;
|
|
|
|
|
|
full_path = build_path_from_dentry(direntry);
|
|
full_path = build_path_from_dentry(direntry);
|
|
- if(full_path == NULL) {
|
|
|
|
|
|
+ if (full_path == NULL) {
|
|
FreeXid(xid);
|
|
FreeXid(xid);
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
|
|
|
|
- if(nd && (nd->flags & LOOKUP_OPEN)) {
|
|
|
|
|
|
+ if (nd && (nd->flags & LOOKUP_OPEN)) {
|
|
int oflags = nd->intent.open.flags;
|
|
int oflags = nd->intent.open.flags;
|
|
|
|
|
|
desiredAccess = 0;
|
|
desiredAccess = 0;
|
|
@@ -164,28 +165,29 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
|
|
write_only = TRUE;
|
|
write_only = TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
- if((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
|
|
|
|
|
|
+ if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
|
|
disposition = FILE_CREATE;
|
|
disposition = FILE_CREATE;
|
|
- else if((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
|
|
|
|
|
|
+ else if ((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
|
|
disposition = FILE_OVERWRITE_IF;
|
|
disposition = FILE_OVERWRITE_IF;
|
|
- else if((oflags & O_CREAT) == O_CREAT)
|
|
|
|
|
|
+ else if ((oflags & O_CREAT) == O_CREAT)
|
|
disposition = FILE_OPEN_IF;
|
|
disposition = FILE_OPEN_IF;
|
|
else {
|
|
else {
|
|
- cFYI(1,("Create flag not set in create function"));
|
|
|
|
|
|
+ cFYI(1, ("Create flag not set in create function"));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- /* BB add processing to set equivalent of mode - e.g. via CreateX with ACLs */
|
|
|
|
|
|
+ /* BB add processing to set equivalent of mode - e.g. via CreateX with
|
|
|
|
+ ACLs */
|
|
if (oplockEnabled)
|
|
if (oplockEnabled)
|
|
oplock = REQ_OPLOCK;
|
|
oplock = REQ_OPLOCK;
|
|
|
|
|
|
- buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
|
|
|
|
- if(buf == NULL) {
|
|
|
|
|
|
+ buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
|
|
|
|
+ if (buf == NULL) {
|
|
kfree(full_path);
|
|
kfree(full_path);
|
|
FreeXid(xid);
|
|
FreeXid(xid);
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
- 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_NOT_DIR,
|
|
&fileHandle, &oplock, buf, cifs_sb->local_nls,
|
|
&fileHandle, &oplock, buf, cifs_sb->local_nls,
|
|
@@ -193,13 +195,13 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
|
|
else
|
|
else
|
|
rc = -EIO; /* no NT SMB support fall into legacy open below */
|
|
rc = -EIO; /* no NT SMB support fall into legacy open below */
|
|
|
|
|
|
- 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_NOT_DIR,
|
|
&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);
|
|
- }
|
|
|
|
|
|
+ }
|
|
if (rc) {
|
|
if (rc) {
|
|
cFYI(1, ("cifs_create returned 0x%x", rc));
|
|
cFYI(1, ("cifs_create returned 0x%x", rc));
|
|
} else {
|
|
} else {
|
|
@@ -207,13 +209,13 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
|
|
then we now have to set the mode if possible */
|
|
then we now have to set the mode if possible */
|
|
if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) &&
|
|
if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) &&
|
|
(oplock & CIFS_CREATE_ACTION))
|
|
(oplock & CIFS_CREATE_ACTION))
|
|
- 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,
|
|
(__u64)current->fsgid,
|
|
(__u64)current->fsgid,
|
|
0 /* dev */,
|
|
0 /* dev */,
|
|
- cifs_sb->local_nls,
|
|
|
|
- cifs_sb->mnt_cifs_flags &
|
|
|
|
|
|
+ cifs_sb->local_nls,
|
|
|
|
+ cifs_sb->mnt_cifs_flags &
|
|
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
|
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
|
} else {
|
|
} else {
|
|
CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
|
|
CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
|
|
@@ -221,26 +223,28 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
|
|
(__u64)-1,
|
|
(__u64)-1,
|
|
0 /* dev */,
|
|
0 /* dev */,
|
|
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 {
|
|
- /* BB implement mode setting via Windows security descriptors */
|
|
|
|
- /* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/
|
|
|
|
- /* could set r/o dos attribute if mode & 0222 == 0 */
|
|
|
|
|
|
+ /* BB implement mode setting via Windows security
|
|
|
|
+ descriptors e.g. */
|
|
|
|
+ /* CIFSSMBWinSetPerms(xid,pTcon,path,mode,-1,-1,nls);*/
|
|
|
|
+
|
|
|
|
+ /* Could set r/o dos attribute if mode & 0222 == 0 */
|
|
}
|
|
}
|
|
|
|
|
|
/* BB server might mask mode so we have to query for Unix case*/
|
|
/* BB server might mask mode so we have to query for Unix case*/
|
|
if (pTcon->ses->capabilities & CAP_UNIX)
|
|
if (pTcon->ses->capabilities & CAP_UNIX)
|
|
rc = cifs_get_inode_info_unix(&newinode, full_path,
|
|
rc = cifs_get_inode_info_unix(&newinode, full_path,
|
|
- inode->i_sb,xid);
|
|
|
|
|
|
+ inode->i_sb, xid);
|
|
else {
|
|
else {
|
|
rc = cifs_get_inode_info(&newinode, full_path,
|
|
rc = cifs_get_inode_info(&newinode, full_path,
|
|
- buf, inode->i_sb,xid);
|
|
|
|
- if(newinode) {
|
|
|
|
|
|
+ buf, inode->i_sb, xid);
|
|
|
|
+ if (newinode) {
|
|
newinode->i_mode = mode;
|
|
newinode->i_mode = mode;
|
|
- if((oplock & CIFS_CREATE_ACTION) &&
|
|
|
|
- (cifs_sb->mnt_cifs_flags &
|
|
|
|
|
|
+ if ((oplock & CIFS_CREATE_ACTION) &&
|
|
|
|
+ (cifs_sb->mnt_cifs_flags &
|
|
CIFS_MOUNT_SET_UID)) {
|
|
CIFS_MOUNT_SET_UID)) {
|
|
newinode->i_uid = current->fsuid;
|
|
newinode->i_uid = current->fsuid;
|
|
newinode->i_gid = current->fsgid;
|
|
newinode->i_gid = current->fsgid;
|
|
@@ -259,14 +263,14 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
|
|
direntry->d_op = &cifs_dentry_ops;
|
|
direntry->d_op = &cifs_dentry_ops;
|
|
d_instantiate(direntry, newinode);
|
|
d_instantiate(direntry, newinode);
|
|
}
|
|
}
|
|
- if((nd->flags & LOOKUP_OPEN) == FALSE) {
|
|
|
|
|
|
+ if ((nd->flags & LOOKUP_OPEN) == FALSE) {
|
|
/* mknod case - do not leave file open */
|
|
/* mknod case - do not leave file open */
|
|
CIFSSMBClose(xid, pTcon, fileHandle);
|
|
CIFSSMBClose(xid, pTcon, fileHandle);
|
|
- } else if(newinode) {
|
|
|
|
|
|
+ } else if (newinode) {
|
|
pCifsFile =
|
|
pCifsFile =
|
|
kzalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
|
|
kzalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
|
|
|
|
|
|
- if(pCifsFile == NULL)
|
|
|
|
|
|
+ if (pCifsFile == NULL)
|
|
goto cifs_create_out;
|
|
goto cifs_create_out;
|
|
pCifsFile->netfid = fileHandle;
|
|
pCifsFile->netfid = fileHandle;
|
|
pCifsFile->pid = current->tgid;
|
|
pCifsFile->pid = current->tgid;
|
|
@@ -276,33 +280,33 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
|
|
init_MUTEX(&pCifsFile->fh_sem);
|
|
init_MUTEX(&pCifsFile->fh_sem);
|
|
mutex_init(&pCifsFile->lock_mutex);
|
|
mutex_init(&pCifsFile->lock_mutex);
|
|
INIT_LIST_HEAD(&pCifsFile->llist);
|
|
INIT_LIST_HEAD(&pCifsFile->llist);
|
|
- atomic_set(&pCifsFile->wrtPending,0);
|
|
|
|
|
|
+ atomic_set(&pCifsFile->wrtPending, 0);
|
|
|
|
|
|
- /* set the following in open now
|
|
|
|
|
|
+ /* set the following in open now
|
|
pCifsFile->pfile = file; */
|
|
pCifsFile->pfile = file; */
|
|
write_lock(&GlobalSMBSeslock);
|
|
write_lock(&GlobalSMBSeslock);
|
|
- list_add(&pCifsFile->tlist,&pTcon->openFileList);
|
|
|
|
|
|
+ list_add(&pCifsFile->tlist, &pTcon->openFileList);
|
|
pCifsInode = CIFS_I(newinode);
|
|
pCifsInode = CIFS_I(newinode);
|
|
- if(pCifsInode) {
|
|
|
|
|
|
+ if (pCifsInode) {
|
|
/* if readable file instance put first in list*/
|
|
/* if readable file instance put first in list*/
|
|
if (write_only == TRUE) {
|
|
if (write_only == TRUE) {
|
|
- list_add_tail(&pCifsFile->flist,
|
|
|
|
|
|
+ list_add_tail(&pCifsFile->flist,
|
|
&pCifsInode->openFileList);
|
|
&pCifsInode->openFileList);
|
|
} else {
|
|
} else {
|
|
list_add(&pCifsFile->flist,
|
|
list_add(&pCifsFile->flist,
|
|
&pCifsInode->openFileList);
|
|
&pCifsInode->openFileList);
|
|
}
|
|
}
|
|
- if((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
|
|
|
|
|
|
+ if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
|
|
pCifsInode->clientCanCacheAll = TRUE;
|
|
pCifsInode->clientCanCacheAll = TRUE;
|
|
pCifsInode->clientCanCacheRead = TRUE;
|
|
pCifsInode->clientCanCacheRead = TRUE;
|
|
cFYI(1,("Exclusive Oplock for inode %p",
|
|
cFYI(1,("Exclusive Oplock for inode %p",
|
|
newinode));
|
|
newinode));
|
|
- } else if((oplock & 0xF) == OPLOCK_READ)
|
|
|
|
|
|
+ } else if ((oplock & 0xF) == OPLOCK_READ)
|
|
pCifsInode->clientCanCacheRead = TRUE;
|
|
pCifsInode->clientCanCacheRead = TRUE;
|
|
}
|
|
}
|
|
write_unlock(&GlobalSMBSeslock);
|
|
write_unlock(&GlobalSMBSeslock);
|
|
}
|
|
}
|
|
- }
|
|
|
|
|
|
+ }
|
|
cifs_create_out:
|
|
cifs_create_out:
|
|
kfree(buf);
|
|
kfree(buf);
|
|
kfree(full_path);
|
|
kfree(full_path);
|
|
@@ -310,8 +314,8 @@ cifs_create_out:
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|
|
|
|
|
|
-int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
|
|
|
|
- dev_t device_number)
|
|
|
|
|
|
+int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
|
|
|
|
+ dev_t device_number)
|
|
{
|
|
{
|
|
int rc = -EPERM;
|
|
int rc = -EPERM;
|
|
int xid;
|
|
int xid;
|
|
@@ -329,43 +333,44 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
|
|
pTcon = cifs_sb->tcon;
|
|
pTcon = cifs_sb->tcon;
|
|
|
|
|
|
full_path = build_path_from_dentry(direntry);
|
|
full_path = build_path_from_dentry(direntry);
|
|
- if(full_path == NULL)
|
|
|
|
|
|
+ if (full_path == NULL)
|
|
rc = -ENOMEM;
|
|
rc = -ENOMEM;
|
|
else if (pTcon->ses->capabilities & CAP_UNIX) {
|
|
else if (pTcon->ses->capabilities & CAP_UNIX) {
|
|
- if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
|
|
|
|
|
|
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
|
|
rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path,
|
|
rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path,
|
|
- mode,(__u64)current->fsuid,(__u64)current->fsgid,
|
|
|
|
|
|
+ mode, (__u64)current->fsuid,
|
|
|
|
+ (__u64)current->fsgid,
|
|
device_number, cifs_sb->local_nls,
|
|
device_number, 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 = CIFSSMBUnixSetPerms(xid, pTcon,
|
|
rc = CIFSSMBUnixSetPerms(xid, pTcon,
|
|
full_path, mode, (__u64)-1, (__u64)-1,
|
|
full_path, mode, (__u64)-1, (__u64)-1,
|
|
device_number, cifs_sb->local_nls,
|
|
device_number, cifs_sb->local_nls,
|
|
- cifs_sb->mnt_cifs_flags &
|
|
|
|
|
|
+ cifs_sb->mnt_cifs_flags &
|
|
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
|
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
|
}
|
|
}
|
|
|
|
|
|
- if(!rc) {
|
|
|
|
|
|
+ if (!rc) {
|
|
rc = cifs_get_inode_info_unix(&newinode, full_path,
|
|
rc = cifs_get_inode_info_unix(&newinode, full_path,
|
|
- inode->i_sb,xid);
|
|
|
|
|
|
+ inode->i_sb, xid);
|
|
if (pTcon->nocase)
|
|
if (pTcon->nocase)
|
|
direntry->d_op = &cifs_ci_dentry_ops;
|
|
direntry->d_op = &cifs_ci_dentry_ops;
|
|
else
|
|
else
|
|
direntry->d_op = &cifs_dentry_ops;
|
|
direntry->d_op = &cifs_dentry_ops;
|
|
- if(rc == 0)
|
|
|
|
|
|
+ if (rc == 0)
|
|
d_instantiate(direntry, newinode);
|
|
d_instantiate(direntry, newinode);
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
- if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
|
|
|
|
|
|
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
|
|
int oplock = 0;
|
|
int oplock = 0;
|
|
u16 fileHandle;
|
|
u16 fileHandle;
|
|
FILE_ALL_INFO * buf;
|
|
FILE_ALL_INFO * buf;
|
|
|
|
|
|
- cFYI(1,("sfu compat create special file"));
|
|
|
|
|
|
+ cFYI(1, ("sfu compat create special file"));
|
|
|
|
|
|
- buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
|
|
|
|
- if(buf == NULL) {
|
|
|
|
|
|
+ buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
|
|
|
|
+ if (buf == NULL) {
|
|
kfree(full_path);
|
|
kfree(full_path);
|
|
FreeXid(xid);
|
|
FreeXid(xid);
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
@@ -373,39 +378,38 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
|
|
|
|
|
|
rc = CIFSSMBOpen(xid, pTcon, full_path,
|
|
rc = CIFSSMBOpen(xid, pTcon, full_path,
|
|
FILE_CREATE, /* fail if exists */
|
|
FILE_CREATE, /* fail if exists */
|
|
- GENERIC_WRITE /* BB would
|
|
|
|
|
|
+ GENERIC_WRITE /* BB would
|
|
WRITE_OWNER | WRITE_DAC be better? */,
|
|
WRITE_OWNER | WRITE_DAC be better? */,
|
|
/* Create a file and set the
|
|
/* Create a file and set the
|
|
file attribute to SYSTEM */
|
|
file attribute to SYSTEM */
|
|
CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
|
|
CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
|
|
&fileHandle, &oplock, buf,
|
|
&fileHandle, &oplock, buf,
|
|
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);
|
|
|
|
|
|
/* BB FIXME - add handling for backlevel servers
|
|
/* BB FIXME - add handling for backlevel servers
|
|
which need legacy open and check for all
|
|
which need legacy open and check for all
|
|
- calls to SMBOpen for fallback to
|
|
|
|
- SMBLeagcyOpen */
|
|
|
|
- if(!rc) {
|
|
|
|
|
|
+ calls to SMBOpen for fallback to SMBLeagcyOpen */
|
|
|
|
+ if (!rc) {
|
|
/* BB Do not bother to decode buf since no
|
|
/* BB Do not bother to decode buf since no
|
|
local inode yet to put timestamps in,
|
|
local inode yet to put timestamps in,
|
|
but we can reuse it safely */
|
|
but we can reuse it safely */
|
|
int bytes_written;
|
|
int bytes_written;
|
|
struct win_dev *pdev;
|
|
struct win_dev *pdev;
|
|
pdev = (struct win_dev *)buf;
|
|
pdev = (struct win_dev *)buf;
|
|
- if(S_ISCHR(mode)) {
|
|
|
|
|
|
+ if (S_ISCHR(mode)) {
|
|
memcpy(pdev->type, "IntxCHR", 8);
|
|
memcpy(pdev->type, "IntxCHR", 8);
|
|
pdev->major =
|
|
pdev->major =
|
|
cpu_to_le64(MAJOR(device_number));
|
|
cpu_to_le64(MAJOR(device_number));
|
|
- pdev->minor =
|
|
|
|
|
|
+ pdev->minor =
|
|
cpu_to_le64(MINOR(device_number));
|
|
cpu_to_le64(MINOR(device_number));
|
|
rc = CIFSSMBWrite(xid, pTcon,
|
|
rc = CIFSSMBWrite(xid, pTcon,
|
|
fileHandle,
|
|
fileHandle,
|
|
sizeof(struct win_dev),
|
|
sizeof(struct win_dev),
|
|
0, &bytes_written, (char *)pdev,
|
|
0, &bytes_written, (char *)pdev,
|
|
NULL, 0);
|
|
NULL, 0);
|
|
- } else if(S_ISBLK(mode)) {
|
|
|
|
|
|
+ } else if (S_ISBLK(mode)) {
|
|
memcpy(pdev->type, "IntxBLK", 8);
|
|
memcpy(pdev->type, "IntxBLK", 8);
|
|
pdev->major =
|
|
pdev->major =
|
|
cpu_to_le64(MAJOR(device_number));
|
|
cpu_to_le64(MAJOR(device_number));
|
|
@@ -432,7 +436,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
|
|
|
|
|
|
|
|
|
|
struct dentry *
|
|
struct dentry *
|
|
-cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct nameidata *nd)
|
|
|
|
|
|
+cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
|
|
|
|
+ struct nameidata *nd)
|
|
{
|
|
{
|
|
int xid;
|
|
int xid;
|
|
int rc = 0; /* to get around spurious gcc warning, set to zero here */
|
|
int rc = 0; /* to get around spurious gcc warning, set to zero here */
|
|
@@ -447,8 +452,6 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
|
|
(" parent inode = 0x%p name is: %s and dentry = 0x%p",
|
|
(" parent inode = 0x%p name is: %s and dentry = 0x%p",
|
|
parent_dir_inode, direntry->d_name.name, direntry));
|
|
parent_dir_inode, direntry->d_name.name, direntry));
|
|
|
|
|
|
- /* BB Add check of incoming data - e.g. frame not longer than maximum SMB - let server check the namelen BB */
|
|
|
|
-
|
|
|
|
/* check whether path exists */
|
|
/* check whether path exists */
|
|
|
|
|
|
cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
|
|
cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
|
|
@@ -472,7 +475,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
|
|
deadlock in the cases (beginning of sys_rename itself)
|
|
deadlock in the cases (beginning of sys_rename itself)
|
|
in which we already have the sb rename sem */
|
|
in which we already have the sb rename sem */
|
|
full_path = build_path_from_dentry(direntry);
|
|
full_path = build_path_from_dentry(direntry);
|
|
- if(full_path == NULL) {
|
|
|
|
|
|
+ if (full_path == NULL) {
|
|
FreeXid(xid);
|
|
FreeXid(xid);
|
|
return ERR_PTR(-ENOMEM);
|
|
return ERR_PTR(-ENOMEM);
|
|
}
|
|
}
|
|
@@ -487,10 +490,10 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
|
|
|
|
|
|
if (pTcon->ses->capabilities & CAP_UNIX)
|
|
if (pTcon->ses->capabilities & CAP_UNIX)
|
|
rc = cifs_get_inode_info_unix(&newInode, full_path,
|
|
rc = cifs_get_inode_info_unix(&newInode, full_path,
|
|
- parent_dir_inode->i_sb,xid);
|
|
|
|
|
|
+ parent_dir_inode->i_sb, xid);
|
|
else
|
|
else
|
|
rc = cifs_get_inode_info(&newInode, full_path, NULL,
|
|
rc = cifs_get_inode_info(&newInode, full_path, NULL,
|
|
- parent_dir_inode->i_sb,xid);
|
|
|
|
|
|
+ parent_dir_inode->i_sb, xid);
|
|
|
|
|
|
if ((rc == 0) && (newInode != NULL)) {
|
|
if ((rc == 0) && (newInode != NULL)) {
|
|
if (pTcon->nocase)
|
|
if (pTcon->nocase)
|
|
@@ -499,7 +502,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
|
|
direntry->d_op = &cifs_dentry_ops;
|
|
direntry->d_op = &cifs_dentry_ops;
|
|
d_add(direntry, newInode);
|
|
d_add(direntry, newInode);
|
|
|
|
|
|
- /* since paths are not looked up by component - the parent
|
|
|
|
|
|
+ /* since paths are not looked up by component - the parent
|
|
directories are presumed to be good here */
|
|
directories are presumed to be good here */
|
|
renew_parental_timestamps(direntry);
|
|
renew_parental_timestamps(direntry);
|
|
|
|
|
|
@@ -511,13 +514,13 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
|
|
else
|
|
else
|
|
direntry->d_op = &cifs_dentry_ops;
|
|
direntry->d_op = &cifs_dentry_ops;
|
|
d_add(direntry, NULL);
|
|
d_add(direntry, NULL);
|
|
- /* if it was once a directory (but how can we tell?) we could do
|
|
|
|
- shrink_dcache_parent(direntry); */
|
|
|
|
|
|
+ /* if it was once a directory (but how can we tell?) we could do
|
|
|
|
+ shrink_dcache_parent(direntry); */
|
|
} else {
|
|
} else {
|
|
cERROR(1,("Error 0x%x on cifs_get_inode_info in lookup of %s",
|
|
cERROR(1,("Error 0x%x on cifs_get_inode_info in lookup of %s",
|
|
- rc,full_path));
|
|
|
|
- /* BB special case check for Access Denied - watch security
|
|
|
|
- exposure of returning dir info implicitly via different rc
|
|
|
|
|
|
+ rc, full_path));
|
|
|
|
+ /* BB special case check for Access Denied - watch security
|
|
|
|
+ exposure of returning dir info implicitly via different rc
|
|
if file exists or not but no access BB */
|
|
if file exists or not but no access BB */
|
|
}
|
|
}
|
|
|
|
|
|
@@ -538,11 +541,11 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
|
|
} else {
|
|
} else {
|
|
cFYI(1, ("neg dentry 0x%p name = %s",
|
|
cFYI(1, ("neg dentry 0x%p name = %s",
|
|
direntry, direntry->d_name.name));
|
|
direntry, direntry->d_name.name));
|
|
- if(time_after(jiffies, direntry->d_time + HZ) ||
|
|
|
|
|
|
+ if (time_after(jiffies, direntry->d_time + HZ) ||
|
|
!lookupCacheEnabled) {
|
|
!lookupCacheEnabled) {
|
|
d_drop(direntry);
|
|
d_drop(direntry);
|
|
isValid = 0;
|
|
isValid = 0;
|
|
- }
|
|
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
return isValid;
|
|
return isValid;
|
|
@@ -559,8 +562,7 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
|
|
|
|
|
|
struct dentry_operations cifs_dentry_ops = {
|
|
struct dentry_operations cifs_dentry_ops = {
|
|
.d_revalidate = cifs_d_revalidate,
|
|
.d_revalidate = cifs_d_revalidate,
|
|
-/* d_delete: cifs_d_delete, *//* not needed except for debugging */
|
|
|
|
- /* no need for d_hash, d_compare, d_release, d_iput ... yet. BB confirm this BB */
|
|
|
|
|
|
+/* d_delete: cifs_d_delete, */ /* not needed except for debugging */
|
|
};
|
|
};
|
|
|
|
|
|
static int cifs_ci_hash(struct dentry *dentry, struct qstr *q)
|
|
static int cifs_ci_hash(struct dentry *dentry, struct qstr *q)
|