OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [fs/] [cifs/] [dir.c] - Blame information for rev 78

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 *   fs/cifs/dir.c
3
 *
4
 *   vfs operations that deal with dentries
5
 *
6
 *   Copyright (C) International Business Machines  Corp., 2002,2007
7
 *   Author(s): Steve French (sfrench@us.ibm.com)
8
 *
9
 *   This library is free software; you can redistribute it and/or modify
10
 *   it under the terms of the GNU Lesser General Public License as published
11
 *   by the Free Software Foundation; either version 2.1 of the License, or
12
 *   (at your option) any later version.
13
 *
14
 *   This library is distributed in the hope that it will be useful,
15
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
17
 *   the GNU Lesser General Public License for more details.
18
 *
19
 *   You should have received a copy of the GNU Lesser General Public License
20
 *   along with this library; if not, write to the Free Software
21
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
 */
23
#include <linux/fs.h>
24
#include <linux/stat.h>
25
#include <linux/slab.h>
26
#include <linux/namei.h>
27
#include "cifsfs.h"
28
#include "cifspdu.h"
29
#include "cifsglob.h"
30
#include "cifsproto.h"
31
#include "cifs_debug.h"
32
#include "cifs_fs_sb.h"
33
 
34
static void
35
renew_parental_timestamps(struct dentry *direntry)
36
{
37
        /* BB check if there is a way to get the kernel to do this or if we
38
           really need this */
39
        do {
40
                direntry->d_time = jiffies;
41
                direntry = direntry->d_parent;
42
        } while (!IS_ROOT(direntry));
43
}
44
 
45
/* Note: caller must free return buffer */
46
char *
47
build_path_from_dentry(struct dentry *direntry)
48
{
49
        struct dentry *temp;
50
        int namelen;
51
        int pplen;
52
        char *full_path;
53
        char dirsep;
54
 
55
        if (direntry == NULL)
56
                return NULL;  /* not much we can do if dentry is freed and
57
                we need to reopen the file after it was closed implicitly
58
                when the server crashed */
59
 
60
        dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb));
61
        pplen = CIFS_SB(direntry->d_sb)->prepathlen;
62
cifs_bp_rename_retry:
63
        namelen = pplen;
64
        for (temp = direntry; !IS_ROOT(temp);) {
65
                namelen += (1 + temp->d_name.len);
66
                temp = temp->d_parent;
67
                if (temp == NULL) {
68
                        cERROR(1, ("corrupt dentry"));
69
                        return NULL;
70
                }
71
        }
72
 
73
        full_path = kmalloc(namelen+1, GFP_KERNEL);
74
        if (full_path == NULL)
75
                return full_path;
76
        full_path[namelen] = 0;  /* trailing null */
77
        for (temp = direntry; !IS_ROOT(temp);) {
78
                namelen -= 1 + temp->d_name.len;
79
                if (namelen < 0) {
80
                        break;
81
                } else {
82
                        full_path[namelen] = dirsep;
83
                        strncpy(full_path + namelen + 1, temp->d_name.name,
84
                                temp->d_name.len);
85
                        cFYI(0, ("name: %s", full_path + namelen));
86
                }
87
                temp = temp->d_parent;
88
                if (temp == NULL) {
89
                        cERROR(1, ("corrupt dentry"));
90
                        kfree(full_path);
91
                        return NULL;
92
                }
93
        }
94
        if (namelen != pplen) {
95
                cERROR(1,
96
                       ("did not end path lookup where expected namelen is %d",
97
                        namelen));
98
                /* presumably this is only possible if racing with a rename
99
                of one of the parent directories  (we can not lock the dentries
100
                above us to prevent this, but retrying should be harmless) */
101
                kfree(full_path);
102
                goto cifs_bp_rename_retry;
103
        }
104
        /* DIR_SEP already set for byte  0 / vs \ but not for
105
           subsequent slashes in prepath which currently must
106
           be entered the right way - not sure if there is an alternative
107
           since the '\' is a valid posix character so we can not switch
108
           those safely to '/' if any are found in the middle of the prepath */
109
        /* BB test paths to Windows with '/' in the midst of prepath */
110
        strncpy(full_path, CIFS_SB(direntry->d_sb)->prepath, pplen);
111
        return full_path;
112
}
113
 
114
/* char * build_wildcard_path_from_dentry(struct dentry *direntry)
115
{
116
        if(full_path == NULL)
117
                return full_path;
118
 
119
        full_path[namelen] = '\\';
120
        full_path[namelen+1] = '*';
121
        full_path[namelen+2] = 0;
122
BB remove above eight lines BB */
123
 
