aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/inode.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2008-02-25 15:25:21 -0500
committerSteve French <sfrench@us.ibm.com>2008-02-25 15:25:21 -0500
commit75f12983d9949fef67ecc133ef4727d93d42b25a (patch)
tree81ebb40589193fd8e6366cda2a64961d1de6e1cb /fs/cifs/inode.c
parente086fcea861f82f2086a97e401a15e1ba07e8566 (diff)
[CIFS] consolidate duplicate code in posix/unix inode handling
Signed-off-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r--fs/cifs/inode.c279
1 files changed, 103 insertions, 176 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 1d8aa0385ef7..8c23fb330ea9 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -69,6 +69,90 @@ static void cifs_set_ops(struct inode *inode)
69 } 69 }
70} 70}
71 71
72static void cifs_unix_info_to_inode(struct inode *inode,
73 FILE_UNIX_BASIC_INFO *info, int force_uid_gid)
74{
75 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
76 struct cifsInodeInfo *cifsInfo = CIFS_I(inode);
77 __u64 num_of_bytes = le64_to_cpu(info->NumOfBytes);
78 __u64 end_of_file = le64_to_cpu(info->EndOfFile);
79
80 inode->i_atime = cifs_NTtimeToUnix(le64_to_cpu(info->LastAccessTime));
81 inode->i_mtime =
82 cifs_NTtimeToUnix(le64_to_cpu(info->LastModificationTime));
83 inode->i_ctime = cifs_NTtimeToUnix(le64_to_cpu(info->LastStatusChange));
84 inode->i_mode = le64_to_cpu(info->Permissions);
85
86 /*
87 * Since we set the inode type below we need to mask off
88 * to avoid strange results if bits set above.
89 */
90 inode->i_mode &= ~S_IFMT;
91 switch (le32_to_cpu(info->Type)) {
92 case UNIX_FILE:
93 inode->i_mode |= S_IFREG;
94 break;
95 case UNIX_SYMLINK:
96 inode->i_mode |= S_IFLNK;
97 break;
98 case UNIX_DIR:
99 inode->i_mode |= S_IFDIR;
100 break;
101 case UNIX_CHARDEV:
102 inode->i_mode |= S_IFCHR;
103 inode->i_rdev = MKDEV(le64_to_cpu(info->DevMajor),
104 le64_to_cpu(info->DevMinor) & MINORMASK);
105 break;
106 case UNIX_BLOCKDEV:
107 inode->i_mode |= S_IFBLK;
108 inode->i_rdev = MKDEV(le64_to_cpu(info->DevMajor),
109 le64_to_cpu(info->DevMinor) & MINORMASK);
110 break;
111 case UNIX_FIFO:
112 inode->i_mode |= S_IFIFO;
113 break;
114 case UNIX_SOCKET:
115 inode->i_mode |= S_IFSOCK;
116 break;
117 default:
118 /* safest to call it a file if we do not know */
119 inode->i_mode |= S_IFREG;
120 cFYI(1, ("unknown type %d", le32_to_cpu(info->Type)));
121 break;
122 }
123
124 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) &&
125 !force_uid_gid)
126 inode->i_uid = cifs_sb->mnt_uid;
127 else
128 inode->i_uid = le64_to_cpu(info->Uid);
129
130 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) &&
131 !force_uid_gid)
132 inode->i_gid = cifs_sb->mnt_gid;
133 else
134 inode->i_gid = le64_to_cpu(info->Gid);
135
136 inode->i_nlink = le64_to_cpu(info->Nlinks);
137
138 spin_lock(&inode->i_lock);
139 if (is_size_safe_to_change(cifsInfo, end_of_file)) {
140 /*
141 * We can not safely change the file size here if the client
142 * is writing to it due to potential races.
143 */
144 i_size_write(inode, end_of_file);
145
146 /*
147 * i_blocks is not related to (i_size / i_blksize),
148 * but instead 512 byte (2**9) size is required for
149 * calculating num blocks.
150 */
151 inode->i_blocks = (512 - 1 + num_of_bytes) >> 9;
152 }
153 spin_unlock(&inode->i_lock);
154}
155
72int cifs_get_inode_info_unix(struct inode **pinode, 156int cifs_get_inode_info_unix(struct inode **pinode,
73 const unsigned char *search_path, struct super_block *sb, int xid) 157 const unsigned char *search_path, struct super_block *sb, int xid)
74{ 158{
@@ -114,7 +198,6 @@ int cifs_get_inode_info_unix(struct inode **pinode,
114 } 198 }
115 } else { 199 } else {
116 struct cifsInodeInfo *cifsInfo; 200 struct cifsInodeInfo *cifsInfo;
117 __u32 type = le32_to_cpu(findData.Type);
118 __u64 num_of_bytes = le64_to_cpu(findData.NumOfBytes); 201 __u64 num_of_bytes = le64_to_cpu(findData.NumOfBytes);
119 __u64 end_of_file = le64_to_cpu(findData.EndOfFile); 202 __u64 end_of_file = le64_to_cpu(findData.EndOfFile);
120 203
@@ -145,73 +228,8 @@ int cifs_get_inode_info_unix(struct inode **pinode,
145 /* this is ok to set on every inode revalidate */ 228 /* this is ok to set on every inode revalidate */
146 atomic_set(&cifsInfo->inUse, 1); 229 atomic_set(&cifsInfo->inUse, 1);
147 230
148 inode->i_atime = 231 cifs_unix_info_to_inode(inode, &findData, 0);
149 cifs_NTtimeToUnix(le64_to_cpu(findData.LastAccessTime));
150 inode->i_mtime =
151 cifs_NTtimeToUnix(le64_to_cpu
152 (findData.LastModificationTime));
153 inode->i_ctime =
154 cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange));
155 inode->i_mode = le64_to_cpu(findData.Permissions);
156 /* since we set the inode type below we need to mask off
157 to avoid strange results if bits set above */
158 inode->i_mode &= ~S_IFMT;
159 if (type == UNIX_FILE) {
160 inode->i_mode |= S_IFREG;
161 } else if (type == UNIX_SYMLINK) {
162 inode->i_mode |= S_IFLNK;
163 } else if (type == UNIX_DIR) {
164 inode->i_mode |= S_IFDIR;
165 } else if (type == UNIX_CHARDEV) {
166 inode->i_mode |= S_IFCHR;
167 inode->i_rdev = MKDEV(le64_to_cpu(findData.DevMajor),
168 le64_to_cpu(findData.DevMinor) & MINORMASK);
169 } else if (type == UNIX_BLOCKDEV) {
170 inode->i_mode |= S_IFBLK;
171 inode->i_rdev = MKDEV(le64_to_cpu(findData.DevMajor),
172 le64_to_cpu(findData.DevMinor) & MINORMASK);
173 } else if (type == UNIX_FIFO) {
174 inode->i_mode |= S_IFIFO;
175 } else if (type == UNIX_SOCKET) {
176 inode->i_mode |= S_IFSOCK;
177 } else {
178 /* safest to call it a file if we do not know */
179 inode->i_mode |= S_IFREG;
180 cFYI(1, ("unknown type %d", type));
181 }
182
183 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
184 inode->i_uid = cifs_sb->mnt_uid;
185 else
186 inode->i_uid = le64_to_cpu(findData.Uid);
187
188 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
189 inode->i_gid = cifs_sb->mnt_gid;
190 else
191 inode->i_gid = le64_to_cpu(findData.Gid);
192
193 inode->i_nlink = le64_to_cpu(findData.Nlinks);
194
195 spin_lock(&inode->i_lock);
196 if (is_size_safe_to_change(cifsInfo, end_of_file)) {
197 /* can not safely change the file size here if the
198 client is writing to it due to potential races */
199 i_size_write(inode, end_of_file);
200
201 /* blksize needs to be multiple of two. So safer to default to
202 blksize and blkbits set in superblock so 2**blkbits and blksize
203 will match rather than setting to:
204 (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/
205 232
206 /* This seems incredibly stupid but it turns out that i_blocks
207 is not related to (i_size / i_blksize), instead 512 byte size
208 is required for calculating num blocks */
209
210 /* 512 bytes (2**9) is the fake blocksize that must be used */
211 /* for this calculation */
212 inode->i_blocks = (512 - 1 + num_of_bytes) >> 9;
213 }
214 spin_unlock(&inode->i_lock);
215 233
216 if (num_of_bytes < end_of_file) 234 if (num_of_bytes < end_of_file)
217 cFYI(1, ("allocation size less than end of file")); 235 cFYI(1, ("allocation size less than end of file"));
@@ -774,15 +792,10 @@ psx_del_no_retry:
774static void posix_fill_in_inode(struct inode *tmp_inode, 792static void posix_fill_in_inode(struct inode *tmp_inode,
775 FILE_UNIX_BASIC_INFO *pData, int *pobject_type, int isNewInode) 793 FILE_UNIX_BASIC_INFO *pData, int *pobject_type, int isNewInode)
776{ 794{
795 struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
777 loff_t local_size; 796 loff_t local_size;
778 struct timespec local_mtime; 797 struct timespec local_mtime;
779 798
780 struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
781 struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb);
782
783 __u32 type = le32_to_cpu(pData->Type);
784 __u64 num_of_bytes = le64_to_cpu(pData->NumOfBytes);
785 __u64 end_of_file = le64_to_cpu(pData->EndOfFile);
786 cifsInfo->time = jiffies; 799 cifsInfo->time = jiffies;
787 atomic_inc(&cifsInfo->inUse); 800 atomic_inc(&cifsInfo->inUse);
788 801
@@ -790,113 +803,27 @@ static void posix_fill_in_inode(struct inode *tmp_inode,
790 local_mtime = tmp_inode->i_mtime; 803 local_mtime = tmp_inode->i_mtime;
791 local_size = tmp_inode->i_size; 804 local_size = tmp_inode->i_size;
792 805
793 tmp_inode->i_atime = 806 cifs_unix_info_to_inode(tmp_inode, pData, 1);
794 cifs_NTtimeToUnix(le64_to_cpu(pData->LastAccessTime)); 807 cifs_set_ops(tmp_inode);
795 tmp_inode->i_mtime =
796 cifs_NTtimeToUnix(le64_to_cpu(pData->LastModificationTime));
797 tmp_inode->i_ctime =
798 cifs_NTtimeToUnix(le64_to_cpu(pData->LastStatusChange));
799
800 tmp_inode->i_mode = le64_to_cpu(pData->Permissions);
801 /* since we set the inode type below we need to mask off type
802 to avoid strange results if bits above were corrupt */
803 tmp_inode->i_mode &= ~S_IFMT;
804 if (type == UNIX_FILE) {
805 *pobject_type = DT_REG;
806 tmp_inode->i_mode |= S_IFREG;
807 } else if (type == UNIX_SYMLINK) {
808 *pobject_type = DT_LNK;
809 tmp_inode->i_mode |= S_IFLNK;
810 } else if (type == UNIX_DIR) {
811 *pobject_type = DT_DIR;
812 tmp_inode->i_mode |= S_IFDIR;
813 } else if (type == UNIX_CHARDEV) {
814 *pobject_type = DT_CHR;
815 tmp_inode->i_mode |= S_IFCHR;
816 tmp_inode->i_rdev = MKDEV(le64_to_cpu(pData->DevMajor),
817 le64_to_cpu(pData->DevMinor) & MINORMASK);
818 } else if (type == UNIX_BLOCKDEV) {
819 *pobject_type = DT_BLK;
820 tmp_inode->i_mode |= S_IFBLK;
821 tmp_inode->i_rdev = MKDEV(le64_to_cpu(pData->DevMajor),
822 le64_to_cpu(pData->DevMinor) & MINORMASK);
823 } else if (type == UNIX_FIFO) {
824 *pobject_type = DT_FIFO;
825 tmp_inode->i_mode |= S_IFIFO;
826 } else if (type == UNIX_SOCKET) {
827 *pobject_type = DT_SOCK;
828 tmp_inode->i_mode |= S_IFSOCK;
829 } else {
830 /* safest to just call it a file */
831 *pobject_type = DT_REG;
832 tmp_inode->i_mode |= S_IFREG;
833 cFYI(1, ("unknown inode type %d", type));
834 }
835
836 cFYI(DBG2, ("object type: %d", type));
837 tmp_inode->i_uid = le64_to_cpu(pData->Uid);
838 tmp_inode->i_gid = le64_to_cpu(pData->Gid);
839 tmp_inode->i_nlink = le64_to_cpu(pData->Nlinks);
840 808
841 spin_lock(&tmp_inode->i_lock); 809 if (!S_ISREG(tmp_inode->i_mode))
842 if (is_size_safe_to_change(cifsInfo, end_of_file)) { 810 return;
843 /* can not safely change the file size here if the
844 client is writing to it due to potential races */
845 i_size_write(tmp_inode, end_of_file);
846
847 /* 512 bytes (2**9) is the fake blocksize that must be used */
848 /* for this calculation, not the real blocksize */
849 tmp_inode->i_blocks = (512 - 1 + num_of_bytes) >> 9;
850 }
851 spin_unlock(&tmp_inode->i_lock);
852
853 if (S_ISREG(tmp_inode->i_mode)) {
854 cFYI(1, ("File inode"));
855 tmp_inode->i_op = &cifs_file_inode_ops;
856
857 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
858 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
859 tmp_inode->i_fop = &cifs_file_direct_nobrl_ops;
860 else
861 tmp_inode->i_fop = &cifs_file_direct_ops;
862 811
863 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 812 /*
864 tmp_inode->i_fop = &cifs_file_nobrl_ops; 813 * No sense invalidating pages for new inode
865 else 814 * since we we have not started caching
866 tmp_inode->i_fop = &cifs_file_ops; 815 * readahead file data yet.
867 816 */
868 if ((cifs_sb->tcon) && (cifs_sb->tcon->ses) && 817 if (isNewInode)
869 (cifs_sb->tcon->ses->server->maxBuf < 818 return;
870 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE))
871 tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
872 else
873 tmp_inode->i_data.a_ops = &cifs_addr_ops;
874
875 if (isNewInode)
876 return; /* No sense invalidating pages for new inode
877 since we we have not started caching
878 readahead file data yet */
879 819
880 if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) && 820 if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) &&
881 (local_size == tmp_inode->i_size)) { 821 (local_size == tmp_inode->i_size)) {
882 cFYI(1, ("inode exists but unchanged")); 822 cFYI(1, ("inode exists but unchanged"));
883 } else {
884 /* file may have changed on server */
885 cFYI(1, ("invalidate inode, readdir detected change"));
886 invalidate_remote_inode(tmp_inode);
887 }
888 } else if (S_ISDIR(tmp_inode->i_mode)) {
889 cFYI(1, ("Directory inode"));
890 tmp_inode->i_op = &cifs_dir_inode_ops;
891 tmp_inode->i_fop = &cifs_dir_ops;
892 } else if (S_ISLNK(tmp_inode->i_mode)) {
893 cFYI(1, ("Symbolic Link inode"));
894 tmp_inode->i_op = &cifs_symlink_inode_ops;
895/* tmp_inode->i_fop = *//* do not need to set to anything */
896 } else { 823 } else {
897 cFYI(1, ("Special inode")); 824 /* file may have changed on server */
898 init_special_inode(tmp_inode, tmp_inode->i_mode, 825 cFYI(1, ("invalidate inode, readdir detected change"));
899 tmp_inode->i_rdev); 826 invalidate_remote_inode(tmp_inode);
900 } 827 }
901} 828}
902 829