File: | obj-scan-build/libdiskfs/../../libdiskfs/dir-renamed.c |
Location: | line 134, column 4 |
Description: | Value stored to 'err' is never read |
1 | /* |
2 | Copyright (C) 1994,95,96,97,98,99,2001,2003 Free Software Foundation, Inc. |
3 | |
4 | This program is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU General Public License as |
6 | published by the Free Software Foundation; either version 2, or (at |
7 | your option) any later version. |
8 | |
9 | This program is distributed in the hope that it will be useful, but |
10 | WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU General Public License |
15 | along with this program; if not, write to the Free Software |
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
17 | |
18 | #include "priv.h" |
19 | |
20 | |
21 | /* Check if source directory is in the path of the target directory. |
22 | We get target locked, source unlocked but with a reference. When |
23 | we return, nothing is locked, and target has lost its reference. |
24 | This routine assumes that no renames of directories will happen |
25 | while it is running; as a result, ufs_rename serializes all renames |
26 | of directories. */ |
27 | static error_t |
28 | checkpath(struct node *source, |
29 | struct node *target, |
30 | struct protid *cred) |
31 | { |
32 | error_t err; |
33 | struct node *np; |
34 | |
35 | for (np = target, err = 0; |
36 | /* nothing */; |
37 | /* This special lookup does a diskfs_nput on its first argument |
38 | when it succeeds. */ |
39 | err = diskfs_lookup (np, "..", LOOKUP | SPEC_DOTDOT0x10000000, &np, 0, cred)) |
40 | { |
41 | if (err) |
42 | { |
43 | diskfs_nput (np); |
44 | return err; |
45 | } |
46 | |
47 | if (np == source) |
48 | { |
49 | diskfs_nput (np); |
50 | return EINVAL((0x10 << 26) | ((22) & 0x3fff)); |
51 | } |
52 | |
53 | if (np == diskfs_root_node || np == cred->po->shadow_root) |
54 | { |
55 | diskfs_nput (np); |
56 | return 0; |
57 | } |
58 | } |
59 | } |
60 | |
61 | /* Rename directory node FNP (whose parent is FDP, and which has name |
62 | FROMNAME in that directory) to have name TONAME inside directory |
63 | TDP. None of these nodes are locked, and none should be locked |
64 | upon return. This routine is serialized, so it doesn't have to be |
65 | reentrant. Directories will never be renamed except by this |
66 | routine. FROMCRED and TOCRED are the users responsible for |
67 | FDP/FNP and TDP respectively. */ |
68 | error_t |
69 | diskfs_rename_dir (struct node *fdp, struct node *fnp, const char *fromname, |
70 | struct node *tdp, const char *toname, |
71 | struct protid *fromcred, struct protid *tocred) |
72 | { |
73 | error_t err; |
74 | struct node *tnp, *tmpnp; |
75 | void *buf = alloca (diskfs_dirstat_size)__builtin_alloca (diskfs_dirstat_size); |
76 | struct dirstat *ds; |
77 | struct dirstat *tmpds; |
78 | |
79 | pthread_mutex_lock (&tdp->lock); |
80 | diskfs_nref (tdp); /* reference and lock will get consumed by |
81 | checkpath */ |
82 | err = checkpath (fnp, tdp, tocred); |
83 | |
84 | if (err) |
85 | return err; |
86 | |
87 | /* Now, lock the parent directories. This is legal because tdp is not |
88 | a child of fnp (guaranteed by checkpath above). */ |
89 | pthread_mutex_lock (&fdp->lock); |
90 | if (fdp != tdp) |
91 | pthread_mutex_lock (&tdp->lock); |
92 | |
93 | /* 1: Lookup target; if it exists, make sure it's an empty directory. */ |
94 | ds = buf; |
95 | err = diskfs_lookup (tdp, toname, RENAME, &tnp, ds, tocred); |
96 | assert (err != EAGAIN)((err != ((0x10 << 26) | ((35) & 0x3fff))) ? (void) (0) : __assert_fail ("err != ((0x10 << 26) | ((35) & 0x3fff))" , "../../libdiskfs/dir-renamed.c", 96, __PRETTY_FUNCTION__)); /* <-> assert (TONAME != "..") */ |
97 | |
98 | if (tnp == fnp) |
99 | { |
100 | diskfs_drop_dirstat (tdp, ds); |
101 | diskfs_nput (tnp); |
102 | pthread_mutex_unlock (&tdp->lock); |
103 | if (fdp != tdp) |
104 | pthread_mutex_unlock (&fdp->lock); |
105 | return 0; |
106 | } |
107 | |
108 | /* Check permissions to remove FROMNAME and lock FNP. */ |
109 | tmpds = alloca (diskfs_dirstat_size)__builtin_alloca (diskfs_dirstat_size); |
110 | err = diskfs_lookup (fdp, fromname, REMOVE, &tmpnp, tmpds, fromcred); |
111 | assert (!tmpnp || tmpnp == fnp)((!tmpnp || tmpnp == fnp) ? (void) (0) : __assert_fail ("!tmpnp || tmpnp == fnp" , "../../libdiskfs/dir-renamed.c", 111, __PRETTY_FUNCTION__)); |
112 | if (tmpnp) |
113 | diskfs_nrele (tmpnp); |
114 | diskfs_drop_dirstat (fdp, tmpds); |
115 | if (err) |
116 | goto out; |
117 | |
118 | if (tnp) |
119 | { |
120 | if (! S_ISDIR(tnp->dn_stat.st_mode)((((tnp->dn_stat.st_mode)) & 0170000) == (0040000))) |
121 | err = ENOTDIR((0x10 << 26) | ((20) & 0x3fff)); |
122 | else if (!diskfs_dirempty (tnp, tocred)) |
123 | err = ENOTEMPTY((0x10 << 26) | ((66) & 0x3fff)); |
124 | } |
125 | |
126 | if (err && err != ENOENT((0x10 << 26) | ((2) & 0x3fff))) |
127 | goto out; |
128 | |
129 | /* 2: Set our .. to point to the new parent */ |
130 | if (fdp != tdp) |
131 | { |
132 | if (tdp->dn_stat.st_nlink == diskfs_link_max - 1) |
133 | { |
134 | err = EMLINK((0x10 << 26) | ((31) & 0x3fff)); |
Value stored to 'err' is never read | |
135 | return EMLINK((0x10 << 26) | ((31) & 0x3fff)); |
136 | } |
137 | tdp->dn_stat.st_nlink++; |
138 | tdp->dn_set_ctime = 1; |
139 | if (diskfs_synchronous) |
140 | diskfs_node_update (tdp, 1); |
141 | |
142 | tmpds = alloca (diskfs_dirstat_size)__builtin_alloca (diskfs_dirstat_size); |
143 | err = diskfs_lookup (fnp, "..", RENAME | SPEC_DOTDOT0x10000000, |
144 | &tmpnp, tmpds, fromcred); |
145 | assert (err != ENOENT)((err != ((0x10 << 26) | ((2) & 0x3fff))) ? (void) ( 0) : __assert_fail ("err != ((0x10 << 26) | ((2) & 0x3fff))" , "../../libdiskfs/dir-renamed.c", 145, __PRETTY_FUNCTION__)); |
146 | if (err) |
147 | { |
148 | diskfs_drop_dirstat (fnp, tmpds); |
149 | goto out; |
150 | } |
151 | assert (tmpnp == fdp)((tmpnp == fdp) ? (void) (0) : __assert_fail ("tmpnp == fdp", "../../libdiskfs/dir-renamed.c", 151, __PRETTY_FUNCTION__)); |
152 | |
153 | err = diskfs_dirrewrite (fnp, fdp, tdp, "..", tmpds); |
154 | if (diskfs_synchronous) |
155 | diskfs_file_update (fnp, 1); |
156 | if (err) |
157 | goto out; |
158 | |
159 | fdp->dn_stat.st_nlink--; |
160 | fdp->dn_set_ctime = 1; |
161 | if (diskfs_synchronous) |
162 | diskfs_node_update (fdp, 1); |
163 | } |
164 | |
165 | |
166 | /* 3: Increment the link count on the node being moved and rewrite |
167 | tdp. */ |
168 | if (fnp->dn_stat.st_nlink == diskfs_link_max - 1) |
169 | { |
170 | pthread_mutex_unlock (&fnp->lock); |
171 | diskfs_drop_dirstat (tdp, ds); |
172 | pthread_mutex_unlock (&tdp->lock); |
173 | if (tnp) |
174 | diskfs_nput (tnp); |
175 | return EMLINK((0x10 << 26) | ((31) & 0x3fff)); |
176 | } |
177 | fnp->dn_stat.st_nlink++; |
178 | fnp->dn_set_ctime = 1; |
179 | diskfs_node_update (fnp, diskfs_synchronous); |
180 | |
181 | if (tnp) |
182 | { |
183 | err = diskfs_dirrewrite (tdp, tnp, fnp, toname, ds); |
184 | ds = 0; |
185 | if (!err) |
186 | { |
187 | tnp->dn_stat.st_nlink--; |
188 | tnp->dn_set_ctime = 1; |
189 | } |
190 | diskfs_clear_directory (tnp, tdp, tocred); |
191 | if (diskfs_synchronous) |
192 | diskfs_file_update (tnp, 1); |
193 | } |
194 | else |
195 | { |
196 | err = diskfs_direnter (tdp, toname, fnp, ds, tocred); |
197 | if (diskfs_synchronous) |
198 | diskfs_file_update (tdp, 1); |
199 | } |
200 | |
201 | if (err) |
202 | goto out; |
203 | |
204 | /* 4: Remove the entry in fdp. */ |
205 | ds = buf; |
206 | pthread_mutex_unlock (&fnp->lock); |
207 | err = diskfs_lookup (fdp, fromname, REMOVE, &tmpnp, ds, fromcred); |
208 | assert (!tmpnp || tmpnp == fnp)((!tmpnp || tmpnp == fnp) ? (void) (0) : __assert_fail ("!tmpnp || tmpnp == fnp" , "../../libdiskfs/dir-renamed.c", 208, __PRETTY_FUNCTION__)); |
209 | if (tmpnp) |
210 | diskfs_nrele (tmpnp); |
211 | if (err) |
212 | goto out; |
213 | |
214 | diskfs_dirremove (fdp, fnp, fromname, ds); |
215 | ds = 0; |
216 | fnp->dn_stat.st_nlink--; |
217 | fnp->dn_set_ctime = 1; |
218 | if (diskfs_synchronous) |
219 | { |
220 | diskfs_file_update (fdp, 1); |
221 | diskfs_node_update (fnp, 1); |
222 | } |
223 | |
224 | out: |
225 | if (tdp) |
226 | pthread_mutex_unlock (&tdp->lock); |
227 | if (tnp) |
228 | diskfs_nput (tnp); |
229 | if (fdp && fdp != tdp) |
230 | pthread_mutex_unlock (&fdp->lock); |
231 | if (fnp) |
232 | pthread_mutex_unlock (&fnp->lock); |
233 | if (ds) |
234 | diskfs_drop_dirstat (tdp, ds); |
235 | return err; |
236 | } |