124
/* Inode operations in similar order to how they appear in Linux file fs.h */
125
 
126
int
127
cifs_create(struct inode *inode, struct dentry *direntry, int mode,
128
                struct nameidata *nd)
129
{
130
        int rc = -ENOENT;
131
        int xid;
132
        int oplock = 0;
133
        int desiredAccess = GENERIC_READ | GENERIC_WRITE;
134
        __u16 fileHandle;
135
        struct cifs_sb_info *cifs_sb;
136
        struct cifsTconInfo *pTcon;
137
        char *full_path = NULL;
138
        FILE_ALL_INFO *buf = NULL;
139
        struct inode *newinode = NULL;
140
        struct cifsFileInfo *pCifsFile = NULL;
141
        struct cifsInodeInfo *pCifsInode;
142
        int disposition = FILE_OVERWRITE_IF;
143
        int write_only = FALSE;
144
 
145
        xid = GetXid();
146
 
147
        cifs_sb = CIFS_SB(inode->i_sb);
148
        pTcon = cifs_sb->tcon;
149
 
150
        full_path = build_path_from_dentry(direntry);
151
        if (full_path == NULL) {
152
                FreeXid(xid);
153
                return -ENOMEM;
154
        }
155
 
156
        if (nd && (nd->flags & LOOKUP_OPEN)) {
157
                int oflags = nd->intent.open.flags;
158
 
159
                desiredAccess = 0;
160
                if (oflags & FMODE_READ)
161
                        desiredAccess |= GENERIC_READ;
162
                if (oflags & FMODE_WRITE) {
163
                        desiredAccess |= GENERIC_WRITE;
164
                        if (!(oflags & FMODE_READ))
165
                                write_only = TRUE;
166
                }
167
 
168
                if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
169
                        disposition = FILE_CREATE;
170
                else if ((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
171
                        disposition = FILE_OVERWRITE_IF;
172
                else if ((oflags & O_CREAT) == O_CREAT)
173
                        disposition = FILE_OPEN_IF;
174
                else {
175
                        cFYI(1, ("Create flag not set in create function"));
176
                }
177
        }
178
 
179
        /* BB add processing to set equivalent of mode - e.g. via CreateX with
180
           ACLs */
181
        if (oplockEnabled)
182
                oplock = REQ_OPLOCK;
183
 
184
        buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
185
        if (buf == NULL) {
186
                kfree(full_path);
187
                FreeXid(xid);
188
                return -ENOMEM;
189
        }
190
        if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS)
191
                rc = CIFSSMBOpen(xid, pTcon, full_path, disposition,
192
                         desiredAccess, CREATE_NOT_DIR,
193
                         &fileHandle, &oplock, buf, cifs_sb->local_nls,
194
                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
195
        else
196
                rc = -EIO; /* no NT SMB support fall into legacy open below */
197
 
198
        if (rc == -EIO) {
199
                /* old server, retry the open legacy style */
200
                rc = SMBLegacyOpen(xid, pTcon, full_path, disposition,
201
                        desiredAccess, CREATE_NOT_DIR,
202
                        &fileHandle, &oplock, buf, cifs_sb->local_nls,
203
                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
204
        }
205
        if (rc) {
206
                cFYI(1, ("cifs_create returned 0x%x", rc));
207
        } else {
208
                /* If Open reported that we actually created a file
209
                then we now have to set the mode if possible */
210
                if ((pTcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) {
211
                        mode &= ~current->fs->umask;
212
                        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
213
                                CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
214
                                        (__u64)current->fsuid,
215
                                        (__u64)current->fsgid,
216
 
217
                                        cifs_sb->local_nls,
218
                                        cifs_sb->mnt_cifs_flags &
219
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
220
                        } else {
221
                                CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
222
                                        (__u64)-1,
223
                                        (__u64)-1,
224
 
225
                                        cifs_sb->local_nls,
226
                                        cifs_sb->mnt_cifs_flags &
227
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
228
                        }
229
                } else {
230
                        /* BB implement mode setting via Windows security
231
                           descriptors e.g. */
232
                        /* CIFSSMBWinSetPerms(xid,pTcon,path,mode,-1,-1,nls);*/
233
 
234
                        /* Could set r/o dos attribute if mode & 0222 == 0 */
235
                }
236
 
237
                /* server might mask mode so we have to query for it */
238
                if (pTcon->unix_ext)
239
                        rc = cifs_get_inode_info_unix(&newinode, full_path,
240
                                                 inode->i_sb, xid);
241
                else {
242
                        rc = cifs_get_inode_info(&newinode, full_path,
243
                                                 buf, inode->i_sb, xid);
244
                        if (newinode) {
245
                                newinode->i_mode = mode;
246
                                if ((oplock & CIFS_CREATE_ACTION) &&
247
                                    (cifs_sb->mnt_cifs_flags &
248
                                     CIFS_MOUNT_SET_UID)) {
249
                                        newinode->i_uid = current->fsuid;
250
                                        newinode->i_gid = current->fsgid;
251
                                }
252
                        }
253
                }
254
 
255
                if (rc != 0) {
256
                        cFYI(1,
257
                             ("Create worked but get_inode_info failed rc = %d",
258
                              rc));
259
                } else {
260
                        if (pTcon->nocase)
261
                                direntry->d_op = &cifs_ci_dentry_ops;
262
                        else
263
                                direntry->d_op = &cifs_dentry_ops;
264
                        d_instantiate(direntry, newinode);
265
                }
266
                if ((nd == NULL /* nfsd case - nfs srv does not set nd */) ||
267
                        ((nd->flags & LOOKUP_OPEN) == FALSE)) {
268
                        /* mknod case - do not leave file open */
269
                        CIFSSMBClose(xid, pTcon, fileHandle);
270
                } else if (newinode) {
271
                        pCifsFile =
272
                           kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
273
 
274
                        if (pCifsFile == NULL)
275
                                goto cifs_create_out;
276
                        pCifsFile->netfid = fileHandle;
277
                        pCifsFile->pid = current->tgid;
278
                        pCifsFile->pInode = newinode;
279
                        pCifsFile->invalidHandle = FALSE;
280
                        pCifsFile->closePend     = FALSE;
281
                        init_MUTEX(&pCifsFile->fh_sem);
282
                        mutex_init(&pCifsFile->lock_mutex);
283
                        INIT_LIST_HEAD(&pCifsFile->llist);
284
                        atomic_set(&pCifsFile->wrtPending, 0);
285
 
286
                        /* set the following in open now
287
                                pCifsFile->pfile = file; */
288
                        write_lock(&GlobalSMBSeslock);
289
                        list_add(&pCifsFile->tlist, &pTcon->openFileList);
290
                        pCifsInode = CIFS_I(newinode);
291
                        if (pCifsInode) {
292
                                /* if readable file instance put first in list*/
293
                                if (write_only == TRUE) {
294
                                        list_add_tail(&pCifsFile->flist,
295
                                                &pCifsInode->openFileList);
296
                                } else {
297
                                        list_add(&pCifsFile->flist,
298
                                                &pCifsInode->openFileList);
299
                                }
300
                                if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
301
                                        pCifsInode->clientCanCacheAll = TRUE;
302
                                        pCifsInode->clientCanCacheRead = TRUE;
303
                                        cFYI(1, ("Exclusive Oplock inode %p",
304
                                                newinode));
305
                                } else if ((oplock & 0xF) == OPLOCK_READ)
306
                                        pCifsInode->clientCanCacheRead = TRUE;
307
                        }
308
                        write_unlock(&GlobalSMBSeslock);
309
                }
310
        }
311
cifs_create_out:
312
        kfree(buf);
313
        kfree(full_path);
314
        FreeXid(xid);
315
        return rc;
316
}
317
 
318
int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
319
                dev_t device_number)
320
{
321
        int rc = -EPERM;
322
        int xid;
323
        struct cifs_sb_info *cifs_sb;
324
        struct cifsTconInfo *pTcon;
325
        char *full_path = NULL;
326
        struct inode *newinode = NULL;
327
 
328
        if (!old_valid_dev(device_number))
329
                return -EINVAL;
330
 
331
        xid = GetXid();
332
 
333
        cifs_sb = CIFS_SB(inode->i_sb);
334
        pTcon = cifs_sb->tcon;
335
 
336
        full_path = build_path_from_dentry(direntry);
337
        if (full_path == NULL)
338
                rc = -ENOMEM;
339
        else if (pTcon->unix_ext) {
340
                mode &= ~current->fs->umask;
341
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
342
                        rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path,
343
                                mode, (__u64)current->fsuid,
344
                                (__u64)current->fsgid,
345
                                device_number, cifs_sb->local_nls,
346
                                cifs_sb->mnt_cifs_flags &
347
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
348
                } else {
349
                        rc = CIFSSMBUnixSetPerms(xid, pTcon,
350
                                full_path, mode, (__u64)-1, (__u64)-1,
351
                                device_number, cifs_sb->local_nls,
352
                                cifs_sb->mnt_cifs_flags &
353
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
354
                }
355
 
356
                if (!rc) {
357
                        rc = cifs_get_inode_info_unix(&newinode, full_path,
358
                                                inode->i_sb, xid);
359
                        if (pTcon->nocase)
360
                                direntry->d_op = &cifs_ci_dentry_ops;
361
                        else
362
                                direntry->d_op = &cifs_dentry_ops;
363
                        if (rc == 0)
364
                                d_instantiate(direntry, newinode);
365
                }
366
        } else {
367
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
368
                        int oplock = 0;
369
                        u16 fileHandle;
370
                        FILE_ALL_INFO * buf;
371
 
372
                        cFYI(1, ("sfu compat create special file"));
373
 
374
                        buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
375
                        if (buf == NULL) {
376
                                kfree(full_path);
377
                                FreeXid(xid);
378
                                return -ENOMEM;
379
                        }
380
 
381
                        rc = CIFSSMBOpen(xid, pTcon, full_path,
382
                                         FILE_CREATE, /* fail if exists */
383
                                         GENERIC_WRITE /* BB would
384
                                          WRITE_OWNER | WRITE_DAC be better? */,
385
                                         /* Create a file and set the
386
                                            file attribute to SYSTEM */
387
                                         CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
388
                                         &fileHandle, &oplock, buf,
389
                                         cifs_sb->local_nls,
390
                                         cifs_sb->mnt_cifs_flags &
391
                                            CIFS_MOUNT_MAP_SPECIAL_CHR);
392
 
393
                        /* BB FIXME - add handling for backlevel servers
394
                           which need legacy open and check for all
395
                           calls to SMBOpen for fallback to SMBLeagcyOpen */
396
                        if (!rc) {
397
                                /* BB Do not bother to decode buf since no
398
                                   local inode yet to put timestamps in,
399
                                   but we can reuse it safely */
400
                                unsigned int bytes_written;
401
                                struct win_dev *pdev;
402
                                pdev = (struct win_dev *)buf;
403
                                if (S_ISCHR(mode)) {
404
                                        memcpy(pdev->type, "IntxCHR", 8);
405
                                        pdev->major =
406
                                              cpu_to_le64(MAJOR(device_number));
407
                                        pdev->minor =
408
                                              cpu_to_le64(MINOR(device_number));
409
                                        rc = CIFSSMBWrite(xid, pTcon,
410
                                                fileHandle,
411
                                                sizeof(struct win_dev),
412
                                                0, &bytes_written, (char *)pdev,
413
                                                NULL, 0);
414
                                } else if (S_ISBLK(mode)) {
415
                                        memcpy(pdev->type, "IntxBLK", 8);
416
                                        pdev->major =
417
                                              cpu_to_le64(MAJOR(device_number));
418
                                        pdev->minor =
419
                                              cpu_to_le64(MINOR(device_number));
420
                                        rc = CIFSSMBWrite(xid, pTcon,
421
                                                fileHandle,
422
                                                sizeof(struct win_dev),
423
                                                0, &bytes_written, (char *)pdev,
424
                                                NULL, 0);
425
                                } /* else if(S_ISFIFO */
426
                                CIFSSMBClose(xid, pTcon, fileHandle);
427
                                d_drop(direntry);
428
                        }
429
                        kfree(buf);
430
                        /* add code here to set EAs */
431
                }
432
        }
433
 
434
        kfree(full_path);
435
        FreeXid(xid);
436
        return rc;
437
}
438
 
