[linux-cifs-client] [PATCH 2/4] cifs: use common code for turning
off ATTR_READONLY in cifs_unlink
Jeff Layton
jlayton at redhat.com
Tue Sep 16 11:27:14 GMT 2008
We already have a cifs_set_file_info function that can flip DOS
attribute bits. Have cifs_unlink call it to handle turning ATTR_HIDDEN
on and ATTR_READONLY off when an unlink attempt returns -EACCES.
This also removes a level of indentation.
Signed-off-by: Jeff Layton <jlayton at redhat.com>
---
fs/cifs/inode.c | 119 ++++++++++++++++++++++---------------------------------
1 files changed, 47 insertions(+), 72 deletions(-)
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 9161c7b..3f0995d 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -29,6 +29,8 @@
#include "cifs_debug.h"
#include "cifs_fs_sb.h"
+static int cifs_set_file_info(struct inode *inode, struct iattr *attrs,
+ int xid, char *full_path, __u32 dosattr);
static void cifs_set_ops(struct inode *inode, const bool is_dfs_referral)
{
@@ -675,7 +677,8 @@ int cifs_unlink(struct inode *pinode, struct dentry *direntry)
struct cifsInodeInfo *cifsInode;
struct super_block *sb;
struct inode *inode = direntry->d_inode;
- FILE_BASIC_INFO *pinfo_buf;
+ struct iattr *attrs;
+ __u32 dosattr;
cFYI(1, ("cifs_unlink, pinode = 0x%p, dentry=0x%p", pinode, direntry));
@@ -736,84 +739,56 @@ psx_del_no_retry:
}
} else if (rc == -EACCES) {
/* try only if r/o attribute set in local lookup data? */
- pinfo_buf = kzalloc(sizeof(FILE_BASIC_INFO), GFP_KERNEL);
- if (pinfo_buf) {
- /* ATTRS set to normal clears r/o bit */
- pinfo_buf->Attributes = cpu_to_le32(ATTR_NORMAL);
- if (!(pTcon->ses->flags & CIFS_SES_NT4))
- rc = CIFSSMBSetPathInfo(xid, pTcon, full_path,
- pinfo_buf,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- else
- rc = -EOPNOTSUPP;
-
- if (rc == -EOPNOTSUPP) {
- int oplock = 0;
- __u16 netfid;
- /* rc = CIFSSMBSetAttrLegacy(xid, pTcon,
- full_path,
- (__u16)ATTR_NORMAL,
- cifs_sb->local_nls);
- For some strange reason it seems that NT4 eats the
- old setattr call without actually setting the
- attributes so on to the third attempted workaround
- */
-
- /* BB could scan to see if we already have it open
- and pass in pid of opener to function */
- rc = CIFSSMBOpen(xid, pTcon, full_path,
- FILE_OPEN, SYNCHRONIZE |
- FILE_WRITE_ATTRIBUTES, 0,
- &netfid, &oplock, NULL,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (rc == 0) {
- rc = CIFSSMBSetFileInfo(xid, pTcon,
- pinfo_buf,
- netfid,
- current->tgid);
- CIFSSMBClose(xid, pTcon, netfid);
- }
- }
- kfree(pinfo_buf);
+ attrs = kzalloc(sizeof(*attrs), GFP_KERNEL);
+ if (attrs == NULL) {
+ rc = -ENOMEM;
+ goto out_reval;
}
+
+ /* try to reset dos attributes */
+ cifsInode = CIFS_I(inode);
+ dosattr = cifsInode->cifsAttrs & ~ATTR_READONLY;
+ if (dosattr == 0)
+ dosattr |= ATTR_NORMAL;
+ dosattr |= ATTR_HIDDEN;
+
+ rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr);
+ kfree(attrs);
+ if (rc != 0)
+ goto out_reval;
+
+ rc = CIFSSMBDelFile(xid, pTcon, full_path, cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
if (rc == 0) {
- rc = CIFSSMBDelFile(xid, pTcon, full_path,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (!rc) {
+ if (inode)
+ drop_nlink(inode);
+ } else if (rc == -ETXTBSY) {
+ int oplock = 0;
+ __u16 netfid;
+
+ rc = CIFSSMBOpen(xid, pTcon, full_path,
+ FILE_OPEN, DELETE,
+ CREATE_NOT_DIR |
+ CREATE_DELETE_ON_CLOSE,
+ &netfid, &oplock, NULL,
+ cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
+ if (rc == 0) {
+ CIFSSMBRenameOpenFile(xid, pTcon,
+ netfid, NULL,
+ cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
+ CIFSSMBClose(xid, pTcon, netfid);
if (inode)
drop_nlink(inode);
- } else if (rc == -ETXTBSY) {
- int oplock = 0;
- __u16 netfid;
-
- rc = CIFSSMBOpen(xid, pTcon, full_path,
- FILE_OPEN, DELETE,
- CREATE_NOT_DIR |
- CREATE_DELETE_ON_CLOSE,
- &netfid, &oplock, NULL,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (rc == 0) {
- CIFSSMBRenameOpenFile(xid, pTcon,
- netfid, NULL,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- CIFSSMBClose(xid, pTcon, netfid);
- if (inode)
- drop_nlink(inode);
- }
- /* BB if rc = -ETXTBUSY goto the rename logic BB */
}
+ /* BB if rc = -ETXTBUSY goto the rename logic BB */
}
}
+out_reval:
if (inode) {
cifsInode = CIFS_I(inode);
cifsInode->time = 0; /* will force revalidate to get info
--
1.5.5.1
More information about the linux-cifs-client
mailing list