[CIFS] reset mode when client notices that ATTR_READONLY is no longer set
[deliverable/linux.git] / fs / cifs / inode.c
index 24df13a256e50e335895e2c6e0323556e8a75e92..e75a844accd7b5d58060d4d2159730a7650dac96 100644 (file)
@@ -494,6 +494,12 @@ int cifs_get_inode_info(struct inode **pinode,
                           mode e.g. 555 */
                        if (cifsInfo->cifsAttrs & ATTR_READONLY)
                                inode->i_mode &= ~(S_IWUGO);
+                       else if ((inode->i_mode & S_IWUGO) == 0)
+                               /* the ATTR_READONLY flag may have been */
+                               /* changed on server -- set any w bits  */
+                               /* allowed by mnt_file_mode             */
+                               inode->i_mode |= (S_IWUGO &
+                                                 cifs_sb->mnt_file_mode);
                /* BB add code here -
                   validate if device or weird share or device type? */
                }
@@ -1134,20 +1140,22 @@ static int cifs_truncate_page(struct address_space *mapping, loff_t from)
        return rc;
 }
 
-int cifs_vmtruncate(struct inode * inode, loff_t offset)
+static int cifs_vmtruncate(struct inode * inode, loff_t offset)
 {
        struct address_space *mapping = inode->i_mapping;
        unsigned long limit;
 
+       spin_lock(&inode->i_lock);
        if (inode->i_size < offset)
                goto do_expand;
        /*
         * truncation of in-use swapfiles is disallowed - it would cause
         * subsequent swapout to scribble on the now-freed blocks.
         */
-       if (IS_SWAPFILE(inode))
+       if (IS_SWAPFILE(inode)) {
+               spin_unlock(&inode->i_lock);
                goto out_busy;
-       spin_lock(&inode->i_lock);              
+       }
        i_size_write(inode, offset);
        spin_unlock(&inode->i_lock);
        unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
@@ -1156,12 +1164,16 @@ int cifs_vmtruncate(struct inode * inode, loff_t offset)
 
 do_expand:
        limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
-       if (limit != RLIM_INFINITY && offset > limit)
+       if (limit != RLIM_INFINITY && offset > limit) {
+               spin_unlock(&inode->i_lock);
                goto out_sig;
-       if (offset > inode->i_sb->s_maxbytes)
+       }
+       if (offset > inode->i_sb->s_maxbytes) {
+               spin_unlock(&inode->i_lock);
                goto out_big;
+       }
        i_size_write(inode, offset);
-
+       spin_unlock(&inode->i_lock);
 out_truncate:
        if (inode->i_op && inode->i_op->truncate)
                inode->i_op->truncate(inode);
@@ -1425,9 +1437,11 @@ cifs_setattr_exit:
        return rc;
 }
 
+#if 0
 void cifs_delete_inode(struct inode *inode)
 {
        cFYI(1, ("In cifs_delete_inode, inode = 0x%p", inode));
        /* may have to add back in if and when safe distributed caching of
           directories added e.g. via FindNotify */
 }
+#endif
This page took 0.027445 seconds and 5 git commands to generate.