439
 
440
struct dentry *
441
cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
442
            struct nameidata *nd)
443
{
444
        int xid;
445
        int rc = 0; /* to get around spurious gcc warning, set to zero here */
446
        struct cifs_sb_info *cifs_sb;
447
        struct cifsTconInfo *pTcon;
448
        struct inode *newInode = NULL;
449
        char *full_path = NULL;
450
 
451
        xid = GetXid();
452
 
453
        cFYI(1, (" parent inode = 0x%p name is: %s and dentry = 0x%p",
454
              parent_dir_inode, direntry->d_name.name, direntry));
455
 
456
        /* check whether path exists */
457
 
458
        cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
459
        pTcon = cifs_sb->tcon;
460
 
461
        /*
462
         * Don't allow the separator character in a path component.
463
         * The VFS will not allow "/", but "\" is allowed by posix.
464
         */
465
        if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
466
                int i;
467
                for (i = 0; i < direntry->d_name.len; i++)
468
                        if (direntry->d_name.name[i] == '\\') {
469
                                cFYI(1, ("Invalid file name"));
470
                                FreeXid(xid);
471
                                return ERR_PTR(-EINVAL);
472
                        }
473
        }
474
 
475
        /* can not grab the rename sem here since it would
476
        deadlock in the cases (beginning of sys_rename itself)
477
        in which we already have the sb rename sem */
