[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