478
        full_path = build_path_from_dentry(direntry);
479
        if (full_path == NULL) {
480
                FreeXid(xid);
481
                return ERR_PTR(-ENOMEM);
482
        }
483
 
484
        if (direntry->d_inode != NULL) {
485
                cFYI(1, (" non-NULL inode in lookup"));
486
        } else {
487
                cFYI(1, (" NULL inode in lookup"));
488
        }
489
        cFYI(1,
490
             (" Full path: %s inode = 0x%p", full_path, direntry->d_inode));
491
 
492
        if (pTcon->unix_ext)
493
                rc = cifs_get_inode_info_unix(&newInode, full_path,
494
                                              parent_dir_inode->i_sb, xid);
495
        else
496
                rc = cifs_get_inode_info(&newInode, full_path, NULL,
497
                                         parent_dir_inode->i_sb, xid);
498
 
499
        if ((rc == 0) && (newInode != NULL)) {
500
                if (pTcon->nocase)
501
                        direntry->d_op = &cifs_ci_dentry_ops;
502
                else
503
                        direntry->d_op = &cifs_dentry_ops;
504
                d_add(direntry, newInode);
505
 
506
                /* since paths are not looked up by component - the parent
507
                   directories are presumed to be good here */
508
                renew_parental_timestamps(direntry);
509
 
510
        } else if (rc == -ENOENT) {
511
                rc = 0;
512
                direntry->d_time = jiffies;
513
                if (pTcon->nocase)
514
                        direntry->d_op = &cifs_ci_dentry_ops;
515
                else
516
                        direntry->d_op = &cifs_dentry_ops;
517
                d_add(direntry, NULL);
518
        /*      if it was once a directory (but how can we tell?) we could do
519
                shrink_dcache_parent(direntry); */
520
        } else {
521
                cERROR(1, ("Error 0x%x on cifs_get_inode_info in lookup of %s",
522
                           rc, full_path));
523
                /* BB special case check for Access Denied - watch security
524
                exposure of returning dir info implicitly via different rc
525
                if file exists or not but no access BB */
526
        }
527
 
528
        kfree(full_path);
529
        FreeXid(xid);
530
        return ERR_PTR(rc);
531
}
532
 
533
static int
534
cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
535
{
536
        int isValid = 1;
537
 
538
        if (direntry->d_inode) {
539
                if (cifs_revalidate(direntry)) {
540
                        return 0;
541
                }
542
        } else {
543
                cFYI(1, ("neg dentry 0x%p name = %s",
544
                         direntry, direntry->d_name.name));
545
                if (time_after(jiffies, direntry->d_time + HZ) ||
546
                        !lookupCacheEnabled) {
547
                        d_drop(direntry);
548
                        isValid = 0;
549
                }
550
        }
551
 
552
        return isValid;
553
}
554
 
555
/* static int cifs_d_delete(struct dentry *direntry)
556
{
557
        int rc = 0;
558
 
559
        cFYI(1, ("In cifs d_delete, name = %s", direntry->d_name.name));
560
 
561
        return rc;
562
}     */
563
 
564
struct dentry_operations cifs_dentry_ops = {
565
        .d_revalidate = cifs_d_revalidate,
566
/* d_delete:       cifs_d_delete,      */ /* not needed except for debugging */
567
};
568
 
569
static int cifs_ci_hash(struct dentry *dentry, struct qstr *q)
570
{
571
        struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls;
572
        unsigned long hash;
573
        int i;
574
 
575
        hash = init_name_hash();
576
        for (i = 0; i < q->len; i++)
577
                hash = partial_name_hash(nls_tolower(codepage, q->name[i]),
578
                                         hash);
579
        q->hash = end_name_hash(hash);
580
 
581
        return 0;
582
}
583
 
584
static int cifs_ci_compare(struct dentry *dentry, struct qstr *a,
585
                           struct qstr *b)
586
{
587
        struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls;
588
 
589
        if ((a->len == b->len) &&
590
            (nls_strnicmp(codepage, a->name, b->name, a->len) == 0)) {
591
                /*
592
                 * To preserve case, don't let an existing negative dentry's
593
                 * case take precedence.  If a is not a negative dentry, this
594
                 * should have no side effects
595
                 */
596
                memcpy(a->name, b->name, a->len);
597
                return 0;
598
        }
599
        return 1;
600
}
601
 
602
struct dentry_operations cifs_ci_dentry_ops = {
603
        .d_revalidate = cifs_d_revalidate,
604
        .d_hash = cifs_ci_hash,
605
        .d_compare = cifs_ci_compare,
606
};

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.